summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
committerKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
commitad547a6b5986815fda458221149728d9d9ab1d87 (patch)
tree16296910eb3eca724371474ea9aea3994dc69614 /Build/source/texk/dvipdfm-x
parent947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff)
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipdfm-x')
-rw-r--r--Build/source/texk/dvipdfm-x/AUTHORS16
-rw-r--r--Build/source/texk/dvipdfm-x/COPYING340
-rw-r--r--Build/source/texk/dvipdfm-x/ChangeLog6106
-rw-r--r--Build/source/texk/dvipdfm-x/INSTALL182
-rw-r--r--Build/source/texk/dvipdfm-x/Makefile.am299
-rw-r--r--Build/source/texk/dvipdfm-x/Makefile.in2034
-rw-r--r--Build/source/texk/dvipdfm-x/README109
-rw-r--r--Build/source/texk/dvipdfm-x/ac/withenable.ac7
-rw-r--r--Build/source/texk/dvipdfm-x/aclocal.m41217
-rw-r--r--Build/source/texk/dvipdfm-x/agl.c817
-rw-r--r--Build/source/texk/dvipdfm-x/agl.h64
-rw-r--r--Build/source/texk/dvipdfm-x/bmpimage.c539
-rw-r--r--Build/source/texk/dvipdfm-x/bmpimage.h35
-rw-r--r--Build/source/texk/dvipdfm-x/cff.c1488
-rw-r--r--Build/source/texk/dvipdfm-x/cff.h150
-rw-r--r--Build/source/texk/dvipdfm-x/cff_dict.c724
-rw-r--r--Build/source/texk/dvipdfm-x/cff_dict.h45
-rw-r--r--Build/source/texk/dvipdfm-x/cff_limits.h44
-rw-r--r--Build/source/texk/dvipdfm-x/cff_stdstr.h107
-rw-r--r--Build/source/texk/dvipdfm-x/cff_types.h138
-rw-r--r--Build/source/texk/dvipdfm-x/cid.c610
-rw-r--r--Build/source/texk/dvipdfm-x/cid.h47
-rw-r--r--Build/source/texk/dvipdfm-x/cid_basefont.h507
-rw-r--r--Build/source/texk/dvipdfm-x/cidtype0.c2118
-rw-r--r--Build/source/texk/dvipdfm-x/cidtype0.h38
-rw-r--r--Build/source/texk/dvipdfm-x/cidtype2.c1181
-rw-r--r--Build/source/texk/dvipdfm-x/cidtype2.h29
-rw-r--r--Build/source/texk/dvipdfm-x/cmap.c993
-rw-r--r--Build/source/texk/dvipdfm-x/cmap.h114
-rw-r--r--Build/source/texk/dvipdfm-x/cmap_p.h101
-rw-r--r--Build/source/texk/dvipdfm-x/cmap_read.c605
-rw-r--r--Build/source/texk/dvipdfm-x/cmap_read.h32
-rw-r--r--Build/source/texk/dvipdfm-x/cmap_write.c690
-rw-r--r--Build/source/texk/dvipdfm-x/cmap_write.h36
-rw-r--r--Build/source/texk/dvipdfm-x/config.h.in267
-rwxr-xr-xBuild/source/texk/dvipdfm-x/configure18430
-rw-r--r--Build/source/texk/dvipdfm-x/configure.ac96
-rw-r--r--Build/source/texk/dvipdfm-x/cs_type2.c808
-rw-r--r--Build/source/texk/dvipdfm-x/cs_type2.h43
-rw-r--r--Build/source/texk/dvipdfm-x/data/Adobe-Japan1-YuMincho-Regular135
-rw-r--r--Build/source/texk/dvipdfm-x/data/EUC-UCS26800
-rw-r--r--Build/source/texk/dvipdfm-x/data/cid-x.map152
-rw-r--r--Build/source/texk/dvipdfm-x/data/dvipdfmx.cfg228
-rw-r--r--Build/source/texk/dvipdfm-x/data/glyphlist.txt4322
-rw-r--r--Build/source/texk/dvipdfm-x/data/pdfglyphlist.txt385
-rw-r--r--Build/source/texk/dvipdfm-x/dpxconf.c110
-rw-r--r--Build/source/texk/dvipdfm-x/dpxconf.h75
-rw-r--r--Build/source/texk/dvipdfm-x/dpxcrypt.c1941
-rw-r--r--Build/source/texk/dvipdfm-x/dpxcrypt.h97
-rw-r--r--Build/source/texk/dvipdfm-x/dpxfile.c1324
-rw-r--r--Build/source/texk/dvipdfm-x/dpxfile.h67
-rw-r--r--Build/source/texk/dvipdfm-x/dpxutil.c893
-rw-r--r--Build/source/texk/dvipdfm-x/dpxutil.h131
-rw-r--r--Build/source/texk/dvipdfm-x/dvi.c2884
-rw-r--r--Build/source/texk/dvipdfm-x/dvi.h111
-rw-r--r--Build/source/texk/dvipdfm-x/dvicodes.h130
-rwxr-xr-xBuild/source/texk/dvipdfm-x/dvipdfmx-upjf.test38
-rw-r--r--Build/source/texk/dvipdfm-x/dvipdfmx.c1252
-rw-r--r--Build/source/texk/dvipdfm-x/dvipdfmx.h33
-rwxr-xr-xBuild/source/texk/dvipdfm-x/dvipdft105
-rw-r--r--Build/source/texk/dvipdfm-x/epdf.c518
-rw-r--r--Build/source/texk/dvipdfm-x/epdf.h41
-rw-r--r--Build/source/texk/dvipdfm-x/error.c95
-rw-r--r--Build/source/texk/dvipdfm-x/error.h55
-rw-r--r--Build/source/texk/dvipdfm-x/fontmap.c1433
-rw-r--r--Build/source/texk/dvipdfm-x/fontmap.h96
-rw-r--r--Build/source/texk/dvipdfm-x/jp2image.c422
-rw-r--r--Build/source/texk/dvipdfm-x/jp2image.h36
-rw-r--r--Build/source/texk/dvipdfm-x/jpegimage.c1102
-rw-r--r--Build/source/texk/dvipdfm-x/jpegimage.h36
-rw-r--r--Build/source/texk/dvipdfm-x/man/dvipdfmx.1354
-rw-r--r--Build/source/texk/dvipdfm-x/man/dvipdft.140
-rw-r--r--Build/source/texk/dvipdfm-x/man/extractbb.199
-rw-r--r--Build/source/texk/dvipdfm-x/mem.c57
-rw-r--r--Build/source/texk/dvipdfm-x/mem.h50
-rw-r--r--Build/source/texk/dvipdfm-x/mfileio.c171
-rw-r--r--Build/source/texk/dvipdfm-x/mfileio.h70
-rw-r--r--Build/source/texk/dvipdfm-x/mpost.c1679
-rw-r--r--Build/source/texk/dvipdfm-x/mpost.h45
-rw-r--r--Build/source/texk/dvipdfm-x/mt19937ar.c192
-rw-r--r--Build/source/texk/dvipdfm-x/numbers.c171
-rw-r--r--Build/source/texk/dvipdfm-x/numbers.h101
-rw-r--r--Build/source/texk/dvipdfm-x/otl_opt.c340
-rw-r--r--Build/source/texk/dvipdfm-x/otl_opt.h35
-rw-r--r--Build/source/texk/dvipdfm-x/pdfcolor.c1560
-rw-r--r--Build/source/texk/dvipdfm-x/pdfcolor.h117
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdev.c1849
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdev.h178
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdoc.c2878
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdoc.h176
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdraw.c1888
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdraw.h165
-rw-r--r--Build/source/texk/dvipdfm-x/pdfencoding.c1079
-rw-r--r--Build/source/texk/dvipdfm-x/pdfencoding.h76
-rw-r--r--Build/source/texk/dvipdfm-x/pdfencrypt.c764
-rw-r--r--Build/source/texk/dvipdfm-x/pdfencrypt.h45
-rw-r--r--Build/source/texk/dvipdfm-x/pdffont.c1091
-rw-r--r--Build/source/texk/dvipdfm-x/pdffont.h165
-rw-r--r--Build/source/texk/dvipdfm-x/pdflimits.h42
-rw-r--r--Build/source/texk/dvipdfm-x/pdfnames.c469
-rw-r--r--Build/source/texk/dvipdfm-x/pdfnames.h49
-rw-r--r--Build/source/texk/dvipdfm-x/pdfobj.c4624
-rw-r--r--Build/source/texk/dvipdfm-x/pdfobj.h205
-rw-r--r--Build/source/texk/dvipdfm-x/pdfparse.c1009
-rw-r--r--Build/source/texk/dvipdfm-x/pdfparse.h62
-rw-r--r--Build/source/texk/dvipdfm-x/pdfresource.c375
-rw-r--r--Build/source/texk/dvipdfm-x/pdfresource.h45
-rw-r--r--Build/source/texk/dvipdfm-x/pdfximage.c1225
-rw-r--r--Build/source/texk/dvipdfm-x/pdfximage.h103
-rw-r--r--Build/source/texk/dvipdfm-x/pkfont.c753
-rw-r--r--Build/source/texk/dvipdfm-x/pkfont.h33
-rw-r--r--Build/source/texk/dvipdfm-x/pngimage.c1143
-rw-r--r--Build/source/texk/dvipdfm-x/pngimage.h39
-rw-r--r--Build/source/texk/dvipdfm-x/pst.c184
-rw-r--r--Build/source/texk/dvipdfm-x/pst.h72
-rw-r--r--Build/source/texk/dvipdfm-x/pst_obj.c992
-rw-r--r--Build/source/texk/dvipdfm-x/pst_obj.h34
-rw-r--r--Build/source/texk/dvipdfm-x/sfnt.c532
-rw-r--r--Build/source/texk/dvipdfm-x/sfnt.h121
-rw-r--r--Build/source/texk/dvipdfm-x/spc_color.c189
-rw-r--r--Build/source/texk/dvipdfm-x/spc_color.h30
-rw-r--r--Build/source/texk/dvipdfm-x/spc_dvipdfmx.c139
-rw-r--r--Build/source/texk/dvipdfm-x/spc_dvipdfmx.h30
-rw-r--r--Build/source/texk/dvipdfm-x/spc_dvips.c1082
-rw-r--r--Build/source/texk/dvipdfm-x/spc_dvips.h37
-rw-r--r--Build/source/texk/dvipdfm-x/spc_html.c867
-rw-r--r--Build/source/texk/dvipdfm-x/spc_html.h37
-rw-r--r--Build/source/texk/dvipdfm-x/spc_misc.c680
-rw-r--r--Build/source/texk/dvipdfm-x/spc_misc.h36
-rw-r--r--Build/source/texk/dvipdfm-x/spc_pdfm.c2435
-rw-r--r--Build/source/texk/dvipdfm-x/spc_pdfm.h37
-rw-r--r--Build/source/texk/dvipdfm-x/spc_tpic.c1118
-rw-r--r--Build/source/texk/dvipdfm-x/spc_tpic.h39
-rw-r--r--Build/source/texk/dvipdfm-x/spc_util.c1204
-rw-r--r--Build/source/texk/dvipdfm-x/spc_util.h58
-rw-r--r--Build/source/texk/dvipdfm-x/spc_xtx.c465
-rw-r--r--Build/source/texk/dvipdfm-x/spc_xtx.h41
-rw-r--r--Build/source/texk/dvipdfm-x/specials.c832
-rw-r--r--Build/source/texk/dvipdfm-x/specials.h103
-rw-r--r--Build/source/texk/dvipdfm-x/subfont.c649
-rw-r--r--Build/source/texk/dvipdfm-x/subfont.h31
-rw-r--r--Build/source/texk/dvipdfm-x/system.h40
-rw-r--r--Build/source/texk/dvipdfm-x/t1_char.c1588
-rw-r--r--Build/source/texk/dvipdfm-x/t1_char.h26
-rw-r--r--Build/source/texk/dvipdfm-x/t1_load.c1323
-rw-r--r--Build/source/texk/dvipdfm-x/t1_load.h11
-rw-r--r--Build/source/texk/dvipdfm-x/tests/Makefile_upjf20
-rw-r--r--Build/source/texk/dvipdfm-x/tests/UPJF-UTF16-H71
-rw-r--r--Build/source/texk/dvipdfm-x/tests/annot.dvibin0 -> 680 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/annot.tex25
-rw-r--r--Build/source/texk/dvipdfm-x/tests/bookm.dvibin0 -> 1508 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/bookm.tex60
-rw-r--r--Build/source/texk/dvipdfm-x/tests/cmr10.pfbbin0 -> 26882 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/cmr10.tfmbin0 -> 1296 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/dvipdfmx.cfg222
-rw-r--r--Build/source/texk/dvipdfm-x/tests/fullmap.dvibin0 -> 256 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/fullmap.tex7
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ids_2_6.dvibin0 -> 128 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ids_3_2.dvibin0 -> 128 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ids_a_b.dvibin0 -> 128 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/image.bmpbin0 -> 3354 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/image.dvibin0 -> 592 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/image.jp2bin0 -> 2341 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/image.jpegbin0 -> 5778 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/image.pdfbin0 -> 2690 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/image.pngbin0 -> 1436 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/image.tex37
-rw-r--r--Build/source/texk/dvipdfm-x/tests/opc_fe.dvibin0 -> 128 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/paper.dvibin0 -> 260 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/paper.tex6
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picbmp.bb3
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picbmp.xbb4
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picjp2.bb3
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picjp2.xbb4
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picjpeg.bb3
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picjpeg.xbb4
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picpdf.bb3
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picpdf.xbb6
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picpng.bb3
-rw-r--r--Build/source/texk/dvipdfm-x/tests/picpng.xbb4
-rw-r--r--Build/source/texk/dvipdfm-x/tests/psfonts.map1
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ptex.dvibin0 -> 188 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ptx_2_2.dvibin0 -> 188 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ptx_6_6.dvibin0 -> 188 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/resrc.dvibin0 -> 1144 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/resrc.tex6
-rw-r--r--Build/source/texk/dvipdfm-x/tests/rev_2_2.dvibin0 -> 188 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/rev_2_3.dvibin0 -> 188 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/reverse.dvibin0 -> 188 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/test.ttcbin0 -> 45876 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/test_extended_color.tex137
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ttc.dvibin0 -> 620 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/ttc.tex3
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf-g.tfmbin0 -> 368 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf-r.tfmbin0 -> 108 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf.dvibin0 -> 260 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf.map9
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf.tex19
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf.tfmbin0 -> 812 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf_full.cnf13
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf_full.vfbin0 -> 7008 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf_omit.cnf13
-rw-r--r--Build/source/texk/dvipdfm-x/tests/upjf_omit.vfbin0 -> 6972 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/void.dvibin0 -> 104 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/xbmc.dvibin0 -> 252 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/xbmc.tex1
-rw-r--r--Build/source/texk/dvipdfm-x/tests/xbmc10.600pkbin0 -> 11328 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tests/xbmc10.tfmbin0 -> 1328 bytes
-rw-r--r--Build/source/texk/dvipdfm-x/tfm.c1245
-rw-r--r--Build/source/texk/dvipdfm-x/tfm.h57
-rw-r--r--Build/source/texk/dvipdfm-x/truetype.c994
-rw-r--r--Build/source/texk/dvipdfm-x/truetype.h31
-rw-r--r--Build/source/texk/dvipdfm-x/tt_aux.c281
-rw-r--r--Build/source/texk/dvipdfm-x/tt_aux.h33
-rw-r--r--Build/source/texk/dvipdfm-x/tt_cmap.c1773
-rw-r--r--Build/source/texk/dvipdfm-x/tt_cmap.h74
-rw-r--r--Build/source/texk/dvipdfm-x/tt_glyf.c659
-rw-r--r--Build/source/texk/dvipdfm-x/tt_glyf.h58
-rw-r--r--Build/source/texk/dvipdfm-x/tt_gsub.c2021
-rw-r--r--Build/source/texk/dvipdfm-x/tt_gsub.h66
-rw-r--r--Build/source/texk/dvipdfm-x/tt_post.c286
-rw-r--r--Build/source/texk/dvipdfm-x/tt_post.h52
-rw-r--r--Build/source/texk/dvipdfm-x/tt_table.c513
-rw-r--r--Build/source/texk/dvipdfm-x/tt_table.h194
-rw-r--r--Build/source/texk/dvipdfm-x/type0.c363
-rw-r--r--Build/source/texk/dvipdfm-x/type0.h29
-rw-r--r--Build/source/texk/dvipdfm-x/type1.c844
-rw-r--r--Build/source/texk/dvipdfm-x/type1.h31
-rw-r--r--Build/source/texk/dvipdfm-x/type1c.c754
-rw-r--r--Build/source/texk/dvipdfm-x/type1c.h31
-rw-r--r--Build/source/texk/dvipdfm-x/unicode.c258
-rw-r--r--Build/source/texk/dvipdfm-x/unicode.h35
-rw-r--r--Build/source/texk/dvipdfm-x/vf.c572
-rw-r--r--Build/source/texk/dvipdfm-x/vf.h32
-rw-r--r--Build/source/texk/dvipdfm-x/xbb.c422
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-ann.test26
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-bad.test38
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-bb.test67
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-bkm.test26
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-psz.test31
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-ptx.test31
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-res.test26
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-rev.test26
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfm-ttc.test26
-rwxr-xr-xBuild/source/texk/dvipdfm-x/xdvipdfmx.test45
245 files changed, 119663 insertions, 0 deletions
diff --git a/Build/source/texk/dvipdfm-x/AUTHORS b/Build/source/texk/dvipdfm-x/AUTHORS
new file mode 100644
index 00000000000..72116f9121b
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/AUTHORS
@@ -0,0 +1,16 @@
+(This file public domain.)
+
+Principal authors of dvipdfmx: Jin-Hwan Cho, Matthias Franz, and
+Shunsaku Hirata, the dvipdfmx project team.
+
+dvipdfmx was based on dvipdfm, by Mark Wicks,
+Kettering University, Flint, Michigan, USA.
+
+Additional support for xetex (aka xdvipdfmx, .xdv) originally by
+Jonathan Kew and Jin-Hwan Cho, with updates by Khaled Hosny.
+
+Additional CJK and other support from Akira Kakuto, Jiang Jiang,
+Takuji Tanaka, and others.
+
+Other updates by TeX Live developers: Peter Breitenlohner,
+Karl Berry, and others.
diff --git a/Build/source/texk/dvipdfm-x/COPYING b/Build/source/texk/dvipdfm-x/COPYING
new file mode 100644
index 00000000000..60549be514a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog
new file mode 100644
index 00000000000..afb4702b6cc
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/ChangeLog
@@ -0,0 +1,6106 @@
+2021-02-12 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvi.c: Fix a bug (segfault) that current_font is not checked
+ properly when catch_phantom=1.
+ * configure.ac: Version 20210212.
+
+2021-01-31 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_misc.c: Processing of pdffontatrr special should be
+ delayed until the end of the document since the font may not
+ be loaded at the time this special is executed.
+
+2021-01-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvipdfmx.c: Set the runtime flag suppressing error messages
+ for kpathsea library when "-q" option is used.
+ * dvipdfmx.c, xbb.c: Update copyright year.
+ https://tug.org/pipermail/dvipdfmx/2021-January/000216.html
+
+2021-01-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_misc.c: Add a compatibility special pdffontattr.
+ * configure.ac: Version 20210124.
+
+2021-01-22 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cidtype0.c: Fix the VORG bug reported in
+ https://tug.org/pipermail/dvipdfmx/2021-January/000193.html
+ * configure.ac: Version 20210122.
+
+2021-01-16 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfximage.c: Dvipdfmx behavior changed. Now it stops
+ processing and exits with non-zero exit status when image
+ inclusion fails.
+ * dvi.c: Ignore dvi_set with invalid gid when processing DVI
+ files created by dvilua[la]tex.
+ * dvipdfmx.c: Bump copyright year.
+ * configure.ac: Version 20210116.
+
+2021-01-15 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvi.c, dvipdfmx.c, pdfdoc.[ch]: Experimental support for
+ dviluatex extended fnt_def. Separate annot_grow (linkmargin)
+ for horizontal and vertical direction can be specified.
+ * configure.ac: Version 20210115.
+
+2021-01-10 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cmap_read.c, t1_load.c: Fix a bug causing a segfault
+ reported as dvipdfmx-upjf.test test failure. Add missing size
+ tests for the data comparison.
+ https://tug.org/pipermail/tlbuild/2021q1/004765.html
+
+2021-01-09 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cidtype0.c, cidtype2.c, pdffont.[ch], type0.c: Fix a bug
+ that vertical metrics are not written. Introduced in rev.56400.
+ * configure.ac: Version 20210109.
+
+2020-12-16 Karl Berry <karl@freefriends.org>
+
+ * dvipdfmx.c (show_usage): -f loads an additional map file,
+ does not omit loading of default map(s).
+ https://tug.org/pipermail/dvipdfmx/2020-December/000146.html
+
+2020-12-16 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: Fix a bug introduced in rev.56265: When the
+ resource dictionary (of some resource category) is an indirect
+ object and then pdf:put operation is done against that
+ resource category, the operation fails. Now this situation is
+ taken into account. (The content of old resource is merged
+ into new one).
+ * configure.ac: Version 20201216.
+
+2020-12-14 Akira Kakuto <kakuto@w32tex.org>
+
+ * pkfont.c: Fix an incorrect argument for mktexpk.
+ https://tug.org/pipermail/dvipdfmx/2020-December/000142.html.
+ * configure.ac: Version 20201214.
+
+2020-11-11 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_html.c: Fix a bug that html-special was not working
+ after the changes introduced in rev.55722 (pdf:bann accepts a
+ reference ID).
+ * type0.c: Add pseudo-unique tag to ToUnicode CMap name again.
+ * configure.ac: Version 20201111.
+
+2020-10-31 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfximage.c: Fix a bug that mps images are not reused when
+ they are included multiple times. Bug introduced by "Forward
+ reference" support added on 2020-07-21.
+ * configure.ac: Version 20201031.
+
+2020-10-28 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cidtype0.c: Fix a bug that the conditional for deciding if
+ CIDSet should be written is inverted. CIDSet is deprecated in
+ PDF version 2.0.
+ * cidtype2.c, type1.c, type1c.c: Do not write CIDSet and
+ CharSet when the output PDF version is set to 2.0 or higher.
+ * configure.ac: Version 20201028.
+
+2020-10-19 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cidtype0.c, cidtype2.c, type0.c: User defined CID-to-GID
+ PostScript CMap with filename of the form
+ REGISTRY-ORDERING-PSFontName can be loaded (if exist) for
+ mapping CIDs to GIDs. This feature can be used for directory
+ mapping CIDs to GIDs instead of
+ CID -> to-code CMaps -> TrueType cmap -> GID route.
+ * data/Adobe-Japan1-YuMincho-Regular: An example of CID-to-GID
+ CMap file.
+ * configure.ac: Version 20201019.
+
+2020-10-14 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_cmap.c: Fix a bug that checking array indices is wrong.
+ * cidtype2.c: Warning message when CID is mapped to a sequence
+ of several Unicode characters is corrected. Fix a wrong
+ assumption introduced by xdvipdfmx.
+ * configure.ac: Version 20201014.
+
+2020-10-08 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvi.c: Fix problems introduced by the changes on 2020/10/03.
+ Fix a possible problem of invalid access. Fix a problem that
+ non-BMP characters are not handled properly for the "unicode"
+ encoding.
+ * spc_pdfm.c: pdf:bcolor and pdf:scolor accept both fill and
+ stroke color specified at the same time. Change the behavior
+ when an indirect object is specified for pdf:pageresources.
+ * configure.ac: Version 20201008.
+
+2020-10-06 Akira Kakuto <kakuto@w32tex.org>
+
+ * spc_dvips.c: Add an option -dALLOWPSTRANSPARENCY in
+ GS_CALCULATOR to obtain correct results in PSTrics for XeTeX
+ in the case of newer Ghostscript such as gs-9.53.3.
+ Reported in
+ https://tug.org/pipermail/dvipdfmx/2020-October/000109.html
+
+2020-10-06 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvipdfmx.c: Fix a bug that printing output file name is wrong.
+ * dvi.c: Change XeTeX font handling. Convert glyph metrics to
+ an internal format at load time. Don't interpret type1
+ CharStrings again and again.
+ * configure.ac: Version 20201006.
+
+2020-10-05 Karl Berry <karl@tug.org>
+
+ * man/dvipdfmx.1: update date.
+
+2020-10-05 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * man/dvipdfmx.1: Fix a problem in the man page as reported in
+ https://tug.org/pipermail/dvipdfmx/2020-October/000107.html.
+
+2020-10-03 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cid.c, cid.h: Add "const" attribute to arguments fontmap_rec
+ and fmap_opt.
+ * cmap.c: Correct calculation of min-bytes and max-bytes. Fix
+ indentation.
+ * dvi.c, mpost.c, pdfdev.[ch], pdffont.[ch]: Simplify input
+ text handling. The "mapc" option is handled in dvi.c.
+ * configure.ac: Version 20201003.
+
+2020-09-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c: Fix a bug that the max number of indirect objects
+ is wrongly set, causing a problem when too many indirect
+ objects are created.
+ * pdflimit.h: Add PDF_NUM_INDIRECT_MAX indicating the maximum
+ number of indirect objects which can be allocated as described
+ in PDF Ref. v.1.7 and ISO 32000-1.
+ * configure.ac: Version 20200926.
+
+2020-09-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdffont.c: Fix a bug introduced by the recent font related
+ changes which can cause a problem when there is a font
+ defined but not used.
+ * configure.ac: Version 20200924.
+
+2020-09-22 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cid.[ch], cidtype0.[ch], cidtype2.[ch], pdfdev.c,
+ pdffont.[ch], pkfont.[ch], truetype.[ch], type0.[ch],
+ type1.[ch], type1c.[ch]: Revise font related code and largely
+ simplify it. Type0 and CIDFont now use the same struct as
+ simple fonts.
+ * Makefile.am, cid_p.h: Remove cid_p.h.
+ * pdfdraw.[ch]: Fix a bug in calculation of determinant.
+ Enable few functions for future improvement.
+ * dpxutil.c: Fix a bug in the roll operation.
+ * configure.ac: Version 20200922.
+
+2020-09-07 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_misc.c: Fix a bug that the upper limit of stack id is wrong.
+ * Update copyright years and README. Remove outdated
+ information from README.
+
+2020-09-06 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: pdf:bcolor and pdf:scolor now accept new
+ keywords "fill" and "stroke" to indicate either of fill/stroke
+ color is specified.
+ * spc_misc.[ch], specials.[ch]: New special commands for
+ pdfcolorstack are added. This is a compatibility feature to
+ pdfcolorstack in pdftex.
+ * configure.ac: Version 20200906.
+
+2020-09-05 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: Workaround for an issue that occurs when an
+ indirect object (object reference) is used for a resource
+ dictionary entry in pdf:put command. The content of an already
+ existing resource dictionary is copied to the new dictionary.
+ * pdfobj.c, pdfdoc.c: pdf_indirect stores a pointer to the
+ object itself but there is no way to know if the object is
+ released. This can result in using junk pointers. To resolve
+ this issue, a list is added to record released indirect objects.
+ * configure.ac: Version 20200905.
+
+2020-09-02 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfnames.c: Fix an incompatible behavior introduced by the
+ previous changes on the named object (rev.55887).
+ * configure.ac: Version 20200902.
+
+2020-08-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: Fix a bug exposed by the previous changes on the
+ named object (rev.55887). Remove unnecessary spc_flush_object.
+ * configure.ac: Version 20200826.
+
+2020-08-16 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dpxutil.[ch]: Add stack operation.
+ * epdf.[ch], pdfdraw.[ch]: Revise Clip path support for PSTricks.
+ Revert changes related to "rectadd" introduced in rev.31262
+ and rev.31302 which cause non-conforming behavior in "clip"
+ operatation.
+ * dvi.[c], mpost.c, pdfdev.[ch], pdfdoc.[ch], pdfdraw.[ch],
+ spc_html.c, spc_misc.c. spc_pdfm.c, spc_xtx.c, specials.[ch]:
+ Revise bcontent support. Try to resolve various inconsistent
+ behaviors when special commnads are used within pdf:bcontent
+ and pdf:econtent. dev_coords and pt_fixee are removed from pdf
+ module and moved to specials.c.
+ * mpost.h, spc_html.h, spc_misc.h, spc_pdfm.h, spc_xtx.h:
+ Update copyright years.
+ * configure.ac: Version 20200816.
+
+2020-08-08 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * fontmap.[ch], pdffont.[ch], tt_aux.[ch], tt_cmap.[ch]:
+ Use uint32_t for TTC index.
+
+2020-07-31 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cid.c: Avoid accessing array elements exceeding max array index.
+ * spc_pdfm.c: Check array elements also for to-unicode conversion.
+ * tt_cmap.c: Additional changes are required for the previous CMap name fix.
+
+2020-07-29 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: Improve codes in unicode conversion and
+ annotation rect calculation.
+ * spc_xtx.c: Add missing reset_xgstate().
+ * tt_cmap.c: Add wmode to auto-generated CMap names.
+
+2020-07-28 Clerk Ma <maqiyuan130324@vip.qq.com>
+
+ * pdfobj.c: Simple modifications for LIBDPX.
+
+2020-07-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cmap_write.c: Change ariable names.
+ * dvipdfmx.c: Remove unused variables. Modify init sequence.
+ Page size specified as a command line option overwrites
+ settings specified by pagesize specials.
+ * pdfdev.[ch], pdfdoc.[ch], pdfencrypt.[ch], pdfobj.[ch]:
+ File static variables are now placed in a single struct.
+ * pdfparse.[ch], spc_pdfm.c: PDF parse object function is
+ called with a callback function to be called when an object of
+ unknown type is encountered.
+ * pdfximage.c: Do not include an unnecessary file.
+ * dpxconf.[ch], xbb.c: Add is_xbb in dpx_conf.
+ * dpxutil.[ch], dvi.c, dvipdfmx.c: Add dpx_util_read_length().
+ * configure.ac: Version 20200726.
+
+2020-07-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cidtype0.c: Fix a bug introduced in rev.37144 that generated
+ CIDType0 font file is corrupt when the "force fixed-pitch"
+ option is enabled.
+ * pdfximage.c: "filename" was wrongly used for cached converted
+ PS images.
+
+2020-07-21 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdoc.[ch], pdfnames.[ch], pdfobj.c, pdfximage.[ch],
+ spc_dvips.c, spc_html.c, spc_misc.c, spc_pdfm.c, specials.c:
+ "Forward reference" of image objects is also supported.
+ Object reference by name is now available globally but not
+ only for the "special" module.
+ * configure.ac: Version 20200721.
+
+2020-07-19 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdraw.c: Avoid invoking gs operation for an empty ExtGState.
+
+2020-07-18 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvipdfmx.c, pdfximage.[ch]: Don't call ordinary functions
+ such as pdf_close_images() which can call ERROR() in
+ error_cleanup(). This can result in a recursive call of
+ error_cleanup().
+
+2020-07-11 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdev.c, pdfdoc.c, pdfdraw.[ch], pdfobj.[ch], spc_pdfm.c:
+ ExtGState can be manipulated with a dedicated stack.
+ Add new specials pdf:bxgstate and pdf:exgstate to push/pop
+ ExtGState into/from the stack.
+ * pdfcolor.c: Fix a bug that assignment was missing
+ in pdf_color_compare().
+ * configure.ac: Version 20200711.
+
+2020-07-04 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfcolor.c, spc_util.c: Fix a bug in pdfcolor.c.
+ Add initialization of a variable and NULL pointer check.
+ * configure.ac: Version 20200704.
+
+2020-07-02 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdoc.c, spc_pdfm.c: Possible fix for a bug that pdf:btrans
+ inside pdf:bcontent and pdf:econtent does not work correctly.
+ Extend pdf:bann to accept a reference ID which can be used
+ later to refer the annotation dictionary object. When
+ line-breaks occur, it just points to the first annotation
+ dictionary of the line-breaking annotation series.
+
+2020-06-28 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvi.[ch], spc_dvipdfmx.c, spc_pdfm.c, specials.[ch]: Two new
+ special commands added as workarounds for \phantom text issue
+ in creating annotation (link). "pdf:xann" which extends the
+ current annotation area by a specified amount.
+ "dvipdfmx:catch_phantom" to control the behavior of dvipdfmx,
+ when this is set to true, then dvipdfmx extends the annotation
+ area when it encounters "horizontal movement" such as DVI
+ "right". Optionally height and depth of such area can be
+ specified (default: current font size for height and depth 0).
+ * pdfcolor.c: Change prefix for ColorSpace resource name to "XC".
+ * pdfdoc.c: Add missing release object.
+
+2020-06-27 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfcolor.[ch], pdfdoc.c, pdfdraw.c, spc_util.c: An extension
+ to the color support. All color-spaces can be supported (only
+ for pdf: color commands). ColorSpace can be specified by a
+ name key (e.g. DeviceRGB) or an object reference which is a
+ reference to an object defining ColorSpace itself.
+ * configure.ac: Version 20200627.
+
+2020-06-24 Akira Kakuto <kakuto@w32tex.org>
+
+ * dpxfile.c, pdfximage.c: Remove unnecessary changes on
+ 2020-06-22.
+
+2020-06-22 Akira Kakuto <kakuto@w32tex.org>
+
+ * dvipdfmx.c: Move dpx_delete_old_cache(image_cache_life)
+ because image caching did'nt work.
+ * dvi.c: Use MFOPEN() instead of fopen().
+ * dpxfile.c, pdfximage.c: Use generalized stat() to handle
+ UTF-8 names (Windows only).
+
+2020-06-21 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_cmap.c: Lower priority for Soft-hyphen U+00AD when
+ generating ToUnicode CMap.
+ * tt_cmap.c, type1c.c: Cause an error when "CFF " table is not
+ found. (Possibly due to variable font which uses unsupported
+ "CFF2" table)
+
+2020-06-09 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * pdfdev.c: Another workaround for fake-bold issue.
+ (See changes 2019-06-30 and 2020-02-29)
+
+2020-05-26 Akira Kakuto <kakuto@w32tex.org>
+
+ * dvi.c: Introduce rgba_used in order to indicate that
+ rgba_color for a XeTeX font is used or not. It enables full
+ range of opacity, 0-255.
+ * configure.ac: Version 20200526.
+
+2020-05-10 TANAKA Takuji <ttk@t-lab.opal.ne.jp>
+
+ * vf.c: reduce message by '-v' less than by '-vv' for
+ fallback of virtual fonts.
+
+2020-05-03 TANAKA Takuji <ttk@t-lab.opal.ne.jp>
+
+ * dvipdfmx-upjf.test, Makefile.{am,in},
+ tests/Makefile_upjf, tests/upjf{,-r,-g}.tfm,
+ tests/upjf.{tex,dvi,map}, tests/upjf_{full,omit}.vf,
+ tests/upjf_{full,omit}.cnf, tests/UPJF-UTF16-H:
+ Add a new test for fallback of virtual fonts.
+ * vf.c: Tweak debugging message for fallback of virtual fonts.
+
+2020-03-27 Karl Berry <karl@tug.org>
+
+ * TeX Live 2020.
+
+2020-03-15 TANAKA Takuji <ttk@t-lab.opal.ne.jp>
+
+ * tfm.c, tfm.h, vf.c: Fallback multibyte character
+ in virtual font for (u)pTeX.
+ * configure.ac: version 20200315.
+ https://github.com/texjporg/tex-jp-build/issues/99
+
+ A new rule for virtual fonts is implemented:
+ If a virtual font has no entry of a codepoint and the first
+ MAPFONT designates a (u)pTeX TFM(JFM), then we designate the
+ glyph (usually with a fullwidth metric) of the same codepoint
+ in the TFM(JFM) with the smallest font ID.
+ The new rule helps to shrink size of Japanese virtual fonts.
+
+2020-02-29 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * pdfdev.c: Revert the commit on 2019-06-30: see
+ https://tug.org/pipermail/tex-live/2020-February/044855.html.
+ Note that the problem with fake-bold reappears!
+ https://tug.org/pipermail/dvipdfmx/2019-June/000014.html.
+
+2020-02-12 Akira Kakuto <kakuto@w32tex.org>
+
+ * dvipdfmx.c: Fix a potential bug in set_default_pdf_filename().
+ see https://tug.org/pipermail/tex-live/2020-February/044731.html
+
+2020-02-06 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c: In pdf_new_string(), the supplied string was
+ checked and dvipdfmx aborted when it was NULL. This check
+ is removed since it is actually not necessary. The string is
+ regarded simply as an empty string if it is NULL from now on.
+ See https://tex.stackexchange.com/questions/522794/problem-in-updated-tex-live,
+ although we can't reproduce the problem.
+ * spc_pdfm.c: Add two pdftex specials which are basically
+ similar to the existing dvipdfmx special "pdf:literal",
+ "pdf:page:" and "pdf:direct:". It is not possible to test
+ properly since exact spec is unknown to us. Currently,
+ "pdf:direct:" is just an alias of "pdf:page:". It cannot be
+ properly implemented at present.
+
+2020-01-24 Akira Kakuto <kakuto@w32tex.org>
+
+ * dvi.c: Forgot to null-terminate strings in the previous
+ changes.
+
+2020-01-22 Akira Kakuto <kakuto@w32tex.org>
+
+ * dvi.c: Correct wrong sizes of opassword and upassword
+ in scan_special_encrypt().
+
+2020-01-16 Karl Berry <karl@freefriends.org>
+
+ * xbb.c (show_version),
+ * dvipdfmx.c (show_version): copyright 2020.
+ * configure.ac: version 20200116 for TL'20.
+
+2019-11-14 Akira Kakuto <kakuto@w32tex.org>
+
+ * mt19937ar.c: Add to support common font names in all
+ platforms when SOURCE_DATE_EPOCH is suitably set. A pseudo
+ random number generating program coded by Takuji Nishimura and
+ Makoto Matsumoto.
+ * README: Add a subject "11. Random number generating function".
+ * mem.h: Add "#define srand(x) init_genrand((x))", etc. because
+ it is the only common header file for dpxcrypt.c, pdfencrypt.c,
+ and pdffont.c, which use rand().
+ * Makefile.am: Add mt19937ar.c.
+ * configure.ac: Version 20191114.
+
+2019-11-13 Akira Kakuto <kakuto@w32tex.org>
+
+ * spc_dvips.c: Add -dDELAYSAFER in GS_CALCULATOR because
+ SAFER mode became the default in the gs-9.50.
+
+2019-09-08 Akira Kakuto <kakuto@w32tex.org>
+
+ * dvi.c: Show appropriate message if unsupported pfa
+ is used. Reported in
+ https://tug.org/pipermail/dvipdfmx/2019-September/000031.html.
+
+2019-08-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dpxutil.c: Timezone offset is incremented by 1 hour if
+ tm_isdst > 0, as suggested in
+ https://tug.org/pipermail/dvipdfmx/2019-July/000017.html
+ * pdfcolor.c: Always output color change instruction when color
+ push/pop is invoked. Fix for the issue reported in
+ https://tug.org/pipermail/dvipdfmx/2019-August/000029.html
+ * configure.ac: Version 20190824.
+
+2019-08-17 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdoc.c, spc_pdfm.c: Workaround for some problems reported
+ in https://tug.org/pipermail/dvipdfmx/2019-August/000021.html.
+ Try to deref page resource dictionary when adding page resources.
+ Allow direct objects for page resources.
+ * configure.ac: Version 20190817.
+
+2019-08-05 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c: Ignore zlib error while uncompressing data.
+ Z_DATA_ERROR is ignored when avail_in is 0.
+ Accepting some incorrectly written compressed data.
+ Reported by Jens Adam:
+ https://tug.org/pipermail/tex-live/2019-August/043983.html
+ * dvipdfmx.c: Fix a bug that 'm' option was broken.
+ This option must be processed before dvi_init().
+ Bug reported to TUG mailing list:
+ https://tug.org/pipermail/dvipdfmx/2019-July/000019.html
+ * configure.ac: Version 20190805.
+
+2019-08-03 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_gsub.c: Fix a bug that OTL coverage data were not read and
+ were initialized to wrong values when LigatureSetCount was 0.
+ Similar issue is found also in alternate substitution.
+ Reported by Jens Adam:
+ https://tug.org/pipermail/tex-live/2019-August/043983.html
+
+2019-06-30 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdev.c: Fix a bug that fake-bold is not handled properly
+ in some situations as reported in
+ https://tug.org/pipermail/dvipdfmx/2019-June/000014.html.
+ When text rendering mode is changed within a text block which
+ is enclosed by q and Q, the change does not affect subsequent
+ text blocks. Current implementation of text handling is not
+ robust so we may need to reconsider it.
+
+2019-06-01 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * unicode.c: Fix a bug that end of buffer check was wrong.
+
+2019-05-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cmap_write.c, dvipdfmx.c, pdfdev.c, pdfdev.h, pdfdoc.c
+ spc_dvips.c, spc_pdfm.c, truetype.c, xbb.c:
+ Fix for compiler warnings.
+ * tt_post.c: Add missing "*/" in a deactivated section.
+ * system.h: "pragma warning" only when _MSC_VER is defined.
+
+2019-05-22 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_gsub.c: Fix a bug that otl_gsub_read_alternate() and
+ otl_gsub_read_ligature() exit loops wrongly for erroneous
+ data, which leads to uninitialized values.
+ Reported by Chih-Hsuan Yen:
+ https://tug.org/pipermail/dvipdfmx/2019-May/000004.html.
+ * configure.ac: Version 20190522.
+
+2019-05-08 Akira Kakuto <kakuto@w32tex.org>
+
+ * dpxfile.c: Avoid buffer overflow.
+
+2019-05-08 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: Transformation also applies to annotations
+ created by pdf:ann.
+
+2019-05-07 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_cmap.c: Fix a bug that CFF charset data were not read.
+ * unicode.c: Fix a bug that end-of-buffer calculation was
+ wrong.
+
+2019-05-05 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdoc.c: g option affects only annotations created by
+ "pdf:bann/eann" and html "a link" specials.
+ Report from Joseph Wright:
+ https://tug.org/pipermail/tex-live/2019-May/043612.html
+
+2019-05-03 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * specials.c: transformation applied to current point was not
+ done properly.
+
+2019-05-03 Akira Kakuto <kakuto@w32tex.org>
+
+ * dpxfile.c, mfileio.h, pdfximage.c: Support non-ascii file
+ names in default code page of OS irrespective of values of a
+ variable 'command_line_encoding' (Windows only).
+
+2019-05-03 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c, pdfobj.h: Add support for ASCIIHex and ASCII85
+ decode filter. Support for decoding stream data with multiple
+ filters applied. Remove unused function.
+ * tt_cmap.c, tt_gsub.[ch]: Revise ToUnicode CMap creation for
+ OpenType. Use GSUB for mapping unencoded glyphs to Unicode
+ (XeTeX support), lowering priority of CJK compatibility
+ ideographs.
+ * configure.ac: Version 20190503.
+
+2019-04-07 Karl Berry <karl@freefriends.org>
+
+ * TeX Live 2019.
+
+2019-04-01 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfencoding.c: Fix a bug that dvipdfmx wrongly tries to
+ create ToUnicode CMap even when there is no valid mapping
+ entry. It just results in "Invalid CMap" warning.
+
+2019-03-30 Akira Kakuto <kakuto@w32tex.org>
+
+ * spc_xtx.c: "ap->curptr" was copied to "buffer" without
+ length validation. Fix this security problem.
+ * spc_pdfm.c: "ap->curptr" was copied to "buffer" without
+ length validation. Fix this security problem.
+ * specials.c: Error message was written using vsprintf(),
+ which has no length limitation. Use vsnprintf() instead.
+
+ Report from Andy Nguyen of ETH Zurich.
+
+2019-03-05 Clerk Ma <maqiyuan130324@vip.qq.com>
+
+ * tt_table.c: Fix 'null character(s)' warning caused by
+ fonts like Roboto (Android) or YuMincho (Windows 10).
+
+2019-02-25 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * tt_cmap.c (is_PUA_or_presentation):
+ Skip also CJK Radicals Supplement, to lower the priority for
+ double encoded glyphs. This does not break tounicode entries
+ for glyphs which are only encoded in this region.
+
+2019-02-25 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_post.c: Since OpenType ver. 1.7, PostScript glyph names
+ more than 32767 are allowed for version 2.0 post table. Some
+ minore fixes in chek of valid index range.
+ * configure.ac: Version 20190225.
+
+2019-02-23 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * tt_post.c (tt_lookup_post_table): Fix a bug that the loop
+ exceeds post->numberOfGlyphs (= the size of post->glyphNamePtr).
+ https://github.com/texjporg/tex-jp-build/issues/74
+
+2019-02-11 Karl Berry <karl@tug.org>
+
+ * configure.ac,
+ * dvipdfmx.c: copyright 2019.
+
+2019-02-10 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * cidtype0.c, cidtype2.c: Fix typo.
+
+2019-01-27 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: Suppress a warning in tounicode special.
+ Dvipdfmx had been giving a wrong warning when an optional
+ argument to tounicode special is not supplied.
+
+2018-12-27 Clerk Ma <maqiyuan130324@vip.qq.com>
+
+ * pdfobj.c: Introduce a static variable pdf_output_file_stats
+ for LIBDPX. It does not affect (x)dvipdfmx.
+
+2018-12-21 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvi.[ch], dvipdfmx.c, pdfdoc.[ch], pdfencrypt.[ch],
+ spc_pdfm.c: Add a new special pdf:trailerid for directly
+ specifying trailer ID.
+ * spc_tpic.c, tfm.c, tt_gsub.c: Avoid compiler warning.
+ * configure.ac: Version 20181221.
+
+2018-10-12 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvipdfmx.c: Fix a bug that landscape option is not handled
+ properly.
+ * configure.ac: Version 20181012.
+
+2018-10-08 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * mpost.c: Fix a bug in inline PS code handling.
+ * dpxfile.c, pdfencrypt.c, type0.c: Avoid compiler warnings.
+ * pdfobj.c: Fix a bug in (unused) TIFF predictor code.
+ * configure.ac: Version 20181008.
+
+2018-10-07 Simon Cozens <simon@simon-cozens.org>
+
+ * pdfobj.c: Clear static variables to allow PDF funcfions to
+ be used more than once.
+
+2018-10-02 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvipdfmx.c: Fixed a bug in handling of command line option '-M'.
+ * mpost.c: Fixed a bug in MetaPost generated PS files.
+ Font selection had not been properly done for gsave/grestore.
+ * configure.ac: Version 20181002.
+
+2018-09-16 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvi.[ch], dvipdfmx.c: Fixed a bug that papersize special does
+ not work (introduced in the previous change). Command line
+ options other than papersize now take precedence over special
+ command options.
+ * dpxconf.[ch], tt_aux.c: Moved always_embed flag to dpx_conf.
+ * pdfencrypt.c: Fixed a bug that calculation of encryption key
+ was not done properly for RC4 and revision 2-3 AES security.
+
+2018-09-16 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dpxutil.[ch], dvi.[ch], dvipdfmx.c, pdfdoc.[ch], pdfencrypt.[ch],
+ pdffont.[ch], xbb.c: Remove duplicated code. Reorganize
+ initialization process. Use struct for passing options.
+ * configure.ac: Version 20180916.
+
+2018-09-14 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * agl.[ch], bmpimage.c, cid.[ch], cidtype0.[ch], cidtype2.[ch],
+ cmap.[ch], cmap_read.c, dpxconf.[ch], dpxfile.[ch], dvi.[ch],
+ dvipdfmx.[ch], epdf.c, fontmap.[ch], jp2image.c, jpegimage.c,
+ mpost.[ch], pdfcolor.[ch], pdfdev.[ch], pdfdoc.[ch], pdfdraw.c,
+ pdfencoding.[ch], pdfencrypt.[ch], pdffont.[ch], pdfobj.[ch],
+ pdfximage.[ch], pngimage.c, spc_pdfm.c, spc_util.[ch],
+ specials.[ch], subfont.[ch], t1_char.c, tfm.[ch], truetype.c,
+ tt_aux.[ch], tt_cmap.[ch], tt_gsub.[ch], type0.[ch], type1.c,
+ type1c.c, vf.[ch], xbb.c: Cleanup. Remove duplicated code.
+ Reorganize global variables.
+ * configure.ac: Version 20180914.
+
+2018-09-09 Karl Berry <karl@tug.org>
+
+ * xdvipfm-bb.test: LC_ALL=LANGUAGE=C.
+
+2018-09-06 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfencoding.c: Reverted change made for 20071115.
+ ToUnicode creation for simple font was broken. Not working
+ as intended at all.
+ * pdfdoc.c, epdf.c, pdffont.c: Rearranged code.
+ * pdfobj.c: Added some debugging code.
+ * configure.ac: Version 20180906.
+
+2018-09-04 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c: More fix on circular reference issue.
+ * configure.ac: Version 20180904.
+
+2018-09-02 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvi.c: Experimental support for XeTeX transparency font feature.
+ * cid.c, cid_p.h, cidtype0.c, cmap.[ch], cmap_p.h, fontmap.[ch],
+ pdfdev.c, pdffont.c, tt_cmap.[ch], type0.c:
+ Removed reverse CMap mappings. Do not use cff charset data
+ directly in pdfdev. Using reverse CMap for ToUnicode creation
+ causes problems since input CMap can not be assumed to be
+ always Unicode. Also, current implementation is imcomplete.
+ * configure.ac: Version 20180902.
+
+2018-08-28 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * otl_conf.[ch]: Removed. This undocumented feature is no
+ longer used.
+ * Makefile.am: Update for otl_conf.[ch] removal.
+
+2018-08-27 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * jpegimage.c: Do not write application specific markers which
+ are not necessary for displaying images.
+ * pdfencrypt.c: Set a compatibility flag bit for PDF 2.0.
+ * spc_pdfm.c: Fixed a bug that string objects are not handled
+ properly in pdf:stream special. Additional dictionay keys can
+ be specified for tounicode conversion.
+ * configure.ac: Version 20180827.
+
+2018-08-23 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * type1.c: Add glyph names of component glyphs used by seac
+ operator to CharSet string.
+ * configure.ac: Version 20180823.
+
+2018-08-21 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c: Fix for "infinite loop" detection. Now handles the
+ case of circular reference properly.
+ * pdfencrypt.c: Fixed bug that key size is not adjusted
+ correctly.
+ * configure.ac: Version 20180821.
+
+2018-08-18 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cidtype2.c: Workaround for CIDSet issue. All glyphs
+ including component glyphs and dummy glyphs except .notdef
+ should be listed in CIDSet.
+
+2018-08-17 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cmap_write.c, tt_cmap.[ch], type0.c: Fixed a bug that
+ CMapName in CMap resource is not properly written.
+ Not correctly handles PostScript name and string objects.
+ Use CMapName constructed from font's BaseFont entry.
+ * spc_pdfm.c, spc_pdfm.h, specials.c: Added new special command
+ pdf:pageresources similar to pdfTeX \pdfpageresources
+ primitive.
+ * pdfencrypt.c: Adobe extension for AES 256-bit encryption is
+ not necessary for PDF version 2.0.
+
+2018-05-23 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c: First search for an input file with a suffix .xdv
+ or .dvi. Report from Andreas Scherer:
+ http://tug.org/pipermail/tex-k/2018-May/002882.html.
+
+2018-05-16 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfparse.c: Revert. The changes on 2018-05-14 must be
+ problematic. Again, kanji characters including 0x5c can't be
+ used as names of image files in (e)-pTeX.
+
+2018-05-14 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfparse.c: Allow image file names including 0x5c for
+ (e)-pTeX in CP932-like system (Windows only).
+
+2018-05-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * tt_cmap.c: Revert a part of changes in 2017-12-09,
+ which breaks to give tounicode entries for ligatures.
+ http://tug.org/pipermail/tex-live/2018-May/041608.html.
+ * configure.ac: Version 20180506.
+
+2018-04-28 Stefan Br\"uns <stefan.bruens@rwth-aachen.de>
+
+ * pngimage.c: Fix a bug which causes a segfault with 1/2/4-bit
+ transparent indexed PNGs.
+ * configure.ac: Version 20180428.
+
+2018-03-03 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * xbb.c: Remove unused lines.
+
+2018-03-02 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * epdf.c, pdfobj.c, pdfobj.h: Remove multiple warnings.
+
+2018-03-01 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * pdfobj.c: Fix typo and improve a warning (incomplete fix).
+
+2018-02-17 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cid.c, dpxfile.[ch], dvipdfmx.c, epdf.c, jp2image.c,
+ jpegimage.c, pdfcolor.c, pdfencoding.c, pdfencrypt.c,
+ pdflimits.h, pdfobj.[ch], pdfximage.c, pngimage.c,
+ spc_dvips.c, spc_pdfm.c, spc_tpic.c, type0.c, xbb.c:
+ Accept PDF version tag 2.0.
+ * numbers.[ch], tfm.c: Remove format specific number
+ representation from numbers.[ch].
+ * configure.ac: Version 20180217.
+
+2018-01-27 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * tfm.c, number.[ch]: Support new JFM spec (3-byte characters
+ in TYPE > 0).
+
+2017-12-21 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * jpegimage.c: If j_info->xdpi and j_info->ydpi are not
+ determined in JPEG_scan_file(), they are assumed to be 72.0.
+
+2017-12-09 Jiang Jiang <gzjjgod@gmail.com>
+
+ * tt_cmap.c (is_PUA_or_presentation, add_to_cmap_if_used):
+ Skip KANGXI RADICALs which are commonly double encoded.
+ http://tug.org/pipermail/xetex/2017-June/027147.html
+
+2017-10-02 Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
+
+ * dvi.c: Initialize direction mode in clear_state(). See
+ https://github.com/texjporg/tex-jp-build/issues/30
+
+2017-09-18 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_gsub.c: Fixed a bug that only last specified OTL GSUB
+ feature was enabled.
+ * configure.ac: Version 20170918.
+
+2017-08-25 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfximage.h, spc_pdfm.c: Remove MAX_IMAGES which is not
+ needed.
+
+2017-08-06 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dpxutil.[ch], epdf.c, pdfdoc.[ch], pdfximage.c, xbb.c:
+ Support for /Rotate page attribute in PDF inclusion.
+ * configure.ac: Version 20170806.
+
+2017-06-27 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfdoc.c: Simplify the change in pdf_doc_get_page().
+ * configure.ac: Change version number to distinguish from TL 2017.
+
+2017-06-25 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfdoc.c: Discard the backward compatibility for pdf BoundingBox
+ in pdf_doc_get_page(), to be consistent with the latex
+ driver dvipdfmx.def.
+
+2017-06-25 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_cmap.c: Fix a bug that different CMaps are not attached
+ to each instances of font using different OpenType layout features.
+ Fix a bug that ToUnicode support for substituted glyph was incomplete.
+
+2017-06-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_pdfm.c: Remove unused variable attr in spc_handler_pdfm_image().
+
+2017-05-19 Karl Berry <karl@tug.org>
+
+ * Version 20170318 for TeX Live 2017 release.
+
+2017-05-08 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfdraw.c: Replace a small number 1.0e-8 by OUR_EPSILON = 2.5e-16,
+ responding incompletely to
+ http://tug.org/pipermail/tex-live/2017-May/040090.html.
+
+2017-04-26 Paul Vojta <vojta@math.berkeley.edu>
+
+ * dvi.c, dvipdfmx.c, spc_html.c, spc_util.c: Support additional
+ length units.
+
+2017-04-16 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_cmap.c: Fix a bug that generation of GID to CID mapping for
+ format 2 CFF charsets was wrong. "unicode" encoding support was
+ broken for fonts using this format.
+
+2017-04-15 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * fontmap.c, tt_cmap.c, tt_gsub.c, tt_gsub.h, pdffont.c: Removed
+ undocumented OpenType Layout GSUB support. Added simplified version of
+ OpenType Layout GSUB support. Fontmap option "-l otl_tags" enables
+ OpenType GSUB features specified by otl_tags, where otl_tags is a ":"
+ separated list of OpenType Layout feature tags
+ (or strings of script.language.feature form).
+
+2017-04-12 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: Fix a bug in static const char *optstrig.
+
+2017-04-09 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_cmap.c: Vertical writing support had been broken since at some
+ point of xdvipdfmx merge for "unicode" encoding. Apply vert/vrt2 GSUB
+ feature when generating Unicode mapping.
+
+2017-03-18 Karl Berry <karl@tug.org>
+
+ * xbb.c: update copyright years.
+
+ * xdvipdfm-bb.test: remove any ^%%Creat line, not just %%CreationDate.
+ * tests/*.[x]bb: remove %%Creator: lines since they embed version.
+
+2017-03-18 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Bump version to 20170318 for TeX Live 2017.
+
+2017-03-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: Command line -p option wins papersize and pagesize
+ specials, as dvips.
+
+2017-02-17 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c: Add possibly forgotten braces.
+
+2017-01-24 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * jpegimage.c: Support Exif tags 0x5110, 0x5111, and 0x5112 in order to
+ avoid warnings for some kind of jpeg images. Changes are borrowed from
+ writejpg.w by Luigi in the recent LuaTeX.
+
+2016-12-29 Hironobu Yamashita <h.y.acetaminophen@gmail.com>
+
+ * cid_basefont.h: Add data for STHeiti-Regular-Acro, and correct
+ several data.
+
+2016-12-18 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c, dvi.h, dvipdfmx.c, mpost.c, pdfencoding.c, pdfobj.c,
+ pdfparse.c, pdfparse.h, tt_cmap.c, type0.c, type1.c, vf.c, xbb.c:
+ Merge libdpx by Clerk Ma at https://github.com/clerkma/ptex-ng.
+
+2016-10-30 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdffont.c, pdfobj.h: Use (time_t)-1 for INVALID_EPOCH_VALUE.
+
+2016-10-05 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxfile.c: Use PATH_MAX instead of _MAX_PATH.
+
+2016-10-03 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxfile.c: Sync with MikTeX.
+
+2016-06-25 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ Modify to make PDF/A generation a bit easier.
+ * pdfobj.c: Do not compress XMP Metadata.
+ * cidtype2.c, type1.c, type1c.c: Always write CIDSet for CIDType2 and
+ CharSet for Type1 font. Check consistency of glyph width.
+
+2016-06-19 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvipdfmx.c: Disable overriding "D" option setting from
+ dvipdfmx:config special.
+ * configure.ac: Change version from 20160307 to 20160619 in order to
+ distinguish the new one from that in TeX Live 2016.
+
+2016-05-20 Karl Berry <karl@tug.org>
+
+ * Version 20160307 for TeX Live 2016.
+
+2016-05-10 Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
+
+ * cidtype2.c: Fix bugs in horizontal-vertical mixed scripts by
+ TrueType fonts.
+
+2016-05-08 Masamichi HOSODA <trueroad@trueroad.jp>
+
+ * dvi.c, dvipdfmx.c, dvipdfmx.h, special.c: Add new specials to handle
+ command line options.
+ * spc_dvipdfmx.c, spc_dvipdfmx.h: Add for the new specials.
+ * Makefile.am, Makefile.in: Change for the added spc_dvipdfmx.c,
+ and spc_dvipdfmx.h.
+
+2016-05-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdffont.c: Avoid to crash for too large a value of SOURCE_DATE_EPOCH.
+ (w32 only).
+
+2016-05-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfdoc.c, pdfencrypt.c, pdffont.c, pdfobj.h, xbb.c: Improve the
+ support of SOURCE_DATE_EPOCH.
+
+2016-05-02 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfdoc.c, xbb.c: Apply the patch by Alexis,
+ http://tug.org/pipermail/tex-live/2016-May/038339.html
+ for the support of SOURCE_DATE_EPOCH.
+ * pdfencrypt.c: Use gmtime instead of localtime if SOURCE_DATE_EPOCH
+ is given, to be consistent with the patch by Alexis.
+
+2016-03-07 Karl Berry <karl@tug.org>
+
+ * man/dvipdfmx.1: .B not .b.
+ Report on tex-k from esr, 29 Feb 2016 12:30:31.
+
+2016-03-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * configure.ac, tests/*.[bb,xbb]: Update version number to 20160307
+ for TeX Live 2016.
+
+2016-03-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c, dvipdfmx.h, mpost.c: Introduce a new option --mvorigin.
+ The translation of the origin in MP inclusion by using dvipdfmx.def
+ or xdvipdfmx.def is enabled only if the option --mvorigin is set.
+
+2016-02-25 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: Change the default value of pdfdecimaldigits from 2
+ to 3, to be consistent with pdfTeX.
+
+2016-02-24 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfdoc.c, pdfencrypt.c, pdffont.c, pdfobj.h, xbb.c: Support to output
+ a unique pdf file from a unique xdv/dvi file. If an environment
+ variable SOURCE_DATE_EPOCH is defined correctly like
+ SOURCE_DATE_EPOCH=1456304783, the value is used as the current time,
+ and if the name of the output pdf file is the same, its content is
+ exactly unique.
+
+2016-02-23 Masamichi HOSODA <trueroad@trueroad.jp>
+
+ * pdfdoc.c: Support UTF-16 with null bytes as labels.
+
+2016-02-23 Jonathan Kew <jfkthame@gmail.com>
+
+ * dvicodes.h, dvi.c, pdfdev.[ch]: Support xetex 0.99995 output
+ (dvi format 7) that includes ActualText content.
+
+2016-02-17 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_pdfm.c: Remaining fix for that on 2016-02-13.
+
+2016-02-13 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_pdfm.c: Remove maybe-redundant code to obtain consistency
+ between dvi (dvipdfmx) and xdv (xdvipdfmx) with respect to
+ \special{pdf:dest...}.
+
+2016-02-09 Jiang Jiang <gzjjgod@gmail.com>
+
+ * dvi.c: Tweak skip_native_font_def() to make it handle more
+ flags.
+ * dpxutil.c: Remove a redundant check found by -Wall.
+
+2016-02-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c: disable check_postamble() introduced by Peter, because
+ features embolden != 0, slant != 0, and extend != 1 do not work.
+
+2016-01-30 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * tt_post.c: Check post->glyphNamePtr[gid] before an access
+ in tt_get_glyphname(). Reported by Werner LEMBERG:
+ http://tug.org/pipermail/tex-live/2016-January/037696.html.
+
+2016-01-19 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxfile.c: Remove trailing directory separators if any in
+ dpx_get_tmpdir().
+
+2016-01-11 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c, mfileio.[ch]: Modification on handling of xref table.
+ More permissive on treating white-spaces but more strict on
+ handling tokens.
+
+2016-01-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * epdf.c: A typo in a message.
+ * xbb.c: Change copyright year.
+ * tests/: Change test data.
+
+2016-01-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * t1_load.c: Avoid to crash for unsupported type1 fonts as native fonts.
+ * configure.ac: version 20160106.
+ * almost all files: change Copyright year.
+
+2016-01-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c: Symplify support of native type1 fonts in XeTeX.
+
+2016-01-03 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxfile.c: Change \ to / for WIN32 also in the case where
+ HAVE_MKSTEMP is defined (win32 only).
+ * cff.h, dvi.c, t1_load.c: Improve the change made on 2015-08-05.
+ The static function static int is_notdef_notzero() in dvi.c is removed.
+
+2015-12-30 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * epdf.[ch], pdfdoc.[ch], pdfximage.[ch],
+ spc_{dvips,html,misc,pdfm,util}.c, spc_util.h: Don't use global variables
+ for selecting boundary box. Cleanups.
+
+2015-12-29 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * dvipdfmx.c, dvi.c: Allow empty password in pdf:encrypt special.
+ * dvipdfmx.c, pdfdoc.[ch], pdfobj.[ch]: Add option to disable Xref
+ stream and object stream.
+
+2015-12-28 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * bmpimage.c, dvipdfmx.c, pdfobj.[ch], pngimage.c: Support for predictor
+ functions for FlateDecode filter. PNG optimal and TIFF2 predictor functions
+ are currently implemented. It solves the preblem that PNG images become
+ sometimes larger in size when embedded in PDF file.
+
+2015-12-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pngimage.c: Workaround for Adobe Potoshop generated PNGs which have
+ cHRM chunk but not gAMA chunk.
+ * agl.c, spc_pdfm.c, unicode.c, unicode.h: Addition of some
+ Unicode related functions. Try conversion to UTF16BE only for string
+ objects which can be considered as a valid Unicode text.
+
+2015-12-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * t1_load.c: Support for get/putinterval and get/put in encoding
+ definition found in some Type1 fonts such as cmctt10.pfb.
+
+2015-11-05 Karl Berry <karl@tug.org>
+
+ * data/dvipdfmx.cfg (D): add -dAutoRotatePages=/None.
+ Suggestion/request from Akira, 4 Nov 2015 22:41:14.
+
+2015-09-27 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: Remove conditional error message in kpathsea_debug,
+ since there should be no errors.
+
+2015-08-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Most .c and .h files: Update Copyright years.
+ Replace '(unsigned) long' by '(unsigned) int' or '(u)int32_t'
+ except when needed with for ftell() and fseek().
+
+2015-08-23 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * agl.[ch], cid.[ch], cidtype0.[ch], cidtype2.[ch], cmap_p.h,
+ cs_type2.[ch], dpxcrypt.[ch], dpxutil.[ch], dvi.c, fontmap.[ch],
+ otl_conf.c, pdfcolor..[ch], pdfdev.h, pdfdoc.c, pdfencoding.c,
+ pdfencrypt.[ch], pdfnames.[ch], pdfobj.[ch], sfnt.h, spc_pdfm.c,
+ spc_xtx.c, truetype.c, t1_char.[ch], tt_cmap.[ch], unicode.[ch]:
+ No reason to use 'long' for 32-bit integers.
+
+ * system.h: Moved #undef's for Win32 symbols from here ...
+ * error.h, mpost.c: ... to here.
+
+2015-08-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvipdfmx.c (main): Drop CDECL.
+ * agl.c, otl_opt.c, pdfencoding.c, pdfnames.c, pdfobj.c,
+ t1_char.c, tt_cmap.c, tt_glyf.c:
+ Replace 'static <TYPE> CDECL' => 'static inline <TYPE>'.
+ * system.h: Drop __cdecl and CDECL.
+
+2015-08-14 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfcolor.[ch]: Drop unused pdf_color_set_default().
+
+ * pdfdev.h: Drop pdf_dev_setfont() and pdf_dev_set_colormode().
+
+ * pdfdoc.[ch]: Drop unused pdf_doc_{end,make}_article().
+ Declare pdf_doc_get_mediabox() as static.
+
+ * pdfdraw.h: Drop pdf_dev_{fill,eofill,stroke,fillstroke}(), and
+ pdf_dev_grestoreall().
+
+ * pdfnames.[ch]: Declare printable_key() as static.
+
+ * pdfximage.h: Drop pdf_ximage_disable_ebb().
+
+ * tfm.[ch]: Drop tfm_get_space(). Skip tfm_string_{depth,height}.
+
+ * tt_table.[ch]: Declare tt_get_name() as static.
+
+2015-08-14 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * cff.[ch]: Declare cff_match_string() as static.
+ * cff.h: Drop unused '#define cff_is_stdstr(s)'.
+
+ * cid.[ch]: Declare CIDFont_new(), CIDFont_release(),
+ CIDFont_flush(), and CIDFont_cache_init() as static.
+
+ * cmap.[ch]: Declare CMap_match_codespace() as static.
+ * cmap_write.h: Put '#if 0...#endif' around Map_ToCode_stream().
+
+2015-08-13 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * agl.[ch]: Declare agl_load_listfile() as static.
+
+ * cff_types.h: Drop unused type l_size.
+
+ * dpxutil.[ch]: Extern sputx(), getxpair(), putxpair(),
+ ostrtouc(), and esctouc() moved from here ...
+ * cmap_write.c: ... to here or ...
+ * pst_obj.c: ... to here as static.
+
+2015-08-12 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * mpost.[ch]: Extern check_for_mp() moved from here ...
+ * pdfximage.c: ... to here as static.
+
+2015-08-05 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c: Introduce a new static function static int is_notdef_notzero()
+ to fix the support of native type1 fonts. The t1disasm is required.
+ The fix is intended as an intermediate one until more fine fix is given.
+
+2015-08-03 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvi.c: Better detection of bad (inconsistent) DVI files.
+ * xdvipdfm-bad.test: New shell script to test bad DVI files.
+ * tests/ids_2_6.dvi, tests/ids_3_2.dvi, tests/ids_a_b.dvi,
+ tests/opc_fe.dvi, tests/ptx_2_2.dvi, tests/ptx_6_6.dvi,
+ tests/rev_2_2.dvi, tests/rev_2_3.dvi, tests/void.dvi: New test
+ input data (bad DVI files).
+ * Makefile.am: Add the new test and input data.
+
+2015-07-31 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvipdfmx.c, xbb.c: Use getopt_long() for option parsing.
+
+2015-07-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * xdvipdfm-ptx.test: New shell script to test Ascii pTeX output.
+ * xdvipdfm-rev.test: New shell script to test TeX-XeT output.
+ * tests/ptex.dvi, tests/reverse.dvi: New test input data.
+ * Makefile.am: Add the new tests and input data.
+
+2015-07-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am, ac/withenable.ac, configure.ac, dvipdfmx.c,
+ xbb.c: Only one binary and a symlink dvipdfmx->xdvipdfmx.
+ * ac/dvipdfm-x.ac (removed): Obsolete configure options.
+ * dvipdfm*.test (removed): Obsolete tests.
+ * tests/img*.{bb,bbx} (removed): Obsolete test data.
+
+2015-07-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Make dvipdfmx and xdvipdfmx essentially the same.
+ * dvicodes.h: Slightly reformat.
+ * dvi.c: Run-time decision to hanlde XeTeX extensions only for
+ id_byte 6 and Ascii pTeX extension only for post_id_byte 3.
+ * pdfdev.c: Remove '#ifdef XETEX' (one probably a mistake).
+ * pdfdoc.c: New artbox handling only for XDV files (from XeTeX).
+ * system.h: Drop redundant #include <kpathsea/c-auto.h>.
+
+2015-07-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfdoc.c: Somewhat simplify to avoid compiler warnings.
+
+2015-07-22 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * epdf.c. pdfdoc.c, pdfobj.h, pdfximage.c, spc_pdfm.c, spc_util.c, xbb.c:
+ Support pagebox=artbox etc. in PDF inclusion. It works with a new
+ dvipdfmx.def. Thanks Y. Terada.
+
+2015-07-18 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * epdf.c, pdfobj.c: Try to embed a PDF image, even if the PDF version
+ is newer than the setting.
+
+2015-07-08 Simon Cozens <simon@simon-cozens.org>
+
+ * pngimage.c: Fixed a typo "XObjcect" => "XObject".
+
+2015-07-07 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am: Better dependencies for 'make check'.
+ * ac/dvipdfm-x.ac: Fixed a typo.
+ * xdvipdfmx.test: Fixed a typo.
+
+2015-07-06 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dpxcrypt.c: Bugfix: Replace byte => uint8_t.
+ * dpxcrypt.[ch]: Replace u{8,32,64} => uint{8,32,64}_t.
+ * pdfencrypt.c: Declare pdf_enc_init() as static.
+ drop useless cast (const char *) => (char *).
+ * unicode.h: Drop unnecessary #include <inttypes.h>.
+
+2015-07-04 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * jpegimage.c: Use size_t, uint32_t,... instead of short/long int.
+ * dpxcrypt.c/h, dvi.c/h, pdfencrypt.c/h, dvipdfmx.c, pdfobj.c:
+ Add AES encryption support in PDF ecryption.
+ * pngimage.c : Support images with 16 bit depth.
+ * unicode.c/h: Add UTF-8 decoding function.
+
+2015-05-23 Jiang Jiang <gzjjgod@gmail.com>
+
+ * dvi.c: Fix Type1 font encoding and metrics.
+
+2015-05-21 Karl Berry <karl@tug.org>
+
+ * version 20150515 for TL'15.
+
+2015-05-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c: Do not identify Type1 fonts as TrueType or OpenType.
+
+2015-05-04 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * cidtype0.c: Avoid compiler warnings:
+ (CIDFont_type0_get_used_chars, CIDType0Error_Show,
+ CIDFontInfo_init, CIDFontInfo_close, -CIDType0Error,
+ CIDFont_type0_add_CIDSet): Declare as static.
+ (CIDFont_type0_add_CIDSet): Initialize num_glyphs, last_cid.
+ (CIDFont_type0_open): Always initialize sfont, drop unused.
+
+2015-05-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * cidtype0.c: Support old compilers.
+
+2015-05-01 Jiang Jiang <gzjjgod@gmail.com>
+
+ * cidtype0.c, cidtype0.h, cid.c: Combine all Type 0 open functions
+ into one. Simplify some implementations.
+
+2015-04-27 Jiang Jiang <gzjjgod@gmail.com>
+
+ * cidtype0.c: Fix TTC support for Type 1 Composite and Type 0 fonts.
+
+2015-04-27 Jiang Jiang <gzjjgod@gmail.com>
+
+ * dpxfile.c: Ignore empty file in filetype checking.
+
+2015-04-26 Jiang Jiang <gzjjgod@gmail.com>
+
+ * cidtype0.c, cidtype2.c: Support loading CID type 0 font from
+ TrueType Collection.
+
+ * truetype.c: Fix offset in offset for TrueType loading.
+
+2015-04-25 Jiang Jiang <gzjjgod@gmail.com>
+
+ * cff_dict.c: Be more permissive in CFF dict parsing, fix Yuppy SC
+ and Yuppy TC fonts support.
+
+2015-04-25 Jiang Jiang <gzjjgod@gmail.com>
+
+ * sfnt.c: Fix Mac TrueType font support.
+ bug found by Richard Koch <richardmoncriefkoch@icloud.com>.
+
+2015-04-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvi.c, tt_cmap.c: Fixed a dfont bug, from Akira,
+ bug found by Dohyun Kim <nomosnomos@gmail.com>.
+
+2015-04-19 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pngimage.c: Ask libpng to do gamma correction with assumed
+ screen gamma 2.2.
+
+2015-04-12 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfobj.c: Fix some problems in reading cross-reference streams.
+ * pngimage.c: Support PNG gAMA chunk.
+ * jpegimage.c: Various fixes in handling JPEG Exif data
+ (possible overflow and buffer overrun), adjusting indent and spaces.
+ * jp2image.c: JPEG2000 opacity channel support.
+ * pdfcolor.c: Update for PDF 1.7 in pdfcolor.c.
+
+2015-04-05 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pngimage.c: XMP Metadata support for PNG images.
+
+2015-03-27 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * mfileio.[ch]: Use mfgets() parameters as for fgets().
+
+2015-03-24 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * bmpimage.c, dpxcrypt.c, dvi.c, fontmap.[ch], jpegimage.c,
+ pdfcolor.[ch], pdfdev.[ch], pdfdoc.c, pdfdraw.c, spc_tpic.c,
+ spc_util.c, spc_xtx.c, xbb.c: Copyright "2014" => "2015".
+
+2015-03-24 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: Change "Copyright (C) 2002-2014" to
+ "Copyright (C) 2002-2015".
+
+2015-03-17 Khaled Hosny <khaledhosny@eglug.org>
+
+ * pdfcolor.c, pdfcolor.h, pdfdoc.c, pdfdraw.c, spc_util.c: Add spot
+ colors support, based on patch by Apostolos Syropoulos.
+
+2015-03-15 Khaled Hosny <khaledhosny@eglug.org>
+
+ * tests/*.{bb,xbb}: Update version number.
+
+2015-03-15 Karl Berry <karl@tug.org>
+
+ * configure.ac: version 20150315 for TL'15.
+
+2015-03-12 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * jpegimage.c: Fix a bug introduced by me on 2015-02-16.
+
+2015-03-01 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * spc_tpic.c: Make tpic "ar" command dvips compatible to fix the problem
+ that an excess line is drawn when "ar" command is used along
+ with dvips transformation commands.
+
+2015-02-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * fontmap.h (pdf_insert_native_fontmap_record): Declare also
+ without '#ifdef XETEX'.
+ * fontmap.c (pdf_insert_native_fontmap_record): Define also
+ without '#ifdef XETEX'; drop redundant test for path==NULL.
+
+2015-02-24 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvi.c (dvi_locate_native_font): Avoid sprintf() buffer overrun.
+
+ * dvi.c (dvi_locate_native_font): Fix a small memory leak.
+
+2015-02-21 Khaled Hosny <khaledhosny@eglug.org>
+
+ * dvi.c (dvi_locate_font, dvi_locate_native_font): make sure the
+ all members of loaded font struct are initialized, avoid crash in
+ dvi_close for simple fonts because hvmt member is not initialized.
+ Fixes the xdvipdfmx-bkm test.
+ * dvi.c (dvi_locate_native_font): fix loading files without absolute
+ paths.
+ * dvi.c (dvi_locate_native_font): fix loading TTC fonts.
+ * xdvipdfm-ttc.test, tests/ttc.dvi, tests/ttc.tex, tests/test.ttc,
+ Makefile.am: new test.
+ * dvi.c (dvi_locate_native_font): correctly load vertical glyph
+ metrics.
+ * configure.ac, Makefile.am: drop FreeType dependency.
+ * dvi.c, fontmap.c, fontmap.h: remove the nonop pdf_load_native_font.
+ * fontmap.c, fontmap.h (pdf_insert_{native_}fontmap_record): return
+ the newly inserted record.
+ * dvi.c: adapt.
+
+2015-02-21 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvi.c: Read glyph advances without the need for FreeType, based on
+ patch by Clerk Ma.
+ * fontmap.c, fontmap.h: Stop loading FreeType fonts.
+
+2015-02-16 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * jpegimage.c: Fix jpeg_get_density().
+
+2015-01-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * bmpimage.c, dpxcrypt.c, dvi.c: Avoid compiler warnings.
+
+2015-01-07 Khaled Hosny <khaledhosny@eglug.org>
+
+ * pdfdev.c (pdf_dev_reset_fonts): don't reset text_state.bold_param
+ unless called for a new page, otherwise we "forget" that the last font
+ was a fake bold font and don't reset text stroke when this function
+ gets called immediatly after a fake bold font is used
+ (https://sourceforge.net/p/xetex/bugs/105/).
+ * pdfdev.h, pdfdoc.c, pdfdraw.c, spc_xtx.c: adapt.
+
+2014-12-03 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * xbb.c: Support to specify a page in a multi-page PDF to extract
+ bounding box, usage: extractbb -p page foo.pdf.
+
+2014-12-01 Karl Berry <karl@tug.org>
+
+ * data/dvipdfmx.cfg (D): add back -sPAPERSIZE=a0, needed for
+ pstricks under xetex; retain -dEPSCROP, needed for negative llx/lly.
+ From Akira, thread at
+ http://tug.org/pipermail/xetex/2014-November/025664.html.
+
+2014-11-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvipdfmx.test, xdvipdfmx.test: Also test --showpaper option.
+
+2014-11-29 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c, dpxconf.c, dpxconf.h: Add an option --showpaper which
+ shows available paper formats and exits.
+
+2014-11-29 Karl Berry <karl@tug.org>
+
+ * dvipdfmx.c (show_usage): use [all pages] instead of (-).
+ From peb.
+
+2014-11-28 Karl Berry <karl@tug.org>
+
+ * dvipdfmx.c (main): accept --extractbb per help message.
+ (show_usage): one line of description.
+ * xbb.c (show_usage): likewise.
+ Suggestion from Tom Schneider, texhax 22 Nov 2014 08:53:19.
+
+2014-11-19 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvipdfmx.c: Modified support to make DLL(s) in W32TeX.
+
+2014-11-15 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: Support to make DLL in W32TeX.
+
+2014-11-05 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxfile.c: Check if fqpn == NULL in dpx_open_file(), because
+ MESG (fqpn) crashes if fqpn == NULL.
+
+2014-11-04 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pkfont.c: Fix the messed up formatting codes.
+ * pdfparse.c: Avoid undefined behaviour when char is signed.
+
+2014-11-03 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pdfdev.c: Do not convert integer part of real numbers to long int
+ when printing a real number.
+ * pdfparse.c: Do not use temporary integer values for storing
+ parsed numbers.
+ * pkfont.c: Remove debugging codes, additional fixes in formatting
+ integer values.
+
+2014-10-29 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pkfont.c: Cast unsigned integers when they appear in subtractions
+ to obtain results in double.
+
+2014-10-05 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_dvips.c: Add " showpage\n" to a temporary file gs_in because
+ Ghostscript 9.15 gives an empty pdf without it
+ in dpx_file_apply_filter().
+
+2014-10-03 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_dvips.c: Fix a bug in spc_dvips_at_end_page (void), that is
+ change "if (!temporary_defs)" to "if (temporary_defs)".
+
+2014-09-29 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_pdfm.c: Minor cleanup.
+
+2014-09-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * {bmp,jp2,jpeg,png}image.[ch], xbb.c: More cleanup (whitespace
+ and long => int or uint32_t).
+
+2014-09-24 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * jp2image.c: Add newline at end of file.
+ (read_box_hdr): Correctly handle 8byte lbox value.
+ (read_res__data): Change result type 'unsigned long' => 'void'.
+ (scan_res_): Reindent.
+
+ No reason to use 'long' for 32-bit integers.
+ * bmpimage.[ch], jp2image.[ch], xbb.c: Change bmp_get_bbox() and
+ jp2_get_bbox() args 'long *' => 'int *'.
+
+2014-09-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_pdfm.c: If input string is UTF16BE with BOM, do nothing in
+ maybe_reencode_utf8().
+
+2014-09-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ No reason to use 'long' for 32-bit integers.
+ * dvi.[ch], pkfont.c, specials.[ch], tfm.[ch]: Use (u)int32_t
+ instead of long, UNSIGNED_QUAD, etc.
+ * dvipdfmx.c: Replace long => int.
+ * jp2image.c, otl_conf.c: Drop rewind() after file_size().
+ * mfileio.[ch]: New functions xfile_size(), xseek_absolute(),
+ xseek_relative(), xseek_end(), and xtell_position().
+ * numbers.[ch]: Replace (UN)SIGNED_BYTE => (un)signed char,
+ (UN)SIGNED_PAIR => (un)signed short, (UN)SIGNED_TRIPLE =>
+ un)signed int, (UN)SIGNED_QUAD => (u)int32_t.
+ New functions get_unsigned_num() and get_positive_quad().
+ * vf.c: Use get_positive_quad() and get_unsigned_num().
+
+2014-09-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * vf.c: Add missing break in case X1: case X2: case X3: case X4:
+ in void vf_set_char(int32_t ch, int vf_font).
+
+2014-08-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * t1_char.c: Fix a bug in type1 handling reported by Bob Tennent
+ (http://tug.org/pipermail/tex-live/2014-June/035580.html).
+
+2014-08-22 TANAKA Takuji <KXD02663@nifty.ne.jp>
+
+ * error.h: Allow Unicode messages on Windows console.
+
+2014-08-22 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * vf.c (get_pkt_unsigned_num): Fixed a stupid bug/typo.
+
+2014-08-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * numbers.[ch]: New function skip_bytes().
+ * vf.[ch]: Simplify VF reading. Replace, e.g., long => int32_t.
+
+2014-08-20 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac: Add AC_TYPE_INT32_T for int32_t.
+ * numbers.c: Drop unused code.
+ * numbers.h: Drop unused code.
+ Include <inttypes.h> and <stdint.h> for int32_t and uint32_t.
+ Clarify signed vs unsigned four byte numbers from binary files.
+ * dvi.c: Simplify handling of DVI commands.
+ * vf.c: Replace 'Ubyte' => 'unsigned char'.
+
+2014-08-19 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pngimage.c: Avoid PNG warnings.
+
+2014-08-16 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvi.c: Drop unused variable. Use "%lu" for unsigned long vars.
+
+2014-08-16 Khaled Hosny <khaledhosny@eglug.org>
+
+ * dvi.c, dvicodes.h, fontmap.c, fontmap.h: Switch to XDV version 6
+ used by latest XeTeX.
+
+2014-08-16 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c, pdflimits.h: Set PDF_VERSION_DEFAULT = 5 to be
+ consistent with dvipdfmx.cfg.
+
+2014-08-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfobj.c: Avoid unconstifying casts. Drop unused variable.
+ Avoid possibly uninitialized use of variable filter_name.
+
+2014-08-14 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfobj.c: Return 1 even if the PDF version of included file is
+ newer than the assumed version in check_for_pdf(), because
+ load_image() in pdfximage.c needs very long time if format ==
+ IMAGE_TYPE_UNKNOWN and the file size is very large.
+ Anyway the inclusion of the PDF file fails.
+
+2014-08-14 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * epdf.c, pdfobj.c: Support streams with DecodeParms.
+
+2014-08-12 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvipdfm-bb.test, xdvipdfm-bb.test: Also test .bmp and .jp2.
+ * tests/image.{bmp,dvi,jp2,tex}: Additional test input.
+ * tests/{img,pic}{bmp,jp2}.{bb,xbb}: Expected test output.
+ * Makefile.am (EXTRA_DIST): Add the new files.
+
+2014-08-11 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * jp2image.c: Declare scan_file() as static. Drop variables
+ that are set but not used [-Wunused-but-set-variable].
+
+2014-08-11 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * bmpimage.[ch], jp2image.[ch] (new), pdfximage.c, xbb.c:
+ Add support for JPEG 2000 (JP2 and JPX baseline subset) and
+ BMP support for extractbb.
+
+2014-08-11 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am: Drop libutil.a, i.e., compile all files once for
+ dvipdfmx and once for xdvipdfmx.
+
+2014-08-05 Jiang Jiang <gzjjgod@gmail.com>
+
+ * tt_cmap.c (otf_create_ToUnicode_stream, create_ToUnicode_cmap):
+ Only load CMAP_TYPE_CODE_TO_CID cmap to do reverse lookup when
+ constructing ToUnicode streams for PDF.
+
+ * type0.c, type0.h, pdffont.c: Remove redundant pdf_font_findfont()
+ function.
+
+2014-08-05 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pst_obj.c, t1_char.c: ANSI C function protos and definitions,
+ i.e., FOO(void) instead of FOO().
+
+2014-08-04 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * tt_cmap.c (create_ToUnicode_cmap): Drop unused variables.
+
+2014-08-04 Jiang Jiang <gzjjgod@gmail.com>
+
+ * cff.c (cff_get_glyphname): Remove duplicated cff_read_charsets()
+ call.
+
+ * tt_cmap.c (sfnt_get_glyphname, create_ToUnicode_cmap): Make sure
+ we only do glyph name lookup for CFF fonts when they are not CID
+ fonts.
+
+ * cmap_read.c: Fix warnings when comparing size_t with negative
+ value (< 0).
+
+2014-08-03 Jiang Jiang <gzjjgod@gmail.com>
+
+ * tt_cmap.c (sfnt_get_glyphname, handle_subst_glyphs): Fix error on
+ glyph name lookup.
+
+ * cff.c (cff_glyph_lookup), pdfdev.c (pdf_dev_set_string): Correctly
+ handles the dvi file when Unicode to CID mapping file is specified,
+ where pdf_dev_set_string() got string of cids instead of glyphs.
+
+ * cmap.c: Add reverse lookup from CID to Unicode codepoints.
+
+ * tt_cmap.c, type0.c: Refactor create_ToUnicode_cmap{4, 12}(), use
+ reverse CMap lookup to construct ToUnicode streams.
+
+2014-08-03 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfobj.c: Fix a typo in check_for_pdf().
+
+2014-08-02 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * tt_cmap.c: Fix a bug in unicode encoding in CFF/OpenType fonts.
+
+2014-08-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * type0.c: Fix a bug in Type0Font_clean (Type0Font *font).
+
+2014-07-30 Khaled Hosny <khaledhosny@eglug.org>
+
+ * dvi.c, dvicodes.h: Support TeX-XeT's begin_reflect and end_reclect
+ opcodes in dvipdfmx.
+
+ * dvi.c (dvi_set, do_glyph_array): Use dvi_right to ensure
+ consistency.
+
+2014-07-29 Khaled Hosny <khaledhosny@eglug.org>
+
+ * spc_pdfm.c: remove the #ifdef ENABLE_TOUNICODE as it is always true.
+ * spc_pdfm.c: rename my_parse_pdf_dict to
+ parse_pdf_dict_with_tounicode.
+
+ * dvipdfmx.c, dvi.c: Always accept .xdv file extension.
+ * dvipdfmx.c: Remove some unnecessary is_xetex checks.
+ * dvipdfmx.c: Allow DVIPDFM emulation mode even with xdvipdfmx, there
+ is no much gain from not doing so.
+ * pdfnames.c: Remove wrong is_xetex check.
+
+ * dvi.c, dvipdfmx.c, dvipdfmx.h, spc_pdfm.c: Rename is_xetex to is_xdv
+ and set it to 1 when DVI id equals XDV_ID.
+
+ * pdfdev.c (pdf_dev_locate_font): Don't crash if mrec is None.
+ * dvipdfm.test, xdvipdfm.test, Makefile.am: Test the above bug.
+ * tests/xbmc.{dvi,tex}, tests/xbmc10.{600pk,tfm}: New test data.
+
+2014-07-28 Jiang Jiang <gzjjgod@gmail.com>
+
+ * dpxfile.c (qcheck_filetype): Skip opening non-existent file.
+
+ * tt_cmap.c (lookup_cmap12): Fix a compiler warning when trying to
+ compare unsigned value with 0.
+
+2014-07-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * type0.c (Type0Font_*_ToUnicode_stream): Declare once as static
+ (once again!).
+
+2014-07-28 Khaled Hosny <khaledhosny@eglug.org>
+
+ * dvi.c (do_pic_file): Don't insert the pic file while skimming
+ reflected segments.
+
+ * tt_cmap.c (handle_subst_glyphs): Don't try to added invalid CMap
+ entries (regression from r34718).
+
+ * cff.c, cff.h: Add cff_get_glyphname convenience function.
+ * tt_cmap.c (sfnt_get_glyphname): Support getting glyph names from
+ OpenType/CFF fonts (regression from r34718).
+
+2014-07-28 Jiang Jiang <gzjjgod@gmail.com>
+
+ * cid.c, pdfdev.c: Correct release of retained cff_charsets.
+
+2014-07-27 Jiang Jiang <gzjjgod@gmail.com>
+
+ * cff.c, cff.h, cid.c, cid_p.h, cidtype0.c, fontmap.c, fontmap.h,
+ pdfdev.c: Fix CID-keyed fonts glyph lookup with XeTeX.
+
+ * pdfdev.c, pdffont.c, pdffont.h, tt_cmap.c, type0.c, type0.h: Fix
+ reverse CMap lookup for ToUnicode map generation.
+
+ * cff.c: Avoid read past 65536 glyphs.
+
+2014-07-26 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dpxfile.c: Add a default case to avoid compiler warnings.
+
+2014-07-25 Khaled Hosny <khaledhosny@eglug.org>
+
+ * dpxfile.c, dpxfile.h: Use an enum for resource type instead of
+ preprocessor macros (easier to view in a debugger).
+
+ * dvi.c, vf.c: Remove unnecessary is_xetex checks; there is no reason
+ not to support SET3 and PUT3 in xdvipdfmx (XeTeX does not use them
+ anyway).
+
+2014-07-24 Khaled Hosny <khaledhosny@eglug.org>
+
+ * cff.c. cff.h, cid.c, cid.h, cid_p.h, cidtype0.c, cidtype2.c,
+ pdffont.c, pdffont.h, sfnt.c, sfnt.h, t1_load.c, truetype.c, tt_aux.c,
+ tt_cmap.c, tt_cmap.h, tt_glyf.c, tt_gsub.c, tt_post.c, tt_post.h,
+ tt_table.c, type0.c, type1c.c: These files are now identical for
+ dvipdfmx and xdvipdfmx and are part of libutil.a.
+ * type0.h (Type0Font_get_ft_to_gid): Removed.
+ * Makefile.am: Adapted.
+
+ * pdfdev.c: Reduced dvipdfmx/xdvipdfmx diffs.
+
+ * dvi.c: Use dvi_is_tracking_boxes when applicable.
+
+2014-07-22 Khaled Hosny <khaledhosny@eglug.org>
+
+ * src/dvi.c, src/dvicodes.h: Support DVI-IVD inspired text reflection
+ for XeTeX.
+ * src/vf.c: Adapt
+
+2014-07-22 Karl Berry <karl@tug.org>
+
+ * Makefile.am (check-libutil-source-list): new target for manual
+ checking of #ifdef XETEX list.
+ (libutil_a_SOURCES): move type1c.c (containing #ifdef XETEX) from here
+ (dvipdfmx_SOURCES): to here.
+
+ * cidtype0,
+ * type1c.c: add disambiguating numbers to the repeated
+ "Not a CFF/OpenType font?" message. (Many other repeated msgs remain.)
+
+2014-07-21 Karl Berry <karl@tug.org>
+
+ * fontmap.c (fontmap_parse_mapdef_dps): ignore the second <
+ in << in a map file line (just like the [ in <[ has always been
+ ignored).
+ * Makefile.am (EXTRA_DIST): add fullmap.tex and .dvi,
+ just for documentation/future purposes, not executed as a new test.
+ Report from Ulrike Fischer, 4 Jun 2014 11:15:06 +0200,
+ http://tug.org/pipermail/tex-live/2014-June/035486.html
+
+2014-07-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * cmap_read.c: Avoid cast from pointer to integer of different
+ size on 64-bit Windows.
+
+2014-06-22 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_dvips.c: Use rungs instead of gswin32c in order to support
+ both of gswin32c and gswin64c (Windows only).
+
+2014-06-21 Khaled Hosny <khaledhosny@eglug.org>
+
+ * pdfdoc.c: Set PDF Docinfo's /Producer string from pdf:docinfo if
+ supplied (http://sourceforge.net/p/xetex/bugs/93/).
+
+2014-06-20 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * agl.c, cid.c, dpxfile.c, dpxutil.c, dvipdfmx.c, epdf.c,
+ fontmap.c, mpost.c, otl_conf.c, otl_opt.c, pdfnames.c,
+ pdfparse.c, spc_dvips.c, spc_html.c, spc_misc.c, specials.c,
+ subfont.c: Avoid undefined behaviour when char is signed.
+
+2014-06-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * xbb.c: Check kpse_in_name_ok and kpse_out_name_ok in extractbb.
+
+2014-06-16 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am: Drop the obsolete ACLOCAL_AMFLAGS.
+
+2014-05-22 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: disable warnings in the case of -q option.
+
+2014-05-13 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfobj.[ch] (pdf_unshift_array): Bug fix: correctly copy array
+ elements, using memmove(). Declare pdf_unshift_array as static.
+ Bug reported by Richard M Kreuter <kreuter@progn.net>.
+
+2014-05-10 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * bmpimage.c: Error exit instead of crashing for unsupported
+ bmp inclusion in bmp_include_image().
+
+2014-05-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: Move special-case single option --help or --version
+ after determination of program name (from Heiko).
+ Change my_name for extractbb and ebb.
+ xbb.c: Move '++flag' from inside 'if()' to 'then' part of the
+ 'if' statement (from Heiko).
+
+2014-04-30 Khaled Hosny <khaledhosny@eglug.org>
+
+ * tt_cmap.c: [XDVIPDFMX] prefere glyph name for glyph with PUA or
+ alphabetic presentation forms entries in font cmap.
+
+2014-04-24 Karl Berry <karl@tug.org>
+
+ * man/dvipdfm.1,
+ * Makefile.am (dist_man1_MANS): rename man page to dvipdfmx.1.
+ (man1_links): make a dvipdfm.1 link.
+ [XDVIPDFMX]: make an xdvipdfmx.1 link.
+
+2014-04-17 Karl Berry <karl@tug.org>
+
+ * dvipdfmx.c (show_usage): default map in practice is pdftex.map.
+ * man/dvipdfm.1: major update to something closer to current
+ reality, from Bob Tennent and me.
+
+2014-03-31 Karl Berry <karl@tug.org>
+
+ * dvipdfmx.c (show_usage): avoid long lines in help msg,
+ include bug reporting address, and
+ (show_version): use printf instead of fprintf(stdout.
+
+2014-03-24 Karl Berry <karl@tug.org>
+
+ * error.c (WARN, ERROR): use my_name, not loud stars.
+ #include "dvipdfmx.h" for decl.
+ * tt_table.c: use WARN for warnings, not fprintf.
+
+2014-03-20 Karl Berry <karl@tug.org>
+
+ * dvipdfmx.c (show_version): eliminate useless leading blank line.
+ (main): special-case --help and --version on their own to avoid
+ possible diagnostics.
+
+2014-03-18 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * xbb.c: Update one more Copyright year.
+ * tests/{img,pic}{jpeg,png,pdf}.{bb,xbb}: Update Creator.
+
+2014-03-17 Karl Berry <karl@tug.org>
+
+ * configure.ac: version 20140317 for TeX Live 2014.
+ * all files: update copyright years.
+
+2014-03-17 Bob Tennent <rdt@cs.queensu.ca>
+
+ * dpxfile.c (dpx_open_file),
+ * fontmap.c (pdf_load_fontmap_file): show fontmap file found,
+ if verbose.
+
+2014-03-06 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvi.c, dvipdfmx.c: Remove unused code.
+ * pdfdraw.c: Remove unused arg1 of pdf_dev__rectshape() and
+ pdf_dev__flushpath().
+
+2014-01-27 TANAKA Takuji <KXD02663@nifty.ne.jp>
+
+ * dvipdfmx.c: Revise procedure of reading command line arguments.
+ (Windows only)
+
+2014-01-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxfile.c: Fix a bug in dpx_file_apply_filter(), report from
+ Michael Rutter <http://tug.org/pipermail/tex-live/2014-January/034771.html>
+
+2014-01-13 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am, /ac/withenable.ac, configure.ac:
+ Replace libs/paper => libs/libpaper.
+
+2014-01-13 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dbxfile.c [WIN32]: Include <wchar.h>. Avoid use of
+ uninitialized variables cmdvw and qvw.
+
+2014-01-12 TANAKA Takuji <KXD02663@nifty.ne.jp>
+
+ * dvipdfmx.c: Add '--kpathsea-debug' option and
+ fix a bug in '--dvipdfm' option.
+ * dvipdfmx.c, mfileio.[ch], dbxfile.c: Allow Unicode file name
+ on Windows.
+
+2014-01-02 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pngimage.c: Allow libpng >= 1.6.3 to read images with
+ incorrect CMF bytes.
+
+2013-12-16 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am (dvipdfmx_SOURCES): Move cidtype0.c to here.
+ From Alexey Kryukov <anagnost@yandex.ru>
+
+2013-12-14 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * spc_xtx.c: Guarantee that mline in is_pdfm_mapline(mline) is a
+ zero-ended string when called by spc_handler_xtx_fontmapline().
+
+2013-12-13 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * spc_pdfm.c: Guarantee that mline in is_pdfm_mapline(mline) is a
+ zero-ended string when called by spc_handler_pdfm_mapline().
+
+2013-11-28 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * xbb.c: Add suffixes ".ai", ".AI" for the Illustrator files.
+ In recent illustrators, their default format is PDF.
+
+2013-11-23 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * mpost.c: Fix a bug which I introduced in MetaPost mode (-M option).
+ Note that the definition of x, and y in
+ pdf_doc_begin_page (scale, x, y) is the negative of those in
+ pdf_doc_begin_grabbing (ident, x, y, ...).
+
+2013-11-23 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * mpost.c: Set the origin at (llx, lly) to match the new xetex.def
+ and dvipdfmx.def.
+
+2013-11-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * xbb.c: Set pdf_version in extractbb to be PDF_VERSION_MAX.
+
+2013-11-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * pdfobj.c: Correct %c to %d since pdf_version is unsigned int.
+ Fix a typo.
+
+2013-10-24 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am, /ac/withenable.ac, configure.ac: Use libs/paper.
+
+2013-10-12 Khaled Hosny <khaledhosny@eglug.org>
+
+ * dvi.c, dvicodes.h: Rename XDVI_ID to XDV_ID.
+
+2013-09-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac: Drop the useless KPSE_LT_HACK.
+ Drop the redundant AC_HEADER_STDC and check for mkstemp.
+
+2013-09-26 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * epdf.c, pdfdraw.c, pdfobj.c, pdfximage.c, spc_color.c,
+ spc_color.c, specials.c: These files are now identical for dvipdfmx
+ and xdvipdfmx and are part of libutil.a.
+ * Makefile.am: Adapted.
+
+ * spc_pdfm.c: Reduced dvipdfmx/xdvipdfmx diffs.
+
+2013-09-26 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * bmpimage.c, dpxfile.c, pdfparse.c, spc_html.c, spc_tpic.c:
+ These files are now identical for dvipdfmx and xdvipdfmx and are
+ part of libutil.a.
+ * Makefile.am: Adapted.
+
+ * cff_dict.c, pdfdraw.c, pdfobj.[ch], pdfximage.[ch],
+ tt_table.c, type1.c: Reduced dvipdfmx/xdvipdfmx diffs.
+
+2013-09-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfnames.c: Fix (x)dvipdfm-bkm.test (notjump).
+
+2013-09-24 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfnames.[ch], pdfobj.c, specials.c: Fix (x)dvipdfm-res.test
+ (tikz-bug).
+
+ * tests/annot.{dvi,tex}: Test a broken link annotation.
+
+2013-09-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxcrypt.h, dpxcrypt.c: Use uint32_t instead of unsigned long to
+ calculate MD5, because it leads to an error if compiled with clang
+ on 64bit OS X, reported by T. Yamamoto.
+
+2013-09-12 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * (x)dvipdfm-bkm.test: Additional tests with bookmarks.
+ * tests/bookm.{dvi,tex}: Additional test input files.
+ * Makefile.am: Adapted.
+
+2013-09-01 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * spc_util.c: This file is identical for dvipdfmx and xdvipdfmx,
+ now part of libutil.a.
+
+2013-08-18 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * epdf.c (add_stream_flate): Use z_const.
+ * pdfobj.c (pdf_add_stream_flate): Use z_const.
+
+2013-08-12 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvipdfmx.c (show_usage): Adapt to modified program (stdin).
+ * xdvipdfm-psz.test: Fixed a typo (found by Mojca Miklavec).
+
+2013-08-11 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dvipdfmx.c: pdf_filename should not be NULL to compare it with
+ a string.
+
+2013-08-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvipdfmx.[ch]: Declare and define 'char *my_name' as
+ "dvipdfmx" or "xdvipdfmx" and use it instead of PROGNAME.
+ * pdfdoc.c, pdfencrypt.c: Use my_name instead of PACKAGE.
+
+ * dvipdfmx.c, pdfobj.c: Use option '-o -' for output to stdout.
+
+ * dvipdfmx.c, dvi.c: Allow dvipdfmx to read from stdin.
+
+ * pdfobj.c (write_dict): Drop '\n' saving a few kb.
+
+ * pdfcolor.[ch], pdfdev.c, pdfdraw.[ch], spc_pdfm.c: Always use
+ dvipdfmx type color handling.
+
+ * agl.c, cmap_write.c, dpxutil.c, jpegimage.c, otl_conf.c,
+ pdfcolor.c, pdfresource.c, pngimage.c, pst.c, pst_obj.c,
+ spc_misc.c, tfm.c, vf.c, xbb.c: These files are identical for
+ dvipdfmx and xdvipdfmx, now part of libutil.a.
+
+ * configure.ac: Define PACKAGE again via AC_INIT.
+ * dpxfile.c: Use "dvipdfmx" for kpse_reset_program_name().
+
+ * (x)dvipdfm-psz.test: Test (x)dvipdfmx with stdin and stdout.
+
+2013-08-09 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dvi.c: Bug fix: handle papersize specials, suggested by Akira
+ (from Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>).
+
+ * (x)dvipdfm-psz.test: Additional tests with papersize specials.
+ * tests/paper.{dvi,tex}: Additional test input files.
+ * Makefile.am: Adapted.
+
+ * *.test: Sanitize environment variables (from Akira).
+
+2013-08-08 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfdoc.[ch], pdfnames.c, spc_pdfm.c: Bug fix: handle pdf:bann,
+ pdf:eann, and pdf:ann specials.
+
+2013-08-07 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac: Avoid that config.h depends on $enable_build.
+ Replace CHO_CHECK_{ZLIB,LIBPNG} => AC_LINK_IFELSE and
+ CHO_CHECK_LIBPAPER => KPSE_LIBPAPER.
+ Makefile.am: Use $(PAPER_INCLUDES) and (PAPER_LIBS).
+
+2013-08-06 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * (x)dvipdfm-ann.test: Additional tests.
+ * tests/cmr10.{pfb,tfm}, tests/annot.{dvi,tex},
+ tests/psfonts.map: Additional test input files.
+ * Makefile.am, dvipdfmx.cfg: Adapted.
+
+ Bugfix from Akira:
+ * dvi.c, xdvipdfmx.c: May need to append ".dvi" to dvi_filename.
+ * xdvipdfmx.c: At the moment dvipdfmx can not read stdin.
+
+2013-08-02 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfobj.c (pdf_open): Bugfix: Always set pf->catalog.
+ * xbb.c: Use same code to get the .pdf bounding box in dvipdfmx
+ and xdvipdfmx.
+ * dvi.c: Avoid duplicate page number output, e.g., "[1[1]]".
+ * (x)dvipdfmx.test: Add test with image files.
+ * tests/image.tex, tests/image.tex: Additional test input files.
+ * Makefile.am (EXTRA_DIST, DISTCLEANFILES): More test IO files.
+ Define PACKAGE as "dvipdfmx" for kpse_reset_program_name().
+
+2013-07-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Removed diffs between src/ and xsrc/ version of the remaining
+ files and moved them to the top-level: cidtype0.c, dvi.c,
+ dvipdfmx.c, epdf.c, jpegimage.c, pdfcolor.c, pdfdev.c, pdfdoc.c,
+ pdfdraw.c, pdfobj.c, pdfximage.c, spc_pdfm.c, spc_tpic.c,
+ tt_cmap.c, type1c.c, xbb.c.
+ * Makefile.am: Adapted.
+
+ * jpegimage.c (jpeg_get_density): Bugfix (from xdvipdfmx r108).
+
+2013-07-22 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * tt_aux.c, tt_post.c: Try to avoid a segfault for some broken
+ TrueType fonts with 'post' table Version 0x00000000UL or other.
+
+ * unicode.[ch]: Drop '#include "agl.h"' and others.
+ * pdffont.c: Add '#include "agl.h"'.
+
+ * Removed diffs between src/ and xsrc/ version of these files
+ and moved them to the top-level: cff_dict.c, pdfencrypt.c,
+ pdfnames.h, spc_dvips.c, specials.c, tfm.c, truetype.c, type1.c.
+
+ * Makefile.am (libutil.a): Build a library from files that do
+ not depend on '-DXETEX': cs_type2.c, dpxconf.c, dpxcrypt.c,
+ error.c, mem.c, mfileio.c, numbers.c, otl_opt.c, pdfencoding.c,
+ pdfencrypt.c, subfont.c, unicode.c.
+
+ * Reduced dvipdfmx/xdvipdfmx diffs in these files:
+ dvipdfmx.c, jpegimage.c, pdfdoc.c, pdfdraw.c, pdfnames.c,
+ pdfobj.c, pdfximage.c, spc_pdfm.c, spc_tpic.c, tt_cmap.c, xbb.c.
+
+2013-07-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * xsrc/jpegimage.c: Added jpeg_get_bbox() and jpeg_get_density()
+ from src/jpegimage.c.
+ * xsrc/pdfdoc.c: Added pdf_doc_get_page() from src/pdfdoc.c.
+ * xsrc/pngimage.c: Added png_get_bbox() from src/pngimage.c.
+ * xbb.h (removed): Merged ...
+ * dvipdfmx.h: ... into here.
+
+ * Removed diffs between src/ and xsrc/ version of these files
+ and moved them to the top-level: pdfobj.h, pngimage.c.
+
+ * Reduced dvipdfmx/xdvipdfmx diffs in these files:
+ dvipdfmx.c, epdf.c, pdfdoc.c, pdfobj.c, pdfximage.c, xbb.c.
+
+ * src/dvipdfmx.c, xsrc/dvipdfmx.c: Add '--xbb', '--ebb' options.
+
+ * (x)dvipdfmx.test: Correctly set the environment variables.
+ * (x)dvipdfm-bb.test: New shell scripts to test bounding box
+ extraction.
+ * tests/dvipdfmx.cfg, tests/image.* (new): Test input files.
+ * tests/img*.*, tests/pic*.* (new): Expected output files.
+ input and expected output files.
+
+2013-07-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Removed diffs between src/ and xsrc/ version of these files
+ and moved them to the top-level: cff.c, dvi.h, mpost.c,
+ pdfdev.h, pdfdoc.h, pdfdraw.h.
+
+ * Reduced dvipdfmx/xdvipdfmx diffs in these files:
+ dvi.c, dvipdfmx.c, epdf.c, xbb.c.
+
+ * *src/dvipdfmx.c: Use FILESTRCASEEQ instead of !STRN_CMP.
+
+2013-07-08 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Removed diffs between src/ and xsrc/ version of these files
+ and moved them to the top-level: bmpimage.c, cidtype2.c, epdf.h,
+ fontmap.c, pdfcolor.h, pdfparse.c, pdfximage.h, sfnt.[ch],
+ tt_aux.[ch], tt_post.c, tt_table.c.
+
+ * Reduced dvipdfmx/xdvipdfmx diffs in these files:
+ cidtype0.c, epdf.c, pdfcolor.c, pdfdev.[ch], pdfximage.c.
+
+2013-07-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * xsrc/dvi.c: Use !FILESTRCASEEQ instead of STR_CMP.
+
+2013-07-05 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Removed diffs between src/ and xsrc/ version of these files
+ and moved them to the top-level: cff.h, spc_color.c,
+ spc_html.c, spc_util.[ch], tt_glyf.c, type0.c.
+
+ * Reduced dvipdfmx/xdvipdfmx diffs in these files:
+ cff.c, dvi.[ch], cidtype0.c, cidtype2.c, dvipdfmx.c, fontmap.c,
+ pdfcolor.[ch], truetype.c, tt_aux.[ch], type1c.c.
+
+ * Makefile.am: Moved Makefile fragments to ../../am/.
+
+2013-07-03 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Removed diffs between src/ and xsrc/ version of these files
+ and moved them to the top-level: dpxfile.[ch], fontmap.h,
+ jpegimage.h, pngimage.h, tt_cmap.h, type0.h, vf.c, xbb.h.
+
+ * Reduced dvipdfmx/xdvipdfmx diffs in these files:
+ src/cff_dict.c, (x)src/cidtype0.c, (x)src/cidtype2.c,
+ (x)src/dvipdfmx.c, (x)src/jpegimage.c, src/pdfencrypt.c,
+ src/pdfparse.c, src/pngimage.c, src/spc_html.c,
+ (x)src/tt_cmap.c, (x)src/tt_table.c, src/xbb.c.
+
+2013-07-01 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * data/Makefile.am, man/Makefile.am (removed): Merged into ...
+ * Makefile.am: ... here.
+ * configure.ac: Adapted.
+
+2013-06-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * First '#include <config.h>' in all C files and not in headers.
+
+2013-06-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/dvipdfmx.h, xsrc/spc_xtx.[ch]: Moved to the top-level.
+ * Moved these files (identical in src/ and xsrc/) to the
+ top-level: agl.[ch], bmpimage.h, cff_dict.h, cff_limits.h,
+ cff_stdstr.h, cff_types.h, cid.[ch], cid_basefont.h, cid_p.h,
+ cidtype0.h, cidtype2.h, cmap.[ch], cmap_p.h, cmap_read.[ch],
+ cmap_write.[ch], cs_type2.[ch], dpxconf.[ch], dpxcrypt.[ch],
+ dvicodes.h, mem.[ch], mfileio.[ch], mpost.h, numbers.[ch],
+ otl_conf.[ch], otl_opt.[ch], pdfencoding.[ch], pdfencrypt.h,
+ pdffont.[ch], pdflimits.h, pdfparse.h, pdfresource.[ch],
+ pkfont.[ch], pst.[ch], pst_obj.[ch], sfnt.h, spc_color.h,
+ spc_dvips.h, spc_html.h, spc_misc.[ch], spc_pdfm.h, spc_tpic.h,
+ specials.h, subfont.[ch], system.h, t1_char.[ch], t1_load.[ch],
+ tfm.h, truetype.h, tt_glyf.h, tt_gsub.[ch], tt_post.h,
+ tt_table.h, type1.h, type1c.h, unicode.[ch], vf.h.
+
+ * Removed diffs between src/ and xsrc/ version of these files
+ and moved them to the top-level: dpxutil.[ch], error.[ch].
+
+ * Makefile.am: Adjust.
+
+2013-06-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * (x)src/Makefile.am (removed): Merged into Makefile.am.
+ * src/dvipdfmx.test, src/dvipdft, xsrc/xdvipdfmx.test: Moved ...
+ * dvipdfmx.test, dvipdft, xdvipdfmx.test: ... to here.
+ * Makefile.am, configure.ac: Adapted.
+
+2013-06-26 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/dvipdfmx.test: Invoke ./dvipdfmx instead of dvipdfmx.
+ * xsrc/xdvipdfmx.test: Invoke ./xdvipdfmx instead of xdvipdfmx.
+
+ Reduce dvipdfmx/xdvipdfmx diffs.
+
+ * xsrc/spc_color.[ch], xsrc/spc_misc.[ch], xsrc/spc_pdfm.[ch],
+ xsrc/spc_xtx.[ch], xspc/specials.c: Drop no-op functions
+ spc_*_at_{begin,end}_{document,page}().
+ * (x)spc/spc_dvips.[ch], (x)spc/specials.c: Use '#ifdef XETEX'
+ to avoid most diffs.
+
+2013-06-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Merge dvipdfmx and xdvipdfmx into dvipdfm-x.
+
+ * README, ChangeLog: Merged and consolidated the files from
+ dvipdfmx and xdvipdfmx.
+
+2013-05-30 Karl Berry <karl@tug.org>
+
+ * version 20130405 for TeX Live 2013.
+
+2013-04-30 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * src/dpxfile.c, src/pdfximage.c, src/dvipdfmx.c, data/dvipdfmx.cfg:
+ Add a compatible mode with the old behavior per Karl, where
+ image cache is ignored.
+
+2013-04-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * (x)dvipdfmx.test: New shell scripts for a simple test.
+ * Makefile.am: Adapted.
+
+2013-04-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/dvipdfmx.c: Default is not to cache image files.
+ Must not cast command line value to 'unsigned'.
+
+2013-04-30 Karl Berry <karl@tug.org>
+
+ * data/dvipdfmx.cfg (D): back to using -dEPSCrop instead of
+ -sPAPERSIZE=a0, in conjunction with changes to dvipdfmx.def
+ and xetex.def.
+ (I): set to -1 for the safest default.
+
+2013-04-05 Karl Berry <karl@tug.org>
+
+ * configure.ac: version 20130405 for TL'13.
+
+2013-03-28 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * src/dpxfile.c, src/spc_dvips.c: Recover dpx_create_temp_file()
+ for PSTricks.
+
+2013-03-26 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/dpxfile.[ch]: Avoid gcc warnings.
+
+2013-03-26 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * src/dvi.c: Correct my mistake to delete RELEASE(q).
+
+2013-03-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Patch from Tsuchimura Nobuyuki <tutimura@nn.iij4u.or.jp> to
+ speed up inclusion of eps figures.
+ * data/dvipdfmx.cfg, src/dpxfile.[ch], src/dvi.c,
+ src/dvicodes.h, src/dvipdfmx.c, src/pdfximage.c, src/vf.c:
+ Applied with small modifications to avoid compiler warnings,
+ adapted for WIN32 by Akira Kakuto.
+
+2013-03-24 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * src/dpxfile.c: Change dpx_create_temp_file() because tmpnam()
+ sometimes fails on Windows.
+
+2013-03-20 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * spc_dvips.c (spc_handler_ps_tricks_pdef, spc_handler_ps_tricks_tdef,
+ spc_handler_ps_tricks_bput, spc_dvips_at_begin_document, calculate_PS):
+ Don't crash when temporary file creation fail.
+
+2013-03-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for xdvipdfmx:
+ * dvi.c (dvi_locate_native_font): Drop unused variable.
+
+2013-03-14 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * src/dvi.c, src/dvicodes.h, vf.c: Revert "Support DVI-IVD inspired text
+ reflection for XeTeX".
+ * src/fontmap.c: Remove commented out old Mac code.
+ * src/fontmap.c (pdf_load_native_font_from_path, pdf_load_native_font):
+ Merge.
+ * src/dvi.c, src/fontmap.c, src/fontmap.h: Ignore native font family and
+ style names that we no longer use.
+ * src/dvi.c (read_native_font_record, do_native_font_def): Don't check
+ for XDV_FLAG_FONTTYPE_* flags as they do nothing.
+ * src/dvi.c (do_glyph_array): Use FT_Get_Advance() instead of the slower
+ FT_Load_Glyph().
+ * src/dvi.c, src/fontmap.c, src/fontmap.h: Drop no longer needed
+ glyph_widths cache.
+ * dvi.c: Drop unneeded includes.
+
+2013-02-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/dpxutil.[ch]: Reduce dvipdfmx/xdvipdfmx diffs.
+ * src/fontmap.[ch]: Copied from xdvipdfmx to dvipdfmx.
+ * src/agl.c: Copied from dvipdfmx to xdvipdfmx.
+
+ Only for xdvipdfmx:
+ * src/fontmap.c, src/pdfnames.c, src/pdfobj.c, src/spc_pdfm.c,
+ src/tt_cmap.c: Adapt to modified definition of ht_*_table().
+
+2013-02-22 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * src/fontmap.c (pdf_load_native_font_from_path): Fix loading font files
+ without an extension (e.g. Mac suitcase fonts).
+
+2013-02-21 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * src/tt_cmap.c (handle_subst_glyphs): Use FT_Get_Glyph_Name() instead of
+ reading 'post' table directly, to handle CFF fonts where the 'post' table
+ has no glyph names.
+ * rc/tt_cmap.c (create_ToUnicode_cmap4, create_ToUnicode_cmap12,
+ otf_create_ToUnicode_stream): Adapt.
+
+2013-02-15 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * src/cidtype2.c: Fix loading *.dfont files on non-Mac platforms.
+ * src/fontmap.c: Don't include unused ApplicationServices headers
+ * configure.ac src/Makefile.am: Don't check for now unused Apple
+ ApplicationServices.
+
+2013-02-12 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * src/dpxfile.c, src/dpxfile.h (dpx_find_dfont_file): Make public.
+ * src/fontmap.c (pdf_load_native_font_from_path): Fix loading *.dfont files.
+ * src/fontmap.c (pdf_load_native_font): Drop use of deprecated ATS API, all
+ native fonts should be given as file names.
+ * src/fontmap.c (pdf_load_native_font): Show failed font name in error
+ message.
+
+2013-02-08 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * data/Makefile.am (configdatadir, mapdatadir, cmapdatadir):
+ Change texmf => texmf-dist.
+
+2013-01-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * configure.ac, src/Makefile.am: Allow subdir-objects.
+
+2013-01-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for xdvipdfmx:
+ * src/dvi.c: Avoid unused variables sbuf and slen.
+
+2013-01-19 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only xdvipdfmx:
+ * src/dvi.c, src/dvicodes.h: Support DVI-IVD inspired text reflection
+ for XeTeX.
+ * src/vf.c: Adapt
+ * src/dvi.c: Drop code for ancient FreeType 2.2.0
+ * src/fontmap.c, src/fontmap.h: Drop no longer use FreeType version
+ variables.
+
+2013-01-11 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Reduce dvipdfmx/xdvipdfmx diffs.
+
+ Only for dvipdfmx:
+ src/Makefile.am: Use AM_CPPFLAGS instead of dvipdfmx_CPPFLAGS.
+ src/cid.[ch], src/cid_p.h, src/cid_p.h, src/dvicodes.h,
+ src/fontmap.h, src/pdffont.[ch], src/sfnt.[ch], src/t1_load.c,
+ src/tt_glyf.c, src/tt_gsub.c: Copied from ../xdvipdfmx.
+
+ Only for xdvipdfmx:
+ * src/agl.c: Definition of hval_free() moved up.
+ * src/pdffont.h: Added #ifdef XETEX ... #endif.
+ * src/t1_load.c: Added #ifdef XETEX ... #else ... #endif.
+ * src/dpxconf.[ch], src/dpxcrypt.[ch]: Copied from ../dvipdfmx.
+ * src/sfnt.c: '#if HAVE_CONFIG_H' => '#ifdef HAVE_CONFIG_H'.
+
+2013-01-10 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * read_v2_post_names() in tt_post.c: Change calculation of post->count
+ for special fonts with unused index.
+
+2013-01-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/cid.c: Avoid casts (const char *) -> (char *).
+
+2013-01-09 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid various gcc-4.6 warnings.
+ * src/cidtype2.c, src/dvipdfmx.c, src/fontmap.c, src/otl_conf.c,
+ src/pdfencoding.c, src/spc_pdfm.c, src/tt_cmap.c: Do not use
+ unsafe casts (char **) -> (const char **).
+ * src/bmpimage.c, src/cidtype0.c, src/cidtype2.c, src/dvi.c,
+ src/jpegimage.c, src/pdffont.c, src/pkfont.c, src/spc_pdfm.c,
+ src/tt_aux.c, src/tt_cmap.c, src/tt_glyf.c, src/tt_post.c,
+ src/type1.c, src/type1c.c: Drop set but unused variables.
+ src/pdfdraw.c: Do not test '(&v) != NULL', this is always true.
+
+2012-12-12 Khaled Hosny <khaledhosny@eglug.org>
+
+ * src/tt_cmap.c: Make sure CMapName of embedded CMaps does not contain
+ slashes.
+
+2012-12-11 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * src/tt_cmap.c: Fix crash with fonts that has some glyphs without name
+ entries in 'post' table.
+
+2012-11-20 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for xdvipdfmx:
+ * src/Makefile.am: Avoid use of deprecated INCLUDES.
+
+2012-09-24 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * version.ac (removed): We now maintain dvipdfmx here.
+ * configure.ac: Adapted.
+
+2012-09-21 Karl Berry <karl@tug.org>
+
+ * many files: remove useless $Header$ from old repo,
+ do not point to dvipdfmx@ email address any more.
+
+2012-09-19 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * ChangeLog.TL (removed): Now merged ...
+ * ChangeLog: ... into this.
+
+2012-09-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Only for xdvipdfmx:
+ * fontmap.c: unused function pdf_clear_fontmaps
+ * fontmap.h: unused function pdf_clear_fontmaps
+ * pdfcolor.c: unused functions pdf_get_colorspace_num_components,
+ pdf_get_colorspace_subtype
+ * pdfcolor.h: unused functions pdf_get_colorspace_num_components,
+ pdf_get_colorspace_subtype
+ * pdfdev.c: unused functions pdf_dev_currentfont, pdf_dev_get_font_ptsize
+ * pdfdev.h: unused functions pdf_dev_currentfont, pdf_dev_get_font_ptsize
+ * pdfdraw.c: unused functions static int pdf_coord__itransform,
+ pdf_dev_setflat, pdf_dev_itransform, pdf_dev_rectstroke
+ * pdfdraw.h: unused functions pdf_dev_setflat, pdf_dev_itransform,
+ pdf_dev_rectstroke
+ * pdffont.c: unused functions pdf_get_font_fontname, pdf_font_get_flags
+ * pdffont.h: unused functions pdf_get_font_fontname, pdf_font_get_flags
+ * pdfobj.c: unused functions pdf_put_array, pdf_shift_array,
+ pdf_pop_array, pdf_put_dict, pdf_stream_set_flags, pdf_stream_get_flags
+ * pdfobj.h: unused functions pdf_put_array, pdf_shift_array,
+ pdf_pop_array, pdf_put_dict, pdf_stream_set_flags, pdf_stream_get_flags
+ * type0.c: unused function Type0Font_get_encoding
+ * type0.h: unused function Type0Font_get_encoding
+
+2012-09-06 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * configure.ac, src/fontmap.c, src/Makefile.am: Remove FontConfig
+ dependency, as it is not needed anymore with recent XeTeX.
+
+2012-08-31 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Reduce TL/W32TeX diffs.
+ * src/cidtype0.c, src/cidtype2.c, src/cmap_write.c, src/mpost.c,
+ src/truetype.c, src/tt_cmap.c, src/tt_gsub.c, src/tt_post.c:
+ Cast function args to avoid WIN32 (MSVC) warnings.
+ * src/pdfobj.c (pdf_out_xchar): Reformulate to avoid MSVC warnings.
+ * src/xbb.c (show_usage): Correctly report .bb or .xbb as default.
+
+ Only for xdvipdfmx:
+ * src/xbb.c: Always use binary mode for output file.
+
+ Only for xdvipdfmx:
+ * src/pdfencrypt.c (getpass) [WIN32]: Use "*" to `echo' password.
+ * src/dvipdfmx.c (main) [WIN32]: Call texlive_gs_init().
+ * src/dvi.c (dvi_init): Fix logic for appending ".dvi" or ".xdv".
+ * spc_dvips.c: Use binary mode for all file io.
+ [WIN32]: Use gswin32c; avoid memory leak.
+
+2012-08-26 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Only for dvipdfmx:
+ * src/tt_table.c (tt_read_hhea_table),
+ src/tt_post.c (read_v2_post_names),
+ src/cc_tmap.c (otf_load_Unicode_CMap): typos.
+
+2012-08-26 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for xdvipdfmx:
+ * src/agl.c: Reduce differences with dvipdfmx.
+ * BUGS, NEWS, TODO, contrib/*, doc/*, index.html, style_base.css,
+ style_dflt.css, style_ie.css, style_plain.css: Remove files removed
+ from dvipdfmx.
+ * data/*: Sync with dvipdfmx.
+
+2012-08-23 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for dvipdfmx:
+ * src/Makefile.am: Remove mention of non-existent files.
+
+ Only for xdvipdfmx:
+ * src/dvipdfmx.c, src/mem.c, src/mem.h, src/xbb.c, src/dvipdfmx.c,
+ src/mem.c, src/mem.h, src/xbb.c: Remove memory debugging code.
+ * src/agl.c, src/agl.h: Remove the built-in AGL name list to minimize
+ difference with dvipdfmx.
+ * src/agl_standard.c, src/mk_agl_standard_c.pl: Removed.
+ * src/asl_charset.h: Removed unused file.
+ * src/Makefile.am: Adapted.
+
+2012-08-21 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * src/tt_post.c (read_v2_post_names): support large truetype fonts
+ which are strictly speaking out of spec, idx > 32767.
+ * src/dvipdfmx.c: support monocase filesystem.
+
+2012-08-21 keiichirou shikano <k16.shikano@gmail.com>
+
+ * src/cff.c, src/cff.h. src/type1.c: fix type1 SEAC bug.
+
+2012-08-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * src/dpxfile.c: Drop tests for __TDS_VERSION__.
+ * configure.ac: Drop definition of __TDS_VERSION__.
+
+ Only for xdvipdfmx:
+ Try to avoid mem_debug_check warning.
+ * spc_dvips.c (spc_dvips_at_end_document): Free ps_headers.
+
+2012-08-20 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ Flatten, i.e., remove dvipdfmx-20120420/.
+ * Makefile.am (EXTRA_DIST): Drop $(DVIPDFMX_TREE){,-PATCHES}.
+ * configure.ac: Drop DVIPDFMX_TREE.
+ * version.ac (removed): Obsolete.
+
+2012-08-20 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for dvipdfmx:
+ * src/dvipdfmx.c, src/mem.c, src/mem.h, src/xbb.c, src/dvipdfmx.c,
+ src/mem.c, src/mem.h, src/xbb.c: Remove memory debugging code.
+
+2012-08-18 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Only for xdvipdfmx:
+ * dvi.c: Fix a bug in dvi_init(). The old one fails for dvi or xdv
+ files of very short name. For example "xdvipdfmx t" fails for t.xdv.
+
+2012-08-18 Khaled Hosny <khaledhosny@eglug.org>
+
+ Only for dvipdfmx:
+ Move contents of dvipdfmx-20120420 to the top directory
+ * Makefile.am, configure.ac, data/Makefile.am, man/Makefile.am,
+ src/Makefile.am: Adapted.
+ * configure.in, m4/cho-kpse.m4, m4/cho-libs.m4, m4/maw-time.m4:
+ Removed.
+
+2012-05-21 Norbert Preining <preining@logic.at>
+
+ Only for dvipdfmx:
+ * patch-05-cid-x_map (new): add entries for rml-jis and gbm-jis
+
+2012-05-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * fontmap.c: fix a typo. allow pdftex.map without PS name.
+
+2012-04-27 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Reduce dvipdfmx/xdvipdfmx diffs.
+ * cid.[ch], cidtype[02].c, dpxutil.[ch], pdfdoc.[ch],
+ mem.[ch], truetype.c, tt_cmap.c, type1c.c: Trivial changes.
+
+2012-04-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Try to avoid mem_debug_check warning.
+
+ Only for dvipdfmx:
+ * mem.c: Increase MEM_LINE, avoid C99-ism, add tex-k@tug.org.
+
+ Only for xdvipdfmx:
+ * mem.h: Enable use of MEM_DEBUG.
+ * mem.c: Increase MEM_LINE, avoid C99-ism, add tex-k@tug.org.
+ * dvipdfmx.c (main): Enable mem_debug_check().
+
+ For both:
+ * spc_pdfm.c (spc_handler_pdfm_stream_with_type): Free fullname.
+
+2012-04-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * dvipdfmx.c (show_version): Print "modified for TeX Live,".
+
+2012-04-20 Alexander Grahn <A.Grahn@hzdr.de>
+
+ * src/spc_pdfm.c: use kpse to find media
+
+2012-04-20 Norbert Preining <preining@logic.at>
+
+ * src/dvipdfmx.c: add a new directive "i" for reading subsidiary
+ config files
+ * data/dvipdfmx.cfg: document the new directive
+
+ Only for dvipdfmx:
+ Imported snapshot 20120420.
+ * version.ac, man/dvipdfm.1: Adapted.
+
+2012-04-14 Khaled Hosny <khaledhosny@eglug.org>
+
+ * src/spc_dvips.c: Fixed bug in "ps: plotfile" special.
+
+2012-03-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Remove extern decls from *.c files.
+
+ * dpxfile.c: Drop obsolete comment that mkstemp may not be
+ declared in stdlib.h.
+ * spc_color.c: Drop 'extern' from function definition.
+ * error.h: ANSI C prototype for error_cleanup().
+ * error.c: Drop extern decl, now in error.h.
+ * dvipdfmx.c: Add '#include "error.h"' and drop extern decl.
+
+ Only for xdvipdfmx:
+ * dvi.c: Move extern decls from here ...
+ * dvi.h: ... to here ...
+ * fontmap.h: ... and here.
+ * tt_aux.c: Move extern decl from here ...
+ * tt_aux.h: ... to here ...
+ * dvipdfmx.c: ... and #include "tt_aux.h".
+
+2012-03-05 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfdev.c (handle_multibyte_string): Handle UTP-16 surrogates
+ for UCS-4 supplementary planes.
+ Based on patch from Tanaka Takuji-san.
+
+2012-03-04 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for xdvipdfmx:
+ Avoid 'the address of XXX will always evaluate as true' warnings.
+ * pdfdraw.c (m_stack_depth): Use '(s) != NULL' instead of '(s)'.
+ Gcc >=4.3 produces identical code but -Wall yields no warning.
+
+2012-02-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for xdvipdfmx:
+ * configure.ac: Fixed a typo (no libpaper for TeX Live builds).
+
+2012-01-17 Hironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
+
+ Only for dvipdfmx:
+ * dvi.c, pdfdev.c: Support for (e-)(u)pTeX dtou direction.
+
+2011-12-06 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * data/Makefile.am:
+ Replace ${prefix}/texmf => $(datarootdir)/texmf.
+
+2011-11-06 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Only for xdvipdfmx:
+ * spc_pdfm.c: fix a typo in spc_handler_pdfm_dest().
+ reencode also the destination in \special{pdf:dest ...} to UTF-16.
+
+2011-11-05 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Only for dvipdfmx:
+ * dvi.c, spc-pdfm.c, tfm.c and vf.c: remove incompatible lines
+ with the non-upTeX case and erase #ifdef upTeX.
+
+2011-10-18 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for xdvipdfmx:
+ * tt_cmap.c: Fix typo "featre" -> "feature".
+
+2011-09-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Only for xdvipdfmx:
+ * dvi.c, spc-pdfm.c, tfm.c and vf.c: apply patches by Takuji Tanaka
+ in order to support (e)-upTeX. The (e)-upTeX support is enabled by
+ defining upTeX. In the case -DupTeX, the dvipdfmx must be compatible
+ with the old one, which can be obtained without -DupTeX.
+
+2011-06-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac (AC_TYPE_UINT32_T): Portability fix for AIX.
+ * dpxcrypt.c: Use headers as in configure test for uint32_t.
+
+ Only for dvipdfmx:
+ * patch-02-exec_spawn (new): Bug fix for exec_spawn() from
+ Akira Kakuto <kakuto@fuk.kindai.ac.jp> and Peter Breitenlohner.
+
+2011-06-06 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dpxfile.c (exec_spawn): Do not quote execvp() arguments.
+
+2011-06-03 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * dpxfile.c (exec_spawn): Exit if execvp() fails, some clean up.
+
+2011-06-03 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * dpxfile.c: fix a bug in exec_spawn().
+
+2011-05-31 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * man/extractbb.1: Update extractbb manpage.
+
+2011-05-09 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * ../dvipdfmx-20110311/data/dvipdfmx.cfg: Synched from Master.
+ * patch-00-cfg: Adapted (by Karl Berry <karl@tug.org>).
+
+2011-05-03 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ Imported snapshot 20110311.
+ * configure.ac: Adapted.
+
+2011-04-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * patch-00-cfg (new): Change dvipdfmx.cfg to use rungs instead of
+ the default ps2pdf -dSAFER, to avoid complete pstricks failure with
+ xetex.
+
+2011-04-18 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for xdvipdfmx:
+ * src/fontmap.c [OS X]: #include FT_MAC_H to get prototype for
+ FT_GetFilePath_From_Mac_ATS_Name().
+
+2011-03-11 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dpxcrypt.c:
+ Applied the patch for 64bit systems; suggested by Akira Kakuto.
+
+2011-03-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/*.[ch]: Remove trivial dvipdfmx/xdvipdfmx diffs.
+
+ Only for xdvipdfmx:
+ * src/Makefile.am: Mark asl_charset.h as unused.
+
+2011-03-09 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ Only for dvipdfmx:
+ * dpxfile.c, configure.in, man/extractbb.1:
+ Applied the patches for TeX Live 2011 by Peter Breitenlohner.
+
+2011-03-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Only for xdvipdfmx:
+ * src/dvipdfmx.c, src/pdfencrypt.c and src/pdfencrypt.h:
+ recover compute_id_string() for the consistency with dvipdfmx
+ as much as possible.
+
+2011-03-09 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac: Check for <sys/wait.h>, drop check for system().
+ * src/pdfencrypt.c (compute_id_string): Drop unused function.
+
+2011-03-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * src/dpxfile.c: Avoid to use system().
+
+2011-03-07 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * patch-01-dpxfile (new): Use concat3() instead of concatn().
+ Avoid compiler warnings: add const's; cast `unsigned char' to
+ `unsigned short' for printing.
+ * patch-02-manpage (new): Add ebb to NAME; better formatting.
+
+2011-03-07 Matthias Franz
+
+ * dvi.c, dvi.h, dvipdfmx.c, pdfencrypt.c, pdfencrypt.h, spc_pdfm.c:
+ Added special pdf:encrypt to turn on document encryption from
+ within the DVI file (suggested by Michael Joyner). Format:
+ \special{pdf:encrypt ownerpw (abc) userpw (xyz) length 128 perm 252}
+ If a parameter is omitted, the default value / empty password
+ is used. The special must appear at the beginning of the file.
+
+2011-03-05 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dpxfile.c:
+ Applied the secutiry patch written by Akira Kakuto
+ (suggested by Karl Berry).
+
+2011-02-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/pngimage.c (create_cspace_ICCBased): Avoid libpng-1.5.x
+ compiler warning.
+
+2011-02-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * src/Makefile.am [WIN32]: Add dvipdfmx.exe, ebb.exe, and
+ extractbb.exe wrappers for MinGW.
+
+2010-02-11 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * man: New directory with manual pages (from Master).
+ man/dvipdft.1 needs to be updated and man/dvipdfm.1 replaced by
+ man/dvipdfmx.1 (with a link to dvipdfm.1).
+ * Makefile.am, configure.ac: Adapted.
+
+ * man/extractbb.1, man/dvipdfm.1, dvipdft.1: Formatting.
+
+2010-12-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * src/dvipdfmx.c: Check for argv[0] with .exe via strcasecmp().
+
+2010-12-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Only for dvipdfmx:
+ * configure.ac, src/Makefile.am: Ignore shell script for WIN32.
+
+2010-10-11 Matthias Franz
+
+ Only for dvipdfmx:
+ * dvipdfmx.cfg:
+ Added quotes around command line parameters %i and %o
+ (suggested by Karl Berry).
+
+2010-06-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid using "%hu" with fscanf/sscanf, for older Solaris.
+ * src/pdfobj.c (pdf_open, check_for_pdf_version): Declare minor
+ as unsigned int for use with "%u".
+
+2010-06-08 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Solaris9 doesn't support "%hhu".
+ * src/dpxfile.c (dpx_file_apply_filter):
+ Use (unsigned short) version with "%hu".
+ * src/pdfobj.c (pdf_open, check_for_pdf_version): Declare minor
+ as unsigned short for use with "%hu".
+
+2010-05-29 Matthias Franz
+
+ * dpxfile.c, dpxfile.h, pdfobj.c, pdfximage.c:
+ Further changes to fix the "%hhu" problem on Solaris 9.
+
+2010-05-26 Matthias Franz
+
+ * pdfobj.c:
+ Changed type of PDF minor number from char to short in
+ check_for_pdf_version in order to fix a compilation problem with
+ Solaris 9; reported by Ulrich Seidl.
+
+2010-05-24 Matthias Franz
+
+ * dvipdfmx.cfg:
+ Generate PDF 1.5 as default (suggested by Karl Berry).
+
+2010-03-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac: Remove AC_TYPE_SIZE_T, now part of KPSE_COMMON.
+
+2010-03-28 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvi.c, dvi.h, dvipdfmx.c, spc_pdfm.c:
+ Implemented a new special \special{pdf: minorversion num} which
+ will override the value given either by the configuration file
+ or by the command line option; requested by Karl Berry.
+
+2010-03-21 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cidtype2.c:
+ Assume that the output encoding of CMap files is UTF-16, not UCS2
+ as the recent Adobe-Japan1-UCS2 shows; reported by Haruhiko Okumura
+ and the patch were prepared by Akira Kakuto.
+
+2010-02-22 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/pngimage.c (check_for_png), src/xbb.c (check_for_png):
+ Replace png_check_sig() by png_sig_cmp() for libpng-1.4.
+ From Hanno Boeck <hanno@hboeck,de>.
+
+2010-02-20 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/sfnt.h: #define CHAR as SFNT_CHAR to avoid conflict with
+ CHAR from <winnt.h>.
+
+2010-02-07 Matthias Franz
+
+ * type1.c:
+ Fixed bug caused by fonts without data for private dictionary.
+ (The private dictionary was omitted instead of inserting an
+ empty dictionary.) This caused problems with Acrobat Reader, for
+ example with the dsrom10 font. Bug reported by Vladimir Vlasov.
+
+2010-02-07 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c, pdfdoc.c, pdfobj.h, pdfobj.c, pdfencrypt.h, pdfenctypr.c:
+ Now the trailer always contains ID array to work Screen annotations
+ under Adobe Reader 9.
+
+2009-12-14 Matthias Franz
+
+ * dvipdfmx.c:
+ Turn on quiet mode earlier if "-q" option is given.
+
+2009-11-28 Matthias Franz
+
+ * spc_dvips.c:
+ Fixed bug in "ps: plotfile" special, found by Alexander Bostroem.
+
+2009-11-18 Matthias Franz
+
+ * man/extractbb.1, man/Makefile.am, Makefile.am, configure.in:
+ Added man page for extractbb in new directory man. This
+ addresses Debian bug #512357 and a request by Karl Berry.
+
+2009-11-07 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac, src/dpxfile.c: Require recent kpathsea version.
+
+2009-10-10 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c, xbb.c:
+ Change usage() as suggested by Matthias Franz and Karl Berry.
+
+2009-10-09 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c:
+ Implemented the usual options --version and --help
+ (suggested by Karl Berry.)
+
+2009-09-19 Matthias Franz
+
+ * epdf.c, pdfdoc.c, pdfdoc.h, xbb.c:
+ Bug fix: The number of pages in a PDF document as reported by
+ extractbb was always 0. (The code for reporting the number of
+ pages of a PDF file was accidentally removed during a previous
+ modification.)
+
+2009-09-18 Matthias Franz
+
+ * dpxutil.c, dpxutil.h and all calls to the changed functions:
+ Polished code for hash tables. Now the function for freeing
+ values is defined with ht_init_table. ht_append_table now
+ produces an error if the key is already in use (but this
+ could be changed easily). A new insert mode where a value
+ does _not_ replace an existing value for the same key has
+ been introduced, but there is no short name for it yet.
+
+2009-09-02 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid more maximal compiler warnings:
+ * src/pst_obj.c (pst_new_mark, pst_release_obj, pst_parse_null):
+ Instead of casting a const string to non-const, make a copy and
+ later free the copy.
+
+2009-08-31 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid almost all maximal compiler warnings:
+ * src/*.[ch]: Constify start/end pointer args and local vars.
+ Rewrite all parsing routines to operate on const strings.
+ Constify struct member strings. Drop or adjust casts.
+ Cast a few non-const start pointers to 'const char **'.
+ Use a few non-const local vars, not to modify const strings.
+
+2009-08-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid some more maximal compiler warnings.
+
+ * src/tt_post.[ch] (tt_post_table): Constify struct member
+ strings and drop casts.
+ (macglyphorder): Declare 'const char**' not 'const char*const*'.
+
+ * src/truetype.c (selectglyph): Use additional const string local
+ var and drop cast.
+
+ * src/dpxcrypt.[ch] (transform, MD5_write): Constify args.
+ * src/pdfencrypt.c (compute_user_password): Drop cast.
+
+ * src/fontmap.c (chop_sfd_name): Drop useless cast.
+ (substr): Constify string arg and local var.
+ (strip_options): Constify local var and drop cast.
+
+ * src/cmap_write.c (CMap_create_stream): Constify cast.
+ * src/pdfcolor.c (str2iccSig, iccp_check_colorspace,
+ iccp_get_rendering_intent, iccp_unpack_header,
+ iccp_get_checksum): Constify local vars and casts.
+ * src/pdfencoding.[ch] (pdf_encoding_new_encoding,
+ pdf_encoding_findresource): Constify args.
+ * src/pdfobj.c (pdf_out): Constify cast.
+ * src/specials.c (spc_exec_special): Drop useless casts.
+
+ Only for dvipdfmx:
+ * src/pdfdoc.c (pdf_doc_add_goto): Constify local vars.
+
+ Only for xdvipdfmx:
+ * src/fontmap.c (pdf_load_native_font): Constify local var and
+ drop cast.
+ * src/spc_dvips.c (spc_handler_ps_tricks_brotate,
+ spc_handler_ps_tricks_transform): Constify local vars.
+ (pstricks_key): Constify string members.
+
+2009-08-30 Matthias Franz
+
+ * dvipdfmx.cfg:
+ Turned on optimization of PDF destinations by default.
+
+2009-08-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid some more compiler warnings.
+
+ Only for dvipdfmx:
+ * src/pdfobj.c (parse_xref_stream): Drop inner declaration of
+ size and use size_obj, not to shadow previous local (diff type).
+ Rename local index=>index_obj, not to shadow string function.
+
+ Only for xdvipdfmx:
+ Avoid zillions of 'initialization discards' warnings.
+ src/agl.h, src/agl_standard.c, src/mk_agl_standard_c.pl:
+ Constify string array 'agl_standard_names'.
+ src/agl.c (agl_load_standard_names): Adjust.
+
+ Some "declaration of 'xxx' shadows ...". Among the remaining
+ ones, those for 'distiller_template' in src/spc_dvips.c (local
+ vs. global) should be looked at (FIXME).
+ * src/pdfobj.c (parse_xref_stream): Drop inner declaration of
+ size and use size_obj, not to shadow previous local (diff type).
+ * src/epdf.c (pdf_get_page_content): Drop unnecessary inner
+ declaration of content_new, not to shadow previous local.
+
+2009-08-27 Matthias Franz
+
+ * truetype.c, type1.c, type1c.c:
+ Changed precision in font widths arrays from 1.0 to 0.1.
+ (Applies only to Type 1, Type 1C and TrueType, not PK fonts.)
+
+2009-08-27 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid some more maximal compiler warnings.
+
+ * src/cff.[ch] (cff_get_sid, cff_add_string): Constify string arg.
+ * src/cidtype2.c (find_tocode_cmap), src/cmap.c (CMap_decode_char),
+ src/dpxfile.c (dpx_create_temp_file, dpx_file_apply_filter):
+ Constify local vars and drop casts.
+ * src/dpxutil.c (get_hash): Constify cast.
+ * src/pdfnames.c (cmp_key), src/t1_char.c (stem_compare),
+ tt_glyf.c (glyf_cmp): Constify local vars and adjust casts.
+ * src/t1_load.[ch] (t1_get_standard_glyph): Constify return
+ type and drop cast.
+ * src/type1.c (pdf_font_load_type1): Constify local vars.
+ * src/cidtype0.c (CIDFont_type0_t1cdofont,
+ CIDFont_type0_t1dofont): Drop casts.
+
+2009-08-26 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid some maximal compiler warnings.
+
+ * src/*.c: ANSI C function definitions, i.e., '()'=>'(void)'.
+
+ * src/agl.c (skip_capital, skip_modifier): Constify string args.
+ (is_smallcap, agl_name_convert_unicode, put_unicode_glyph,
+ agl_sput_UTF16BE, agl_get_unicodes): Constify local strings
+ and drop casts.
+ * src/xbb.c: Constify global strings.
+
+2009-08-23 Matthias Franz
+
+ * epdf.c, pdfdoc.c, pdfdoc.h, pdfximage.c, pdfximage.h, xbb.c:
+ Removed the feature of negative page numbers for PDF inclusion.
+ It was never used and made the code more complicated.
+
+ * dvipdfmx.c, pdfximage.c:
+ Changed the code for PS and PDF page inclusion:
+ The function mkstemp on NetBSD may return the same name twice
+ if the file has been deleted after the first call. (Reported
+ by Jukka Salmi.) This interfered with our file name caching.
+ Now we don't delete the temporary file after PS->PDF conversion,
+ but cache the temporary file name instead. An advantage is that
+ we don't have to convert the same file multiple times if several
+ pages are imported.
+
+2009-08-17 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * tt_post.c:
+ Fixed the crashing bug with Mona font found by Alexis Ballier.
+
+2009-07-17 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/pdfximage.h: add prototype for pdf_ximage_get_subtype.
+
+2009-07-08 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c:
+ Add -E option that enables DVIPDFM emulation mode in DVIPDFMx.
+
+2009-07-07 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfximage.c, pdfximage.h, spc_pdfm.c:
+ Add pdf_ximage_set_attr() and pdf_ximage_get_subtype()
+ to resolve the conflict with bmpsize package in dvipdfm
+ emulation mode; reported by Heiko Oberdiek.
+
+2009-06-20 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am (AM_CFLAGS): enable compiler warnings.
+ * src/pdfobj.c (pdf_file_new): declare as static.
+
+2009-06-05 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac: replace '--enable-tetex-build' by
+ '--enable-texlive-build' (automatic if configured as part of the
+ TeXLive tree).
+
+2009-06-04 Karl Berry <karl@tug.org>
+
+ Only for dvipdfmx:
+ * src/Makefile.am (dist_bin_SCRIPTS): dvipdft.
+ * src/dvipdft: revised script from Matthias to replace
+ version in dvipdfm.
+
+2009-05-27 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Adapt to TL2009 build system.
+
+2009-05-25 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.ac, src/Makefile.am: Do not use CPPFLAGS for
+ required -I flags, leave it for the user.
+
+2009-05-22 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * generic/pgf-doc-diff.version2cvs, generic/pgf-generic-diff.version2cvs:
+ Removed the patches for the CVS version of pgf,
+ because they are applied to the main stream.
+
+2009-05-15 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * pdfdoc.c (pdf_doc_get_page): Avoid C99isms
+ (variable declaration not at the beginning of a block).
+
+ From Vladimir Volovich <vvv@vsu.ru>
+
+2009-05-10 Matthias Franz
+
+ * epdf.c:
+ Don't try to convert included PDF files whose version number
+ is higher than output file version. (If run as dvipdfm,
+ conversion still occurs.)
+
+ * Makefile.am, Makefile.in, dvipdfmx.c, dvipdfmx.h, jpegimage.c, pngimage.c, xbb.c, xbb.h:
+ Added dvipdfm compatibility mode. This mode is triggered
+ if dvipdfmx is called as "dvipdfm", and likewise extractbb
+ as "ebb". (The latter mode was already present.)
+
+ * dpxconf.c:
+ Made predefined paper sizes match values given by libpaper.
+
+2009-05-06 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c, pdflimits.h, pdfobj.c:
+ Improved PDF version handling.
+
+ * cmap_read.c:
+ Fixed a silly bug; reported by Fumihito YOSHIDA.
+
+2009-05-06 Matthias Franz
+
+ * cid.c, dvipdfmx.c, pdflimits.h, pdfobj.c:
+ Fixed minor issues with PDF version handling, following
+ a question by Akira Kakuto. The minimal and maximal
+ PDF versions allowed are now defined in pdflimits.h.
+
+2009-05-03 Matthias Franz
+
+ * dvipdfmx.c, epdf.c, epdf.h, pdfdoc.c, pdfdoc.h, pdfobj.c, pdfobj.h, pdfximage.c, pdfximage.h, xbb.c:
+ Improved PDF version handling. A "Version" entry in the
+ document catalog is now honored. Moreover, dvipdfmx accepts
+ to write PDF 1.7, and extractbb doesn't complain about PDF
+ versions any more. Encryption keys too long for PDF 1.3 now
+ lead to an error instead of a silent change of PDF version.
+
+2009-05-02 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * tt_table.c:
+ Fixed a bug of reading numOfExSideBearings; reported by
+ Tomas Janousek.
+
+2009-04-30 Matthias Franz
+
+ * dvipdfmx.cfg:
+ Use ps2pdf for PS-to-PDF conversion on all platforms.
+
+2009-04-29 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_color.c, spc_pdfm.c, spc_util.c, spc_util.h:
+ Allow changing strokecolor or fillcolor only; for example,
+ "pdf:scolor Red []" changes fillcolor only and
+ "pdf:scolor [] Red" changes strokecolor only, but
+ "pdf:scolor Red" changes both fillcolor and strokecolor.
+
+ * pdfparse.c:
+ Parse stream objects in a strict way as DVIPDFM because
+ DVIPDFMx already has another specials for stream objects.
+
+2009-04-26 Matthias Franz
+
+ * pdfobj.c:
+ Don't print unnecessary newlines in PDF dictionaries.
+
+ * pdfobj.c, pdfobj.h, xbb.c:
+ Added "%%HiResBoundingBox" and "%%PDFVersion" lines to
+ extractbb output.
+
+ * dpxutil.c, dpxutil.h, dvipdfmx.c, pdfdoc.c,pdfdoc.h, pdfnames.c, pdfnames.h, pdfobj.c, pdfobj.h, spc_pdfm.c, specials.c, dvipdfmx.cfg:
+ Rename PDF destinations to shorter names (in order to save
+ space). Together with the removal of unused PDF destinations
+ implemented previously, this is more or less equivalent to
+ Heiko Oberdiek's LaTeX package "hypdestopt".
+
+2009-04-20 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdoc.c:
+ Bug fix: \special{pdf:bann} ... \special{pdf:eann} (e.g., \hyperlink)
+ cause a problem when it was surrounded by the pair
+ \special{pdf:bcontent} ... \special{\special{pdf:econtent}.
+
+2009-04-19 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * generic/pgf-doc-diff.texlive2008, generic/pgf-generic-diff.texlive2008:
+ Patches and a new dvipdfmx driver for PGF, Version 2.00
+ included in texlive 2008.
+
+ * generic/pgfsys-dvipdfmx.def.version2, generic/pgfsys-dvipdfmx-patch.tex.version2:
+ Removed contributed files because of new patch files
+ pgf-doc-diff.texlive2008 and pgf-generic-diff.texlive2008.
+
+2009-04-18 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * generic/pgf-doc-diff.version2cvs, generic/pgf-generic-diff.version2cvs:
+ Patches and a new dvipdfmx driver for PGF, Version 2.00-cvs 20090418.
+
+ * contrib/context/spec-dpx.tex, contrib/latex/animate.sty.sample, color.sty.sample, dvipdfmx.def.sample, graphics.sty.sample, movie15.sty.sample, sample-imagemask.tex:
+ Removed contributed files already applied to texlive 2008.
+
+2009-04-08 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * t1_load.c:
+ Ignores the second /Subrs dicts and /CharStrings not followed
+ by dict; Adobe's OPO_____.PFB and OPBO____.PFB had those problems.
+
+2009-04-07 Matthias Franz
+
+ * xbb.c:
+ Removed binary mode option "-b". In ebb, just ignore it.
+
+2009-03-30 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdoc.c:
+ Fixed the bug: bbox->llx is not extracted for PDF images.
+
+2009-03-29 Matthias Franz
+
+ * xbb.c:
+ Changed output-to-stdout option to "-O".
+
+2009-03-24 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cff.c, dpxutil.c, pdfencoding.c, pdfencrypt.c, mem.c:
+ Revive system.h to work with TeXLive.
+
+2009-03-23 Matthias Franz
+
+ * dvipdfmx.c, jpegimage.c, jpegimage.h, pngimage.c, pngimage.h, xbb.c:
+ Several changes related to xbb/extractbb:
+ Combined code with jpegimage.c and pngimage.c, added number
+ of pages to xbb output for PDF files, introduced quiet mode
+ (option "-q") and output to stdout (option "-s"), improved test
+ of filename check in dvipdfmx.c (now uses <libgen.h>), new
+ version numbering for xbb (same as dvipdfmx version)
+
+2009-03-16 Matthias Franz
+
+ * pdfdev.c, pdfdraw.c, spc_html.c, spc_pdfm.c, spc_tpic.c:
+ Added comments to show the PDF operators inserted by each
+ call of pdf_doc_add_page_content. This makes it easier to
+ find out which part of the source is responsible for a PDF
+ operator in the output. Example:
+
+ pdf_doc_add_page_content(work_buffer, len); /* op: q cm *
+
+2009-03-16 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * src/cff.c, src/dpxutil.c, src/mem.c, src/pdfencoding.c,
+ src/pdfencrypt.c: Must include Kpathsea headers (via `system.h')
+ before including `mem.h'.
+
+2009-03-15 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * data/Makefile.am, data/Makefile.in, data/EUC-UCS2:
+ Revive the cmap EUC-UCS2; suggested by Nobuyuki Tsuchimura.
+
+2009-03-12 Matthias Franz
+
+ * dvipdfmx.c:
+ Don't print messages in quiet mode.
+
+ * dpxfile.c, dpxfile.h, pdfximage.c, data/dvipdfmx.cfg:
+ Added conversion specifier "%v" (PDF version) to PS-to-PDF
+ conversion template. Also changed default template for
+ GhostScript to use the script ps2pdf instead of calling gs
+ directly. (This works for all platforms.)
+
+ * pdfobj.c:
+ Fixed a bug concerning empty PDF strings: Empty PDF strings
+ were reduced to NULL, which could lead to errors when calling
+ string functions.
+
+2009-01-15 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * specials.c:
+ Apply Jonathan Kew's fix reported on August 7, 2008.
+ (Sorry that it was too late!)
+
+2008-12-11 Matthias Franz
+
+ * xbb.c:
+ Fixed an off-by-one and an off-by-two error in the generation
+ of output file names for extractbb.
+ (Debian bug #506329, reported by G\'abor Braun.)
+
+ * mpost.c, pdfcolor.c, pdfcolor.h, pdfdev.c, pdfdev.h, pdfdoc.c, pdfdraw.c, pdfdraw.h, spc_color.c, spc_pdfm.c:
+ Polished the code for color support. PDF color operators will
+ not be generated any more if old and new color coincide.
+
+2008-11-30 Matthias Franz
+
+ * spc_tpic.c:
+ Polished code.
+
+ * pdfdev.c, spc_html.c:
+ Concatenated transformation matrices for images.
+
+ * data/dvipdfmx.cfg, dvipdfmx.c, pdfdoc.c:
+ Fixed two problems with removal of PDF destinations: Non-link
+ annotations produced a warning, and broken links were not
+ detected if no valid destination existed.
+ Removing unused destinations is now default behaviour and can
+ be prevented by using the flag "-C 0x10". Since the feature
+ is still new, this flag is set in dvipdfmx.cfg.
+
+ * spc_color.c, spc_color.h, spc_dvips.c, spc_dvips.h, spc_misc.c, spc_misc.h, spc_pdfm.c, spc_pdfm.h, specials.c:
+ Removed unnecessary (no-op) handlers for specials.
+
+ * cid.c, cid.h, dpxconf.c, dpxconf.h, dvi.c, dvi.h, fontmap.c, fontmap.h, numbers.c, numbers.h, pdfcolor.c, pdfcolor.h, pdfdev.c, pdfdev.h, pdfdoc.c, pdfdoc.h, pdfdraw.c, pdfdraw.h, pdffont.c, pdffont.h, pdfobj.c, pdfobj.h, pdfresource.c, pdfresource.h, pst_obj.c, pst_obj.h, tfm.c, tfm.h, tt_table.c, tt_table.h, type0.c, type0.h:
+ Commented out unused functions.
+
+2008-11-08 Matthias Franz
+
+ * pdfcolor.c, pdfcolor.h, spc_tpic.c:
+ Made tpic specials respect color settings. Before, they
+ always used black for drawing commands.
+ (Debian bug #485567, reported by Daniel Skorka.)
+
+2008-11-03 Matthias Franz
+
+ * dpxutil.c, dvipdfmx.c, mem.c, pdfdoc.c, pdfdoc.h, pdfnames.c, pdfnames.h:
+ Remove unused PDF destinations. (Packages like hyperref
+ create destinations regardless of whether they are used
+ or not.) This option is currently turned off by default;
+ it can be enabled with "-C 0x10".
+
+ * dvipdfmx.c:
+ Improved parsing of "-v" command line option; contributed
+ by Akira Kakuto. Note that there are still problems if an
+ argument to an option (or the name of the DVI file) starts
+ with a minus sign
+
+ * pkfont.c:
+ Corrected bounding box computation for PK fonts. Before,
+ it was always [0, 0, 0, 0]. Also removed a redundant call
+ to pdf_encoding_add_usedchars.
+
+2008-10-13 Matthias Franz
+
+ * cff.c, cff.h, cff_dict.c, cidtype0.c, pdfdev.c, t1_load.c, type1.c, type1c.c:
+ Various speed improvements:
+ cff.c: cff_add_string now has an option to avoid checking for
+ duplicate strings.
+ pdfdev.c: p_dtoa does not call library functions any more.
+ t1_load.c: t1_decrypt is not called for each byte seperately
+ any more. (Well, this does not make a big difference.)
+
+2008-09-29 Matthias Franz
+
+ * epdf.c, pdfdoc.c, pdfdoc.h, pdfobj.c, pdfobj.h, xbb.c:
+ Made PDF parsing more robust. In particular, we can now
+ detect (illegal) loops in a PDF document hierarchy.
+ Also, much of the PDF parsing code in epdf.c and xbb.c has
+ been combined to the function pdf_doc_get_page in pdfdoc.c.
+ Loops in PDF page trees are detected as well.
+ Moreover, the various bounding boxes of a page are now
+ handled correctly: MediaBox and CropBox are inherited,
+ but not the others.
+
+2008-08-31 Matthias Franz
+
+ * type1.c:
+ Fixed a bug when processing "seac" operators in Type 1
+ fonts. If the base or accent char were not used otherwise,
+ an "Invalid SID" error could occur.
+
+2008-08-05 Matthias Franz
+
+ * type1c.c:
+ Fixed a buffer overflow when using 256 glyphs of a CFF font
+ (plus ".notdef").
+
+2008-08-04 Matthias Franz
+
+ * type1c.c:
+ Fixed a segfault when processing CFF fonts.
+
+2008-07-16 Matthias Franz
+
+ * pdfnames.c, pdfobj.c, pdfobj.h:
+ Replaced pdf_copy_object by the (almost) equivalent,
+ but simpler function pdf_transfer_label. Simplified
+ pdf_compare_reference.
+
+ * pdfnames.c:
+ Reintroduced warning about duplicate object keys.
+
+2008-06-20 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_pdfm.c:
+ Fixed a bug on beads with nonzero depth; reported by
+ Alexander Grahn.
+
+2008-06-13 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_pdfm.c:
+ Fixed a bug on annotations with nonzero depth; reported by
+ Alexander Grahn.
+
+2008-06-07 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * contrib/latex/movie15.sty.sample:
+ Support movie15.sty, version 2008/01/16.
+
+ * pdfobj.c, pdfobj.h, pdfparse.c, spc_pdfm.c, pdfnames.c:
+ Allow PDF stream of length zero and suppress some warning messages.
+
+2008-06-06 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * contrib/latex/animate.sty.sample:
+ Support animate.sty, version 2008/06/03.
+
+2008-06-05 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * mpost.c, pdfdev.c, pdfdev.h, pdfdoc.c, pdfdoc.h, spc_pdfm.c:
+ DVIPDFMx supports PGF version 2.00.
+ New specials "pdf:bcontent", "pdf:econtent", and "pdf:code".
+ Moreover, "pdf:exobj << additional_dict >>" merges additional
+ dictionaries into the XObject dictionary, not resources.
+
+ * pgfsys-dvipdfmx.def.version2, pgfsys-dvipdfmx-patch.tex.version2:
+ A sample DVIPDFMx driver for PGF version 2.00. Note that
+ pgfsys-dvipdfmx-patch.tex must be loaded after loading the
+ basiclayers of PGF. Otherwise image mask and transparency
+ group do not work.
+
+2008-06-01 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdev.h, spc_pdfm.c, spc_util.c, dvipdfmx.def.sample:
+ Changed the option "mask" to "hide" in "pdf:image" special.
+ New "pdf:stream" special for a string given externally.
+
+ * pgf-generic.diff, pgfsys-dvipdfmx.def, xcolor.sty.sample:
+ Renamed and moved pgf patches for version 1 to contrib/generic.
+ Removed "xcolor.sty.sample".
+
+2008-05-29 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_dvips.c, pdfdoc.c, spc_html.c, spc_misc.c, pdfximage.c, pdfximage.h, spc_pdfm.c, spc_util.c, pdfdev.h:
+ Support PGF image masking; support additional attribute dictionary
+ for included images as pdfTeX.
+
+ * xcolor.sty.sample, pgf-generic.diff, pgfsys-dvipdfmx.def, sample-imagemask.tex, dvipdfmx.def.sample:
+ Sample files for image masking and xcolor, pgf patches.
+
+2008-05-28 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_pdfm.c:
+ Remove an warning message which occurs with the PGF
+ transparent model.
+
+ * spc_util.c:
+ Support dvips color names defined in dvipsname.def with
+ "pdf:bcolor" special, e.g. "pdf: bcolor JungleGreen".
+
+2008-05-23 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * data/Makefile.am, data/Makefile.in:
+ Removed the obsolete CMap files in the data directory.
+
+ * data/Makefile.in, src/Makefile.am, src/Makefile.in:
+ Apply Karl Berry's symlink patch.
+
+2008-05-22 Matthias Franz
+
+ * cff_dict.c, dpxconf.c, dpxfile.c, dvipdfmx.c, epdf.c, fontmap.c, pdfdoc.c, pdfdraw.h, pdfencoding.c, pdfobj.c, pst_obj.c, sfnt.c, spc_pdfm.c, xbb.c, truetype.c, pdfencoding.c, pdfdraw.c:
+ Fixed some compiler warnings issued by "gcc -Wall".
+
+2008-05-21 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdoc.c:
+ Fix the timezone bug in asn_data() based on the dvipdfm-0.13.2d
+ code; this patch was suggested by Nobuyuki Tsuchimura.
+
+2008-05-20 Matthias Franz
+
+ * dvipdfmx.c, pdfdoc.c, pdfdoc.h, pdfobj.c, pdfobj.h:
+ Polished object stream code; removed command line option flag
+ 0x10 (no object streams).
+
+2008-05-20 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * contrib/latex/dvipdfmx.def.sample:
+ Fix ithe problem when including a PDF image with bounding box
+ having nonzero llx or nonzero lly.
+
+2008-05-18 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdffont.c, pdffont.h, type1.c, type1c.c, truetype.c:
+ Fix the problem with MusiXTeX's Type1 fonts. Some characters
+ of these fonts have different widths from the corresponding
+ TFM files; reported by Yasuhiro Okazaki and Jean-Pierre Coulon.
+ DVIPDFMx now reads character width from TFM if found.
+ Otherwise, the information comes from the font file.
+ However, Type0 fonts (not simple fonts) do not refer to TFM.
+
+2008-05-18 Matthias Franz
+
+ * epdf.c, pdfobj.c, pdfobj.h, xbb.c:
+ Added PDF 1.5 parsing. Note that many PDF 1.5 files have
+ compressed xref streams with DecodeParms entry. Since we
+ don't support this, we cannot read these files.
+
+ * epdf.c:
+ Allow page import from tagged PDF files. Tags are ignored.
+
+2008-05-18 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c, dpxfile.c, dpxfile.h, otl_conf.c, spc_pdfm.c, system.h:
+ Arranged MiKTeX related codes according to MiKTeX SVN repository.
+
+ * fontmap.c, fontmap.h, pdfdev.c, pdffont.c:
+ Ignore obsolete remap option -r in DVIPDFM fontmaps.
+
+2008-05-17 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c, xbb.c, xbb.h, src/Makefile.am, src/Makefile.in, contrib/latex/dvipdfmx.def.sample:
+ DVIPDFMx now extracts bounding box information.
+ The binary dvipdfmx can be linked as extractbb, ebb, xbb, and
+ it works as same as the linked name. (extractbb == xbb)
+ This idea was suggested by Karl Berry.
+
+2008-05-17 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Makefile.in, aclocal.m4:
+ Remove acinclude.m4. Give a new tag DVIPDFMX-20080517.
+
+ * cid.c, cidtype0.c, cid_p.h, truetype.c, cidtype2.c, fontmap.c, fontmap.h, tt_aux.c, tt_aux.h, type1c.c:
+ New fontmap option '-v' to give StemV value explicitly;
+ especially for Chinese truetype fonts, e.g., Simsun;
+ this feature was suggested by Yue Wang.
+
+ * dvipdfmx.def:
+ Support automatic generation of .xbb if -shell-escape is given.
+ Don't forget to replace $TEXMF/tex/latex/dvipdfmx/dvipdfmx.def
+ to contrib/latex/dvipdfmx.def.sample.
+
+ * mpost.c:
+ Support MPS files generated by MetaFun.
+
+ * pdfximage.c:
+ Try distiller specified in the configuration file
+ if interpreting MPS file fails.
+
+2008-05-16 Matthias Franz
+
+ * pdfobj.c:
+ Fixed incorrect size entry in xref stream dictionary.
+
+ * pdfparse.c:
+ Fixed a bug in hex string parsing.
+
+2008-05-16 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c, spc_pdfm.c, dpxfile.c, otl_conf.c:
+ Restore the application name from "dvipdfm" to "dvidpfmx".
+ Notice that "dvipdfmx.cfg" must be located in "$TEXMF/dvipdfmx".
+
+ * dvipdfmx.c, fontmap.c, fontmap.h, spc_pdfm.c:
+ Support font mapping files with DVIPS/pdfTeX format.
+
+2008-05-13 Matthias Franz
+
+ * cid.c, dvipdfmx.c, epdf.c, mpost.c, pdfencoding.c, pdfobj.c, pdfobj.h, pdfparse.c, pdfparse.h, pdfximage.c, pdfximage.h, spc_pdfm.c, xbb.c:
+ Changed code for PDF import so that objects are not duplicated
+ if they are imported through several pages of the same file.
+ Some PDF parsing functions now take an additional argument
+ of type pdf_file. If this is NULL, them indirect references
+ are not accepted.
+
+2008-05-10 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dpxfile.c, pdffont.c:
+ Support Mac OS X Resource Fork Font (/rsrc) with TrueType outlines.
+
+2008-05-09 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * truetype.c, cidtype0.c, cidtype2.c, pdffont.c, pdffont.h, sfnt.c, sfnt.h, tt_glyf.c, tt_cmap.c, tt_table.c, tt_aux.c, dpxfile.c, dpxfile.h:
+ Support Mac OS X Data Fork Font (.dfont) with TrueType outlines.
+
+2008-05-08 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cidtype0.c, cidtype2.c, tt_aux.c, tt_table.c:
+ Support Mac TrueType fonts without OS/2 table.
+
+2008-04-28 Matthias Franz
+
+ * src/pdfencoding.c, src/pdfobj.c:
+ No declarations after statements allowed in C89.
+ (contributed by Vladimir Volovich <vvv at vsu.ru> via Karl Berry)
+
+ * src/Makefile.am:
+ xbb needs zlib too.
+ (contributed by Karl Berry <karl at tug.org>)
+
+ * m4/maw-kpse.m4, maw-libs.m4 (removed):
+ Renamed ...
+ * m4/chi-kpse.m4, cho-libs.m4 (new):
+ ... into these.
+ * Makefile.am:
+ Added `ACLOCAL_AMFLAGS -I m4'.
+ * configure.in:
+ Use new names; respect library dependencies; moved macro
+ definitions ...
+ * m4/maw-time.m4 (new):
+ ... to here.
+ * acinclude.m4 (removed):
+ Moved macro definitions ...
+ * m4/maw-kpse.m4, maw-libs.m4 (both new):
+ ... to here.
+ (all contributed by Peter Breitenlohner <peb at mppmu.mpg.de>
+ via Karl Berry)
+
+2008-04-06 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * configure.in: respect library dependencies.
+
+2008-03-04 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * Makefile.am: added `ACLOCAL_AMFLAGS -I m4'
+ * configure.in: moved macro definitions ...
+ * m4/maw-time.m4 (new): ... to here
+ * acinclude.m4 (removed): moved macro definitions ...
+ * m4/maw-kpse.m4, maw-libs.m4 (both new): ... to here.
+
+2008-03-01 Matthias Franz
+
+ * dvipdfmx.def:
+ Write bounding box information only if necessary.
+
+ * dvipdfmx.def, spc_util.c:
+ New 'clip' parameter for 'pdf:epdf' and 'pdf:image'
+ specials. 'clip 1' enables clipping (default),
+ 'clip 0' disables it.
+
+2008-02-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Allow maintainer mode to regenerate files.
+ * configure.in, acinclude.m4: added AC_DEFINES's third arg to
+ provide autoheader templates.
+ * configure.in: use AC_DEFINES for XETEX and XETEX_MAC.
+
+2008-02-13 Matthias Franz
+
+ * dvipdfmx.def, epdf.c, pdfdoc.c, pdfximage.c, pdfximage.h, spc_dvips.c, spc_html.c, spc_misc.c, spc_pdfm.c, spc_util.c, spc_util.h:
+ Added new 'page' parameter to PDF and PS inclusion. This
+ can be used with the graphicx package and the (experimental)
+ graphics driver dvipdfmx.def (see contrib/latex). Example:
+
+ \includegraphics[page=4]{a.pdf}
+
+ Page numbers can also be negative; the last page is -1.
+
+ Remarks:
+ 1) Currently PDF objects may be duplicated in the output
+ if several pages are included from the same file.
+ -- done (2008-05-13)
+ 2) The graphicx package currently uses the same bounding
+ box information (that of the first page) for all pages.
+
+2008-02-13 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * acinclude.m4, aclocal.m4, configure.in, configure:
+ Karl Berry reports configure fixes for TeXLive.
+
+ * pdfencoding.c, pdffont.c:
+ Fix an encoding bug by the MinionPro package;
+ reported by Juho Lee.
+
+2008-02-12 Matthias Franz
+
+ * pdfencrypt.c:
+ Encrypted PDF files with key lengths strictly between
+ 40 and 128 bits could not be opened. Changed code to
+ meet Adobe Reader's behaviour for revision 3 (PDF 1.4)
+ encryption.
+
+2008-02-08 Matthias Franz
+
+ * epdf.c, pdfobj.c:
+ Improved PDF document parsing: pages without contents,
+ undefined indirect references and media boxes with
+ indirect references are now allowed. (Undefined
+ indirect references are needed for documents with
+ several cross-reference tables if the trailer contains
+ a reference to an object outside the part of the
+ xref table seen so far.)
+
+2008-01-11 Matthias Franz
+
+ * dvipdfmx.c:
+ Fixed a bug in processing DVI comments.
+
+ * cmap_read.c, pst.c, pst_obj.c , t1_load.c:
+ Fixed a bug in postscript number parsing; reported
+ by Ulrike Fischer.
+
+2008-01-06 Matthias Franz
+
+ * type1.c, type1c.c:
+ Fixed a bug in the computation of glyph width arrays
+ for Type1 and Type1C font dictionaries; reported by
+ Ulrike Fischer.
+
+2007-12-05 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_pdfm.c:
+ Fixed a memory deallocation problem in the ConTeXt sample of
+ Francesco Pretto.
+
+2007-12-03 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cmap.c:
+ Code mappings in CMap may overlap, but succeeding maps
+ superceded preceding maps; reported and patched by Luo Jie.
+
+2007-11-27 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdev.c:
+ Restored the DVIPDFM code for calculation of kerns;
+ reported by Keiichirou Shikano.
+
+2007-11-22 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdev.c:
+ Fixed a bug related to calculate kern; reported by
+ Keiichirou Shikano.
+
+ * spc_util.c:
+ Fixed a memory deallocation bug.
+
+2007-11-18 Matthias Franz
+
+ * vf.c:
+ Fixed small memory leak.
+
+2007-11-17 Matthias Franz
+
+ * pdfobj.c:
+ Suppress unnecessary white-space in PDF arrays.
+
+ * dpxfile.c, dvipdfmx.c, mem.c, mem.h, tfm.c, xbb.c:
+ Fixed some small memory leaks.
+
+2007-11-15 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cid_basefont.h:
+ Add a predefined simplified Chinese font, AdobeHeitiStd-Regular.otf.
+
+ * pdffont.c:
+ Fixed a bug causing problems with Type0 fonts;
+ reported by Akira Kakuto.
+
+2007-11-13 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dpxutil.c, dpxutil.h, dvipdfmx.c, mem.c, mem.h, fontmap.c, pdfdoc.c, pdfdoc.h, pdfobj.c, pdfobj.h, subfont.c, subfont.h, vf.c, dpxfile.c, xbb.c:
+ Applied the memory leak patch by Matthias Franz.
+
+ * pdfencoding.c, pdfencoding.h, pdffont.c, type1.c, type1c.c, truetype.c, pkfont.c:
+ Applied the encoding patch by Matthias Franz.
+
+ * agl.c, agl.h:
+ Introduced new predefined glyphlist.txt; contributed by
+ Matthias Franz.
+
+2007-11-03 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * mpost.c:
+ Fixed a bug in skip_prolog(), which is unable to skip prolog.
+ Now work with "prologues:=3" mode in metapost 1.000.
+
+2007-07-03 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cff_dict.c:
+ Fixed a bug in pack_real() using work_buffer twice;
+ found by Takanori Uchiyama and reported by Akira Kakuto.
+
+2007-06-30 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cidtype0.c, cff_dict.h:
+ Fixed a bug checking cid >= CIDCount, which causes a problem
+ with some CJK otf fonts without having the CIDCount value.
+
+2007-06-28 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cff_dict.c:
+ Modified pack_real() to support musix20.pfb in Mac OS X 10.4 Quartz.
+ It seems that Mac OS X 10.4 Quartz has a bug on reading real numbers
+ in CFF font format. Since Mac OS X 10.4.10 the problem was solved.
+
+2007-05-18 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * jpegimage.c, pngimage.c, pdfximage.c, pdfximage.h, dvipdfmx.c, xbb.c:
+ Updated "xbb" to generate ".xbb" not ".bb". There is a big
+ difference between "xbb" and "ebb" in handling bitmap images.
+ In the case of bitmap images not having density information,
+ there is no way to know the density (or DPI) of the image.
+ "ebb" always assume that the image has 100 DPI so that
+ 100 pixels = 1 in = 72 bp. However, in this case, screen
+ capture image does not look clear. Thus, "xbb" follows pdfTeX,
+ which uses density information if exists, otherwise 72 DPI,
+ i.e., 72 pixels = 1 in = 72 bp, is used. With the modified
+ "dvipdfmx.def" driver for the LaTeX graphics package, you can
+ get the same result as pdfTeX.
+
+2007-05-04 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * xbb.c:
+ New program "xbb" extending "ebb".
+
+2007-05-03 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfximage.c, pdfximage.h, dvipdfmx.c:
+ Support bbox for "pdf:image" special (experimental).
+ The program "ebb" extracting the bounding box of image files
+ always multiply 72/100 for bitmap images (png and jpg).
+ It causes some trouble with LaTeX graphicx package which read
+ the bounding box from ".bb" file usually generated by "ebb".
+ New experimantal option "-C 0x0020" is introduced. With this
+ option, dvipdfmx no longer multiply 72/100 for bitmap images
+ so that users can get the same result as pdftex.
+
+2007-04-25 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_pdfm.c:
+ Extended pdf:outline special to support open/close bookmark.
+ The previous version 20070409 had problem because toclevel
+ of part is -1 in some class files.
+
+2007-04-24 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_util.c:
+ Predefined colors, Black, White, and Gray caused some problem
+ in Adobe Reader 7 and 8; but not in other PDF viewers, e.g.,
+ Previewer.app. It was solved by changing cmyk value to gray value.
+
+2007-04-17 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c, pdfobj.c:
+ The default of the PDF minor version was changed from 3 to 4.
+
+ * type1.c:
+ A bug was reported from Werner Lemberg (run nfssfont.tex for
+ the font ptmr8y). It happened when any character is used more
+ than one in one encoding file (e.g., texnansi.enc). To fix it,
+ Encoding resource was revived (but Hirata noted that there was
+ some problem with Ghostscript, not confirmed yet) and Widths
+ resource was changed to look up correct glyphs according to the
+ given encoding.
+
+ * vf.c:
+ Suppress an annoying warning message if no verbose option is given.
+
+2007-04-13 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * tt_cmap.c:
+ Support OpenType with PID=0, EID=3
+
+2007-04-09 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvipdfmx.c:
+ Updated the usage as suggested by Matthias Franz
+
+2007-04-03 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfobj.c, pdfdoc.h, pdfencrypt.c, pdfencrypt.h, pdfobj.c, pdfobj.h, pdfparse.c, dvipdfmx.c:
+ Support object stream for PDF v1.5 or higher; contributed by
+ Matthias Franz. Previewer.app in Mac OS X did not work with
+ encryption under v1.5, but no problem with Adobe Reader 8
+
+2007-03-26 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfobj.c:
+ Support xref stream for PDF v1.5 or higher; contributed by Matthias Franz
+
+2007-03-17 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dpxfile.c:
+ Fixed a bug in reading .enc file; reported by Matthias Franz
+
+
+2007-02-28 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * epdf.c:
+ Fixed a problem in handling Cropbox
+
+2007-02-14 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cidtype0.c tt_glyf.c tt_table.h, tt_table.c:
+ Fixed a bug in reading htmx and vtmx tables; reported by
+ Jjgod Jiang based on the solution by Jonathan Kew
+
+2007-01-21 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * fontmap.c:
+ Fixed typos found by Jonathan Kew
+
+2007-01-20 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * specials.h:
+ Fixed warning message in the IRIX compilation,
+ reported by Karl Berry and found by Olaf Weber
+
+2007-01-19 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * fontmap.c:
+ Fixed a bug reported by Shigeru Miyata on Dec 28, 2005
+
+ * spc_html.c:
+ Fixed a bug reported by Nobuyuki Tsuchimura on Jan 19, 2007
+
+2006-12-20 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * configure:
+ Remake using autoconf-2.59
+
+ * configure.in config.h.in src/pdfdoc.c:
+ Apply tm_gmtoff related modifications by Karl Berry
+
+2006-12-15 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * configure aclocal.m4 Makefile.in src/Makefile.in data/Makefile.in:
+ Remake using aclocal-1.6, automake-1.6, and autoconf-2.59
+
+ * configure.in src/Makefile.am data/Makefile.am:
+ Apply configure related modifications by Karl Berry
+
+2006-12-11 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * mpost.c, pdfdev.c, pdfdev.h, spc_pdfm.c, pdfcolor.c, pdfcolor.h,
+ pdfdraw.c, pdfdraw.h:
+ Temporary implementation for mps files generated by mptopdf.
+
+2006-12-11 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfcolor.c:
+ Fixed the color bug reported by H. J. Lee and Pablo Rodriguez.
+
+2006-12-07 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfobj.c:
+ Fixed a bug with xref, reported by Paul Guyot.
+
+2006-12-06 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * t1_load.c:
+ Modified to work with broken fonts, e.g. belleek/blsy.pfb.
+
+ * dvipdfmx.c, dvi.c, dvi.h:
+ Add xoffset and yoffset specials.
+
+2005-12-18 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dpxfile.c:
+ Fixed a bug found by Karnes Kim.
+
+2005-10-14 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_tpic.c:
+ Fix a bug on spc_handler_tpic_bk() and spc_handler_tpic_wh();
+ reported by Akira Kakuto.
+
+2005-08-31 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdoc.c, pdfdraw.c:
+ Stroke and fill color controls with gsave and grestore.
+
+2005-08-30 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdraw.h, pdfdraw.c, mpost.c:
+ Fix a bug on MetaPost manipulation.
+
+ * pdfobj.c:
+ Allow PDF images generated from Mac OS X.
+
+ * truetype.c:
+ Fix a bug on PK Type3 font.
+
+2005-08-24 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_pdfm.c:
+ Fix a bug on finding XObject.
+
+2005-08-23 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdraw.h, pdfdraw.c:
+ Fix a bug on matrix concatenation and inverse matrix.
+
+ * spc_pdfm.c:
+ Fix a bug on giving object name in image.
+
+2005-08-15 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdoc.c, spc_pdfm.c, specials.c:
+ Fix a bug on article|bead|thread specials.
+
+2005-08-14 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_html.c, spc_pdfm.c, specials.c:
+ Fix a bug causing memory leak, and correct a typo.
+
+2005-08-12 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdev.c, pdfdev.h, spc_dvips.c, spc_pdfm.c, spc_util.c:
+ Modified transform_info structure using pdf_tmatrix.
+
+2005-08-11 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfdoc.c, pdfdraw.c, pdfdraw.h, spc_pdfm.c:
+ Optimization of changing transform matrices.
+ The "pdf:literal" special works almost same as pdfTeX's
+ "\pdfliteral" primitive. But "pdf:literal direct" is slightly
+ different from pdfTeX's "\pdfliteral direct". It does not
+ affected by "pdf:literal".
+
+2005-08-08 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * spc_pdfm.c:
+ Test implementation of \special{pdf:literal ...}.
+
+ * spc_misc.c:
+ Ignores \special{pos: ...} too.
+
+ * spec-dpx.tex:
+ Modified to fit the changes introduced in 2005-08-08.
+
+2005-08-02 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvi.c, spc_pdfm.c:
+ Fixed a few bugs introduced by changes in 2005-08-01.
+
+ * dvipdfmx.def, spec-dpx.tex:
+ Modified to fit the changes introduced in 2005-08-01.
+ ConTeXt module still has a bug, e.g., \handleMPfshow.
+
+2005-08-01 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * specials.c, spc_html.c, spc_pdfm.c:
+ Various minor changes to specials.
+ Rewriting HTML special support.
+
+2005-07-31 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * specials.c:
+ Fixed a bug introduced by changes in 2005-07-30.
+ (@page1 not handled correctly)
+
+2005-07-30 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * colors.h: removed
+ Color definitions placed into spc_util.c.
+
+ * pdfdev.c, pdfdraw:
+ Various changes.
+
+ * pdfcolor, pdfdoc:
+ set_bgcolor pdfcolor --> pdfdoc.
+
+ * cid.c:
+ Force fixedpitch option for printer/acro fonts.
+
+ * spc_*, specials.c:
+
+ * And many others....
+
+2005-07-28 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfdev.c:
+ Simply use sprintf for printing numbers.................
+ Fixed an ancient bug causing very frequent (unnecessary)
+ font selection.
+
+2005-07-21 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfencoding.c: Fixed bugs.
+
+ * truetype.c: Update and various changes.
+ Apply ligature GSUB for glyph name "a_b" and glyph names
+ with AGL mapping to multiple Unicode character sequence.
+ Suffixes "liga", "dlig", "frac" ... are always recognized
+ as feature tag for glyph composition. But for "a_b.vert",
+ dvipdfmx first compose glyph "a_b" (by some way) and then
+ apply "vert" substitution to composed glyph. It may often
+ behaves unexpectedly. Suffixes like "aalt1" is treated as
+ alternate substitution; e.g., "a.salt1" is interpreted as
+ first stylistic alternate of default glyph for "a". Those
+ features are just for completeness. (esp. alternate GSUB)
+ Reorganized various process of finding glyphs, but still
+ complicated. TTC is supported (but index is always 0).
+
+2005-07-20 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdffont.c:
+ Minor changes.
+
+ * pkfont.c:
+ Mostly rewritten. Allow .enc file to be specified
+ in fontmap. But it is not for reencoding but to get
+ glyph names for ToUnicode creation.
+
+ * dpxfile.c:
+ Check file type.
+
+ * pdfcolor.c, vf.c: Don't use strcasecmp, strncmp.
+
+2005-07-18 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfximage.c:
+ Set image format conversion filter to NULL if empty
+ string "" is given. Put various system dependent things
+ into dpxfile.c.
+
+ * dpxfile.c:
+ Creation of temporary files, call other program
+ via system() to apply filter to file.
+
+ * dpxconf.c, dpxconf.h: new files
+ Currently paper format related codes.
+
+ * dvipdfmx.c: cleanup
+ Papersize handling --> dpxconf.c
+ Removed undocumented extension for page label.
+
+ * dvipdfmx.c:
+ 's' option for MPS-to-PDF conversion mode. Treat page
+ numbers as suffix. For "dvipdfmx -M -s 1-3 foo",
+ dvipdfmx first tries to open "foo". If "foo" exists,
+ it then start conversion of "foo" (ignore 's'), if not,
+ "foo.1", "foo.2", and "foo.3" is searched and multi-page
+ PDF file is generated.
+
+2005-07-17 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * spc_dvips.c:
+ Fixes in psfile special.
+
+2005-07-17 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dpxutil.c, dpxutil.h:
+ Added few functions to make fontmap.c independent
+ from pdfparse.c. Various parse_xxx from pdfparse.c.
+ mangle_name() removed.
+
+ * pdfparse.c, pdfparse.h, dpxutil.c, dpxutil.h, ...:
+ Several parsing routine moved to dpxutil.c.
+ parse_c_ident() is not really for "C" ident.
+ parse_c_string() is not really for "C" string.
+ And there are too many unclear parse_xxx routines
+ unrelated to PDF in "pdfparse".
+ There are many uncertainty in parsing \special too.
+
+ * spc_xxx:
+ skip_white() wrongly used in many places.
+ skip_white() skips from '%' to newline...
+
+ * pdf:tounicode, pdf:mapfile, and pdf:mapline
+ using very different syntax than other pdf:
+ prefix specials.
+
+ * dvi.c, pdffont.c:
+ Minor changes in debug and error message.
+
+ * psimage.c, psimage.h, t1crypt.c, t1crypt.h: Removed.
+
+ * t1_load.c: Merge t1crypt
+
+ * pdfximage.c, pdfximage.h: Merge psimage
+ psimage.c is not really for PostScript support.
+ It just call external program to do conversion form
+ PS to PDF. There are no reason to restrict this to
+ from-PS conversion.
+
+ * fontmap.c:
+ Do not use pdfparse.c. Added 'u' option to specify
+ "ToUnicode". This is for testing. Don't use this.
+
+ * pdffont.c:
+ Read ToUnicode CMap specified in fontmap.
+
+ * spc_util.c: HSB color...
+ Converted to RGB.
+
+ * cidtype0.c, cidtype2.c:
+ Do not use mangle_name in dpxutil.c.
+
+ * Various fixes related to pdflimits.h:
+ This only contains PDF_NAME_LEN_MAX.
+
+2005-07-16 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * fontmap.c, fontmap.h
+ Create fontmap entries for each subfont, containing
+ SFD mapping information and "link" to fontmap entry
+ "foo@SFD@". Removed pdf_lookup_fontmap_record2().
+
+ * dvi.c, mpost.c, pdfdev.c:
+ Modification needed by changes in fontmap handling.
+
+ * spc_pdfm.c:
+ Minor changes in fontmap specials. Fixed leak in
+ "append" fontmap.
+
+ * subfont.c, subfont.h:
+ Minor fixes and changes.
+
+ * mpost.c: Bug fix.
+ Fixed a bug (typo) in mp_setfont.
+
+2005-07-14 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * subfont.c, subfont.h:
+ xxx_sfd_yyy -> sfd_xxx_yyy
+ Added code for testing SFD file handling.
+ Added various comments.
+
+ * fontmap.c:
+ Check if subfont ID is valid before loading
+ SFD mapping table for subfonts.
+ Changes related to the above changes in subfont.c.
+
+2005-07-13 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dvipdfmx.c: minor fix
+ agl_set_verbose() called in pdffont.c too.
+
+ * fontmap.c:
+ Workaround for problems in subfont fontmap lookup.
+ Delete all conflicting explicit fontmap entries for
+ subfonts in pdf_insert_fontmap_record() when adding
+ fontmap entry with @SFD@ extension.
+
+ * subfont.c, subfont.h:
+ Scan SFD file for valid subfont IDs. (Required by
+ changes made to fontmap.c mentioned above.)
+ Removed unnecessary file static variables.
+ Simplified file reading and parsing.
+
+ * dvi.c: set_verbose() for subfont.c
+
+ * fontmap.c:
+ Correctly handle fontmap entry like "dmj@DNP@12".
+
+2005-07-11 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * agl.c: Fixed various small bugs
+
+2005-07-09 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * fontmap.c, fontmap.h, pdfdev.c: Fake-bold again
+ 'b' option. This is experimental feature.
+
+ * pdfdev.c:
+ Graphics state is not properly managed yet.
+ Fake-bold and set_rule changes linewidth without
+ using pdf_dev_setlinewidth().
+ Enclose set_rule with q and Q.
+
+ * agl.c: Removed unused variable
+
+2005-07-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_cmap.c: Bug fix
+ Format 12 cmap subtable support not working...
+
+ * fontmap.c: Test for UCS-4
+ 'p' option to specify UCS plane.
+ This is just for testing purpose. Don't use that.
+
+2005-07-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_cmap.c: Bug fix in ToUnicode creation
+ ToUnicode CMap creation (inversion of TrueType cmap) was
+ not working for format 12 cmap subtable.
+
+2005-06-27 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cid_basefont.h:
+ Add missing font definitions.
+
+ * data/config/dvipdfmx.cfg:
+ Forgot to mention that 'D "..."' line is commented.
+ Now there are no default setting for image converter,
+ so PS inclusion will always fail unless you modify
+ dvipdfmx.cfg.
+
+2005-06-26 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * data/config/cid-x.map: empty
+ Contained examples for fonts with unclear license.
+ Not maintained for a long time.
+
+ * data/CMap/Adobe-Identity-UCS2: removed
+ Wrongly named file. Content of this file is
+ actually identity mapping.
+
+ * type0.c:
+ Create dummy ToUnicode CMap "Adobe-Identity-UCS2".
+
+ * specials.c:
+ spc_push_object() always create label for objects.
+ Objects created with pdf:obj should always be written
+ to output.
+
+ * ainclude.m4, configure.in:
+ Define __TDS_VERSION__, require xbasename in kpathsea,
+ removed unused macros, simplified.
+
+ * dpxfile.c:
+ Use __TDS_VERSION__ instead of HAVE_KPSE_ENC_FORMAT
+ and others.
+
+ * dvipdfmx.c:
+ Alwyas use xbasename().
+
+ * fontmap.c, fontmap.h:
+ Fake bold and OTL options removed.
+
+ * otl_conf.c:
+ Deactivated.
+
+ * pdfdev.c:
+ Fake bold option removed. (undocumented)
+
+ * configure.in, acinclude.m4:
+ Various changes. Error if kpathsea library doesn't
+ have xbasename().
+ Define __TDS_VERSION__, removed HAVE_KPSE_XXX_FORMAT.
+
+ * configure and others: recreated
+
+2005-06-20 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_gsub.c, tt_gsub.h: Alternate substitution
+ LookupType 3 (Alternate Substitution) GSUB lookup.
+ Unused.
+
+2005-06-13 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_gsub.c:
+ Added support for LookupType 7 (Extension Substitution).
+ Large CJK fonts may want them. Not tested well.
+
+2005-06-09 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_glyf.c:
+ Set top-side bearing to (sTypoAscender - bbox.ury) for
+ fonts without vmtx table (vertOriginY = sTypoAscender).
+
+2005-06-09 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dpxfile.c:
+ Fixes for old kpathsea library.
+
+2005-06-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dpxfile.c, dpxfile.h:
+ Fallback to old path searching behaviour.
+ Warn about files found in old location.
+
+ * dvipdfmx.c:
+ set_verbose() for dpxfile.
+
+2005-06-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cid_basefont.h: Update for Adobe Reader 7
+
+ * cid.c, pdfobj.c: Accept version tag 1.6
+
+2005-06-06 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * acconfig.h: removed
+
+ * data/CMap/glyphlist.txt: --> data/config/
+ No appropriate place yet.
+
+ * cmap_read.c:
+ Fixed a bug in reading CIDSystemInfo dict.
+
+ * pdfencoding.c, pdfencoding.h:
+ pdf_load_ToUnicode_stream(). Load ToUnicode CMap from file and
+ then create ToUnicode stream object.
+ See also changes in truetype, type1, type1c, and pdffont.
+
+ * pdffont.c:
+ First try to load ToUnicode CMap with file name 'tfm_name'.
+ See also changes in truetype, type1, type1c, and pdfencoding.
+
+ * truetype.c, type1.c, type1c.c
+ Don't create ToUnicode if fontdict already have them.
+ See also changes in pdffont and pdfencoding.
+
+ * Makefile.am, data/Makefile.am, src/Makefile.am:
+ Fixes, simplified, updated...
+ There are problems in data/Makefile.am yet. Installation
+ directory for .map and .cmap is not correctly set.
+
+ * Makefile.in and others: recreated
+
+ * configure.in:
+
+2005-05-07 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * spc_color.c:
+ Color special without push/pop allowed?
+
+ * spc_pdfm.c:
+ pdf:literal broken for more than 2 years?
+ Fixed a bug in creating annot.
+
+ * data/config/dvipdfmx.cfg:
+ Comments...
+
+2005-05-04 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * README: update
+
+ * pdfparse.c:
+ There were several problems in handling broken PDF files.
+
+ * pdfobj.c:
+ There were several problems in handling broken PDF files.
+ Stream dict is freed twice when parsing stream object failed.
+
+ * tfm.c:
+ PK font creation was not working due to incorrect design size
+ value returned by tfm_get_desing_size().
+
+ * index.html:
+ Update and fixes for links. Many sentences doesn't make sense
+ when the document is printed. Stylesheet default to "plain"
+ style. Encoding set to "utf-8".
+
+ * style.css: renamed to style_dflt.css
+
+ * style_plain.css:
+ Plain style stylesheet.
+
+2005-03-07 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfcolor.c:
+ Color not correctly reset at page break?
+ Maybe more bugs...
+
+ * pdfdoc.c:
+ Encapsulating docxxx within single struct pdf_doc.
+
+2005-03-05 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * mpost.c:
+ Text handling was not correct for subfonts.
+
+ * pdfencoding.c:
+ Increased verbose level for ToUnicode warning.
+
+2005-02-03 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * otl_conf.c, spc_pdfm.c:
+ Fixed remaining bugs related to MiKTeX file searching.
+
+ * cvs tag: DVIPDFMX-20050201 (revised)
+
+2005-02-01 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * cidtype2.c:
+ Fixed a critical bug on the DW entry for CIDType2 fonts.
+
+ * cvs tag: DVIPDFMX-20050201
+
+2005-01-06 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * dvi.c: Fixed a bug on converting subfont character numbers.
+
+ * snapshot: two snapshots
+ DVIPDFMX-20040824 (release): before full update
+ DVIPDFMX-20040912 (current): with the bug fix on 2005-01-06
+
+2004-09-12 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * specials: rewriting...
+ All \special related files renamed to spc_xxxx and specials.
+ Use function pointer table rather than doing everything with
+ if-else or switch-case.
+
+ * pdfparse.c:
+ Few functions are expelled from pdfparse.c since they are not
+ related to PDF parse at all. pdfparse still contains dvipdfmx
+ only extension and they might be enabled even when parsing
+ ordinary PDF files.
+
+ * spc_pdfm, pdfparse:
+ tounicode special moved to spc_pdfm.
+
+2004-09-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * ttf, tt_*:
+ ttf.[ch] -> truetype.[ch], renamed few files, added tt_post.
+
+ * unicode, pdfencoding:
+ ToUnicode support migrated to pdfencoding.
+
+2004-09-05 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfencoding: encodings -> pdfencoding
+
+ * bug fixes.
+
+ * pdflimits: This was not pdflimits nor implementation limit
+ of PDF viewers at all.
+
+2004-09-02 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pngimage, jpegimage:
+ Improvement on embedded ICC profile support.
+ Profiles with same MD5 checksum are shared among images.
+
+ * pdfcolor:
+ Added something for managing color space resources.
+
+ * pkfont.c:
+ Depends on tfm.c again.
+
+2004-08-30 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfdoc, pdfdev:
+ Mostly independent from dvi interpreter.
+ pdfparse still depend on dvi.c through pdfspecial.c due to
+ pdf: special @xpos and @ypos.
+
+ * pdfdraw:
+ Primitive graphics drawing functions and graphics state
+ management: pdf_dev_moveto, pdf_dev_gsave, pdf_dev_lineto,
+ pdf_dev_flushpath, and so on (migrated from mpost.c).
+ PostScript, tpic, and all other graphics specials should not
+ directly access page content stream but must use those
+ functions instead. Text state and colors are still managed
+ completely differently.
+
+ * Added many comments in source and headers...
+
+ * Rearranged initialization process again.
+ pdf_init_fontmap: Initialize fontmapping database.
+ pdf_open_document: Open output file, initialize various
+ document resource handler, and set default media size...
+ pdf_init_device: Unit conversion, precision and others.
+ pdf_doc_begin_page: Initialize graphics state, etc.
+
+2004-08-27 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cidtype0.c:
+ Fixed several bugs in Type1 and CFF -> CID CFF converison.
+ There might be more bugs...
+
+ * doc/dpxunicode.pdf: Update.
+
+2004-08-24 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cid_basefont.h: Bug fix
+ Added missing '['.
+
+ * doc/dpxunicode.pdf: Update
+
+ * tt_cmap.c:
+
+2004-08-22 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * otl_conf.[ch]: New file
+ OTL feature is managed by configuration file.
+
+ * fontmap.c:
+ -S and -L option removed. Added option -l.
+
+ * doc/dpxunicode.pdf: Update.
+
+2004-08-16 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Unicode support for CID OpenType.
+
+2004-08-15 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * fontmap.c:
+ -f option changed to -S. Added -L for ligature substitution.
+
+ * tt_gsub.c and others: New fontmap option -L
+ Map ligatures not in Unicode to PUA.
+ ToUnicode support handle substituted glyphs.
+ See, doc/dpxunicode.pdf for details.
+
+2004-08-14 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * otl_opt.[ch]: New file
+ Handle fontmap options for OTL features.
+
+2004-08-11 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c: Bug fix.
+ The seac operator support was broken since 2004-8-02.
+
+ * fontmap.c: New fontmap option "-f tag" and "-b number".
+ Specify OpenType layout feature with -f option for "unicode"
+ endoding font. Glyph substituion specified by -f option is not
+ reflected in ToUnicode CMap yet. Only single substitution GSUB
+ subtable is supported.
+ The "-b" option specifies "boldness" parameter for fake-bold
+ (stroke line width of fill-then-stroke text).
+
+ * ...:
+ Changes for new features mentioned above.
+
+2004-08-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_cmap.c, cidtype0.c: Bug fixes
+
+2004-08-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Makefile.in, Makefile.am:
+ cmap_parse --> cmap_read.
+
+ * cmap_parse.[ch]: Remaned to cmap_read.[ch]
+
+ * cmap_write.[ch]: New file
+ Create CMap PDF stream object. Output is not efficient yet.
+
+ * dvi.c: Bug fix
+ Multiply pdf:pagesize special page height and page width by DVI
+ magnification factor.
+
+ * agl.[ch], unicode.[ch], ....:
+ Use cmap_write.
+
+ * dpxfile.[ch]: New file
+ .....
+
+2004-08-07 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Type1 font accept "unicode" encoding.
+ Converted to CIDFontType 0 CIDFont.
+
+2004-08-02 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * New files: t1_load.[ch], t1_char.[ch]
+ type1.c --> type1.c, t1_load.c, t1_char.c.
+ t1_load: load Type1 font (PFB) into cff_font structure.
+ t1_char: type 1 charstring interpreter and type 1 to type 2
+ charstring converter (type 2 encoder). There are many duplicated
+ code in cs_type2 and t1_char.
+
+2004-07-31 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * New files: pdfdraw.[ch], pdfcolor.[ch]
+
+ * mpost.c, tpic.c:
+ Use pdfdraw and pdfcolor.
+
+ * pdfdev.c:
+ CTM affects box calculation in dev_expand_box(). Special
+ bann/eann set correct bounding box for rotated text.
+
+ * New keyword "unicode" in fontmap:
+ The keyword "unicode" can be specified as encoding in fontmap.
+ With this option dvipdfmx creates Unicode-to-GID mapping CMap
+ and GID to Unicode (ToUnicode) CMap from TrueType cmap table
+ (format 4 Windows-UCS2 and format 12 Windows-UCS4 subtable is
+ supported) for TrueType font. All font with encoding "unicode"
+ is treated as Type0 font.
+ Currently supported only for Unicode TrueType font.
+
+
+2004-07-27 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Many bug fixes.
+
+ * fontmap.c: Bug fix.
+ Do not increment num_fontmap when replacing duplicate
+ entries.
+
+ * mpost.c:
+ Support PS operator findfont etc. Not compatible with dvips.
+
+2004-07-18 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * fontmap.c:
+ Add/replace/remove fontmap entries.
+ Added fontmap_add_map_record(). Scan single mapfile line.
+
+ * fontmap.c, pdfdev.c:
+ fontmap_tex_name(), ... abort if invalid value is passed.
+
+ * psspecial.c: bmpfile special
+ This is not PS special...
+
+ * pdfobj.[ch], pdfspecial.c:
+ Added pdf_copy_object(): Copy object data without changing
+ object label. Dvipdfmx now can handle pdf specials like:
+
+ \special{pdf:obj @foo << /Bar @bar >>}
+ \special{pdf:obj @bar << /Foo @foo >>}
+
+ Object reference can appear before definition of object.
+
+2004-07-15 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cidtype2.c, type0.c:
+ Write CID glyph metrics for non-embedded TrueType fonts.
+
+ * dvipdfmx.c, cidtype0.[ch], cidtype2.[ch], cid.[ch]:
+ Treat all CIDFont as fixed pitch font if bit 0x0004 is set
+ in "-C" option. (for backward compatibility)
+
+2004-07-14 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * New files: bmpimage.c, bmpimage.h
+ Windows BMP image format support. (not tested well...)
+ 1/4/8/24-bits per pixel images, uncompressed or 4-bit/8-bit RLE
+ compressed images are supported.
+
+ * pdfparse.c:
+ Added dictionary key "T" to the list of strings to be
+ converted to Unicode...
+
+2004-07-12 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dvipdfmx.c:
+ Added new option "-C".
+ Thumbnail support available again.
+
+ * tpic.c, tpic.h:
+ Spline path ("sp" command) was not handled correctly.
+ Use (semi-)transparent color for shading, enabled by option
+ -C 2. (not enabled by default since it requires PDF version
+ 1.4+) Apply shading only to closed paths.
+
+ * psspecial.c:
+ epsbox support was broken.
+
+ * pdfdoc.c: Thumbnail supported again
+
+2004-07-04 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * configure, ...:
+ HAVE_KPSE_OPENTYPE_FORMAT and HAVE_KPSE_ENC_FORMAT is not
+ correctly set when compiled with gcc3.
+
+2004-06-28 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfximage.c:
+ Do not clip PDF images when "clip" option is not given.
+
+2004-06-27 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Workaround for "three dot leader" problem.
+
+2004-06-16 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Do not adjust refernece point of included images if users do
+ not supply bounding box.
+
+ * Look for .ofm first.
+ Workaround for incompatibility introduced on change 2004-01-20.
+
+ * pdfdoc.c: Fixed bug that dvipdfmx crushes with null string key in
+ name tree.
+
+2004-06-02 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * pdfspecial.c: Bug fix on cropbox in do_bxobj().
+
+2004-05-03 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * jpegimage.c: Uninitialized variable.
+
+2004-04-09 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * README, index.html: update
+
+ * contrib/patches/glyphlist-cm-add.txt: new file
+ Additional glyphlist for Computer Modern font.
+
+ * NEWS: new file
+ Empty.
+
+ * pdfdev.c:
+ Do not increase line width.
+
+2004-04-03 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * README: update
+
+2004-03-25 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * jpegimage.c: ICC profile
+ Added APP2 ICC_PROFILE support.
+ ICC profile is not deleted from JPEG stream.
+
+ * Embedded ICC profile support for JPEG and PNG enabled.
+ ICC profiles are not cached. Alternate color space?
+
+2004-03-24 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Thumbnail support removed.
+
+ * index.html:
+ Quick check against WCAG 1.0. Lowercasified all HTML tags for
+ migration to XHTML.
+
+ * pdfdoc.c:
+ Dvipdfm/dvipdfmx copyright notice remved from PDF Docinfo's
+ /Producer string, simplified to "dvipdfmx (VERSION)".
+
+ * configure.in, configure:
+ Minor change.
+
+2004-03-22 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pngimage.c: Minor changes.
+
+ Remaining things for complete PNG 1.1 support is:
+ Complete iCCP support. Support tEXt and other metadata chunks
+ using XML Metadata stream. pHYS (and oFFs) support (in ebb).
+ Preserve filter (PNG predictor) if possible, but some softwares
+ using filters very inefficiently. 16-bit RGB/Gray (PDF-1.5).
+
+ JPEG (JFIF) can also store ICC profile with APP2. Implementing
+ very basic ICC profile support might be useful.
+
+2004-03-21 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * README: updated
+
+ * data/config/cid-x.map:
+ "slant" option -s supported in vertical mode.
+
+ * pngimage.c: Fixed a serious bug, more chunks supported.
+
+ Gamma obtained by png_get_gAMA() is inverse of screen gamma
+ that the image is prepared. Gamma is sometimes inverted...
+
+ Approximated CalRGB color space used along with /Intent if
+ sRGB chunk is found (not sure how to treat it).
+
+ Experimental iCCP support --enable-iccp.
+ Doesn't validate ICC profile embedded in PNG.
+ Range? Rendering Intent?
+
+ * pdfdev.c:
+ A line width of zero means thinnest line drawable in target
+ device. dev_rule() was wrongly changed to increase line width
+ if the width is too thin.
+
+2004-03-20 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * unicode.c, agl.c, type0.c: ToUnicode CMap support
+
+ Always create ToUnicode CMap for simple fonts regardless of
+ the existence of glyph list file. If 10% of glyph names can
+ not be converted to Unicode, ToUnicode CMap is not embedded.
+ The reason for the (non-zero) limit 10% is; ToUnicode CMap
+ is shared among fonts using same .enc file. In this case,
+ Unicode mapping is created for all glyphs in the .enc file
+ where non-standard glyph names like "visiblespace" is often
+ expected. But those glyphs are usually not used in the TeX's
+ output and hence it should be simply ignored if mapping is
+ not available.
+ Sharing ToUnicode CMap is not so efficient as expected for
+ simple fonts, "subsetted" ToUnicode CMap might be better.
+
+ type0.c search ToUnicode CMap named as REGISTRY-ORDERING-UCS2
+ or FONTNAME-UCS2, the latter case is for CIDFontType 2 font
+ using font's internal glyph ordering. It does not care about
+ the content of CMap at all, especially usecmap is not checked.
+ Don't use it.
+
+ * README, data/config/cid-x.map:
+
+ Description about -m option removed from README.
+ This option is no longer necessary for usual cases, and use
+ of it is not recommended as the original dvipdfm fails to read
+ fontmap file with this option.
+
+ * cmap.c:
+
+ Increment n-1 th byte if n-th byte overflow in bfrange like:
+
+ <00> <01> <00 FF>
+
+ The dstCode string is treated like an integer, but the number
+ of bytes required for that character code is not increased.
+ Acrobat's "ToUnicode" CMap contains such bfrange entries and
+ causing a serious problem in Korean TrueType fonts.
+
+2004-03-18 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfspecial.c:
+ pdf:literal direct should not translate origin.
+
+2004-03-17 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c, type1c.c, cmap.c, ...: Memory leak.
+
+2004-03-16 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * mpost.c, psspecialc.: Fixed bugs.
+
+2004-03-14 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dvipdfmx.c:
+ Scan first page's paper size special first.
+
+ * pdfparse.c: \x in PDF string - broken
+
+ This (undocumented) extension to the PDF string object disturbs
+ and interrupts PDF object parsing and subsequent text re-encoding
+ specified by tounicode special (another extension). And it makes
+ impossible to separate parsing and re-encoding process ("x" after
+ backslash representing Unicode hex value...).
+
+ Support for this extension was removed since it is desirable to
+ move (or isolate) tounicode special to the appropriate place, not
+ pdfparse but pdfspecial, if possible.
+
+ Note that this kind of extension might be incompatible with all
+ other PDF applications, "\x" should be treated as a single "x" in
+ literal strings (like PostScript).
+
+ * pdfspecial.c: Special image/uxobj is partially broken.
+
+ Special uxobj doesn't work for external images after the change
+ made on 2003-08-12. It only works for the grabbed page contents
+ created by special bxobj/exobj.
+
+ Access to XObject reference (but can't be placed in the document)
+ is now available again. Supporting uxobj is usually not necessary
+ for external images because they are always reused as a document
+ resource but allowing access to the (form) XObject's indirect
+ reference by name like @foo is usefull for using them as an entry
+ of appearance dictionary in annotations.
+
+ * pdfspecial.c, pdfdev.c:
+
+ Special bann/eann does not take account of current transformation
+ matrix correctly. It result in incorrect /Rect for all annotations
+ created by special bann/eann if transformation is applied.
+
+ Not fixed yet.
+
+ * pdfparse.c: "ToUnicode" special
+
+ Illegal PDF string is expected within pdf: specials. Many users
+ try to use raw Shift-JIS text without properly escaping backslash
+ appears in the 2nd byte of double-byte character. The same problem
+ occurs in many other encodings.
+
+ As a workaround for this problem, backslashes are not treated as
+ "escape" in some situation when the current "ToUnicode" CMap name
+ contains a substring RKSJ, B5, GBK, or KSC.
+
+ * cmap.c, ...:
+
+
+2004-03-12 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * mpost.c:
+ Skip until %%EndProlog.
+
+ * pdfspecial.c, pdfdev.c, pdfdoc.c:
+ pdf_doc_set_mediasize()/pdf_doc_get_mediasize().
+
+ * tfm.c
+ tfm.c was highly wasteful and inflexible.
+ Preparing for 31-bits character code support.
+
+2004-03-11 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dvipdfmx.c, dvi.[ch], pdfdev.[ch], pdfdoc.[ch],...:
+ An effort to eliminate complicated initilization chain...
+
+ * pdfximage.c, pdfximage.h: New file.
+ An effort to make image support more flexible.
+ Included images and grabbed page contents (forms) should be managed by
+ pdf_ximage as document resource (like font).
+
+ * pdfspecial.c, psspecial.c:
+ Image support moved to pdfximage. (might be broken)
+
+ * mpost.[ch], epdf.[ch], pngimage.[ch], jpegimage.[ch], psimage.[ch]:
+ Image support moved to pdfximage.
+
+ * dvipdfmx.c, mpost.[ch]:
+ Experimental "mpspdfmx" mode -M.
+
+ * pdfspecial.c, pdfdev.c, pdfdoc.c:
+ Hard to explain... There are many misleading/illogical things.
+
+ * dvipdfmx.c, dvi.[ch]:
+ DVI specials related to page/paper size is pre-scanned.
+
+ * dvipdfmx.c:
+ Page selection option "-s" accept page labels.
+ For example, command line option "-s 1-10/r,11-12/D:2:empty-page-,13-"
+ set page labels for page 1-10 to lowercase roman numerals, page 11-12
+ to arabic numerals starting with 2 and with prefix "empty-page-",...
+
+ * dvipdfmx.c:
+ An option for "bookmark open lavel" -O.
+
+ * pdfdoc.c:
+ Undocumented watermark/page decoration feature. Not completed yet.
+
+ * thumbnail.c:
+ I can hardly think that thumbnail support is useful. Acrobat Reader
+ can create thumbnail image and other PDF viewers like gs* and Xpdf
+ doesn't support it. Currently broken due to changes in pngimage.c.
+
+ * dvipdfmx.c, pdfdev.c:
+ The default precision set back to 2 fractional digits. Most sensitive
+ part is dev_set_string() but the accuracy of this part is essentially
+ limited to 0.01 point in the most cases. Increasing precision above 2
+ does not give good result (except DVI rules) but merely increases file
+ size.
+
+2004-03-05 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfdoc.c:
+ Fixed a critical bug introduced on change 2004-02-29:
+ Consistency check was done after pages are free-ed.
+
+ * pdfdoc.c, pdfspecial.c:
+ special pdf:names. Add name tree entry.
+
+ * pdfobj.c, pdfparse.c:
+ Few functions added for manipulating PDF array.
+
+2004-03-04 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfparse.c: Added missing () in macro PDF_TOKEN_END()
+
+ * pdffont.c: Compiler warning on uninitialized variable.
+
+2004-03-02 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Groff support:
+ Groff support was essentially broken. Dvipdfm(x) generated
+ very inaccurate result due to incorrect choice of scale/unit.
+ It should be fixed now.
+
+2004-02-29 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfspecial, pdfdoc, pdfobj, pdfparse:
+ Partially rewrote...
+
+ * pdfdoc.c:
+ Moved static ... to static struct { ... } docXXX.
+ Removed (strange) optimization.
+ Outline item open/close.
+
+ * tfm.c:
+ Partially rewote...
+
+2004-02-25 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Too many warnings when compiled with -Wshadow...
+ pdfdoc.c need to be fixed.
+
+ * -Wmissing-prototypes, -Wmissing-declarations
+
+2004-02-21 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type0.c:
+ Changes for New TDS/kpathsea.
+ Fixed a bug in get_tounicode_cmap()...
+
+2004-02-19 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cidtype0.c, type0.c:
+ Write CID glyph metrics for non-embedded CFF/OpenType fonts.
+
+2004-02-18 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tpic.c:
+ Ignore unpainted path in flush_path().
+ show_path() output 'n' operator for path without stroking nor filling
+ to avoid Acrobat error (bug?) "Illegal operation inside a path.".
+
+2004-02-17 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pkfont.c, pkfont.h, pdfdev.c:
+ Removed dependency to TFM in pkfont.
+
+ * type1.[ch], type1c.[ch], type0.[ch], ttf.[ch]:
+ No longer need to know font resource name and remap.
+
+ * pdffont.c, pdffont.h:
+ Added new file.
+
+ * type1.[ch], type1c.[ch], ttf.[ch], pkfont.[ch], pdfdev.c, dvipdfmx.c:
+ Simple font support will be unified to pdffont.c
+
+2004-02-16 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c, type1c.c, cidtype0.c:
+ Remove UniqueID and XUID from CFF Top dict.
+
+ * type1.c:
+ Keep original FontBBox instead of replacing it with tight one obtained
+ from glyph's charstrings to prevent Acrobat 4 from greeking text.
+ Acrobat 4 may display text drawn with fonts which only contain small
+ glyphs like period and minus-sign with greeked text.
+
+ * tt_build.c:
+ TrueType output slightly optimized.
+
+ * ttf.c, cidtype2.c:
+ Preserve 'name' table when embedding TrueType font.
+
+2004-02-15 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1c.c, cs_type2.c, cs_type2.h, cidtype0.c:
+ Dependency to TFM removed. Widths are obtained from font file.
+
+ * type1c.c:
+ Delete unused strings from CFF string index.
+
+ * tfm.c, tfm.h:
+ Added tfm_get_codingscheme(). CODINGSCHEME from TFM header.
+
+ * agl.c, agl.h, unicode.c, unicode.h, ttf.c:
+ Handle decomposed (in Unicode) glyphs in AGL and glyph names of a form
+ XXX_YYY_ZZZ in ToUnicode CMap. The glyph name with suffix, like "x.y",
+ is sotred as a glyph "x" with a suffix that implies a variant "y" of
+ "x" in AGL table, not as "x.y" glyph. (for future use)
+
+2004-02-13 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c:
+ Bug fix. Skip first four bytes of encrypted PFB section.
+ Not warn about "dotsection" operator which exist only for
+ compatibility to Type 1 font rasterizer that can't do hint
+ replacement.
+
+ * tfm.c, tfm.h:
+ Fixed a bug that calculation of tfm_string_height() was incorrect.
+ ASCII pTeX specific things are put within #ifndef WITHOUT_ASCII_PTEX.
+
+2004-02-12 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c:
+ Another bug in flex handling. hmoveto and vmoveto allowed.
+
+ * type1c.c, cmap.c, cidtype0.c, encodings.c, fontmap.c:
+ Changes for new TDS and teTeX/kpathsea.
+
+ * encodings.c, encodings.h, pdfdev.c:
+ Removed get_encoding().
+
+2004-02-10 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c:
+ Bug fix. Compression of vhcurveto-hvcurveto was not actually done.
+ One more bug in flex handling.
+
+2004-02-08 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dvipdfmx.c:
+ paperinit() and paperdone().
+
+ * tfm.c:
+ Bug fix. Read OFM level 1 header, required by get_design_size().
+
+ * dvi.c, dvi.h, vf.c:
+ DVI specials in virtual fonts (patch by P. TJ MacPhee).
+
+2004-02-05 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cid.c, cidtype2.c:
+ Use font's internal glyph ordering if CSI Adobe-Identity is
+ specified for TrueType font. This feature is intended to be
+ used with Identity CMap and /I option in fontmap.
+
+ * configure, acinclude.m4, acconfig.h, config.h.in,...:
+ Check kpse_{enc,cmap,sfd,opentype}_format.
+
+ * type1.c:
+ Fixed a bug in flex handling.
+
+2004-02-04 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * dvipdfmx.c:
+ libpaper support.
+
+ * configure, acinclude.m4, acconfig.h, config.h.in:
+ --with-paper added for configure option. HAVE_LIBPAPER in config.h.
+
+ * pdfspecial.c: Added "bp" and "truebp" in units[].
+
+ * Accept w<unit>,h<unit> for papersize option.
+
+2004-02-03 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c:
+ Counter control (othersubr #12 and #13) supported.
+
+2004-02-01 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_build.c, tt_build.h, cidtype2.c, ttf.c:
+ Workaround for Ghostscript's bug.
+ Ghostscript doesn't handle CIDToGIDMap correctly.
+ Use Identity CIDToGIDMap.
+
+ * ttf.c:
+ Removed dependency to TFM. Glyph metric is obtained from font file.
+
+ * type1.c:
+ Warn about "seac" operator.
+
+2004-01-31 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c: Bug fix.
+
+ * Added many 'const'.
+
+2004-01-29 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * type1.c: Type 1 -> Type 1C conversion
+ PostScript Type 1 font is converted to Type 1C (CFF).
+ There are few limitations: Ghost hint is not converted to edge
+ hint. The Type 1 charstring operator "dotsection" is ignored.
+ The ExpertEncoding is not supported. The "seac" operator is not
+ supported. Counter control is not supported.
+
+ * Makefile.in, Makefile.am, standardenc.h: standardenc.h removed.
+
+ * pst.c:
+ Fixed a bug in skip_comments() that cause infinite loop.
+
+2004-01-27 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cff.c, cff.h, cff_dict.c, cff_dict.h:
+ Added few functions for Type 1 -> Type 1C conversion.
+
+2004-01-24 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pkfont.c:
+ Acrobat and MacOS X's Preview have some problem with Type 3 font.
+ Acrobat cannot handle non-invertible transformation matrix which
+ happens when PK glyph with width and/or height equals to zero is
+ embedded as Type 3 font. The preview app. of MacOS X 10.3 cannot
+ display few glyphs generated by dvipdfm with unknown reasons.
+
+2004-01-21 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * cs_type2.c: Don't use rint().
+
+2004-01-21 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * psimage.c, configure.in, config.h.in:
+ Use mkstemp() if available.
+
+2004-01-20 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * tt_table.[ch], tt_build.[ch], cidtype[02].c:
+ CIDFont glyph metrics for embedded font.
+
+2004-01-17 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * pdfobj.[ch], pdfparse.[ch], mpost.c, pdfencrypt.c, pngimage.c:
+ Removed pdf_*_stringx().
+
+ * pdfobj.c, pdfparse.c: Changes for PDF-1.3 compliance.
+
+2004-01-14 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * ToUnicode support for CFF/OpenType + built-in encoding.
+
+ * Bug fix in cff.c, type1c.c
+
+ * Workaround for Shift-JIS string parsing in pdfparse.c.
+
+ * pngimage.c don't require PNG-write/MNG-feature/progressive-read.
+
+ * Unicode: unsigned short --> long.
+
+ * Removed winansi.h
+
+2004-01-07 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * IMPORTANT CHANGE:
+ Searching order is reversed in fontmap.c.
+ Last match takes precedence in font mapping now.
+
+ * Fixed bug in cff.c, cmap.c, and type1c.c.
+
+2003-12-28 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Bug fixes in pdfparse.c and cid_basefont.h.
+
+2003-12-15 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Minor fixes.
+
+ * Added PDF special "fstream" - create PDF stream object from file.
+ This allows users to attach files in PDF.
+
+2003-12-07 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * JPEG moved to jpegimage.c.
+
+ * Bug fixes.
+
+2003-12-06 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Changes in pdfspecail.c.
+
+ * Fixed a bug in mpost.c.
+
+2003-12-02 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Added a patch for dvipdfm's ebb.c. (PDF ArtBox support)
+
+2003-11-29 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Bug fixes.
+
+ * CFF/OpenType support for single-byte font.
+
+2003-11-26 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Little enhancement to epdf.c.
+
+ * Merged epsbox.sty patch by Noda.
+
+2003-11-25 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Many part of font/encoding related code rewrote.
+
+ * Unicode support for single-byte font.
+
+2003-11-10 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed a bug on the algorithm converting arc to cubic bezier
+ curves in arc() (tpic.c), which is reported by Werner Lemberg.
+
+2003-11-04 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * PNG support completely rewritten. Color pallete images are
+ now not converted to 24-bit RGB, colorspace Indexed is used
+ instead. Added tRNS and alpha chunnel (transparency) support.
+ Experimental gAMA, cHRM and sRGB support.
+
+2003-11-03 Shunsaku Hirata <hirata@project.ktug.or.kr>
+
+ * Fixed bug that dvipdfmx stops with error "Invalid Subr Index"
+ when embedding CFF OpenType font.
+
+2003-10-09 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Add a missing line including pdfparse.h in dvi.c, which is
+ reported by Akira Kakuto.
+
+ * Changed the default font map files for teTeX 2.x as suggested
+ by Haruhiko Okumura.
+
+2003-10-08 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * A bug on the paper size checking routine of dvi_paper_size()
+ in dvi.c is fixed, which is reported by Haruhiko Okumura.
+
+2003-10-06 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * A bug on the kerning routine of dev_set_string() in pdfdev.c is
+ fixed, which is reported by Edward G.J. Lee.
+
+2003-08-12 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Changed to embed images only one time.
+
+ * Updated configure.in and config.h.in to support WORDS_BIGENDIAN
+ and SIZEOF_SHORT, SIZEOF_INT, SIZEOF_LONG.
+
+2003-08-11 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * A faked font name was used for TrueType fonts without any PS
+ font name as suggested by Hin-Tak Leung.
+
+2003-08-05 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Built-in codes (originally from libgcrypt-1.1.42) was used
+ for PDF encryption instead of the OpenSSL library as suggested
+ by Thomas Esser.
+
+2003-07-28 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * A significant bug reported from Haruhiko Okumura is fixed.
+ The bug occurs only if compiled with gcc 3.x, not gcc 2.x.
+
+2003-03-26 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * New feature, hexadecimal Unicode, suggested by iNOUE Koich!
+ and Akira Kakuto is implemented.
+
+2003-03-13 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed bugs on reading and writing OpenType fonts.
+
+2003-03-12 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Applied changes for MiKTeX in ps_include() (psimage.c).
+
+2003-03-11 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed a bug in cff_charsets_lookup() (cff.c).
+
+2003-02-06 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed a bug in string_mode() (pdfdev.c) reported by iNOUE Koich!.
+
+2002-12-30 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed a bug in writing null array.
+
+ * Fixed a bug in reading CMap and encoding files in MiKTeX.
+
+2002-11-28 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Support color shading feature in ConTeXt.
+
+2002-11-25 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * New feature pdfdecimaldigits (default=3) is implemented.
+
+ * Fixed a missing line in dvipdfmx.c.
+
+ * Fixed a bug in page attribute boxes, e.g., CropBox, TrimBox.
+
+2002-11-11 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * The "pdf: dest" special reads pdf_object not pdf_array.
+
+ * Fixed a bug in finding encoding files with extension.
+
+ * Look up the entries in miktex.ini while finding files.
+
+2002-10-31 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed a bug in finding files with the kpathsea library 3.3.7.
+
+2002-10-28 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * The project name was changed to dvipdfmx from dvipdfm-cjk.
+
+ * Changed the way of finding files (MiKTeX and KPATHSEA)
+ (contributed by Akira Kakuto).
+
+ * Support embedded MetaPost graphics in ConTeXt using new PDF
+ special \special{pdf:literal [direct|reverse] ...}.
+
+2002-10-25 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Removed all files related to the original dvipdfm,
+ and all CMap files from Adobe.
+
+ * Changed the executable file dvipdfm to dvipdfmx,
+ the configuration file config to dvipdfmx.cfg,
+ the Type0 map file cid.map to cid-x.map.
+
+2002-10-24 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * It is possible to change the size of each page with the
+ special command \special{pdf:pagesize ...}. Override the
+ previous changes if there are two such commands in a page.
+
+2002-10-17 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed a bug in parsing an array in two lines. (mpost.c)
+
+ * Changed not to lookup the header to find fonts. (mpost.c)
+
+2002-10-09 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Duplication is allowed for named_references[]. (pdfspecial.c)
+
+2002-06-05 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed a bug in parse_key_val() found by Yasuhiro Okazaki.
+
+2002-05-31 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Bug fixed for ToUnicode conversion in PDF outlines(bookmarks),
+ docinfo, and text annotations (contributed by Akira Kakuto).
+
+ * Included the ToUnicode CMap, EUC-UCS2.
+
+2002-05-22 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Support CJK characters in PDF outlines(bookmarks), docinfo, and
+ text annotations (contributed by Akira Kakuto).
+
+2002-05-15 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * PDF encryption support with the OpenSSL library.
+
+2002-04-30 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * ToUnicode CMap (only Unicode) support for Identity-H(V).
+
+ * Included the ToUnicode CMap, Adobe-Identity-UCS2.
+
+2002-04-22 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Included two CMaps, UniKSCms-UCS2-H(V) which fix a bug in
+ UniKS-UCS-H(V).
+
+2002-04-17 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Changed xxx_set_debug() to #ifdef DEBUG.
+
+2002-04-16 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Improved reading PNG image files.
+
+ * Rearranged all files to work with GNU autotools.
+
+ * Removed HAVE_TTF_FORMATS and HAVE_OFM_FORMATS.
+
+2002-04-09 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Minor fix on 'source/pkfont.c'.
+
+2002-04-07 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Fixed all warning messages generated with MSVC++.
+
+ * Rewrote the functions 'xxx_locate_font()' again.
+
+2002-04-04 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Changed the order of loading virtual and physical fonts as
+ suggested by Akira Kakuto <kakuto@fsci.fuk.kindai.ac.jp>.
+ If map entries are found, virtual fonts will not be used anymore.
+
+2002-04-02 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Implemented no-embedding and stylistic variants for CIDFontType0.
+
+2002-03-31 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Added two CMaps, ETenms-B5-H and ETenms-B5-V.
+
+2002-03-30 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Minor fix on the patch by Takanori Uchiyama.
+
+2002-03-29 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Applied the patch by Takanori Uchiyama <uchiyama@appi.keio.ac.jp>,
+ supporting the direction command of ASCII pTeX's extension in
+ virtual fonts.
+
+ * Two CMaps, Identity-H and Identity-V are hard-coded in cmap.c.
+
+2002-03-20 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Applied the patch by Jungshik Shin, not embedding the unnecessary
+ character /.notdef in type1 fonts.
+
+2002-03-20 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Modified cid_basefont.h.
+
+2002-03-05 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Support for UTF8 encoding through Identity CMap.
+
+2002-02-25 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Implemented no-embedding feature for CIDFontType2.
+
+ * Implemented Bold, Italic, BoldItalic attributes for CIDFontType2
+ and CID predefined fonts.
+
+2002-02-22 Jin-Hwan Cho <chofchof@ktug.or.kr>
+
+ * Implemented subfont approach for CJK and HLaTeX.
+
+2002-01-07 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed bug introduced on 2002-01-05.
+
+2002-01-05 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Workaround for some bad TrueType fonts that does not have US-English
+ PostScript font name.
+
+2001-12-27 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Changed to parse all charstrings. Check for the SEAC character.
+
+ * Minor changes in CFF related codes.
+
+2001-12-26 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Merged cmap and cmap_parse.
+
+2001-12-25 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Cleaned up TrueType and CFF related codes.
+
+ * Minor bug fixes.
+
+2001-12-23 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed bug that always requires Private DICT(s) which may not exist.
+
+ * Cleaned up TrueType and CFF related things.
+
+2001-12-18 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Biased subroutine number is signed in cs_type2.c.
+
+2001-12-14 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * macglyphs.h regenerated from apple's TTRefMan.
+
+2001-12-13 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Minor cleanups.
+
+ * Fixed typo (yacture -> yacute, Islash -> lslash) in macglyphs.h.
+
+ * Fixed signedness of TureType cmap subtable format 0 data.
+
+2001-12-11 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Minor fixes.
+
+ * Fixed bug that interpretion of hmtx table is still wrong.
+
+ * Fixed fixed().
+
+ * More improved FontDescriptor for TrueType/OpenType fonts.
+
+ * Support for PostScript glyph name in TrueType post table.
+ Full subsettting is also available for non-CJK TrueType fonts.
+ Cyrillic and other TrueType fonts can be used.
+ Requires post table with version 2.0.
+
+2001-12-09 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Bug fixes.
+
+2001-12-05 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed bug that last entry of the loca table may not be read.
+
+ * DW is set to that of missing glyph (CIDFontType 2).
+
+ * Bug fixes.
+
+2001-12-04 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixes.
+
+2001-12-03 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Minor charnges, cleanups.
+
+ * Write CIDSet.
+
+2001-12-02 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Initial CFF CID-Keyed Font support.
+ Only Type 2 charstring is supported.
+
+2001-11-27 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Minor fixes, cleanups.
+
+2001-11-26 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed (serious) bug that hmtx table is incorrectly interpreted.
+
+ * Fixed bug that encoding ID of RPC and BIG5 are interchanged.
+
+ * Added missing cast in cidtype2.c.
+
+2001-11-25 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Bug fix.
+
+2001-11-24 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Added missing free() (RELEASE) in cidtype2.c.
+
+ * Minor fixes.
+
+ * Fixed typos.
+
+2001-11-22 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Clean up.
+
+ * Allow `Preview & Print' licensed fonts to be embedded.
+ TrueType OS/2 table is preserved.
+
+2001-11-20 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Minor cleanups. Fixed typos.
+
+ * Strip out bad strings form PostScript names;
+ -WIN-RKSJ-H, -WINP-RKSJ-H, -WING-RKSJ-H, and -90pv-RKSJ-H.
+ Some font uses PostScript name one of above strings appended,
+ even if Shift-JIS encoding is not used.
+
+2001-11-18 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Workaround for Omega: Omega uses setxxx (single-byte char) command
+ while double-byte font is in use. Pass character type to
+ dev_set_string() to distinguish single-byte and double-byte.
+ Maybe, it works with CJK-LaTeX by preparing set of CMaps.
+
+ * Write double-byte strings as hex strings.
+ This makes bit faster and tend to generate smaller PDF in most cases.
+
+ * CMap parser uses wrok_buffer in mfileio.
+
+ * Reserved w_array and w2_array in struct cid_font for future use.
+
+ * Now write /W array for TrueType, proportional latin and kana works
+ properly. The metric information are taken from font file, not from
+ TFM, to ensure we always have correct widths. The default width (DW)
+ is set to 1000.
+
+ * Changed sizeof() appeared in sfnt_put_xxx() to expected values in
+ sfnt.h. I do not assume LONG to be exactly 32-bit long, ....
+
+2001-11-17 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Added Chinese and Korean related stuff again. Chinese and Korean
+ languages are supported through Omega, or by achieving Ascii pTeX
+ compatibility.
+
+ * Closing CMaps is missing. Added cmap_close_all(), which is invoked by
+ dev_close_all_fonts() in pdfdev.c.
+
+ * Check length of output string for Type 0 font. It must be multiple of
+ 2. Omega uses 8-bit and 16-bit mixed string even for double-byte
+ fonts. This causes problems.
+
+ * Abort if missing/invalid character is used.
+
+2001-11-15 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Bug fixes.
+
+2001-11-12 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * (nearly) Completely rewritten.
+
+ * Force Identity CMap. (double-byte character codes are mapped to CID)
+
+ * Added CMap parser. (mkcidcct.pl is no longer needed)
+
+ * Sync with jpatch.
+
+2001-10-01 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Should return -1 when encoding_id >= 0 in type0_font().
+
+2001-08-08 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed a bug that raster images show up incorrectly in vertical
+ writing mode.
+
+2001-08-07 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Removed dev_set_string2(), use dev_set_string() instead.
+
+ * set_dev_vwmode() is renamed to set_dev_wmode().
+ Added dev_wmode() and mp_mode flag in pdfdev.c.
+
+ * Support for Japanized MetaPost (pdfparse.h, mpost.c).
+
+2001-07-21 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed a bug that do not reset text state in vertical writing.
+
+2001-07-20 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed wrong positioning for slanted non-CJK font in vertical writing.
+
+2001-07-19 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Support OS/2 table version 0x0002.
+
+2001-07-17 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Support multiple parents for a single CID-keyed font
+ (incomplete).
+
+ TODO:
+ check the consistency of charcter collections.
+
+ * Removed entries for unsupported CMaps.
+
+ * Updated cid.map.
+
+2001-07-15 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Better font metric info for CIDFontType2.
+
+ * Added (partial) support for vertical writing.
+ Added wmode flag to struct a_type0_font and dev_font.
+
+ TODO:
+ GSUB support in CIDFontType2.
+ /W2 and /DW2.
+
+ * Added support for vertical version of CMaps in mkcidcct.pl
+
+2001-07-07 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Minor fixes.
+
+ * Updated out2uni.c
+
+2001-06-30 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * --> dvipdfm-0.13.2c
+
+2001-06-29 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Fixed a bug that select incorrect indexToLocaFormat
+ (cidtype2.c).
+
+ * Fixed several bugs in cidtype2.c.
+
+2001-06-27 Shunsaku Hirata <hira4scp@mbox.nc.kyushu-u.ac.jp>
+
+ * Added support for CJK-TrueType font embedding.
+
+ * Cleaned up Type0 and CID font handling code.
diff --git a/Build/source/texk/dvipdfm-x/INSTALL b/Build/source/texk/dvipdfm-x/INSTALL
new file mode 100644
index 00000000000..b42a17ac464
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/INSTALL
@@ -0,0 +1,182 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/Build/source/texk/dvipdfm-x/Makefile.am b/Build/source/texk/dvipdfm-x/Makefile.am
new file mode 100644
index 00000000000..c738137d3d0
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/Makefile.am
@@ -0,0 +1,299 @@
+## Makefile.am for the TeX Live subdirectory texk/dvipdfm-x/
+##
+## Copyright (C) 2009-2015 Peter Breitenlohner <tex-live@tug.org>
+## You may freely use, modify and/or distribute this file.
+##
+bin_PROGRAMS = xdvipdfmx
+if !WIN32
+dist_bin_SCRIPTS = dvipdft
+endif !WIN32
+
+AM_CPPFLAGS = $(KPATHSEA_INCLUDES) $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) $(LIBPAPER_INCLUDES)
+AM_CFLAGS = $(WARNING_CFLAGS)
+
+xdvipdfmx_SOURCES = \
+ agl.c \
+ agl.h \
+ bmpimage.c \
+ bmpimage.h \
+ cff.c \
+ cff.h \
+ cff_dict.c \
+ cff_dict.h \
+ cff_limits.h \
+ cff_stdstr.h \
+ cff_types.h \
+ cid_basefont.h \
+ cid.c \
+ cid.h \
+ cidtype0.c \
+ cidtype0.h \
+ cidtype2.c \
+ cidtype2.h \
+ cmap.c \
+ cmap.h \
+ cmap_p.h \
+ cmap_read.c \
+ cmap_read.h \
+ cmap_write.c \
+ cmap_write.h \
+ cs_type2.c \
+ cs_type2.h \
+ dpxconf.c \
+ dpxconf.h \
+ dpxcrypt.c \
+ dpxcrypt.h \
+ dpxfile.c \
+ dpxfile.h \
+ dpxutil.c \
+ dpxutil.h \
+ dvi.c \
+ dvi.h \
+ dvicodes.h \
+ dvipdfmx.c \
+ dvipdfmx.h \
+ epdf.c \
+ epdf.h \
+ error.c \
+ error.h \
+ fontmap.c \
+ fontmap.h \
+ jp2image.c \
+ jp2image.h \
+ jpegimage.c \
+ jpegimage.h \
+ mem.c \
+ mem.h \
+ mfileio.c \
+ mfileio.h \
+ mpost.c \
+ mpost.h \
+ mt19937ar.c \
+ numbers.c \
+ numbers.h \
+ otl_opt.c \
+ otl_opt.h \
+ pdfcolor.c \
+ pdfcolor.h \
+ pdfdev.c \
+ pdfdev.h \
+ pdfdoc.c \
+ pdfdoc.h \
+ pdfdraw.c \
+ pdfdraw.h \
+ pdfencrypt.c \
+ pdfencrypt.h \
+ pdfencoding.c \
+ pdfencoding.h \
+ pdffont.c \
+ pdffont.h \
+ pdflimits.h \
+ pdfnames.c \
+ pdfnames.h \
+ pdfobj.c \
+ pdfobj.h \
+ pdfparse.c \
+ pdfparse.h \
+ pdfresource.c \
+ pdfresource.h \
+ pdfximage.c \
+ pdfximage.h \
+ pkfont.c \
+ pkfont.h \
+ pngimage.c \
+ pngimage.h \
+ pst.c \
+ pst.h \
+ pst_obj.c \
+ pst_obj.h \
+ sfnt.c \
+ sfnt.h \
+ spc_color.c \
+ spc_color.h \
+ spc_dvipdfmx.c \
+ spc_dvipdfmx.h \
+ spc_dvips.c \
+ spc_dvips.h \
+ spc_html.c \
+ spc_html.h \
+ spc_misc.c \
+ spc_misc.h \
+ spc_pdfm.c \
+ spc_pdfm.h \
+ spc_tpic.c \
+ spc_tpic.h \
+ spc_util.h \
+ spc_util.c \
+ spc_xtx.c \
+ spc_xtx.h \
+ specials.c \
+ specials.h \
+ subfont.c \
+ subfont.h \
+ system.h \
+ t1_char.c \
+ t1_char.h \
+ t1_load.c \
+ t1_load.h \
+ tfm.c \
+ tfm.h \
+ truetype.c \
+ truetype.h \
+ tt_aux.c \
+ tt_aux.h \
+ tt_cmap.c \
+ tt_cmap.h \
+ tt_glyf.c \
+ tt_glyf.h \
+ tt_gsub.c \
+ tt_gsub.h \
+ tt_post.c \
+ tt_post.h \
+ tt_table.c \
+ tt_table.h \
+ type0.c \
+ type0.h \
+ type1.c \
+ type1.h \
+ type1c.c \
+ type1c.h \
+ unicode.c \
+ unicode.h \
+ vf.c \
+ vf.h \
+ xbb.c
+
+LDADD = $(KPATHSEA_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) $(LIBPAPER_LIBS)
+
+$(xdvipdfmx_OBJECTS): config.force
+
+## Links
+##
+bin_links = \
+ xdvipdfmx$(EXEEXT):dvipdfm \
+ xdvipdfmx$(EXEEXT):dvipdfmx \
+ xdvipdfmx$(EXEEXT):ebb \
+ xdvipdfmx$(EXEEXT):extractbb
+
+if WIN32
+noinst_PROGRAMS = call_xdvipdfmx
+endif WIN32
+
+call_xdvipdfmx_CPPFLAGS = -DEXEPROG=\"xdvipdfmx.exe\"
+nodist_call_xdvipdfmx_SOURCES = callexe.c
+
+include $(top_srcdir)/../../am/bin_links.am
+
+## Manpages
+
+dist_man1_MANS = man/dvipdfmx.1 man/dvipdft.1 man/extractbb.1
+man1_links = \
+ dvipdfmx:dvipdfm \
+ dvipdfmx:xdvipdfmx \
+ extractbb:ebb
+include $(top_srcdir)/../../am/man1_links.am
+
+## Data
+##
+configdatadir = $(datarootdir)/texmf-dist/dvipdfmx
+dist_configdata_DATA = data/dvipdfmx.cfg
+
+glyphlistdatadir = $(datarootdir)/texmf-dist/fonts/map/glyphlist
+dist_glyphlistdata_DATA = data/glyphlist.txt data/pdfglyphlist.txt
+
+mapdatadir = $(datarootdir)/texmf-dist/fonts/map/dvipdfmx
+dist_mapdata_DATA = data/cid-x.map
+
+cmapdatadir = $(datarootdir)/texmf-dist/fonts/cmap/dvipdfmx
+dist_cmapdata_DATA = data/EUC-UCS2
+
+install-exec-hook: install-bin-links
+if WIN32
+ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT)
+ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/dvipdfmx$(EXEEXT)
+ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/ebb$(EXEEXT)
+ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/extractbb$(EXEEXT)
+endif WIN32
+
+install-data-hook: install-man1-links
+
+uninstall-hook: uninstall-bin-links uninstall-man1-links
+if WIN32
+ rm -f $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT)
+ rm -f $(DESTDIR)$(bindir)/dvipdfmx$(EXEEXT)
+ rm -f $(DESTDIR)$(bindir)/ebb$(EXEEXT)
+ rm -f $(DESTDIR)$(bindir)/extractbb$(EXEEXT)
+endif WIN32
+
+all-local: config.force
+
+config.force: $(ZLIB_DEPEND) $(LIBPNG_DEPEND) $(KPATHSEA_DEPEND) $(LIBPAPER_DEPEND)
+ echo timestamp >config.force
+ $(SHELL) ./config.status --recheck
+
+DISTCLEANFILES = config.force
+
+## Rebuild libkpathsea
+@KPATHSEA_RULE@
+## Rebuild libpng
+@LIBPNG_RULE@
+## Rebuild libz
+@ZLIB_RULE@
+## Rebuild libpaper
+@LIBPAPER_RULE@
+
+## Tests
+##
+TESTS = xdvipdfmx.test xdvipdfm-ann.test xdvipdfm-bad.test xdvipdfm-bb.test
+TESTS += xdvipdfm-bkm.test xdvipdfm-psz.test xdvipdfm-ptx.test xdvipdfm-res.test
+TESTS += xdvipdfm-rev.test xdvipdfm-ttc.test
+TESTS += dvipdfmx-upjf.test
+xdvipdfmx.log xdvipdfm-ann.log xdvipdfm-bad.log xdvipdfm-bb.log \
+ xdvipdfm-bkm.log xdvipdfm-psz.log xdvipdfm-ptx.log xdvipdfm-res.log \
+ xdvipdfm-rev.log xdvipdfm-ttc.log: xdvipdfmx$(EXEEXT)
+EXTRA_DIST = $(TESTS)
+## xdvipdfmx.test
+EXTRA_DIST += tests/dvipdfmx.cfg tests/psfonts.map
+EXTRA_DIST += tests/cmr10.pfb tests/cmr10.tfm
+EXTRA_DIST += tests/image.dvi tests/image.tex
+EXTRA_DIST += tests/xbmc.dvi tests/xbmc.tex tests/xbmc10.600pk tests/xbmc10.tfm
+DISTCLEANFILES += image*.pdf xbmc*.pdf
+## xdvipdfm-ann.test
+EXTRA_DIST += tests/annot.dvi tests/annot.tex
+DISTCLEANFILES += annot*.pdf
+## xdvipdfm-bad.test
+EXTRA_DIST += tests/ids_2_6.dvi tests/ids_3_2.dvi tests/ids_a_b.dvi tests/opc_fe.dvi
+EXTRA_DIST += tests/ptx_2_2.dvi tests/ptx_6_6.dvi tests/rev_2_2.dvi tests/rev_2_3.dvi
+EXTRA_DIST += tests/void.dvi
+## xdvipdfm-bb.test
+EXTRA_DIST += tests/image.bmp tests/picbmp.bb tests/picbmp.xbb
+EXTRA_DIST += tests/image.jp2 tests/picjp2.bb tests/picjp2.xbb
+EXTRA_DIST += tests/image.jpeg tests/picjpeg.bb tests/picjpeg.xbb
+EXTRA_DIST += tests/image.png tests/picpng.bb tests/picpng.xbb
+EXTRA_DIST += tests/image.pdf tests/picpdf.bb tests/picpdf.xbb
+DISTCLEANFILES += pic*.*
+## xdvipdfm-bkm.test
+EXTRA_DIST += tests/bookm.dvi tests/bookm.tex
+DISTCLEANFILES += bookm*.pdf
+## xdvipdfm-psz.test
+EXTRA_DIST += tests/paper.dvi tests/paper.tex
+DISTCLEANFILES += paper*.pdf
+## xdvipdfm-ptx.test
+EXTRA_DIST += tests/ptex.dvi
+DISTCLEANFILES += ptex*.pdf
+## xdvipdfm-res.test
+EXTRA_DIST += tests/resrc.dvi tests/resrc.tex
+DISTCLEANFILES += resrc*.pdf
+## xdvipdfm-rev.test
+EXTRA_DIST += tests/reverse.dvi
+DISTCLEANFILES += reverse.pdf
+## xdvipdfm-ttc.test
+EXTRA_DIST += tests/ttc.dvi tests/ttc.tex tests/test.ttc
+DISTCLEANFILES += ttc*.pdf
+## dvipdfmx-upjf.test
+EXTRA_DIST += tests/upjf.dvi tests/upjf.tex tests/upjf.map tests/Makefile_upjf
+EXTRA_DIST += tests/upjf_full.cnf tests/upjf_omit.cnf tests/upjf_full.vf tests/upjf_omit.vf
+EXTRA_DIST += tests/upjf-r.tfm tests/upjf-g.tfm tests/upjf.tfm tests/UPJF-UTF16-H
+DISTCLEANFILES += upjf.vf upjf*.pdf
+##
+EXTRA_DIST += tests/fullmap.dvi tests/fullmap.tex
diff --git a/Build/source/texk/dvipdfm-x/Makefile.in b/Build/source/texk/dvipdfm-x/Makefile.in
new file mode 100644
index 00000000000..28dbd24b646
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/Makefile.in
@@ -0,0 +1,2034 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# am/bin_links.am: Makefile fragment for bindir links.
+#
+# Copyright 2017-2020 Karl Berry <tex-live@tug.org>
+# Copyright 2011-2013 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+#
+# requires conditional WIN32
+# requires $(bin_links)
+# Symlinks within $(bindir): FILE:LINK indicates LINK->FILE
+# for binaries and scripts use, e.g.,
+# binprog$(EXEEXT):foo
+# script:bar
+# respectively, such that the links created on cygwin are
+# 'foo->binprog.exe' and 'bar->script'.
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = xdvipdfmx$(EXEEXT)
+@WIN32_TRUE@noinst_PROGRAMS = call_xdvipdfmx$(EXEEXT)
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../../m4/kpse-common.m4 \
+ $(top_srcdir)/../../m4/kpse-kpathsea-flags.m4 \
+ $(top_srcdir)/../../m4/kpse-libpaper-flags.m4 \
+ $(top_srcdir)/../../m4/kpse-libpng-flags.m4 \
+ $(top_srcdir)/../../m4/kpse-warnings.m4 \
+ $(top_srcdir)/../../m4/kpse-win32.m4 \
+ $(top_srcdir)/../../m4/kpse-zlib-flags.m4 \
+ $(top_srcdir)/../../m4/libtool.m4 \
+ $(top_srcdir)/../../m4/ltoptions.m4 \
+ $(top_srcdir)/../../m4/ltsugar.m4 \
+ $(top_srcdir)/../../m4/ltversion.m4 \
+ $(top_srcdir)/../../m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__dist_bin_SCRIPTS_DIST) \
+ $(dist_cmapdata_DATA) $(dist_configdata_DATA) \
+ $(dist_glyphlistdata_DATA) $(dist_mapdata_DATA) \
+ $(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = callexe.c
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(cmapdatadir)" \
+ "$(DESTDIR)$(configdatadir)" "$(DESTDIR)$(glyphlistdatadir)" \
+ "$(DESTDIR)$(mapdatadir)"
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+nodist_call_xdvipdfmx_OBJECTS = call_xdvipdfmx-callexe.$(OBJEXT)
+call_xdvipdfmx_OBJECTS = $(nodist_call_xdvipdfmx_OBJECTS)
+call_xdvipdfmx_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+call_xdvipdfmx_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+am_xdvipdfmx_OBJECTS = agl.$(OBJEXT) bmpimage.$(OBJEXT) cff.$(OBJEXT) \
+ cff_dict.$(OBJEXT) cid.$(OBJEXT) cidtype0.$(OBJEXT) \
+ cidtype2.$(OBJEXT) cmap.$(OBJEXT) cmap_read.$(OBJEXT) \
+ cmap_write.$(OBJEXT) cs_type2.$(OBJEXT) dpxconf.$(OBJEXT) \
+ dpxcrypt.$(OBJEXT) dpxfile.$(OBJEXT) dpxutil.$(OBJEXT) \
+ dvi.$(OBJEXT) dvipdfmx.$(OBJEXT) epdf.$(OBJEXT) \
+ error.$(OBJEXT) fontmap.$(OBJEXT) jp2image.$(OBJEXT) \
+ jpegimage.$(OBJEXT) mem.$(OBJEXT) mfileio.$(OBJEXT) \
+ mpost.$(OBJEXT) mt19937ar.$(OBJEXT) numbers.$(OBJEXT) \
+ otl_opt.$(OBJEXT) pdfcolor.$(OBJEXT) pdfdev.$(OBJEXT) \
+ pdfdoc.$(OBJEXT) pdfdraw.$(OBJEXT) pdfencrypt.$(OBJEXT) \
+ pdfencoding.$(OBJEXT) pdffont.$(OBJEXT) pdfnames.$(OBJEXT) \
+ pdfobj.$(OBJEXT) pdfparse.$(OBJEXT) pdfresource.$(OBJEXT) \
+ pdfximage.$(OBJEXT) pkfont.$(OBJEXT) pngimage.$(OBJEXT) \
+ pst.$(OBJEXT) pst_obj.$(OBJEXT) sfnt.$(OBJEXT) \
+ spc_color.$(OBJEXT) spc_dvipdfmx.$(OBJEXT) spc_dvips.$(OBJEXT) \
+ spc_html.$(OBJEXT) spc_misc.$(OBJEXT) spc_pdfm.$(OBJEXT) \
+ spc_tpic.$(OBJEXT) spc_util.$(OBJEXT) spc_xtx.$(OBJEXT) \
+ specials.$(OBJEXT) subfont.$(OBJEXT) t1_char.$(OBJEXT) \
+ t1_load.$(OBJEXT) tfm.$(OBJEXT) truetype.$(OBJEXT) \
+ tt_aux.$(OBJEXT) tt_cmap.$(OBJEXT) tt_glyf.$(OBJEXT) \
+ tt_gsub.$(OBJEXT) tt_post.$(OBJEXT) tt_table.$(OBJEXT) \
+ type0.$(OBJEXT) type1.$(OBJEXT) type1c.$(OBJEXT) \
+ unicode.$(OBJEXT) vf.$(OBJEXT) xbb.$(OBJEXT)
+xdvipdfmx_OBJECTS = $(am_xdvipdfmx_OBJECTS)
+xdvipdfmx_LDADD = $(LDADD)
+xdvipdfmx_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am__dist_bin_SCRIPTS_DIST = dvipdft
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+SCRIPTS = $(dist_bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../../build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/agl.Po ./$(DEPDIR)/bmpimage.Po \
+ ./$(DEPDIR)/call_xdvipdfmx-callexe.Po ./$(DEPDIR)/cff.Po \
+ ./$(DEPDIR)/cff_dict.Po ./$(DEPDIR)/cid.Po \
+ ./$(DEPDIR)/cidtype0.Po ./$(DEPDIR)/cidtype2.Po \
+ ./$(DEPDIR)/cmap.Po ./$(DEPDIR)/cmap_read.Po \
+ ./$(DEPDIR)/cmap_write.Po ./$(DEPDIR)/cs_type2.Po \
+ ./$(DEPDIR)/dpxconf.Po ./$(DEPDIR)/dpxcrypt.Po \
+ ./$(DEPDIR)/dpxfile.Po ./$(DEPDIR)/dpxutil.Po \
+ ./$(DEPDIR)/dvi.Po ./$(DEPDIR)/dvipdfmx.Po ./$(DEPDIR)/epdf.Po \
+ ./$(DEPDIR)/error.Po ./$(DEPDIR)/fontmap.Po \
+ ./$(DEPDIR)/jp2image.Po ./$(DEPDIR)/jpegimage.Po \
+ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mfileio.Po ./$(DEPDIR)/mpost.Po \
+ ./$(DEPDIR)/mt19937ar.Po ./$(DEPDIR)/numbers.Po \
+ ./$(DEPDIR)/otl_opt.Po ./$(DEPDIR)/pdfcolor.Po \
+ ./$(DEPDIR)/pdfdev.Po ./$(DEPDIR)/pdfdoc.Po \
+ ./$(DEPDIR)/pdfdraw.Po ./$(DEPDIR)/pdfencoding.Po \
+ ./$(DEPDIR)/pdfencrypt.Po ./$(DEPDIR)/pdffont.Po \
+ ./$(DEPDIR)/pdfnames.Po ./$(DEPDIR)/pdfobj.Po \
+ ./$(DEPDIR)/pdfparse.Po ./$(DEPDIR)/pdfresource.Po \
+ ./$(DEPDIR)/pdfximage.Po ./$(DEPDIR)/pkfont.Po \
+ ./$(DEPDIR)/pngimage.Po ./$(DEPDIR)/pst.Po \
+ ./$(DEPDIR)/pst_obj.Po ./$(DEPDIR)/sfnt.Po \
+ ./$(DEPDIR)/spc_color.Po ./$(DEPDIR)/spc_dvipdfmx.Po \
+ ./$(DEPDIR)/spc_dvips.Po ./$(DEPDIR)/spc_html.Po \
+ ./$(DEPDIR)/spc_misc.Po ./$(DEPDIR)/spc_pdfm.Po \
+ ./$(DEPDIR)/spc_tpic.Po ./$(DEPDIR)/spc_util.Po \
+ ./$(DEPDIR)/spc_xtx.Po ./$(DEPDIR)/specials.Po \
+ ./$(DEPDIR)/subfont.Po ./$(DEPDIR)/t1_char.Po \
+ ./$(DEPDIR)/t1_load.Po ./$(DEPDIR)/tfm.Po \
+ ./$(DEPDIR)/truetype.Po ./$(DEPDIR)/tt_aux.Po \
+ ./$(DEPDIR)/tt_cmap.Po ./$(DEPDIR)/tt_glyf.Po \
+ ./$(DEPDIR)/tt_gsub.Po ./$(DEPDIR)/tt_post.Po \
+ ./$(DEPDIR)/tt_table.Po ./$(DEPDIR)/type0.Po \
+ ./$(DEPDIR)/type1.Po ./$(DEPDIR)/type1c.Po \
+ ./$(DEPDIR)/unicode.Po ./$(DEPDIR)/vf.Po ./$(DEPDIR)/xbb.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(nodist_call_xdvipdfmx_SOURCES) $(xdvipdfmx_SOURCES)
+DIST_SOURCES = $(xdvipdfmx_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(dist_man1_MANS)
+DATA = $(dist_cmapdata_DATA) $(dist_configdata_DATA) \
+ $(dist_glyphlistdata_DATA) $(dist_mapdata_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
+ config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope check recheck
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../../build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__DIST_COMMON = $(dist_man1_MANS) $(srcdir)/Makefile.in \
+ $(srcdir)/config.h.in $(top_srcdir)/../../am/bin_links.am \
+ $(top_srcdir)/../../am/man1_links.am \
+ $(top_srcdir)/../../build-aux/compile \
+ $(top_srcdir)/../../build-aux/config.guess \
+ $(top_srcdir)/../../build-aux/config.sub \
+ $(top_srcdir)/../../build-aux/depcomp \
+ $(top_srcdir)/../../build-aux/install-sh \
+ $(top_srcdir)/../../build-aux/ltmain.sh \
+ $(top_srcdir)/../../build-aux/missing \
+ $(top_srcdir)/../../build-aux/test-driver \
+ $(top_srcdir)/../texlive/w32_wrapper/callexe.c \
+ ../../build-aux/ar-lib ../../build-aux/compile \
+ ../../build-aux/config.guess ../../build-aux/config.sub \
+ ../../build-aux/depcomp ../../build-aux/install-sh \
+ ../../build-aux/ltmain.sh ../../build-aux/missing \
+ ../../build-aux/texinfo.tex ../../build-aux/ylwrap AUTHORS \
+ COPYING ChangeLog INSTALL README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+# Exists only to be overridden by the user if desired.
+AM_DISTCHECK_DVI_TARGET = dvi
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KPATHSEA_DEPEND = @KPATHSEA_DEPEND@
+KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@
+KPATHSEA_LIBS = @KPATHSEA_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBPAPER_DEPEND = @LIBPAPER_DEPEND@
+LIBPAPER_INCLUDES = @LIBPAPER_INCLUDES@
+LIBPAPER_LIBS = @LIBPAPER_LIBS@
+LIBPNG_DEPEND = @LIBPNG_DEPEND@
+LIBPNG_INCLUDES = @LIBPNG_INCLUDES@
+LIBPNG_LIBS = @LIBPNG_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WARNING_CFLAGS = @WARNING_CFLAGS@
+ZLIB_DEPEND = @ZLIB_DEPEND@
+ZLIB_INCLUDES = @ZLIB_INCLUDES@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+@WIN32_FALSE@dist_bin_SCRIPTS = dvipdft
+AM_CPPFLAGS = $(KPATHSEA_INCLUDES) $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) $(LIBPAPER_INCLUDES)
+AM_CFLAGS = $(WARNING_CFLAGS)
+xdvipdfmx_SOURCES = \
+ agl.c \
+ agl.h \
+ bmpimage.c \
+ bmpimage.h \
+ cff.c \
+ cff.h \
+ cff_dict.c \
+ cff_dict.h \
+ cff_limits.h \
+ cff_stdstr.h \
+ cff_types.h \
+ cid_basefont.h \
+ cid.c \
+ cid.h \
+ cidtype0.c \
+ cidtype0.h \
+ cidtype2.c \
+ cidtype2.h \
+ cmap.c \
+ cmap.h \
+ cmap_p.h \
+ cmap_read.c \
+ cmap_read.h \
+ cmap_write.c \
+ cmap_write.h \
+ cs_type2.c \
+ cs_type2.h \
+ dpxconf.c \
+ dpxconf.h \
+ dpxcrypt.c \
+ dpxcrypt.h \
+ dpxfile.c \
+ dpxfile.h \
+ dpxutil.c \
+ dpxutil.h \
+ dvi.c \
+ dvi.h \
+ dvicodes.h \
+ dvipdfmx.c \
+ dvipdfmx.h \
+ epdf.c \
+ epdf.h \
+ error.c \
+ error.h \
+ fontmap.c \
+ fontmap.h \
+ jp2image.c \
+ jp2image.h \
+ jpegimage.c \
+ jpegimage.h \
+ mem.c \
+ mem.h \
+ mfileio.c \
+ mfileio.h \
+ mpost.c \
+ mpost.h \
+ mt19937ar.c \
+ numbers.c \
+ numbers.h \
+ otl_opt.c \
+ otl_opt.h \
+ pdfcolor.c \
+ pdfcolor.h \
+ pdfdev.c \
+ pdfdev.h \
+ pdfdoc.c \
+ pdfdoc.h \
+ pdfdraw.c \
+ pdfdraw.h \
+ pdfencrypt.c \
+ pdfencrypt.h \
+ pdfencoding.c \
+ pdfencoding.h \
+ pdffont.c \
+ pdffont.h \
+ pdflimits.h \
+ pdfnames.c \
+ pdfnames.h \
+ pdfobj.c \
+ pdfobj.h \
+ pdfparse.c \
+ pdfparse.h \
+ pdfresource.c \
+ pdfresource.h \
+ pdfximage.c \
+ pdfximage.h \
+ pkfont.c \
+ pkfont.h \
+ pngimage.c \
+ pngimage.h \
+ pst.c \
+ pst.h \
+ pst_obj.c \
+ pst_obj.h \
+ sfnt.c \
+ sfnt.h \
+ spc_color.c \
+ spc_color.h \
+ spc_dvipdfmx.c \
+ spc_dvipdfmx.h \
+ spc_dvips.c \
+ spc_dvips.h \
+ spc_html.c \
+ spc_html.h \
+ spc_misc.c \
+ spc_misc.h \
+ spc_pdfm.c \
+ spc_pdfm.h \
+ spc_tpic.c \
+ spc_tpic.h \
+ spc_util.h \
+ spc_util.c \
+ spc_xtx.c \
+ spc_xtx.h \
+ specials.c \
+ specials.h \
+ subfont.c \
+ subfont.h \
+ system.h \
+ t1_char.c \
+ t1_char.h \
+ t1_load.c \
+ t1_load.h \
+ tfm.c \
+ tfm.h \
+ truetype.c \
+ truetype.h \
+ tt_aux.c \
+ tt_aux.h \
+ tt_cmap.c \
+ tt_cmap.h \
+ tt_glyf.c \
+ tt_glyf.h \
+ tt_gsub.c \
+ tt_gsub.h \
+ tt_post.c \
+ tt_post.h \
+ tt_table.c \
+ tt_table.h \
+ type0.c \
+ type0.h \
+ type1.c \
+ type1.h \
+ type1c.c \
+ type1c.h \
+ unicode.c \
+ unicode.h \
+ vf.c \
+ vf.h \
+ xbb.c
+
+LDADD = $(KPATHSEA_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) $(LIBPAPER_LIBS)
+bin_links = \
+ xdvipdfmx$(EXEEXT):dvipdfm \
+ xdvipdfmx$(EXEEXT):dvipdfmx \
+ xdvipdfmx$(EXEEXT):ebb \
+ xdvipdfmx$(EXEEXT):extractbb
+
+call_xdvipdfmx_CPPFLAGS = -DEXEPROG=\"xdvipdfmx.exe\"
+nodist_call_xdvipdfmx_SOURCES = callexe.c
+dist_man1_MANS = man/dvipdfmx.1 man/dvipdft.1 man/extractbb.1
+man1_links = \
+ dvipdfmx:dvipdfm \
+ dvipdfmx:xdvipdfmx \
+ extractbb:ebb
+
+configdatadir = $(datarootdir)/texmf-dist/dvipdfmx
+dist_configdata_DATA = data/dvipdfmx.cfg
+glyphlistdatadir = $(datarootdir)/texmf-dist/fonts/map/glyphlist
+dist_glyphlistdata_DATA = data/glyphlist.txt data/pdfglyphlist.txt
+mapdatadir = $(datarootdir)/texmf-dist/fonts/map/dvipdfmx
+dist_mapdata_DATA = data/cid-x.map
+cmapdatadir = $(datarootdir)/texmf-dist/fonts/cmap/dvipdfmx
+dist_cmapdata_DATA = data/EUC-UCS2
+DISTCLEANFILES = config.force image*.pdf xbmc*.pdf annot*.pdf pic*.* \
+ bookm*.pdf paper*.pdf ptex*.pdf resrc*.pdf reverse.pdf \
+ ttc*.pdf upjf.vf upjf*.pdf
+TESTS = xdvipdfmx.test xdvipdfm-ann.test xdvipdfm-bad.test \
+ xdvipdfm-bb.test xdvipdfm-bkm.test xdvipdfm-psz.test \
+ xdvipdfm-ptx.test xdvipdfm-res.test xdvipdfm-rev.test \
+ xdvipdfm-ttc.test dvipdfmx-upjf.test
+EXTRA_DIST = $(TESTS) tests/dvipdfmx.cfg tests/psfonts.map \
+ tests/cmr10.pfb tests/cmr10.tfm tests/image.dvi \
+ tests/image.tex tests/xbmc.dvi tests/xbmc.tex \
+ tests/xbmc10.600pk tests/xbmc10.tfm tests/annot.dvi \
+ tests/annot.tex tests/ids_2_6.dvi tests/ids_3_2.dvi \
+ tests/ids_a_b.dvi tests/opc_fe.dvi tests/ptx_2_2.dvi \
+ tests/ptx_6_6.dvi tests/rev_2_2.dvi tests/rev_2_3.dvi \
+ tests/void.dvi tests/image.bmp tests/picbmp.bb \
+ tests/picbmp.xbb tests/image.jp2 tests/picjp2.bb \
+ tests/picjp2.xbb tests/image.jpeg tests/picjpeg.bb \
+ tests/picjpeg.xbb tests/image.png tests/picpng.bb \
+ tests/picpng.xbb tests/image.pdf tests/picpdf.bb \
+ tests/picpdf.xbb tests/bookm.dvi tests/bookm.tex \
+ tests/paper.dvi tests/paper.tex tests/ptex.dvi tests/resrc.dvi \
+ tests/resrc.tex tests/reverse.dvi tests/ttc.dvi tests/ttc.tex \
+ tests/test.ttc tests/upjf.dvi tests/upjf.tex tests/upjf.map \
+ tests/Makefile_upjf tests/upjf_full.cnf tests/upjf_omit.cnf \
+ tests/upjf_full.vf tests/upjf_omit.vf tests/upjf-r.tfm \
+ tests/upjf-g.tfm tests/upjf.tfm tests/UPJF-UTF16-H \
+ tests/fullmap.dvi tests/fullmap.tex
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/../../am/bin_links.am $(top_srcdir)/../../am/man1_links.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
+ esac;
+$(top_srcdir)/../../am/bin_links.am $(top_srcdir)/../../am/man1_links.am $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+call_xdvipdfmx$(EXEEXT): $(call_xdvipdfmx_OBJECTS) $(call_xdvipdfmx_DEPENDENCIES) $(EXTRA_call_xdvipdfmx_DEPENDENCIES)
+ @rm -f call_xdvipdfmx$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(call_xdvipdfmx_OBJECTS) $(call_xdvipdfmx_LDADD) $(LIBS)
+
+xdvipdfmx$(EXEEXT): $(xdvipdfmx_OBJECTS) $(xdvipdfmx_DEPENDENCIES) $(EXTRA_xdvipdfmx_DEPENDENCIES)
+ @rm -f xdvipdfmx$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(xdvipdfmx_OBJECTS) $(xdvipdfmx_LDADD) $(LIBS)
+install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-dist_binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agl.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmpimage.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/call_xdvipdfmx-callexe.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cff.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cff_dict.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cid.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cidtype0.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cidtype2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmap_read.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmap_write.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cs_type2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dpxconf.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dpxcrypt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dpxfile.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dpxutil.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvi.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epdf.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontmap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jp2image.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpegimage.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mfileio.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpost.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mt19937ar.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/numbers.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otl_opt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfcolor.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfdev.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfdoc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfdraw.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfencoding.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfencrypt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdffont.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfnames.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfobj.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfparse.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfresource.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdfximage.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkfont.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngimage.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pst.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pst_obj.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfnt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_color.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_dvipdfmx.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_dvips.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_html.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_misc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_pdfm.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_tpic.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_util.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spc_xtx.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specials.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subfont.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1_char.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1_load.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfm.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/truetype.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt_aux.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt_cmap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt_glyf.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt_gsub.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt_post.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt_table.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/type0.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/type1.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/type1c.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicode.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vf.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbb.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+call_xdvipdfmx-callexe.o: callexe.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(call_xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT call_xdvipdfmx-callexe.o -MD -MP -MF $(DEPDIR)/call_xdvipdfmx-callexe.Tpo -c -o call_xdvipdfmx-callexe.o `test -f 'callexe.c' || echo '$(srcdir)/'`callexe.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/call_xdvipdfmx-callexe.Tpo $(DEPDIR)/call_xdvipdfmx-callexe.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='callexe.c' object='call_xdvipdfmx-callexe.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(call_xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o call_xdvipdfmx-callexe.o `test -f 'callexe.c' || echo '$(srcdir)/'`callexe.c
+
+call_xdvipdfmx-callexe.obj: callexe.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(call_xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT call_xdvipdfmx-callexe.obj -MD -MP -MF $(DEPDIR)/call_xdvipdfmx-callexe.Tpo -c -o call_xdvipdfmx-callexe.obj `if test -f 'callexe.c'; then $(CYGPATH_W) 'callexe.c'; else $(CYGPATH_W) '$(srcdir)/callexe.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/call_xdvipdfmx-callexe.Tpo $(DEPDIR)/call_xdvipdfmx-callexe.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='callexe.c' object='call_xdvipdfmx-callexe.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(call_xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o call_xdvipdfmx-callexe.obj `if test -f 'callexe.c'; then $(CYGPATH_W) 'callexe.c'; else $(CYGPATH_W) '$(srcdir)/callexe.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-man1: $(dist_man1_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(dist_man1_MANS)'; \
+ list2=''; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+install-dist_cmapdataDATA: $(dist_cmapdata_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_cmapdata_DATA)'; test -n "$(cmapdatadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(cmapdatadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(cmapdatadir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(cmapdatadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(cmapdatadir)" || exit $$?; \
+ done
+
+uninstall-dist_cmapdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_cmapdata_DATA)'; test -n "$(cmapdatadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(cmapdatadir)'; $(am__uninstall_files_from_dir)
+install-dist_configdataDATA: $(dist_configdata_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_configdata_DATA)'; test -n "$(configdatadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(configdatadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(configdatadir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdatadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(configdatadir)" || exit $$?; \
+ done
+
+uninstall-dist_configdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_configdata_DATA)'; test -n "$(configdatadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(configdatadir)'; $(am__uninstall_files_from_dir)
+install-dist_glyphlistdataDATA: $(dist_glyphlistdata_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_glyphlistdata_DATA)'; test -n "$(glyphlistdatadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(glyphlistdatadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(glyphlistdatadir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(glyphlistdatadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(glyphlistdatadir)" || exit $$?; \
+ done
+
+uninstall-dist_glyphlistdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_glyphlistdata_DATA)'; test -n "$(glyphlistdatadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(glyphlistdatadir)'; $(am__uninstall_files_from_dir)
+install-dist_mapdataDATA: $(dist_mapdata_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_mapdata_DATA)'; test -n "$(mapdatadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(mapdatadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(mapdatadir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(mapdatadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(mapdatadir)" || exit $$?; \
+ done
+
+uninstall-dist_mapdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_mapdata_DATA)'; test -n "$(mapdatadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(mapdatadir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-zstd: distdir
+ tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ *.tar.zst*) \
+ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) config.h \
+ all-local
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(cmapdatadir)" "$(DESTDIR)$(configdatadir)" "$(DESTDIR)$(glyphlistdatadir)" "$(DESTDIR)$(mapdatadir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f ./$(DEPDIR)/agl.Po
+ -rm -f ./$(DEPDIR)/bmpimage.Po
+ -rm -f ./$(DEPDIR)/call_xdvipdfmx-callexe.Po
+ -rm -f ./$(DEPDIR)/cff.Po
+ -rm -f ./$(DEPDIR)/cff_dict.Po
+ -rm -f ./$(DEPDIR)/cid.Po
+ -rm -f ./$(DEPDIR)/cidtype0.Po
+ -rm -f ./$(DEPDIR)/cidtype2.Po
+ -rm -f ./$(DEPDIR)/cmap.Po
+ -rm -f ./$(DEPDIR)/cmap_read.Po
+ -rm -f ./$(DEPDIR)/cmap_write.Po
+ -rm -f ./$(DEPDIR)/cs_type2.Po
+ -rm -f ./$(DEPDIR)/dpxconf.Po
+ -rm -f ./$(DEPDIR)/dpxcrypt.Po
+ -rm -f ./$(DEPDIR)/dpxfile.Po
+ -rm -f ./$(DEPDIR)/dpxutil.Po
+ -rm -f ./$(DEPDIR)/dvi.Po
+ -rm -f ./$(DEPDIR)/dvipdfmx.Po
+ -rm -f ./$(DEPDIR)/epdf.Po
+ -rm -f ./$(DEPDIR)/error.Po
+ -rm -f ./$(DEPDIR)/fontmap.Po
+ -rm -f ./$(DEPDIR)/jp2image.Po
+ -rm -f ./$(DEPDIR)/jpegimage.Po
+ -rm -f ./$(DEPDIR)/mem.Po
+ -rm -f ./$(DEPDIR)/mfileio.Po
+ -rm -f ./$(DEPDIR)/mpost.Po
+ -rm -f ./$(DEPDIR)/mt19937ar.Po
+ -rm -f ./$(DEPDIR)/numbers.Po
+ -rm -f ./$(DEPDIR)/otl_opt.Po
+ -rm -f ./$(DEPDIR)/pdfcolor.Po
+ -rm -f ./$(DEPDIR)/pdfdev.Po
+ -rm -f ./$(DEPDIR)/pdfdoc.Po
+ -rm -f ./$(DEPDIR)/pdfdraw.Po
+ -rm -f ./$(DEPDIR)/pdfencoding.Po
+ -rm -f ./$(DEPDIR)/pdfencrypt.Po
+ -rm -f ./$(DEPDIR)/pdffont.Po
+ -rm -f ./$(DEPDIR)/pdfnames.Po
+ -rm -f ./$(DEPDIR)/pdfobj.Po
+ -rm -f ./$(DEPDIR)/pdfparse.Po
+ -rm -f ./$(DEPDIR)/pdfresource.Po
+ -rm -f ./$(DEPDIR)/pdfximage.Po
+ -rm -f ./$(DEPDIR)/pkfont.Po
+ -rm -f ./$(DEPDIR)/pngimage.Po
+ -rm -f ./$(DEPDIR)/pst.Po
+ -rm -f ./$(DEPDIR)/pst_obj.Po
+ -rm -f ./$(DEPDIR)/sfnt.Po
+ -rm -f ./$(DEPDIR)/spc_color.Po
+ -rm -f ./$(DEPDIR)/spc_dvipdfmx.Po
+ -rm -f ./$(DEPDIR)/spc_dvips.Po
+ -rm -f ./$(DEPDIR)/spc_html.Po
+ -rm -f ./$(DEPDIR)/spc_misc.Po
+ -rm -f ./$(DEPDIR)/spc_pdfm.Po
+ -rm -f ./$(DEPDIR)/spc_tpic.Po
+ -rm -f ./$(DEPDIR)/spc_util.Po
+ -rm -f ./$(DEPDIR)/spc_xtx.Po
+ -rm -f ./$(DEPDIR)/specials.Po
+ -rm -f ./$(DEPDIR)/subfont.Po
+ -rm -f ./$(DEPDIR)/t1_char.Po
+ -rm -f ./$(DEPDIR)/t1_load.Po
+ -rm -f ./$(DEPDIR)/tfm.Po
+ -rm -f ./$(DEPDIR)/truetype.Po
+ -rm -f ./$(DEPDIR)/tt_aux.Po
+ -rm -f ./$(DEPDIR)/tt_cmap.Po
+ -rm -f ./$(DEPDIR)/tt_glyf.Po
+ -rm -f ./$(DEPDIR)/tt_gsub.Po
+ -rm -f ./$(DEPDIR)/tt_post.Po
+ -rm -f ./$(DEPDIR)/tt_table.Po
+ -rm -f ./$(DEPDIR)/type0.Po
+ -rm -f ./$(DEPDIR)/type1.Po
+ -rm -f ./$(DEPDIR)/type1c.Po
+ -rm -f ./$(DEPDIR)/unicode.Po
+ -rm -f ./$(DEPDIR)/vf.Po
+ -rm -f ./$(DEPDIR)/xbb.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_cmapdataDATA install-dist_configdataDATA \
+ install-dist_glyphlistdataDATA install-dist_mapdataDATA \
+ install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-dist_binSCRIPTS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f ./$(DEPDIR)/agl.Po
+ -rm -f ./$(DEPDIR)/bmpimage.Po
+ -rm -f ./$(DEPDIR)/call_xdvipdfmx-callexe.Po
+ -rm -f ./$(DEPDIR)/cff.Po
+ -rm -f ./$(DEPDIR)/cff_dict.Po
+ -rm -f ./$(DEPDIR)/cid.Po
+ -rm -f ./$(DEPDIR)/cidtype0.Po
+ -rm -f ./$(DEPDIR)/cidtype2.Po
+ -rm -f ./$(DEPDIR)/cmap.Po
+ -rm -f ./$(DEPDIR)/cmap_read.Po
+ -rm -f ./$(DEPDIR)/cmap_write.Po
+ -rm -f ./$(DEPDIR)/cs_type2.Po
+ -rm -f ./$(DEPDIR)/dpxconf.Po
+ -rm -f ./$(DEPDIR)/dpxcrypt.Po
+ -rm -f ./$(DEPDIR)/dpxfile.Po
+ -rm -f ./$(DEPDIR)/dpxutil.Po
+ -rm -f ./$(DEPDIR)/dvi.Po
+ -rm -f ./$(DEPDIR)/dvipdfmx.Po
+ -rm -f ./$(DEPDIR)/epdf.Po
+ -rm -f ./$(DEPDIR)/error.Po
+ -rm -f ./$(DEPDIR)/fontmap.Po
+ -rm -f ./$(DEPDIR)/jp2image.Po
+ -rm -f ./$(DEPDIR)/jpegimage.Po
+ -rm -f ./$(DEPDIR)/mem.Po
+ -rm -f ./$(DEPDIR)/mfileio.Po
+ -rm -f ./$(DEPDIR)/mpost.Po
+ -rm -f ./$(DEPDIR)/mt19937ar.Po
+ -rm -f ./$(DEPDIR)/numbers.Po
+ -rm -f ./$(DEPDIR)/otl_opt.Po
+ -rm -f ./$(DEPDIR)/pdfcolor.Po
+ -rm -f ./$(DEPDIR)/pdfdev.Po
+ -rm -f ./$(DEPDIR)/pdfdoc.Po
+ -rm -f ./$(DEPDIR)/pdfdraw.Po
+ -rm -f ./$(DEPDIR)/pdfencoding.Po
+ -rm -f ./$(DEPDIR)/pdfencrypt.Po
+ -rm -f ./$(DEPDIR)/pdffont.Po
+ -rm -f ./$(DEPDIR)/pdfnames.Po
+ -rm -f ./$(DEPDIR)/pdfobj.Po
+ -rm -f ./$(DEPDIR)/pdfparse.Po
+ -rm -f ./$(DEPDIR)/pdfresource.Po
+ -rm -f ./$(DEPDIR)/pdfximage.Po
+ -rm -f ./$(DEPDIR)/pkfont.Po
+ -rm -f ./$(DEPDIR)/pngimage.Po
+ -rm -f ./$(DEPDIR)/pst.Po
+ -rm -f ./$(DEPDIR)/pst_obj.Po
+ -rm -f ./$(DEPDIR)/sfnt.Po
+ -rm -f ./$(DEPDIR)/spc_color.Po
+ -rm -f ./$(DEPDIR)/spc_dvipdfmx.Po
+ -rm -f ./$(DEPDIR)/spc_dvips.Po
+ -rm -f ./$(DEPDIR)/spc_html.Po
+ -rm -f ./$(DEPDIR)/spc_misc.Po
+ -rm -f ./$(DEPDIR)/spc_pdfm.Po
+ -rm -f ./$(DEPDIR)/spc_tpic.Po
+ -rm -f ./$(DEPDIR)/spc_util.Po
+ -rm -f ./$(DEPDIR)/spc_xtx.Po
+ -rm -f ./$(DEPDIR)/specials.Po
+ -rm -f ./$(DEPDIR)/subfont.Po
+ -rm -f ./$(DEPDIR)/t1_char.Po
+ -rm -f ./$(DEPDIR)/t1_load.Po
+ -rm -f ./$(DEPDIR)/tfm.Po
+ -rm -f ./$(DEPDIR)/truetype.Po
+ -rm -f ./$(DEPDIR)/tt_aux.Po
+ -rm -f ./$(DEPDIR)/tt_cmap.Po
+ -rm -f ./$(DEPDIR)/tt_glyf.Po
+ -rm -f ./$(DEPDIR)/tt_gsub.Po
+ -rm -f ./$(DEPDIR)/tt_post.Po
+ -rm -f ./$(DEPDIR)/tt_table.Po
+ -rm -f ./$(DEPDIR)/type0.Po
+ -rm -f ./$(DEPDIR)/type1.Po
+ -rm -f ./$(DEPDIR)/type1c.Po
+ -rm -f ./$(DEPDIR)/unicode.Po
+ -rm -f ./$(DEPDIR)/vf.Po
+ -rm -f ./$(DEPDIR)/xbb.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-dist_binSCRIPTS \
+ uninstall-dist_cmapdataDATA uninstall-dist_configdataDATA \
+ uninstall-dist_glyphlistdataDATA uninstall-dist_mapdataDATA \
+ uninstall-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+uninstall-man: uninstall-man1
+
+.MAKE: all check-am install-am install-data-am install-exec-am \
+ install-strip uninstall-am
+
+.PHONY: CTAGS GTAGS TAGS all all-am all-local am--depfiles am--refresh \
+ check check-TESTS check-am clean clean-binPROGRAMS \
+ clean-cscope clean-generic clean-libtool clean-noinstPROGRAMS \
+ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+ dist-zstd distcheck distclean distclean-compile \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-tags distcleancheck distdir distuninstallcheck dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am \
+ install-data-hook install-dist_binSCRIPTS \
+ install-dist_cmapdataDATA install-dist_configdataDATA \
+ install-dist_glyphlistdataDATA install-dist_mapdataDATA \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-exec-hook install-html install-html-am install-info \
+ install-info-am install-man install-man1 install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-dist_binSCRIPTS \
+ uninstall-dist_cmapdataDATA uninstall-dist_configdataDATA \
+ uninstall-dist_glyphlistdataDATA uninstall-dist_mapdataDATA \
+ uninstall-hook uninstall-man uninstall-man1
+
+.PRECIOUS: Makefile
+
+
+$(xdvipdfmx_OBJECTS): config.force
+
+.PHONY: install-bin-links uninstall-bin-links
+
+install-bin-links:
+@WIN32_FALSE@ $(MKDIR_P) $(DESTDIR)$(bindir)
+@WIN32_FALSE@ @cd $(DESTDIR)$(bindir) && \
+@WIN32_FALSE@ for s in $(bin_links); do \
+@WIN32_FALSE@ link=`echo $$s | sed 's,.*:,,'`; \
+@WIN32_FALSE@ file=`echo $$s | sed 's,:.*,,'`; \
+@WIN32_FALSE@ rm -f $$link; \
+@WIN32_FALSE@ echo "creating link '$$link' -> '$$file'"; \
+@WIN32_FALSE@ $(LN_S) $$file $$link || exit 1; \
+@WIN32_FALSE@ done
+
+uninstall-bin-links:
+@WIN32_FALSE@ @for s in $(bin_links); do \
+@WIN32_FALSE@ link=`echo $$s | sed 's,.*:,,'`; \
+@WIN32_FALSE@ rm -f $(DESTDIR)$(bindir)/$$link; \
+@WIN32_FALSE@ done
+.PHONY: install-man1-links uninstall-man1-links
+
+install-man1-links:
+ @cd $(DESTDIR)$(man1dir) && \
+ for s in $(man1_links); do \
+ link=`echo $$s | sed 's,.*:,,'`; \
+ file=`echo $$s | sed 's,:.*,,'`; \
+ rm -f $$link.1; \
+ echo "creating link '$$link.1' -> '$$file.1'"; \
+ echo ".so man1/$$file.1" >$$link.1; \
+ done
+
+uninstall-man1-links:
+ @for s in $(man1_links); do \
+ link=`echo $$s | sed 's,.*:,,'`; \
+ rm -f $(DESTDIR)$(man1dir)/$$link.1; \
+ done
+
+install-exec-hook: install-bin-links
+@WIN32_TRUE@ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT)
+@WIN32_TRUE@ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/dvipdfmx$(EXEEXT)
+@WIN32_TRUE@ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/ebb$(EXEEXT)
+@WIN32_TRUE@ $(INSTALL_PROGRAM) call_xdvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/extractbb$(EXEEXT)
+
+install-data-hook: install-man1-links
+
+uninstall-hook: uninstall-bin-links uninstall-man1-links
+@WIN32_TRUE@ rm -f $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT)
+@WIN32_TRUE@ rm -f $(DESTDIR)$(bindir)/dvipdfmx$(EXEEXT)
+@WIN32_TRUE@ rm -f $(DESTDIR)$(bindir)/ebb$(EXEEXT)
+@WIN32_TRUE@ rm -f $(DESTDIR)$(bindir)/extractbb$(EXEEXT)
+
+all-local: config.force
+
+config.force: $(ZLIB_DEPEND) $(LIBPNG_DEPEND) $(KPATHSEA_DEPEND) $(LIBPAPER_DEPEND)
+ echo timestamp >config.force
+ $(SHELL) ./config.status --recheck
+
+@KPATHSEA_RULE@
+@LIBPNG_RULE@
+@ZLIB_RULE@
+@LIBPAPER_RULE@
+xdvipdfmx.log xdvipdfm-ann.log xdvipdfm-bad.log xdvipdfm-bb.log \
+ xdvipdfm-bkm.log xdvipdfm-psz.log xdvipdfm-ptx.log xdvipdfm-res.log \
+ xdvipdfm-rev.log xdvipdfm-ttc.log: xdvipdfmx$(EXEEXT)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Build/source/texk/dvipdfm-x/README b/Build/source/texk/dvipdfm-x/README
new file mode 100644
index 00000000000..99ab70beb9c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/README
@@ -0,0 +1,109 @@
+dvipdfmx and xdvipdfmx for TeX Live
+===================================
+
+This package is released under the GNU GPL, version 2, or (at your
+option) any later version.
+
+dvipdfmx is now maintained as part of TeX Live.
+
+Mailing list for bug reports and all discussion:
+https://lists.tug.org/dvipdfmx; anyone can join the list, but it is not
+necessary to join to post. Archives are public.
+
+xdvipdfmx
+=========
+xdvipdfmx is an extended version of dvipdfmx, and is now incorporated in
+the same sources.
+
+The extensions provided by xdvipdfmx provide support for the Extended DVI
+(.xdv) format used by xetex, including support for platform-native fonts
+and the xetex graphics primitives, as well as Unicode/OpenType text.
+
+Like its direct ancestor dvipdfmx, this is free software and may be
+redistributed under the terms of the GNU General Public License,
+version 2 or (at your option) any later version.
+
+Jonathan Kew mentions that in the past, XeTeX used a Mac-specific
+program xdv2pdf as the backend instead of xdvipdfmx. xdv2pdf supported
+a couple of special effects that are not yet available through
+xdvipdfmx: the Quartz graphics-based shadow support, AAT "variation"
+fonts like Skia, transparency as an attribute of font color, maybe other
+things. It would be nice for those things to continue to be supported,
+if anyone is looking for some nontrivial but not-impossible job and
+happens across this file.
+
+
+1. Introduction
+ ------------
+
+ The dvipdfmx (formerly dvipdfm-cjk) project provides an eXtended version
+ of the dvipdfm, a DVI to PDF translator developed by Mark A. Wicks.
+
+ The primary goal of this project is to support multi-byte character
+ encodings and large character sets for East Asian languages. The secondary
+ goal is to support as many features as pdfTeX developed by Han The Thanh.
+
+ This project is a combined work of the dvipdfm-jpn project by Shunsaku
+ Hirata and its modified one, dvipdfm-kor, by Jin-Hwan Cho.
+
+
+2. Installation
+ ------------
+
+ Currently, dvipdfmx is distributed as part of TeX Live. For TeX Live users,
+ please refer to the following site
+
+ https://www.tug.org/texlive/svn/
+
+ for an instruction on how to obtain and build the dvipdfmx program.
+
+3. Random number generating function
+ ---------------------------------
+
+ Prefixes of font names are calculated by using a function which
+ generates pseudo random numbers. In order to obtain a unique
+ prefix on all platforms when current time is common, a special
+ function MT19937, coded by Takuji Nishimura and Makoto Matsumoto,
+ is used. The header of the C program by Takuji Nishimura and
+ Makoto Matsumoto is the following:
+
+ A C-program for MT19937, with initialization improved 2002/1/26.
+ Coded by Takuji Nishimura and Makoto Matsumoto.
+
+ Before using, initialize the state by using init_genrand(seed)
+ or init_by_array(init_key, key_length).
+
+ Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ Any feedback is very welcome.
+ http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+ email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
diff --git a/Build/source/texk/dvipdfm-x/ac/withenable.ac b/Build/source/texk/dvipdfm-x/ac/withenable.ac
new file mode 100644
index 00000000000..2dca6b4b27c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/ac/withenable.ac
@@ -0,0 +1,7 @@
+## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/
+dnl
+dnl Copyright (C) 2009-2015 Peter Breitenlohner <tex-live@tug.org>
+dnl You may freely use, modify and/or distribute this file.
+dnl
+## configure options and TL libraries required for dvipdfm-x
+KPSE_ENABLE_PROG([dvipdfm-x], [kpathsea libpng libpaper])
diff --git a/Build/source/texk/dvipdfm-x/aclocal.m4 b/Build/source/texk/dvipdfm-x/aclocal.m4
new file mode 100644
index 00000000000..480e6d79297
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/aclocal.m4
@@ -0,0 +1,1217 @@
+# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
+
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.16'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.16.3], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.16.3])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_COND_IF -*- Autoconf -*-
+
+# Copyright (C) 2008-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_COND_IF
+# _AM_COND_ELSE
+# _AM_COND_ENDIF
+# --------------
+# These macros are only used for tracing.
+m4_define([_AM_COND_IF])
+m4_define([_AM_COND_ELSE])
+m4_define([_AM_COND_ENDIF])
+
+# AM_COND_IF(COND, [IF-TRUE], [IF-FALSE])
+# ---------------------------------------
+# If the shell condition COND is true, execute IF-TRUE, otherwise execute
+# IF-FALSE. Allow automake to learn about conditional instantiating macros
+# (the AC_CONFIG_FOOS).
+AC_DEFUN([AM_COND_IF],
+[m4_ifndef([_AM_COND_VALUE_$1],
+ [m4_fatal([$0: no such condition "$1"])])dnl
+_AM_COND_IF([$1])dnl
+if test -z "$$1_TRUE"; then :
+ m4_n([$2])[]dnl
+m4_ifval([$3],
+[_AM_COND_ELSE([$1])dnl
+else
+ $3
+])dnl
+_AM_COND_ENDIF([$1])dnl
+fi[]dnl
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ # TODO: see whether this extra hack can be removed once we start
+ # requiring Autoconf 2.70 or later.
+ AS_CASE([$CONFIG_FILES],
+ [*\'*], [eval set x "$CONFIG_FILES"],
+ [*], [set x $CONFIG_FILES])
+ shift
+ # Used to flag and report bootstrapping failures.
+ am_rc=0
+ for am_mf
+ do
+ # Strip MF so we end up with the name of the file.
+ am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile which includes
+ # dependency-tracking related rules and includes.
+ # Grep'ing the whole file directly is not great: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+ || continue
+ am_dirpart=`AS_DIRNAME(["$am_mf"])`
+ am_filepart=`AS_BASENAME(["$am_mf"])`
+ AM_RUN_LOG([cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles]) || am_rc=$?
+ done
+ if test $am_rc -ne 0; then
+ AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+ for automatic dependency tracking. If GNU make was not used, consider
+ re-running the configure script with MAKE="gmake" (or whatever is
+ necessary). You can also try re-running configure with the
+ '--disable-dependency-tracking' option to at least be able to build
+ the package (albeit without support for automatic dependency tracking).])
+ fi
+ AS_UNSET([am_dirpart])
+ AS_UNSET([am_filepart])
+ AS_UNSET([am_mf])
+ AS_UNSET([am_rc])
+ rm -f conftest-deps.mk
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
+am__doit:
+ @echo this is the am__doit target >confinc.out
+.PHONY: am__doit
+END
+am__include="#"
+am__quote=
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+ AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+ AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+ ['0:this is the am__doit target'],
+ [AS_CASE([$s],
+ [BSD], [am__include='.include' am__quote='"'],
+ [am__include='include' am__quote=''])])
+ if test "$am__include" != "#"; then
+ _am_result="yes ($s style)"
+ break
+ fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ MISSING="\${SHELL} '$am_aux_dir/missing'"
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([../../m4/kpse-common.m4])
+m4_include([../../m4/kpse-kpathsea-flags.m4])
+m4_include([../../m4/kpse-libpaper-flags.m4])
+m4_include([../../m4/kpse-libpng-flags.m4])
+m4_include([../../m4/kpse-warnings.m4])
+m4_include([../../m4/kpse-win32.m4])
+m4_include([../../m4/kpse-zlib-flags.m4])
+m4_include([../../m4/libtool.m4])
+m4_include([../../m4/ltoptions.m4])
+m4_include([../../m4/ltsugar.m4])
+m4_include([../../m4/ltversion.m4])
+m4_include([../../m4/lt~obsolete.m4])
diff --git a/Build/source/texk/dvipdfm-x/agl.c b/Build/source/texk/dvipdfm-x/agl.c
new file mode 100644
index 00000000000..c65cd4244e8
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/agl.c
@@ -0,0 +1,817 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * References:
+ *
+ * Unicode and Glyph Names, ver. 2.3., Adobe Solution Network
+ * http://partners.adobe.com/asn/tech/type/unicodegn.jsp
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <ctype.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "mfileio.h"
+#include "pdfparse.h"
+#include "dpxconf.h"
+/* Hash */
+#include "dpxutil.h"
+#include "dpxfile.h"
+
+#include "unicode.h"
+
+#include "agl.h"
+
+static int agl_load_listfile (const char *filename, int format);
+
+static agl_name *
+agl_new_name (void)
+{
+ agl_name *agln;
+
+ agln = NEW(1, agl_name);
+ agln->name = NULL;
+ agln->suffix = NULL;
+ agln->n_components = 0;
+ agln->alternate = NULL;
+ agln->is_predef = 0;
+
+ return agln;
+}
+
+static void
+agl_release_name (agl_name *agln)
+{
+ agl_name *next;
+
+ while (agln) {
+ next = agln->alternate;
+ if (agln->name)
+ RELEASE(agln->name);
+ if (agln->suffix)
+ RELEASE(agln->suffix);
+ agln->name = NULL;
+ RELEASE(agln);
+ agln = next;
+ }
+}
+
+char *
+agl_chop_suffix (const char *glyphname, char **suffix)
+{
+ char *name, *p;
+ int len;
+
+ ASSERT(glyphname && suffix);
+
+ p = strchr(glyphname, '.');
+ if (p) {
+ len = strlen(glyphname) - strlen(p);
+ if (len < 1) {
+ name = NULL;
+ *suffix = NEW(strlen(glyphname), char);
+ strcpy(*suffix, glyphname+1);
+ } else {
+ p++;
+ name = NEW(len + 1, char);
+ strncpy(name, glyphname, len);
+ name[len] = '\0';
+ if (p[0] == '\0') {
+ *suffix = NULL;
+ } else {
+ *suffix = NEW(strlen(p) + 1, char);
+ strcpy(*suffix, p);
+ }
+ }
+ } else {
+ name = NEW(strlen(glyphname) + 1, char);
+ strcpy(name, glyphname);
+ *suffix = NULL;
+ }
+
+ return name;
+}
+
+static const char * const modifiers[] = {
+ "acute", "breve", "caron", "cedilla", "circumflex",
+ "dieresis", "dotaccent", "grave", "hungarumlaut",
+ "macron", "ogonek", "ring", "tilde", "commaaccent",
+ "slash",
+
+ /* The following entries are not accent nor something
+ * but PS font may have those "small" version...
+ */
+ "ampersand", "exclam", "exclamdown",
+ "question","questiondown",
+ NULL
+};
+
+static int
+skip_capital (const char **p, const char *endptr)
+{
+ int slen = 0, len;
+
+ len = (int) (endptr - (*p));
+
+ if (len >= 2 &&
+ ((**p == 'A' && *(*p+1) == 'E') ||
+ (**p == 'O' && *(*p+1) == 'E'))) {
+ *p += 2;
+ slen = 2;
+ } else if (len >= 3 &&
+ **p == 'E' &&
+ *(*p+1) == 't' &&
+ *(*p+2) == 'h') {
+ *p += 3;
+ slen = 3;
+ } else if (len >= 5 &&
+ **p == 'T' &&
+ *(*p+1) == 'h' &&
+ *(*p+2) == 'o' &&
+ *(*p+3) == 'r' &&
+ *(*p+4) == 'n') {
+ *p += 5;
+ slen = 5;
+ } else if (len >= 1 &&
+ **p >= 'A' && **p <= 'Z') {
+ *p += 1;
+ slen = 1;
+ }
+
+ return slen;
+}
+
+static int
+skip_modifier (const char **p, const char *endptr)
+{
+ int slen = 0, len;
+ int i;
+
+ len = (int) (endptr - (*p));
+
+ for (i = 0; modifiers[i] != NULL; i++) {
+ if ((len >= strlen(modifiers[i]) &&
+ !memcmp(*p, modifiers[i], len))) {
+ slen = strlen(modifiers[i]);
+ *p += slen;
+ break;
+ }
+ }
+
+ return slen;
+}
+
+static int
+is_smallcap (const char *glyphname)
+{
+ int len, slen;
+ const char *p, *endptr;
+
+ if (!glyphname)
+ return 0;
+
+ p = glyphname;
+ len = strlen(glyphname);
+ if (len < 6 ||
+ strcmp(p + len - 5, "small"))
+ return 0;
+
+ endptr = p + len - 5;
+
+ len -= 5;
+ slen = skip_modifier(&p, endptr);
+ if (slen == len)
+ return 1; /* Acutesmall, Gravesmall, etc */
+ else if (slen > 0) { /* ??? */
+ return 0;
+ }
+
+ len -= skip_capital(&p, endptr);
+ if (len == 0) {
+ return 1; /* Asmall, AEsmall, etc */
+ }
+
+ while (len > 0) { /* allow multiple accent */
+ slen = skip_modifier(&p, endptr);
+ if (slen == 0)
+ return 0;
+ len -= slen;
+ }
+
+ return 1;
+}
+
+#define SUFFIX_LIST_MAX 16
+#define AGL_VAR_SMCP_IDX 0
+static struct {
+ const char *key;
+ const char *otl_tag;
+ const char *suffixes[SUFFIX_LIST_MAX];
+} var_list[] = {
+ {"small" , "smcp", {"sc", NULL}},
+ {"swash" , "swsh", {NULL}},
+ {"superior" , "sups", {NULL}},
+ {"inferior" , "sinf", {NULL}},
+ {"numerator" , "numr", {NULL}},
+ {"denominator" , "dnom", {NULL}},
+ {"oldstyle" , "onum", {NULL}},
+
+ /* The following only used by TeX, there are no
+ * corresponding OTL feat. tag.
+ */
+ {"display" , NULL, {NULL}},
+ {"text" , NULL, {NULL}},
+ {"big" , NULL, {NULL}},
+ {"bigg" , NULL, {NULL}},
+ {"Big" , NULL, {NULL}},
+ {"Bigg" , NULL, {NULL}},
+ {NULL, NULL, {NULL}}
+};
+
+const char *
+agl_suffix_to_otltag (const char *suffix)
+{
+ int i, j;
+
+ for (i = 0; var_list[i].key; i++) {
+ for (j = 0; var_list[i].suffixes[j]; j++) {
+ if (!strcmp(suffix, var_list[i].suffixes[j]))
+ return var_list[i].otl_tag;
+ }
+ if (!strcmp(suffix, var_list[i].key))
+ return var_list[i].otl_tag;
+ if (var_list[i].otl_tag &&
+ !strcmp(suffix, var_list[i].otl_tag))
+ return var_list[i].otl_tag;
+ }
+
+ return NULL;
+}
+
+static int
+agl_guess_name (const char *glyphname)
+{
+ int i, len;
+
+ if (is_smallcap(glyphname))
+ return AGL_VAR_SMCP_IDX;
+
+ len = strlen(glyphname);
+ for (i = 1; var_list[i].key != NULL; i++) {
+ if (len > strlen(var_list[i].key) &&
+ !strcmp(glyphname+len-strlen(var_list[i].key), var_list[i].key)
+ ) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static agl_name *
+agl_normalized_name (char *glyphname)
+{
+ agl_name *agln;
+ char *suffix;
+ int i, n;
+
+ if (!glyphname)
+ return NULL;
+
+ agln = agl_new_name();
+ suffix = strchr(glyphname, '.');
+ if (suffix) {
+ n = strlen(glyphname) - strlen(suffix);
+ if (suffix[1] != '\0') {
+ agln->suffix = NEW(strlen(suffix), char);
+ strcpy(agln->suffix, suffix+1);
+ }
+ agln->name = NEW(n+1, char);
+ memcpy(agln->name, glyphname, n);
+ agln->name[n] = '\0';
+ } else if (is_smallcap(glyphname)) {
+ n = strlen(glyphname) - 5;
+ agln->suffix = NEW(3, char);
+ strcpy(agln->suffix, "sc");
+ agln->name = NEW(n+1, char);
+ for (i = 0; i < n; i++) {
+ agln->name[i] = isupper((unsigned char)glyphname[i]) ?
+ (glyphname[i] + 32) : glyphname[i];
+ }
+ agln->name[n] = '\0';
+ } else {
+ int var_idx;
+
+#define SET_STRING(p,s) do {\
+ (p) = NEW(strlen((s))+1, char);\
+ strcpy((p),(s));\
+} while (0)
+ var_idx = agl_guess_name(glyphname);
+ if (var_idx < 0 ||
+ !var_list[var_idx].key) {
+ n = strlen(glyphname);
+ } else {
+ n = strlen(glyphname) - strlen(var_list[var_idx].key);
+ if (var_list[var_idx].suffixes[0])
+ SET_STRING(agln->suffix, var_list[var_idx].suffixes[0]);
+ else {
+ SET_STRING(agln->suffix, var_list[var_idx].key);
+ }
+ }
+ agln->name = NEW(n+1, char);
+ memcpy(agln->name, glyphname, n);
+ agln->name[n] = '\0';
+ }
+
+ return agln;
+}
+
+static struct ht_table aglmap;
+
+static inline void
+hval_free (void *hval)
+{
+ agl_release_name((struct agl_name *) hval);
+}
+
+void
+agl_init_map (void)
+{
+ ht_init_table(&aglmap, hval_free);
+ agl_load_listfile(AGL_EXTRA_LISTFILE, 0);
+ if (agl_load_listfile(AGL_PREDEF_LISTFILE, 1) < 0) {
+ WARN("Failed to load AGL file \"%s\"...", AGL_PREDEF_LISTFILE);
+ }
+ if (agl_load_listfile(AGL_DEFAULT_LISTFILE, 0) < 0) {
+ WARN("Failed to load AGL file \"%s\"...", AGL_DEFAULT_LISTFILE);
+ }
+}
+
+void
+agl_close_map (void)
+{
+ ht_clear_table(&aglmap);
+}
+
+#define WBUF_SIZE 1024
+
+static int
+agl_load_listfile (const char *filename, int is_predef)
+{
+ int count = 0;
+ const char *p, *endptr;
+ char *nextptr;
+ char wbuf[WBUF_SIZE];
+ FILE *fp;
+
+ if (!filename)
+ return -1;
+
+ fp = DPXFOPEN(filename, DPX_RES_TYPE_AGL);
+ if (!fp) {
+ return -1;
+ }
+
+ if (dpx_conf.verbose_level > 0)
+ MESG("<AGL:%s", filename);
+
+ while ((p = mfgets(wbuf, WBUF_SIZE, fp)) != NULL) {
+ agl_name *agln, *duplicate;
+ char *name;
+ int n_unicodes, i;
+ int32_t unicodes[AGL_MAX_UNICODES];
+
+ endptr = p + strlen(p);
+ skip_white(&p, endptr);
+
+ /* Need table version check. */
+ if (!p || p[0] == '#' || p >= endptr)
+ continue;
+ nextptr = strchr(p, ';');
+ if (!nextptr || nextptr == p)
+ continue;
+
+ name = parse_ident(&p, nextptr);
+
+ skip_white(&p, endptr);
+ if (!name || p[0] != ';') {
+ WARN("Invalid AGL entry: %s", wbuf);
+ if (name)
+ RELEASE(name);
+ continue;
+ }
+
+ p++;
+ skip_white(&p, endptr);
+
+ n_unicodes = 0;
+ while (p < endptr &&
+ ((p[0] >= '0' && p[0] <= '9') ||
+ (p[0] >= 'A' && p[0] <= 'F'))
+ ) {
+
+ if (n_unicodes >= AGL_MAX_UNICODES) {
+ WARN("Too many Unicode values");
+ break;
+ }
+ unicodes[n_unicodes++] = strtol(p, &nextptr, 16);
+
+ p = nextptr;
+ skip_white(&p, endptr);
+ }
+
+ if (n_unicodes == 0) {
+ WARN("AGL entry ignored (no mapping): %s", wbuf);
+ RELEASE(name);
+ continue;
+ }
+
+ agln = agl_normalized_name(name);
+ agln->is_predef = is_predef;
+ agln->n_components = n_unicodes;
+ for (i = 0; i < n_unicodes; i++) {
+ agln->unicodes[i] = unicodes[i];
+ }
+
+ duplicate = ht_lookup_table(&aglmap, name, strlen(name));
+ if (!duplicate)
+ ht_append_table(&aglmap, name, strlen(name), agln);
+ else {
+ while (duplicate->alternate)
+ duplicate = duplicate->alternate;
+ duplicate->alternate = agln;
+ }
+
+ if (dpx_conf.verbose_level > 5) {
+ if (agln->suffix)
+ MESG("agl: %s [%s.%s] -->", name, agln->name, agln->suffix);
+ else
+ MESG("agl: %s [%s] -->", name, agln->name);
+ for (i = 0; i < agln->n_components; i++) {
+ if (agln->unicodes[i] > 0xffff) {
+ MESG(" U+%06X", agln->unicodes[i]);
+ } else {
+ MESG(" U+%04X", agln->unicodes[i]);
+ }
+ }
+ MESG("\n");
+ }
+
+ RELEASE(name);
+ count++;
+ }
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(">");
+
+ return count;
+}
+
+agl_name *
+agl_lookup_list (const char *glyphname)
+{
+ agl_name *agln;
+
+ if (!glyphname)
+ return NULL;
+
+ agln = ht_lookup_table(&aglmap, glyphname, strlen(glyphname));
+
+ return agln;
+}
+
+int
+agl_name_is_unicode (const char *glyphname)
+{
+ char c, *suffix;
+ int i, len;
+
+ if (!glyphname)
+ return 0;
+
+ suffix = strchr(glyphname, '.');
+ len = (int) (suffix ? suffix - glyphname : strlen(glyphname));
+ /*
+ * uni02ac is invalid glyph name and mapped to th empty string.
+ */
+ if (len >= 7 && (len - 3) % 4 == 0 &&
+ !strncmp(glyphname, "uni", 3)) {
+ c = glyphname[3];
+ /*
+ * Check if the 4th character is uppercase hexadecimal digit.
+ * "union" should not be treated as Unicode glyph name.
+ */
+ if (isdigit((unsigned char)c) || (c >= 'A' && c <= 'F'))
+ return 1;
+ else
+ return 0;
+ } else if (len <= 7 && len >= 5 &&
+ glyphname[0] == 'u') {
+ for (i = 1; i < len - 1; i++) {
+ c = glyphname[i];
+ if (!isdigit((unsigned char)c) && (c < 'A' || c > 'F'))
+ return 0;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+int32_t
+agl_name_convert_unicode (const char *glyphname)
+{
+ int32_t ucv = -1;
+ const char *p;
+
+ if (!agl_name_is_unicode(glyphname))
+ return -1;
+
+ if (strlen(glyphname) > 7 && *(glyphname+7) != '.') {
+ WARN("Mapping to multiple Unicode characters not supported.");
+ return -1;
+ }
+
+ if (glyphname[1] == 'n')
+ p = glyphname + 3;
+ else
+ p = glyphname + 1;
+ ucv = 0;
+ while (*p != '\0' && *p != '.') {
+ if (!isdigit((unsigned char)*p) && (*p < 'A' || *p > 'F')) {
+ WARN("Invalid char %c in Unicode glyph name %s.", *p, glyphname);
+ return -1;
+ }
+ ucv <<= 4;
+ ucv += isdigit((unsigned char)*p) ? *p - '0' : *p - 'A' + 10;
+ p++;
+ }
+
+ if (!UC_is_valid(ucv)) {
+ if (ucv < 0x10000) {
+ WARN("Invalid Unicode code value U+%04X.", ucv);
+ } else {
+ WARN("Invalid Unicode code value U+%06X.", ucv);
+ }
+ ucv = -1;
+ }
+
+ return ucv;
+}
+
+
+
+static int
+xtol (const char *start, int len)
+{
+ int v = 0;
+
+ while (len-- > 0) {
+ v <<= 4;
+ if (isdigit((unsigned char)*start)) {
+ v += *start - '0';
+ } else if (*start >= 'A' && *start <= 'F') {
+ v += *start - 'A' + 10;
+ } else {
+ return -1;
+ }
+ start++;
+ }
+
+ return v;
+}
+
+#define IS_PUA(u) (((u) >= 0x00E000L && (u) <= 0x00F8FFL) || \
+ ((u) >= 0x0F0000L && (u) <= 0x0FFFFDL) || \
+ ((u) >= 0x100000L && (u) <= 0x10FFFDL) \
+)
+
+static int32_t
+put_unicode_glyph (const char *name,
+ unsigned char **dstpp, unsigned char *limptr)
+{
+ const char *p;
+ int32_t len = 0, ucv;
+
+ p = name;
+ ucv = 0;
+
+ if (p[1] != 'n') {
+ p += 1;
+ ucv = xtol(p, strlen(p));
+ len += UC_UTF16BE_encode_char(ucv, dstpp, limptr);
+ } else {
+ p += 3;
+ while (*p != '\0') {
+ ucv = xtol(p, 4);
+ len += UC_UTF16BE_encode_char(ucv, dstpp, limptr);
+ p += 4;
+ }
+ }
+
+ return len;
+}
+
+int32_t
+agl_sput_UTF16BE (const char *glyphstr,
+ unsigned char **dstpp, unsigned char *limptr,
+ int *fail_count)
+{
+ int32_t len = 0;
+ int count = 0;
+ const char *p, *endptr;
+
+ ASSERT(glyphstr && dstpp);
+
+ p = glyphstr;
+ endptr = strchr(p, '.');
+ if (!endptr)
+ endptr = p + strlen(p);
+
+ while (p < endptr) {
+ char *name;
+ const char *delim;
+ int32_t sub_len;
+ int i;
+ agl_name *agln0, *agln1 = NULL;
+
+ delim = strchr(p, '_');
+ if (delim == p) {
+ /*
+ * Glyph names starting with a underscore or two subsequent
+ * underscore in glyph name not allowed?
+ */
+ WARN("Invalid glyph name component in \"%s\".", glyphstr);
+ count++;
+ if (fail_count)
+ *fail_count = count;
+ return len; /* Cannot continue */
+ } else if (!delim || delim > endptr) {
+ delim = endptr;
+ }
+ sub_len = (int32_t) (delim - p);
+
+ name = NEW(sub_len+1, char);
+ memcpy(name, p, sub_len);
+ name[sub_len] = '\0';
+
+ if (agl_name_is_unicode(name)) {
+ sub_len = put_unicode_glyph(name, dstpp, limptr);
+ if (sub_len > 0)
+ len += sub_len;
+ else {
+ count++;
+ }
+ } else {
+ agln1 = agl_lookup_list(name);
+ if (!agln1 || (agln1->n_components == 1 &&
+ IS_PUA(agln1->unicodes[0]))) {
+ agln0 = agl_normalized_name(name);
+ if (agln0) {
+ if (dpx_conf.verbose_level > 1 && agln0->suffix) {
+ WARN("agl: fix %s --> %s.%s",
+ name, agln0->name, agln0->suffix);
+ }
+ agln1 = agl_lookup_list(agln0->name);
+ agl_release_name(agln0);
+ }
+ }
+ if (agln1) {
+ for (i = 0; i < agln1->n_components; i++) {
+ len += UC_UTF16BE_encode_char(agln1->unicodes[i], dstpp, limptr);
+ }
+ } else {
+ if (dpx_conf.verbose_level > 0) {
+ WARN("No Unicode mapping for glyph name \"%s\" found.", name);
+ }
+ count++;
+ }
+ }
+ RELEASE(name);
+ p = delim + 1;
+ }
+
+ if (fail_count)
+ *fail_count = count;
+ return len;
+}
+
+int
+agl_get_unicodes (const char *glyphstr,
+ int32_t *unicodes, int max_unicodes)
+{
+ int count = 0;
+ const char *p, *endptr;
+
+ p = glyphstr;
+ endptr = strchr(p, '.');
+ if (!endptr)
+ endptr = p + strlen(p);
+
+ while (p < endptr) {
+ char *name;
+ const char *delim;
+ int32_t sub_len;
+ int i;
+ agl_name *agln0, *agln1 = NULL;
+
+ delim = strchr(p, '_');
+ if (delim == p) {
+ /*
+ * Glyph names starting with a underscore or two subsequent
+ * underscore in glyph name not allowed?
+ */
+ WARN("Invalid glyph name component in \"%s\".", glyphstr);
+ return -1; /* Cannot continue */
+ } else if (!delim || delim > endptr) {
+ delim = endptr;
+ }
+ sub_len = (int32_t) (delim - p);
+
+ name = NEW(sub_len+1, char);
+ memcpy(name, p, sub_len);
+ name[sub_len] = '\0';
+
+ if (agl_name_is_unicode(name)) {
+ p = name;
+ if (p[1] != 'n') { /* uXXXXXXXX */
+ if (count >= max_unicodes) {
+ RELEASE(name);
+ return -1;
+ }
+ p++;
+ unicodes[count++] = xtol(p, strlen(p));
+ } else {
+ p += 3;
+ while (*p != '\0') {
+ if (count >= max_unicodes) {
+ RELEASE(name);
+ return -1;
+ }
+ unicodes[count++] = xtol(p, 4);
+ p += 4;
+ }
+ }
+ } else {
+ agln1 = agl_lookup_list(name);
+ if (!agln1 || (agln1->n_components == 1 &&
+ IS_PUA(agln1->unicodes[0]))) {
+ agln0 = agl_normalized_name(name);
+ if (agln0) {
+ if (dpx_conf.verbose_level > 1 && agln0->suffix) {
+ WARN("agl: fix %s --> %s.%s",
+ name, agln0->name, agln0->suffix);
+ }
+ agln1 = agl_lookup_list(agln0->name);
+ agl_release_name(agln0);
+ }
+ }
+ if (agln1) {
+ if (count + agln1->n_components > max_unicodes) {
+ RELEASE(name);
+ return -1;
+ }
+ for (i = 0; i < agln1->n_components; i++) {
+ unicodes[count++] = agln1->unicodes[i];
+ }
+ } else {
+ if (dpx_conf.verbose_level > 1)
+ WARN("No Unicode mapping for glyph name \"%s\" found.", name);
+ RELEASE(name);
+ return -1;
+ }
+ }
+ RELEASE(name);
+ p = delim + 1;
+ }
+
+ return count;
+}
diff --git a/Build/source/texk/dvipdfm-x/agl.h b/Build/source/texk/dvipdfm-x/agl.h
new file mode 100644
index 00000000000..252a6eeebce
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/agl.h
@@ -0,0 +1,64 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _AGL_H_
+#define _AGL_H_
+
+#define AGL_DEFAULT_LISTFILE "glyphlist.txt"
+#define AGL_PREDEF_LISTFILE "pdfglyphlist.txt"
+#define AGL_EXTRA_LISTFILE "texglyphlist.txt"
+
+#define AGL_MAX_UNICODES 16
+struct agl_name {
+ char *name;
+ char *suffix;
+ int n_components;
+ int32_t unicodes[AGL_MAX_UNICODES];
+ struct agl_name *alternate;
+ int is_predef;
+};
+typedef struct agl_name agl_name;
+
+extern char *agl_chop_suffix (const char *glyphname, char **suffix);
+
+extern int32_t agl_sput_UTF16BE (const char *name,
+ unsigned char **dstpp,
+ unsigned char *limptr, int *num_fails);
+
+extern int agl_get_unicodes (const char *glyphstr,
+ int32_t *unicodes, int max_uncodes);
+
+extern int agl_name_is_unicode (const char *glyphname);
+extern int32_t agl_name_convert_unicode (const char *glyphname);
+
+extern const char *agl_suffix_to_otltag (const char *suffix);
+
+extern agl_name *agl_lookup_list (const char *glyphname);
+
+#if 0
+extern int agl_select_listfile (const char *mapfile);
+#endif
+
+extern void agl_init_map (void);
+extern void agl_close_map (void);
+
+#endif /* _AGL_H_ */
diff --git a/Build/source/texk/dvipdfm-x/bmpimage.c b/Build/source/texk/dvipdfm-x/bmpimage.c
new file mode 100644
index 00000000000..844a328f421
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/bmpimage.c
@@ -0,0 +1,539 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * BMP SUPPORT: Not fully supported.
+ * Unsupported features: Transparency, etc.
+ */
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+
+#include "pdfobj.h"
+
+#include "bmpimage.h"
+
+#define DIB_FILE_HEADER_SIZE 14
+#define DIB_CORE_HEADER_SIZE 12
+#define DIB_INFO_HEADER_SIZE 40
+#define DIB_INFO_HEADER_SIZE2 64
+#define DIB_INFO_HEADER_SIZE4 108
+#define DIB_INFO_HEADER_SIZE5 124
+
+#define DIB_COMPRESS_NONE 0
+#define DIB_COMPRESS_RLE8 1
+#define DIB_COMPRESS_RLE4 2
+
+#define DIB_HEADER_SIZE_MAX (DIB_FILE_HEADER_SIZE+DIB_INFO_HEADER_SIZE5)
+
+struct hdr_info {
+ unsigned int offset;
+ unsigned int hsize;
+ unsigned int width;
+ int height;
+ int compression;
+ unsigned short bit_count; /* Bits per pix */
+ int psize; /* Bytes per palette color: 3 for OS2, 4 for Win */
+ unsigned int x_pix_per_meter;
+ unsigned int y_pix_per_meter;
+};
+
+static int read_header (FILE *fp, struct hdr_info *hdr);
+static int read_raster_rle8 (unsigned char *data_ptr,
+ int width, int height, FILE *fp);
+static int read_raster_rle4 (unsigned char *data_ptr,
+ int width, int height, FILE *fp);
+
+int
+check_for_bmp (FILE *fp)
+{
+ unsigned char sigbytes[2];
+
+ if (!fp)
+ return 0;
+
+ rewind(fp);
+ if (fread(sigbytes, 1, sizeof(sigbytes), fp) != sizeof(sigbytes) ||
+ sigbytes[0] != 'B' || sigbytes[1] != 'M')
+ return 0;
+ return 1;
+}
+
+static void
+get_density (double *xdensity, double *ydensity, struct hdr_info *hdr)
+{
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode)
+ *xdensity = *ydensity = 72.0 / 100.0;
+ else if (hdr->x_pix_per_meter > 0 && hdr->y_pix_per_meter > 0) { /* 0 for undefined. FIXME */
+ *xdensity = 72.0 / (hdr->x_pix_per_meter * 0.0254);
+ *ydensity = 72.0 / (hdr->y_pix_per_meter * 0.0254);
+ } else {
+ *xdensity = 1.0;
+ *ydensity = 1.0;
+ }
+}
+
+int
+bmp_get_bbox (FILE *fp, int *width, int *height,
+ double *xdensity, double *ydensity)
+{
+ int r;
+ struct hdr_info hdr;
+
+ rewind(fp);
+ r = read_header(fp, &hdr);
+
+ *width = hdr.width;
+ *height = hdr.height < 0 ? -hdr.height : hdr.height;
+ get_density(xdensity, ydensity, &hdr);
+
+ return r;
+}
+
+
+int
+bmp_include_image (pdf_ximage *ximage, FILE *fp)
+{
+ pdf_obj *stream, *stream_dict, *colorspace;
+ ximage_info info;
+ struct hdr_info hdr;
+ int num_palette, flip;
+ int i;
+
+ pdf_ximage_init_image_info(&info);
+
+ stream = stream_dict = colorspace = NULL;
+
+ rewind(fp);
+ if (read_header(fp, &hdr) < 0)
+ return -1;
+
+ get_density(&info.xdensity, &info.ydensity, &hdr);
+ info.width = hdr.width;
+ info.height = hdr.height;
+ if (info.height < 0) {
+ info.height = -info.height;
+ flip = 0;
+ } else {
+ flip = 1;
+ }
+
+
+ if (hdr.bit_count < 24) {
+ if (hdr.bit_count != 1 &&
+ hdr.bit_count != 4 && hdr.bit_count != 8) {
+ WARN("Unsupported palette size: %ld", hdr.bit_count);
+ return -1;
+ }
+ num_palette = (hdr.offset - hdr.hsize - DIB_FILE_HEADER_SIZE) / hdr.psize;
+ info.bits_per_component = hdr.bit_count;
+ info.num_components = 1;
+ } else if (hdr.bit_count == 24) { /* full color */
+ num_palette = 1; /* dummy */
+ info.bits_per_component = 8;
+ info.num_components = 3;
+ } else {
+ WARN("Unkown/Unsupported BMP bitCount value: %ld", hdr.bit_count);
+ return -1;
+ }
+
+ if (info.width == 0 || info.height == 0 || num_palette < 1) {
+ WARN("Invalid BMP file: width=%ld, height=%ld, #palette=%d",
+ info.width, info.height, num_palette);
+ return -1;
+ }
+
+ /* Start reading raster data */
+ stream = pdf_new_stream(STREAM_COMPRESS);
+ stream_dict = pdf_stream_dict(stream);
+
+ /* Color space: Indexed or DeviceRGB */
+ if (hdr.bit_count < 24) {
+ pdf_obj *lookup;
+ unsigned char *palette, bgrq[4];
+
+ palette = NEW(num_palette*3+1, unsigned char);
+ for (i = 0; i < num_palette; i++) {
+ if (fread(bgrq, 1, hdr.psize, fp) != hdr.psize) {
+ WARN("Reading file failed...");
+ RELEASE(palette);
+ return -1;
+ }
+ /* BGR data */
+ palette[3*i ] = bgrq[2];
+ palette[3*i+1] = bgrq[1];
+ palette[3*i+2] = bgrq[0];
+ }
+ lookup = pdf_new_string(palette, num_palette*3);
+ RELEASE(palette);
+
+ colorspace = pdf_new_array();
+ pdf_add_array(colorspace, pdf_new_name("Indexed"));
+ pdf_add_array(colorspace, pdf_new_name("DeviceRGB"));
+ pdf_add_array(colorspace, pdf_new_number(num_palette-1));
+ pdf_add_array(colorspace, lookup);
+ } else {
+ colorspace = pdf_new_name("DeviceRGB");
+ }
+ pdf_add_dict(stream_dict, pdf_new_name("ColorSpace"), colorspace);
+
+ /* Raster data of BMP is four-byte aligned. */
+ {
+ int rowbytes, n;
+ unsigned char *p, *stream_data_ptr = NULL;
+
+ rowbytes = (info.width * hdr.bit_count + 7) / 8;
+
+ seek_absolute(fp, hdr.offset);
+ if (hdr.compression == DIB_COMPRESS_NONE) {
+ int dib_rowbytes;
+ int padding;
+
+ padding = (rowbytes % 4) ? 4 - (rowbytes % 4) : 0;
+ dib_rowbytes = rowbytes + padding;
+ stream_data_ptr = NEW(rowbytes*info.height + padding, unsigned char);
+ for (n = 0; n < info.height; n++) {
+ p = stream_data_ptr + n * rowbytes;
+ if (fread(p, 1, dib_rowbytes, fp) != dib_rowbytes) {
+ WARN("Reading BMP raster data failed...");
+ pdf_release_obj(stream);
+ RELEASE(stream_data_ptr);
+ return -1;
+ }
+ }
+ } else if (hdr.compression == DIB_COMPRESS_RLE8) {
+ stream_data_ptr = NEW(rowbytes*info.height, unsigned char);
+ if (read_raster_rle8(stream_data_ptr, info.width, info.height, fp) < 0) {
+ WARN("Reading BMP raster data failed...");
+ pdf_release_obj(stream);
+ RELEASE(stream_data_ptr);
+ return -1;
+ }
+ } else if (hdr.compression == DIB_COMPRESS_RLE4) {
+ stream_data_ptr = NEW(rowbytes*info.height, unsigned char);
+ if (read_raster_rle4(stream_data_ptr, info.width, info.height, fp) < 0) {
+ WARN("Reading BMP raster data failed...");
+ pdf_release_obj(stream);
+ RELEASE(stream_data_ptr);
+ return -1;
+ }
+ } else {
+ WARN("Unknown/Unsupported compression type for BMP image: %ld", hdr.compression);
+ pdf_release_obj(stream);
+ return -1;
+ }
+
+ /* gbr --> rgb */
+ if (hdr.bit_count == 24) {
+ for (n = 0; n < info.width * info.height * 3; n += 3) {
+ unsigned char g;
+ g = stream_data_ptr[n];
+ stream_data_ptr[n ] = stream_data_ptr[n+2];
+ stream_data_ptr[n+2] = g;
+ }
+ }
+
+ if (flip) {
+ for (n = info.height - 1; n >= 0; n--) {
+ p = stream_data_ptr + n * rowbytes;
+ pdf_add_stream(stream, p, rowbytes);
+ }
+ } else {
+ pdf_add_stream(stream, stream_data_ptr, rowbytes*info.height);
+ }
+ RELEASE(stream_data_ptr);
+ }
+
+ /* Predictor is usually not so efficient for indexed images. */
+ if (hdr.bit_count >= 24 && info.bits_per_component >= 8 &&
+ info.height > 64) {
+ pdf_stream_set_predictor(stream, 15, info.width,
+ info.bits_per_component, info.num_components);
+ }
+ pdf_ximage_set_image(ximage, &info, stream);
+
+ return 0;
+}
+
+
+static int
+read_header (FILE *fp, struct hdr_info *hdr)
+{
+ unsigned char buf[DIB_HEADER_SIZE_MAX+4];
+ unsigned char *p;
+
+ p = buf;
+ if (fread(buf, 1, DIB_FILE_HEADER_SIZE + 4, fp)
+ != DIB_FILE_HEADER_SIZE + 4) {
+ WARN("Could not read BMP file header...");
+ return -1;
+ }
+
+ if (p[0] != 'B' || p[1] != 'M') {
+ WARN("File not starting with \'B\' \'M\'... Not a BMP file?");
+ return -1;
+ }
+ p += 2;
+
+#define ULONG_LE(b) ((b)[0] + ((b)[1] << 8) +\
+ ((b)[2] << 16) + ((b)[3] << 24))
+#define USHORT_LE(b) ((b)[0] + ((b)[1] << 8))
+
+ /* fsize = ULONG_LE(p); */ p += 4;
+ if (ULONG_LE(p) != 0) {
+ WARN("Not a BMP file???");
+ return -1;
+ }
+ p += 4;
+ hdr->offset = ULONG_LE(p); p += 4;
+
+ /* info header */
+ hdr->hsize = ULONG_LE(p); p += 4;
+ if (fread(p, sizeof(char), hdr->hsize - 4, fp) != hdr->hsize - 4) {
+ WARN("Could not read BMP file header...");
+ return -1;
+ }
+ switch (hdr->hsize) {
+ case DIB_CORE_HEADER_SIZE:
+ hdr->width = USHORT_LE(p); p += 2;
+ hdr->height = USHORT_LE(p); p += 2;
+ hdr->x_pix_per_meter = 0; /* undefined. FIXME */
+ hdr->y_pix_per_meter = 0; /* undefined. FIXME */
+ if (USHORT_LE(p) != 1) {
+ WARN("Unknown bcPlanes value in BMP COREHEADER.");
+ return -1;
+ }
+ p += 2;
+ hdr->bit_count = USHORT_LE(p); p += 2;
+ hdr->compression = DIB_COMPRESS_NONE;
+ hdr->psize = 3;
+ break;
+ case DIB_INFO_HEADER_SIZE :
+ case DIB_INFO_HEADER_SIZE2:
+ case DIB_INFO_HEADER_SIZE4:
+ case DIB_INFO_HEADER_SIZE5:
+ hdr->width = ULONG_LE(p); p += 4;
+ hdr->height = ULONG_LE(p); p += 4;
+ if (USHORT_LE(p) != 1) {
+ WARN("Unknown biPlanes value in BMP INFOHEADER.");
+ return -1;
+ }
+ p += 2;
+ hdr->bit_count = USHORT_LE(p); p += 2;
+ hdr->compression = ULONG_LE(p); p += 4;
+ /* ignore biSizeImage */ p += 4;
+ hdr->x_pix_per_meter = ULONG_LE(p); p += 4;
+ hdr->y_pix_per_meter = ULONG_LE(p); p += 4;
+ hdr->psize = 4;
+ break;
+ default:
+ WARN("Unknown BMP header type.");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+read_raster_rle8 (unsigned char *data_ptr,
+ int width, int height, FILE *fp)
+{
+ int count = 0;
+ unsigned char *p, b0, b1;
+ int h, v, rowbytes;
+ int eol, eoi;
+
+ p = data_ptr;
+ rowbytes = width;
+ memset(data_ptr, 0, rowbytes*height);
+ for (v = 0, eoi = 0; v < height && !eoi; v++) {
+ for (h = 0, eol = 0; h < width && !eol; ) {
+
+ b0 = get_unsigned_byte(fp);
+ b1 = get_unsigned_byte(fp);
+ count += 2;
+
+ p = data_ptr + v * rowbytes + h;
+
+ if (b0 == 0x00) {
+ switch (b1) {
+ case 0x00: /* EOL */
+ eol = 1;
+ break;
+ case 0x01: /* EOI */
+ eoi = 1;
+ break;
+ case 0x02:
+ h += get_unsigned_byte(fp);
+ v += get_unsigned_byte(fp);
+ count += 2;
+ break;
+ default:
+ h += b1;
+ if (h > width) {
+ WARN("RLE decode failed...");
+ return -1;
+ }
+ if (fread(p, 1, b1, fp) != b1)
+ return -1;
+ count += b1;
+ if (b1 % 2) {
+ get_unsigned_byte(fp);
+ count++;
+ }
+ break;
+ }
+ } else {
+ h += b0;
+ if (h > width) {
+ WARN("RLE decode failed...");
+ return -1;
+ }
+ memset(p, b1, b0);
+ }
+ }
+
+ /* Check for EOL and EOI marker */
+ if (!eol && !eoi) {
+ b0 = get_unsigned_byte(fp);
+ b1 = get_unsigned_byte(fp);
+ if (b0 != 0x00) {
+ WARN("RLE decode failed...");
+ return -1;
+ } else if (b1 == 0x01) {
+ eoi = 1;
+ } else if (b1 != 0x00) {
+ WARN("RLE decode failed...");
+ return -1;
+ }
+ }
+
+ /* next row ... */
+ }
+
+ return count;
+}
+
+static int
+read_raster_rle4 (unsigned char *data_ptr,
+ int width, int height, FILE *fp)
+{
+ int count = 0;
+ unsigned char *p, b0, b1, b;
+ int h, v, rowbytes;
+ int eol, eoi, i, nbytes;
+
+ p = data_ptr;
+ rowbytes = (width + 1) / 2;
+ memset(data_ptr, 0, rowbytes*height);
+ for (v = 0, eoi = 0; v < height && !eoi; v++) {
+ for (h = 0, eol = 0; h < width && !eol; ) {
+
+ b0 = get_unsigned_byte(fp);
+ b1 = get_unsigned_byte(fp);
+ count += 2;
+
+ p = data_ptr + v * rowbytes + (h / 2);
+ if (b0 == 0x00) {
+ switch (b1) {
+ case 0x00: /* EOL */
+ eol = 1;
+ break;
+ case 0x01: /* EOI */
+ eoi = 1;
+ break;
+ case 0x02:
+ h += get_unsigned_byte(fp);
+ v += get_unsigned_byte(fp);
+ count += 2;
+ break;
+ default:
+ if (h + b1 > width) {
+ WARN("RLE decode failed...");
+ return -1;
+ }
+ nbytes = (b1 + 1)/2;
+ if (h % 2) { /* starting at hi-nib */
+ for (i = 0; i < nbytes; i++) {
+ b = get_unsigned_byte(fp);
+ *p++ |= (b >> 4) & 0x0f;
+ *p = (b << 4) & 0xf0;
+ }
+ } else {
+ if (fread(p, 1, nbytes, fp) != nbytes) {
+ return -1;
+ }
+ }
+ h += b1;
+ count += nbytes;
+ if (nbytes % 2) {
+ get_unsigned_byte(fp);
+ count++;
+ }
+ break;
+ }
+ } else {
+ if (h + b0 > width) {
+ WARN("RLE decode failed...");
+ return -1;
+ }
+ if (h % 2) {
+ *p++ = (b1 >> 4) & 0x0f;
+ b1 = ((b1 << 4) & 0xf0)|((b1 >> 4) & 0x0f);
+ b0--;
+ h++;
+ }
+ nbytes = (b0 + 1)/2;
+ memset(p, b1, nbytes);
+ h += b0;
+ if (h % 2)
+ p[nbytes-1] &= 0xf0;
+ }
+ }
+
+ /* Check for EOL and EOI marker */
+ if (!eol && !eoi) {
+ b0 = get_unsigned_byte(fp);
+ b1 = get_unsigned_byte(fp);
+ if (b0 != 0x00) {
+ WARN("No EOL/EOI marker. RLE decode failed...");
+ return -1;
+ } else if (b1 == 0x01) {
+ eoi = 1;
+ } else if (b1 != 0x00) {
+ WARN("No EOL/EOI marker. RLE decode failed...");
+ return -1;
+ }
+ }
+
+ /* next row ... */
+ }
+
+ return count;
+}
diff --git a/Build/source/texk/dvipdfm-x/bmpimage.h b/Build/source/texk/dvipdfm-x/bmpimage.h
new file mode 100644
index 00000000000..b2a21fdb279
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/bmpimage.h
@@ -0,0 +1,35 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+
+#ifndef _BMPIMAGE_H_
+#define _BMPIMAGE_H_
+
+#include "mfileio.h"
+#include "pdfximage.h"
+
+extern int bmp_include_image (pdf_ximage *ximage, FILE *file);
+extern int check_for_bmp (FILE *file);
+extern int bmp_get_bbox (FILE *file, int *width, int *height,
+ double *xdensity, double *ydensity);
+
+#endif /* _BMPIMAGE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cff.c b/Build/source/texk/dvipdfm-x/cff.c
new file mode 100644
index 00000000000..5eb7b9f6998
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cff.c
@@ -0,0 +1,1488 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+
+#include "cff_limits.h"
+#include "cff_types.h"
+#include "cff_stdstr.h"
+#include "cff_dict.h"
+
+#include "cff.h"
+
+#define CFF_DEBUG 5
+#define CFF_DEBUG_STR "CFF"
+
+static unsigned get_unsigned (FILE *stream, int n)
+{
+ unsigned v = 0;
+
+ while (n-- > 0)
+ v = v*0x100u + get_unsigned_byte(stream);
+
+ return v;
+}
+
+#define get_offset(s, n) get_unsigned((s), (n))
+
+/*
+ * Read Header, Name INDEX, Top DICT INDEX, and String INDEX.
+ */
+cff_font *cff_open(FILE *stream, int offset, int n)
+{
+ cff_font *cff;
+ cff_index *idx;
+
+ cff = NEW(1, cff_font);
+
+ cff->fontname = NULL;
+ cff->index = n;
+ cff->stream = stream;
+ cff->offset = offset;
+ cff->filter = 0; /* not used */
+ cff->flag = 0;
+
+ cff->name = NULL;
+ cff->topdict = NULL;
+ cff->gsubr = NULL;
+ cff->encoding = NULL;
+ cff->charsets = NULL;
+ cff->fdselect = NULL;
+ cff->cstrings = NULL;
+ cff->fdarray = NULL;
+ cff->private = NULL;
+ cff->subrs = NULL;
+
+ cff->num_glyphs = 0;
+ cff->num_fds = 0;
+ cff->string = NULL;
+ cff->_string = NULL;
+
+ cff_seek_set(cff, 0);
+ cff->header.major = get_unsigned_byte(cff->stream);
+ cff->header.minor = get_unsigned_byte(cff->stream);
+ cff->header.hdr_size = get_unsigned_byte(cff->stream);
+ cff->header.offsize = get_unsigned_byte(cff->stream);
+ if (cff->header.offsize < 1 ||
+ cff->header.offsize > 4)
+ ERROR("invalid offsize data");
+
+ if (cff->header.major > 1 ||
+ cff->header.minor > 0) {
+ WARN("%s: CFF version %u.%u not supported.",
+ CFF_DEBUG_STR, cff->header.major, cff->header.minor);
+ cff_close(cff);
+ return NULL;
+ }
+
+ cff_seek_set(cff, (cff->header).hdr_size);
+
+ /* Name INDEX */
+ idx = cff_get_index(cff);
+ if (n > idx->count - 1) {
+ WARN("%s: Invalid CFF fontset index number.", CFF_DEBUG_STR);
+ cff_close(cff);
+ return NULL;
+ }
+
+ cff->name = idx;
+
+ cff->fontname = cff_get_name(cff);
+
+ /* Top DICT INDEX */
+ idx = cff_get_index(cff);
+ if (n > idx->count - 1)
+ ERROR("CFF Top DICT not exist...");
+ cff->topdict = cff_dict_unpack(idx->data + idx->offset[n] - 1,
+ idx->data + idx->offset[n + 1] - 1);
+ if (!cff->topdict)
+ ERROR("Parsing CFF Top DICT data failed...");
+ cff_release_index(idx);
+
+ if (cff_dict_known(cff->topdict, "CharstringType") &&
+ cff_dict_get(cff->topdict, "CharstringType", 0) != 2) {
+ WARN("Only Type 2 Charstrings supported...");
+ cff_close(cff);
+ return NULL;
+ }
+
+ if (cff_dict_known(cff->topdict, "SyntheticBase")) {
+ WARN("CFF Synthetic font not supported.");
+ cff_close(cff);
+ return NULL;
+ }
+
+ /* String INDEX */
+ cff->string = cff_get_index(cff);
+
+ /* offset to GSubr */
+ cff->gsubr_offset = tell_position(cff->stream) - offset;
+
+ /* Number of glyphs */
+ offset = cff_dict_get(cff->topdict, "CharStrings", 0);
+ cff_seek_set(cff, offset);
+ cff->num_glyphs = get_unsigned_pair(cff->stream);
+
+ /* Check for font type */
+ if (cff_dict_known(cff->topdict, "ROS")) {
+ cff->flag |= FONTTYPE_CIDFONT;
+ } else {
+ cff->flag |= FONTTYPE_FONT;
+ }
+
+ /* Check for encoding */
+ if (cff_dict_known(cff->topdict, "Encoding")) {
+ offset = cff_dict_get(cff->topdict, "Encoding", 0);
+ if (offset == 0) { /* predefined */
+ cff->flag |= ENCODING_STANDARD;
+ } else if (offset == 1) {
+ cff->flag |= ENCODING_EXPERT;
+ }
+ } else {
+ cff->flag |= ENCODING_STANDARD;
+ }
+
+ /* Check for charset */
+ if (cff_dict_known(cff->topdict, "charset")) {
+ offset = cff_dict_get(cff->topdict, "charset", 0);
+ if (offset == 0) { /* predefined */
+ cff->flag |= CHARSETS_ISOADOBE;
+ } else if (offset == 1) {
+ cff->flag |= CHARSETS_EXPERT;
+ } else if (offset == 2) {
+ cff->flag |= CHARSETS_EXPSUB;
+ }
+ } else {
+ cff->flag |= CHARSETS_ISOADOBE;
+ }
+
+ cff_seek_set(cff, cff->gsubr_offset); /* seek back to GSubr */
+
+ return cff;
+}
+
+void
+cff_close (cff_font *cff)
+{
+ card16 i;
+
+ if (cff) {
+ if (cff->fontname) RELEASE(cff->fontname);
+ if (cff->name) cff_release_index(cff->name);
+ if (cff->topdict) cff_release_dict(cff->topdict);
+ if (cff->string) cff_release_index(cff->string);
+ if (cff->gsubr) cff_release_index(cff->gsubr);
+ if (cff->encoding) cff_release_encoding(cff->encoding);
+ if (cff->charsets) cff_release_charsets(cff->charsets);
+ if (cff->fdselect) cff_release_fdselect(cff->fdselect);
+ if (cff->cstrings) cff_release_index(cff->cstrings);
+ if (cff->fdarray) {
+ for (i=0;i<cff->num_fds;i++) {
+ if (cff->fdarray[i]) cff_release_dict(cff->fdarray[i]);
+ }
+ RELEASE(cff->fdarray);
+ }
+ if (cff->private) {
+ for (i=0;i<cff->num_fds;i++) {
+ if (cff->private[i]) cff_release_dict(cff->private[i]);
+ }
+ RELEASE(cff->private);
+ }
+ if (cff->subrs) {
+ for (i=0;i<cff->num_fds;i++) {
+ if (cff->subrs[i]) cff_release_index(cff->subrs[i]);
+ }
+ RELEASE(cff->subrs);
+ }
+ if (cff->_string)
+ cff_release_index(cff->_string);
+
+ RELEASE(cff);
+ }
+
+ return;
+}
+
+char *
+cff_get_name (cff_font *cff)
+{
+ char *fontname;
+ l_offset len;
+ cff_index *idx;
+
+ idx = cff->name;
+ len = idx->offset[cff->index + 1] - idx->offset[cff->index];
+ fontname = NEW(len + 1, char);
+ memcpy(fontname, idx->data + idx->offset[cff->index] - 1, len);
+ fontname[len] = '\0';
+
+ return fontname;
+}
+
+int
+cff_set_name (cff_font *cff, char *name)
+{
+ cff_index *idx;
+
+ if (strlen(name) > 127)
+ ERROR("FontName string length too large...");
+
+ if (cff->name)
+ cff_release_index(cff->name);
+
+ cff->name = idx = NEW(1, cff_index);
+ idx->count = 1;
+ idx->offsize = 1;
+ idx->offset = NEW(2, l_offset);
+ (idx->offset)[0] = 1;
+ (idx->offset)[1] = strlen(name) + 1;
+ idx->data = NEW(strlen(name), card8);
+ memmove(idx->data, name, strlen(name)); /* no trailing '\0' */
+
+ return 5 + strlen(name);
+}
+
+int
+cff_put_header (cff_font *cff, card8 *dest, int destlen)
+{
+ if (destlen < 4)
+ ERROR("Not enough space available...");
+
+ *(dest++) = cff->header.major;
+ *(dest++) = cff->header.minor;
+ *(dest++) = 4; /* Additional data in between header and
+ * Name INDEX ignored.
+ */
+ /* We will set all offset (0) to four-byte integer. */
+ *(dest++) = 4;
+ cff->header.offsize = 4;
+
+ return 4;
+}
+
+/* Only read header part but not body */
+cff_index *
+cff_get_index_header (cff_font *cff)
+{
+ cff_index *idx;
+ card16 i, count;
+
+ idx = NEW(1, cff_index);
+
+ idx->count = count = get_unsigned_pair(cff->stream);
+ if (count > 0) {
+ idx->offsize = get_unsigned_byte(cff->stream);
+ if (idx->offsize < 1 || idx->offsize > 4)
+ ERROR("invalid offsize data");
+
+ idx->offset = NEW(count+1, l_offset);
+ for (i=0;i<count;i++) {
+ (idx->offset)[i] = get_offset(cff->stream, idx->offsize);
+ }
+ if (count == 0xFFFF)
+ cff_seek(cff, cff_tell(cff) + idx->offsize);
+ else
+ (idx->offset)[i] = get_offset(cff->stream, idx->offsize);
+
+ if (idx->offset[0] != 1)
+ ERROR("cff_get_index(): invalid index data");
+
+ idx->data = NULL;
+ } else {
+ idx->offsize = 0;
+ idx->offset = NULL;
+ idx->data = NULL;
+ }
+
+ return idx;
+}
+
+cff_index *
+cff_get_index (cff_font *cff)
+{
+ cff_index *idx;
+ card16 i, count;
+ int length, nb_read, offset;
+
+ idx = NEW(1, cff_index);
+
+ idx->count = count = get_unsigned_pair(cff->stream);
+ if (count > 0) {
+ idx->offsize = get_unsigned_byte(cff->stream);
+ if (idx->offsize < 1 || idx->offsize > 4)
+ ERROR("invalid offsize data");
+
+ idx->offset = NEW(count + 1, l_offset);
+ for (i = 0 ; i < count + 1; i++) {
+ idx->offset[i] = get_offset(cff->stream, idx->offsize);
+ }
+
+ if (idx->offset[0] != 1)
+ ERROR("Invalid CFF Index offset data");
+
+ length = idx->offset[count] - idx->offset[0];
+
+ idx->data = NEW(length, card8);
+ offset = 0;
+ while (length > 0) {
+ nb_read = cff_read_data(idx->data + offset, length, cff);
+ offset += nb_read;
+ length -= nb_read;
+ }
+ } else {
+ idx->offsize = 0;
+ idx->offset = NULL;
+ idx->data = NULL;
+ }
+
+ return idx;
+}
+
+int
+cff_pack_index (cff_index *idx, card8 *dest, int destlen)
+{
+ int len = 0;
+ int datalen;
+ card16 i;
+
+ if (idx->count < 1) {
+ if (destlen < 2)
+ ERROR("Not enough space available...");
+ memset(dest, 0, 2);
+ return 2;
+ }
+
+ len = cff_index_size(idx);
+ datalen = idx->offset[idx->count] - 1;
+
+ if (destlen < len)
+ ERROR("Not enough space available...");
+
+ *(dest++) = (idx->count >> 8) & 0xff;
+ *(dest++) = idx->count & 0xff;
+
+ if (datalen < 0xffUL) {
+ idx->offsize = 1;
+ *(dest++) = 1;
+ for (i = 0; i <= idx->count; i++) {
+ *(dest++) = (card8) (idx->offset[i] & 0xff);
+ }
+ } else if (datalen < 0xffffUL) {
+ idx->offsize = 2;
+ *(dest++) = 2;
+ for (i = 0; i <= idx->count; i++) {
+ *(dest++) = (card8) ((idx->offset[i] >> 8) & 0xff);
+ *(dest++) = (card8) ( idx->offset[i] & 0xff);
+ }
+ } else if (datalen < 0xffffffUL) {
+ idx->offsize = 3;
+ *(dest++) = 3;
+ for (i = 0; i <= idx->count; i++) {
+ *(dest++) = (card8)((idx->offset[i] >> 16) & 0xff);
+ *(dest++) = (card8)((idx->offset[i] >> 8) & 0xff);
+ *(dest++) = (card8)(idx->offset[i] & 0xff);
+ }
+ } else {
+ idx->offsize = 4;
+ *(dest++) = 4;
+ for (i = 0; i <= idx->count; i++) {
+ *(dest++) = (card8)((idx->offset[i] >> 24) & 0xff);
+ *(dest++) = (card8)((idx->offset[i] >> 16) & 0xff);
+ *(dest++) = (card8)((idx->offset[i] >> 8) & 0xff);
+ *(dest++) = (card8)(idx->offset[i] & 0xff);
+ }
+ }
+
+ memmove(dest, idx->data, idx->offset[idx->count] - 1);
+
+ return len;
+}
+
+int
+cff_index_size (cff_index *idx)
+{
+ if (idx->count > 0) {
+ l_offset datalen;
+
+ datalen = idx->offset[idx->count] - 1;
+ if (datalen < 0xffUL) {
+ idx->offsize = 1;
+ } else if (datalen < 0xffffUL) {
+ idx->offsize = 2;
+ } else if (datalen < 0xffffffUL) {
+ idx->offsize = 3;
+ } else {
+ idx->offsize = 4;
+ }
+ return (3 + (idx->offsize)*(idx->count + 1) + datalen);
+ } else {
+ return 2;
+ }
+}
+
+
+cff_index *cff_new_index (card16 count)
+{
+ cff_index *idx;
+
+ idx = NEW(1, cff_index);
+ idx->count = count;
+ idx->offsize = 0;
+
+ if (count > 0) {
+ idx->offset = NEW(count + 1, l_offset);
+ (idx->offset)[0] = 1;
+ } else {
+ idx->offset = NULL;
+ }
+ idx->data = NULL;
+
+ return idx;
+}
+
+void cff_release_index (cff_index *idx)
+{
+ if (idx) {
+ if (idx->data) {
+ RELEASE(idx->data);
+ }
+ if (idx->offset) {
+ RELEASE(idx->offset);
+ }
+ RELEASE(idx);
+ }
+}
+
+/* Strings */
+char *cff_get_string (cff_font *cff, s_SID id)
+{
+ char *result = NULL;
+ int len;
+
+ if (id < CFF_STDSTR_MAX) {
+ len = strlen(cff_stdstr[id]);
+ result = NEW(len+1, char);
+ memcpy(result, cff_stdstr[id], len);
+ result[len] = '\0';
+ } else if (cff && cff->string) {
+ cff_index *strings = cff->string;
+ id -= CFF_STDSTR_MAX;
+ if (id < strings->count) {
+ len = (strings->offset)[id+1] - (strings->offset)[id];
+ result = NEW(len + 1, char);
+ memmove(result, strings->data + (strings->offset)[id] - 1, len);
+ result[len] = '\0';
+ }
+ }
+
+ return result;
+}
+
+int cff_get_sid (cff_font *cff, const char *str)
+{
+ card16 i;
+
+ if (!cff || !str)
+ return -1;
+
+ /* I search String INDEX first. */
+ if (cff && cff->string) {
+ cff_index *idx = cff->string;
+ for (i = 0; i < idx->count; i++) {
+ if (strlen(str) == (idx->offset)[i+1] - (idx->offset)[i] &&
+ !memcmp(str, (idx->data)+(idx->offset)[i]-1, strlen(str)))
+ return (i + CFF_STDSTR_MAX);
+ }
+ }
+
+ for (i = 0; i < CFF_STDSTR_MAX; i++) {
+ if (!strcmp(str, cff_stdstr[i]))
+ return i;
+ }
+
+ return -1;
+}
+
+int cff_get_seac_sid (cff_font *cff, const char *str)
+{
+ card16 i;
+
+ if (!cff || !str)
+ return -1;
+
+ for (i = 0; i < CFF_STDSTR_MAX; i++) {
+ if (!strcmp(str, cff_stdstr[i]))
+ return i;
+ }
+
+ return -1;
+}
+
+static int cff_match_string (cff_font *cff, const char *str, s_SID sid)
+{
+ card16 i;
+
+ if (sid < CFF_STDSTR_MAX) {
+ return ((!strcmp(str, cff_stdstr[sid])) ? 1 : 0);
+ } else {
+ i = sid - CFF_STDSTR_MAX;
+ if (cff == NULL || cff->string == NULL || i >= cff->string->count)
+ ERROR("Invalid SID");
+ if (strlen(str) == (cff->string->offset)[i+1] - (cff->string->offset)[i])
+ return (!memcmp(str,
+ (cff->string->data)+(cff->string->offset)[i]-1,
+ strlen(str))) ? 1 : 0;
+ }
+
+ return 0;
+}
+
+void cff_update_string (cff_font *cff)
+{
+ if (cff == NULL)
+ ERROR("CFF font not opened.");
+
+ if (cff->string)
+ cff_release_index(cff->string);
+ cff->string = cff->_string;
+ cff->_string = NULL;
+}
+
+s_SID cff_add_string (cff_font *cff, const char *str, int unique)
+/* Setting unique == 1 eliminates redundant or predefined strings. */
+{
+ card16 idx;
+ cff_index *strings;
+ l_offset offset, size;
+ int len = strlen(str);
+
+ if (cff == NULL)
+ ERROR("CFF font not opened.");
+
+ if (cff->_string == NULL)
+ cff->_string = cff_new_index(0);
+ strings = cff->_string;
+
+ if (unique) {
+ /* TODO: do binary search to speed things up */
+ for (idx = 0; idx < CFF_STDSTR_MAX; idx++) {
+ if (cff_stdstr[idx] && !strcmp(cff_stdstr[idx], str))
+ return idx;
+ }
+ for (idx = 0; idx < strings->count; idx++) {
+ size = strings->offset[idx+1] - strings->offset[idx];
+ offset = strings->offset[idx];
+ if (size == len && !memcmp(strings->data+offset-1, str, len))
+ return (idx + CFF_STDSTR_MAX);
+ }
+ }
+
+ offset = (strings->count > 0) ? strings->offset[strings->count] : 1;
+ strings->offset = RENEW(strings->offset, strings->count+2, l_offset);
+ if (strings->count == 0)
+ strings->offset[0] = 1;
+ idx = strings->count;
+ strings->count += 1;
+ strings->offset[strings->count] = offset + len;
+ strings->data = RENEW(strings->data, offset+len-1, card8);
+ memcpy(strings->data+offset-1, str, len);
+
+ return (idx + CFF_STDSTR_MAX);
+}
+
+/*
+ * Encoding and Charset
+ *
+ * Encoding and Charset arrays always begin with GID = 1.
+ */
+int cff_read_encoding (cff_font *cff)
+{
+ cff_encoding *encoding;
+ int offset, length;
+ card8 i;
+
+ if (cff->topdict == NULL) {
+ ERROR("Top DICT data not found");
+ }
+
+ if (!cff_dict_known(cff->topdict, "Encoding")) {
+ cff->flag |= ENCODING_STANDARD;
+ cff->encoding = NULL;
+ return 0;
+ }
+
+ offset = cff_dict_get(cff->topdict, "Encoding", 0);
+ if (offset == 0) { /* predefined */
+ cff->flag |= ENCODING_STANDARD;
+ cff->encoding = NULL;
+ return 0;
+ } else if (offset == 1) {
+ cff->flag |= ENCODING_EXPERT;
+ cff->encoding = NULL;
+ return 0;
+ }
+
+ cff_seek_set(cff, offset);
+ cff->encoding = encoding = NEW(1, cff_encoding);
+ encoding->format = get_unsigned_byte(cff->stream);
+ length = 1;
+
+ switch (encoding->format & (~0x80)) {
+ case 0:
+ encoding->num_entries = get_unsigned_byte(cff->stream);
+ (encoding->data).codes = NEW(encoding->num_entries, card8);
+ for (i=0;i<(encoding->num_entries);i++) {
+ (encoding->data).codes[i] = get_unsigned_byte(cff->stream);
+ }
+ length += encoding->num_entries + 1;
+ break;
+ case 1:
+ {
+ cff_range1 *ranges;
+ encoding->num_entries = get_unsigned_byte(cff->stream);
+ encoding->data.range1 = ranges
+ = NEW(encoding->num_entries, cff_range1);
+ for (i=0;i<(encoding->num_entries);i++) {
+ ranges[i].first = get_unsigned_byte(cff->stream);
+ ranges[i].n_left = get_unsigned_byte(cff->stream);
+ }
+ length += (encoding->num_entries) * 2 + 1;
+ }
+ break;
+ default:
+ RELEASE(encoding);
+ ERROR("Unknown Encoding format");
+ break;
+ }
+
+ /* Supplementary data */
+ if ((encoding->format) & 0x80) {
+ cff_map *map;
+ encoding->num_supps = get_unsigned_byte(cff->stream);
+ encoding->supp = map = NEW(encoding->num_supps, cff_map);
+ for (i=0;i<(encoding->num_supps);i++) {
+ map[i].code = get_unsigned_byte(cff->stream);
+ map[i].glyph = get_unsigned_pair(cff->stream); /* SID */
+ }
+ length += (encoding->num_supps) * 3 + 1;
+ } else {
+ encoding->num_supps = 0;
+ encoding->supp = NULL;
+ }
+
+ return length;
+}
+
+int cff_pack_encoding (cff_font *cff, card8 *dest, int destlen)
+{
+ int len = 0;
+ cff_encoding *encoding;
+ card16 i;
+
+ if (cff->flag & HAVE_STANDARD_ENCODING || cff->encoding == NULL)
+ return 0;
+
+ if (destlen < 2)
+ ERROR("in cff_pack_encoding(): Buffer overflow");
+
+ encoding = cff->encoding;
+
+ dest[len++] = encoding->format;
+ dest[len++] = encoding->num_entries;
+ switch (encoding->format & (~0x80)) {
+ case 0:
+ if (destlen < len + encoding->num_entries)
+ ERROR("in cff_pack_encoding(): Buffer overflow");
+ for (i=0;i<(encoding->num_entries);i++) {
+ dest[len++] = (encoding->data).codes[i];
+ }
+ break;
+ case 1:
+ {
+ if (destlen < len + (encoding->num_entries)*2)
+ ERROR("in cff_pack_encoding(): Buffer overflow");
+ for (i=0;i<(encoding->num_entries);i++) {
+ dest[len++] = (encoding->data).range1[i].first & 0xff;
+ dest[len++] = (encoding->data).range1[i].n_left;
+ }
+ }
+ break;
+ default:
+ ERROR("Unknown Encoding format");
+ break;
+ }
+
+ if ((encoding->format) & 0x80) {
+ if (destlen < len + (encoding->num_supps)*3 + 1)
+ ERROR("in cff_pack_encoding(): Buffer overflow");
+ dest[len++] = encoding->num_supps;
+ for (i=0;i<(encoding->num_supps);i++) {
+ dest[len++] = (encoding->supp)[i].code;
+ dest[len++] = ((encoding->supp)[i].glyph >> 8) & 0xff;
+ dest[len++] = (encoding->supp)[i].glyph & 0xff;
+ }
+ }
+
+ return len;
+}
+
+/* input: code, output: glyph index */
+card16 cff_encoding_lookup (cff_font *cff, card8 code)
+{
+ card16 gid = 0;
+ cff_encoding *encoding;
+ card16 i;
+
+ if (cff->flag & (ENCODING_STANDARD|ENCODING_EXPERT)) {
+ ERROR("Predefined CFF encoding not supported yet");
+ } else if (cff->encoding == NULL) {
+ ERROR("Encoding data not available");
+ }
+
+ encoding = cff->encoding;
+
+ gid = 0;
+ switch (encoding->format & (~0x80)) {
+ case 0:
+ for (i = 0; i < encoding->num_entries; i++) {
+ if (code == (encoding->data).codes[i]) {
+ gid = i + 1;
+ break;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i < encoding->num_entries; i++) {
+ if (code >= (encoding->data).range1[i].first &&
+ code <= (encoding->data).range1[i].first + (encoding->data).range1[i].n_left) {
+ gid += code - (encoding->data).range1[i].first + 1;
+ break;
+ }
+ gid += (encoding->data).range1[i].n_left + 1;
+ }
+ if (i == encoding->num_entries)
+ gid = 0;
+ break;
+ default:
+ ERROR("Unknown Encoding format.");
+ }
+
+ /* Supplementary data */
+ if (gid == 0 && ((encoding->format) & 0x80)) {
+ cff_map *map;
+ if (!encoding->supp)
+ ERROR("No CFF supplementary encoding data read.");
+ map = encoding->supp;
+ for (i=0;i<(encoding->num_supps);i++) {
+ if (code == map[i].code) {
+ gid = cff_charsets_lookup(cff, map[i].glyph);
+ break;
+ }
+ }
+ }
+
+ return gid;
+}
+
+void cff_release_encoding (cff_encoding *encoding)
+{
+ if (encoding) {
+ switch (encoding->format & (~0x80)) {
+ case 0:
+ if (encoding->data.codes)
+ RELEASE(encoding->data.codes);
+ break;
+ case 1:
+ if (encoding->data.range1)
+ RELEASE(encoding->data.range1);
+ break;
+ default:
+ ERROR("Unknown Encoding format.");
+ }
+ if (encoding->format & 0x80) {
+ if (encoding->supp)
+ RELEASE(encoding->supp);
+ }
+ RELEASE(encoding);
+ }
+}
+
+int cff_read_charsets (cff_font *cff)
+{
+ cff_charsets *charset;
+ int offset, length;
+ card16 count, i;
+
+ if (cff->topdict == NULL)
+ ERROR("Top DICT not available");
+
+ if (!cff_dict_known(cff->topdict, "charset")) {
+ cff->flag |= CHARSETS_ISOADOBE;
+ cff->charsets = NULL;
+ return 0;
+ }
+
+ offset = cff_dict_get(cff->topdict, "charset", 0);
+
+ if (offset == 0) { /* predefined */
+ cff->flag |= CHARSETS_ISOADOBE;
+ cff->charsets = NULL;
+ return 0;
+ } else if (offset == 1) {
+ cff->flag |= CHARSETS_EXPERT;
+ cff->charsets = NULL;
+ return 0;
+ } else if (offset == 2) {
+ cff->flag |= CHARSETS_EXPSUB;
+ cff->charsets = NULL;
+ return 0;
+ }
+
+ cff_seek_set(cff, offset);
+ cff->charsets = charset = NEW(1, cff_charsets);
+ charset->format = get_unsigned_byte(cff->stream);
+ charset->num_entries = 0;
+
+ count = cff->num_glyphs - 1;
+ length = 1;
+
+ /* Not sure. Not well documented. */
+ switch (charset->format) {
+ case 0:
+ charset->num_entries = cff->num_glyphs - 1; /* no .notdef */
+ charset->data.glyphs = NEW(charset->num_entries, s_SID);
+ length += (charset->num_entries) * 2;
+ for (i=0;i<(charset->num_entries);i++) {
+ charset->data.glyphs[i] = get_unsigned_pair(cff->stream);
+ }
+ count = 0;
+ break;
+ case 1:
+ {
+ cff_range1 *ranges = NULL;
+ while (count > 0 && charset->num_entries < cff->num_glyphs) {
+ ranges = RENEW(ranges, charset->num_entries + 1, cff_range1);
+ ranges[charset->num_entries].first = get_unsigned_pair(cff->stream);
+ ranges[charset->num_entries].n_left = get_unsigned_byte(cff->stream);
+ count -= ranges[charset->num_entries].n_left + 1; /* no-overrap */
+ charset->num_entries += 1;
+ charset->data.range1 = ranges;
+ }
+ length += (charset->num_entries) * 3;
+ }
+ break;
+ case 2:
+ {
+ cff_range2 *ranges = NULL;
+ while (count > 0 && charset->num_entries < cff->num_glyphs) {
+ ranges = RENEW(ranges, charset->num_entries + 1, cff_range2);
+ ranges[charset->num_entries].first = get_unsigned_pair(cff->stream);
+ ranges[charset->num_entries].n_left = get_unsigned_pair(cff->stream);
+ count -= ranges[charset->num_entries].n_left + 1; /* non-overrapping */
+ charset->num_entries += 1;
+ }
+ charset->data.range2 = ranges;
+ length += (charset->num_entries) * 4;
+ }
+ break;
+ default:
+ RELEASE(charset);
+ ERROR("Unknown Charset format");
+ break;
+ }
+
+ if (count > 0)
+ ERROR("Charset data possibly broken");
+
+ return length;
+}
+
+int cff_pack_charsets (cff_font *cff, card8 *dest, int destlen)
+{
+ int len = 0;
+ card16 i;
+ cff_charsets *charset;
+
+ if (cff->flag & HAVE_STANDARD_CHARSETS || cff->charsets == NULL)
+ return 0;
+
+ if (destlen < 1)
+ ERROR("in cff_pack_charsets(): Buffer overflow");
+
+ charset = cff->charsets;
+
+ dest[len++] = charset->format;
+ switch (charset->format) {
+ case 0:
+ if (destlen < len + (charset->num_entries)*2)
+ ERROR("in cff_pack_charsets(): Buffer overflow");
+ for (i=0;i<(charset->num_entries);i++) {
+ s_SID sid = (charset->data).glyphs[i]; /* or CID */
+ dest[len++] = (sid >> 8) & 0xff;
+ dest[len++] = sid & 0xff;
+ }
+ break;
+ case 1:
+ {
+ if (destlen < len + (charset->num_entries)*3)
+ ERROR("in cff_pack_charsets(): Buffer overflow");
+ for (i=0;i<(charset->num_entries);i++) {
+ dest[len++] = ((charset->data).range1[i].first >> 8) & 0xff;
+ dest[len++] = (charset->data).range1[i].first & 0xff;
+ dest[len++] = (charset->data).range1[i].n_left;
+ }
+ }
+ break;
+ case 2:
+ {
+ if (destlen < len + (charset->num_entries)*4)
+ ERROR("in cff_pack_charsets(): Buffer overflow");
+ for (i=0;i<(charset->num_entries);i++) {
+ dest[len++] = ((charset->data).range2[i].first >> 8) & 0xff;
+ dest[len++] = (charset->data).range2[i].first & 0xff;
+ dest[len++] = ((charset->data).range2[i].n_left >> 8) & 0xff;
+ dest[len++] = (charset->data).range2[i].n_left & 0xff;
+ }
+ }
+ break;
+ default:
+ ERROR("Unknown Charset format");
+ break;
+ }
+
+ return len;
+}
+
+char* cff_get_glyphname (cff_font *cff, card16 gid)
+{
+ s_SID sid;
+
+ sid = cff_charsets_lookup_inverse(cff, gid);
+ return cff_get_string(cff, sid);
+}
+
+card16 cff_glyph_lookup (cff_font *cff, const char *glyph)
+{
+ card16 gid;
+ cff_charsets *charset;
+ card16 i, n;
+
+ if (cff->flag & (CHARSETS_ISOADOBE|CHARSETS_EXPERT|CHARSETS_EXPSUB)) {
+ ERROR("Predefined CFF charsets not supported yet");
+ } else if (cff->charsets == NULL) {
+ ERROR("Charsets data not available");
+ }
+
+ /* .notdef always have glyph index 0 */
+ if (!glyph || !strcmp(glyph, ".notdef")) {
+ return 0;
+ }
+
+ charset = cff->charsets;
+
+ gid = 0;
+ switch (charset->format) {
+ case 0:
+ for (i = 0; i < charset->num_entries; i++) {
+ gid++;
+ if (cff_match_string(cff, glyph, charset->data.glyphs[i])) {
+ return gid;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i < charset->num_entries; i++) {
+ for (n = 0;
+ n <= charset->data.range1[i].n_left; n++) {
+ gid++;
+ if (cff_match_string(cff, glyph,
+ (s_SID)(charset->data.range1[i].first + n))) {
+ return gid;
+ }
+ }
+ }
+ break;
+ case 2:
+ for (i = 0; i <charset->num_entries; i++) {
+ for (n = 0;
+ n <= charset->data.range2[i].n_left; n++) {
+ gid++;
+ if (cff_match_string(cff, glyph,
+ (s_SID)(charset->data.range2[i].first + n))) {
+ return gid;
+ }
+ }
+ }
+ break;
+ default:
+ ERROR("Unknown Charset format");
+ }
+
+ return 0; /* not found, returns .notdef */
+}
+
+/* Input : SID or CID (16-bit unsigned int)
+ * Output: glyph index
+ */
+card16
+cff_charsets_lookup (cff_font *cff, card16 cid)
+{
+ if (cff->flag & (CHARSETS_ISOADOBE|CHARSETS_EXPERT|CHARSETS_EXPSUB)) {
+ ERROR("Predefined CFF charsets not supported yet");
+ } else if (cff->charsets == NULL) {
+ ERROR("Charsets data not available");
+ }
+
+ return cff_charsets_lookup_gid(cff->charsets, cid);
+}
+
+card16 cff_charsets_lookup_gid (cff_charsets *charset, card16 cid)
+{
+ card16 gid = 0;
+ card16 i;
+
+ if (cid == 0) {
+ return 0; /* GID 0 (.notdef) */
+ }
+
+ switch (charset->format) {
+ case 0:
+ for (i = 0; i <charset->num_entries; i++) {
+ if (cid == charset->data.glyphs[i]) {
+ gid = i + 1;
+ return gid;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i < charset->num_entries; i++) {
+ if (cid >= charset->data.range1[i].first &&
+ cid <= charset->data.range1[i].first + charset->data.range1[i].n_left) {
+ gid += cid - charset->data.range1[i].first + 1;
+ return gid;
+ }
+ gid += charset->data.range1[i].n_left + 1;
+ }
+ break;
+ case 2:
+ for (i = 0; i < charset->num_entries; i++) {
+ if (cid >= charset->data.range2[i].first &&
+ cid <= charset->data.range2[i].first + charset->data.range2[i].n_left) {
+ gid += cid - charset->data.range2[i].first + 1;
+ return gid;
+ }
+ gid += charset->data.range2[i].n_left + 1;
+ }
+ break;
+ default:
+ ERROR("Unknown Charset format");
+ }
+
+ return 0; /* not found */
+}
+
+/* Input : GID
+ * Output: SID/CID (card16)
+ */
+card16
+cff_charsets_lookup_inverse (cff_font *cff, card16 gid)
+{
+ if (cff->flag & (CHARSETS_ISOADOBE|CHARSETS_EXPERT|CHARSETS_EXPSUB)) {
+ ERROR("Predefined CFF charsets not supported yet");
+ } else if (cff->charsets == NULL) {
+ ERROR("Charsets data not available");
+ }
+
+ if (gid == 0) {
+ return 0; /* .notdef */
+ }
+
+ return cff_charsets_lookup_cid(cff->charsets, gid);
+}
+
+card16
+cff_charsets_lookup_cid(cff_charsets *charset, card16 gid)
+{
+ card16 sid = 0;
+ card16 i;
+
+ switch (charset->format) {
+ case 0:
+ if (gid - 1 >= charset->num_entries)
+ ERROR("Invalid GID.");
+ sid = charset->data.glyphs[gid - 1];
+ break;
+ case 1:
+ for (i = 0; i < charset->num_entries; i++) {
+ if (gid <= charset->data.range1[i].n_left + 1) {
+ sid = gid + charset->data.range1[i].first - 1;
+ break;
+ }
+ gid -= charset->data.range1[i].n_left + 1;
+ }
+ if (i == charset->num_entries)
+ ERROR("Invalid GID");
+ break;
+ case 2:
+ for (i = 0; i < charset->num_entries; i++) {
+ if (gid <= charset->data.range2[i].n_left + 1) {
+ sid = gid + charset->data.range2[i].first - 1;
+ break;
+ }
+ gid -= charset->data.range2[i].n_left + 1;
+ }
+ if (i == charset->num_entries)
+ ERROR("Invalid GID");
+ break;
+ default:
+ ERROR("Unknown Charset format");
+ }
+
+ return sid;
+}
+
+void
+cff_release_charsets (cff_charsets *charset)
+{
+ if (charset) {
+ switch (charset->format) {
+ case 0:
+ if (charset->data.glyphs)
+ RELEASE(charset->data.glyphs);
+ break;
+ case 1:
+ if (charset->data.range1)
+ RELEASE(charset->data.range1);
+ break;
+ case 2:
+ if (charset->data.range2)
+ RELEASE(charset->data.range2);
+ break;
+ default:
+ break;
+ }
+ RELEASE(charset);
+ }
+}
+
+/* CID-Keyed font specific */
+int cff_read_fdselect (cff_font *cff)
+{
+ cff_fdselect *fdsel;
+ int offset, length;
+ card16 i;
+
+ if (cff->topdict == NULL)
+ ERROR("Top DICT not available");
+
+ if (!(cff->flag & FONTTYPE_CIDFONT))
+ return 0;
+
+ offset = cff_dict_get(cff->topdict, "FDSelect", 0);
+ cff_seek_set(cff, offset);
+ cff->fdselect = fdsel = NEW(1, cff_fdselect);
+ fdsel->format = get_unsigned_byte(cff->stream);
+
+ length = 1;
+
+ switch (fdsel->format) {
+ case 0:
+ fdsel->num_entries = cff->num_glyphs;
+ (fdsel->data).fds = NEW(fdsel->num_entries, card8);
+ for (i=0;i<(fdsel->num_entries);i++) {
+ (fdsel->data).fds[i] = get_unsigned_byte(cff->stream);
+ }
+ length += fdsel->num_entries;
+ break;
+ case 3:
+ {
+ cff_range3 *ranges;
+ fdsel->num_entries = get_unsigned_pair(cff->stream);
+ fdsel->data.ranges = ranges = NEW(fdsel->num_entries, cff_range3);
+ for (i=0;i<(fdsel->num_entries);i++) {
+ ranges[i].first = get_unsigned_pair(cff->stream);
+ ranges[i].fd = get_unsigned_byte(cff->stream);
+ }
+ if (ranges[0].first != 0)
+ ERROR("Range not starting with 0.");
+ if (cff->num_glyphs != get_unsigned_pair(cff->stream))
+ ERROR("Sentinel value mismatched with number of glyphs.");
+ length += (fdsel->num_entries) * 3 + 4;
+ }
+ break;
+ default:
+ RELEASE(fdsel);
+ ERROR("Unknown FDSelect format.");
+ break;
+ }
+
+ return length;
+}
+
+int cff_pack_fdselect (cff_font *cff, card8 *dest, int destlen)
+{
+ cff_fdselect *fdsel;
+ int len = 0;
+ card16 i;
+
+ if (cff->fdselect == NULL)
+ return 0;
+
+ if (destlen < 1)
+ ERROR("in cff_pack_fdselect(): Buffur overflow");
+
+ fdsel = cff->fdselect;
+
+ dest[len++] = fdsel->format;
+ switch (fdsel->format) {
+ case 0:
+ if (fdsel->num_entries != cff->num_glyphs)
+ ERROR("in cff_pack_fdselect(): Invalid data");
+ if (destlen < len + fdsel->num_entries)
+ ERROR("in cff_pack_fdselect(): Buffer overflow");
+ for (i=0;i<fdsel->num_entries;i++) {
+ dest[len++] = (fdsel->data).fds[i];
+ }
+ break;
+ case 3:
+ {
+ if (destlen < len + 2)
+ ERROR("in cff_pack_fdselect(): Buffer overflow");
+ len += 2;
+ for (i=0;i<(fdsel->num_entries);i++) {
+ if (destlen < len + 3)
+ ERROR("in cff_pack_fdselect(): Buffer overflow");
+ dest[len++] = ((fdsel->data).ranges[i].first >> 8) & 0xff;
+ dest[len++] = (fdsel->data).ranges[i].first & 0xff;
+ dest[len++] = (fdsel->data).ranges[i].fd;
+ }
+ if (destlen < len + 2)
+ ERROR("in cff_pack_fdselect(): Buffer overflow");
+ dest[len++] = (cff->num_glyphs >> 8) & 0xff;
+ dest[len++] = cff->num_glyphs & 0xff;
+ dest[1] = ((len/3 - 1) >> 8) & 0xff;
+ dest[2] = (len/3 - 1) & 0xff;
+ }
+ break;
+ default:
+ ERROR("Unknown FDSelect format.");
+ break;
+ }
+
+ return len;
+}
+
+void cff_release_fdselect (cff_fdselect *fdselect)
+{
+ if (fdselect) {
+ if (fdselect->format == 0) {
+ if (fdselect->data.fds) RELEASE(fdselect->data.fds);
+ } else if (fdselect->format == 3) {
+ if (fdselect->data.ranges) RELEASE(fdselect->data.ranges);
+ }
+ RELEASE(fdselect);
+ }
+}
+
+card8 cff_fdselect_lookup (cff_font *cff, card16 gid)
+{
+ card8 fd = 0xff;
+ cff_fdselect *fdsel;
+
+ if (cff->fdselect == NULL)
+ ERROR("in cff_fdselect_lookup(): FDSelect not available");
+
+ fdsel = cff->fdselect;
+
+ if (gid >= cff->num_glyphs)
+ ERROR("in cff_fdselect_lookup(): Invalid glyph index");
+
+ switch (fdsel->format) {
+ case 0:
+ fd = fdsel->data.fds[gid];
+ break;
+ case 3:
+ {
+ if (gid == 0) {
+ fd = (fdsel->data).ranges[0].fd;
+ } else {
+ card16 i;
+ for (i=1;i<(fdsel->num_entries);i++) {
+ if (gid < (fdsel->data).ranges[i].first)
+ break;
+ }
+ fd = (fdsel->data).ranges[i-1].fd;
+ }
+ }
+ break;
+ default:
+ ERROR("in cff_fdselect_lookup(): Invalid FDSelect format");
+ break;
+ }
+
+ if (fd >= cff->num_fds)
+ ERROR("in cff_fdselect_lookup(): Invalid Font DICT index");
+
+ return fd;
+}
+
+int cff_read_subrs (cff_font *cff)
+{
+ int len = 0;
+ int offset;
+ int i;
+
+ if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdarray == NULL) {
+ cff_read_fdarray(cff);
+ }
+
+ if (cff->private == NULL)
+ cff_read_private(cff);
+
+ if (cff->gsubr == NULL) {
+ cff_seek_set(cff, cff->gsubr_offset);
+ cff->gsubr = cff_get_index(cff);
+ }
+
+ cff->subrs = NEW(cff->num_fds, cff_index *);
+ if (cff->flag & FONTTYPE_CIDFONT) {
+ for (i=0;i<cff->num_fds;i++) {
+ if (cff->private[i] == NULL ||
+ !cff_dict_known(cff->private[i], "Subrs")) {
+ (cff->subrs)[i] = NULL;
+ } else {
+ offset = cff_dict_get(cff->fdarray[i], "Private", 1);
+ offset += cff_dict_get(cff->private[i], "Subrs", 0);
+ cff_seek_set(cff, offset);
+ (cff->subrs)[i] = cff_get_index(cff);
+ len += cff_index_size((cff->subrs)[i]);
+ }
+ }
+ } else {
+ if (cff->private[0] == NULL ||
+ !cff_dict_known(cff->private[0], "Subrs")) {
+ (cff->subrs)[0] = NULL;
+ } else {
+ offset = cff_dict_get(cff->topdict, "Private", 1);
+ offset += cff_dict_get(cff->private[0], "Subrs", 0);
+ cff_seek_set(cff, offset);
+ (cff->subrs)[0] = cff_get_index(cff);
+ len += cff_index_size((cff->subrs)[0]);
+ }
+ }
+
+ return len;
+}
+
+int cff_read_fdarray (cff_font *cff)
+{
+ int len = 0;
+ cff_index *idx;
+ int offset, size;
+ card16 i;
+
+ if (cff->topdict == NULL)
+ ERROR("in cff_read_fdarray(): Top DICT not found");
+
+ if (!(cff->flag & FONTTYPE_CIDFONT))
+ return 0;
+
+ /* must exist */
+ offset = cff_dict_get(cff->topdict, "FDArray", 0);
+ cff_seek_set(cff, offset);
+ idx = cff_get_index(cff);
+ cff->num_fds = (card8)idx->count;
+ cff->fdarray = NEW(idx->count, cff_dict *);
+ for (i=0;i<idx->count;i++) {
+ card8 *data = idx->data + (idx->offset)[i] - 1;
+ size = (idx->offset)[i+1] - (idx->offset)[i];
+ if (size > 0) {
+ (cff->fdarray)[i] = cff_dict_unpack(data, data+size);
+ } else {
+ (cff->fdarray)[i] = NULL;
+ }
+ }
+ len = cff_index_size(idx);
+ cff_release_index(idx);
+
+ return len;
+}
+
+int cff_read_private (cff_font *cff)
+{
+ int len = 0;
+ card8 *data;
+ int offset, size;
+
+ if (cff->flag & FONTTYPE_CIDFONT) {
+ int i;
+
+ if (cff->fdarray == NULL)
+ cff_read_fdarray(cff);
+
+ cff->private = NEW(cff->num_fds, cff_dict *);
+ for (i=0;i<cff->num_fds;i++) {
+ if (cff->fdarray[i] != NULL &&
+ cff_dict_known(cff->fdarray[i], "Private") &&
+ (size = cff_dict_get(cff->fdarray[i], "Private", 0))
+ > 0) {
+ offset = cff_dict_get(cff->fdarray[i], "Private", 1);
+ cff_seek_set(cff, offset);
+ data = NEW(size, card8);
+ if (cff_read_data(data, size, cff) != size)
+ ERROR("reading file failed");
+ (cff->private)[i] = cff_dict_unpack(data, data+size);
+ RELEASE(data);
+ len += size;
+ } else {
+ (cff->private)[i] = NULL;
+ }
+ }
+ } else {
+ cff->num_fds = 1;
+ cff->private = NEW(1, cff_dict *);
+ if (cff_dict_known(cff->topdict, "Private") &&
+ (size = cff_dict_get(cff->topdict, "Private", 0)) > 0) {
+ offset = cff_dict_get(cff->topdict, "Private", 1);
+ cff_seek_set(cff, offset);
+ data = NEW(size, card8);
+ if (cff_read_data(data, size, cff) != size)
+ ERROR("reading file failed");
+ cff->private[0] = cff_dict_unpack(data, data+size);
+ RELEASE(data);
+ len += size;
+ } else {
+ (cff->private)[0] = NULL;
+ len = 0;
+ }
+ }
+
+ return len;
+}
diff --git a/Build/source/texk/dvipdfm-x/cff.h b/Build/source/texk/dvipdfm-x/cff.h
new file mode 100644
index 00000000000..4174186206e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cff.h
@@ -0,0 +1,150 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CFF_H_
+#define _CFF_H_
+
+#include "mfileio.h"
+#include "cff_types.h"
+
+/* Flag */
+#define FONTTYPE_CIDFONT (1 << 0)
+#define FONTTYPE_FONT (1 << 1)
+#define FONTTYPE_MMASTER (1 << 2)
+
+#define ENCODING_STANDARD (1 << 3)
+#define ENCODING_EXPERT (1 << 4)
+
+#define CHARSETS_ISOADOBE (1 << 5)
+#define CHARSETS_EXPERT (1 << 6)
+#define CHARSETS_EXPSUB (1 << 7)
+
+#define HAVE_STANDARD_ENCODING (ENCODING_STANDARD|ENCODING_EXPERT)
+#define HAVE_STANDARD_CHARSETS \
+ (CHARSETS_ISOADOBE|CHARSETS_EXPERT|CHARSETS_EXPSUB)
+
+#define CFF_STRING_NOTDEF 65535
+
+typedef struct
+{
+ char *fontname; /* FontName */
+
+ /* - CFF structure - */
+ cff_header header; /* CFF Header */
+ cff_index *name; /* Name INDEX */
+ cff_dict *topdict; /* Top DICT (single) */
+ cff_index *string; /* String INDEX */
+ cff_index *gsubr; /* Global Subr INDEX */
+ cff_encoding *encoding; /* Encodings */
+ cff_charsets *charsets; /* Charsets */
+ cff_fdselect *fdselect; /* FDSelect, CIDFont only */
+ cff_index *cstrings; /* CharStrings */
+ cff_dict **fdarray; /* CIDFont only */
+ cff_dict **private; /* per-Font DICT */
+ cff_index **subrs; /* Local Subr INDEX, per-Private DICT */
+
+ /* -- extra data -- */
+ l_offset offset; /* non-zero for OpenType or PostScript wrapped */
+ l_offset gsubr_offset;
+ card16 num_glyphs; /* number of glyphs (CharString INDEX count) */
+ card8 num_fds; /* number of Font DICT */
+
+ /* Updated String INDEX.
+ * Please fix this. We should separate input and output.
+ */
+ cff_index *_string;
+
+ FILE *stream;
+
+ int filter; /* not used, ASCII Hex filter if needed */
+
+ int index; /* CFF fontset index */
+ int flag; /* Flag: see above */
+ int is_notdef_notzero; /* 1 if .notdef is not the 1st glyph */
+} cff_font;
+
+extern cff_font *cff_open (FILE *file, int offset, int idx);
+#define cff_seek_set(c, p) seek_absolute (((c)->stream), ((c)->offset) + (p));
+#define cff_read_data(d, l, c) fread(d, 1, l, (c)->stream)
+#define cff_tell(c) ftell((c)->stream)
+#define cff_seek(c, p) seek_absolute((c)->stream, p)
+
+extern void cff_close (cff_font *cff);
+
+/* CFF Header */
+extern int cff_put_header (cff_font *cff, card8 *dest, int destlen);
+
+/* CFF INDEX */
+extern cff_index *cff_get_index (cff_font *cff);
+extern cff_index *cff_get_index_header (cff_font *cff);
+extern void cff_release_index (cff_index *idx);
+extern cff_index *cff_new_index (card16 count);
+extern int cff_index_size (cff_index *idx);
+extern int cff_pack_index (cff_index *idx, card8 *dest, int destlen);
+
+/* Name INDEX */
+extern char *cff_get_name (cff_font *cff);
+extern int cff_set_name (cff_font *cff, char *name);
+
+/* Global and Local Subrs INDEX */
+extern int cff_read_subrs (cff_font *cff);
+
+/* Encoding */
+extern int cff_read_encoding (cff_font *cff);
+extern int cff_pack_encoding (cff_font *cff, card8 *dest, int destlen);
+extern card16 cff_encoding_lookup (cff_font *cff, card8 code);
+extern void cff_release_encoding (cff_encoding *encoding);
+
+/* Charsets */
+extern int cff_read_charsets (cff_font *cff);
+extern int cff_pack_charsets (cff_font *cff, card8 *dest, int destlen);
+
+/* Returns GID of PS name "glyph" */
+extern card16 cff_glyph_lookup (cff_font *cff, const char *glyph);
+/* Return PS name of "gid" */
+extern char* cff_get_glyphname (cff_font *cff, card16 gid);
+/* Returns GID of glyph with SID/CID "cid" */
+extern card16 cff_charsets_lookup (cff_font *cff, card16 cid);
+extern card16 cff_charsets_lookup_gid (cff_charsets *charset, card16 cid);
+extern void cff_release_charsets (cff_charsets *charset);
+/* Returns SID or CID */
+extern card16 cff_charsets_lookup_inverse (cff_font *cff, card16 gid);
+extern card16 cff_charsets_lookup_cid(cff_charsets *charset, card16 gid);
+
+/* FDSelect */
+extern int cff_read_fdselect (cff_font *cff);
+extern int cff_pack_fdselect (cff_font *cff, card8 *dest, int destlen);
+extern card8 cff_fdselect_lookup (cff_font *cff, card16 gid);
+extern void cff_release_fdselect (cff_fdselect *fdselect);
+
+/* Font DICT(s) */
+extern int cff_read_fdarray (cff_font *cff);
+
+/* Private DICT(s) */
+extern int cff_read_private (cff_font *cff);
+
+/* String */
+extern char *cff_get_string (cff_font *cff, s_SID id);
+extern int cff_get_sid (cff_font *cff, const char *str);
+extern int cff_get_seac_sid (cff_font *cff, const char *str);
+extern s_SID cff_add_string (cff_font *cff, const char *str, int unique);
+extern void cff_update_string (cff_font *cff);
+
+#endif /* _CFF_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cff_dict.c b/Build/source/texk/dvipdfm-x/cff_dict.c
new file mode 100644
index 00000000000..35035009824
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cff_dict.c
@@ -0,0 +1,724 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * CFF Font Dictionary
+ *
+ * Adobe Technical Note #5176 "The Compact Font Format Specification"
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "error.h"
+#include "mem.h"
+
+#ifndef CFF_DEBUG_STR
+#define CFF_DEBUG_STR "CFF"
+#define CFF_DEBUG 5
+#endif
+
+/* work_buffer for get_real() */
+#include "mfileio.h"
+
+#include "cff_types.h"
+#include "cff_limits.h"
+
+/* #include "cff_string.h" */
+#include "cff_dict.h"
+/* cff_update_dict requires this. */
+#include "cff.h"
+
+#define CFF_PARSE_OK 0
+#define CFF_ERROR_PARSE_ERROR -1
+#define CFF_ERROR_STACK_OVERFLOW -2
+#define CFF_ERROR_STACK_UNDERFLOW -3
+#define CFF_ERROR_STACK_RANGECHECK -4
+
+#define DICT_ENTRY_MAX 16
+cff_dict *cff_new_dict (void)
+{
+ cff_dict *dict;
+
+ dict = NEW(1, cff_dict);
+ dict->max = DICT_ENTRY_MAX;
+ dict->count = 0;
+ dict->entries = NEW(dict->max, cff_dict_entry);
+
+ return dict;
+}
+
+void cff_release_dict (cff_dict *dict)
+{
+ if (dict) {
+ if (dict->entries) {
+ int i;
+ for (i=0;i<dict->count;i++) {
+ if ((dict->entries)[i].values)
+ RELEASE((dict->entries)[i].values);
+ }
+ RELEASE(dict->entries);
+ }
+ RELEASE(dict);
+ }
+}
+
+/*
+ * Operand stack:
+ * only numbers are stored (as double)
+ *
+ * Operand types:
+ *
+ * number : double (integer or real)
+ * boolean: stored as a number
+ * SID : stored as a number
+ * array : array of numbers
+ * delta : array of numbers
+ */
+
+#define CFF_DICT_STACK_LIMIT 64
+static int stack_top = 0;
+static double arg_stack[CFF_DICT_STACK_LIMIT];
+
+/*
+ * CFF DICT encoding:
+ * TODO: default values
+ */
+
+#define CFF_LAST_DICT_OP1 22
+#define CFF_LAST_DICT_OP2 39
+#define CFF_LAST_DICT_OP (CFF_LAST_DICT_OP1 + CFF_LAST_DICT_OP2)
+
+static struct {
+ const char *opname;
+ int argtype;
+} dict_operator[CFF_LAST_DICT_OP] = {
+ {"version", CFF_TYPE_SID},
+ {"Notice", CFF_TYPE_SID},
+ {"FullName", CFF_TYPE_SID},
+ {"FamilyName", CFF_TYPE_SID},
+ {"Weight", CFF_TYPE_SID},
+ {"FontBBox", CFF_TYPE_ARRAY},
+ {"BlueValues", CFF_TYPE_DELTA},
+ {"OtherBlues", CFF_TYPE_DELTA},
+ {"FamilyBlues", CFF_TYPE_DELTA},
+ {"FamilyOtherBlues", CFF_TYPE_DELTA},
+ {"StdHW", CFF_TYPE_NUMBER},
+ {"StdVW", CFF_TYPE_NUMBER},
+ {NULL, -1}, /* first byte of two-byte operator */
+ /* Top */
+ {"UniqueID", CFF_TYPE_NUMBER},
+ {"XUID", CFF_TYPE_ARRAY},
+ {"charset", CFF_TYPE_OFFSET},
+ {"Encoding", CFF_TYPE_OFFSET},
+ {"CharStrings", CFF_TYPE_OFFSET},
+ {"Private", CFF_TYPE_SZOFF}, /* two numbers (size and offset) */
+ /* Private */
+ {"Subrs", CFF_TYPE_OFFSET},
+ {"defaultWidthX", CFF_TYPE_NUMBER},
+ {"nominalWidthX", CFF_TYPE_NUMBER},
+ /* Operator 2 */
+ {"Copyright", CFF_TYPE_SID},
+ {"IsFixedPitch", CFF_TYPE_BOOLEAN},
+ {"ItalicAngle", CFF_TYPE_NUMBER},
+ {"UnderlinePosition", CFF_TYPE_NUMBER},
+ {"UnderlineThickness", CFF_TYPE_NUMBER},
+ {"PaintType", CFF_TYPE_NUMBER},
+ {"CharstringType", CFF_TYPE_NUMBER},
+ {"FontMatrix", CFF_TYPE_ARRAY},
+ {"StrokeWidth", CFF_TYPE_NUMBER},
+ {"BlueScale", CFF_TYPE_NUMBER},
+ {"BlueShift", CFF_TYPE_NUMBER},
+ {"BlueFuzz", CFF_TYPE_NUMBER},
+ {"StemSnapH", CFF_TYPE_DELTA},
+ {"StemSnapV", CFF_TYPE_DELTA},
+ {"ForceBold", CFF_TYPE_BOOLEAN},
+ {NULL, -1},
+ {NULL, -1},
+ {"LanguageGroup", CFF_TYPE_NUMBER},
+ {"ExpansionFactor", CFF_TYPE_NUMBER},
+ {"InitialRandomSeed", CFF_TYPE_NUMBER},
+ {"SyntheticBase", CFF_TYPE_NUMBER},
+ {"PostScript", CFF_TYPE_SID},
+ {"BaseFontName", CFF_TYPE_SID},
+ {"BaseFontBlend", CFF_TYPE_DELTA}, /* MMaster ? */
+ {NULL, -1},
+ {NULL, -1},
+ {NULL, -1},
+ {NULL, -1},
+ {NULL, -1},
+ {NULL, -1},
+ /* CID-Keyed font */
+ {"ROS", CFF_TYPE_ROS}, /* SID SID number */
+ {"CIDFontVersion", CFF_TYPE_NUMBER},
+ {"CIDFontRevision", CFF_TYPE_NUMBER},
+ {"CIDFontType", CFF_TYPE_NUMBER},
+ {"CIDCount", CFF_TYPE_NUMBER},
+ {"UIDBase", CFF_TYPE_NUMBER},
+ {"FDArray", CFF_TYPE_OFFSET},
+ {"FDSelect", CFF_TYPE_OFFSET},
+ {"FontName", CFF_TYPE_SID},
+};
+
+/* Parse DICT data */
+static double get_integer (card8 **data, card8 *endptr, int *status)
+{
+ int result = 0;
+ card8 b0, b1, b2;
+
+ b0 = *(*data)++;
+ if (b0 == 28 && *data < endptr - 2) { /* shortint */
+ b1 = *(*data)++;
+ b2 = *(*data)++;
+ result = b1*256+b2;
+ if (result > 0x7fffL)
+ result -= 0x10000L;
+ } else if (b0 == 29 && *data < endptr - 4) { /* longint */
+ int i;
+ result = *(*data)++;
+ if (result > 0x7f)
+ result -= 0x100;
+ for (i=0;i<3;i++) {
+ result = result*256+(**data);
+ *data += 1;
+ }
+ } else if (b0 >= 32 && b0 <= 246) { /* int (1) */
+ result = b0 - 139;
+ } else if (b0 >= 247 && b0 <= 250) { /* int (2) */
+ b1 = *(*data)++;
+ result = (b0-247)*256+b1+108;
+ } else if (b0 >= 251 && b0 <= 254) {
+ b1 = *(*data)++;
+ result = -(b0-251)*256-b1-108;
+ } else {
+ *status = CFF_ERROR_PARSE_ERROR;
+ }
+
+ return (double) result;
+}
+
+/* Simply uses strtod */
+static double get_real(card8 **data, card8 *endptr, int *status)
+{
+ double result = 0.0;
+ int nibble = 0, pos = 0;
+ int len = 0, fail = 0;
+
+ if (**data != 30 || *data >= endptr -1) {
+ *status = CFF_ERROR_PARSE_ERROR;
+ return 0.0;
+ }
+
+ *data += 1; /* skip first byte (30) */
+
+ pos = 0;
+ while ((! fail) && len < WORK_BUFFER_SIZE - 2 && *data < endptr) {
+ /* get nibble */
+ if (pos % 2) {
+ nibble = **data & 0x0f;
+ *data += 1;
+ } else {
+ nibble = (**data >> 4) & 0x0f;
+ }
+ if (nibble >= 0x00 && nibble <= 0x09) {
+ work_buffer[len++] = nibble + '0';
+ } else if (nibble == 0x0a) { /* . */
+ work_buffer[len++] = '.';
+ } else if (nibble == 0x0b || nibble == 0x0c) { /* E, E- */
+ work_buffer[len++] = 'e';
+ if (nibble == 0x0c)
+ work_buffer[len++] = '-';
+ } else if (nibble == 0x0e) { /* `-' */
+ work_buffer[len++] = '-';
+ } else if (nibble == 0x0d) { /* skip */
+ /* do nothing */
+ } else if (nibble == 0x0f) { /* end */
+ work_buffer[len++] = '\0';
+ if (((pos % 2) == 0) && (**data != 0xff)) {
+ fail = 1;
+ }
+ break;
+ } else { /* invalid */
+ fail = 1;
+ }
+ pos++;
+ }
+
+ /* returned values */
+ if (fail || nibble != 0x0f) {
+ *status = CFF_ERROR_PARSE_ERROR;
+ } else {
+ char *s;
+ result = strtod(work_buffer, &s);
+ if (*s != 0 || errno == ERANGE) {
+ *status = CFF_ERROR_PARSE_ERROR;
+ }
+ }
+
+ return result;
+}
+
+/* operators */
+static void add_dict (cff_dict *dict,
+ card8 **data, card8 *endptr, int *status)
+{
+ int id, argtype;
+
+ id = **data;
+ if (id == 0x0c) {
+ *data += 1;
+ if (*data >= endptr ||
+ (id = **data + CFF_LAST_DICT_OP1) >= CFF_LAST_DICT_OP) {
+ *status = CFF_ERROR_PARSE_ERROR;
+ return;
+ }
+ } else if (id >= CFF_LAST_DICT_OP1) {
+ *status = CFF_ERROR_PARSE_ERROR;
+ return;
+ }
+
+ argtype = dict_operator[id].argtype;
+ if (dict_operator[id].opname == NULL || argtype < 0) {
+ /* YuppySC-Regular.otf from OS X for instance uses op id 37, simply ignore
+ this dict instead of treat it as parsing error. */
+ return;
+ }
+
+ if (dict->count >= dict->max) {
+ dict->max += DICT_ENTRY_MAX;
+ dict->entries = RENEW(dict->entries, dict->max, cff_dict_entry);
+ }
+
+ (dict->entries)[dict->count].id = id;
+ (dict->entries)[dict->count].key = dict_operator[id].opname;
+ if (argtype == CFF_TYPE_NUMBER ||
+ argtype == CFF_TYPE_BOOLEAN ||
+ argtype == CFF_TYPE_SID ||
+ argtype == CFF_TYPE_OFFSET) {
+ /* check for underflow here, as exactly one operand is expected */
+ if (stack_top < 1) {
+ *status = CFF_ERROR_STACK_UNDERFLOW;
+ return;
+ }
+ stack_top--;
+ (dict->entries)[dict->count].count = 1;
+ (dict->entries)[dict->count].values = NEW(1, double);
+ (dict->entries)[dict->count].values[0] = arg_stack[stack_top];
+ dict->count += 1;
+ } else {
+ /* just ignore operator if there were no operands provided;
+ don't treat this as underflow (e.g. StemSnapV in TemporaLGCUni-Italic.otf) */
+ if (stack_top > 0)
+ {
+ (dict->entries)[dict->count].count = stack_top;
+ (dict->entries)[dict->count].values = NEW(stack_top, double);
+ while (stack_top > 0) {
+ stack_top--;
+ (dict->entries)[dict->count].values[stack_top] = arg_stack[stack_top];
+ }
+ dict->count += 1;
+ }
+ }
+
+ *data += 1;
+
+ return;
+}
+
+/*
+ * All operands are treated as number or array of numbers.
+ * Private: two numbers, size and offset
+ * ROS : three numbers, SID, SID, and a number
+ */
+cff_dict *cff_dict_unpack (card8 *data, card8 *endptr)
+{
+ cff_dict *dict;
+ int status = CFF_PARSE_OK;
+
+ stack_top = 0;
+
+ dict = cff_new_dict();
+ while (data < endptr && status == CFF_PARSE_OK) {
+ if (*data < 22) { /* operator */
+ add_dict(dict, &data, endptr, &status);
+ } else if (*data == 30) { /* real - First byte of a sequence (variable) */
+ if (stack_top < CFF_DICT_STACK_LIMIT) {
+ arg_stack[stack_top] = get_real(&data, endptr, &status);
+ stack_top++;
+ } else {
+ status = CFF_ERROR_STACK_OVERFLOW;
+ }
+ } else if (*data == 255 || (*data >= 22 && *data <= 27)) { /* reserved */
+ data++;
+ } else { /* everything else are integer */
+ if (stack_top < CFF_DICT_STACK_LIMIT) {
+ arg_stack[stack_top] = get_integer(&data, endptr, &status);
+ stack_top++;
+ } else {
+ status = CFF_ERROR_STACK_OVERFLOW;
+ }
+ }
+ }
+
+ if (status != CFF_PARSE_OK) {
+ ERROR("%s: Parsing CFF DICT failed. (error=%d)", CFF_DEBUG_STR, status);
+ } else if (stack_top != 0) {
+ WARN("%s: Garbage in CFF DICT data.", CFF_DEBUG_STR);
+ stack_top = 0;
+ }
+
+ return dict;
+}
+
+/* Pack DICT data */
+static int pack_integer (card8 *dest, int destlen, int value)
+{
+ int len = 0;
+
+ if (value >= -107 && value <= 107) {
+ if (destlen < 1)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ dest[0] = (value + 139) & 0xff;
+ len = 1;
+ } else if (value >= 108 && value <= 1131) {
+ if (destlen < 2)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ value = 0xf700u + value - 108;
+ dest[0] = (value >> 8) & 0xff;
+ dest[1] = value & 0xff;
+ len = 2;
+ } else if (value >= -1131 && value <= -108) {
+ if (destlen < 2)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ value = 0xfb00u - value - 108;
+ dest[0] = (value >> 8) & 0xff;
+ dest[1] = value & 0xff;
+ len = 2;
+ } else if (value >= -32768 && value <= 32767) { /* shortint */
+ if (destlen < 3)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ dest[0] = 28;
+ dest[1] = (value >> 8) & 0xff;
+ dest[2] = value & 0xff;
+ len = 3;
+ } else { /* longint */
+ if (destlen < 5)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ dest[0] = 29;
+ dest[1] = (value >> 24) & 0xff;
+ dest[2] = (value >> 16) & 0xff;
+ dest[3] = (value >> 8) & 0xff;
+ dest[4] = value & 0xff;
+ len = 5;
+ }
+
+ return len;
+}
+
+static int pack_real (card8 *dest, int destlen, double value)
+{
+ int i = 0, pos = 2;
+ char buffer[32];
+
+ if (destlen < 2)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+
+ dest[0] = 30;
+
+ if (value == 0.0) {
+ dest[1] = 0x0f;
+ return 2;
+ }
+
+ if (value < 0.0) {
+ dest[1] = 0xe0;
+ value *= -1.0;
+ pos++;
+ }
+
+ /* To avoid the problem with Mac OS X 10.4 Quartz,
+ * change the presion of the real numbers
+ * on June 27, 2007 for musix20.pfb */
+ sprintf(buffer, "%.13g", value);
+
+ for (i = 0; buffer[i] != '\0'; i++) {
+ unsigned char ch = 0;
+ if (buffer[i] == '.') {
+ ch = 0x0a;
+ } else if (buffer[i] >= '0' && buffer[i] <= '9') {
+ ch = buffer[i] - '0';
+ } else if (buffer[i] == 'e') {
+ ch = (buffer[++i] == '-' ? 0x0c : 0x0b);
+ } else {
+ ERROR("%s: Invalid character.", CFF_DEBUG_STR);
+ }
+
+ if (destlen < pos/2 + 1)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+
+ if (pos % 2) {
+ dest[pos/2] += ch;
+ } else {
+ dest[pos/2] = (ch << 4);
+ }
+ pos++;
+ }
+
+ if (pos % 2) {
+ dest[pos/2] += 0x0f;
+ pos++;
+ } else {
+ if (destlen < pos/2 + 1)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ dest[pos/2] = 0xff;
+ pos += 2;
+ }
+
+ return pos/2;
+}
+
+static int cff_dict_put_number (double value,
+ card8 *dest, int destlen,
+ int type)
+{
+ int len = 0;
+ double nearint;
+
+ nearint = floor(value+0.5);
+ /* set offset to longint */
+ if (type == CFF_TYPE_OFFSET) {
+ int lvalue;
+
+ lvalue = (int) value;
+ if (destlen < 5)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ dest[0] = 29;
+ dest[1] = (lvalue >> 24) & 0xff;
+ dest[2] = (lvalue >> 16) & 0xff;
+ dest[3] = (lvalue >> 8) & 0xff;
+ dest[4] = lvalue & 0xff;
+ len = 5;
+ } else if (value > CFF_INT_MAX || value < CFF_INT_MIN ||
+ (fabs(value - nearint) > 1.0e-5)) { /* real */
+ len = pack_real(dest, destlen, value);
+ } else { /* integer */
+ len = pack_integer(dest, destlen, (int) nearint);
+ }
+
+ return len;
+}
+
+static int
+put_dict_entry (cff_dict_entry *de,
+ card8 *dest, int destlen)
+{
+ int len = 0;
+ int i, type, id;
+
+ if (de->count > 0) {
+ id = de->id;
+ if (dict_operator[id].argtype == CFF_TYPE_OFFSET ||
+ dict_operator[id].argtype == CFF_TYPE_SZOFF) {
+ type = CFF_TYPE_OFFSET;
+ } else {
+ type = CFF_TYPE_NUMBER;
+ }
+ for (i = 0; i < de->count; i++) {
+ len += cff_dict_put_number(de->values[i],
+ dest+len,
+ destlen-len, type);
+ }
+ if (id >= 0 && id < CFF_LAST_DICT_OP1) {
+ if (len + 1 > destlen)
+ ERROR("%s: Buffer overflow.", CFF_DEBUG_STR);
+ dest[len++] = id;
+ } else if (id >= 0 && id < CFF_LAST_DICT_OP) {
+ if (len + 2 > destlen)
+ ERROR("in cff_dict_pack(): Buffer overflow");
+ dest[len++] = 12;
+ dest[len++] = id - CFF_LAST_DICT_OP1;
+ } else {
+ ERROR("%s: Invalid CFF DICT operator ID.", CFF_DEBUG_STR);
+ }
+ }
+
+ return len;
+}
+
+int cff_dict_pack (cff_dict *dict, card8 *dest, int destlen)
+{
+ int len = 0;
+ int i;
+
+ for (i = 0; i < dict->count; i++) {
+ if (!strcmp(dict->entries[i].key, "ROS")) {
+ len += put_dict_entry(&dict->entries[i], dest, destlen);
+ break;
+ }
+ }
+ for (i = 0; i < dict->count; i++) {
+ if (strcmp(dict->entries[i].key, "ROS")) {
+ len += put_dict_entry(&dict->entries[i], dest+len, destlen-len);
+ }
+ }
+
+ return len;
+}
+
+void cff_dict_add (cff_dict *dict, const char *key, int count)
+{
+ int id, i;
+
+ for (id=0;id<CFF_LAST_DICT_OP;id++) {
+ if (key && dict_operator[id].opname &&
+ strcmp(dict_operator[id].opname, key) == 0)
+ break;
+ }
+
+ if (id == CFF_LAST_DICT_OP)
+ ERROR("%s: Unknown CFF DICT operator.", CFF_DEBUG_STR);
+
+ for (i=0;i<dict->count;i++) {
+ if ((dict->entries)[i].id == id) {
+ if ((dict->entries)[i].count != count)
+ ERROR("%s: Inconsistent DICT argument number.", CFF_DEBUG_STR);
+ return;
+ }
+ }
+
+ if (dict->count + 1 >= dict->max) {
+ dict->max += 8;
+ dict->entries = RENEW(dict->entries, dict->max, cff_dict_entry);
+ }
+
+ (dict->entries)[dict->count].id = id;
+ (dict->entries)[dict->count].key = dict_operator[id].opname;
+ (dict->entries)[dict->count].count = count;
+ if (count > 0) {
+ (dict->entries)[dict->count].values = NEW(count, double);
+ memset((dict->entries)[dict->count].values,
+ 0, sizeof(double)*count);
+ } else {
+ (dict->entries)[dict->count].values = NULL;
+ }
+ dict->count += 1;
+
+ return;
+}
+
+void cff_dict_remove (cff_dict *dict, const char *key)
+{
+ int i;
+ for (i = 0; i < dict->count; i++) {
+ if (key && strcmp(key, (dict->entries)[i].key) == 0) {
+ (dict->entries)[i].count = 0;
+ if ((dict->entries)[i].values)
+ RELEASE((dict->entries)[i].values);
+ (dict->entries)[i].values = NULL;
+ }
+ }
+}
+
+int cff_dict_known (cff_dict *dict, const char *key)
+{
+ int i;
+
+ for (i = 0; i < dict->count; i++) {
+ if (key && strcmp(key, (dict->entries)[i].key) == 0
+ && (dict->entries)[i].count > 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+double cff_dict_get (cff_dict *dict, const char *key, int idx)
+{
+ double value = 0.0;
+ int i;
+
+ ASSERT(key && dict);
+
+ for (i = 0; i < dict->count; i++) {
+ if (strcmp(key, (dict->entries)[i].key) == 0) {
+ if ((dict->entries)[i].count > idx)
+ value = (dict->entries)[i].values[idx];
+ else
+ ERROR("%s: Invalid index number.", CFF_DEBUG_STR);
+ break;
+ }
+ }
+
+ if (i == dict->count)
+ ERROR("%s: DICT entry \"%s\" not found.", CFF_DEBUG_STR, key);
+
+ return value;
+}
+
+void cff_dict_set (cff_dict *dict, const char *key, int idx, double value)
+{
+ int i;
+
+ ASSERT(dict && key);
+
+ for (i = 0 ; i < dict->count; i++) {
+ if (strcmp(key, (dict->entries)[i].key) == 0) {
+ if ((dict->entries)[i].count > idx)
+ (dict->entries)[i].values[idx] = value;
+ else
+ ERROR("%s: Invalid index number.", CFF_DEBUG_STR);
+ break;
+ }
+ }
+
+ if (i == dict->count)
+ ERROR("%s: DICT entry \"%s\" not found.", CFF_DEBUG_STR, key);
+}
+
+void cff_dict_update (cff_dict *dict, cff_font *cff)
+{
+ int i;
+
+ for (i = 0;i < dict->count; i++) {
+ if ((dict->entries)[i].count > 0) {
+ char *str;
+ int id;
+
+ id = (dict->entries)[i].id;
+ if (dict_operator[id].argtype == CFF_TYPE_SID) {
+ str = cff_get_string(cff, (dict->entries)[i].values[0]);
+ (dict->entries)[i].values[0] = cff_add_string(cff, str, 1);
+ RELEASE(str);
+ } else if (dict_operator[id].argtype == CFF_TYPE_ROS) {
+ str = cff_get_string(cff, (dict->entries)[i].values[0]);
+ (dict->entries)[i].values[0] = cff_add_string(cff, str, 1);
+ RELEASE(str);
+ str = cff_get_string(cff, (dict->entries)[i].values[1]);
+ (dict->entries)[i].values[1] = cff_add_string(cff, str, 1);
+ RELEASE(str);
+ }
+ }
+ }
+}
diff --git a/Build/source/texk/dvipdfm-x/cff_dict.h b/Build/source/texk/dvipdfm-x/cff_dict.h
new file mode 100644
index 00000000000..f5b27708559
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cff_dict.h
@@ -0,0 +1,45 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CFF_DICT_H_
+#define _CFF_DICT_H_
+
+#include "cff_types.h"
+#include "cff.h"
+
+#define CFF_NOMINALWIDTHX_DEFAULT 0.0
+#define CFF_DEFAULTWIDTHX_DEFAULT 0.0
+
+extern cff_dict *cff_new_dict (void);
+extern void cff_release_dict (cff_dict *dict);
+
+extern void cff_dict_set (cff_dict *dict, const char *key, int idx, double value);
+extern double cff_dict_get (cff_dict *dict, const char *key, int idx);
+extern void cff_dict_add (cff_dict *dict, const char *key, int count);
+extern void cff_dict_remove (cff_dict *dict, const char *key);
+extern int cff_dict_known (cff_dict *dict, const char *key);
+
+/* decode/encode DICT */
+extern cff_dict *cff_dict_unpack (card8 *data, card8 *endptr);
+extern int cff_dict_pack (cff_dict *dict, card8 *dest, int destlen);
+
+extern void cff_dict_update (cff_dict *dict, cff_font *cff);
+
+#endif /* _CFF_DICT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cff_limits.h b/Build/source/texk/dvipdfm-x/cff_limits.h
new file mode 100644
index 00000000000..fa95ba94455
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cff_limits.h
@@ -0,0 +1,44 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CFF_LIMITS_H_
+#define _CFF_LIMITS_H_
+
+#include <limits.h>
+
+#define CFF_INT_MAX 0x7fffffff
+#define CFF_INT_MIN (-0x7fffffff - 1)
+
+#if (INT_MAX < CFF_INT_MAX || INT_MIN > CFF_INT_MIN)
+#error "CFF support won't work on this system."
+#endif
+
+#define CFF_SID_MAX 64999
+#define CFF_STDSTR_MAX 391
+
+/* Type 2 Charstring */
+#define CS_NUM_SUBR_MAX 65536
+#define CS_STR_LEN_MAX 65536
+#define CS_STEM_ZONE_MAX 96
+#define CS_ARG_STACK_MAX 48
+#define CS_TRANS_ARRAY_MAX 32
+#define CS_SUBR_NEST_MAX 10
+
+#endif /* _CFF_LIMITS_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cff_stdstr.h b/Build/source/texk/dvipdfm-x/cff_stdstr.h
new file mode 100644
index 00000000000..e7517f29b89
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cff_stdstr.h
@@ -0,0 +1,107 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CFF_STDSTR_H_
+#define _CFF_STDSTR_H_
+
+#define CFF_STDSTR_MAX 391
+
+const char *const cff_stdstr[CFF_STDSTR_MAX] = {
+ ".notdef", "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quoteright", "parenleft",
+ "parenright", "asterisk", "plus", "comma", "hyphen",
+ "period", "slash", "zero", "one", "two",
+ "three", "four", "five", "six", "seven",
+ "eight", "nine", "colon", "semicolon", "less",
+ "equal", "greater", "question", "at", "A",
+ "B", "C", "D", "E", "F",
+ "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P",
+ "Q", "R", "S", "T", "U",
+ "V", "W", "X", "Y", "Z",
+ "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
+ "quoteleft", "a", "b", "c", "d",
+ "e", "f", "g", "h", "i",
+ "j", "k", "l", "m", "n",
+ "o", "p", "q", "r", "s",
+ "t", "u", "v", "w", "x",
+ "y", "z", "braceleft", "bar", "braceright",
+ "asciitilde", "exclamdown", "cent", "sterling", "fraction",
+ "yen", "florin", "section", "currency", "quotesingle",
+ "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi",
+ "fl", "endash", "dagger", "daggerdbl", "periodcentered",
+ "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
+ "guillemotright", "ellipsis", "perthousand", "questiondown", "grave",
+ "acute", "circumflex", "tilde", "macron", "breve",
+ "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
+ "ogonek", "caron", "emdash", "AE", "ordfeminine",
+ "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+ "dotlessi", "lslash", "oslash", "oe", "germandbls",
+ "onesuperior", "logicalnot", "mu", "trademark", "Eth",
+ "onehalf", "plusminus", "Thorn", "onequarter", "divide",
+ "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
+ "registered", "minus", "eth", "multiply", "threesuperior",
+ "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
+ "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
+ "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
+ "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
+ "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
+ "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+ "aacute", "acircumflex", "adieresis", "agrave", "aring",
+ "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
+ "egrave", "iacute", "icircumflex", "idieresis", "igrave",
+ "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
+ "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
+ "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+ "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall",
+ "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle",
+ "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle",
+ "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior",
+ "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior",
+ "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
+ "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+ "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
+ "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall",
+ "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
+ "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
+ "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+ "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
+ "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
+ "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
+ "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall",
+ "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
+ "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall",
+ "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
+ "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior",
+ "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior",
+ "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior",
+ "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior",
+ "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall",
+ "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+ "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall",
+ "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall",
+ "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall",
+ "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall",
+ "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
+ "001.000", "001.001", "001.002", "001.003",
+ "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"
+};
+
+#endif /* _CFF_STDSTR_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cff_types.h b/Build/source/texk/dvipdfm-x/cff_types.h
new file mode 100644
index 00000000000..56370d19283
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cff_types.h
@@ -0,0 +1,138 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CFF_TYPES_H_
+#define _CFF_TYPES_H_
+
+/* CFF Data Types */
+
+#define CFF_TYPE_UNKNOWN 0
+#define CFF_TYPE_INTEGER (1 << 0)
+#define CFF_TYPE_REAL (1 << 1)
+#define CFF_TYPE_NUMBER (CFF_TYPE_INTEGER|CFF_TYPE_REAL)
+#define CFF_TYPE_BOOLEAN (1 << 2)
+#define CFF_TYPE_SID (1 << 3)
+#define CFF_TYPE_ARRAY (1 << 4)
+#define CFF_TYPE_DELTA (1 << 5)
+
+/* SID SID number */
+#define CFF_TYPE_ROS (1 << 6)
+/* offset(0) */
+#define CFF_TYPE_OFFSET (1 << 7)
+/* size offset(0) */
+#define CFF_TYPE_SZOFF (1 << 8)
+
+typedef unsigned char card8; /* 1-byte unsigned number */
+typedef unsigned short card16; /* 2-byte unsigned number */
+typedef unsigned char c_offsize; /* 1-byte unsigned number specifies the size
+ of an Offset field or fields, range 1-4 */
+typedef uint32_t l_offset; /* 1, 2, 3, or 4-byte offset */
+typedef unsigned short s_SID; /* 2-byte string identifier */
+
+typedef struct {
+ card16 count; /* number of objects stored in INDEX */
+ c_offsize offsize; /* Offset array element size, 1-4 */
+ l_offset *offset; /* Offset array, count + 1 offsets */
+ card8 *data; /* Object data */
+} cff_index;
+
+typedef struct {
+ card8 major; /* format major version (starting at 1) */
+ card8 minor; /* format minor version (starting at 0) */
+ card8 hdr_size; /* Header size (bytes) */
+ c_offsize offsize; /* Absolute offset (0) size */
+} cff_header;
+
+
+/* Dictionary */
+typedef struct {
+ int id; /* encoded data value (as card8 or card16) */
+ const char *key; /* opname */
+ int count; /* number of values */
+ double *values; /* values */
+} cff_dict_entry;
+
+typedef struct {
+ int max;
+ int count;
+ cff_dict_entry *entries;
+} cff_dict;
+
+/* Encoding, Charset and FDSelect */
+typedef struct
+{
+ s_SID first; /* SID or CID, or card8 for Encoding */
+ card8 n_left; /* no. of remaining gids/codes in this range */
+} cff_range1;
+
+typedef struct
+{
+ s_SID first; /* SID or CID (card16) */
+ card16 n_left; /* card16-version of range1 */
+} cff_range2;
+
+typedef struct
+{
+ card8 code;
+ s_SID glyph;
+} cff_map;
+
+typedef struct
+{
+ card8 format; /* if (format & 0x80) then have supplement */
+ card8 num_entries; /* number of entries */
+ union {
+ card8 *codes; /* format 0 */
+ cff_range1 *range1; /* format 1 */
+ } data;
+ card8 num_supps; /* number of supplementary data */
+ cff_map *supp; /* supplement */
+} cff_encoding;
+
+typedef struct
+{
+ card8 format;
+ card16 num_entries;
+ union {
+ s_SID *glyphs; /* format 0 */
+ cff_range1 *range1; /* format 1 */
+ cff_range2 *range2; /* format 2 */
+ } data;
+} cff_charsets;
+
+/* CID-Keyed font specific */
+typedef struct
+{
+ card16 first;
+ card8 fd;
+} cff_range3;
+
+typedef struct
+{
+ card8 format;
+ card16 num_entries; /* number of glyphs/ranges */
+ union {
+ card8 *fds; /* format 0 */
+ cff_range3 *ranges; /* format 3 */
+ } data;
+ /* card16 sentinel; */ /* format 3 only, must be equals to num_glyphs */
+} cff_fdselect;
+
+#endif /* _CFF_TYPES_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cid.c b/Build/source/texk/dvipdfm-x/cid.c
new file mode 100644
index 00000000000..9935513ad3e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cid.c
@@ -0,0 +1,610 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * CID-keyed font support:
+ *
+ * See also, cidtype0, and cidtype2
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+
+#include "cidtype0.h"
+#include "cidtype2.h"
+#include "cid.h"
+
+#define PDF_CID_SUPPORT_MIN 2
+#define PDF_CID_SUPPORT_MAX 6
+
+/*
+ * Unicode and PDF Standard Character Collections.
+ *
+ * Adobe-Identity is only for TrueType fonts and it means font's
+ * internal glyph ordering.
+ */
+static struct {
+ const char *registry;
+ const char *ordering;
+ /* Heighest Supplement values supported by PDF-1.0, 1.1, ...; see
+ * also http://partners.adobe.com/public/developer/font/index.html#ckf
+ */
+ int supplement[21];
+} CIDFont_stdcc_def[] = {
+ {"Adobe", "UCS", {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0}},
+ {"Adobe", "GB1", {-1, -1, 0, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4}},
+ {"Adobe", "CNS1", {-1, -1, 0, 0, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4}},
+ {"Adobe", "Japan1", {-1, -1, 2, 2, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6}},
+ {"Adobe", "Korea1", {-1, -1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2}},
+ {"Adobe", "Identity", {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0}},
+ {NULL, NULL, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0}}
+};
+#define SUP_IDX_MAX 20
+#define UCS_CC 0
+#define ACC_START 1
+#define ACC_END 4
+
+static char registry_Adobe[] = "Adobe";
+static char ordering_Identity[] = "Identity";
+static char ordering_UCS[] = "UCS";
+
+CIDSysInfo CSI_IDENTITY = {
+ registry_Adobe,
+ ordering_Identity,
+ 0
+};
+
+CIDSysInfo CSI_UNICODE = {
+ registry_Adobe,
+ ordering_UCS,
+ 0
+};
+
+/*
+ * Optional supplement after alias name.
+ */
+
+static struct {
+ const char *name;
+ int index;
+} CIDFont_stdcc_alias[] = {
+ {"AU", 0}, {"AG1", 1}, {"AC1", 2}, {"AJ1", 3}, {"AK1", 4}, {"AI", 5},
+ {"UCS", 0}, {"GB1", 1}, {"CNS1", 2}, {"Japan1", 3}, {"Korea1", 4}, {"Identity", 5},
+ {"U", 0}, {"G", 1}, {"C", 2}, {"J", 3}, {"K", 4}, {"I", 5},
+ {NULL, 0}
+};
+
+static void release_opt (cid_opt *opt);
+static int get_cidsysinfo (CIDSysInfo *csi, const char *map_name, const fontmap_opt *fmap_opt);
+
+int opt_flags_cidfont = 0;
+
+int
+CIDFont_is_ACCFont (pdf_font *font)
+{
+ int i;
+ CIDSysInfo *csi;
+
+ ASSERT(font);
+
+ csi = &font->cid.csi;
+ for (i = ACC_START; i <= ACC_END ; i++) {
+ if (!strcmp(csi->registry, CIDFont_stdcc_def[i].registry) &&
+ !strcmp(csi->ordering, CIDFont_stdcc_def[i].ordering))
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+CIDFont_is_UCSFont (pdf_font *font)
+{
+ CIDSysInfo *csi;
+
+ ASSERT(font);
+
+ csi = &font->cid.csi;
+
+ if (!strcmp(csi->ordering, "UCS") ||
+ !strcmp(csi->ordering, "UCS2"))
+ return 1;
+
+ return 0;
+}
+
+char *
+CIDFont_get_usedchars (pdf_font *font)
+{
+ if (!font->usedchars) {
+ font->usedchars = NEW(8192, char);
+ memset(font->usedchars, 0, 8192*sizeof(char));
+ }
+
+ return font->usedchars;
+}
+
+char *
+CIDFont_get_usedchars_v (pdf_font *font)
+{
+ if (!font->cid.usedchars_v) {
+ font->cid.usedchars_v = NEW(8192, char);
+ memset(font->cid.usedchars_v, 0, 8192*sizeof(char));
+ }
+
+ return font->cid.usedchars_v;
+}
+
+
+static int
+source_font_type (pdf_font *font)
+{
+ int type = PDF_FONT_FONTTYPE_CIDTYPE0;
+
+ ASSERT(font);
+
+ if (font->flags & CIDFONT_FLAG_TYPE1) {
+ type = PDF_FONT_FONTTYPE_TYPE1;
+ } else if (font->flags & CIDFONT_FLAG_TYPE1C) {
+ type = PDF_FONT_FONTTYPE_TYPE1C;
+ } else if (font->flags & CIDFONT_FLAG_TRUETYPE) {
+ type = PDF_FONT_FONTTYPE_TRUETYPE;
+ }
+
+ return type;
+}
+
+void
+pdf_font_load_cidfont (pdf_font *font)
+{
+ int error = 0;
+
+ if (!font || !font->reference)
+ return;
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(":%s", font->filename);
+ if (dpx_conf.verbose_level > 1) {
+ if (font->fontname)
+ MESG("[%s]", font->fontname);
+ }
+
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_CIDTYPE0:
+ if(dpx_conf.verbose_level > 0)
+ MESG("[CIDFontType0]");
+ switch (source_font_type(font)) {
+ case PDF_FONT_FONTTYPE_TYPE1:
+ error = CIDFont_type0_t1dofont(font);
+ break;
+ case PDF_FONT_FONTTYPE_TYPE1C:
+ error = CIDFont_type0_t1cdofont(font);
+ break;
+ default:
+ error = CIDFont_type0_dofont(font);
+ break;
+ }
+ break;
+ case PDF_FONT_FONTTYPE_CIDTYPE2:
+ if(dpx_conf.verbose_level > 0)
+ MESG("[CIDFontType2]");
+ error = CIDFont_type2_dofont(font);
+ break;
+ }
+
+ if (error)
+ ERROR("Error occurred while loading font: %s", font->filename);
+
+ return;
+}
+
+#include "pdfparse.h"
+#include "cid_basefont.h"
+
+static int
+CIDFont_base_open (pdf_font *font, const char *name, cid_opt *opt)
+{
+ pdf_obj *fontdict, *descriptor;
+ char *fontname = NULL;
+ int idx;
+
+ ASSERT(font);
+
+ for (idx = 0; cid_basefont[idx].fontname != NULL; idx++) {
+ if (!strcmp(name, cid_basefont[idx].fontname) ||
+ (strlen(name) == strlen(cid_basefont[idx].fontname) - strlen("-Acro") &&
+ !strncmp(name, cid_basefont[idx].fontname,
+ strlen(cid_basefont[idx].fontname)-strlen("-Acro")))
+ )
+ break;
+ }
+
+ if (cid_basefont[idx].fontname == NULL)
+ return -1;
+
+ fontname = NEW(strlen(name)+12, char);
+ memset(fontname, 0, strlen(name)+12);
+ strcpy(fontname, name);
+
+ switch (opt->style) {
+ case FONT_STYLE_BOLD:
+ strcat(fontname, ",Bold");
+ break;
+ case FONT_STYLE_ITALIC:
+ strcat(fontname, ",Italic");
+ break;
+ case FONT_STYLE_BOLDITALIC:
+ strcat(fontname, ",BoldItalic");
+ break;
+ }
+ {
+ const char *start;
+ const char *end;
+
+ start = cid_basefont[idx].fontdict;
+ end = start + strlen(start);
+ fontdict = parse_pdf_dict(&start, end, NULL);
+ start = cid_basefont[idx].descriptor;
+ end = start + strlen(start);
+ descriptor = parse_pdf_dict(&start, end, NULL);
+
+ ASSERT(fontdict && descriptor);
+ }
+
+ font->fontname = fontname;
+ font->flags |= PDF_FONT_FLAG_BASEFONT;
+ {
+ char *registry, *ordering;
+ int supplement;
+ pdf_obj *tmp;
+
+ tmp = pdf_lookup_dict(fontdict, "CIDSystemInfo");
+
+ ASSERT( tmp && pdf_obj_typeof(tmp) == PDF_DICT );
+
+ registry = pdf_string_value(pdf_lookup_dict(tmp, "Registry"));
+ ordering = pdf_string_value(pdf_lookup_dict(tmp, "Ordering"));
+ supplement = pdf_number_value(pdf_lookup_dict(tmp, "Supplement"));
+
+ font->cid.csi.registry = NEW(strlen(registry)+1, char);
+ font->cid.csi.ordering = NEW(strlen(ordering)+1, char);
+ strcpy(font->cid.csi.registry, registry);
+ strcpy(font->cid.csi.ordering, ordering);
+ font->cid.csi.supplement = supplement;
+ }
+
+ {
+ pdf_obj *tmp;
+ char *type;
+
+ tmp = pdf_lookup_dict(fontdict, "Subtype");
+ ASSERT( tmp != NULL && pdf_obj_typeof(tmp) == PDF_NAME );
+
+ type = pdf_name_value(tmp);
+ if (!strcmp(type, "CIDFontType0"))
+ font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0;
+ else if (!strcmp(type, "CIDFontType2"))
+ font->subtype = PDF_FONT_FONTTYPE_CIDTYPE2;
+ else {
+ ERROR("Unknown CIDFontType \"%s\"", type);
+ }
+ }
+
+ if (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH) {
+ if (pdf_lookup_dict(fontdict, "W")) {
+ pdf_remove_dict(fontdict, "W");
+ }
+ if (pdf_lookup_dict(fontdict, "W2")) {
+ pdf_remove_dict(fontdict, "W2");
+ }
+ }
+
+ pdf_add_dict(fontdict, pdf_new_name("Type"), pdf_new_name("Font"));
+ pdf_add_dict(fontdict, pdf_new_name("BaseFont"), pdf_new_name(fontname));
+ pdf_add_dict(descriptor, pdf_new_name("Type"), pdf_new_name("FontDescriptor"));
+ pdf_add_dict(descriptor, pdf_new_name("FontName"), pdf_new_name(fontname));
+
+ font->resource = fontdict;
+ font->descriptor = descriptor;
+
+ opt->embed = 0;
+
+ return 0;
+}
+
+int
+pdf_font_cidfont_lookup_cache (pdf_font *fonts, int count, const char *map_name,
+ CIDSysInfo *cmap_csi, const fontmap_opt *fmap_opt)
+{
+ int font_id = -1;
+ pdf_font *font = NULL;
+ cid_opt opt;
+ int has_csi;
+
+ ASSERT(fonts);
+
+ opt.style = fmap_opt->style;
+ opt.embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1;
+ opt.csi.registry = NULL;
+ opt.csi.ordering = NULL;
+ opt.csi.supplement = 0;
+ has_csi = get_cidsysinfo(&opt.csi, map_name, fmap_opt);
+ opt.stemv = fmap_opt->stemv;
+
+ if (!has_csi && cmap_csi) {
+ /*
+ * No CIDSystemInfo supplied explicitly. Copy from CMap's one if available.
+ * It is not neccesary for CID-keyed fonts. But TrueType requires them.
+ */
+ opt.csi.registry = NEW(strlen(cmap_csi->registry)+1, char);
+ strcpy(opt.csi.registry, cmap_csi->registry);
+ opt.csi.ordering = NEW(strlen(cmap_csi->ordering)+1, char);
+ strcpy(opt.csi.ordering, cmap_csi->ordering);
+ opt.csi.supplement = cmap_csi->supplement;
+ has_csi = 1;
+ }
+ /*
+ * Here, we do not compare font->ident and map_name because of
+ * implicit CIDSystemInfo supplied by CMap for TrueType.
+ */
+ for (font_id = 0; font_id < count; font_id++) {
+ font = &fonts[font_id];
+ if (font->subtype != PDF_FONT_FONTTYPE_CIDTYPE0 &&
+ font->subtype != PDF_FONT_FONTTYPE_CIDTYPE2)
+ continue;
+ if (!strcmp(font->filename, map_name) &&
+ font->cid.options.style == opt.style &&
+ font->index == fmap_opt->index) {
+ if (font->cid.options.embed == opt.embed) {
+ /*
+ * Case 1: CSI not available (Identity CMap)
+ * Font is TrueType --> continue
+ * Font is CIDFont --> break
+ * Case 2: CSI matched --> break
+ */
+ if (!has_csi) {
+ if (font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2)
+ continue;
+ else
+ break;
+ } else if (!strcmp(font->cid.csi.registry, opt.csi.registry) &&
+ !strcmp(font->cid.csi.ordering, opt.csi.ordering)) {
+ if (font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2)
+ font->cid.csi.supplement =
+ MAX(opt.csi.supplement, font->cid.csi.supplement); /* FIXME: font modified */
+ break;
+ }
+ } else if (font->flags & PDF_FONT_FLAG_BASEFONT) {
+ break;
+ }
+ }
+ }
+ release_opt(&opt);
+
+ return (font_id < count) ? font_id : -1;
+}
+
+int
+pdf_font_open_cidfont (pdf_font *font, const char *map_name, CIDSysInfo *cmap_csi, const fontmap_opt *fmap_opt)
+{
+ cid_opt opt;
+ int has_csi;
+
+ opt.style = fmap_opt->style;
+ opt.embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1;
+ opt.csi.registry = NULL;
+ opt.csi.ordering = NULL;
+ opt.csi.supplement = 0;
+ has_csi = get_cidsysinfo(&opt.csi, map_name, fmap_opt);
+ opt.stemv = fmap_opt->stemv;
+
+ if (!has_csi && cmap_csi) {
+ /*
+ * No CIDSystemInfo supplied explicitly. Copy from CMap's one if available.
+ * It is not neccesary for CID-keyed fonts. But TrueType requires them.
+ */
+ opt.csi.registry = NEW(strlen(cmap_csi->registry)+1, char);
+ strcpy(opt.csi.registry, cmap_csi->registry);
+ opt.csi.ordering = NEW(strlen(cmap_csi->ordering)+1, char);
+ strcpy(opt.csi.ordering, cmap_csi->ordering);
+ opt.csi.supplement = cmap_csi->supplement;
+ has_csi = 1;
+ }
+
+ if (CIDFont_type0_open(font, map_name, fmap_opt->index, &opt) < 0 &&
+ CIDFont_type2_open(font, map_name, fmap_opt->index, &opt) < 0 &&
+ CIDFont_type0_open_from_t1 (font, map_name, fmap_opt->index, &opt) < 0 &&
+ CIDFont_type0_open_from_t1c(font, map_name, fmap_opt->index, &opt) < 0 &&
+ CIDFont_base_open (font, map_name, &opt) < 0) {
+ release_opt(&opt);
+ return -1;
+ }
+
+ font->filename = NEW(strlen(map_name)+1, char);
+ strcpy(font->filename, map_name);
+ font->ident = NEW(strlen(map_name)+1, char);
+ strcpy(font->ident, map_name);
+ font->index = fmap_opt->index;
+ font->cid.options = opt;
+
+ if (font->cid.csi.registry && font->cid.csi.ordering) {
+ if (cmap_csi) {
+ if (strcmp(font->cid.csi.registry, cmap_csi->registry) ||
+ strcmp(font->cid.csi.ordering, cmap_csi->ordering)) {
+ WARN("Inconsistent ROS found:\n");
+ MESG("\tFont: %s-%s-%d\n", font->cid.csi.registry, font->cid.csi.ordering, font->cid.csi.supplement);
+ MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement);
+ ERROR("Incompatible CMap specified for this font.");
+ }
+ if (font->cid.csi.supplement < cmap_csi->supplement) {
+ font->cid.csi.supplement = cmap_csi->supplement;
+ }
+ }
+ } else {
+ ASSERT(font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2);
+ if (cmap_csi) {
+ font->cid.csi.registry = NEW(strlen(cmap_csi->registry)+1, char);
+ strcpy(font->cid.csi.registry, cmap_csi->registry);
+ font->cid.csi.ordering = NEW(strlen(cmap_csi->ordering)+1, char);
+ strcpy(font->cid.csi.ordering, cmap_csi->ordering);
+ font->cid.csi.supplement = cmap_csi->supplement;
+ } else { /* This means font's internal glyph ordering. */
+ font->cid.csi.registry = NEW(strlen("Adobe")+1, char);
+ strcpy(font->cid.csi.registry, "Adobe");
+ font->cid.csi.ordering = NEW(strlen("Identity")+1, char);
+ strcpy(font->cid.csi.ordering, "Identity");
+ font->cid.csi.supplement = 0;
+ }
+ }
+
+ return 0;
+}
+
+
+/******************************* OPTIONS *******************************/
+
+/*
+ * FORMAT:
+ *
+ * (:int:)?!?string(/string)?(,string)?
+ */
+
+static void
+release_opt (cid_opt *opt)
+{
+ if (opt->csi.registry)
+ RELEASE(opt->csi.registry);
+ if (opt->csi.ordering)
+ RELEASE(opt->csi.ordering);
+}
+
+static int
+get_cidsysinfo (CIDSysInfo *csi, const char *map_name, const fontmap_opt *fmap_opt)
+{
+ int has_csi = 0;
+ int sup_idx;
+ int i, csi_idx = -1, n, m;
+
+ sup_idx = pdf_get_version() - 10;
+ sup_idx = (sup_idx > SUP_IDX_MAX) ? SUP_IDX_MAX : sup_idx;
+
+ if (!fmap_opt || !fmap_opt->charcoll)
+ return 0;
+
+ /* First try alias for standard one. */
+ for (i = 0; CIDFont_stdcc_alias[i].name != NULL; i++) {
+ n = strlen(CIDFont_stdcc_alias[i].name);
+ if (!strncmp(fmap_opt->charcoll,
+ CIDFont_stdcc_alias[i].name, n)) {
+ csi_idx = CIDFont_stdcc_alias[i].index;
+ csi->registry = NEW(strlen(CIDFont_stdcc_def[csi_idx].registry)+1, char);
+ strcpy(csi->registry, CIDFont_stdcc_def[csi_idx].registry);
+ csi->ordering = NEW(strlen(CIDFont_stdcc_def[csi_idx].ordering)+1, char);
+ strcpy(csi->ordering, CIDFont_stdcc_def[csi_idx].ordering);
+ if (strlen(fmap_opt->charcoll) > n) {
+ csi->supplement = (int) strtoul(&(fmap_opt->charcoll[n]), NULL, 10);
+ } else { /* Use heighest supported value for current output PDF version. */
+ csi->supplement = CIDFont_stdcc_def[csi_idx].supplement[sup_idx];
+ }
+ has_csi = 1;
+ break;
+ }
+ }
+ if (!has_csi) {
+ char *p, *q;
+
+ p = (char *) fmap_opt->charcoll;
+
+ /* Full REGISTRY-ORDERING-SUPPLEMENT */
+ p = strchr(fmap_opt->charcoll, '-');
+ if (!p || p[1] == '\0')
+ ERROR("String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", fmap_opt->charcoll);
+ p++;
+
+ q = strchr(p, '-');
+ if (!q || q[1] == '\0')
+ ERROR("String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", fmap_opt->charcoll);
+ q++;
+
+ if (!isdigit((unsigned char)q[0]))
+ ERROR("String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", fmap_opt->charcoll);
+
+ n = strlen(fmap_opt->charcoll) - strlen(p) - 1;
+ csi->registry = NEW(n+1, char);
+ memcpy(csi->registry, fmap_opt->charcoll, n);
+ csi->registry[n] = '\0';
+
+ m = strlen(p) - strlen(q) - 1;
+ csi->ordering = NEW(m+1, char);
+ memcpy(csi->ordering, p, m);
+ csi->ordering[m] = '\0';
+
+ csi->supplement = (int) strtoul(q, NULL, 10);
+
+ has_csi = 1;
+
+ /* Check for standart character collections. */
+ for (i = 0; CIDFont_stdcc_def[i].ordering != NULL; i++) {
+ if ((CIDFont_stdcc_def[i].registry &&
+ !strcmp(csi->registry, CIDFont_stdcc_def[i].registry)) &&
+ !strcmp(csi->ordering, CIDFont_stdcc_def[i].ordering)) {
+ csi_idx = i;
+ break;
+ }
+ }
+ }
+
+ if (csi && csi_idx >= 0) {
+ if (csi->supplement > CIDFont_stdcc_def[csi_idx].supplement[sup_idx]
+ && (fmap_opt->flags & FONTMAP_OPT_NOEMBED)) {
+ WARN("Heighest supplement number supported in PDF-%d.%d for %s-%s is %d.",
+ pdf_get_version_major(), pdf_get_version_minor(),
+ csi->registry, csi->ordering,
+ CIDFont_stdcc_def[csi_idx].supplement[sup_idx]);
+ WARN("Some character may not shown without embedded font (--> %s).", map_name);
+ }
+ }
+
+ return has_csi;
+}
+
+void
+CIDFont_set_flags (int flags)
+{
+ opt_flags_cidfont |= flags;
+}
diff --git a/Build/source/texk/dvipdfm-x/cid.h b/Build/source/texk/dvipdfm-x/cid.h
new file mode 100644
index 00000000000..ab33ca5b470
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cid.h
@@ -0,0 +1,47 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CID_H_
+#define _CID_H_
+
+#include "pdffont.h"
+
+extern CIDSysInfo CSI_IDENTITY;
+extern CIDSysInfo CSI_UNICODE;
+
+extern int opt_flags_cidfont;
+extern void CIDFont_set_flags (int flags);
+
+#define CIDFONT_FORCE_FIXEDPITCH (1 << 1)
+
+extern char *CIDFont_get_usedchars (pdf_font *font);
+extern char *CIDFont_get_usedchars_v (pdf_font *font);
+
+extern int CIDFont_is_ACCFont (pdf_font *font);
+extern int CIDFont_is_UCSFont (pdf_font *font);
+
+#include "fontmap.h"
+extern int pdf_font_cidfont_lookup_cache (pdf_font *fonts, int count, const char *map_name,
+ CIDSysInfo *cmap_csi, const fontmap_opt *fmap_opt);
+extern int pdf_font_open_cidfont (pdf_font *font, const char *map_name,
+ CIDSysInfo *cmap_csi, const fontmap_opt *fmap_opt);
+extern void pdf_font_load_cidfont (pdf_font *font);
+
+#endif /* _CID_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cid_basefont.h b/Build/source/texk/dvipdfm-x/cid_basefont.h
new file mode 100644
index 00000000000..bd3c814e7f3
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cid_basefont.h
@@ -0,0 +1,507 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CID_BASEFONT_H_
+#define _CID_BASEFONT_H_
+
+/* PLEASE SEND INFORMATION ON FONTS
+ *
+ * Those fonts are only for fixed-pitch glyphs (full-, half-, third-,
+ * and quarter- widths). Glyph widths should be determined solely from
+ * CID and CIDSystemInfo for those never-embedded fonts. Fixed-pitch
+ * pre-rotated forms are not supported yet.
+ *
+ * Font dictionaly entry Subtype and CIDSystemInfo is mandatory here.
+ * Font descriptor entry CapHeight, Ascent, Descent, ItalicAngle, Flags,
+ * FontBBox, and StemV is required. However, CapHeight, Ascent, Descent,
+ * and ItalicAngle is irrelevant for font-matching of CJK fonts. Panose
+ * entry in Style dictionary may affect in Acrobat. Serif font should
+ * have flag bit position 2 (2) set and all CJK fonts should also have
+ * bit position 3 (4) set: CJK font serif -> Flags 6, sans serif -> 4.
+ *
+ * Please always supply DW entry in font dictionary although this can
+ * be optional. PDF reference 1.2 had been described default value for
+ * DW as 0 (correct value if 1000) and several versions of Mac OS X
+ * implement so!
+ */
+
+const struct {
+ const char *fontname;
+ const char *fontdict;
+ const char *descriptor;
+} cid_basefont[] = {
+ /*
+ * Fonts found in printers
+ *
+ * Ryumin-Light and GothicBBB-Medium is often available in
+ * PostScript printer sold in Japan. There may be additonal
+ * Morisawa fonts such as ShinGo-Bold, but less common than
+ * those two fonts.
+ */
+ {
+ "Ryumin-Light",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Japan1) /Supplement 2 >> \
+/DW 1000 \
+/W [\
+ 231 632 500 \
+ 8718 [500 500] \
+]\
+>>",
+ "<< \
+/CapHeight 709 /Ascent 723 /Descent -241 /StemV 69 \
+/FontBBox [-170 -331 1024 903] \
+/ItalicAngle 0 /Flags 6 \
+/Style << /Panose <010502020300000000000000> >> \
+>>"
+ },
+ {
+ "GothicBBB-Medium",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Japan1) /Supplement 2 >> \
+/DW 1000 \
+/W [\
+ 231 632 500 \
+ 8718 [500 500] \
+]\
+>>",
+ "<< \
+/CapHeight 737 /Ascent 752 /Descent -271 /StemV 99 \
+/FontBBox [-174 -268 1001 944] \
+/ItalicAngle 0 /Flags 4 \
+/Style << /Panose <0801020b0500000000000000> >> \
+>>"
+ },
+
+ /* Adobe Asian Font Packs for Acrobat Reader 4 */
+ {
+ "MHei-Medium-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (CNS1) /Supplement 0 >> \
+/DW 1000 \
+/W [\
+13648 13742 500 \
+17603 [500] \
+]\
+>>",
+ "<< \
+/Ascent 752 /CapHeight 737 /Descent -271 /StemV 58 \
+/FontBBox [-45 -250 1015 887] \
+/ItalicAngle 0 /Flags 4 /XHeight 553 \
+/Style << /Panose <000001000600000000000000> >> \
+>>"
+ },
+ {
+ "MSung-Light-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (CNS1) /Supplement 0 >> \
+/DW 1000 \
+/W [\
+13648 13742 500 \
+17603 [500] \
+]\
+>>",
+ "<< \
+/Ascent 752 /CapHeight 737 /Descent -271 /StemV 58 \
+/FontBBox [-160 -249 1015 888] \
+/ItalicAngle 0 /Flags 6 /XHeight 553 \
+/Style << /Panose <000000000400000000000000> >> \
+>>"
+ },
+ {
+ "STSong-Light-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (GB1) /Supplement 2 >> \
+/DW 1000 \
+/W [\
+ 814 939 500 \
+ 7716 [500] \
+22355 [500 500] \
+22357 [500] \
+]\
+>>",
+ "<< \
+/Ascent 752 /CapHeight 737 /Descent -271 /StemV 58 \
+/FontBBox [-25 -254 1000 880] \
+/ItalicAngle 0 /Flags 6 /XHeight 599 \
+/Style << /Panose <000000000400000000000000> >> \
+>>"
+ },
+ {
+ "STHeiti-Regular-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (GB1) /Supplement 1 >> \
+/DW 1000 \
+/W [\
+ 814 939 500 \
+ 7716 [500] \
+22355 [500 500] \
+22357 [500] \
+]\
+>>",
+ "<< \
+/Ascent 752 /CapHeight 737 /Descent -271 /StemV 58 \
+/FontBBox [-34 -250 1000 882] \
+/ItalicAngle 0 /Flags 4 /XHeight 599 \
+/Style << /Panose <000001000600000000000000> >> \
+>>"
+ },
+ {
+ "HeiseiKakuGo-W5-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Japan1) /Supplement 2 >> \
+/DW 1000 \
+/W [\
+ 231 632 500 \
+ 8718 [500 500] \
+]\
+>>",
+ "<< \
+/Ascent 752 /CapHeight 737 /Descent -221 /StemV 114 \
+/FontBBox [-92 -250 1010 922] \
+/ItalicAngle 0 /Flags 4 /XHeight 553 \
+/Style << /Panose <0801020b0600000000000000> >> \
+>>"
+ },
+ {
+ "HeiseiMin-W3-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Japan1) /Supplement 2 >> \
+/DW 1000 \
+/W [\
+ 231 632 500 \
+ 8718 [500 500] \
+]\
+>>",
+ "<< \
+/Ascent 723 /CapHeight 709 /Descent -241 /StemV 69 \
+/FontBBox [-123 -257 1001 910] \
+/ItalicAngle 0 /Flags 6 /XHeight 450 \
+/Style << /Panose <010502020400000000000000> >> \
+>>"
+ },
+ {
+ "HYGoThic-Medium-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Korea1) /Supplement 1 >> \
+/DW 1000 \
+/W [\
+ 97 [500] \
+ 8094 8190 500 \
+]\
+>>",
+ "<< \
+/Ascent 752 /CapHeight 737 /Descent -271 /StemV 58 \
+/FontBBox [-6 -145 1003 880] \
+/ItalicAngle 0 /Flags 4 /XHeight 553 \
+/Style << /Panose <000001000600000000000000> >> \
+>>"
+ },
+ {
+ "HYSMyeongJo-Medium-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Korea1) /Supplement 1 >> \
+/DW 1000 \
+/W [\
+ 97 [500] \
+ 8094 8190 500 \
+]\
+>>",
+ "<< \
+/Ascent 752 /CapHeight 737 /Descent -271 /StemV 58 \
+/FontBBox [-0 -148 1001 880] \
+/ItalicAngle 0 /Flags 6 /XHeight 553 \
+/Style << /Panose <000000000600000000000000> >> \
+>>"
+ },
+
+ /* Acrobat Reader 5 */
+ {
+ "MSungStd-Light-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (CNS1) /Supplement 4 >> \
+/DW 1000 \
+/W [\
+13648 13742 500 \
+17603 [500] \
+]\
+>>",
+ "<< \
+/Ascent 880 /CapHeight 662 /Descent -120 /StemV 54 \
+/FontBBox [-160 -249 1015 1071] \
+/ItalicAngle 0 /Flags 6 \
+/Style << /Panose <000000000400000000000000> >> \
+>>"
+ },
+ {
+ "STSongStd-Light-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (GB1) /Supplement 4 >> \
+/DW 1000 \
+/W [\
+ 814 939 500 \
+ 7716 [500] \
+22355 [500 500] \
+22357 [500] \
+]\
+>>",
+ "<< \
+/Ascent 880 /CapHeight 626 /Descent -120 /StemV 44 \
+/FontBBox [-134 -254 1001 905] \
+/ItalicAngle 0 /Flags 6 \
+/Style << /Panose <000000000400000000000000> >> \
+>>"
+ },
+ {
+ "HYSMyeongJoStd-Medium-Acro",
+ "<< \
+/Subtype /CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Korea1) /Supplement 2 >> \
+/DW 1000 \
+/W [\
+ 97 [500] \
+ 8094 8190 500 \
+]\
+>>",
+ "<< \
+/Ascent 880 /CapHeight 720 /Descent -120 /StemV 60 \
+/FontBBox [-28 -148 1001 880] \
+/ItalicAngle 0 /Flags 6 \
+/Style << /Panose <000000000600000000000000> >> \
+>>"
+ },
+
+ /* Adobe Asian Font Packs for Adobe Reader 6 */
+
+ /*
+ * Widths of Adobe-CNS1-4
+ * 1 95 proportional
+ * 13648 13742 half-width
+ * 17601 17601 proportional?
+ * 17603 17603 half-width?
+ */
+ {
+ "AdobeMingStd-Light-Acro",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (CNS1) /Supplement 4 >> \
+/DW 1000 \
+/W [\
+13648 13742 500 \
+17603 [500] \
+]\
+>>",
+ "<< \
+/Ascent 880 /Descent -120 /StemV 48 /CapHeight 731 \
+/FontBBox [-38 -121 1002 918] \
+/ItalicAngle 0 /Flags 6 /XHeight 466 \
+/Style << /Panose <000002020300000000000000> >> \
+>>"
+ },
+ /*
+ * Widths of Adobe-GB1-4
+ * 1 95 proportional
+ * 814 939 half-width
+ * 7712 7715 proportional
+ * 7716 7716 half-width space
+ * 22353 22354 proportional
+ * 22355 22357 half-width
+ */
+ {
+ "AdobeSongStd-Light-Acro",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (GB1) /Supplement 4 >> \
+/DW 1000 \
+/W [\
+ 814 939 500 \
+ 7716 [500] \
+22355 [500 500] \
+22357 [500] \
+]\
+>>",
+ "<< \
+/Ascent 880 /Descent -120 /StemV 66 /CapHeight 626 \
+/FontBBox [-134 -254 1001 905] \
+/ItalicAngle 0 /Flags 6 /XHeight 416 \
+/Style << /Panose <000002020300000000000000> >> \
+>>"
+ },
+ /*
+ * Widths of Adobe-Japan1-4
+ * 1 230 proportional
+ * 231 632 half-width
+ * 9354 9737 proportional
+ * 9738 9757 quater-width
+ * 9758 9778 third-width
+ * 12063 12087 half-width
+ */
+ {
+ "KozMinPro-Regular-Acro",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Japan1) /Supplement 4 >> \
+/DW 1000 \
+/W [\
+ 231 632 500 \
+ 8718 [500 500] \
+ 9738 9757 250 \
+ 9758 9778 333 \
+12063 12087 500 \
+]\
+>>",
+ "<< \
+/Ascent 880 /Descent -120 /StemV 86 /CapHeight 740 \
+/FontBBox [-195 -272 1110 1075] \
+/ItalicAngle 0 /Flags 6 /XHeight 502 \
+/Style << /Panose <000002020400000000000000> >> \
+>>"
+ },
+ {
+ "KozGoPro-Medium-Acro",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering(Japan1) /Supplement 4 >> \
+/DW 1000 \
+/W [\
+ 231 632 500 \
+ 8718 [500 500] \
+ 9738 9757 250 \
+ 9758 9778 333 \
+12063 12087 500 \
+]\
+>>",
+ "<< \
+/Ascent 880 /Descent -120 /StemV 99 /CapHeight 763 \
+/FontBBox [-149 -374 1254 1008] \
+/ItalicAngle 0 /Flags 4 /XHeight 549 \
+/Style << /Panose <0000020b0700000000000000> >> \
+>>"
+ },
+ /*
+ * Widths of Adobe-Korea1-2
+ * 1 95 proportional
+ * 97 97 half-width?
+ * 8094 8190 half-width
+ */
+ {
+ "AdobeMyungjoStd-Medium-Acro",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (Korea1) /Supplement 2 >> \
+/DW 1000 \
+/W [\
+ 97 [500] \
+ 8094 8190 500 \
+]\
+>>",
+ "<< \
+/Ascent 880 /Descent -120 /StemV 99 /CapHeight 719 \
+/FontBBox [-28 -148 1001 880] \
+/ItalicAngle 0 /Flags 6 /XHeight 478 \
+/Style << /Panose <000002020600000000000000> >> \
+>>"
+ },
+
+ /* Addition in Adobe Reader 7 */
+ /*
+ * Adobe-Japan1-5
+ * 15449-15911 proportional
+ * 15912-15975 proportional
+ * 15976-16192 proportional (vert)
+ * 16469-16714 pre-rotated proportional
+ * 16715-16778 pre-rotated proportional
+ * Adobe-Japan1-6
+ * 20317-20371 proportional
+ * 20372-20426 proportional
+ * 20958 - (reserved for future use)
+ * 20961-21015 pre-rotated proportional
+ * 21016-21070 pre-rotated proportional
+ */
+ {
+ "KozMinProVI-Regular",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << \
+ /Registry (Adobe) \
+ /Ordering (Japan1) \
+ /Supplement 6 \
+>> \
+/DW 1000 \
+/W [\
+ 231 632 500 \
+ 8718 [500 500] \
+ 9738 9757 250 \
+ 9758 9778 333 \
+ 12063 12087 500 \
+]\
+ >>",
+ "<< \
+/Ascent 880 /Descent -120 /StemV 86 /CapHeight 742 \
+/FontBBox [-437 -340 1144 1317] \
+/ItalicAngle 0 /Flags 6 /XHeight 503 \
+/Style << \
+ /Panose <000002020400000000000000> \
+>> \
+ >>"
+ },
+
+ /* Addition in Adobe Reader 8 */
+ /*
+ * Font information of AdobeHeitiStd-Regular.otf may not be correct!
+ * Just copied the information of AdobeSongStd-Light.otf.
+ */
+ {
+ "AdobeHeitiStd-Regular",
+ "<< \
+/Subtype/CIDFontType0 \
+/CIDSystemInfo << /Registry (Adobe) /Ordering (GB1) /Supplement 4 >> \
+/DW 1000 \
+/W [\
+ 814 939 500 \
+ 7716 [500] \
+22355 [500 500] \
+22357 [500] \
+]\
+>>",
+ "<< \
+/Ascent 880 /Descent -120 /StemV 66 /CapHeight 626 \
+/FontBBox [-134 -254 1001 905] \
+/ItalicAngle 0 /Flags 6 /XHeight 416 \
+/Style << /Panose <000002020300000000000000> >> \
+>>"
+ },
+ /* END */
+ {NULL, NULL, NULL}
+};
+
+#endif /* _CID_BASEFONT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cidtype0.c b/Build/source/texk/dvipdfm-x/cidtype0.c
new file mode 100644
index 00000000000..fd00dd7bd8d
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cidtype0.c
@@ -0,0 +1,2118 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * CID-Keyed Font support:
+ *
+ * Only CFF/OpenType CID-Keyed Font with Type 2 charstrings is supported.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "numbers.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+
+#include "dpxfile.h"
+
+#include "pdfobj.h"
+/* pseudo unique tag */
+#include "pdffont.h"
+
+/* Font info. from OpenType tables */
+#include "sfnt.h"
+#include "tt_aux.h"
+/* Metrics */
+#include "tt_table.h"
+
+#include "cff_types.h"
+#include "cff_limits.h"
+#include "cff.h"
+#include "cff_dict.h"
+#include "cs_type2.h"
+
+/* typedef CID in cmap.h */
+#include "cmap.h"
+#include "type0.h"
+#include "cid.h"
+#include "cidtype0.h"
+
+/* Type1 --> CFF CIDFont */
+#include "unicode.h"
+#include "t1_load.h"
+#include "t1_char.h"
+
+#include "agl.h"
+
+#include "cmap.h"
+#include "cmap_write.h"
+#include "fontmap.h"
+
+/*
+ * PDF Reference 3rd. ed., p.340, "Glyph Metrics in CID Fonts".
+ */
+#ifndef PDFUNIT
+#define PDFUNIT(v) (ROUND((1000.0*(v))/(head->unitsPerEm),1))
+#endif
+
+static void
+add_CIDHMetrics (sfnt *sfont, pdf_obj *fontdict,
+ unsigned char *CIDToGIDMap, unsigned short last_cid,
+ struct tt_maxp_table *maxp,
+ struct tt_head_table *head, struct tt_longMetrics *hmtx)
+{
+ pdf_obj *w_array, *an_array = NULL;
+ int cid, start = 0, prev = 0;
+ double defaultAdvanceWidth;
+ int empty = 1;
+
+ (void) sfont; /* unsed */
+ defaultAdvanceWidth = PDFUNIT(hmtx[0].advance);
+ /*
+ * We alway use format:
+ * c [w_1 w_2 ... w_n]
+ */
+ w_array = pdf_new_array();
+ for (cid = 0; cid <= last_cid; cid++) {
+ USHORT gid;
+ double advanceWidth;
+ gid = CIDToGIDMap ? ((CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1]) : cid;
+ if (gid >= maxp->numGlyphs || (cid != 0 && gid == 0))
+ continue;
+ advanceWidth = PDFUNIT(hmtx[gid].advance);
+ if (advanceWidth == defaultAdvanceWidth) {
+ if (an_array) {
+ pdf_add_array(w_array, pdf_new_number(start));
+ pdf_add_array(w_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ } else {
+ if (cid != prev + 1 && an_array) {
+ pdf_add_array(w_array, pdf_new_number(start));
+ pdf_add_array(w_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ if (an_array == NULL) {
+ an_array = pdf_new_array();
+ start = cid;
+ }
+ pdf_add_array(an_array, pdf_new_number(advanceWidth));
+ prev = cid;
+ }
+ }
+
+ if (an_array) {
+ pdf_add_array(w_array, pdf_new_number(start));
+ pdf_add_array(w_array, an_array);
+ empty = 0;
+ }
+
+ /*
+ * We always write DW for older MacOS X's preview app.
+ * PDF Reference 2nd. ed, wrongly described default value of DW as 0, and
+ * MacOS X's (up to 10.2.8) preview app. implements this wrong description.
+ */
+ pdf_add_dict(fontdict,
+ pdf_new_name("DW"),
+ pdf_new_number(defaultAdvanceWidth));
+ if (!empty) {
+ pdf_add_dict(fontdict,
+ pdf_new_name("W"),
+ pdf_ref_obj(w_array));
+ }
+ pdf_release_obj(w_array);
+
+ return;
+}
+
+static void
+add_CIDVMetrics (sfnt *sfont, pdf_obj *fontdict,
+ unsigned char *CIDToGIDMap, unsigned short last_cid,
+ struct tt_maxp_table *maxp,
+ struct tt_head_table *head, struct tt_longMetrics *hmtx)
+{
+ pdf_obj *w2_array, *an_array = NULL;
+ int cid;
+#if 0
+ int prev = 0, start = 0;
+#endif
+ struct tt_VORG_table *vorg;
+ struct tt_vhea_table *vhea = NULL;
+ struct tt_longMetrics *vmtx = NULL;
+ double defaultAdvanceHeight, defaultVertOriginY;
+ int empty = 1;
+
+ /*
+ * No accurate vertical metrics can be obtained by simple way if the
+ * font does not have VORG table. Only CJK fonts may have VORG.
+ */
+ if (sfnt_find_table_pos(sfont, "VORG") <= 0)
+ return;
+
+ vorg = tt_read_VORG_table(sfont);
+ defaultVertOriginY = PDFUNIT(vorg->defaultVertOriginY);
+ if (sfnt_find_table_pos(sfont, "vhea") > 0)
+ vhea = tt_read_vhea_table(sfont);
+ if (vhea && sfnt_find_table_pos(sfont, "vmtx") > 0) {
+ sfnt_locate_table(sfont, "vmtx");
+ vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics, vhea->numOfExSideBearings);
+ }
+
+ if (sfnt_find_table_pos(sfont, "OS/2") <= 0) {
+ struct tt_os2__table *os2;
+ /* OpenType font must have OS/2 table. */
+ os2 = tt_read_os2__table(sfont);
+ defaultVertOriginY = PDFUNIT(os2->sTypoAscender);
+ defaultAdvanceHeight = PDFUNIT(os2->sTypoAscender - os2->sTypoDescender);
+ RELEASE(os2);
+ } else {
+ /* Some TrueType fonts used in Macintosh does not have OS/2 table. */
+ defaultAdvanceHeight = 1000;
+ }
+
+ w2_array = pdf_new_array();
+ for (cid = 0; cid <= last_cid; cid++) {
+ USHORT i, gid;
+ double advanceHeight, vertOriginX, vertOriginY;
+ gid = CIDToGIDMap ? ((CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1]) : cid;
+ if (gid >= maxp->numGlyphs || (cid != 0 && gid == 0))
+ continue;
+ advanceHeight = vmtx ? PDFUNIT(vmtx[gid].advance) : defaultAdvanceHeight;
+ vertOriginX = PDFUNIT(hmtx[gid].advance*0.5);
+ vertOriginY = defaultVertOriginY;
+ for (i = 0;
+ i < vorg->numVertOriginYMetrics && gid >= vorg->vertOriginYMetrics[i].glyphIndex;
+ i++) {
+ if (gid == vorg->vertOriginYMetrics[i].glyphIndex)
+ vertOriginY = PDFUNIT(vorg->vertOriginYMetrics[i].vertOriginY);
+ }
+#if 0
+ /*
+ * c [w1_1y v_1x v_1y w1_2y v_2x v_2y ...]
+ * Not working... Why?
+ * Acrobat Reader:
+ * Wrong rendering, interpretation of position vector is wrong.
+ * Xpdf and gs: ignores W2?
+ */
+ if (vertOriginY == defaultVertOriginY &&
+ advanceHeight == defaultAdvanceHeight) {
+ if (an_array) {
+ pdf_add_array(w2_array, pdf_new_number(start));
+ pdf_add_array(w2_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ } else {
+ if (cid != prev + 1 && an_array) {
+ pdf_add_array(w2_array, pdf_new_number(start));
+ pdf_add_array(w2_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ if (an_array == NULL) {
+ an_array = pdf_new_array();
+ start = cid;
+ }
+ pdf_add_array(an_array, pdf_new_number(-advanceHeight));
+ pdf_add_array(an_array, pdf_new_number(vertOriginX));
+ pdf_add_array(an_array, pdf_new_number(vertOriginY));
+ prev = cid;
+ }
+#else
+ /*
+ * c_first c_last w1_y v_x v_y
+ * This form may hit Acrobat's implementation limit of array element size, 8192.
+ * AFPL GhostScript 8.11 stops with rangecheck error with this. Maybe GS's bug?
+ */
+ if (vertOriginY != defaultVertOriginY ||
+ advanceHeight != defaultAdvanceHeight) {
+ pdf_add_array(w2_array, pdf_new_number(cid));
+ pdf_add_array(w2_array, pdf_new_number(cid));
+ pdf_add_array(w2_array, pdf_new_number(-advanceHeight));
+ pdf_add_array(w2_array, pdf_new_number(vertOriginX));
+ pdf_add_array(w2_array, pdf_new_number(vertOriginY));
+ empty = 0;
+ }
+#endif
+ }
+
+#if 0
+ if (an_array) {
+ pdf_add_array(w2_array, pdf_new_number(start));
+ pdf_add_array(w2_array, an_array);
+ empty = 0;
+ }
+#endif
+
+ if (defaultVertOriginY != 880 || defaultAdvanceHeight != 1000) {
+ an_array = pdf_new_array();
+ pdf_add_array(an_array, pdf_new_number(defaultVertOriginY));
+ pdf_add_array(an_array, pdf_new_number(-defaultAdvanceHeight));
+ pdf_add_dict(fontdict, pdf_new_name ("DW2"), an_array);
+ }
+ if (!empty) {
+ pdf_add_dict(fontdict,
+ pdf_new_name("W2"), pdf_ref_obj(w2_array));
+ }
+ pdf_release_obj(w2_array);
+
+ if (vorg->vertOriginYMetrics)
+ RELEASE(vorg->vertOriginYMetrics);
+ RELEASE(vorg);
+
+ if (vmtx)
+ RELEASE(vmtx);
+ if (vhea)
+ RELEASE(vhea);
+
+ return;
+}
+
+static void
+add_CIDMetrics (sfnt *sfont, pdf_obj *fontdict,
+ unsigned char *CIDToGIDMap, unsigned short last_cid, int need_vmetrics)
+{
+ struct tt_longMetrics *hmtx;
+ struct tt_head_table *head;
+ struct tt_hhea_table *hhea;
+ struct tt_maxp_table *maxp;
+
+ /*
+ * Read head, hhea, maxp:
+ *
+ * unitsPerEm --> head
+ * numHMetrics --> hhea
+ * numGlyphs --> maxp
+ */
+ head = tt_read_head_table(sfont);
+ maxp = tt_read_maxp_table(sfont);
+ hhea = tt_read_hhea_table(sfont);
+
+ sfnt_locate_table(sfont, "hmtx");
+ hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings);
+
+ add_CIDHMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
+ if (need_vmetrics)
+ add_CIDVMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
+
+ RELEASE(hmtx);
+ RELEASE(hhea);
+ RELEASE(maxp);
+ RELEASE(head);
+
+ return;
+}
+
+/*
+ * Create an instance of embeddable font.
+ */
+static int
+write_fontfile (pdf_font *font, cff_font *cffont)
+{
+ cff_index *topdict, *fdarray, *private;
+ unsigned char *dest;
+ int destlen = 0, i, size;
+ int offset, topdict_offset, fdarray_offset;
+
+ /* DICT sizes (offset set to long int) */
+ topdict = cff_new_index(1);
+ fdarray = cff_new_index(cffont->num_fds);
+ private = cff_new_index(cffont->num_fds);
+
+ cff_dict_remove(cffont->topdict, "UniqueID");
+ cff_dict_remove(cffont->topdict, "XUID");
+ cff_dict_remove(cffont->topdict, "Private"); /* some bad font may have */
+ cff_dict_remove(cffont->topdict, "Encoding"); /* some bad font may have */
+
+ topdict->offset[1] = cff_dict_pack(cffont->topdict,
+ (card8 *) work_buffer,
+ WORK_BUFFER_SIZE) + 1;
+ for (i = 0;i < cffont->num_fds; i++) {
+ size = 0;
+ if (cffont->private && cffont->private[i]) {
+ size = cff_dict_pack(cffont->private[i],
+ (card8 *) work_buffer, WORK_BUFFER_SIZE);
+ if (size < 1) { /* Private had contained only Subr */
+ cff_dict_remove(cffont->fdarray[i], "Private");
+ }
+ }
+ (private->offset)[i+1] = (private->offset)[i] + size;
+ (fdarray->offset)[i+1] = (fdarray->offset)[i] +
+ cff_dict_pack(cffont->fdarray[i],
+ (card8 *) work_buffer, WORK_BUFFER_SIZE);
+ }
+
+ destlen = 4; /* header size */
+ destlen += cff_set_name(cffont, font->fontname);
+ destlen += cff_index_size(topdict);
+ destlen += cff_index_size(cffont->string);
+ destlen += cff_index_size(cffont->gsubr);
+ destlen += (cffont->charsets->num_entries) * 2 + 1; /* charset format 0 */
+ destlen += (cffont->fdselect->num_entries) * 3 + 5; /* fdselect format 3 */
+ destlen += cff_index_size(cffont->cstrings);
+ destlen += cff_index_size(fdarray);
+ destlen += private->offset[private->count] - 1; /* Private is not INDEX */
+
+ dest = NEW(destlen, card8);
+
+ offset = 0;
+ /* Header */
+ offset += cff_put_header(cffont, dest + offset, destlen - offset);
+ /* Name */
+ offset += cff_pack_index(cffont->name, dest + offset, destlen - offset);
+ /* Top DICT */
+ topdict_offset = offset;
+ offset += cff_index_size(topdict);
+ /* Strings */
+ offset += cff_pack_index(cffont->string, dest + offset, destlen - offset);
+ /* Global Subrs */
+ offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset);
+
+ /* charset */
+ cff_dict_set(cffont->topdict, "charset", 0, offset);
+ offset += cff_pack_charsets(cffont, dest + offset, destlen - offset);
+
+ /* FDSelect */
+ cff_dict_set(cffont->topdict, "FDSelect", 0, offset);
+ offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset);
+
+ /* CharStrings */
+ cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
+ offset += cff_pack_index(cffont->cstrings,
+ dest + offset, cff_index_size(cffont->cstrings));
+ cff_release_index(cffont->cstrings);
+ cffont->cstrings = NULL; /* Charstrings cosumes huge memory */
+
+ /* FDArray and Private */
+ cff_dict_set(cffont->topdict, "FDArray", 0, offset);
+ fdarray_offset = offset;
+ offset += cff_index_size(fdarray);
+
+ fdarray->data = NEW(fdarray->offset[fdarray->count] - 1, card8);
+ for (i = 0; i < cffont->num_fds; i++) {
+ size = private->offset[i+1] - private->offset[i];
+ if (cffont->private[i] && size > 0) {
+ cff_dict_pack(cffont->private[i], dest + offset, size);
+ cff_dict_set(cffont->fdarray[i], "Private", 0, size);
+ cff_dict_set(cffont->fdarray[i], "Private", 1, offset);
+ }
+ cff_dict_pack(cffont->fdarray[i],
+ fdarray->data + (fdarray->offset)[i] - 1,
+ fdarray->offset[fdarray->count] - 1);
+ offset += size;
+ }
+
+ cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray));
+ cff_release_index(fdarray);
+ cff_release_index(private);
+
+ /* Finally Top DICT */
+ topdict->data = NEW(topdict->offset[topdict->count] - 1, card8);
+ cff_dict_pack(cffont->topdict,
+ topdict->data, topdict->offset[topdict->count] - 1);
+ cff_pack_index(topdict, dest + topdict_offset, cff_index_size(topdict));
+ cff_release_index(topdict);
+
+ /*
+ * FontFile
+ */
+ {
+ pdf_obj *fontfile, *stream_dict;
+
+ fontfile = pdf_new_stream(STREAM_COMPRESS);
+ stream_dict = pdf_stream_dict(fontfile);
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("FontFile3"),
+ pdf_ref_obj (fontfile));
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Subtype"),
+ pdf_new_name("CIDFontType0C"));
+ pdf_add_stream(fontfile, (char *) dest, offset);
+ pdf_release_obj(fontfile);
+ RELEASE(dest);
+ }
+
+ return destlen;
+}
+
+static void
+CIDFont_type0_add_CIDSet (pdf_font *font, char *used_chars, card16 last_cid) {
+ /*
+ * CIDSet:
+ * Length of CIDSet stream is not clear. Must be 8192 bytes long?
+ */
+ pdf_obj *cidset;
+
+ cidset = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_stream(cidset, used_chars, (last_cid / 8) + 1);
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
+ pdf_release_obj(cidset);
+}
+
+int
+CIDFont_type0_dofont (pdf_font *font)
+{
+ FILE *fp;
+ sfnt *sfont;
+ cff_font *cffont;
+ cff_index *charstrings, *idx;
+ cff_charsets *charset = NULL;
+ cff_fdselect *fdselect = NULL;
+ int charstring_len, max_len;
+ int destlen = 0;
+ int size, offset = 0;
+ card8 *data;
+ card16 num_glyphs = 0, gid;
+ int cid;
+ card16 cs_count, last_cid = 0;
+ int fd, prev_fd;
+ char *used_chars;
+ unsigned char *CIDToGIDMap = NULL;
+
+ ASSERT(font);
+
+ if (!font->reference)
+ return 0;
+
+ pdf_add_dict(font->resource,
+ pdf_new_name("FontDescriptor"),
+ pdf_ref_obj (font->descriptor));
+
+ if (font->flags & PDF_FONT_FLAG_BASEFONT) {
+ return 0;
+ } else if (!font->cid.options.embed &&
+ (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH)) {
+ /* No metrics needed. */
+ pdf_add_dict(font->resource,
+ pdf_new_name("DW"), pdf_new_number(1000.0));
+ return 0;
+ }
+
+ used_chars = font->usedchars;
+
+ fp = DPXFOPEN(font->filename, DPX_RES_TYPE_OTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(font->filename, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ WARN("Could not open file: %s", font->filename);
+ return -1;
+ }
+ }
+
+ sfont = sfnt_open(fp);
+ if (!sfont) {
+ WARN("Failed to read font file: %s", font->filename);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (sfont->type == SFNT_TYPE_TTC)
+ offset = ttc_read_offset(sfont, font->index);
+
+ if ((sfont->type != SFNT_TYPE_TTC &&
+ sfont->type != SFNT_TYPE_POSTSCRIPT) ||
+ sfnt_read_table_directory(sfont, offset) < 0 ||
+ (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
+ WARN("Not a CFF/OpenType font: %s", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ cffont = cff_open(sfont->stream, offset, 0);
+ if (!cffont) {
+ WARN("Failed to read CFF font data: %s", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (!(cffont->flag & FONTTYPE_CIDFONT)) {
+ WARN("Unexpected type (CIDFont expected): %s", font->filename);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ cff_read_charsets(cffont);
+
+ {
+ int cid_count;
+
+ if (cff_dict_known(cffont->topdict, "CIDCount")) {
+ cid_count = (int) cff_dict_get(cffont->topdict, "CIDCount", 0);
+ } else {
+ cid_count = CID_MAX + 1;
+ }
+
+ CIDToGIDMap = NEW(2 * cid_count, unsigned char);
+ memset(CIDToGIDMap, 0, 2 * cid_count);
+ add_to_used_chars2(used_chars, 0); /* .notdef */
+ for (cid = 0; cid <= CID_MAX; cid++) {
+ if (is_used_char2(used_chars, cid)) {
+ gid = cff_charsets_lookup(cffont, (card16)cid);
+ if (cid != 0 && gid == 0) {
+ WARN("Glyph for CID %u missing in font \"%s\".", (CID) cid, font->filename);
+ used_chars[cid/8] &= ~(1 << (7 - (cid % 8)));
+ continue;
+ }
+ CIDToGIDMap[2*cid] = (gid >> 8) & 0xff;
+ CIDToGIDMap[2*cid+1] = gid & 0xff;
+ last_cid = cid;
+ num_glyphs++;
+ }
+ }
+ }
+
+ /*
+ * DW, W, DW2 and W2:
+ * Those values are obtained from OpenType table (not TFM).
+ */
+ if (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH) {
+ pdf_add_dict(font->resource,
+ pdf_new_name("DW"), pdf_new_number(1000.0));
+ } else {
+ add_CIDMetrics(sfont, font->resource, CIDToGIDMap, last_cid,
+ font->cid.need_vmetrics ? 1 : 0);
+ }
+
+ if (!font->cid.options.embed) {
+ RELEASE(CIDToGIDMap);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return 0;
+ }
+
+ /*
+ * Embed font subset.
+ */
+ cff_read_fdselect(cffont);
+ cff_read_fdarray(cffont);
+ cff_read_private(cffont);
+
+ cff_read_subrs(cffont);
+
+ offset = (int) cff_dict_get(cffont->topdict, "CharStrings", 0);
+ cff_seek_set(cffont, offset);
+ idx = cff_get_index_header(cffont);
+ /* offset is now absolute offset ... bad */
+ offset = cff_tell(cffont);
+
+ if ((cs_count = idx->count) < 2) {
+ WARN("No valid charstring data found: %s", font->filename);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ /* New Charsets data */
+ charset = NEW(1, cff_charsets);
+ charset->format = 0;
+ charset->num_entries = 0;
+ charset->data.glyphs = NEW(num_glyphs, s_SID);
+
+ /* New FDSelect data */
+ fdselect = NEW(1, cff_fdselect);
+ fdselect->format = 3;
+ fdselect->num_entries = 0;
+ fdselect->data.ranges = NEW(num_glyphs, cff_range3);
+
+ /* New CharStrings INDEX */
+ charstrings = cff_new_index((card16)(num_glyphs+1));
+ max_len = 2 * CS_STR_LEN_MAX;
+ charstrings->data = NEW(max_len, card8);
+ charstring_len = 0;
+
+ /*
+ * TODO: Re-assign FD number.
+ */
+ prev_fd = -1; gid = 0;
+ data = NEW(CS_STR_LEN_MAX, card8);
+ for (cid = 0; cid <= last_cid; cid++) {
+ unsigned short gid_org;
+
+ if (!is_used_char2(used_chars, cid))
+ continue;
+
+ gid_org = (CIDToGIDMap[2*cid] << 8)|(CIDToGIDMap[2*cid+1]);
+ if ((size = (idx->offset)[gid_org+1] - (idx->offset)[gid_org])
+ > CS_STR_LEN_MAX) {
+ WARN("Charstring too long: %s (gid=%u)", font->filename, gid_org);
+ RELEASE(data);
+ RELEASE(charstrings);
+ RELEASE(fdselect);
+ RELEASE(charset);
+ cff_release_index(idx);
+ RELEASE(CIDToGIDMap);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ if (charstring_len + CS_STR_LEN_MAX >= max_len) {
+ max_len = charstring_len + 2 * CS_STR_LEN_MAX;
+ charstrings->data = RENEW(charstrings->data, max_len, card8);
+ }
+ (charstrings->offset)[gid] = charstring_len + 1;
+ cff_seek(cffont, offset + (idx->offset)[gid_org] - 1);
+ cff_read_data(data, size, cffont);
+ fd = cff_fdselect_lookup(cffont, gid_org);
+ charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
+ max_len - charstring_len,
+ data, size,
+ cffont->gsubr, (cffont->subrs)[fd], 0, 0, NULL);
+ if (cid > 0 && gid_org > 0) {
+ charset->data.glyphs[charset->num_entries] = cid;
+ charset->num_entries += 1;
+ }
+ if (fd != prev_fd) {
+ fdselect->data.ranges[fdselect->num_entries].first = gid;
+ fdselect->data.ranges[fdselect->num_entries].fd = fd;
+ fdselect->num_entries += 1;
+ prev_fd = fd;
+ }
+ gid++;
+ }
+ if (gid != num_glyphs) {
+ WARN("Unexpeced error: %s", font->filename);
+ RELEASE(data);
+ RELEASE(charstrings);
+ RELEASE(fdselect);
+ RELEASE(charset);
+ cff_release_index(idx);
+ RELEASE(CIDToGIDMap);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ RELEASE(data);
+ cff_release_index(idx);
+
+ RELEASE(CIDToGIDMap);
+
+ (charstrings->offset)[num_glyphs] = charstring_len + 1;
+ charstrings->count = num_glyphs;
+ cffont->num_glyphs = num_glyphs;
+ cffont->cstrings = charstrings;
+
+ /* discard old one, set new data */
+ cff_release_charsets(cffont->charsets);
+ cffont->charsets = charset;
+ cff_release_fdselect(cffont->fdselect);
+ cffont->fdselect = fdselect;
+
+ /* no Global subr */
+ if (cffont->gsubr)
+ cff_release_index(cffont->gsubr);
+ cffont->gsubr = cff_new_index(0);
+
+ for (fd = 0; fd < cffont->num_fds; fd++) {
+ if (cffont->subrs && cffont->subrs[fd]) {
+ cff_release_index(cffont->subrs[fd]);
+ cffont->subrs[fd] = NULL;
+ }
+ if (cffont->private && (cffont->private)[fd]) {
+ cff_dict_remove((cffont->private)[fd], "Subrs"); /* no Subrs */
+ }
+ }
+
+ destlen = write_fontfile(font, cffont);
+
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen);
+
+ if (pdf_check_version(2, 0) < 0) {
+ CIDFont_type0_add_CIDSet(font, used_chars, last_cid);
+ }
+
+ return 0;
+}
+
+int
+CIDFont_type0_open_from_t1 (pdf_font *font, const char *name, int index, cid_opt *opt)
+{
+ CIDSysInfo csi;
+ char *fontname;
+ cff_font *cffont;
+ FILE *fp = NULL;
+
+ ASSERT(font);
+
+ fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT);
+ if (!fp)
+ return -1;
+
+ cffont = t1_load_font(NULL, 1, fp);
+ if (!cffont) {
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ {
+ char *shortname;
+ int fontname_len = 8;
+
+ shortname = cff_get_name(cffont);
+ if (!shortname) {
+ WARN("No valid FontName found: %s", name);
+ cff_close(cffont);
+ DPXFCLOSE(fp);
+ }
+ /*
+ * Mangled name requires more 7 bytes.
+ */
+ fontname = NEW(strlen(shortname) + fontname_len, char);
+ memset(fontname, 0, strlen(shortname) + fontname_len);
+ strcpy(fontname, shortname);
+ RELEASE(shortname);
+ }
+
+ csi.registry = NEW(strlen("Adobe") + 1, char);
+ strcpy(csi.registry, "Adobe");
+ csi.ordering = NEW(strlen("Identity") + 1, char);
+ strcpy(csi.ordering, "Identity");
+ csi.supplement = 0;
+ if (opt->style != FONT_STYLE_NONE) {
+ WARN(",Bold, ,Italic, ... not supported for this type of font...");
+ opt->style = FONT_STYLE_NONE;
+ }
+
+ font->fontname = fontname;
+ font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0;
+ font->cid.csi = csi;
+ font->flags |= CIDFONT_FLAG_TYPE1;
+
+ font->resource = pdf_new_dict();
+ pdf_add_dict(font->resource,
+ pdf_new_name("Type"),
+ pdf_new_name("Font"));
+ pdf_add_dict(font->resource,
+ pdf_new_name("Subtype"),
+ pdf_new_name("CIDFontType0"));
+
+ pdf_font_make_uniqueTag(font->uniqueID);
+
+ font->descriptor = pdf_new_dict();
+ {
+ char *tmp;
+
+ tmp = NEW(strlen(font->fontname)+8, char);
+ sprintf(tmp, "%s+%s", font->uniqueID, font->fontname);
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(tmp));
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(tmp));
+ RELEASE(tmp);
+ }
+ {
+ pdf_obj *csi_dict = pdf_new_dict();
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Registry"),
+ pdf_new_string(csi.registry, strlen(csi.registry)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Ordering"),
+ pdf_new_string(csi.ordering, strlen(csi.ordering)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Supplement"),
+ pdf_new_number(csi.supplement));
+ pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), csi_dict);
+ }
+
+ return 0;
+}
+
+int
+CIDFont_type0_open (pdf_font *font, const char *name, int index, cid_opt *opt)
+{
+ CIDSysInfo csi;
+ char *fontname;
+ sfnt *sfont = NULL;
+ cff_font *cffont;
+ FILE *fp = NULL;
+ ULONG offset = 0;
+
+ ASSERT(font);
+
+ fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT);
+ if (!fp) return -1;
+ }
+
+ sfont = sfnt_open(fp);
+ if (!sfont) {
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (sfont->type == SFNT_TYPE_TTC)
+ offset = ttc_read_offset(sfont, index);
+
+ if ((sfont->type != SFNT_TYPE_TTC && sfont->type != SFNT_TYPE_POSTSCRIPT) ||
+ sfnt_read_table_directory(sfont, offset) < 0 ||
+ (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ cffont = cff_open(sfont->stream, offset, 0);
+ if (!cffont) {
+ WARN("Cannot read CFF font data");
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (!(cffont->flag & FONTTYPE_CIDFONT)) {
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ {
+ char *shortname;
+ int fontname_len = 8;
+
+ shortname = cff_get_name(cffont);
+ if (!shortname) {
+ WARN("No valid FontName found.");
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ /*
+ * Mangled name requires more 7 bytes.
+ * Style requires more 11 bytes.
+ */
+ fontname_len += 11;
+ fontname = NEW(strlen(shortname) + fontname_len, char);
+ memset(fontname, 0, strlen(shortname) + fontname_len);
+ strcpy(fontname, shortname);
+ RELEASE(shortname);
+ }
+ csi.registry = cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 0));
+ csi.ordering = cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 1));
+ csi.supplement = (int)cff_dict_get(cffont->topdict, "ROS", 2);
+
+ cff_close(cffont);
+
+ if (opt->embed && opt->style != FONT_STYLE_NONE) {
+ WARN("Embedding disabled due to style option for %s.", name);
+ opt->embed = 0;
+
+ switch (opt->style) {
+ case FONT_STYLE_BOLD:
+ strcat(fontname, ",Bold");
+ break;
+ case FONT_STYLE_ITALIC:
+ strcat(fontname, ",Italic");
+ break;
+ case FONT_STYLE_BOLDITALIC:
+ strcat(fontname, ",BoldItalic");
+ break;
+ }
+ }
+
+ /* getting font info. from TrueType tables */
+ font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name);
+ if (!font->descriptor) {
+ WARN("Could not obtain necessary font info: %s", name);
+ RELEASE(fontname);
+ RELEASE(csi.registry);
+ RELEASE(csi.ordering);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ font->fontname = fontname;
+ font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0;
+ font->cid.csi = csi;
+
+ font->resource = pdf_new_dict();
+ pdf_add_dict(font->resource,
+ pdf_new_name("Type"),
+ pdf_new_name("Font"));
+ pdf_add_dict(font->resource,
+ pdf_new_name("Subtype"),
+ pdf_new_name("CIDFontType0"));
+
+ if (opt->embed) {
+ char *tmp;
+
+ tmp = NEW(strlen(font->fontname)+8, char);
+ pdf_font_make_uniqueTag(font->uniqueID);
+ sprintf(tmp, "%s+%s", font->uniqueID, font->fontname);
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(tmp));
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(tmp));
+ RELEASE(tmp);
+ } else {
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(font->fontname));
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
+ }
+ {
+ pdf_obj *csi_dict = pdf_new_dict();
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Registry"),
+ pdf_new_string(csi.registry, strlen(csi.registry)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Ordering"),
+ pdf_new_string(csi.ordering, strlen(csi.ordering)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Supplement"),
+ pdf_new_number(csi.supplement));
+ pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), csi_dict);
+ }
+ pdf_add_dict(font->resource,
+ pdf_new_name("DW"),
+ pdf_new_number(1000)); /* not sure */
+
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ return 0;
+}
+
+int
+CIDFont_type0_open_from_t1c (pdf_font *font, const char *name, int index, cid_opt *opt)
+{
+ CIDSysInfo csi;
+ char *fontname;
+ sfnt *sfont = NULL;
+ cff_font *cffont;
+ FILE *fp = NULL;
+ ULONG offset = 0;
+
+ ASSERT(font);
+
+ fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT);
+ if (!fp) return -1;
+ }
+
+ sfont = sfnt_open(fp);
+ if (!sfont) {
+ WARN("Not a CFF/OpenType font: %s", name);
+ DPXFCLOSE(fp);
+ }
+
+ if (sfont->type == SFNT_TYPE_TTC)
+ offset = ttc_read_offset(sfont, index);
+
+ if ((sfont->type != SFNT_TYPE_TTC && sfont->type != SFNT_TYPE_POSTSCRIPT) ||
+ sfnt_read_table_directory(sfont, offset) < 0 ||
+ (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ cffont = cff_open(sfont->stream, offset, 0);
+ if (!cffont) {
+ WARN("Cannot read CFF font data: %s", name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (cffont->flag & FONTTYPE_CIDFONT) {
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ {
+ char *shortname;
+ int fontname_len = 8;
+
+ shortname = cff_get_name(cffont);
+ if (!shortname) {
+ WARN("No valid FontName found: %s", name);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ /*
+ * Mangled name requires more 7 bytes.
+ */
+ fontname = NEW(strlen(shortname) + fontname_len, char);
+ memset(fontname, 0, strlen(shortname) + fontname_len);
+ strcpy(fontname, shortname);
+ RELEASE(shortname);
+ }
+ csi.registry = NEW(strlen("Adobe") + 1, char);
+ strcpy(csi.registry, "Adobe");
+ csi.ordering = NEW(strlen("Identity") + 1, char);
+ strcpy(csi.ordering, "Identity");
+ csi.supplement = 0;
+
+ cff_close(cffont);
+
+ opt->embed = 1;
+ /* getting font info. from TrueType tables */
+ font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name);
+ if (!font->descriptor) {
+ WARN("Could not obtain necessary font info: %s", name);
+ RELEASE(fontname);
+ RELEASE(csi.registry);
+ RELEASE(csi.ordering);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ } else if (!opt->embed) {
+ WARN("Can’t embed font due to font license: %s", name);
+ RELEASE(fontname);
+ RELEASE(csi.registry);
+ RELEASE(csi.ordering);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ font->fontname = fontname;
+ font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0;
+ font->cid.csi = csi;
+ font->flags |= CIDFONT_FLAG_TYPE1C;
+
+ font->resource = pdf_new_dict();
+ pdf_add_dict(font->resource,
+ pdf_new_name("Type"),
+ pdf_new_name("Font"));
+ pdf_add_dict(font->resource,
+ pdf_new_name("Subtype"),
+ pdf_new_name("CIDFontType0"));
+
+ if (opt->embed) {
+ char *tmp;
+
+ tmp = NEW(strlen(font->fontname)+8, char);
+ pdf_font_make_uniqueTag(font->uniqueID);
+ sprintf(tmp, "%s+%s", font->uniqueID, font->fontname);
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(tmp));
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(tmp));
+ RELEASE(tmp);
+ } else {
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(font->fontname));
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
+ }
+ {
+ pdf_obj *csi_dict = pdf_new_dict();
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Registry"),
+ pdf_new_string(csi.registry, strlen(csi.registry)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Ordering"),
+ pdf_new_string(csi.ordering, strlen(csi.ordering)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Supplement"),
+ pdf_new_number(csi.supplement));
+ pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), csi_dict);
+ }
+
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ return 0;
+}
+
+int
+CIDFont_type0_t1cdofont (pdf_font *font)
+{
+ FILE *fp;
+ sfnt *sfont;
+ cff_font *cffont;
+ cff_index *charstrings, *idx;
+ int charstring_len, max_len;
+ int destlen = 0;
+ int size, offset = 0;
+ card8 *data;
+ card16 num_glyphs, gid, last_cid;
+ int i, cid;
+ char *used_chars;
+ double default_width, nominal_width;
+
+ ASSERT(font);
+
+ if (!font->reference)
+ return 0;
+
+ pdf_add_dict(font->resource,
+ pdf_new_name("FontDescriptor"),
+ pdf_ref_obj (font->descriptor));
+
+ used_chars = font->usedchars;
+
+ fp = DPXFOPEN(font->filename, DPX_RES_TYPE_OTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(font->filename, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ WARN("Could not open file: %s", font->filename);
+ return -1;
+ }
+ }
+
+ sfont = sfnt_open(fp);
+ if (!sfont) {
+ WARN("Failed to read font data: %s", font->filename);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (sfont->type == SFNT_TYPE_TTC)
+ offset = ttc_read_offset(sfont, font->index);
+
+ if ((sfont->type != SFNT_TYPE_TTC &&
+ sfont->type != SFNT_TYPE_POSTSCRIPT) ||
+ sfnt_read_table_directory(sfont, offset) < 0 ||
+ (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
+ WARN("Not a CFF/OpenType font: %s", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ cffont = cff_open(sfont->stream, offset, 0);
+ if (!cffont) {
+ WARN("Failed to read CFF font data: %s", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (cffont->flag & FONTTYPE_CIDFONT) {
+ WARN("Unxpected type (CIDFont) found: %s", font->filename);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ cff_read_private(cffont);
+ cff_read_subrs (cffont);
+
+ if (cffont->private[0] && cff_dict_known(cffont->private[0], "StdVW")) {
+ double stemv;
+ stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("StemV"), pdf_new_number(stemv));
+ }
+ if (cffont->private[0] && cff_dict_known(cffont->private[0], "defaultWidthX")) {
+ default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0);
+ } else {
+ default_width = CFF_DEFAULTWIDTHX_DEFAULT;
+ }
+ if (cffont->private[0] && cff_dict_known(cffont->private[0], "nominalWidthX")) {
+ nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0);
+ } else {
+ nominal_width = CFF_NOMINALWIDTHX_DEFAULT;
+ }
+
+ num_glyphs = 0; last_cid = 0;
+ add_to_used_chars2(used_chars, 0); /* .notdef */
+ for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
+ int c, j;
+
+ c = used_chars[i];
+ for (j = 7; j >= 0; j--) {
+ if (c & (1 << j)) {
+ num_glyphs++;
+ last_cid = (i + 1) * 8 - j - 1;
+ }
+ }
+ }
+
+ {
+ cff_fdselect *fdselect;
+
+ fdselect = NEW(1, cff_fdselect);
+ fdselect->format = 3;
+ fdselect->num_entries = 1;
+ fdselect->data.ranges = NEW(1, cff_range3);
+ fdselect->data.ranges[0].first = 0;
+ fdselect->data.ranges[0].fd = 0;
+ cffont->fdselect = fdselect;
+ }
+
+ {
+ cff_charsets *charset;
+
+ charset = NEW(1, cff_charsets);
+ charset->format = 0;
+ charset->num_entries = num_glyphs-1;
+ charset->data.glyphs = NEW(num_glyphs-1, s_SID);
+
+ for (gid = 0, cid = 0; cid <= last_cid; cid++) {
+ if (is_used_char2(used_chars, cid)) {
+ if (gid > 0)
+ charset->data.glyphs[gid-1] = cid;
+ gid++;
+ }
+ }
+ /* cff_release_charsets(cffont->charsets); */
+ cffont->charsets = charset;
+ }
+
+ cff_dict_add(cffont->topdict, "CIDCount", 1);
+ cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
+
+ cffont->fdarray = NEW(1, cff_dict *);
+ cffont->fdarray[0] = cff_new_dict();
+ cff_dict_add(cffont->fdarray[0], "FontName", 1);
+ cff_dict_set(cffont->fdarray[0], "FontName", 0,
+ (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
+ cff_dict_add(cffont->fdarray[0], "Private", 2);
+ cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
+ cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
+ /* FDArray - index offset, not known yet */
+ cff_dict_add(cffont->topdict, "FDArray", 1);
+ cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
+ /* FDSelect - offset, not known yet */
+ cff_dict_add(cffont->topdict, "FDSelect", 1);
+ cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);
+
+ cff_dict_remove(cffont->topdict, "UniqueID");
+ cff_dict_remove(cffont->topdict, "XUID");
+ cff_dict_remove(cffont->topdict, "Private");
+ cff_dict_remove(cffont->topdict, "Encoding");
+
+
+ /* */
+ offset = (int) cff_dict_get(cffont->topdict, "CharStrings", 0);
+ cff_seek_set(cffont, offset);
+ idx = cff_get_index_header(cffont);
+ /* offset is now absolute offset ... bad */
+ offset = cff_tell(cffont);
+
+ if (idx->count < 2) {
+ WARN("No valid charstring data found: %s", font->filename);
+ cff_release_index(idx);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ /* New CharStrings INDEX */
+ charstrings = cff_new_index((card16)(num_glyphs+1));
+ max_len = 2 * CS_STR_LEN_MAX;
+ charstrings->data = NEW(max_len, card8);
+ charstring_len = 0;
+
+ gid = 0;
+ data = NEW(CS_STR_LEN_MAX, card8);
+ for (cid = 0; cid <= last_cid; cid++) {
+ if (!is_used_char2(used_chars, cid))
+ continue;
+
+ if ((size = (idx->offset)[cid+1] - (idx->offset)[cid])
+ > CS_STR_LEN_MAX) {
+ WARN("Charstring too long:%s (gid=%u)", font->filename, cid);
+ RELEASE(data);
+ cff_release_index(charstrings);
+ cff_release_index(idx);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ if (charstring_len + CS_STR_LEN_MAX >= max_len) {
+ max_len = charstring_len + 2 * CS_STR_LEN_MAX;
+ charstrings->data = RENEW(charstrings->data, max_len, card8);
+ }
+ (charstrings->offset)[gid] = charstring_len + 1;
+ cff_seek(cffont, offset + (idx->offset)[cid] - 1);
+ cff_read_data(data, size, cffont);
+ charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
+ max_len - charstring_len,
+ data, size,
+ cffont->gsubr, (cffont->subrs)[0],
+ default_width, nominal_width, NULL);
+ gid++;
+ }
+ if (gid != num_glyphs) {
+ WARN("Unexpeced error: %s", font->filename);
+ RELEASE(data);
+ cff_release_index(charstrings);
+ cff_release_index(idx);
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ RELEASE(data);
+ cff_release_index(idx);
+
+ (charstrings->offset)[num_glyphs] = charstring_len + 1;
+ charstrings->count = num_glyphs;
+ cffont->num_glyphs = num_glyphs;
+ cffont->cstrings = charstrings;
+
+ /* no Global subr */
+ if (cffont->gsubr)
+ cff_release_index(cffont->gsubr);
+ cffont->gsubr = cff_new_index(0);
+
+ if (cffont->subrs && cffont->subrs[0]) {
+ cff_release_index(cffont->subrs[0]);
+ cffont->subrs[0] = NULL;
+ }
+ if (cffont->private && (cffont->private)[0]) {
+ cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */
+ }
+
+ cff_add_string(cffont, "Adobe", 1);
+ cff_add_string(cffont, "Identity", 1);
+
+ cff_dict_update(cffont->topdict, cffont);
+ cff_dict_update(cffont->private[0], cffont);
+ cff_update_string(cffont);
+
+ /* CFF code need to be rewrote... */
+ cff_dict_add(cffont->topdict, "ROS", 3);
+ cff_dict_set(cffont->topdict, "ROS", 0,
+ (double) cff_get_sid(cffont, "Adobe"));
+ cff_dict_set(cffont->topdict, "ROS", 1,
+ (double) cff_get_sid(cffont, "Identity"));
+ cff_dict_set(cffont->topdict, "ROS", 2, 0.0);
+
+ destlen = write_fontfile(font, cffont);
+
+ /*
+ * DW, W, DW2 and W2:
+ * Those values are obtained from OpenType table (not TFM).
+ */
+ {
+ unsigned char *CIDToGIDMap;
+
+ CIDToGIDMap = NEW(2 * (last_cid+1), unsigned char);
+ memset(CIDToGIDMap, 0, 2 * (last_cid + 1));
+ for (cid = 0; cid <= last_cid; cid++) {
+ if (is_used_char2(used_chars, cid)) {
+ CIDToGIDMap[2*cid ] = (cid >> 8) & 0xff;
+ CIDToGIDMap[2*cid+1] = cid & 0xff;
+ }
+ }
+ add_CIDMetrics(sfont, font->resource, CIDToGIDMap, last_cid,
+ font->cid.need_vmetrics ? 1 : 0);
+ RELEASE(CIDToGIDMap);
+ }
+
+ cff_close(cffont);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen);
+
+ if (pdf_check_version(2, 0) < 0) {
+ CIDFont_type0_add_CIDSet(font, used_chars, last_cid);
+ }
+
+ return 0;
+}
+
+static int
+load_base_CMap (const char *font_name, int wmode, cff_font *cffont)
+{
+ int cmap_id = -1;
+ CMap *cmap;
+ char *cmap_name;
+ card16 gid;
+ unsigned char range_min[4] = {0x00, 0x00, 0x00, 0x00};
+ unsigned char range_max[4] = {0x7f, 0xff, 0xff, 0xff};
+
+ cmap_name = NEW(strlen(font_name)+strlen("-UCS4-H")+1, char);
+ if (wmode) {
+ sprintf(cmap_name, "%s-UCS4-V", font_name);
+ } else {
+ sprintf(cmap_name, "%s-UCS4-H", font_name);
+ }
+
+ cmap_id = CMap_cache_find(cmap_name);
+ if (cmap_id >= 0) {
+ RELEASE(cmap_name);
+ return cmap_id;
+ }
+
+ cmap = CMap_new();
+ CMap_set_name (cmap, cmap_name);
+ CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID);
+ CMap_set_wmode(cmap, wmode);
+ CMap_add_codespacerange(cmap, range_min, range_max, 4);
+ CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY);
+ RELEASE(cmap_name);
+
+ for (gid = 1; gid < cffont->num_glyphs; gid++) {
+ int32_t ucv;
+ s_SID sid;
+ char *glyph, *name, *suffix;
+ unsigned char srcCode[4];
+
+ sid = cff_charsets_lookup_inverse(cffont, gid);
+ glyph = cff_get_string (cffont, sid);
+
+ name = agl_chop_suffix(glyph, &suffix);
+ if (!name) {
+ if (suffix)
+ RELEASE(suffix);
+ RELEASE(glyph);
+ continue;
+ }
+
+ if (suffix) {
+ RELEASE(name);
+ RELEASE(suffix);
+ RELEASE(glyph);
+ continue;
+ }
+
+ if (agl_name_is_unicode(name)) {
+ ucv = agl_name_convert_unicode(name);
+ srcCode[0] = (ucv >> 24) & 0xff;
+ srcCode[1] = (ucv >> 16) & 0xff;
+ srcCode[2] = (ucv >> 8) & 0xff;
+ srcCode[3] = ucv & 0xff;
+ CMap_add_cidchar(cmap, srcCode, 4, gid);
+ } else {
+ agl_name *agln;
+
+ agln = agl_lookup_list(name);
+ if (!agln)
+ WARN("Glyph \"%s\" inaccessible (no Unicode mapping)", glyph);
+ while (agln) {
+ if (agln->n_components > 1) {
+ WARN("Glyph \"%s\" inaccessible (composite character)", glyph);
+ } else if (agln->n_components == 1) {
+ ucv = agln->unicodes[0];
+ srcCode[0] = (ucv >> 24) & 0xff;
+ srcCode[1] = (ucv >> 16) & 0xff;
+ srcCode[2] = (ucv >> 8) & 0xff;
+ srcCode[3] = ucv & 0xff;
+ CMap_add_cidchar(cmap, srcCode, 4, gid);
+ }
+ agln = agln->alternate;
+ }
+ }
+ RELEASE(name);
+ if (suffix)
+ RELEASE(suffix);
+ RELEASE(glyph);
+ }
+ cmap_id = CMap_cache_add(cmap);
+
+ return cmap_id;
+}
+
+int
+t1_load_UnicodeCMap (const char *font_name,
+ const char *otl_tags, /* not supported yet */
+ int wmode)
+{
+ int cmap_id = -1;
+ cff_font *cffont;
+ FILE *fp;
+
+ if (!font_name)
+ return -1;
+
+ fp = DPXFOPEN(font_name, DPX_RES_TYPE_T1FONT);
+ if (!fp)
+ return -1;
+
+ cffont = t1_load_font(NULL, 1, fp);
+ DPXFCLOSE(fp);
+ if (!cffont)
+ return -1;
+
+ cmap_id = load_base_CMap(font_name, wmode, cffont);
+
+ cff_close(cffont);
+
+ if (cmap_id < 0) {
+ WARN("Failed to create Unicode charmap for font \"%s\".", font_name);
+ return -1;
+ }
+
+ if (otl_tags) {
+ WARN("Glyph substitution not supported for Type1 font yet...");
+ }
+
+ return cmap_id;
+}
+
+
+/*
+ * ToUnicode CMap
+ */
+
+static pdf_obj *
+create_ToUnicode_stream (cff_font *cffont,
+ const char *font_name, const char *used_glyphs)
+{
+ pdf_obj *stream = NULL;
+ CMap *cmap;
+ CID cid;
+ card16 gid;
+ int glyph_count, total_fail_count;
+ char *cmap_name;
+#define WBUF_SIZE 1024
+ unsigned char wbuf[WBUF_SIZE];
+ unsigned char *p, *endptr;
+ static unsigned char range_min[2] = {0x00, 0x00};
+ static unsigned char range_max[2] = {0xff, 0xff};
+
+ if (!font_name || !used_glyphs)
+ return NULL;
+
+ cmap = CMap_new();
+
+ cmap_name = NEW(strlen(font_name)+strlen("-UTF16")+1, char);
+ strcpy(cmap_name, font_name);
+ strcat(cmap_name, "-UTF16");
+ CMap_set_name (cmap, cmap_name);
+ RELEASE(cmap_name);
+
+ CMap_set_wmode(cmap, 0);
+ CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE);
+ CMap_set_CIDSysInfo(cmap, &CSI_UNICODE);
+
+ CMap_add_codespacerange(cmap, range_min, range_max, 2);
+
+ glyph_count = total_fail_count = 0;
+ p = wbuf;
+ endptr = wbuf + WBUF_SIZE;
+ for (cid = 1; cid < cffont->num_glyphs; cid++) { /* Skip .notdef */
+ if (is_used_char2(used_glyphs, cid)) {
+ char *glyph;
+ int32_t len;
+ int fail_count;
+
+ wbuf[0] = (cid >> 8) & 0xff;
+ wbuf[1] = (cid & 0xff);
+
+ p = wbuf + 2;
+ gid = cff_charsets_lookup_inverse(cffont, cid);
+ if (gid == 0)
+ continue;
+ glyph = cff_get_string(cffont, gid);
+ if (glyph) {
+ len = agl_sput_UTF16BE(glyph, &p, endptr, &fail_count);
+ if (len < 1 || fail_count) {
+ total_fail_count += fail_count;
+ } else {
+ CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, len);
+ }
+ RELEASE(glyph);
+ }
+ glyph_count++;
+ }
+ }
+
+ if (total_fail_count != 0 &&
+ total_fail_count >= glyph_count/10) {
+ WARN("%d glyph names (out of %d) missing Unicode mapping.",
+ total_fail_count, glyph_count);
+ WARN("ToUnicode CMap \"%s-UTF16\" removed.", font_name);
+ } else {
+ stream = CMap_create_stream(cmap);
+ }
+ CMap_release(cmap);
+
+ return stream;
+}
+
+pdf_obj *
+CIDFont_type0_t1create_ToUnicode_stream (const char *filename, const char *fontname, const char *used_chars)
+{
+ pdf_obj *ref = NULL;
+ pdf_obj *tounicode;
+ cff_font *cffont;
+ FILE *fp;
+
+ ASSERT(filename);
+ ASSERT(fontname);
+ ASSERT(used_chars);
+
+ fp = DPXFOPEN(filename, DPX_RES_TYPE_T1FONT);
+ if (!fp) {
+ return NULL;
+ }
+
+ cffont = t1_load_font(NULL, 1, fp);
+ if (cffont) {
+ tounicode = create_ToUnicode_stream(cffont, fontname, used_chars);
+ if (tounicode) {
+ ref = pdf_ref_obj(tounicode);
+ pdf_release_obj(tounicode);
+ }
+ }
+ DPXFCLOSE(fp);
+
+ return ref;
+}
+
+/* Duplicate from type1.c */
+#define TYPE1_NAME_LEN_MAX 127
+
+#define FONT_FLAG_FIXEDPITCH (1 << 0) /* Fixed-width font */
+#define FONT_FLAG_SERIF (1 << 1) /* Serif font */
+#define FONT_FLAG_SYMBOLIC (1 << 2) /* Symbolic font */
+#define FONT_FLAG_SCRIPT (1 << 3) /* Script font */
+#define FONT_FLAG_STANDARD (1 << 5) /* Adobe Standard Character Set */
+#define FONT_FLAG_ITALIC (1 << 6) /* Italic */
+#define FONT_FLAG_ALLCAP (1 << 16) /* All-cap font */
+#define FONT_FLAG_SMALLCAP (1 << 17) /* Small-cap font */
+#define FONT_FLAG_FORCEBOLD (1 << 18) /* Force bold at small text sizes */
+
+static void
+get_font_attr (pdf_font *font, cff_font *cffont)
+{
+ double capheight, ascent, descent;
+ double italicangle, stemv;
+ double defaultwidth, nominalwidth;
+ int flags = 0;
+ int gid;
+ int i;
+ static const char *L_c[] = {
+ "H", "P", "Pi", "Rho", NULL
+ };
+ static const char *L_d[] = {
+ "p", "q", "mu", "eta", NULL
+ };
+ static const char *L_a[] = {
+ "b", "h", "lambda", NULL
+ };
+ t1_ginfo gm;
+
+ defaultwidth = 500.0;
+ nominalwidth = 0.0;
+
+ /*
+ * CapHeight, Ascent, and Descent is meaningfull only for Latin/Greek/Cyrillic.
+ * The BlueValues and OtherBlues also have those information.
+ */
+ if (cff_dict_known(cffont->topdict, "FontBBox")) {
+ /* Default values */
+ capheight = ascent = cff_dict_get(cffont->topdict, "FontBBox", 3);
+ descent = cff_dict_get(cffont->topdict, "FontBBox", 1);
+ } else {
+ capheight = 680.0;
+ ascent = 690.0;
+ descent = -190.0;
+ }
+ if (cff_dict_known(cffont->private[0], "StdVW")) {
+ stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
+ } else {
+ /*
+ * We may use the following values for StemV:
+ * Thin - ExtraLight: <= 50
+ * Light: 71
+ * Regular(Normal): 88
+ * Medium: 109
+ * SemiBold(DemiBold): 135
+ * Bold - Heavy: >= 166
+ */
+ stemv = 88.0;
+ }
+ if (cff_dict_known(cffont->topdict, "ItalicAngle")) {
+ italicangle = cff_dict_get(cffont->topdict, "ItalicAngle", 0);
+ if (italicangle != 0.0)
+ flags |= FONT_FLAG_ITALIC;
+ } else {
+ italicangle = 0.0;
+ }
+
+ /*
+ * Use "space", "H", "p", and "b" for various values.
+ * Those characters should not "seac". (no accent)
+ */
+ gid = cff_glyph_lookup(cffont, "space");
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ defaultwidth = gm.wx;
+ }
+
+ for (i = 0; L_c[i] != NULL; i++) {
+ gid = cff_glyph_lookup(cffont, L_c[i]);
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ capheight = gm.bbox.ury;
+ break;
+ }
+ }
+
+ for (i = 0; L_d[i] != NULL; i++) {
+ gid = cff_glyph_lookup(cffont, L_d[i]);
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ descent = gm.bbox.lly;
+ break;
+ }
+ }
+
+ for (i = 0; L_a[i] != NULL; i++) {
+ gid = cff_glyph_lookup(cffont, L_a[i]);
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ ascent = gm.bbox.ury;
+ break;
+ }
+ }
+
+ if (defaultwidth != 0.0) {
+ cff_dict_add(cffont->private[0], "defaultWidthX", 1);
+ cff_dict_set(cffont->private[0], "defaultWidthX", 0, defaultwidth);
+ }
+ if (nominalwidth != 0.0) {
+ cff_dict_add(cffont->private[0], "nominalWidthX", 1);
+ cff_dict_set(cffont->private[0], "nominalWidthX", 0, nominalwidth);
+ }
+ if (cff_dict_known(cffont->private[0], "ForceBold") &&
+ cff_dict_get(cffont->private[0], "ForceBold", 0)) {
+ flags |= FONT_FLAG_FORCEBOLD;
+ }
+ if (cff_dict_known(cffont->private[0], "IsFixedPitch") &&
+ cff_dict_get(cffont->private[0], "IsFixedPitch", 0)) {
+ flags |= FONT_FLAG_FIXEDPITCH;
+ }
+ if (font->fontname &&
+ !strstr(font->fontname, "Sans")) {
+ flags |= FONT_FLAG_SERIF;
+ }
+ flags |= FONT_FLAG_SYMBOLIC;
+
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("CapHeight"), pdf_new_number(capheight));
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("Ascent"), pdf_new_number(ascent));
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("Descent"), pdf_new_number(descent));
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("ItalicAngle"), pdf_new_number(italicangle));
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("StemV"), pdf_new_number(stemv));
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("Flags"), pdf_new_number(flags));
+}
+
+static void
+add_metrics (pdf_font *font, cff_font *cffont,
+ unsigned char *CIDToGIDMap,
+ double *widths, double default_width, CID last_cid)
+{
+ pdf_obj *tmp;
+ double val;
+ card16 cid, gid;
+ char *used_chars;
+ int i;
+
+ /*
+ * The original FontBBox of the font is preserved, instead
+ * of replacing it with tight bounding box calculated from
+ * charstrings, to prevent Acrobat 4 from greeking text as
+ * much as possible.
+ */
+ if (!cff_dict_known(cffont->topdict, "FontBBox")) {
+ WARN("No FontBBox found: %s", font->filename);
+ } else {
+ tmp = pdf_new_array();
+ for (i = 0; i < 4; i++) {
+ val = cff_dict_get(cffont->topdict, "FontBBox", i);
+ pdf_add_array(tmp, pdf_new_number(ROUND(val, 1.0)));
+ }
+ pdf_add_dict(font->descriptor, pdf_new_name("FontBBox"), tmp);
+ }
+
+ used_chars = font->usedchars;
+
+ /* FIXME:
+ * This writes "CID CID width".
+ * I think it's better to handle each 8 char block
+ * and to use "CID_start [ w0 w1 ...]".
+ */
+ tmp = pdf_new_array();
+ for (cid = 0; cid <= last_cid; cid++) {
+ if (is_used_char2(used_chars, cid)) {
+ gid = (CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1];
+ if (widths[gid] != default_width) {
+ pdf_add_array(tmp, pdf_new_number(cid));
+ pdf_add_array(tmp, pdf_new_number(cid));
+ pdf_add_array(tmp, pdf_new_number(ROUND(widths[gid], 1.0)));
+ }
+ }
+ }
+ pdf_add_dict(font->resource,
+ pdf_new_name("DW"), pdf_new_number(default_width));
+ if (pdf_array_length(tmp) > 0) {
+ pdf_add_dict(font->resource, pdf_new_name("W"), pdf_ref_obj(tmp));
+ }
+ pdf_release_obj(tmp);
+}
+
+int
+CIDFont_type0_t1dofont (pdf_font *font)
+{
+ cff_font *cffont;
+ double defaultwidth, nominalwidth;
+ int num_glyphs = 0;
+ FILE *fp;
+ int i, offset;
+ char *used_chars = NULL;
+ card16 last_cid, gid, cid;
+ unsigned char *CIDToGIDMap;
+
+ ASSERT(font);
+
+ if (!font->reference) {
+ return 0;
+ }
+
+ pdf_add_dict(font->resource,
+ pdf_new_name("FontDescriptor"),
+ pdf_ref_obj (font->descriptor));
+
+ fp = DPXFOPEN(font->filename, DPX_RES_TYPE_T1FONT);
+ if (!fp) {
+ WARN("Type1: Could not open Type1 font.");
+ return -1;
+ }
+
+ cffont = t1_load_font(NULL, 0, fp);
+ if (!cffont) {
+ WARN("Could not read Type 1 font...");
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ DPXFCLOSE(fp);
+
+ ASSERT(font->fontname);
+ ASSERT(font->usedchars);
+
+ used_chars = font->usedchars;
+
+ cff_set_name(cffont, font->fontname);
+
+ /* defaultWidthX, CapHeight, etc. */
+ get_font_attr(font, cffont);
+ if (cff_dict_known(cffont->private[0], "defaultWidthX")) {
+ defaultwidth = cff_dict_get(cffont->private[0], "defaultWidthX", 0);
+ } else {
+ defaultwidth = 0.0;
+ }
+ if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
+ nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
+ } else {
+ nominalwidth = 0.0;
+ }
+
+ num_glyphs = 0; last_cid = 0;
+ add_to_used_chars2(used_chars, 0); /* .notdef */
+ for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
+ int c, j;
+
+ c = used_chars[i];
+ for (j = 7; j >= 0; j--) {
+ if (c & (1 << j)) {
+ num_glyphs++;
+ last_cid = (i + 1) * 8 - j - 1;
+ }
+ }
+ }
+
+ {
+ cff_fdselect *fdselect;
+
+ fdselect = NEW(1, cff_fdselect);
+ fdselect->format = 3;
+ fdselect->num_entries = 1;
+ fdselect->data.ranges = NEW(1, cff_range3);
+ fdselect->data.ranges[0].first = 0;
+ fdselect->data.ranges[0].fd = 0;
+ cffont->fdselect = fdselect;
+ }
+
+ CIDToGIDMap = NEW(2*(last_cid+1), unsigned char);
+ memset(CIDToGIDMap, 0, 2*(last_cid+1));
+ {
+ cff_charsets *charset;
+
+ charset = NEW(1, cff_charsets);
+ charset->format = 0;
+ charset->num_entries = num_glyphs-1;
+ charset->data.glyphs = NEW(num_glyphs-1, s_SID);
+
+ for (gid = 0, cid = 0; cid <= last_cid; cid++) {
+ if (is_used_char2(used_chars, cid)) {
+ if (gid > 0)
+ charset->data.glyphs[gid-1] = cid;
+ CIDToGIDMap[2*cid ] = (gid >> 8) & 0xff;
+ CIDToGIDMap[2*cid+1] = gid & 0xff;
+ gid++;
+ }
+ }
+
+ cff_release_charsets(cffont->charsets);
+ cffont->charsets = charset;
+ }
+
+ cff_dict_add(cffont->topdict, "CIDCount", 1);
+ cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
+
+ cffont->fdarray = NEW(1, cff_dict *);
+ cffont->fdarray[0] = cff_new_dict();
+ cff_dict_add(cffont->fdarray[0], "FontName", 1);
+ cff_dict_set(cffont->fdarray[0], "FontName", 0,
+ (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
+ cff_dict_add(cffont->fdarray[0], "Private", 2);
+ cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
+ cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
+
+ /* FDArray - index offset, not known yet */
+ cff_dict_add(cffont->topdict, "FDArray", 1);
+ cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
+ /* FDSelect - offset, not known yet */
+ cff_dict_add(cffont->topdict, "FDSelect", 1);
+ cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);
+
+ cff_dict_add(cffont->topdict, "charset", 1);
+ cff_dict_set(cffont->topdict, "charset", 0, 0.0);
+
+ cff_dict_add(cffont->topdict, "CharStrings", 1);
+ cff_dict_set(cffont->topdict, "CharStrings", 0, 0.0);
+
+ {
+ cff_index *cstring;
+ t1_ginfo gm;
+ int max = 0;
+ double *widths;
+ int w_stat[1001], max_count, dw;
+
+ widths = NEW(num_glyphs, double);
+ memset(w_stat, 0, sizeof(int)*1001);
+ offset = 0L;
+ cstring = cff_new_index((card16)num_glyphs);
+ cstring->data = NULL;
+ cstring->offset[0] = 1;
+ gid = 0;
+ for (cid = 0; cid <= last_cid; cid++) {
+ if (!is_used_char2(used_chars, cid))
+ continue;
+
+ if (offset + CS_STR_LEN_MAX >= max) {
+ max += CS_STR_LEN_MAX*2;
+ cstring->data = RENEW(cstring->data, max, card8);
+ }
+ offset += t1char_convert_charstring(cstring->data + cstring->offset[gid] - 1, CS_STR_LEN_MAX,
+ cffont->cstrings->data + cffont->cstrings->offset[cid] - 1,
+ cffont->cstrings->offset[cid+1] - cffont->cstrings->offset[cid],
+ cffont->subrs[0], defaultwidth, nominalwidth, &gm);
+ cstring->offset[gid+1] = offset + 1;
+ if (gm.use_seac) {
+ WARN("The \"seac\" command for an accented character found: %s", font->filename);
+ RELEASE(widths);
+ cff_release_index(cstring);
+ RELEASE(CIDToGIDMap);
+ cff_close(cffont);
+ return -1;
+ }
+ widths[gid] = gm.wx;
+ if (gm.wx >= 0.0 && gm.wx <= 1000.0) {
+ w_stat[((int) gm.wx)] += 1;
+ }
+ gid++;
+ }
+
+ cff_release_index(cffont->cstrings);
+ cffont->cstrings = cstring;
+
+ max_count = 0; dw = -1;
+ for (i = 0; i <= 1000; i++) {
+ if (w_stat[i] > max_count) {
+ dw = i;
+ max_count = w_stat[i];
+ }
+ }
+ if (dw >= 0) {
+ add_metrics(font, cffont, CIDToGIDMap, widths, dw, last_cid);
+ } else {
+ add_metrics(font, cffont, CIDToGIDMap, widths, defaultwidth, last_cid);
+ }
+ RELEASE(widths);
+ }
+ cff_release_index(cffont->subrs[0]);
+ cffont->subrs[0] = NULL;
+
+ RELEASE(CIDToGIDMap);
+
+ cff_add_string(cffont, "Adobe", 1);
+ cff_add_string(cffont, "Identity", 1);
+
+ cff_dict_update(cffont->topdict, cffont);
+ cff_dict_update(cffont->private[0], cffont);
+
+ cff_update_string(cffont);
+
+ /* CFF code need to be rewrote... */
+ cff_dict_add(cffont->topdict, "ROS", 3);
+ cff_dict_set(cffont->topdict, "ROS", 0,
+ (double) cff_get_sid(cffont, "Adobe"));
+ cff_dict_set(cffont->topdict, "ROS", 1,
+ (double) cff_get_sid(cffont, "Identity"));
+ cff_dict_set(cffont->topdict, "ROS", 2, 0.0);
+
+ cffont->num_glyphs = num_glyphs;
+ offset = write_fontfile(font, cffont);
+
+ cff_close(cffont);
+
+ if (pdf_check_version(2, 0) < 0) {
+ CIDFont_type0_add_CIDSet(font, used_chars, last_cid);
+ }
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/cidtype0.h b/Build/source/texk/dvipdfm-x/cidtype0.h
new file mode 100644
index 00000000000..c4faa24486c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cidtype0.h
@@ -0,0 +1,38 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CIDTYPE0_H_
+#define _CIDTYPE0_H_
+
+#include "pdffont.h"
+
+extern int CIDFont_type0_open (pdf_font *font, const char *name, int index, cid_opt *opt);
+extern int CIDFont_type0_dofont (pdf_font *font);
+
+/* Type1 --> CFF CIDFont */
+extern int t1_load_UnicodeCMap (const char *font_name, const char *otl_tags, int wmode);
+extern int CIDFont_type0_open_from_t1 (pdf_font *font, const char *name, int index, cid_opt *opt);
+extern int CIDFont_type0_open_from_t1c (pdf_font *font, const char *name, int index, cid_opt *opt);
+extern int CIDFont_type0_t1dofont (pdf_font *font);
+extern int CIDFont_type0_t1cdofont (pdf_font *font);
+
+extern pdf_obj *CIDFont_type0_t1create_ToUnicode_stream (const char *filename, const char *fontname, const char *used_chars);
+
+#endif /* _CIDTYPE0_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cidtype2.c b/Build/source/texk/dvipdfm-x/cidtype2.c
new file mode 100644
index 00000000000..11554b47780
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cidtype2.c
@@ -0,0 +1,1181 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * TrueType glyf table is sorted by CID and no CIDToGIDMap is used here.
+ * GhostScript can't handle CIDToGIDMap correctly.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "numbers.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxfile.h"
+
+#include "unicode.h"
+
+#include "pdfobj.h"
+/* pseudo unique tag */
+#include "pdffont.h"
+
+#ifndef PDF_NAME_LEN_MAX
+# define PDF_NAME_LEN_MAX 255
+#endif
+
+/* TrueType */
+#include "sfnt.h"
+#include "tt_aux.h"
+#include "tt_glyf.h"
+#include "tt_cmap.h"
+#include "tt_table.h"
+
+#include "tt_gsub.h"
+
+/* CID font */
+#include "cmap.h"
+#include "type0.h"
+#include "cid.h"
+#include "cidtype2.h"
+
+/*
+ * PDF viewer applications use following tables (CIDFontType 2)
+ *
+ * head, hhea, loca, maxp, glyf, hmtx, fpgm, cvt_, prep
+ *
+ * - from PDF Ref. v.1.3, 2nd ed.
+ *
+ * The fpgm, cvt_, and prep tables appears only when TrueType instructions
+ * requires them. Those tables must be preserved if they exist.
+ * We use must_exist flag to indicate `preserve it if present'
+ * and to make sure not to cause an error when it does not exist.
+ *
+ * post and name table must exist in ordinary TrueType font file,
+ * but when a TrueType font is converted to CIDFontType 2 font, those tables
+ * are no longer required.
+ *
+ * The OS/2 table (required for TrueType font for Windows and OS/2) contains
+ * liscencing information, but PDF viewers seems not using them.
+ *
+ * The 'name' table added. See comments in ttf.c.
+ */
+
+static struct
+{
+ const char *name;
+ int must_exist;
+} required_table[] = {
+ {"OS/2", 0}, {"head", 1}, {"hhea", 1}, {"loca", 1}, {"maxp", 1},
+ {"name", 1}, {"glyf", 1}, {"hmtx", 1}, {"fpgm", 0}, {"cvt ", 0},
+ {"prep", 0}, {NULL, 0}
+};
+
+static int
+validate_name (char *fontname, int len)
+{
+ int i, count;
+ char *p;
+ static const char *badstrlist[] = {
+ "-WIN-RKSJ-H",
+ "-WINP-RKSJ-H",
+ "-WING-RKSJ-H",
+ "-90pv-RKSJ-H",
+ NULL
+ };
+
+ for (count = 0, i = 0; i < len; i++) {
+ if (fontname[i] == 0) {
+ memmove(fontname + i, fontname + i + 1, len - i);
+ count++;
+ len--;
+ }
+ }
+ if (count > 0) {
+ WARN("Removed %d null character(s) from fontname --> %s",
+ count, fontname);
+ }
+ fontname[len] = '\0';
+
+ /* For some fonts that have bad PS name. ad hoc. remove me. */
+ for (i = 0; badstrlist[i] != NULL; i++) {
+ p = strstr(fontname, badstrlist[i]);
+ if (p && p > fontname) {
+ WARN("Removed string \"%s\" from fontname \"%s\".",
+ badstrlist[i], fontname);
+ p[0] = '\0';
+ len = (int) (p - fontname);
+ break;
+ }
+ }
+
+ if (len < 1) {
+ WARN("No valid character found in fontname string.");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * We will follow the convension for finding ToUnicode CMap described in PDF
+ * Reference 4th ed., page 432. The name of "ToCode" (not limited to Unicode
+ * here) CMap is obtained by concatenating the registry, ordering, and the
+ * name of encoding.
+ *
+ * UCSms-UCS4, UCSms-UCS2, UCS4 added...
+ */
+
+#define WIN_UCS_INDEX_MAX 1
+#define KNOWN_ENCODINGS_MAX 9
+static struct
+{
+ unsigned short platform;
+ unsigned short encoding;
+ const char *pdfnames[5];
+} known_encodings[] = {
+ {TT_WIN, TT_WIN_UCS4, {"UCSms-UCS4", "UCSms-UCS2", "UCS4", "UCS2", NULL}},
+ {TT_WIN, TT_WIN_UNICODE, {"UCSms-UCS4", "UCSms-UCS2", "UCS4", "UCS2", NULL}},
+ {TT_WIN, TT_WIN_SJIS, {"90ms-RKSJ", NULL}},
+ {TT_WIN, TT_WIN_RPC, {"GBK-EUC", NULL}},
+ {TT_WIN, TT_WIN_BIG5, {"ETen-B5", NULL}},
+ {TT_WIN, TT_WIN_WANSUNG, {"KSCms-UHC", NULL}},
+ {TT_MAC, TT_MAC_JAPANESE, {"90pv-RKSJ", NULL}},
+ {TT_MAC, TT_MAC_TRADITIONAL_CHINESE, {"B5pc", NULL}},
+ {TT_MAC, TT_MAC_SIMPLIFIED_CHINESE, {"GBpc-EUC", NULL}},
+ {TT_MAC, TT_MAC_KOREAN, {"KSCpc-EUC", NULL}},
+ {0, 0, {NULL}}
+};
+
+static CMap *
+find_tocode_cmap (const char *reg, const char *ord, int select)
+{
+ int cmap_id = -1, i;
+ char *cmap_name;
+ const char *append;
+
+ if (!reg || !ord ||
+ select < 0 || select > KNOWN_ENCODINGS_MAX) {
+ WARN("Character set unknown.");
+ return NULL;
+ }
+
+ for (i = 0; cmap_id < 0 && i < 5; i++) {
+ append = known_encodings[select].pdfnames[i];
+ if (!append)
+ break;
+ cmap_name = NEW(strlen(reg) + strlen(ord) + strlen(append) + 3, char);
+ sprintf(cmap_name, "%s-%s-%s", reg, ord, append);
+ cmap_id = CMap_cache_find(cmap_name);
+ RELEASE(cmap_name);
+ }
+ if (cmap_id < 0) {
+ WARN("Could not find CID-to-Code mapping for \"%s-%s\".", reg, ord);
+ WARN("I tried to load (one of) the following file(s):");
+ for (i = 0; i < 5; i++) {
+ append = known_encodings[select].pdfnames[i];
+ if (!append)
+ break;
+ MESG(" %s-%s-%s", reg, ord, append);
+ }
+ WARN("Please check if this file exists.");
+ return NULL;
+ }
+
+ return CMap_cache_get(cmap_id);
+}
+
+
+/*
+ * CIDFont glyph metrics:
+ * Mostly same as add_CID[HV]Metrics in cidtype0.c.
+ */
+#define PDFUNIT(v) ((double) (ROUND(1000.0*(v)/(g->emsize), 1)))
+
+static void
+add_TTCIDHMetrics (pdf_obj *fontdict, struct tt_glyphs *g,
+ char *used_chars, unsigned char *cidtogidmap, unsigned short last_cid)
+{
+ int cid, start = 0, prev = 0;
+ pdf_obj *w_array, *an_array = NULL;
+ double dw;
+ int empty = 1;
+
+ w_array = pdf_new_array();
+ if (g->dw != 0 && g->dw <= g->emsize) {
+ dw = PDFUNIT(g->dw);
+ } else {
+ dw = PDFUNIT(g->gd[0].advw);
+ }
+ for (cid = 0; cid <= last_cid; cid++) {
+ USHORT idx, gid;
+ double width;
+
+ if (!is_used_char2(used_chars, cid))
+ continue;
+ gid = (cidtogidmap) ? ((cidtogidmap[2*cid] << 8)|cidtogidmap[2*cid+1]) : cid;
+ idx = tt_get_index(g, gid);
+ if (cid != 0 && idx == 0)
+ continue;
+ width = PDFUNIT((g->gd)[idx].advw);
+ if (width == dw) {
+ if (an_array) {
+ pdf_add_array(w_array, pdf_new_number(start));
+ pdf_add_array(w_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ } else {
+ if (cid != prev + 1) {
+ if (an_array) {
+ pdf_add_array(w_array, pdf_new_number(start));
+ pdf_add_array(w_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ }
+ if (an_array == NULL) {
+ an_array = pdf_new_array();
+ start = cid;
+ }
+ pdf_add_array(an_array, pdf_new_number(width));
+ prev = cid;
+ }
+ }
+
+ if (an_array) {
+ pdf_add_array(w_array, pdf_new_number(start));
+ pdf_add_array(w_array, an_array);
+ empty = 0;
+ }
+
+ pdf_add_dict(fontdict, pdf_new_name("DW"), pdf_new_number(dw));
+ if (!empty) {
+ pdf_add_dict(fontdict, pdf_new_name("W"), pdf_ref_obj(w_array));
+ }
+ pdf_release_obj(w_array);
+
+ return;
+}
+
+static void
+add_TTCIDVMetrics (pdf_obj *fontdict, struct tt_glyphs *g,
+ char *used_chars, unsigned short last_cid)
+{
+ pdf_obj *w2_array, *an_array = NULL;
+ int cid;
+#if 0
+ int prev = 0, start = 0;
+#endif
+ double defaultVertOriginY, defaultAdvanceHeight;
+ int empty = 1;
+
+ defaultVertOriginY = PDFUNIT(g->default_advh - g->default_tsb);
+ defaultAdvanceHeight = PDFUNIT(g->default_advh);
+
+ w2_array = pdf_new_array();
+ for (cid = 0; cid <= last_cid; cid++) {
+ USHORT idx;
+#if 0
+ USHORT gid;
+#endif
+ double vertOriginX, vertOriginY, advanceHeight;
+
+ if (!is_used_char2(used_chars, cid))
+ continue;
+#if 0
+ gid = (cidtogidmap) ? ((cidtogidmap[2*cid] << 8)|cidtogidmap[2*cid+1]) : cid;
+#endif
+ idx = tt_get_index(g, (USHORT)cid);
+ if (cid != 0 && idx == 0)
+ continue;
+ advanceHeight = PDFUNIT(g->gd[idx].advh);
+ vertOriginX = PDFUNIT(0.5*(g->gd[idx].advw));
+ vertOriginY = PDFUNIT(g->gd[idx].tsb + g->gd[idx].ury);
+#if 0
+ /*
+ * c [w1_1y v_1x v_1y w1_2y v_2x v_2y ...]
+ * Not working... Why?
+ * Acrobat Reader:
+ * Wrong rendering, interpretation of position vector is wrong.
+ * Xpdf and gs: ignores W2?
+ */
+ if (vertOriginY == defaultVertOriginY &&
+ advanceHeight == defaultAdvanceHeight) {
+ if (an_array) {
+ pdf_add_array(w2_array, pdf_new_number(start));
+ pdf_add_array(w2_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ } else {
+ if (cid != prev + 1 && an_array) {
+ pdf_add_array(w2_array, pdf_new_number(start));
+ pdf_add_array(w2_array, an_array);
+ an_array = NULL;
+ empty = 0;
+ }
+ if (an_array == NULL) {
+ an_array = pdf_new_array();
+ start = cid;
+ }
+ pdf_add_array(an_array, pdf_new_number(-advanceHeight));
+ pdf_add_array(an_array, pdf_new_number(vertOriginX));
+ pdf_add_array(an_array, pdf_new_number(vertOriginY));
+ prev = cid;
+ }
+#else
+ /*
+ * c_first c_last w1_y v_x v_y
+ * This form may hit Acrobat's implementation limit of array element size,
+ * 8192. AFPL GhostScript 8.11 stops with rangecheck error with this.
+ * Maybe GS's bug?
+ */
+ if (vertOriginY != defaultVertOriginY ||
+ advanceHeight != defaultAdvanceHeight) {
+ pdf_add_array(w2_array, pdf_new_number(cid));
+ pdf_add_array(w2_array, pdf_new_number(cid));
+ pdf_add_array(w2_array, pdf_new_number(-advanceHeight));
+ pdf_add_array(w2_array, pdf_new_number(vertOriginX));
+ pdf_add_array(w2_array, pdf_new_number(vertOriginY));
+ empty = 0;
+ }
+#endif
+ }
+
+#if 0
+ if (an_array) {
+ pdf_add_array(w2_array, pdf_new_number(start));
+ pdf_add_array(w2_array, an_array);
+ empty = 0;
+ }
+#endif
+
+ if (defaultVertOriginY != 880 || defaultAdvanceHeight != 1000) {
+ an_array = pdf_new_array();
+ pdf_add_array(an_array, pdf_new_number(defaultVertOriginY));
+ pdf_add_array(an_array, pdf_new_number(-defaultAdvanceHeight));
+ pdf_add_dict(fontdict, pdf_new_name ("DW2"), an_array);
+ }
+ if (!empty) {
+ pdf_add_dict(fontdict,
+ pdf_new_name("W2"),
+ pdf_ref_obj(w2_array));
+ }
+ pdf_release_obj(w2_array);
+
+ return;
+}
+
+/*
+ * The following routine fixes few problems caused by vendor specific
+ * Unicode mappings.
+ */
+
+#define FIX_CJK_UNIOCDE_SYMBOLS 1
+
+static unsigned short
+fix_CJK_symbols (unsigned short code)
+{
+ unsigned short alt_code;
+ static struct
+ {
+ unsigned short alt1;
+ unsigned short alt2;
+ } CJK_Uni_symbols[] = {
+ /*
+ * Microsoft/Apple Unicode mapping difference:
+ * They are taken from SJIS-Unicode mapping difference but nearly
+ * same thing might be applied to Chinese (e.g., Big5) too.
+ */
+ {0x2014, 0x2015}, /* EM DASH <-> HORIZONTAL BAR */
+ {0x2016, 0x2225}, /* DOUBLE VERTICAL LINE <-> PARALLEL TO */
+ {0x203E, 0xFFE3}, /* OVERLINE <-> FULLWIDTH MACRON */
+ {0x2026, 0x22EF}, /* HORIZONTAL ELLIPSIS <-> MIDLINE HORIZONTAL ELLIPSIS */
+ {0x2212, 0xFF0D}, /* MINUS SIGN <-> FULLWIDTH HYPHEN-MINUS */
+ {0x301C, 0xFF5E}, /* WAVE DASH <-> FULLWIDTH TILDE */
+ {0xFFE0, 0x00A2}, /* FULLWIDTH CENT SIGN <-> CENT SIGN */
+ {0xFFE1, 0x00A3}, /* FULLWIDTH POUND SIGN <-> POUND SIGN */
+ {0xFFE2, 0x00AC}, /* FULLWIDTH NOT SIGN <-> NOT SIGN */
+ {0xFFFF, 0xFFFF}, /* EOD */
+ };
+#define NUM_CJK_SYMBOLS (sizeof(CJK_Uni_symbols)/sizeof(CJK_Uni_symbols[0]))
+ int i;
+
+ alt_code = code;
+ for (i = 0; i < NUM_CJK_SYMBOLS; i++) {
+ if (CJK_Uni_symbols[i].alt1 == code) {
+ alt_code = CJK_Uni_symbols[i].alt2;
+ break;
+ } else if (CJK_Uni_symbols[i].alt2 == code) {
+ alt_code = CJK_Uni_symbols[i].alt1;
+ break;
+ }
+ }
+
+ return alt_code;
+}
+
+static int32_t
+cid_to_code (CMap *cmap, CID cid, int unicode_cmap)
+{
+ unsigned char inbuf[2], outbuf[32];
+ int inbytesleft = 2, outbytesleft = 32;
+ const unsigned char *p;
+ unsigned char *q;
+
+ if (!cmap)
+ return cid;
+
+ inbuf[0] = (cid >> 8) & 0xff;
+ inbuf[1] = cid & 0xff;
+ p = inbuf; q = outbuf;
+
+ CMap_decode_char(cmap, &p, &inbytesleft, &q, &outbytesleft);
+
+ if (inbytesleft != 0)
+ return -1;
+ else if (outbytesleft == 31)
+ return (int32_t) outbuf[0];
+ else if (outbytesleft == 30)
+ return (int32_t) (outbuf[0] << 8|outbuf[1]);
+ else if (outbytesleft == 28) {
+ if (unicode_cmap) {
+ /* We assume the output encoding is UTF-16. */
+ int32_t uc;
+ const unsigned char *endptr;
+
+ p = outbuf;
+ endptr = p + 4;
+ uc = UC_UTF16BE_decode_char(&p, endptr);
+ if (p != endptr)
+ WARN("CID=%u mapped to non-single Unicode characters...", cid);
+ return p == endptr ? uc : -1;
+ } else {
+ return (outbuf[0] << 24)|(outbuf[1] << 16)|(outbuf[2] << 8)|outbuf[3];
+ }
+ }
+
+ return -1;
+}
+
+static uint16_t
+cid_to_gid (CMap *cmap, CID cid)
+{
+ unsigned char inbuf[2], outbuf[2];
+ int inbytesleft = 2, outbytesleft = 2;
+ const unsigned char *p;
+ unsigned char *q;
+
+ if (!cmap)
+ return cid;
+
+ inbuf[0] = (cid >> 8) & 0xff;
+ inbuf[1] = cid & 0xff;
+ p = inbuf; q = outbuf;
+
+ CMap_decode_char(cmap, &p, &inbytesleft, &q, &outbytesleft);
+
+ if (inbytesleft != 0 || outbytesleft != 0)
+ return 0;
+
+ return (uint16_t) (outbuf[0] << 8|outbuf[1]);
+}
+
+/* #define NO_GHOSTSCRIPT_BUG 1 */
+
+int
+CIDFont_type2_dofont (pdf_font *font)
+{
+ pdf_obj *fontfile;
+ sfnt *sfont;
+ char *h_used_chars, *v_used_chars, *used_chars;
+ struct tt_glyphs *glyphs;
+ CMap *cmap = NULL;
+ tt_cmap *ttcmap = NULL;
+ ULONG offset = 0;
+ CID cid, last_cid;
+ unsigned char *cidtogidmap;
+ USHORT num_glyphs;
+ enum {
+ glyph_ordering,
+ via_cid_to_code,
+ via_cid_to_gid,
+ } maptype = via_cid_to_code;
+ int i, unicode_cmap = 0;
+ FILE *fp = NULL;
+
+ if (!font->reference)
+ return 0;
+
+ pdf_add_dict(font->resource,
+ pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor));
+
+ if (font->flags & PDF_FONT_FLAG_BASEFONT)
+ return 0;
+
+ /*
+ * CIDSystemInfo comes here since Supplement can be increased.
+ */
+ {
+ pdf_obj *tmp;
+
+ tmp = pdf_new_dict ();
+ pdf_add_dict(tmp,
+ pdf_new_name("Registry"),
+ pdf_new_string(font->cid.csi.registry, strlen(font->cid.csi.registry)));
+ pdf_add_dict(tmp,
+ pdf_new_name("Ordering"),
+ pdf_new_string(font->cid.csi.ordering, strlen(font->cid.csi.ordering)));
+ pdf_add_dict(tmp,
+ pdf_new_name("Supplement"),
+ pdf_new_number(font->cid.csi.supplement));
+ pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), tmp);
+ }
+
+ /* Quick exit for non-embedded & fixed-pitch font. */
+ if (!font->cid.options.embed &&
+ (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH)) {
+ pdf_add_dict(font->resource, pdf_new_name("DW"), pdf_new_number(1000.0));
+ return 0;
+ }
+
+ fp = DPXFOPEN(font->filename, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(font->filename, DPX_RES_TYPE_DFONT);
+ if (!fp) {
+ WARN("Could not open TTF/dfont file: %s", font->filename);
+ return -1;
+ }
+ sfont = dfont_open(fp, font->index);
+ } else {
+ sfont = sfnt_open(fp);
+ }
+
+ if (!sfont) {
+ WARN("Could not open TTF file: %s", font->filename);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ switch (sfont->type) {
+ case SFNT_TYPE_TTC:
+ offset = ttc_read_offset(sfont, font->index);
+ if (offset == 0) {
+ WARN("Invalid TTC index in %s.", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ break;
+ case SFNT_TYPE_TRUETYPE:
+ if (font->index > 0) {
+ WARN("Found TrueType font file while expecting TTC file (%s).", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ offset = 0;
+ break;
+ case SFNT_TYPE_DFONT:
+ offset = sfont->offset;
+ break;
+ default:
+ WARN("Not a TrueType/TTC font (%s)?", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ break;
+ }
+
+ if (sfnt_read_table_directory(sfont, offset) < 0) {
+ WARN("Could not read TrueType table directory (%s).", font->filename);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ /*
+ * Adobe-Identity means font's internal glyph ordering here.
+ */
+ if (!strcmp(font->cid.csi.registry, "Adobe") &&
+ !strcmp(font->cid.csi.ordering, "Identity")) {
+ maptype = glyph_ordering;
+ ttcmap = NULL;
+ cmap = NULL;
+ } else {
+ if (font->cid.csi.registry && font->cid.csi.ordering) {
+ char *cmap_name;
+ size_t len;
+ int cmap_id;
+
+ len = strlen(font->cid.csi.registry) + strlen(font->cid.csi.ordering);
+ len += strlen(font->fontname);
+ len += 3;
+ cmap_name = NEW(len+1, char);
+ snprintf(cmap_name, len + 1, "%s-%s-%s",
+ font->cid.csi.registry, font->cid.csi.ordering, font->fontname);
+ cmap_id = CMap_cache_find(cmap_name);
+ RELEASE(cmap_name);
+ if (cmap_id >= 0) {
+ cmap = CMap_cache_get(cmap_id);
+ ttcmap = NULL;
+ maptype = via_cid_to_gid;
+ }
+ }
+ if (maptype != via_cid_to_gid) {
+ maptype = via_cid_to_code;
+ /*
+ * This part contains a bug. It may choose SJIS encoding TrueType cmap
+ * table for Adobe-GB1.
+ */
+ for (i = 0; i <= KNOWN_ENCODINGS_MAX; i++) {
+ ttcmap = tt_cmap_read(sfont,
+ known_encodings[i].platform,
+ known_encodings[i].encoding);
+ if (ttcmap)
+ break;
+ }
+ if (!ttcmap) {
+ WARN("No usable TrueType cmap table found for font \"%s\".", font->filename);
+ WARN("CID character collection for this font is set to \"%s-%s\"",
+ font->cid.csi.registry, font->cid.csi.ordering);
+ WARN("Cannot continue without this...");
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ } else if (i <= WIN_UCS_INDEX_MAX) {
+ unicode_cmap = 1;
+ } else {
+ unicode_cmap = 0;
+ }
+
+ if (!strcmp(font->cid.csi.ordering, "UCS") && i <= WIN_UCS_INDEX_MAX) {
+ cmap = NULL;
+ } else {
+ cmap = find_tocode_cmap(font->cid.csi.registry, font->cid.csi.ordering, i);
+ if (!cmap) {
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ }
+ }
+ }
+
+ glyphs = tt_build_init();
+
+ last_cid = 0;
+ num_glyphs = 1; /* .notdef */
+ used_chars = h_used_chars = v_used_chars = NULL;
+ {
+ int c;
+
+ h_used_chars = font->usedchars;
+ v_used_chars = font->cid.usedchars_v;
+
+ ASSERT(h_used_chars || v_used_chars);
+
+ /*
+ * Quick check of max CID.
+ */
+ c = 0;
+ for (i = 8191; i >= 0; i--) {
+ if (h_used_chars && h_used_chars[i] != 0) {
+ last_cid = i * 8 + 7;
+ c = h_used_chars[i];
+ break;
+ }
+ }
+ for (i = 8191; i >= 0; i--) {
+ if (v_used_chars && v_used_chars[i] != 0) {
+ if (i * 8 + 7 >= last_cid) {
+ c = (i * 8 + 7 > last_cid) ? (v_used_chars[i]) : (c | v_used_chars[i]);
+ last_cid = i * 8 + 7;
+ break;
+ }
+ }
+ }
+ if (last_cid > 0) {
+ for (i = 0; i < 8; i++) {
+ if ((c >> i) & 1)
+ break;
+ last_cid--;
+ }
+ }
+ ASSERT(last_cid < 0xFFFFu);
+ }
+
+#ifndef NO_GHOSTSCRIPT_BUG
+ cidtogidmap = NULL;
+#else
+ cidtogidmap = NEW((last_cid + 1) * 2, unsigned char);
+ memset(cidtogidmap, 0, (last_cid + 1) * 2);
+#endif /* !NO_GHOSTSCRIPT_BUG */
+
+ /*
+ * Map CIDs to GIDs.
+ * Horizontal and vertical used_chars are merged.
+ */
+
+ /*
+ * Horizontal
+ */
+ if (h_used_chars) {
+ used_chars = h_used_chars;
+ for (cid = 1; cid <= last_cid; cid++) {
+ int32_t code;
+ uint16_t gid = 0;
+
+ if (!is_used_char2(h_used_chars, cid))
+ continue;
+
+ switch (maptype) {
+ case glyph_ordering:
+ gid = cid;
+ code = cid;
+ break;
+ case via_cid_to_gid:
+ gid = cid_to_gid(cmap, cid);
+ code = cid;
+ break;
+ case via_cid_to_code:
+ code = cid_to_code(cmap, cid, unicode_cmap);
+ if (code < 0) {
+ WARN("Unable to map CID to code: CID=%u", cid);
+ } else {
+ gid = tt_cmap_lookup(ttcmap, code);
+#ifdef FIX_CJK_UNIOCDE_SYMBOLS
+ if (gid == 0 && unicode_cmap) {
+ int alt_code;
+
+ alt_code = fix_CJK_symbols((unsigned short)code);
+ if (alt_code != code) {
+ gid = tt_cmap_lookup(ttcmap, alt_code);
+ if (gid != 0) {
+ WARN("Unicode char U+%04x replaced with U+%04x.", code, alt_code);
+ }
+ }
+ }
+#endif /* FIX_CJK_UNIOCDE_SYMBOLS */
+ }
+ break;
+ }
+ if (gid == 0) {
+ if (code >= 0)
+ WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code);
+ }
+
+ /* TODO: duplicated glyph */
+#ifndef NO_GHOSTSCRIPT_BUG
+ gid = tt_add_glyph(glyphs, gid, cid);
+#else
+ gid = tt_add_glyph(glyphs, gid, num_glyphs);
+ cidtogidmap[2*cid ] = gid >> 8;
+ cidtogidmap[2*cid+1] = gid & 0xff;
+#endif /* !NO_GHOSTSCRIPT_BUG */
+
+ num_glyphs++;
+ }
+ }
+
+ /*
+ * Vertical
+ */
+ if (v_used_chars) {
+ otl_gsub *gsub_list = NULL;
+
+ /*
+ * Require `vrt2' or `vert'.
+ */
+ if (maptype != via_cid_to_code) {
+ gsub_list = NULL;
+ } else {
+ gsub_list = otl_gsub_new();
+ if (otl_gsub_add_feat(gsub_list, "*", "*", "vrt2", sfont) < 0) {
+ if (otl_gsub_add_feat(gsub_list, "*", "*", "vert", sfont) < 0) {
+ WARN("GSUB feature vrt2/vert not found.");
+ otl_gsub_release(gsub_list);
+ gsub_list = NULL;
+ } else {
+ otl_gsub_select(gsub_list, "*", "*", "vert");
+ }
+ } else {
+ otl_gsub_select(gsub_list, "*", "*", "vrt2");
+ }
+ }
+
+ for (cid = 1; cid <= last_cid; cid++) {
+ int32_t code;
+ uint16_t gid = 0;
+
+ if (!is_used_char2(v_used_chars, cid))
+ continue;
+
+ /* There may be conflict of horizontal and vertical glyphs
+ * when font is used with /UCS. However, we simply ignore
+ * that...
+ */
+ if (h_used_chars && is_used_char2(h_used_chars, cid)) {
+ continue;
+ }
+
+ switch (maptype) {
+ case glyph_ordering:
+ gid = cid;
+ code = cid;
+ break;
+ case via_cid_to_gid:
+ gid = cid_to_gid(cmap, cid);
+ code = cid;
+ break;
+ case via_cid_to_code:
+ code = cid_to_code(cmap, cid, unicode_cmap);
+ if (code < 0) {
+ WARN("Unable to map CID to code: CID=%u", cid);
+ } else {
+ gid = tt_cmap_lookup(ttcmap, code);
+#ifdef FIX_CJK_UNIOCDE_SYMBOLS
+ if (gid == 0 && unicode_cmap) {
+ int alt_code;
+
+ alt_code = fix_CJK_symbols((unsigned short)code);
+ if (alt_code != code) {
+ gid = tt_cmap_lookup(ttcmap, alt_code);
+ if (gid != 0) {
+ WARN("Unicode char U+%04x replaced with U+%04x.", code, alt_code);
+ }
+ }
+ }
+#endif /* FIX_CJK_UNIOCDE_SYMBOLS */
+ }
+ break;
+ }
+ if (gid == 0) {
+ if (code >= 0)
+ WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code);
+ } else if (gsub_list) {
+ otl_gsub_apply(gsub_list, &gid);
+ }
+
+#ifndef NO_GHOSTSCRIPT_BUG
+ gid = tt_add_glyph(glyphs, gid, cid);
+#else
+ gid = tt_add_glyph(glyphs, gid, num_glyphs);
+ cidtogidmap[2*cid ] = gid >> 8;
+ cidtogidmap[2*cid+1] = gid & 0xff;
+#endif /* !NO_GHOSTSCRIPT_BUG */
+
+ if (used_chars) /* merge vertical used_chars to horizontal */
+ add_to_used_chars2(used_chars, cid);
+
+ num_glyphs++;
+ }
+
+ if (gsub_list)
+ otl_gsub_release(gsub_list);
+
+ if (!used_chars) /* We have no horizontal. */
+ used_chars = v_used_chars;
+ }
+
+ ASSERT(used_chars);
+
+ tt_cmap_release(ttcmap);
+
+ if (font->cid.options.embed) {
+ if (tt_build_tables(sfont, glyphs) < 0) {
+ WARN("Could not created FontFile stream.");
+ if (cidtogidmap)
+ RELEASE(cidtogidmap);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%u glyphs (Max CID: %u)]", glyphs->num_glyphs, last_cid);
+ } else {
+ if (tt_get_metrics(sfont, glyphs) < 0) {
+ WARN("Reading glyph metrics failed...");
+ if (cidtogidmap)
+ RELEASE(cidtogidmap);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ }
+
+ /*
+ * DW, W, DW2, and W2
+ */
+ if (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH) {
+ pdf_add_dict(font->resource, pdf_new_name("DW"), pdf_new_number(1000.0));
+ } else {
+ add_TTCIDHMetrics(font->resource, glyphs, used_chars, cidtogidmap, last_cid);
+ if (font->cid.need_vmetrics)
+ add_TTCIDVMetrics(font->resource, glyphs, used_chars, last_cid);
+ }
+
+ /* CIDSet
+ * NOTE: All glyphs including component glyph and dummy glyph must be
+ * listed in CIDSet. However, .notdef glyph should be ommitted.
+ */
+ if (pdf_check_version(2, 0) < 0) {
+ pdf_obj *cidset;
+ char *cidset_data;
+
+ cidset_data = NEW(glyphs->last_gid/8 + 1, char);
+ memset(cidset_data, 0, glyphs->last_gid/8 + 1);
+ for (i = 1; i <= glyphs->last_gid; i++)
+ cidset_data[i/8] |= (1 << (7 - i % 8));
+ cidset = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_stream(cidset, cidset_data, glyphs->last_gid/8 + 1);
+ RELEASE(cidset_data);
+ pdf_add_dict(font->descriptor,
+ pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
+ pdf_release_obj(cidset);
+ }
+
+ tt_build_finish(glyphs);
+
+ /* Finish here if not embedded. */
+ if (!font->cid.options.embed) {
+ if (cidtogidmap)
+ RELEASE(cidtogidmap);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ return 0;
+ }
+
+ /* Create font file */
+ for (i = 0; required_table[i].name; i++) {
+ if (sfnt_require_table(sfont,
+ required_table[i].name,
+ required_table[i].must_exist) < 0) {
+ WARN("Some required TrueType table (%s) does not exist.", required_table[i].name);
+ if (cidtogidmap)
+ RELEASE(cidtogidmap);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ }
+
+ /*
+ * FontFile2
+ */
+ fontfile = sfnt_create_FontFile_stream(sfont);
+
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ if (!fontfile) {
+ WARN("Could not created FontFile stream for \"%s\".", font->filename);
+ if (cidtogidmap)
+ RELEASE(cidtogidmap);
+ return -1;
+ }
+ if (dpx_conf.verbose_level > 1) {
+ MESG("[%ld bytes]", pdf_stream_length(fontfile));
+ }
+
+ pdf_add_dict(font->descriptor, pdf_new_name("FontFile2"), pdf_ref_obj (fontfile));
+ pdf_release_obj(fontfile);
+
+ /*
+ * CIDToGIDMap
+ * Adobe's PDF Reference had been describing it as "optional" and
+ * default value as "Identity". However, ISO 32000-1 requires it
+ * for Type 2 CIDFonts with embedded font programs.
+ */
+ if (!cidtogidmap) {
+ pdf_add_dict(font->resource, pdf_new_name("CIDToGIDMap"), pdf_new_name("Identity"));
+ } else {
+ pdf_obj *c2gmstream;
+
+ c2gmstream = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_stream(c2gmstream, cidtogidmap, (last_cid + 1) * 2);
+ pdf_add_dict(font->resource, pdf_new_name("CIDToGIDMap"), pdf_ref_obj (c2gmstream));
+ pdf_release_obj(c2gmstream);
+ RELEASE(cidtogidmap);
+ }
+
+ return 0;
+}
+
+int
+CIDFont_type2_open (pdf_font *font, const char *name, int index, cid_opt *opt)
+{
+ int error;
+ char *fontname;
+ sfnt *sfont;
+ ULONG offset = 0;
+ FILE *fp = NULL;
+
+ ASSERT(font && opt);
+
+ fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(name, DPX_RES_TYPE_DFONT);
+ if (!fp) return -1;
+ sfont = dfont_open(fp, index);
+ } else {
+ sfont = sfnt_open(fp);
+ }
+
+ if (!sfont) {
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ switch (sfont->type) {
+ case SFNT_TYPE_TTC:
+ offset = ttc_read_offset(sfont, index);
+ break;
+ case SFNT_TYPE_TRUETYPE:
+ if (index > 0) {
+ WARN("Invalid TTC index (not TTC font): %s", name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ offset = 0;
+ break;
+ case SFNT_TYPE_DFONT:
+ offset = sfont->offset;
+ break;
+ default:
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (sfnt_read_table_directory(sfont, offset) < 0) {
+ WARN("Reading TrueType table directory failed: %s", name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ /* Ignore TrueType Collection with CFF table. */
+ if (sfont->type == SFNT_TYPE_TTC && sfnt_find_table_pos(sfont, "CFF ")) {
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ {
+ char *shortname;
+ int namelen;
+
+ /* MAC-ROMAN-EN-POSTSCRIPT or WIN-UNICODE-EN(US)-POSTSCRIPT */
+ shortname = NEW(PDF_NAME_LEN_MAX, char);
+ namelen = tt_get_ps_fontname(sfont, shortname, PDF_NAME_LEN_MAX);
+ if (namelen == 0) {
+ memset(shortname, 0, PDF_NAME_LEN_MAX);
+ strncpy(shortname, name, PDF_NAME_LEN_MAX);
+ namelen = strlen(shortname);
+ }
+ error = validate_name(shortname, namelen); /* for SJIS, UTF-16, ... string */
+ if (error) {
+ RELEASE(shortname);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ /*
+ * Strlen works, after validate_named string.
+ * Mangled name requires more 7 bytes.
+ * Style requires more 11 bytes.
+ */
+ fontname = NEW(strlen(shortname)+19, char);
+ strcpy(fontname, shortname);
+ RELEASE(shortname);
+ }
+
+ if (opt->embed && opt->style != FONT_STYLE_NONE) {
+ WARN("Embedding disabled due to style option for %s.", name);
+ opt->embed = 0;
+ }
+ switch (opt->style) {
+ case FONT_STYLE_BOLD:
+ strcat(fontname, ",Bold");
+ break;
+ case FONT_STYLE_ITALIC:
+ strcat(fontname, ",Italic");
+ break;
+ case FONT_STYLE_BOLDITALIC:
+ strcat(fontname, ",BoldItalic");
+ break;
+ }
+ /*
+ * CIDSystemInfo is determined from CMap or from map record option.
+ */
+ font->fontname = fontname;
+ font->subtype = PDF_FONT_FONTTYPE_CIDTYPE2;
+ if (opt->csi.registry && opt->csi.ordering) {
+ font->cid.csi.registry = NEW(strlen(opt->csi.registry)+1, char);
+ strcpy(font->cid.csi.registry, opt->csi.registry);
+ font->cid.csi.ordering = NEW(strlen(opt->csi.ordering)+1, char);
+ strcpy(font->cid.csi.ordering, opt->csi.ordering);
+ font->cid.csi.supplement = opt->csi.supplement;
+ }
+
+ font->resource = pdf_new_dict();
+ pdf_add_dict(font->resource, pdf_new_name("Type"), pdf_new_name("Font"));
+ pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("CIDFontType2"));
+
+ font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name);
+ if (!font->descriptor) {
+ WARN("Could not obtain necessary font info: %s", name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (opt->embed) {
+ char *tmp;
+
+ pdf_font_make_uniqueTag(font->uniqueID);
+ tmp = NEW(strlen(fontname)+8, char);
+ sprintf(tmp, "%s+%s", font->uniqueID, font->fontname);
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(tmp));
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(tmp));
+ RELEASE(tmp);
+ } else {
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(font->fontname));
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
+ }
+
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+
+ /*
+ * Don't write fontdict here.
+ * /Supplement in /CIDSystemInfo may change.
+ */
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/cidtype2.h b/Build/source/texk/dvipdfm-x/cidtype2.h
new file mode 100644
index 00000000000..70ab71e6d67
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cidtype2.h
@@ -0,0 +1,29 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CIDTYPE2_H_
+#define _CIDTYPE2_H_
+
+#include "pdffont.h"
+
+extern int CIDFont_type2_open (pdf_font *font, const char *name, int index, cid_opt *opt);
+extern int CIDFont_type2_dofont (pdf_font *font);
+
+#endif /* _CIDTYPE2_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cmap.c b/Build/source/texk/dvipdfm-x/cmap.c
new file mode 100644
index 00000000000..3884961e9a6
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cmap.c
@@ -0,0 +1,993 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * References:
+ *
+ * PostScript Language Reference Manual, 3rd. ed. (Adobe Systems Inc.)
+ * 5.11.4 CMap Dictionaries
+ * 5.11.5 FMapType 9 Composite Fonts
+ * Building CMap Files for CID-Keyed Fonts, Adobe Technical Note #5099
+ * CID-Keyed Font Technology Overview, Adobe Technical Note #5092
+ * Adobe CMap and CIDFont Files Specification, Adobe Technical Specification #5014
+ *
+ * Undefined Character Handling:
+ * PLRM 3rd. ed., sec. 5.11.5., "Handling Undefined Characters"
+ *
+ * TODO:
+ * Only cid(range|char) allowed for CODE_TO_CID and bf(range|char) for CID_TO_CODE ?
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "cmap_p.h"
+#include "cmap.h"
+
+static int __silent = 0;
+
+void
+CMap_set_silent (int value)
+{
+ __silent = value ? 1 : 0;
+}
+
+/* Private funcs. */
+static int bytes_consumed (CMap *cmap, const unsigned char *instr, int inbytes);
+static void handle_undefined (CMap *cmap,
+ const unsigned char **inbuf, int *inbytesleft,
+ unsigned char **outbuf, int *outbytesleft);
+
+static int check_range (CMap *cmap,
+ const unsigned char *srclo, const unsigned char *srchi, int srcdim,
+ const unsigned char *dst, int dstdim);
+
+static unsigned char *get_mem (CMap *cmap, int size);
+static mapDef *mapDef_new (void);
+static void mapDef_release (mapDef *t);
+static int locate_tbl (mapDef **cur, const unsigned char *code, int dim);
+
+CMap *
+CMap_new (void)
+{
+ CMap *cmap;
+
+ cmap = NEW(1, struct CMap);
+ cmap->name = NULL;
+ cmap->type = CMAP_TYPE_CODE_TO_CID;
+ cmap->wmode = 0;
+ cmap->useCMap = NULL;
+ cmap->CSI = NULL;
+
+ cmap->profile.minBytesIn = 65535;
+ cmap->profile.maxBytesIn = 0;
+ cmap->profile.minBytesOut = 65535;
+ cmap->profile.maxBytesOut = 0;
+
+ cmap->flags = 0;
+
+ cmap->codespace.num = 0;
+ cmap->codespace.max = 10;
+ cmap->codespace.ranges = NEW(10, struct rangeDef);
+
+ cmap->mapTbl = NULL;
+
+ cmap->mapData = NEW(1, struct mapData);
+ cmap->mapData->prev = NULL;
+ cmap->mapData->pos = 0;
+ cmap->mapData->data = NEW(MEM_ALLOC_SIZE, unsigned char);
+
+ return cmap;
+}
+
+void
+CMap_release (CMap *cmap)
+{
+ if (!cmap)
+ return;
+
+ if (cmap->name)
+ RELEASE(cmap->name);
+ if (cmap->CSI) {
+ if (cmap->CSI->registry) RELEASE(cmap->CSI->registry);
+ if (cmap->CSI->ordering) RELEASE(cmap->CSI->ordering);
+ RELEASE(cmap->CSI);
+ }
+ if (cmap->codespace.ranges)
+ RELEASE(cmap->codespace.ranges);
+ if (cmap->mapTbl)
+ mapDef_release(cmap->mapTbl);
+ {
+ mapData *map = cmap->mapData;
+ while (map != NULL) {
+ mapData *prev = map->prev;
+ if (map->data != NULL)
+ RELEASE(map->data);
+ RELEASE(map);
+ map = prev;
+ }
+ }
+
+ RELEASE(cmap);
+}
+
+int
+CMap_is_Identity (CMap *cmap)
+{
+ ASSERT(cmap);
+ if (!strcmp(cmap->name, "Identity-H") || !strcmp(cmap->name, "Identity-V"))
+ return 1;
+ else
+ return 0;
+}
+
+#if 0
+/* NOT IMPLEMENTED YET */
+int
+CMap_is_realy_Identity(CMap *cmap)
+{
+ return 0;
+}
+#endif
+
+int
+CMap_is_valid (CMap *cmap)
+{
+ /* Quick check */
+ if (!cmap || !(cmap->name) || cmap->type < CMAP_TYPE_IDENTITY ||
+ cmap->type > CMAP_TYPE_CID_TO_CODE || cmap->codespace.num < 1 ||
+ (cmap->type != CMAP_TYPE_IDENTITY && !cmap->mapTbl))
+ return 0;
+
+ if (cmap->useCMap) {
+ CIDSysInfo *csi1, *csi2;
+ csi1 = CMap_get_CIDSysInfo(cmap);
+ csi2 = CMap_get_CIDSysInfo(cmap->useCMap);
+ if (strcmp(csi1->registry, csi2->registry) ||
+ strcmp(csi1->ordering, csi2->ordering)) {
+ WARN("CIDSystemInfo mismatched %s <--> %s",
+ CMap_get_name(cmap), CMap_get_name(cmap->useCMap));
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int
+CMap_get_profile (CMap *cmap, int type)
+{
+ int value = 0;
+
+ ASSERT(cmap);
+ switch (type) {
+ case CMAP_PROF_TYPE_INBYTES_MIN:
+ value = cmap->profile.minBytesIn;
+ break;
+ case CMAP_PROF_TYPE_INBYTES_MAX:
+ value = cmap->profile.maxBytesIn;
+ break;
+ case CMAP_PROF_TYPE_OUTBYTES_MIN:
+ value = cmap->profile.maxBytesOut;
+ break;
+ case CMAP_PROF_TYPE_OUTBYTES_MAX:
+ value = cmap->profile.maxBytesOut;
+ break;
+ default:
+ ERROR("%s: Unrecognized profile type %d.", CMAP_DEBUG_STR, type);
+ }
+
+ return value;
+}
+
+/*
+ * Put notdef chars for codes not declared in notdef(range|char)
+ */
+static void
+handle_undefined (CMap *cmap,
+ const unsigned char **inbuf, int *inbytesleft,
+ unsigned char **outbuf, int *outbytesleft)
+{
+ int len = 0;
+
+ if (*outbytesleft < 2)
+ ERROR("%s: Buffer overflow.", CMAP_DEBUG_STR);
+
+ switch (cmap->type) {
+ case CMAP_TYPE_CODE_TO_CID:
+ memcpy(*outbuf, CID_NOTDEF_CHAR, 2);
+ break;
+ case CMAP_TYPE_TO_UNICODE:
+ memcpy(*outbuf, UCS_NOTDEF_CHAR, 2);
+ break;
+ default:
+ WARN("Cannot handle undefined mapping for this type of CMap mapping: %d", cmap->type);
+ WARN("<0000> is used for .notdef char.");
+ memset(*outbuf, 0, 2);
+ }
+ *outbuf += 2;
+ *outbytesleft -= 2;
+
+ len = bytes_consumed(cmap, *inbuf, *inbytesleft);
+
+ *inbuf += len;
+ *inbytesleft -= len;
+}
+
+void
+CMap_decode_char (CMap *cmap,
+ const unsigned char **inbuf, int *inbytesleft,
+ unsigned char **outbuf, int *outbytesleft)
+{
+ mapDef *t;
+ const unsigned char *p, *save;
+ unsigned char c = 0;
+ int count = 0;
+
+ p = save = *inbuf;
+ /*
+ * First handle some special cases:
+ */
+ if (cmap->type == CMAP_TYPE_IDENTITY) {
+ if ((*inbytesleft) % 2)
+ ERROR("%s: Invalid/truncated input string.", CMAP_DEBUG_STR);
+ if (*outbytesleft < 2)
+ ERROR("%s: Buffer overflow.", CMAP_DEBUG_STR);
+ memcpy(*outbuf, *inbuf, 2);
+ *inbuf += 2;
+ *outbuf += 2;
+ *outbytesleft -= 2;
+ *inbytesleft -= 2;
+ return;
+ } else if (!cmap->mapTbl) {
+ if (cmap->useCMap) {
+ CMap_decode_char(cmap->useCMap, inbuf, inbytesleft, outbuf, outbytesleft);
+ return;
+ } else {
+ /* no mapping available in this CMap */
+ WARN("No mapping available for this character.");
+ handle_undefined(cmap, inbuf, inbytesleft, outbuf, outbytesleft);
+ return;
+ }
+ }
+
+ ASSERT(cmap->mapTbl);
+ t = cmap->mapTbl;
+ while (count < *inbytesleft) {
+ c = *p++;
+ count++;
+ if (LOOKUP_END(t[c].flag))
+ break;
+ t = t[c].next;
+ }
+ if (LOOKUP_CONTINUE(t[c].flag)) /* need more bytes */
+ ERROR("%s: Premature end of input string.", CMAP_DEBUG_STR);
+ else if (!MAP_DEFINED(t[c].flag)) {
+ if (cmap->useCMap) {
+ CMap_decode_char(cmap->useCMap, inbuf, inbytesleft, outbuf, outbytesleft);
+ return;
+ } else {
+ /* no mapping available in this CMap */
+ WARN("No character mapping available.");
+ MESG(" CMap name: %s\n", CMap_get_name(cmap));
+ MESG(" input str: ");
+ MESG("<");
+ while (save < p) {
+ MESG("%02x", *save);
+ save++;
+ }
+ MESG(">\n");
+ /*
+ * We know partial match found up to `count' bytes,
+ * but we will not use this information for the sake of simplicity.
+ */
+ handle_undefined(cmap, inbuf, inbytesleft, outbuf, outbytesleft);
+ return;
+ }
+ } else {
+ switch (MAP_TYPE(t[c].flag)) {
+ case MAP_IS_NOTDEF:
+ WARN("Character mapped to .notdef found.");
+ /* continue */
+ case MAP_IS_CID: case MAP_IS_CODE:
+ if (*outbytesleft >= t[c].len)
+ memcpy(*outbuf, t[c].code, t[c].len);
+ else
+ ERROR("%s: Buffer overflow.", CMAP_DEBUG_STR);
+ *outbuf += t[c].len;
+ *outbytesleft -= t[c].len;
+ break;
+ case MAP_IS_NAME:
+ ERROR("%s: CharName mapping not supported.", CMAP_DEBUG_STR);
+ break;
+ default:
+ ERROR("%s: Unknown mapping type.", CMAP_DEBUG_STR);
+ }
+ if (inbytesleft)
+ *inbytesleft -= count;
+ *inbuf = p;
+ }
+}
+
+/*
+ * For convenience, it does not do decoding to CIDs.
+ */
+int
+CMap_decode (CMap *cmap,
+ const unsigned char **inbuf, int *inbytesleft,
+ unsigned char **outbuf, int *outbytesleft)
+{
+ int count;
+
+ ASSERT(cmap && inbuf && outbuf);
+ ASSERT(inbytesleft && outbytesleft);
+ for (count = 0;*inbytesleft > 0 && *outbytesleft > 0; count++)
+ CMap_decode_char(cmap, inbuf, inbytesleft, outbuf, outbytesleft);
+
+ return count;
+}
+
+char *
+CMap_get_name (CMap *cmap)
+{
+ ASSERT(cmap);
+ return cmap->name;
+}
+
+int
+CMap_get_type (CMap *cmap)
+{
+ ASSERT(cmap);
+ return cmap->type;
+}
+
+int
+CMap_get_wmode (CMap *cmap)
+{
+ ASSERT(cmap);
+ return cmap->wmode;
+}
+
+CIDSysInfo *
+CMap_get_CIDSysInfo (CMap *cmap)
+{
+ ASSERT(cmap);
+ return cmap->CSI;
+}
+
+void
+CMap_set_name (CMap *cmap, const char *name)
+{
+ ASSERT(cmap);
+ if (cmap->name)
+ RELEASE(cmap->name);
+ cmap->name = NEW(strlen(name)+1, char);
+ strcpy(cmap->name, name);
+}
+
+void
+CMap_set_type (CMap *cmap, int type)
+{
+ ASSERT(cmap);
+ cmap->type = type;
+}
+
+void
+CMap_set_wmode (CMap *cmap, int wmode)
+{
+ ASSERT(cmap);
+ cmap->wmode = wmode;
+}
+
+void
+CMap_set_CIDSysInfo (CMap *cmap, const CIDSysInfo *csi)
+{
+ ASSERT(cmap);
+
+ if (cmap->CSI) {
+ if (cmap->CSI->registry)
+ RELEASE(cmap->CSI->registry);
+ if (cmap->CSI->ordering)
+ RELEASE(cmap->CSI->ordering);
+ RELEASE(cmap->CSI);
+ }
+
+ if (csi && csi->registry && csi->ordering) {
+ cmap->CSI = NEW(1, CIDSysInfo);
+ cmap->CSI->registry = NEW(strlen(csi->registry)+1, char);
+ strcpy(cmap->CSI->registry, csi->registry);
+ cmap->CSI->ordering = NEW(strlen(csi->ordering)+1, char);
+ strcpy(cmap->CSI->ordering, csi->ordering);
+ cmap->CSI->supplement = csi->supplement;
+ } else {
+ WARN("Invalid CIDSystemInfo.");
+ cmap->CSI = NULL;
+ }
+}
+
+/*
+ * Can have muliple entry ?
+ */
+void
+CMap_set_usecmap (CMap *cmap, CMap *ucmap)
+{
+ int i;
+
+ ASSERT(cmap);
+ ASSERT(ucmap); /* Maybe if (!ucmap) ERROR() is better for this. */
+
+ if (cmap == ucmap)
+ ERROR("%s: Identical CMap object cannot be used for usecmap CMap: 0x%p=0x%p",
+ CMAP_DEBUG_STR, cmap, ucmap);
+
+ /* Check if ucmap have neccesary information. */
+ if (!CMap_is_valid(ucmap))
+ ERROR("%s: Invalid CMap.", CMAP_DEBUG_STR);
+
+ /*
+ * CMapName of cmap can be undefined when usecmap is executed in CMap parsing.
+ * And it is also possible CSI is not defined at that time.
+ */
+ if (cmap->name && strcmp(cmap->name, ucmap->name) == 0)
+ ERROR("%s: CMap refering itself not allowed: CMap %s --> %s",
+ CMAP_DEBUG_STR, cmap->name, ucmap->name);
+
+ if (cmap->CSI && cmap->CSI->registry && cmap->CSI->ordering) {
+ if (strcmp(cmap->CSI->registry, ucmap->CSI->registry) ||
+ strcmp(cmap->CSI->ordering, ucmap->CSI->ordering))
+ ERROR("%s: CMap %s required by %s have different CSI.",
+ CMAP_DEBUG_STR, CMap_get_name(cmap), CMap_get_name(ucmap));
+ }
+
+ /* We must copy codespaceranges. */
+ for (i = 0; i < ucmap->codespace.num; i++) {
+ rangeDef *csr = ucmap->codespace.ranges + i;
+ CMap_add_codespacerange(cmap, csr->codeLo, csr->codeHi, csr->dim);
+ }
+
+ cmap->useCMap = ucmap;
+}
+
+/* Test the validity of character c. */
+static int
+CMap_match_codespace (CMap *cmap, const unsigned char *c, int dim)
+{
+ int i, pos;
+
+ ASSERT(cmap);
+ for (i = 0; i < cmap->codespace.num; i++) {
+ rangeDef *csr = cmap->codespace.ranges + i;
+ if (csr->dim != dim)
+ continue;
+ for (pos = 0; pos < dim; pos++) {
+ if (c[pos] > csr->codeHi[pos] || c[pos] < csr->codeLo[pos])
+ break;
+ }
+ if (pos == dim)
+ return 0; /* Valid */
+ }
+
+ return -1; /* Invalid */
+}
+
+/*
+ * No overlapping codespace ranges are allowed, otherwise mapping is ambiguous.
+ */
+int
+CMap_add_codespacerange (CMap *cmap,
+ const unsigned char *codelo, const unsigned char *codehi, int dim)
+{
+ rangeDef *csr = NULL;
+ int i;
+
+ ASSERT(cmap && dim > 0);
+
+ for (i = 0; i < cmap->codespace.num; i++) {
+ int j, overlap = 1;
+ csr = cmap->codespace.ranges + i;
+ for (j = 0; j < MIN(csr->dim, dim) && overlap; j++) {
+ if ((codelo[j] >= csr->codeLo[j] && codelo[j] <= csr->codeHi[j]) ||
+ (codehi[j] >= csr->codeLo[j] && codehi[j] <= csr->codeHi[j]))
+ overlap = 1;
+ else
+ overlap = 0;
+ }
+ if (overlap) {
+ WARN("Overlapping codespace found. (ingored)");
+ return -1;
+ }
+ }
+
+ if (dim < cmap->profile.minBytesIn)
+ cmap->profile.minBytesIn = dim;
+ if (dim > cmap->profile.maxBytesIn)
+ cmap->profile.maxBytesIn = dim;
+
+ if (cmap->codespace.num + 1 > cmap->codespace.max) {
+ cmap->codespace.max += 10;
+ cmap->codespace.ranges = RENEW(cmap->codespace.ranges, cmap->codespace.max, struct rangeDef);
+ }
+
+ csr = cmap->codespace.ranges + cmap->codespace.num;
+ csr->dim = dim;
+ csr->codeHi = get_mem(cmap, dim);
+ csr->codeLo = get_mem(cmap, dim);
+ memcpy(csr->codeHi, codehi, dim);
+ memcpy(csr->codeLo, codelo, dim);
+
+ (cmap->codespace.num)++;
+
+ return 0;
+}
+
+int
+CMap_add_notdefchar (CMap *cmap, const unsigned char *src, int srcdim, CID dst)
+{
+ return CMap_add_notdefrange(cmap, src, src, srcdim, dst);
+}
+
+int
+CMap_add_notdefrange (CMap *cmap,
+ const unsigned char *srclo, const unsigned char *srchi, int srcdim, CID dst)
+{
+ int c;
+ mapDef *cur;
+
+ ASSERT(cmap);
+ /* dst not used here */
+ /* FIXME */
+ if (check_range(cmap, srclo, srchi, srcdim, (const unsigned char *)&dst, 2) < 0)
+ return -1;
+
+ if (cmap->mapTbl == NULL )
+ cmap->mapTbl = mapDef_new();
+
+ cur = cmap->mapTbl;
+ if (locate_tbl(&cur, srclo, srcdim) < 0)
+ return -1;
+
+ for (c = srclo[srcdim-1]; c <= srchi[srcdim-1]; c++) {
+ if (MAP_DEFINED(cur[c].flag)) {
+ if (!__silent)
+ WARN("Trying to redefine already defined code mapping. (ignored)");
+ } else {
+ cur[c].flag = (MAP_LOOKUP_END|MAP_IS_NOTDEF);
+ cur[c].code = get_mem(cmap, 2);
+ cur[c].len = 2;
+ cur[c].code[0] = dst >> 8;
+ cur[c].code[1] = dst & 0xff;
+ }
+ /* Do not do dst++ for notdefrange */
+ }
+
+ return 0;
+}
+
+int
+CMap_add_bfchar (CMap *cmap,
+ const unsigned char *src, int srcdim,
+ const unsigned char *dst, int dstdim)
+{
+ return CMap_add_bfrange(cmap, src, src, srcdim, dst, dstdim);
+}
+
+int
+CMap_add_bfrange (CMap *cmap,
+ const unsigned char *srclo, const unsigned char *srchi, int srcdim,
+ const unsigned char *base, int dstdim)
+{
+ int c, last_byte, i;
+ mapDef *cur;
+
+ ASSERT(cmap);
+ if (check_range(cmap, srclo, srchi, srcdim, base, dstdim) < 0)
+ return -1;
+
+ if (cmap->mapTbl == NULL)
+ cmap->mapTbl = mapDef_new();
+
+ cur = cmap->mapTbl;
+ if (locate_tbl(&cur, srclo, srcdim) < 0)
+ return -1;
+
+ for (c = srclo[srcdim-1]; c <= srchi[srcdim-1]; c++) {
+ /* According to 5014.CIDFont_Spec.pdf (p.52),
+ * Code mappings (unlike codespace ranges) may overlap,
+ * but succeeding maps superceded preceding maps.
+ * (reported and patched by Luo Jie on 2007/12/2)
+ */
+ if (!MAP_DEFINED(cur[c].flag) || cur[c].len < dstdim) {
+ cur[c].flag = (MAP_LOOKUP_END|MAP_IS_CODE);
+ cur[c].code = get_mem(cmap, dstdim);
+ }
+ /*
+ * We assume restriction to code ranges also applied here.
+ * Addition <00FF> + 1 is undefined.
+ *
+ * Changed on 2004-03-20:
+ *
+ * Should be treated as <0100> in Acrobat's "ToUnicode" CMap.
+ */
+ cur[c].len = dstdim;
+ memcpy(cur[c].code, base, dstdim);
+
+ last_byte = c - srclo[srcdim-1] + base[dstdim-1];
+ cur[c].code[dstdim-1] = (last_byte & 0xFF);
+ for (i = dstdim - 2; i >= 0 && last_byte > 255; i--) {
+ last_byte = cur[c].code[i] + 1;
+ cur[c].code[i] = (last_byte & 0xFF);
+ }
+ }
+
+ return 0;
+}
+
+int
+CMap_add_cidchar (CMap *cmap, const unsigned char *src, int srcdim, CID dst)
+{
+ return CMap_add_cidrange(cmap, src, src, srcdim, dst);
+}
+
+int
+CMap_add_cidrange (CMap *cmap,
+ const unsigned char *srclo, const unsigned char *srchi, int srcdim, CID base)
+{
+ int i, c, v;
+ mapDef *cur;
+
+ ASSERT(cmap);
+ /* base not used here */
+ if (check_range(cmap, srclo, srchi, srcdim, (const unsigned char *)&base, 2) < 0) /* FIXME */
+ return -1;
+
+ if (cmap->mapTbl == NULL )
+ cmap->mapTbl = mapDef_new();
+
+ cur = cmap->mapTbl;
+ if (locate_tbl(&cur, srclo, srcdim) < 0)
+ return -1;
+
+ for (v = 0, i = 0; i < srcdim - 1; i++)
+ v = (v << 8) + srclo[i];
+
+ for (c = srclo[srcdim-1]; c <= srchi[srcdim-1]; c++) {
+ if (cur[c].flag != 0) {
+ if (!__silent)
+ WARN("Trying to redefine already defined CID mapping. (ignored)");
+ } else {
+ cur[c].flag = (MAP_LOOKUP_END|MAP_IS_CID);
+ cur[c].len = 2;
+ cur[c].code = get_mem(cmap, 2);
+ cur[c].code[0] = base >> 8;
+ cur[c].code[1] = base & 0xff;
+ }
+ if (base >= CID_MAX)
+ WARN("CID number too large.");
+ base++;
+ }
+
+ return 0;
+}
+
+static void
+mapDef_release (mapDef *t)
+{
+ int c;
+
+ ASSERT(t);
+ for (c = 0; c < 256; c++) {
+ if (LOOKUP_CONTINUE(t[c].flag))
+ mapDef_release(t[c].next);
+ }
+ RELEASE(t);
+}
+
+static mapDef *
+mapDef_new (void)
+{
+ mapDef *t;
+ int c;
+
+ t = NEW(256, mapDef);
+ for (c=0; c<256; c++) {
+ t[c].flag = (MAP_LOOKUP_END|MAP_IS_UNDEF);
+ t[c].code = NULL;
+ t[c].next = NULL;
+ }
+
+ return t;
+}
+
+static unsigned char *
+get_mem (CMap *cmap, int size)
+{
+ mapData *map;
+ unsigned char *p;
+
+ ASSERT(cmap && cmap->mapData && size >= 0);
+ map = cmap->mapData;
+ if (map->pos + size >= MEM_ALLOC_SIZE) {
+ mapData *prev = map;
+ map = NEW(1, struct mapData);
+ map->data = NEW(MEM_ALLOC_SIZE, unsigned char);
+ map->prev = prev;
+ map->pos = 0;
+ cmap->mapData = map;
+ }
+ p = map->data + map->pos;
+ map->pos += size;
+
+ return p;
+}
+
+static int
+locate_tbl (mapDef **cur, const unsigned char *code, int dim)
+{
+ int i, c;
+
+ ASSERT(cur && *cur);
+ for (i = 0; i < dim-1; i++) {
+ c = code[i];
+ if (MAP_DEFINED((*cur)[c].flag)) {
+ WARN("Ambiguous CMap entry.");
+ return -1;
+ }
+ if ((*cur)[c].next == NULL) /* create new node */
+ (*cur)[c].next = mapDef_new();
+ (*cur)[c].flag |= MAP_LOOKUP_CONTINUE;
+ *cur = (*cur)[c].next;
+ }
+
+ return 0;
+}
+
+/*
+ * Guess how many bytes consumed as a `single' character:
+ * Substring of length bytesconsumed bytes of input string is interpreted as
+ * a `single' character by CMap_decode().
+ */
+static int
+bytes_consumed (CMap *cmap, const unsigned char *instr, int inbytes)
+{
+ int i, pos, longest = 0, bytesconsumed;
+
+ ASSERT(cmap);
+ for (i = 0; i < cmap->codespace.num; i++) {
+ rangeDef *csr = cmap->codespace.ranges + i;
+ for (pos = 0; pos < MIN(csr->dim, inbytes); pos++) {
+ if (instr[pos] > csr->codeHi[pos] || instr[pos] < csr->codeLo[pos])
+ break;
+ }
+ if (pos == csr->dim) /* part of instr is totally valid in this codespace. */
+ return csr->dim;
+ if (pos > longest)
+ longest = pos;
+ }
+
+ if (i == cmap->codespace.num) /* No matching at all */
+ bytesconsumed = cmap->profile.minBytesIn;
+ else {
+ bytesconsumed = cmap->profile.maxBytesIn;
+ for (i = 0; i< cmap->codespace.num; i++) {
+ rangeDef *csr = cmap->codespace.ranges + i;
+ if (csr->dim > longest && csr->dim < bytesconsumed)
+ bytesconsumed = csr->dim;
+ }
+ }
+
+ return bytesconsumed;
+}
+
+static int
+check_range (CMap *cmap,
+ const unsigned char *srclo, const unsigned char *srchi, int srcdim,
+ const unsigned char *dst, int dstdim)
+{
+ if ((srcdim < 1 || dstdim < 1) ||
+ (!srclo || !srchi || !dst) ||
+ memcmp(srclo, srchi, srcdim - 1) ||
+ srclo[srcdim-1] > srchi[srcdim-1]) {
+ WARN("Invalid CMap mapping entry. (ignored)");
+ return -1;
+ }
+
+ if (CMap_match_codespace(cmap, srclo, srcdim) < 0 ||
+ CMap_match_codespace(cmap, srchi, srcdim) < 0) {
+ WARN("Invalid CMap mapping entry. (ignored)");
+ return -1;
+ }
+
+ if (srcdim < cmap->profile.minBytesIn)
+ cmap->profile.minBytesIn = srcdim;
+ if (srcdim > cmap->profile.maxBytesIn)
+ cmap->profile.maxBytesIn = srcdim;
+ if (dstdim < cmap->profile.minBytesOut)
+ cmap->profile.minBytesOut = dstdim;
+ if (dstdim > cmap->profile.maxBytesOut)
+ cmap->profile.maxBytesOut = dstdim;
+
+ return 0;
+}
+
+/************************** CMAP_CACHE **************************/
+#include "cmap_read.h"
+
+#define CMAP_CACHE_ALLOC_SIZE 16u
+
+struct CMap_cache {
+ int num;
+ int max;
+ CMap **cmaps;
+};
+
+static struct CMap_cache *__cache = NULL;
+
+#define CHECK_ID(n) do {\
+ if (! __cache)\
+ ERROR("%s: CMap cache not initialized.", CMAP_DEBUG_STR);\
+ if ((n) < 0 || (n) >= __cache->num)\
+ ERROR("Invalid CMap ID %d", (n));\
+ } while (0)
+
+#include "dpxfile.h"
+
+void
+CMap_cache_init (void)
+{
+ static unsigned char range_min[2] = {0x00, 0x00};
+ static unsigned char range_max[2] = {0xff, 0xff};
+
+ if (__cache)
+ ERROR("%s: Already initialized.", CMAP_DEBUG_STR);
+
+ __cache = NEW(1, struct CMap_cache);
+
+ __cache->max = CMAP_CACHE_ALLOC_SIZE;
+ __cache->cmaps = NEW(__cache->max, CMap *);
+ __cache->num = 0;
+
+ /* Create Identity mapping */
+ __cache->cmaps[0] = CMap_new();
+ CMap_set_name (__cache->cmaps[0], "Identity-H");
+ CMap_set_type (__cache->cmaps[0], CMAP_TYPE_IDENTITY);
+ CMap_set_wmode(__cache->cmaps[0], 0);
+ CMap_set_CIDSysInfo(__cache->cmaps[0], &CSI_IDENTITY);
+ CMap_add_codespacerange(__cache->cmaps[0], range_min, range_max, 2);
+
+ __cache->cmaps[1] = CMap_new();
+ CMap_set_name (__cache->cmaps[1], "Identity-V");
+ CMap_set_type (__cache->cmaps[1], CMAP_TYPE_IDENTITY);
+ CMap_set_wmode(__cache->cmaps[1], 1);
+ CMap_set_CIDSysInfo(__cache->cmaps[1], &CSI_IDENTITY);
+ CMap_add_codespacerange(__cache->cmaps[1], range_min, range_max, 2);
+
+ __cache->num += 2;
+}
+
+CMap *
+CMap_cache_get (int id)
+{
+ CHECK_ID(id);
+ return __cache->cmaps[id];
+}
+
+int
+CMap_cache_find (const char *cmap_name)
+{
+ int id = 0;
+ FILE *fp = NULL;
+
+ if (!__cache)
+ CMap_cache_init();
+ ASSERT(__cache);
+
+ for (id = 0; id < __cache->num; id++) {
+ char *name = NULL;
+ /* CMapName may be undefined when processing usecmap. */
+ name = CMap_get_name(__cache->cmaps[id]);
+ if (name && strcmp(cmap_name, name) == 0) {
+ return id;
+ }
+ }
+
+ fp = DPXFOPEN(cmap_name, DPX_RES_TYPE_CMAP);
+ if (!fp)
+ return -1;
+
+ if (CMap_parse_check_sig(fp) < 0) {
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (dpx_conf.verbose_level > 0)
+ MESG("(CMap:%s", cmap_name);
+
+ if (__cache->num >= __cache->max) {
+ __cache->max += CMAP_CACHE_ALLOC_SIZE;
+ __cache->cmaps = RENEW(__cache->cmaps, __cache->max, CMap *);
+ }
+ id = __cache->num;
+ (__cache->num)++;
+ __cache->cmaps[id] = CMap_new();
+
+ if (CMap_parse(__cache->cmaps[id], fp) < 0)
+ ERROR("%s: Parsing CMap file failed.", CMAP_DEBUG_STR);
+
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(")");
+
+ return id;
+}
+
+int
+CMap_cache_add (CMap *cmap)
+{
+ int id;
+ char *cmap_name0, *cmap_name1;
+
+ if (!CMap_is_valid(cmap))
+ ERROR("%s: Invalid CMap.", CMAP_DEBUG_STR);
+
+ for (id = 0; id < __cache->num; id++) {
+ cmap_name0 = CMap_get_name(cmap);
+ cmap_name1 = CMap_get_name(__cache->cmaps[id]);
+ if (!strcmp(cmap_name0, cmap_name1)) {
+ ERROR("%s: CMap \"%s\" already defined.",
+ CMAP_DEBUG_STR, cmap_name0);
+ return -1;
+ }
+ }
+
+ if (__cache->num >= __cache->max) {
+ __cache->max += CMAP_CACHE_ALLOC_SIZE;
+ __cache->cmaps = RENEW(__cache->cmaps, __cache->max, CMap *);
+ }
+ id = __cache->num;
+ (__cache->num)++;
+ __cache->cmaps[id] = cmap;
+
+ return id;
+}
+
+void
+CMap_cache_close (void)
+{
+ if (__cache) {
+ int id;
+ for (id = 0; id < __cache->num; id++) {
+ CMap_release(__cache->cmaps[id]);
+ }
+ RELEASE(__cache->cmaps);
+ RELEASE(__cache);
+ __cache = NULL;
+ }
+}
diff --git a/Build/source/texk/dvipdfm-x/cmap.h b/Build/source/texk/dvipdfm-x/cmap.h
new file mode 100644
index 00000000000..32f2701776c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cmap.h
@@ -0,0 +1,114 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CMAP_H_
+#define _CMAP_H_
+
+#include "cid.h"
+
+#include <sys/types.h>
+
+typedef unsigned short CID;
+typedef unsigned short UCV16;
+
+/* Limits */
+#define CID_MAX_CID 65535
+#define CID_MAX CID_MAX_CID
+
+#define CID_NOTDEF_CHAR "\0\0"
+#define CID_NOTDEF 0
+
+#define UCS_NOTDEF_CHAR "\377\375"
+#define UCS_NOTDEF 0xfffd
+
+/*
+ * TYPE_IDENTITY and TYPE_CID_TO_CODE is not defined in the CMap spec.
+ */
+#define CMAP_TYPE_IDENTITY 0
+#define CMAP_TYPE_CODE_TO_CID 1
+#define CMAP_TYPE_TO_UNICODE 2
+#define CMAP_TYPE_CID_TO_CODE 3
+
+#define CMAP_PROF_TYPE_INBYTES_MIN 0
+#define CMAP_PROF_TYPE_INBYTES_MAX 1
+#define CMAP_PROF_TYPE_OUTBYTES_MIN 2
+#define CMAP_PROF_TYPE_OUTBYTES_MAX 3
+
+typedef struct CMap CMap;
+
+
+/************************** CMAP_MAIN **************************/
+
+extern void CMap_set_silent (int value);
+
+extern CMap *CMap_new (void);
+extern void CMap_release (CMap *cmap);
+
+extern int CMap_is_valid (CMap *cmap);
+extern int CMap_is_Identity (CMap *cmap);
+extern int CMap_get_profile (CMap *cmap, int type);
+
+extern char *CMap_get_name (CMap *cmap);
+extern int CMap_get_type (CMap *cmap);
+extern int CMap_get_wmode(CMap *cmap);
+extern CIDSysInfo *CMap_get_CIDSysInfo(CMap *cmap);
+
+extern void CMap_set_name (CMap *cmap, const char *name);
+extern void CMap_set_type (CMap *cmap, int type);
+extern void CMap_set_wmode (CMap *cmap, int wmode);
+extern void CMap_set_usecmap(CMap *cmap, CMap *ucmap);
+extern void CMap_set_CIDSysInfo (CMap *cmap, const CIDSysInfo *csi);
+
+/* charName not supported */
+extern int CMap_add_bfchar (CMap *cmap,
+ const unsigned char *src, int srcdim,
+ const unsigned char *dest, int destdim);
+extern int CMap_add_cidchar (CMap *cmap,
+ const unsigned char *src, int srcdim, CID dest);
+extern int CMap_add_bfrange (CMap *cmap,
+ const unsigned char *srclo, const unsigned char *srchi, int srcdim,
+ const unsigned char *dest, int destdim);
+extern int CMap_add_cidrange(CMap *cmap,
+ const unsigned char *srclo, const unsigned char *hi, int srcdim,
+ CID base);
+
+extern int CMap_add_notdefchar (CMap *cmap, const unsigned char *src, int srcdim, CID dst);
+extern int CMap_add_notdefrange (CMap *cmap,
+ const unsigned char *srclo, const unsigned char *srchi, int srcdim,
+ CID dst);
+
+extern int CMap_add_codespacerange (CMap *cmap,
+ const unsigned char *codelo, const unsigned char *codehi, int dim);
+
+extern void CMap_decode_char (CMap *cmap,
+ const unsigned char **inbuf, int *inbytesleft,
+ unsigned char **outbuf, int *outbytesleft);
+
+extern int CMap_decode (CMap *cmap,
+ const unsigned char **inbuf, int *inbytesleft,
+ unsigned char **outbuf, int *outbytesleft);
+
+extern void CMap_cache_init (void);
+extern CMap *CMap_cache_get (int id);
+extern int CMap_cache_find (const char *cmap_name);
+extern void CMap_cache_close (void);
+extern int CMap_cache_add (CMap *cmap);
+
+#endif /* _CMAP_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cmap_p.h b/Build/source/texk/dvipdfm-x/cmap_p.h
new file mode 100644
index 00000000000..6bd082ebf90
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cmap_p.h
@@ -0,0 +1,101 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CMAP_P_H_
+#define _CMAP_P_H_
+
+#include "cid.h"
+
+/* Mapping types, MAP_IS_NAME is not supported. */
+#define MAP_IS_CID (1 << 0)
+#define MAP_IS_NAME (1 << 1)
+#define MAP_IS_CODE (1 << 2)
+#define MAP_IS_NOTDEF (1 << 3)
+
+#define MAP_IS_UNDEF 0
+#define MAP_TYPE_MASK 0x00f
+
+#define MAP_DEFINED(e) (((e) & MAP_TYPE_MASK) != MAP_IS_UNDEF ? 1 : 0)
+#define MAP_TYPE(e) ((e) & MAP_TYPE_MASK)
+
+/* Lookup flags */
+#define MAP_LOOKUP_END 0
+#define MAP_LOOKUP_CONTINUE (1 << 4)
+#define LOOKUP_CONTINUE(f) ((f) & MAP_LOOKUP_CONTINUE)
+#define LOOKUP_END(f) (!LOOKUP_CONTINUE((f)))
+
+/* DEBUG */
+#define CMAP_DEBUG_STR "CMap"
+#define CMAP_DEBUG 3
+
+/* Codespacerange */
+typedef struct rangeDef {
+ int dim; /* Dimension of this codespacerange */
+ unsigned char *codeLo; /* Lower bounds of valid input code */
+ unsigned char *codeHi; /* Upper bounds of valid input code */
+} rangeDef;
+
+typedef struct mapDef {
+ int flag;
+ int len; /* 2 for CID, variable for Code.. */
+ unsigned char *code; /* CID (as 16-bit BE), Code ... */
+ struct mapDef *next; /* Next Subtbl for LOOKUP_CONTINUE */
+} mapDef;
+
+#define MEM_ALLOC_SIZE 4096
+typedef struct mapData {
+ unsigned char *data; /* CID, Code... MEM_ALLOC_SIZE bytes */
+ struct mapData *prev; /* Previous mapData data segment */
+ int pos; /* Position of next free data segment */
+} mapData;
+
+struct CMap {
+ char *name;
+ int type; /* CMapType: 1 for usual CMaps,
+ * 2 for ToUnicode CMaps,
+ * 0 for IDENTITY is also defined for convenience.
+ */
+ int wmode; /* WMode: 0 for Horizontal, 1 for Vertical. */
+ CIDSysInfo *CSI; /* CIDSystemInfo */
+
+ struct CMap *useCMap;
+
+ struct {
+ int num;
+ int max;
+ rangeDef *ranges;
+ } codespace;
+
+ mapDef *mapTbl; /* First 256 segment of mapping table */
+ mapData *mapData; /* Storage for actual CMap data */
+
+ /* Additional data used by cmap.c, etc. */
+
+ int flags; /* Decoder flags Not used yet. */
+
+ struct {
+ int minBytesIn;
+ int maxBytesIn;
+ int minBytesOut;
+ int maxBytesOut;
+ } profile;
+};
+
+#endif /* _CMAP_P_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cmap_read.c b/Build/source/texk/dvipdfm-x/cmap_read.c
new file mode 100644
index 00000000000..14100cc3b35
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cmap_read.c
@@ -0,0 +1,605 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxconf.h"
+#include "dpxutil.h"
+#include "pst.h"
+
+#include "cmap_p.h"
+#include "cmap.h"
+
+#include "cmap_read.h"
+
+#define CMAP_PARSE_DEBUG_STR "CMap_parse:"
+#define CMAP_PARSE_DEBUG 3
+
+#ifdef HAVE_DPXFILE
+#include "dpxfile.h"
+#else
+#include "mfileio.h"
+
+typedef struct {
+ unsigned char *cursor;
+ unsigned char *endptr;
+
+ unsigned char *buf;
+ size_t max;
+ FILE *fp;
+ size_t unread;
+} ifreader;
+
+static ifreader *ifreader_create (FILE *fp, size_t remain, size_t bufsize);
+static size_t ifreader_read (ifreader *reader, size_t size);
+static void ifreader_destroy (ifreader *reader);
+
+static ifreader *
+ifreader_create (FILE *fp, size_t size, size_t bufsize)
+{
+ ifreader *reader;
+
+ reader = NEW(1, ifreader);
+ reader->buf = NEW(bufsize+1, unsigned char);
+ reader->max = bufsize;
+ reader->fp = fp;
+ reader->unread = size;
+
+ reader->cursor = reader->endptr = reader->buf;
+ *reader->endptr = 0;
+
+ return reader;
+}
+
+static void
+ifreader_destroy (ifreader *reader)
+{
+ ASSERT(reader);
+ if (reader->buf)
+ RELEASE(reader->buf);
+ RELEASE(reader);
+}
+
+
+static size_t
+ifreader_read (ifreader *reader, size_t size)
+{
+ size_t bytesread = 0, bytesrem = 0;
+
+ ASSERT(reader);
+ bytesrem = (size_t) reader->endptr - (size_t) reader->cursor;
+ if (size > reader->max) {
+ reader->buf = RENEW(reader->buf, size+1, unsigned char);
+ reader->max = size;
+ }
+ if (reader->unread > 0 && bytesrem < size) {
+ bytesread = MIN(reader->max - bytesrem, reader->unread);
+ memmove(reader->buf, reader->cursor, bytesrem);
+ reader->cursor = reader->buf;
+ reader->endptr = reader->buf + bytesrem;
+ if (fread(reader->endptr, 1, bytesread, reader->fp) != bytesread)
+ ERROR("Reading file failed.");
+ reader->endptr += bytesread;
+ reader->unread -= bytesread;
+ }
+
+ *reader->endptr = 0;
+
+ return bytesread + bytesrem;
+}
+#define ifreader_need(f,s) ifreader_read((f),(s))
+
+#endif /* HAVE_DPXFILE */
+
+static int check_next_token (ifreader *input, const char *key);
+static int get_coderange (ifreader *input, unsigned char *codeLo, unsigned char *codeHi, int *dim, int maxlen);
+
+static int handle_codearray (CMap *cmap, ifreader *input, unsigned char *codeLo, int dim, int count);
+static int do_codespacerange (CMap *cmap, ifreader *input, int count);
+static int do_notdefrange (CMap *cmap, ifreader *input, int count);
+static int do_bfrange (CMap *cmap, ifreader *input, int count);
+static int do_cidrange (CMap *cmap, ifreader *input, int count);
+static int do_notdefchar (CMap *cmap, ifreader *input, int count);
+static int do_bfchar (CMap *cmap, ifreader *input, int count);
+static int do_cidchar (CMap *cmap, ifreader *input, int count);
+
+#define TOKEN_LEN_MAX 127
+
+static int
+check_next_token (ifreader *input, const char *key)
+{
+ int cmp;
+ pst_obj *token;
+ char *str;
+
+ if (ifreader_need(input, strlen(key)) == 0)
+ return -1;
+ if ((token = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+
+ str = (char *) pst_getSV(token);
+ cmp = strcmp(str, key) ? -1 : 0;
+ if (str)
+ RELEASE(str);
+ pst_release_obj(token);
+
+ return cmp;
+}
+
+static int
+get_coderange (ifreader *input,
+ unsigned char *codeLo, unsigned char *codeHi, int *dim, int maxlen)
+{
+ pst_obj *tok1, *tok2;
+ int dim1, dim2;
+
+ if ((tok1 = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) == NULL) {
+ pst_release_obj(tok1);
+ return -1;
+ }
+
+ if (!PST_STRINGTYPE(tok1) || !PST_STRINGTYPE(tok2)) {
+ pst_release_obj(tok1);
+ pst_release_obj(tok2);
+ return -1;
+ }
+
+ dim1 = pst_length_of(tok1);
+ dim2 = pst_length_of(tok2);
+ if (dim1 != dim2 || dim1 > maxlen) {
+ pst_release_obj(tok1);
+ pst_release_obj(tok2);
+ return -1;
+ }
+
+ memcpy(codeLo, pst_data_ptr(tok1), dim1);
+ memcpy(codeHi, pst_data_ptr(tok2), dim2);
+ pst_release_obj(tok1);
+ pst_release_obj(tok2);
+
+ *dim = dim1;
+ return 0;
+}
+
+static int
+do_codespacerange (CMap *cmap, ifreader *input, int count)
+{
+ unsigned char codeLo[TOKEN_LEN_MAX], codeHi[TOKEN_LEN_MAX];
+ int dim;
+
+ while (count-- > 0) {
+ if (get_coderange(input, codeLo, codeHi, &dim, TOKEN_LEN_MAX) < 0)
+ return -1;
+ CMap_add_codespacerange(cmap, codeLo, codeHi, dim);
+ }
+
+ return check_next_token(input, "endcodespacerange");
+}
+
+/*
+ * bfrange
+ * <codeLo> <codeHi> [destCode1 destCode2 ...]
+ */
+static int
+handle_codearray (CMap *cmap, ifreader *input, unsigned char *codeLo, int dim, int count)
+{
+ pst_obj *tok = NULL;
+
+ if (dim < 1)
+ ERROR("Invalid code range.");
+ while (count-- > 0) {
+ if ((tok = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ else if (PST_STRINGTYPE(tok)) {
+ CMap_add_bfchar(cmap, codeLo, dim, (unsigned char *) pst_data_ptr(tok), pst_length_of(tok));
+ } else if (PST_MARKTYPE(tok) || !PST_NAMETYPE(tok))
+ ERROR("%s: Invalid CMap mapping record.", CMAP_PARSE_DEBUG_STR);
+ else
+ ERROR("%s: Mapping to charName not supported.", CMAP_PARSE_DEBUG_STR);
+ pst_release_obj(tok);
+ codeLo[dim-1] += 1;
+ }
+
+ return check_next_token(input, "]");
+}
+
+static int
+do_notdefrange (CMap *cmap, ifreader *input, int count)
+{
+ pst_obj *tok;
+ unsigned char codeLo[TOKEN_LEN_MAX], codeHi[TOKEN_LEN_MAX];
+ int dstCID;
+ int dim;
+
+ while (count-- > 0) {
+ if (ifreader_need(input, TOKEN_LEN_MAX*3) == 0)
+ return -1;
+ if (get_coderange(input, codeLo, codeHi, &dim, TOKEN_LEN_MAX) < 0 ||
+ (tok = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ if (PST_INTEGERTYPE(tok)) {
+ dstCID = pst_getIV(tok);
+ if (dstCID >= 0 && dstCID <= CID_MAX)
+ CMap_add_notdefrange(cmap, codeLo, codeHi, dim, (CID) dstCID);
+ } else
+ WARN("%s: Invalid CMap mapping record. (ignored)", CMAP_PARSE_DEBUG_STR);
+ pst_release_obj(tok);
+ }
+
+ return check_next_token(input, "endnotdefrange");
+}
+
+static int
+do_bfrange (CMap *cmap, ifreader *input, int count)
+{
+ pst_obj *tok;
+ unsigned char codeLo[TOKEN_LEN_MAX], codeHi[TOKEN_LEN_MAX];
+ int srcdim;
+
+ while (count-- > 0) {
+ if (ifreader_need(input, TOKEN_LEN_MAX*3) == 0)
+ return -1;
+ if (get_coderange(input, codeLo, codeHi, &srcdim, TOKEN_LEN_MAX) < 0 ||
+ (tok = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ if (PST_STRINGTYPE(tok)) {
+ CMap_add_bfrange(cmap, codeLo, codeHi, srcdim,
+ (unsigned char *) pst_data_ptr(tok), pst_length_of(tok));
+ } else if (PST_MARKTYPE(tok)) {
+ if (handle_codearray(cmap, input, codeLo, srcdim,
+ codeHi[srcdim-1] - codeLo[srcdim-1] + 1) < 0) {
+ pst_release_obj(tok);
+ return -1;
+ }
+ } else
+ WARN("%s: Invalid CMap mapping record. (ignored)", CMAP_PARSE_DEBUG_STR);
+ pst_release_obj(tok);
+ }
+
+ return check_next_token(input, "endbfrange");
+}
+
+static int
+do_cidrange (CMap *cmap, ifreader *input, int count)
+{
+ pst_obj *tok;
+ unsigned char codeLo[TOKEN_LEN_MAX], codeHi[TOKEN_LEN_MAX];
+ int dstCID;
+ int dim;
+
+ while (count-- > 0) {
+ if (ifreader_need(input, TOKEN_LEN_MAX*3) == 0)
+ return -1;
+ if (get_coderange(input, codeLo, codeHi, &dim, TOKEN_LEN_MAX) < 0 ||
+ (tok = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ if (PST_INTEGERTYPE(tok)) {
+ dstCID = pst_getIV(tok);
+ if (dstCID >= 0 && dstCID <= CID_MAX)
+ CMap_add_cidrange(cmap, codeLo, codeHi, dim, (CID) dstCID);
+ } else
+ WARN("%s: Invalid CMap mapping record. (ignored)", CMAP_PARSE_DEBUG_STR);
+ pst_release_obj(tok);
+ }
+
+ return check_next_token(input, "endcidrange");
+}
+
+static int
+do_notdefchar (CMap *cmap, ifreader *input, int count)
+{
+ pst_obj *tok1, *tok2;
+ int dstCID;
+
+ while (count-- > 0) {
+ if (ifreader_need(input, TOKEN_LEN_MAX*2) == 0)
+ return -1;
+ if ((tok1 = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) == NULL) {
+ pst_release_obj(tok1);
+ return -1;
+ }
+ if (PST_STRINGTYPE(tok1) && PST_INTEGERTYPE(tok2)) {
+ dstCID = pst_getIV(tok2);
+ if (dstCID >= 0 && dstCID <= CID_MAX)
+ CMap_add_notdefchar(cmap, pst_data_ptr(tok1), pst_length_of(tok1), (CID) dstCID);
+ } else
+ WARN("%s: Invalid CMap mapping record. (ignored)", CMAP_PARSE_DEBUG_STR);
+ pst_release_obj(tok1);
+ pst_release_obj(tok2);
+ }
+
+ return check_next_token(input, "endnotdefchar");
+}
+
+static int
+do_bfchar (CMap *cmap, ifreader *input, int count)
+{
+ pst_obj *tok1, *tok2;
+
+ while (count-- > 0) {
+ if (ifreader_need(input, TOKEN_LEN_MAX*2) == 0)
+ return -1;
+ if ((tok1 = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) == NULL) {
+ pst_release_obj(tok1);
+ return -1;
+ }
+ /* We only support single CID font as descendant font, charName should not come here. */
+ if (PST_STRINGTYPE(tok1) && PST_STRINGTYPE(tok2)) {
+ CMap_add_bfchar(cmap,
+ (unsigned char *) pst_data_ptr(tok1), pst_length_of(tok1),
+ (unsigned char *) pst_data_ptr(tok2), pst_length_of(tok2));
+ } else if (PST_NAMETYPE(tok2))
+ ERROR("%s: Mapping to charName not supported.", CMAP_PARSE_DEBUG_STR);
+ else
+ WARN("%s: Invalid CMap mapping record. (ignored)", CMAP_PARSE_DEBUG_STR);
+ pst_release_obj(tok1);
+ pst_release_obj(tok2);
+ }
+
+ return check_next_token(input, "endbfchar");
+}
+
+static int
+do_cidchar (CMap *cmap, ifreader *input, int count)
+{
+ pst_obj *tok1, *tok2;
+ int dstCID;
+
+ while (count-- > 0) {
+ if (ifreader_need(input, TOKEN_LEN_MAX*2) == 0)
+ return -1;
+ if ((tok1 = pst_get_token(&(input->cursor), input->endptr)) == NULL)
+ return -1;
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) == NULL) {
+ pst_release_obj(tok1);
+ return -1;
+ }
+ if (PST_STRINGTYPE(tok1) && PST_INTEGERTYPE(tok2)) {
+ dstCID = pst_getIV(tok2);
+ if (dstCID >= 0 && dstCID <= CID_MAX)
+ CMap_add_cidchar(cmap, pst_data_ptr(tok1), pst_length_of(tok1), (CID) dstCID);
+ } else
+ WARN("%s: Invalid CMap mapping record. (ignored)", CMAP_PARSE_DEBUG_STR);
+ pst_release_obj(tok1);
+ pst_release_obj(tok2);
+ }
+
+ return check_next_token(input, "endcidchar");
+}
+
+
+#define MATCH_NAME(t,n) (PST_NAMETYPE((t)) && (pst_length_of((t)) == strlen((n))) && !memcmp(pst_data_ptr((t)),(n),strlen((n))))
+#define MATCH_OP(t,n) (PST_UNKNOWNTYPE((t)) && (pst_length_of((t)) == strlen((n))) && !memcmp(pst_data_ptr((t)),(n),strlen((n))))
+
+static int
+do_cidsysteminfo (CMap *cmap, ifreader *input)
+{
+ pst_obj *tok1, *tok2;
+ CIDSysInfo csi = {NULL, NULL, -1};
+ int simpledict = 0;
+ int error = 0;
+
+ ifreader_need(input, TOKEN_LEN_MAX*2);
+ /*
+ * Assuming /CIDSystemInfo 3 dict dup begin .... end def
+ * or /CIDSystemInfo << ... >> def
+ */
+ while ((tok1 = pst_get_token(&(input->cursor), input->endptr)) != NULL) {
+ if (PST_MARKTYPE(tok1)) {
+ simpledict = 1;
+ pst_release_obj(tok1);
+ break;
+ } else if (MATCH_OP(tok1, "begin")) {
+ simpledict = 0;
+ pst_release_obj(tok1);
+ break;
+ } else {
+ pst_release_obj(tok1);
+ /* continue */
+ }
+ }
+ tok1 = tok2 = NULL;
+ while (!error &&
+ (tok1 = pst_get_token(&(input->cursor), input->endptr)) != NULL) {
+ if (MATCH_OP(tok1, ">>") && simpledict) {
+ pst_release_obj(tok1);
+ break;
+ } else if (MATCH_OP(tok1, "end") && !simpledict) {
+ pst_release_obj(tok1);
+ break;
+ } else if (MATCH_NAME(tok1, "Registry") &&
+ (tok2 = pst_get_token(&(input->cursor), input->endptr)) != NULL) {
+ if (!PST_STRINGTYPE(tok2))
+ error = -1;
+ else if (!simpledict &&
+ check_next_token(input, "def"))
+ error = -1;
+ if (!error)
+ csi.registry = (char *) pst_getSV(tok2);
+ } else if (MATCH_NAME(tok1, "Ordering") &&
+ (tok2 = pst_get_token(&(input->cursor), input->endptr)) != NULL) {
+ if (!PST_STRINGTYPE(tok2))
+ error = -1;
+ else if (!simpledict &&
+ check_next_token(input, "def"))
+ error = -1;
+ if (!error)
+ csi.ordering = (char *) pst_getSV(tok2);
+ } else if (MATCH_NAME(tok1, "Supplement") &&
+ (tok2 = pst_get_token(&(input->cursor), input->endptr)) != NULL) {
+ if (!PST_INTEGERTYPE(tok2))
+ error = -1;
+ else if (!simpledict &&
+ check_next_token(input, "def"))
+ error = -1;
+ if (!error)
+ csi.supplement = pst_getIV(tok2);
+ }
+ if (tok2)
+ pst_release_obj(tok2);
+ if (tok1)
+ pst_release_obj(tok1);
+ tok1 = tok2 = NULL;
+ }
+ if (!error &&
+ check_next_token(input, "def"))
+ error = -1;
+
+ if (!error &&
+ csi.registry && csi.ordering &&
+ csi.supplement >= 0) {
+ CMap_set_CIDSysInfo(cmap, &csi);
+ }
+
+ if (csi.registry)
+ RELEASE(csi.registry);
+ if (csi.ordering)
+ RELEASE(csi.ordering);
+
+ return error;
+}
+
+#define INPUT_BUF_SIZE 4096
+#define CMAP_SIG_MAX 64
+int
+CMap_parse_check_sig (FILE *fp)
+{
+ int result = -1;
+ char sig[CMAP_SIG_MAX+1];
+
+ if (!fp)
+ return -1;
+
+ rewind(fp);
+ if (fread(sig, sizeof(char), CMAP_SIG_MAX, fp) != CMAP_SIG_MAX)
+ result = -1;
+ else {
+ sig[CMAP_SIG_MAX] = 0;
+ if (strncmp(sig, "%!PS", 4))
+ result = -1;
+ else if (strstr(sig+4, "Resource-CMap"))
+ result = 0;
+ }
+ rewind(fp);
+
+ return result;
+}
+
+int
+CMap_parse (CMap *cmap, FILE *fp)
+{
+ pst_obj *tok1, *tok2;
+ ifreader *input;
+ int status = 0, tmpint = -1;
+
+ ASSERT(cmap && fp);
+
+ input = ifreader_create(fp, file_size(fp), INPUT_BUF_SIZE-1);
+
+ while (status >= 0) {
+ tok1 = tok2 = NULL;
+ ifreader_read(input, INPUT_BUF_SIZE/2);
+ tok1 = pst_get_token(&(input->cursor), input->endptr);
+ if (tok1 == NULL)
+ break;
+ else if (MATCH_NAME(tok1, "CMapName")) {
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) == NULL ||
+ !(PST_NAMETYPE(tok2) || PST_STRINGTYPE(tok2)) ||
+ check_next_token(input, "def") < 0)
+ status = -1;
+ else
+ CMap_set_name(cmap, pst_data_ptr(tok2));
+ } else if (MATCH_NAME(tok1, "CMapType")) {
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) == NULL ||
+ !PST_INTEGERTYPE(tok2) ||
+ check_next_token(input, "def") < 0)
+ status = -1;
+ else
+ CMap_set_type(cmap, pst_getIV(tok2));
+ } else if (MATCH_NAME(tok1, "WMode")) {
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) == NULL ||
+ !PST_INTEGERTYPE(tok2) ||
+ check_next_token(input, "def") < 0)
+ status = -1;
+ else
+ CMap_set_wmode(cmap, pst_getIV(tok2));
+ } else if (MATCH_NAME(tok1, "CIDSystemInfo")) {
+ status = do_cidsysteminfo(cmap, input);
+ } else if (MATCH_NAME(tok1, "Version") ||
+ MATCH_NAME(tok1, "UIDOffset") ||
+ MATCH_NAME(tok1, "XUID")) {
+ /* Ignore */
+ } else if (PST_NAMETYPE(tok1)) {
+ /* Possibly usecmap comes next */
+ if ((tok2 = pst_get_token(&(input->cursor), input->endptr)) != NULL &&
+ MATCH_OP(tok2, "usecmap")) {
+ int id;
+ CMap *ucmap;
+ id = CMap_cache_find(pst_data_ptr(tok1));
+ if (id < 0)
+ status = -1;
+ else {
+ ucmap = CMap_cache_get(id);
+ CMap_set_usecmap(cmap, ucmap);
+ }
+ }
+ } else if (MATCH_OP(tok1, "begincodespacerange")) {
+ status = do_codespacerange(cmap, input, tmpint);
+ } else if (MATCH_OP(tok1, "beginnotdefrange")) {
+ status = do_notdefrange(cmap, input, tmpint);
+ } else if (MATCH_OP(tok1, "beginnotdefchar")) {
+ status = do_notdefchar(cmap, input, tmpint);
+ } else if (MATCH_OP(tok1, "beginbfrange")) {
+ status = do_bfrange(cmap, input, tmpint);
+ } else if (MATCH_OP(tok1, "beginbfchar")) {
+ status = do_bfchar(cmap, input, tmpint);
+ } else if (MATCH_OP(tok1, "begincidrange")) {
+ status = do_cidrange(cmap, input, tmpint);
+ } else if (MATCH_OP(tok1, "begincidchar")) {
+ status = do_cidchar(cmap, input, tmpint);
+ } else if (PST_INTEGERTYPE(tok1)) {
+ tmpint = pst_getIV(tok1);
+ } /* else Simply ignore */
+ if (tok1)
+ pst_release_obj(tok1);
+ if (tok2)
+ pst_release_obj(tok2);
+ }
+
+ ifreader_destroy(input);
+
+ return (status < 0) ? -1 : CMap_is_valid(cmap);
+}
diff --git a/Build/source/texk/dvipdfm-x/cmap_read.h b/Build/source/texk/dvipdfm-x/cmap_read.h
new file mode 100644
index 00000000000..df7b10b73ef
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cmap_read.h
@@ -0,0 +1,32 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CMAP_READ_H_
+#define _CMAP_READ_H_
+
+#include <stdio.h>
+#include "cmap.h"
+
+extern int CMap_parse_check_sig (FILE *fp);
+extern int CMap_parse (CMap *cmap, FILE *fp);
+
+#endif /* _CMAP_READ_H_ */
diff --git a/Build/source/texk/dvipdfm-x/cmap_write.c b/Build/source/texk/dvipdfm-x/cmap_write.c
new file mode 100644
index 00000000000..3af5f9acbe7
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cmap_write.c
@@ -0,0 +1,690 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * References:
+ *
+ * PostScript Language Reference Manual, 3rd. ed. (Adobe Systems Inc.)
+ * 5.11.4 CMap Dictionaries
+ * 5.11.5 FMapType 9 Composite Fonts
+ * Building CMap Files for CID-Keyed Fonts, Adobe Technical Note #5099
+ * CID-Keyed Font Technology Overview, Adobe Technical Note #5092
+ * Adobe CMap and CIDFont Files Specification, Adobe Technical Specification #5014
+ *
+ * Undefined Character Handling:
+ * PLRM 3rd. ed., sec. 5.11.5., "Handling Undefined Characters"
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+#include "pdfresource.h"
+
+#include "cmap_p.h"
+#include "cmap.h"
+
+#include "cmap_write.h"
+
+struct sbuf {
+ char *buf;
+ char *curptr;
+ char *limptr;
+};
+
+static int write_map (mapDef *mtab, int count,
+ unsigned char *codestr, int depth,
+ struct sbuf *wbuf, pdf_obj *stream);
+#if 0
+/* Not completed yet */
+
+/* used_slot...
+ * This is for collecting only used CIDs.
+ * add_inverse_map never supports code-to-code of
+ * cid-to-code mapping.
+ */
+static int add_inverse_map (CMap *icmap, mapDef *mtab,
+ unsigned char *codestr, int depth,
+ unsigned char *used_slot);
+static int add_map (CMap *cmap, mapDef *mtab,
+ unsigned char *codestr, int depth);
+static CMap *invert_cmap (CMap *cmap, unsigned char *used_slot);
+static CMap *flatten_cmap (CMap *cmap);
+#endif /* 0 */
+
+static int
+block_count (mapDef *mtab, int c)
+{
+ int count = 0, n;
+
+ n = mtab[c].len - 1;
+ c += 1;
+ for (; c < 256; c++) {
+ if (LOOKUP_CONTINUE(mtab[c].flag) ||
+ !MAP_DEFINED(mtab[c].flag) ||
+ (MAP_TYPE(mtab[c].flag) != MAP_IS_CID &&
+ MAP_TYPE(mtab[c].flag) != MAP_IS_CODE) ||
+ mtab[c-1].len != mtab[c].len)
+ break;
+ else if (!memcmp(mtab[c-1].code, mtab[c].code, n) &&
+ mtab[c-1].code[n] < 255 &&
+ mtab[c-1].code[n] + 1 == mtab[c].code[n])
+ count++;
+ else {
+ break;
+ }
+ }
+
+ return count;
+}
+
+static int
+sputx (unsigned char c, char **s, char *end)
+{
+ char hi = (c >> 4), lo = c & 0x0f;
+
+ if (*s + 2 > end)
+ ERROR("Buffer overflow.");
+ **s = (hi < 10) ? hi + '0' : hi + '7';
+ *(*s+1) = (lo < 10) ? lo + '0' : lo + '7';
+ *s += 2;
+
+ return 2;
+}
+
+static int
+write_map (mapDef *mtab, int count,
+ unsigned char *codestr, int depth,
+ struct sbuf *wbuf, pdf_obj *stream)
+{
+ int c, i, block_length;
+ mapDef *mtab1;
+ /* Must be greater than 1 */
+#define BLOCK_LEN_MIN 2
+ struct {
+ int start, count;
+ } blocks[256/BLOCK_LEN_MIN+1];
+ int num_blocks = 0;
+
+ for (c = 0; c < 256; c++) {
+ codestr[depth] = (unsigned char) (c & 0xff);
+ if (LOOKUP_CONTINUE(mtab[c].flag)) {
+ mtab1 = mtab[c].next;
+ count = write_map(mtab1, count,
+ codestr, depth + 1, wbuf, stream);
+ } else {
+ if (MAP_DEFINED(mtab[c].flag)) {
+ switch (MAP_TYPE(mtab[c].flag)) {
+ case MAP_IS_CID: case MAP_IS_CODE:
+ block_length = block_count(mtab, c);
+ if (block_length >= BLOCK_LEN_MIN) {
+ blocks[num_blocks].start = c;
+ blocks[num_blocks].count = block_length;
+ num_blocks++;
+ c += block_length;
+ } else {
+ *(wbuf->curptr)++ = '<';
+ for (i = 0; i <= depth; i++)
+ sputx(codestr[i], &(wbuf->curptr), wbuf->limptr);
+ *(wbuf->curptr)++ = '>';
+ *(wbuf->curptr)++ = ' ';
+ *(wbuf->curptr)++ = '<';
+ for (i = 0; i < mtab[c].len; i++)
+ sputx(mtab[c].code[i], &(wbuf->curptr), wbuf->limptr);
+ *(wbuf->curptr)++ = '>';
+ *(wbuf->curptr)++ = '\n';
+ count++;
+ }
+ break;
+ case MAP_IS_NAME:
+ ERROR("%s: Unexpected error...", CMAP_DEBUG_STR);
+ break;
+ case MAP_IS_NOTDEF:
+ break;
+ default:
+ ERROR("%s: Unknown mapping type: %d",
+ CMAP_DEBUG_STR, MAP_TYPE(mtab[c].flag));
+ }
+ }
+ }
+
+ /* Flush if necessary */
+ if (count >= 100 ||
+ wbuf->curptr >= wbuf->limptr ) {
+ char fmt_buf[32];
+ if (count > 100)
+ ERROR("Unexpected error....: %d", count);
+ sprintf(fmt_buf, "%d beginbfchar\n", count);
+ pdf_add_stream(stream, fmt_buf, strlen(fmt_buf));
+ pdf_add_stream(stream,
+ wbuf->buf, (int) (wbuf->curptr - wbuf->buf));
+ wbuf->curptr = wbuf->buf;
+ pdf_add_stream(stream,
+ "endbfchar\n", strlen("endbfchar\n"));
+ count = 0;
+ }
+ }
+
+ if (num_blocks > 0) {
+ char fmt_buf[32];
+
+ if (count > 0) {
+ sprintf(fmt_buf, "%d beginbfchar\n", count);
+ pdf_add_stream(stream, fmt_buf, strlen(fmt_buf));
+ pdf_add_stream(stream,
+ wbuf->buf, (int) (wbuf->curptr - wbuf->buf));
+ wbuf->curptr = wbuf->buf;
+ pdf_add_stream(stream,
+ "endbfchar\n", strlen("endbfchar\n"));
+ count = 0;
+ }
+ sprintf(fmt_buf, "%d beginbfrange\n", num_blocks);
+ pdf_add_stream(stream, fmt_buf, strlen(fmt_buf));
+ for (i = 0; i < num_blocks; i++) {
+ int j;
+
+ c = blocks[i].start;
+ *(wbuf->curptr)++ = '<';
+ for (j = 0; j < depth; j++)
+ sputx(codestr[j], &(wbuf->curptr), wbuf->limptr);
+ sputx((unsigned char)c, &(wbuf->curptr), wbuf->limptr);
+ *(wbuf->curptr)++ = '>';
+ *(wbuf->curptr)++ = ' ';
+ *(wbuf->curptr)++ = '<';
+ for (j = 0; j < depth; j++)
+ sputx(codestr[j], &(wbuf->curptr), wbuf->limptr);
+ sputx((unsigned char)(c + blocks[i].count), &(wbuf->curptr), wbuf->limptr);
+ *(wbuf->curptr)++ = '>';
+ *(wbuf->curptr)++ = ' ';
+ *(wbuf->curptr)++ = '<';
+ for (j = 0; j < mtab[c].len; j++)
+ sputx(mtab[c].code[j], &(wbuf->curptr), wbuf->limptr);
+ *(wbuf->curptr)++ = '>';
+ *(wbuf->curptr)++ = '\n';
+ }
+ pdf_add_stream(stream,
+ wbuf->buf, (int) (wbuf->curptr - wbuf->buf));
+ wbuf->curptr = wbuf->buf;
+ pdf_add_stream(stream,
+ "endbfrange\n", strlen("endbfrange\n"));
+ }
+
+ return count;
+}
+
+/* duplicated from pdfobj.c */
+static void
+write_string (char **outptr, char *endptr, const char *string_data)
+{
+ char *p;
+ const char *s;
+ int i, length;
+
+ s = string_data;
+ length = string_data ? strlen(string_data) : 0;
+ p = *outptr;
+
+ *p++ = '(';
+ for (i = 0; i < length; i++) {
+ unsigned char ch;
+
+ ch = s[i];
+ if (ch < 32 || ch > 126) {
+ p += sprintf(p, "\\%03o", ch);
+ } else {
+ switch (ch) {
+ case '(': case ')': case '\\':
+ *p++ = '\\';
+ *p++ = ch;
+ break;
+ default:
+ *p++ = ch;
+ break;
+ }
+ }
+ }
+ *p++ = ')';
+
+ *outptr = p;
+}
+
+static void
+write_name (char **outptr, char *endptr, const char *name_data)
+{
+ char *p;
+ const char *s;
+ int i, length;
+
+ s = name_data;
+ length = name_data ? strlen(name_data) : 0;
+ p = *outptr;
+#ifndef is_delim
+ /* Avoid '{' and '}' for PostScript compatibility? */
+#define is_delim(c) ((c) == '(' || (c) == ')' || \
+ (c) == '/' || \
+ (c) == '<' || (c) == '>' || \
+ (c) == '[' || (c) == ']' || \
+ (c) == '{' || (c) == '}' || \
+ (c) == '%')
+#endif
+ *p++ = '/';
+ for (i = 0; i < length; i++) {
+ if (s[i] < '!' || s[i] > '~' || s[i] == '#' || is_delim(s[i])) {
+ /* ^ "space" is here. */
+ *p++ = '#';
+ sputx(s[i], &p, endptr);
+ } else {
+ *p++ = s[i];
+ }
+ }
+ *outptr = p;
+}
+
+#define CMAP_BEGIN "\
+/CIDInit /ProcSet findresource begin\n\
+12 dict begin\n\
+begincmap\n\
+"
+
+#define CMAP_END "\
+endcmap\n\
+CMapName currentdict /CMap defineresource pop\n\
+end\n\
+end\n\
+"
+
+pdf_obj *
+CMap_create_stream (CMap *cmap)
+{
+ pdf_obj *stream;
+ pdf_obj *stream_dict;
+ CIDSysInfo *csi;
+ struct sbuf wbuf;
+ struct rangeDef *ranges;
+ unsigned char *codestr;
+ int i, j, count = 0;
+
+ if (!cmap || !CMap_is_valid(cmap)) {
+ WARN("Invalid CMap");
+ return NULL;
+ }
+
+ if (cmap->type == CMAP_TYPE_IDENTITY)
+ return NULL;
+
+ stream = pdf_new_stream(STREAM_COMPRESS);
+ stream_dict = pdf_stream_dict(stream);
+
+ csi = CMap_get_CIDSysInfo(cmap);
+ if (!csi) {
+ csi = (cmap->type != CMAP_TYPE_TO_UNICODE) ?
+ &CSI_IDENTITY : &CSI_UNICODE;
+ }
+
+ if (cmap->type != CMAP_TYPE_TO_UNICODE) {
+ pdf_obj *csi_dict;
+
+ csi_dict = pdf_new_dict();
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Registry"),
+ pdf_new_string(csi->registry, strlen(csi->registry)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Ordering"),
+ pdf_new_string(csi->ordering, strlen(csi->ordering)));
+ pdf_add_dict(csi_dict,
+ pdf_new_name("Supplement"),
+ pdf_new_number(csi->supplement));
+
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Type"),
+ pdf_new_name("CMap"));
+ pdf_add_dict(stream_dict,
+ pdf_new_name("CMapName"),
+ pdf_new_name(cmap->name));
+ pdf_add_dict(stream_dict,
+ pdf_new_name("CIDSystemInfo"), csi_dict);
+ if (cmap->wmode != 0)
+ pdf_add_dict(stream_dict,
+ pdf_new_name("WMode"),
+ pdf_new_number(cmap->wmode));
+ }
+
+ /* TODO:
+ * Predefined CMaps need not to be embedded.
+ */
+ if (cmap->useCMap) {
+ ERROR("UseCMap found (not supported yet)...");
+ if (CMap_is_Identity(cmap->useCMap)) { /* not sure */
+ if (CMap_get_wmode(cmap) == 1) {
+ pdf_add_dict(stream_dict,
+ pdf_new_name("UseCMap"),
+ pdf_new_name("Identity-V"));
+ } else {
+ pdf_add_dict(stream_dict,
+ pdf_new_name("UseCMap"),
+ pdf_new_name("Identity-H"));
+ }
+ } else {
+ int res_id;
+ pdf_obj *ucmap_ref;
+
+ res_id = pdf_findresource("CMap", CMap_get_name(cmap->useCMap));
+ if (res_id >= 0) {
+ ucmap_ref = pdf_get_resource_reference(res_id);
+ } else {
+ pdf_obj *ucmap_obj;
+
+ ucmap_obj = CMap_create_stream(cmap->useCMap);
+ if (!ucmap_obj) {
+ ERROR("Uh ah. I cannot continue...");
+ }
+
+ res_id = pdf_defineresource("CMap",
+ CMap_get_name(cmap->useCMap),
+ ucmap_obj, PDF_RES_FLUSH_IMMEDIATE);
+ ucmap_ref = pdf_get_resource_reference(res_id);
+ }
+ pdf_add_dict(stream_dict, pdf_new_name("UseCMap"), ucmap_ref);
+ }
+ }
+
+#define WBUF_SIZE 40960
+ wbuf.buf = NEW(WBUF_SIZE, char);
+ codestr = NEW(cmap->profile.maxBytesIn, unsigned char);
+ memset(codestr, 0, cmap->profile.maxBytesIn);
+
+ wbuf.curptr = wbuf.buf;
+ wbuf.limptr = wbuf.buf + WBUF_SIZE -
+ 2 * (cmap->profile.maxBytesIn + cmap->profile.maxBytesOut) + 16;
+
+ /* Start CMap */
+ pdf_add_stream(stream, (const void *) CMAP_BEGIN, strlen(CMAP_BEGIN));
+
+ wbuf.curptr += sprintf(wbuf.curptr, "/CMapName ");
+ write_name(&wbuf.curptr, wbuf.limptr, cmap->name);
+ wbuf.curptr += sprintf(wbuf.curptr, " def\n");
+ wbuf.curptr += sprintf(wbuf.curptr, "/CMapType %d def\n" , cmap->type);
+ if (cmap->wmode != 0 &&
+ cmap->type != CMAP_TYPE_TO_UNICODE)
+ wbuf.curptr += sprintf(wbuf.curptr, "/WMode %d def\n", cmap->wmode);
+
+#define CMAP_CSI_FMT "/CIDSystemInfo <<\n\
+ /Registry (%s)\n\
+ /Ordering (%s)\n\
+ /Supplement %d\n\
+>> def\n"
+ wbuf.curptr += sprintf(wbuf.curptr, "/CIDSystemInfo <<\n");
+ wbuf.curptr += sprintf(wbuf.curptr, " /Registry ");
+ write_string(&wbuf.curptr, wbuf.limptr, csi->registry);
+ wbuf.curptr += sprintf(wbuf.curptr, "\n");
+ wbuf.curptr += sprintf(wbuf.curptr, " /Ordering ");
+ write_string(&wbuf.curptr, wbuf.limptr, csi->ordering);
+ wbuf.curptr += sprintf(wbuf.curptr, "\n");
+ wbuf.curptr += sprintf(wbuf.curptr, " /Supplement %d\n>> def\n",
+ csi->supplement);
+ pdf_add_stream(stream, wbuf.buf, (int)(wbuf.curptr - wbuf.buf));
+ wbuf.curptr = wbuf.buf;
+
+ /* codespacerange */
+ ranges = cmap->codespace.ranges;
+ wbuf.curptr += sprintf(wbuf.curptr,
+ "%d begincodespacerange\n", cmap->codespace.num);
+ for (i = 0; i < cmap->codespace.num; i++) {
+ *(wbuf.curptr)++ = '<';
+ for (j = 0; j < ranges[i].dim; j++) {
+ sputx(ranges[i].codeLo[j], &(wbuf.curptr), wbuf.limptr);
+ }
+ *(wbuf.curptr)++ = '>';
+ *(wbuf.curptr)++ = ' ';
+ *(wbuf.curptr)++ = '<';
+ for (j = 0; j < ranges[i].dim; j++) {
+ sputx(ranges[i].codeHi[j], &(wbuf.curptr), wbuf.limptr);
+ }
+ *(wbuf.curptr)++ = '>';
+ *(wbuf.curptr)++ = '\n';
+ }
+ pdf_add_stream(stream, wbuf.buf, (int)(wbuf.curptr - wbuf.buf));
+ wbuf.curptr = wbuf.buf;
+ pdf_add_stream(stream,
+ "endcodespacerange\n", strlen("endcodespacerange\n"));
+
+ /* CMap body */
+ if (cmap->mapTbl) {
+ count = write_map(cmap->mapTbl,
+ 0, codestr, 0, &wbuf, stream); /* Top node */
+ if (count > 0) { /* Flush */
+ char fmt_buf[32];
+ if (count > 100)
+ ERROR("Unexpected error....: %d", count);
+ sprintf(fmt_buf, "%d beginbfchar\n", count);
+ pdf_add_stream(stream, fmt_buf, strlen(fmt_buf));
+ pdf_add_stream(stream,
+ wbuf.buf, (int) (wbuf.curptr - wbuf.buf));
+ pdf_add_stream(stream,
+ "endbfchar\n", strlen("endbfchar\n"));
+ count = 0;
+ wbuf.curptr = wbuf.buf;
+ }
+ }
+ /* End CMap */
+ pdf_add_stream(stream, CMAP_END, strlen(CMAP_END));
+
+ RELEASE(codestr);
+ RELEASE(wbuf.buf);
+
+ return stream;
+}
+
+#if 0
+/* Not completed yet */
+
+static int
+add_inverse_map (CMap *icmap, mapDef *mtab,
+ unsigned char *codestr, int depth,
+ unsigned char *used_slot)
+{
+ CID cid;
+ int c;
+ mapDef *mtab1;
+
+ for (c = 0; c < 256; c++) {
+ codestr[depth] = (unsigned char) (c & 0xff);
+ if (LOOKUP_CONTINUE(mtab[c].flag)) {
+ mtab1 = mtab[c].next;
+ add_inverse_map(icmap, mtab1, codestr, depth + 1, used_slot);
+ } else {
+ if (MAP_DEFINED(mtab[c].flag)) {
+ switch (MAP_TYPE(mtab[c].flag)) {
+ /* We should restrict it to to-CID mapping.
+ * However...
+ */
+ case MAP_IS_CID: case MAP_IS_CODE:
+ if (mtab[c].len == 2) {
+ cid = (mtab[c].code[0] << 8)|mtab[c].code[1];
+#ifndef is_used_char2
+#define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8))))
+#endif
+ if (!used_slot ||
+ is_used_char2(used_slot, cid)) {
+ CMap_add_bfchar(icmap,
+ mtab[c].code, mtab[c].len,
+ codestr, depth + 1);
+ }
+ }
+ break;
+ case MAP_IS_NAME:
+ ERROR("%s: Unexpected error...", CMAP_DEBUG_STR);
+ break;
+ case MAP_IS_NOTDEF:
+ break;
+ default:
+ ERROR("%s: Unknown mapping type: %d",
+ CMAP_DEBUG_STR, MAP_TYPE(mtab[c].flag));
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+add_map (CMap *cmap, mapDef *mtab,
+ unsigned char *codestr, int depth)
+{
+ int c;
+ mapDef *mtab1;
+
+ for (c = 0; c < 256; c++) {
+ codestr[depth] = (unsigned char) (c & 0xff);
+ if (LOOKUP_CONTINUE(mtab[c].flag)) {
+ mtab1 = mtab[c].next;
+ add_map(cmap, mtab1, codestr, depth + 1);
+ } else {
+ if (MAP_DEFINED(mtab[c].flag)) {
+ switch (MAP_TYPE(mtab[c].flag)) {
+ case MAP_IS_CID: case MAP_IS_CODE:
+ CMap_add_bfchar(cmap,
+ codestr, depth + 1,
+ mtab[c].code, mtab[c].len);
+ break;
+ case MAP_IS_NAME:
+ ERROR("%s: Unexpected error...", CMAP_DEBUG_STR);
+ break;
+ case MAP_IS_NOTDEF:
+ break;
+ default:
+ ERROR("%s: Unknown mapping type: %d",
+ CMAP_DEBUG_STR, MAP_TYPE(mtab[c].flag));
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static CMap *
+invert_cmap (CMap *cmap, unsigned char *used_slot)
+{
+ CMap *icmap;
+ unsigned char *codestr;
+ unsigned char range_min[2] = {0x00, 0x00}; /* CID */
+ unsigned char range_max[2] = {0xff, 0xfe}; /* CID */
+
+ cmap = flatten_cmap(cmap);
+ ASSERT(cmap);
+
+ icmap = CMap_new();
+ CMap_set_type(icmap, CMAP_TYPE_CID_TO_CODE);
+ CMap_add_codespacerange(icmap, range_min, range_max, 2);
+
+ if (cmap->mapTbl) {
+ codestr = NEW(cmap->profile.maxBytesIn, unsigned char);
+ memset(codestr, 0, cmap->profile.maxBytesIn);
+ add_inverse_map(icmap, cmap->mapTbl,
+ codestr, 0, used_slot); /* top node */
+ RELEASE(codestr);
+ }
+
+ CMap_release(cmap);
+
+ return icmap;
+}
+
+static CMap *
+flatten_cmap (CMap *cmap)
+{
+ CMap *fcmap;
+ rangeDef *range;
+ int i;
+
+ ASSERT(cmap);
+
+ fcmap = CMap_new();
+
+ for (i = 0; i < cmap->codespace.num; i++) {
+ range = &(cmap->codespace.ranges[i]);
+ CMap_add_codespacerange(fcmap, range->codeLo, range->codeHi, range->dim);
+ }
+ CMap_set_CIDSysInfo(fcmap, cmap->CSI);
+ CMap_set_type (fcmap, cmap->type );
+ CMap_set_wmode(fcmap, cmap->wmode);
+
+ fcmap->flags = cmap->flags;
+ fcmap->version = cmap->version;
+
+ while (cmap) {
+ if (cmap->mapTbl) {
+ unsigned char *codestr;
+
+ codestr = NEW(cmap->profile.maxBytesIn, unsigned char);
+ memset(codestr, 0, cmap->profile.maxBytesIn);
+ add_map(fcmap, cmap->mapTbl, codestr, 0); /* top node */
+ RELEASE(codestr);
+ }
+ cmap = cmap->useCMap;
+ }
+
+ return fcmap;
+}
+
+pdf_obj *
+CMap_ToCode_stream (CMap *cmap, const char *cmap_name,
+ CIDSysInfo *csi, int cmap_type,
+ unsigned char *used_slot, int flags)
+{
+ pdf_obj *stream = NULL;
+ CMap *icmap;
+
+ ASSERT(cmap && cmap_name);
+
+ if (cmap->type !=
+ CMAP_TYPE_CODE_TO_CID)
+ return NULL;
+
+ icmap = invert_cmap(cmap, used_slot);
+ if (icmap) {
+ CMap_set_name(icmap, cmap_name);
+ if (csi)
+ CMap_set_CIDSysInfo(icmap, csi);
+ else {
+ CMap_set_CIDSysInfo(icmap, &(CSI_IDENTITY));
+ }
+ CMap_set_type(icmap, cmap_type);
+
+ stream = CMap_create_stream(icmap, flags);
+
+ CMap_release(icmap);
+ }
+
+ return stream;
+}
+#endif /* 0 */
diff --git a/Build/source/texk/dvipdfm-x/cmap_write.h b/Build/source/texk/dvipdfm-x/cmap_write.h
new file mode 100644
index 00000000000..339c86405e2
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cmap_write.h
@@ -0,0 +1,36 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CMAP_WRITE_H_
+#define _CMAP_WRITE_H_
+
+#include "cmap.h"
+
+extern pdf_obj *CMap_create_stream (CMap *cmap);
+#if 0
+/* Not completed yet */
+extern pdf_obj *CMap_ToCode_stream (CMap *cmap, const char *cmap_name,
+ CIDSysInfo *csi, int cmap_type,
+ unsigned char *used_slot, int flags);
+#endif /* 0 */
+
+#endif /* _CMAP_WRITE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/config.h.in b/Build/source/texk/dvipdfm-x/config.h.in
new file mode 100644
index 00000000000..e4bb1e34dc9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/config.h.in
@@ -0,0 +1,267 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+#undef CLOSEDIR_VOID
+
+/* Define to 1 if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define to 1 if you have the `basename' function. */
+#undef HAVE_BASENAME
+
+/* Define to 1 if you have the `close' function. */
+#undef HAVE_CLOSE
+
+/* Define to 1 if you have the declaration of `isascii', and to 0 if you
+ don't. */
+#undef HAVE_DECL_ISASCII
+
+/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
+ */
+#undef HAVE_DECL_TZNAME
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getenv' function. */
+#undef HAVE_GETENV
+
+/* Define to 1 if you have the `getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have libpaper. */
+#undef HAVE_LIBPAPER
+
+/* Define if you have libpng and its headers. */
+#undef HAVE_LIBPNG
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the `memcmp' function. */
+#undef HAVE_MEMCMP
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define to 1 if you have the `mktemp' function. */
+#undef HAVE_MKTEMP
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the `open' function. */
+#undef HAVE_OPEN
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if `st_mtim' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_MTIM
+
+/* Define to 1 if `tm_zone' is a member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if <time.h> has timezone as an external variable. */
+#undef HAVE_TIMEZONE
+
+/* Define if struct tm has tm_gmtoff as a member. */
+#undef HAVE_TM_GMTOFF
+
+/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
+ `HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you don't have `tm_zone' but do have the external array
+ `tzname'. */
+#undef HAVE_TZNAME
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have zlib and its headers. */
+#undef HAVE_ZLIB
+
+/* Define if your zlib has the compress2 function. */
+#undef HAVE_ZLIB_COMPRESS2
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to 1 if <zlib.h> declares 'z_const'. */
+#undef ZLIB_CONST
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int64_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint64_t
+
+/* Define as empty if not declared in <zlib.h>. */
+#undef z_const
diff --git a/Build/source/texk/dvipdfm-x/configure b/Build/source/texk/dvipdfm-x/configure
new file mode 100755
index 00000000000..be146fd367b
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/configure
@@ -0,0 +1,18430 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20210212.
+#
+# Report bugs to <dvipdfmx@tug.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and dvipdfmx@tug.org
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='dvipdfm-x (TeX Live)'
+PACKAGE_TARNAME='dvipdfm-x--tex-live-'
+PACKAGE_VERSION='20210212'
+PACKAGE_STRING='dvipdfm-x (TeX Live) 20210212'
+PACKAGE_BUGREPORT='dvipdfmx@tug.org'
+PACKAGE_URL=''
+
+ac_unique_file="agl.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+WIN32_CALL_FALSE
+WIN32_CALL_TRUE
+WIN32_FALSE
+WIN32_TRUE
+LIBPAPER_RULE
+LIBPAPER_DEPEND
+LIBPAPER_LIBS
+LIBPAPER_INCLUDES
+LIBPNG_RULE
+LIBPNG_DEPEND
+LIBPNG_LIBS
+LIBPNG_INCLUDES
+ZLIB_RULE
+ZLIB_DEPEND
+ZLIB_LIBS
+ZLIB_INCLUDES
+KPATHSEA_RULE
+KPATHSEA_DEPEND
+KPATHSEA_LIBS
+KPATHSEA_INCLUDES
+PKG_CONFIG
+LIBOBJS
+CPP
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+WARNING_CFLAGS
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL
+am__quote'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_maintainer_mode
+enable_dependency_tracking
+enable_compiler_warnings
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_aix_soname
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_largefile
+with_system_kpathsea
+with_system_zlib
+with_zlib_includes
+with_zlib_libdir
+with_system_libpng
+with_system_libpaper
+with_libpaper_includes
+with_libpaper_libdir
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+LT_SYS_LIBRARY_PATH
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures dvipdfm-x (TeX Live) 20210212 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root
+ [DATAROOTDIR/doc/dvipdfm-x--tex-live-]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20210212:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-compiler-warnings=[no|min|yes|max|all]
+ Turn on compiler warnings [default: yes if
+ maintainer-mode, min otherwise]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --disable-largefile omit support for large files
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-aix-soname=aix|svr4|both
+ shared library versioning (aka "SONAME") variant to
+ provide on AIX, [default=aix].
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
+ compiler's sysroot if not specified).
+ --with-system-kpathsea use installed kpathsea headers and library (requires
+ pkg-config)
+ --with-system-zlib use installed zlib headers and library
+ --with-zlib-includes=DIR
+ zlib headers installed in DIR
+ --with-zlib-libdir=DIR zlib library installed in DIR
+ --with-system-libpng use installed libpng headers and library (requires
+ pkg-config)
+ --with-system-libpaper use installed libpaper headers and library
+ --with-libpaper-includes=DIR
+ libpaper headers installed in DIR
+ --with-libpaper-libdir=DIR
+ libpaper library installed in DIR
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ LT_SYS_LIBRARY_PATH
+ User-defined run-time library search path.
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <dvipdfmx@tug.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+dvipdfm-x (TeX Live) configure 20210212
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------- ##
+## Report this to dvipdfmx@tug.org ##
+## ------------------------------- ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+$as_echo_n "checking for int$2_t... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ # Order is important - never check a type that is potentially smaller
+ # than half of the expected target width.
+ for ac_type in int$2_t 'int' 'long int' \
+ 'long long int' 'short int' 'signed char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+ enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+ enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+ < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ case $ac_type in #(
+ int$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+ break
+fi
+ done
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_intX_t
+
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+$as_echo_n "checking for uint$2_t... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ # Order is important - never check a type that is potentially smaller
+ # than half of the expected target width.
+ for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ case $ac_type in #(
+ uint$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+ break
+fi
+ done
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_uintX_t
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ as_decl_name=`echo $2|sed 's/ *(.*//'`
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+ (void) $as_decl_use;
+#else
+ (void) $as_decl_name;
+#endif
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by dvipdfm-x (TeX Live) $as_me 20210212, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+ac_aux_dir=
+for ac_dir in ../../build-aux "$srcdir"/../../build-aux; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../build-aux \"$srcdir\"/../../build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+
+am__api_version='1.16'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ MISSING="\${SHELL} '$am_aux_dir/missing'"
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
+am__doit:
+ @echo this is the am__doit target >confinc.out
+.PHONY: am__doit
+END
+am__include="#"
+am__quote=
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+ { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+ (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ case $?:`cat confinc.out 2>/dev/null` in #(
+ '0:this is the am__doit target') :
+ case $s in #(
+ BSD) :
+ am__include='.include' am__quote='"' ;; #(
+ *) :
+ am__include='include' am__quote='' ;;
+esac ;; #(
+ *) :
+ ;;
+esac
+ if test "$am__include" != "#"; then
+ _am_result="yes ($s style)"
+ break
+ fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+# Check whether --enable-compiler-warnings was given.
+if test "${enable_compiler_warnings+set}" = set; then :
+ enableval=$enable_compiler_warnings;
+fi
+case $enable_compiler_warnings in #(
+ no | min | yes | max | all) :
+ ;; #(
+ *) :
+ if test "x$enable_maintainer_mode" = xyes; then :
+ enable_compiler_warnings=yes
+else
+ enable_compiler_warnings=min
+fi ;;
+esac
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case $ECHO in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+ ac_path_lt_DD_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in dd; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+ $ac_path_lt_DD_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_lt_DD"; then
+ :
+ fi
+else
+ ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[012][,.]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+##tldbg KPSE_COMMON: dvipdfm-x ().
+##tldbg KPSE_BASIC: Remember dvipdfm-x () as Kpse_Package (for future messages).
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='dvipdfm-x--tex-live-'
+ VERSION='20210212'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler accepts prototypes" >&5
+$as_echo_n "checking whether the compiler accepts prototypes... " >&6; }
+if ${kb_cv_c_prototypes+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+int
+main ()
+{
+extern void foo(int i,...);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ kb_cv_c_prototypes=yes
+else
+ kb_cv_c_prototypes=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kb_cv_c_prototypes" >&5
+$as_echo "$kb_cv_c_prototypes" >&6; }
+if test "x$kb_cv_c_prototypes" = xno; then
+ as_fn_error $? "Sorry, your compiler does not understand prototypes." "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what warning flags to pass to the C compiler" >&5
+$as_echo_n "checking what warning flags to pass to the C compiler... " >&6; }
+if ${kpse_cv_warning_cflags+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$GCC" = xyes; then
+ kpse_cv_warning_cflags=
+if test "x$enable_compiler_warnings" != xno; then
+ kpse_cv_warning_cflags="-Wimplicit -Wreturn-type"
+ case `$CC -dumpversion` in #(
+ 3.4.* | 4.* | 5.*) :
+ kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wdeclaration-after-statement" ;; #(
+ *) :
+ ;;
+esac
+ case `$CC -dumpversion` in #(
+ 3.[234].* | 4.* | 5.*) :
+ kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wno-unknown-pragmas" ;; #(
+ *) :
+ ;;
+esac
+ if test "x$enable_compiler_warnings" != xmin; then
+ kpse_cv_warning_cflags="-Wall -Wunused $kpse_cv_warning_cflags"
+ kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wmissing-prototypes -Wmissing-declarations"
+ if test "x$enable_compiler_warnings" != xyes; then
+ kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wparentheses -Wswitch -Wtrigraphs -Wpointer-arith"
+ kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wcast-qual -Wcast-align -Wwrite-strings"
+ case `$CC -dumpversion` in #(
+ 3.4.* | 4.* | 5.*) :
+ kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wold-style-definition" ;; #(
+ *) :
+ ;;
+esac
+ if test "x$enable_compiler_warnings" != xmax; then
+ kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wshadow"
+ fi
+ fi
+ fi
+fi
+elif test "x$enable_compiler_warnings" = xno; then
+ kpse_cv_warning_cflags=
+else
+ kpse_cv_warning_cflags= # FIXME: warning flags for non-GNU C compilers
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_warning_cflags" >&5
+$as_echo "$kpse_cv_warning_cflags" >&6; }
+WARNING_CFLAGS=$kpse_cv_warning_cflags
+
+
+
+
+
+
+
+
+
+
+
+
+# Set options
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+ enable_dlopen=no
+
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+ shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+ withval=$with_aix_soname; case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname
+else
+ if ${lt_cv_with_aix_soname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_with_aix_soname=aix
+fi
+
+ with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/${ac_tool_prefix}file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test yes = "$GCC"; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='$wl--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ export_dynamic_flag_spec='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test no = "$ld_shlibs"; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' $wl-bernotok'
+ allow_undefined_flag=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ ld_shlibs=yes
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ else
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='$wl-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='$wl-z,text'
+ allow_undefined_flag='$wl-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test yes = "$hardcode_automatic"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+ test no != "$hardcode_minus_L"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+ test yes = "$inherit_rpath"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report what library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_source+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGEFILE_SOURCE 1
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_cv_sys_largefile_source=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
+$as_echo "$ac_cv_sys_largefile_source" >&6; }
+case $ac_cv_sys_largefile_source in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+;;
+esac
+rm -rf conftest*
+
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+if test $ac_cv_sys_largefile_source != unknown; then
+
+$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether closedir returns void" >&5
+$as_echo_n "checking whether closedir returns void... " >&6; }
+if ${ac_cv_func_closedir_void+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_closedir_void=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header_dirent>
+#ifndef __cplusplus
+int closedir ();
+#endif
+
+int
+main ()
+{
+return closedir (opendir (".")) != 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_closedir_void=no
+else
+ ac_cv_func_closedir_void=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_closedir_void" >&5
+$as_echo "$ac_cv_func_closedir_void" >&6; }
+if test $ac_cv_func_closedir_void = yes; then
+
+$as_echo "#define CLOSEDIR_VOID 1" >>confdefs.h
+
+fi
+
+for ac_header in assert.h float.h limits.h pwd.h stdlib.h sys/param.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in putenv
+do :
+ ac_fn_c_check_func "$LINENO" "putenv" "ac_cv_func_putenv"
+if test "x$ac_cv_func_putenv" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PUTENV 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getcwd getwd memcmp memcpy mkstemp mktemp strchr strrchr
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
+case $ac_cv_c_int64_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int64_t $ac_cv_c_int64_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
+case $ac_cv_c_uint64_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT64_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint64_t $ac_cv_c_uint64_t
+_ACEOF
+;;
+ esac
+
+case :$ac_cv_c_int64_t:$ac_cv_c_int64_t: in #(
+ *':no:'*) :
+ as_fn_error $? "Sorry, your compiler does not support 64-bit integer types." "$LINENO" 5 ;; #(
+ *) :
+ ;;
+esac
+ac_fn_c_check_decl "$LINENO" "isascii" "ac_cv_have_decl_isascii" "#include <ctype.h>
+"
+if test "x$ac_cv_have_decl_isascii" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ISASCII $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_MTIM 1
+_ACEOF
+
+
+fi
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+for ac_header in unistd.h stdint.h inttypes.h sys/types.h sys/wait.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5
+$as_echo_n "checking for working memcmp... " >&6; }
+if ${ac_cv_func_memcmp_working+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_memcmp_working=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Some versions of memcmp are not 8-bit clean. */
+ char c0 = '\100', c1 = '\200', c2 = '\201';
+ if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
+ return 1;
+
+ /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
+ or more and with at least one buffer not starting on a 4-byte boundary.
+ William Lewis provided this test program. */
+ {
+ char foo[21];
+ char bar[21];
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ char *a = foo + i;
+ char *b = bar + i;
+ strcpy (a, "--------01111111");
+ strcpy (b, "--------10000000");
+ if (memcmp (a, b, 16) >= 0)
+ return 1;
+ }
+ return 0;
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_memcmp_working=yes
+else
+ ac_cv_func_memcmp_working=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5
+$as_echo "$ac_cv_func_memcmp_working" >&6; }
+test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
+ *" memcmp.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+ ;;
+esac
+
+
+for ac_func in open close getenv basename
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
+$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
+if ${ac_cv_struct_tm+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm tm;
+ int *p = &tm.tm_sec;
+ return !p;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_struct_tm=time.h
+else
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
+$as_echo "$ac_cv_struct_tm" >&6; }
+if test $ac_cv_struct_tm = sys/time.h; then
+
+$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+
+"
+if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TM_TM_ZONE 1
+_ACEOF
+
+
+fi
+
+if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
+
+$as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h
+
+else
+ ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include <time.h>
+"
+if test "x$ac_cv_have_decl_tzname" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_TZNAME $ac_have_decl
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5
+$as_echo_n "checking for tzname... " >&6; }
+if ${ac_cv_var_tzname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <time.h>
+#if !HAVE_DECL_TZNAME
+extern char *tzname[];
+#endif
+
+int
+main ()
+{
+return tzname[0][0];
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_var_tzname=yes
+else
+ ac_cv_var_tzname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5
+$as_echo "$ac_cv_var_tzname" >&6; }
+ if test $ac_cv_var_tzname = yes; then
+
+$as_echo "#define HAVE_TZNAME 1" >>confdefs.h
+
+ fi
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int32_t $ac_cv_c_int32_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT32_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
+_ACEOF
+;;
+ esac
+
+
+ac_fn_c_check_decl "$LINENO" "timezone" "ac_cv_have_decl_timezone" "#include <time.h>
+"
+if test "x$ac_cv_have_decl_timezone" = xyes; then :
+
+$as_echo "#define HAVE_TIMEZONE 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct tm" "tm_gmtoff" "ac_cv_member_struct_tm_tm_gmtoff" "#include <time.h>
+"
+if test "x$ac_cv_member_struct_tm_tm_gmtoff" = xyes; then :
+
+$as_echo "#define HAVE_TM_GMTOFF 1" >>confdefs.h
+
+fi
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5
+$as_echo_n "checking size of char... " >&6; }
+if ${ac_cv_sizeof_char+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_char" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (char)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_char=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5
+$as_echo "$ac_cv_sizeof_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if ${ac_cv_sizeof_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if ${ac_cv_sizeof_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pow" >&5
+$as_echo_n "checking for library containing pow... " >&6; }
+if ${ac_cv_search_pow+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pow ();
+int
+main ()
+{
+return pow ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' m; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_pow=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_pow+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_pow+:} false; then :
+
+else
+ ac_cv_search_pow=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pow" >&5
+$as_echo "$ac_cv_search_pow" >&6; }
+ac_res=$ac_cv_search_pow
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+kpse_save_CPPFLAGS=$CPPFLAGS
+kpse_save_LIBS=$LIBS
+
+##tldbg _KPSE_INIT: Initialize TL infrastructure.
+kpse_BLD=`(cd "./../../." && pwd)`
+kpse_SRC=`(cd "$srcdir/../../." && pwd)`
+
+##tldbg _KPSE_USE_LIBTOOL: Generate a libtool script for use in configure tests.
+: ${CONFIG_LT=./config.lt}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_LT" >&5
+$as_echo "$as_me: creating $CONFIG_LT" >&6;}
+as_write_fail=0
+cat >"$CONFIG_LT" <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>"$CONFIG_LT" <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## --------------------------------- ##
+## Main body of "$CONFIG_LT" script. ##
+## --------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x "$CONFIG_LT"
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $0 [OPTIONS]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+dvipdfm-x (TeX Live) config.lt 20210212
+configured by $0, generated by GNU Autoconf 2.69.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $#
+do
+ case $1 in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) as_fn_error $? "unrecognized option: $1
+Try '$0 --help' for more information." "$LINENO" 5 ;;
+
+ *) as_fn_error $? "unrecognized argument: $1
+Try '$0 --help' for more information." "$LINENO" 5 ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec 6>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in AS \
+DLLTOOL \
+OBJDUMP \
+SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ofile" >&5
+$as_echo "$as_me: creating $ofile" >&6;}
+
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Assembler program.
+AS=$lt_AS
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$lt_OBJDUMP
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+as_fn_exit 0
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec 5>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec 5>>config.log
+$lt_cl_success || as_fn_exit 1
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ac_link="./libtool --mode=link --tag=CC $ac_link"
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PKG_CONFIG"; then
+ ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+PKG_CONFIG=$ac_cv_prog_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_PKG_CONFIG"; then
+ ac_ct_PKG_CONFIG=$PKG_CONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_PKG_CONFIG"; then
+ ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG
+if test -n "$ac_ct_PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5
+$as_echo "$ac_ct_PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_PKG_CONFIG" = x; then
+ PKG_CONFIG="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PKG_CONFIG=$ac_ct_PKG_CONFIG
+ fi
+else
+ PKG_CONFIG="$ac_cv_prog_PKG_CONFIG"
+fi
+
+##tldbg _KPSE_LIB_FLAGS: Setup kpathsea (-lkpathsea) flags.
+echo 'tldbg:_KPSE_LIB_FLAGS called: libdir=kpathsea, libname=kpathsea, options=lt, tlincl=-IBLD/texk -ISRC/texk, tllib=BLD/texk/kpathsea/libkpathsea.la, tlextra=, rebuildsrcdeps=${top_srcdir}/../kpathsea/*.[ch], rebuildblddeps=${top_builddir}/../kpathsea/paths.h.' >&5
+##tldbg _KPSE_LIB_FLAGS_TL: kpathsea (kpathsea) lt.
+
+# Check whether --with-system-kpathsea was given.
+if test "${with_system_kpathsea+set}" = set; then :
+ withval=$with_system_kpathsea;
+fi
+if test "x$with_system_kpathsea" = xyes; then
+ if $PKG_CONFIG kpathsea; then
+ KPATHSEA_INCLUDES=`$PKG_CONFIG kpathsea --cflags`
+ KPATHSEA_LIBS=`$PKG_CONFIG kpathsea --libs`
+elif test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then
+ as_fn_error $? "did not find kpathsea" "$LINENO" 5
+fi
+else
+ KPATHSEA_INCLUDES="-I$kpse_BLD/texk -I$kpse_SRC/texk"
+ KPATHSEA_LIBS="$kpse_BLD/texk/kpathsea/libkpathsea.la"
+ KPATHSEA_DEPEND='${top_builddir}/../kpathsea/libkpathsea.la'
+ KPATHSEA_RULE='# Rebuild libkpathsea
+$(KPATHSEA_DEPEND): ${top_srcdir}/../kpathsea/*.[ch] ${top_builddir}/../kpathsea/paths.h
+ cd ${top_builddir}/../kpathsea && $(MAKE) $(AM_MAKEFLAGS) rebuild
+${top_builddir}/../kpathsea/paths.h:
+ cd ${top_builddir}/../kpathsea && $(MAKE) $(AM_MAKEFLAGS) rebuild'
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libkpathsea supports debugging" >&5
+$as_echo_n "checking if libkpathsea supports debugging... " >&6; }
+if ${kpse_cv_kpse_debug+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval CPPFLAGS=\"$KPATHSEA_INCLUDES \$CPPFLAGS\"
+eval LIBS=\"$KPATHSEA_LIBS \$LIBS\"
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <kpathsea/kpathsea.h>
+int
+main ()
+{
+FILE *f = fopen("f", "r")
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ kpse_cv_kpse_debug=yes
+else
+ kpse_cv_kpse_debug=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CPPFLAGS=$kpse_save_CPPFLAGS
+LIBS=$kpse_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_kpse_debug" >&5
+$as_echo "$kpse_cv_kpse_debug" >&6; }
+if test "x$kpse_cv_kpse_debug" != xyes; then :
+ KPATHSEA_INCLUDES="$KPATHSEA_INCLUDES -DNO_DEBUG"
+fi
+
+##tldbg _KPSE_LIB_FLAGS: Setup zlib (-lz) flags.
+echo 'tldbg:_KPSE_LIB_FLAGS called: libdir=zlib, libname=z, options=, tlincl=-IBLD/libs/zlib/include, tllib=BLD/libs/zlib/libz.a, tlextra=, rebuildsrcdeps=, rebuildblddeps=${top_builddir}/../../libs/zlib/include/zconf.h.' >&5
+##tldbg _KPSE_LIB_FLAGS_TL: zlib (z) .
+
+# Check whether --with-system-zlib was given.
+if test "${with_system_zlib+set}" = set; then :
+ withval=$with_system_zlib;
+fi
+
+# Check whether --with-zlib-includes was given.
+if test "${with_zlib_includes+set}" = set; then :
+ withval=$with_zlib_includes;
+fi
+
+# Check whether --with-zlib-libdir was given.
+if test "${with_zlib_libdir+set}" = set; then :
+ withval=$with_zlib_libdir;
+fi
+if test "x$with_system_zlib" = xyes; then
+ ##tldbg _KPSE_LIB_FLAGS_SYSTEM: zlib (z).
+if test "x$with_zlib_includes" != x && test "x$with_zlib_includes" != xyes; then
+ ZLIB_INCLUDES="-I$with_zlib_includes"
+fi
+ZLIB_LIBS="-lz"
+if test "x$with_zlib_libdir" != x && test "x$with_zlib_libdir" != xyes; then
+ ZLIB_LIBS="-L$with_zlib_libdir $ZLIB_LIBS"
+fi
+else
+ ZLIB_INCLUDES="-I$kpse_BLD/libs/zlib/include"
+ ZLIB_LIBS="$kpse_BLD/libs/zlib/libz.a"
+ ZLIB_DEPEND='${top_builddir}/../../libs/zlib/libz.a'
+ ZLIB_RULE='# Rebuild libz
+$(ZLIB_DEPEND): ${top_builddir}/../../libs/zlib/include/zconf.h
+ cd ${top_builddir}/../../libs/zlib && $(MAKE) $(AM_MAKEFLAGS) rebuild
+${top_builddir}/../../libs/zlib/include/zconf.h:
+ cd ${top_builddir}/../../libs/zlib && $(MAKE) $(AM_MAKEFLAGS) rebuild'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if <zlib.h> defines 'z_const'" >&5
+$as_echo_n "checking if <zlib.h> defines 'z_const'... " >&6; }
+if ${kpse_cv_have_decl_z_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval CPPFLAGS=\"$ZLIB_INCLUDES \$CPPFLAGS\"
+eval LIBS=\"$ZLIB_LIBS \$LIBS\"
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <zlib.h>
+int
+main ()
+{
+z_const char * foo();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ kpse_cv_have_decl_z_const=yes
+else
+ kpse_cv_have_decl_z_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CPPFLAGS=$kpse_save_CPPFLAGS
+LIBS=$kpse_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_have_decl_z_const" >&5
+$as_echo "$kpse_cv_have_decl_z_const" >&6; }
+case $kpse_cv_have_decl_z_const in #(
+ yes) :
+
+$as_echo "#define ZLIB_CONST 1" >>confdefs.h
+ ;; #(
+ *) :
+
+$as_echo "#define z_const /**/" >>confdefs.h
+ ;;
+esac
+
+##tldbg _KPSE_LIB_FLAGS: Setup libpng (-lpng) flags.
+echo 'tldbg:_KPSE_LIB_FLAGS called: libdir=libpng, libname=png, options=, tlincl=-IBLD/libs/libpng/include, tllib=BLD/libs/libpng/libpng.a, tlextra=, rebuildsrcdeps=, rebuildblddeps=${top_builddir}/../../libs/libpng/include/png.h.' >&5
+##tldbg _KPSE_LIB_FLAGS_TL: libpng (png) .
+
+# Check whether --with-system-libpng was given.
+if test "${with_system_libpng+set}" = set; then :
+ withval=$with_system_libpng;
+fi
+if test "x$with_system_libpng" = xyes; then
+ if $PKG_CONFIG libpng; then
+ LIBPNG_INCLUDES=`$PKG_CONFIG libpng --cflags`
+ LIBPNG_LIBS=`$PKG_CONFIG libpng --libs`
+elif test "x$need_libpng:$with_system_libpng" = xyes:yes; then
+ as_fn_error $? "did not find libpng" "$LINENO" 5
+fi
+else
+ LIBPNG_INCLUDES="-I$kpse_BLD/libs/libpng/include"
+ LIBPNG_LIBS="$kpse_BLD/libs/libpng/libpng.a"
+ LIBPNG_DEPEND='${top_builddir}/../../libs/libpng/libpng.a'
+ LIBPNG_RULE='# Rebuild libpng
+$(LIBPNG_DEPEND): ${top_builddir}/../../libs/libpng/include/png.h
+ cd ${top_builddir}/../../libs/libpng && $(MAKE) $(AM_MAKEFLAGS) rebuild
+${top_builddir}/../../libs/libpng/include/png.h:
+ cd ${top_builddir}/../../libs/libpng && $(MAKE) $(AM_MAKEFLAGS) rebuild'
+fi
+
+##tldbg _KPSE_LIB_FLAGS: Setup libpaper (-lpaper) flags.
+echo 'tldbg:_KPSE_LIB_FLAGS called: libdir=libpaper, libname=paper, options=, tlincl=-IBLD/libs/libpaper/include, tllib=BLD/libs/libpaper/libpaper.a, tlextra=, rebuildsrcdeps=, rebuildblddeps=${top_builddir}/../../libs/libpaper/include/paper.h.' >&5
+##tldbg _KPSE_LIB_FLAGS_TL: libpaper (paper) .
+
+# Check whether --with-system-libpaper was given.
+if test "${with_system_libpaper+set}" = set; then :
+ withval=$with_system_libpaper;
+fi
+
+# Check whether --with-libpaper-includes was given.
+if test "${with_libpaper_includes+set}" = set; then :
+ withval=$with_libpaper_includes;
+fi
+
+# Check whether --with-libpaper-libdir was given.
+if test "${with_libpaper_libdir+set}" = set; then :
+ withval=$with_libpaper_libdir;
+fi
+if test "x$with_system_libpaper" = xyes; then
+ ##tldbg _KPSE_LIB_FLAGS_SYSTEM: libpaper (paper).
+if test "x$with_libpaper_includes" != x && test "x$with_libpaper_includes" != xyes; then
+ LIBPAPER_INCLUDES="-I$with_libpaper_includes"
+fi
+LIBPAPER_LIBS="-lpaper"
+if test "x$with_libpaper_libdir" != x && test "x$with_libpaper_libdir" != xyes; then
+ LIBPAPER_LIBS="-L$with_libpaper_libdir $LIBPAPER_LIBS"
+fi
+else
+ LIBPAPER_INCLUDES="-I$kpse_BLD/libs/libpaper/include"
+ LIBPAPER_LIBS="$kpse_BLD/libs/libpaper/libpaper.a"
+ LIBPAPER_DEPEND='${top_builddir}/../../libs/libpaper/libpaper.a'
+ LIBPAPER_RULE='# Rebuild libpaper
+$(LIBPAPER_DEPEND): ${top_builddir}/../../libs/libpaper/include/paper.h
+ cd ${top_builddir}/../../libs/libpaper && $(MAKE) $(AM_MAKEFLAGS) rebuild
+${top_builddir}/../../libs/libpaper/include/paper.h:
+ cd ${top_builddir}/../../libs/libpaper && $(MAKE) $(AM_MAKEFLAGS) rebuild'
+fi
+
+
+$as_echo "#define HAVE_LIBPAPER 1" >>confdefs.h
+
+
+kpse_save_CPPFLAGS=$CPPFLAGS
+kpse_save_LIBS=$LIBS
+
+
+if test "x$enable_build" != xno || test -f config.force; then
+
+eval CPPFLAGS=\"$KPATHSEA_INCLUDES \$CPPFLAGS\"
+eval LIBS=\"$KPATHSEA_LIBS \$LIBS\"
+
+ac_fn_c_check_header_mongrel "$LINENO" "kpathsea/version.h" "ac_cv_header_kpathsea_version_h" "$ac_includes_default"
+if test "x$ac_cv_header_kpathsea_version_h" = xyes; then :
+
+else
+ as_fn_error $? "Sorry, kpathsea too old" "$LINENO" 5
+fi
+
+
+
+eval CPPFLAGS=\"$ZLIB_INCLUDES \$CPPFLAGS\"
+eval LIBS=\"$ZLIB_LIBS \$LIBS\"
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <zlib.h>
+int
+main ()
+{
+Bytef *dst,*src; uLong dstlen, srclen; int lvl, err;
+ err=compress2(dst, &dstlen, src, srclen, lvl);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+ as_fn_error $? "Sorry, you need zlib with compress2" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+eval CPPFLAGS=\"$LIBPNG_INCLUDES \$CPPFLAGS\"
+eval LIBS=\"$LIBPNG_LIBS \$LIBS\"
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <png.h>
+int
+main ()
+{
+png_const_structp png; png_const_infop info; int err;
+ err=png_get_image_width(png, info);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+ as_fn_error $? "Sorry, you need libpng" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+CPPFLAGS=$kpse_save_CPPFLAGS
+LIBS=$kpse_save_LIBS
+
+
+echo timestamp >config.force
+fi
+
+
+$as_echo "#define HAVE_ZLIB 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_ZLIB_COMPRESS2 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_LIBPNG 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for native WIN32 or MINGW32" >&5
+$as_echo_n "checking for native WIN32 or MINGW32... " >&6; }
+if ${kpse_cv_have_win32+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef WIN32
+ choke me
+#endif
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __MINGW32__
+ choke me
+#endif
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ kpse_cv_have_win32=mingw32
+else
+ kpse_cv_have_win32=native
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ kpse_cv_have_win32=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_have_win32" >&5
+$as_echo "$kpse_cv_have_win32" >&6; }
+
+ if test "x$kpse_cv_have_win32" != xno; then
+ WIN32_TRUE=
+ WIN32_FALSE='#'
+else
+ WIN32_TRUE='#'
+ WIN32_FALSE=
+fi
+
+
+ if test -r "$srcdir/../texlive/w32_wrapper/callexe.c"; then
+ WIN32_CALL_TRUE=
+ WIN32_CALL_FALSE='#'
+else
+ WIN32_CALL_TRUE='#'
+ WIN32_CALL_FALSE=
+fi
+
+if test -z "$WIN32_TRUE"; then :
+ ac_config_links="$ac_config_links callexe.c:../texlive/w32_wrapper/callexe.c"
+
+fi
+
+
+ac_config_files="$ac_config_files Makefile"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then
+ as_fn_error $? "conditional \"WIN32\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WIN32_CALL_TRUE}" && test -z "${WIN32_CALL_FALSE}"; then
+ as_fn_error $? "conditional \"WIN32_CALL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by dvipdfm-x (TeX Live) $as_me 20210212, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to <dvipdfmx@tug.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+dvipdfm-x (TeX Live) config.status 20210212
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in AS \
+DLLTOOL \
+OBJDUMP \
+SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+ac_aux_dir='$ac_aux_dir'
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "callexe.c") CONFIG_LINKS="$CONFIG_LINKS callexe.c:../texlive/w32_wrapper/callexe.c" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+ :L)
+ #
+ # CONFIG_LINK
+ #
+
+ if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then
+ :
+ else
+ # Prefer the file from the source tree if names are identical.
+ if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then
+ ac_source=$srcdir/$ac_source
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5
+$as_echo "$as_me: linking $ac_source to $ac_file" >&6;}
+
+ if test ! -r "$ac_source"; then
+ as_fn_error $? "$ac_source: file not found" "$LINENO" 5
+ fi
+ rm -f "$ac_file"
+
+ # Try a relative symlink, then a hard link, then a copy.
+ case $ac_source in
+ [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;;
+ *) ac_rel_source=$ac_top_build_prefix$ac_source ;;
+ esac
+ ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
+ ln "$ac_source" "$ac_file" 2>/dev/null ||
+ cp -p "$ac_source" "$ac_file" ||
+ as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
+ fi
+ ;;
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ # TODO: see whether this extra hack can be removed once we start
+ # requiring Autoconf 2.70 or later.
+ case $CONFIG_FILES in #(
+ *\'*) :
+ eval set x "$CONFIG_FILES" ;; #(
+ *) :
+ set x $CONFIG_FILES ;; #(
+ *) :
+ ;;
+esac
+ shift
+ # Used to flag and report bootstrapping failures.
+ am_rc=0
+ for am_mf
+ do
+ # Strip MF so we end up with the name of the file.
+ am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile which includes
+ # dependency-tracking related rules and includes.
+ # Grep'ing the whole file directly is not great: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+ || continue
+ am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$am_mf" : 'X\(//\)[^/]' \| \
+ X"$am_mf" : 'X\(//\)$' \| \
+ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$am_mf" : 'X\(//\)$' \| \
+ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { echo "$as_me:$LINENO: cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles" >&5
+ (cd "$am_dirpart" \
+ && sed -e '/# am--include-marker/d' "$am_filepart" \
+ | $MAKE -f - am--depfiles) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } || am_rc=$?
+ done
+ if test $am_rc -ne 0; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+ for automatic dependency tracking. If GNU make was not used, consider
+ re-running the configure script with MAKE=\"gmake\" (or whatever is
+ necessary). You can also try re-running configure with the
+ '--disable-dependency-tracking' option to at least be able to build
+ the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ { am_dirpart=; unset am_dirpart;}
+ { am_filepart=; unset am_filepart;}
+ { am_mf=; unset am_mf;}
+ { am_rc=; unset am_rc;}
+ rm -f conftest-deps.mk
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Assembler program.
+AS=$lt_AS
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$lt_OBJDUMP
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/Build/source/texk/dvipdfm-x/configure.ac b/Build/source/texk/dvipdfm-x/configure.ac
new file mode 100644
index 00000000000..d8b2b4eec25
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/configure.ac
@@ -0,0 +1,96 @@
+dnl $Id$
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl Copyright 2016-2020 Karl Berry <tex-live@tug.org>
+dnl Copyright 2009-2015 Peter Breitenlohner <tex-live@tug.org>
+dnl
+dnl This file is free software; the copyright holder
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+AC_INIT([dvipdfm-x (TeX Live)], [20210212], [dvipdfmx@tug.org])
+AC_PREREQ([2.65])
+AC_CONFIG_SRCDIR([agl.c])
+AC_CONFIG_AUX_DIR([../../build-aux])
+AC_CONFIG_MACRO_DIR([../../m4])
+
+dnl Common code for all programs using libkpathsea.
+KPSE_COMMON([dvipdfm-x])
+
+AC_CONFIG_HEADERS([config.h])
+
+dnl Checks for header files.
+AC_CHECK_HEADERS([unistd.h stdint.h inttypes.h sys/types.h sys/wait.h])
+
+dnl Checks for library functions.
+AC_FUNC_MEMCMP
+AC_CHECK_FUNCS([open close getenv basename])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_STRUCT_TM
+AC_STRUCT_TIMEZONE
+AC_C_BIGENDIAN
+AC_TYPE_INT32_T
+AC_TYPE_UINT32_T
+
+AC_CHECK_DECL([timezone],
+ [AC_DEFINE([HAVE_TIMEZONE], 1,
+ [Define if <time.h> has timezone as an external variable.])],
+ [],
+ [[#include <time.h>]])
+AC_CHECK_MEMBER([struct tm.tm_gmtoff],
+ [AC_DEFINE([HAVE_TM_GMTOFF], 1,
+ [Define if struct tm has tm_gmtoff as a member.])],
+ [],
+ [[#include <time.h>]])
+
+AC_CHECK_SIZEOF([char])
+AC_CHECK_SIZEOF([short])
+AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long])
+
+AC_SEARCH_LIBS([pow], [m])
+
+KPSE_KPATHSEA_FLAGS
+KPSE_ZLIB_FLAGS
+KPSE_LIBPNG_FLAGS
+KPSE_LIBPAPER_FLAGS
+AC_DEFINE([HAVE_LIBPAPER], [1], [Define if you have libpaper.])
+
+KPSE_SAVE_FLAGS
+
+if test "x$enable_build" != xno || test -f config.force; then
+
+KPSE_ADD_FLAGS([kpathsea])
+AC_CHECK_HEADER([kpathsea/version.h], [],
+ [AC_MSG_ERROR([Sorry, kpathsea too old])])
+
+KPSE_ADD_FLAGS([zlib])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <zlib.h>]],
+ [[Bytef *dst,*src; uLong dstlen, srclen; int lvl, err;
+ err=compress2(dst, &dstlen, src, srclen, lvl);]])],
+ [],
+ [AC_MSG_ERROR([Sorry, you need zlib with compress2])])
+
+KPSE_ADD_FLAGS([libpng])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <png.h>]],
+ [[png_const_structp png; png_const_infop info; int err;
+ err=png_get_image_width(png, info);]])],
+ [],
+ [AC_MSG_ERROR([Sorry, you need libpng])])
+
+KPSE_RESTORE_FLAGS
+
+echo timestamp >config.force
+fi
+
+dnl We require zlib with compress2 and libpng
+AC_DEFINE([HAVE_ZLIB], 1, [Define if you have zlib and its headers.])
+AC_DEFINE([HAVE_ZLIB_COMPRESS2], 1, [Define if your zlib has the compress2 function.])
+AC_DEFINE([HAVE_LIBPNG], 1, [Define if you have libpng and its headers.])
+
+KPSE_WIN32_CALL
+
+AC_CONFIG_FILES([Makefile])
+
+AC_OUTPUT
diff --git a/Build/source/texk/dvipdfm-x/cs_type2.c b/Build/source/texk/dvipdfm-x/cs_type2.c
new file mode 100644
index 00000000000..df7250c6b7c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cs_type2.c
@@ -0,0 +1,808 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * Type 2 Charstring support:
+ * Decode and encode Type 2 charstring
+ *
+ * All local/global subroutine calls in a given charstring is replace by the
+ * content of subroutine charstrings. We do this because some PostScript RIP
+ * may have problems with sparse subroutine array. Workaround for this is to
+ * re-order subroutine array so that no gap appears in the subroutine array,
+ * or put dummy charstrings that contains only `return' in the gap. However,
+ * re-ordering of subroutine is rather difficult for Type 2 charstrings due
+ * to the bias which depends on the total number of subroutines. Replacing
+ * callgsubr/callsubr calls with the content of the corresponding subroutine
+ * charstring may be more efficient than putting dummy subroutines in the
+ * case of subsetted font. Adobe distiller seems doing same thing.
+ *
+ * And also note that subroutine numbers within subroutines can depend on the
+ * content of operand stack as follows:
+ *
+ * ... l m callsubr << subr #(m+bias): n add callsubr >> ...
+ *
+ * I've not implemented the `random' operator which generates a pseudo-random
+ * number in the range (0, 1] and push them into argument stack.
+ * How pseudo-random sequences are generated is not documented in the Type 2
+ * charstring spec..
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+/* fabs, sqrt ... */
+#include <math.h>
+
+#include "error.h"
+
+/* data types, limits */
+#include "cff_types.h"
+#include "cff_limits.h"
+
+#include "cs_type2.h"
+
+#define CS_TYPE2_DEBUG_STR "Type2 Charstring Parser"
+#define CS_TYPE2_DEBUG 5
+
+/* decoder/encoder status codes */
+#define CS_BUFFER_ERROR -3
+#define CS_STACK_ERROR -2
+#define CS_PARSE_ERROR -1
+#define CS_PARSE_OK 0
+#define CS_PARSE_END 1
+#define CS_SUBR_RETURN 2
+#define CS_CHAR_END 3
+
+static int status = CS_PARSE_ERROR;
+
+#define DST_NEED(a,b) {if ((a) < (b)) { status = CS_BUFFER_ERROR ; return ; }}
+#define SRC_NEED(a,b) {if ((a) < (b)) { status = CS_PARSE_ERROR ; return ; }}
+#define NEED(a,b) {if ((a) < (b)) { status = CS_STACK_ERROR ; return ; }}
+
+/* hintmask and cntrmask need number of stem zones */
+static int num_stems = 0;
+static int phase = 0;
+
+/* subroutine nesting */
+static int nest = 0;
+
+/* advance width */
+static int have_width = 0;
+static double width = 0.0;
+
+/*
+ * Standard Encoding Accented Characters:
+ * Optional four arguments for endchar. See, CFF spec., p.35.
+ * This is obsolete feature and is no longer supported.
+ */
+#if 0
+/* adx ady bchar achar endchar */
+static double seac[4] = {0.0, 0.0, 0.0, 0.0};
+#endif
+
+/* Operand stack and Transient array */
+static int stack_top = 0;
+static double arg_stack[CS_ARG_STACK_MAX];
+static double trn_array[CS_TRANS_ARRAY_MAX];
+
+/*
+ * Type 2 CharString encoding
+ */
+
+/*
+ * 1-byte CharString operaotrs:
+ * cs_escape is first byte of two-byte operator
+ */
+
+/* RESERVED 0 */
+#define cs_hstem 1
+/* RESERVED 2 */
+#define cs_vstem 3
+#define cs_vmoveto 4
+#define cs_rlineto 5
+#define cs_hlineto 6
+#define cs_vlineto 7
+#define cs_rrcurveto 8
+/* cs_closepath 9 : TYPE1 */
+#define cs_callsubr 10
+#define cs_return 11
+#define cs_escape 12
+/* cs_hsbw 13 : TYPE1 */
+#define cs_endchar 14
+/* RESERVED 15 */
+/* RESERVED 16 */
+/* RESERVED 17 */
+#define cs_hstemhm 18
+#define cs_hintmask 19
+#define cs_cntrmask 20
+#define cs_rmoveto 21
+#define cs_hmoveto 22
+#define cs_vstemhm 23
+#define cs_rcurveline 24
+#define cs_rlinecurve 25
+#define cs_vvcurveto 26
+#define cs_hhcurveto 27
+/* SHORTINT 28 : first byte of shortint*/
+#define cs_callgsubr 29
+#define cs_vhcurveto 30
+#define cs_hvcurveto 31
+
+/*
+ * 2-byte CharString operaotrs:
+ * "dotsection" is obsoleted in Type 2 charstring.
+ */
+
+#define cs_dotsection 0
+/* cs_vstem3 1 : TYPE1 */
+/* cs_hstem3 2 : TYPE1 */
+#define cs_and 3
+#define cs_or 4
+#define cs_not 5
+/* cs_seac 6 : TYPE1 */
+/* cs_sbw 7 : TYPE1 */
+/* RESERVED 8 */
+#define cs_abs 9
+#define cs_add 10
+#define cs_sub 11
+#define cs_div 12
+/* RESERVED 13 */
+#define cs_neg 14
+#define cs_eq 15
+/* cs_callothersubr 16 : TYPE1 */
+/* cs_pop 17 : TYPE1 */
+#define cs_drop 18
+/* RESERVED 19 */
+#define cs_put 20
+#define cs_get 21
+#define cs_ifelse 22
+#define cs_random 23
+#define cs_mul 24
+/* RESERVED 25 */
+#define cs_sqrt 26
+#define cs_dup 27
+#define cs_exch 28
+#define cs_index 29
+#define cs_roll 30
+/* cs_setcurrentpoint 31 : TYPE1 */
+/* RESERVED 32 */
+/* RESERVED 33 */
+#define cs_hflex 34
+#define cs_flex 35
+#define cs_hflex1 36
+#define cs_flex1 37
+
+/*
+ * clear_stack() put all operands sotred in operand stack to dest.
+ */
+static void
+clear_stack (card8 **dest, card8 *limit)
+{
+ int i;
+
+ for (i = 0; i < stack_top; i++) {
+ double value;
+ int ivalue;
+ value = arg_stack[i];
+ /* Nearest integer value */
+ ivalue = (int) floor(value+0.5);
+ if (value >= 0x8000L || value <= (-0x8000L - 1)) {
+ /*
+ * This number cannot be represented as a single operand.
+ * We must use `a b mul ...' or `a c div' to represent large values.
+ */
+ ERROR("%s: Argument value too large. (This is bug)", CS_TYPE2_DEBUG_STR);
+ } else if (fabs(value - ivalue) > 3.0e-5) {
+ /* 16.16-bit signed fixed value */
+ DST_NEED(limit, *dest + 5);
+ *(*dest)++ = 255;
+ ivalue = (int) floor(value); /* mantissa */
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ ivalue = (int)((value - ivalue) * 0x10000l); /* fraction */
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ /* Everything else are integers. */
+ } else if (ivalue >= -107 && ivalue <= 107) {
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = ivalue + 139;
+ } else if (ivalue >= 108 && ivalue <= 1131) {
+ DST_NEED(limit, *dest + 2);
+ ivalue = 0xf700u + ivalue - 108;
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ } else if (ivalue >= -1131 && ivalue <= -108) {
+ DST_NEED(limit, *dest + 2);
+ ivalue = 0xfb00u - ivalue - 108;
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ } else if (ivalue >= -32768 && ivalue <= 32767) { /* shortint */
+ DST_NEED(limit, *dest + 3);
+ *(*dest)++ = 28;
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = (ivalue) & 0xff;
+ } else { /* Shouldn't come here */
+ ERROR("%s: Unexpected error.", CS_TYPE2_DEBUG_STR);
+ }
+ }
+
+ stack_top = 0; /* clear stack */
+
+ return;
+}
+
+/*
+ * Single byte operators:
+ * Path construction, Operator for finishing a path, Hint operators.
+ *
+ * phase:
+ * 0: inital state
+ * 1: hint declaration, first stack-clearing operator appeared
+ * 2: in path construction
+ */
+
+static void
+do_operator1 (card8 **dest, card8 *limit, card8 **data, card8 *endptr)
+{
+ card8 op = **data;
+
+ *data += 1;
+
+ switch (op) {
+ case cs_hstemhm:
+ case cs_vstemhm:
+ /* charstring may have hintmask if above operator have seen */
+ case cs_hstem:
+ case cs_vstem:
+ if (phase == 0 && (stack_top % 2)) {
+ have_width = 1;
+ width = arg_stack[0];
+ }
+ num_stems += stack_top/2;
+ clear_stack(dest, limit);
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = op;
+ phase = 1;
+ break;
+ case cs_hintmask:
+ case cs_cntrmask:
+ if (phase < 2) {
+ if (phase == 0 && (stack_top % 2)) {
+ have_width = 1;
+ width = arg_stack[0];
+ }
+ num_stems += stack_top/2;
+ }
+ clear_stack(dest, limit);
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = op;
+ if (num_stems > 0) {
+ int masklen = (num_stems + 7) / 8;
+ DST_NEED(limit, *dest + masklen);
+ SRC_NEED(endptr, *data + masklen);
+ memmove(*dest, *data, masklen);
+ *data += masklen;
+ *dest += masklen;
+ }
+ phase = 2;
+ break;
+ case cs_rmoveto:
+ if (phase == 0 && (stack_top % 2)) {
+ have_width = 1;
+ width = arg_stack[0];
+ }
+ clear_stack(dest, limit);
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = op;
+ phase = 2;
+ break;
+ case cs_hmoveto:
+ case cs_vmoveto:
+ if (phase == 0 && (stack_top % 2) == 0) {
+ have_width = 1;
+ width = arg_stack[0];
+ }
+ clear_stack(dest, limit);
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = op;
+ phase = 2;
+ break;
+ case cs_endchar:
+ if (stack_top == 1) {
+ have_width = 1;
+ width = arg_stack[0];
+ clear_stack(dest, limit);
+ } else if (stack_top == 4 || stack_top == 5) {
+ WARN("\"seac\" character deprecated in Type 2 charstring.");
+ status = CS_PARSE_ERROR;
+ return;
+ } else if (stack_top > 0) {
+ WARN("%s: Operand stack not empty.", CS_TYPE2_DEBUG_STR);
+ }
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = op;
+ status = CS_CHAR_END;
+ break;
+ /* above oprators are candidate for first stack-clearing operator */
+ case cs_rlineto:
+ case cs_hlineto:
+ case cs_vlineto:
+ case cs_rrcurveto:
+ case cs_rcurveline:
+ case cs_rlinecurve:
+ case cs_vvcurveto:
+ case cs_hhcurveto:
+ case cs_vhcurveto:
+ case cs_hvcurveto:
+ if (phase < 2) {
+ WARN("%s: Broken Type 2 charstring.", CS_TYPE2_DEBUG_STR);
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ clear_stack(dest, limit);
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = op;
+ break;
+ /* all operotors above are stack-clearing operator */
+ /* no output */
+ case cs_return:
+ case cs_callgsubr:
+ case cs_callsubr:
+ ERROR("%s: Unexpected call(g)subr/return", CS_TYPE2_DEBUG_STR);
+ break;
+ default:
+ /* no-op ? */
+ WARN("%s: Unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR, op);
+ status = CS_PARSE_ERROR;
+ break;
+ }
+
+ return;
+}
+
+/*
+ * Double byte operators:
+ * Flex, arithmetic, conditional, and storage operators.
+ *
+ * Following operators are not supported:
+ * random: How random ?
+ */
+static void
+do_operator2 (card8 **dest, card8 *limit, card8 **data, card8 *endptr)
+{
+ card8 op;
+
+ *data += 1;
+
+ SRC_NEED(endptr, *data + 1);
+
+ op = **data;
+ *data += 1;
+
+ switch(op) {
+ case cs_dotsection: /* deprecated */
+ WARN("Operator \"dotsection\" deprecated in Type 2 charstring.");
+ status = CS_PARSE_ERROR;
+ return;
+ case cs_hflex:
+ case cs_flex:
+ case cs_hflex1:
+ case cs_flex1:
+ if (phase < 2) {
+ WARN("%s: Broken Type 2 charstring.", CS_TYPE2_DEBUG_STR);
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ clear_stack(dest, limit);
+ DST_NEED(limit, *dest + 2);
+ *(*dest)++ = cs_escape;
+ *(*dest)++ = op;
+ break;
+ /* all operator above are stack-clearing */
+ /* no output */
+ case cs_and:
+ NEED(stack_top, 2);
+ stack_top--;
+ if (arg_stack[stack_top] && arg_stack[stack_top-1]) {
+ arg_stack[stack_top-1] = 1.0;
+ } else {
+ arg_stack[stack_top-1] = 0.0;
+ }
+ break;
+ case cs_or:
+ NEED(stack_top, 2);
+ stack_top--;
+ if (arg_stack[stack_top] || arg_stack[stack_top-1]) {
+ arg_stack[stack_top-1] = 1.0;
+ } else {
+ arg_stack[stack_top-1] = 0.0;
+ }
+ break;
+ case cs_not:
+ NEED(stack_top, 1);
+ if (arg_stack[stack_top-1]) {
+ arg_stack[stack_top-1] = 0.0;
+ } else {
+ arg_stack[stack_top-1] = 1.0;
+ }
+ break;
+ case cs_abs:
+ NEED(stack_top, 1);
+ arg_stack[stack_top-1] = fabs(arg_stack[stack_top-1]);
+ break;
+ case cs_add:
+ NEED(stack_top, 2);
+ arg_stack[stack_top-2] += arg_stack[stack_top-1];
+ stack_top--;
+ break;
+ case cs_sub:
+ NEED(stack_top, 2);
+ arg_stack[stack_top-2] -= arg_stack[stack_top-1];
+ stack_top--;
+ break;
+ case cs_div: /* doesn't check overflow */
+ NEED(stack_top, 2);
+ arg_stack[stack_top-2] /= arg_stack[stack_top-1];
+ stack_top--;
+ break;
+ case cs_neg:
+ NEED(stack_top, 1);
+ arg_stack[stack_top-1] *= -1.0;
+ break;
+ case cs_eq:
+ NEED(stack_top, 2);
+ stack_top--;
+ if (arg_stack[stack_top] == arg_stack[stack_top-1]) {
+ arg_stack[stack_top-1] = 1.0;
+ } else {
+ arg_stack[stack_top-1] = 0.0;
+ }
+ break;
+ case cs_drop:
+ NEED(stack_top, 1);
+ stack_top--;
+ break;
+ case cs_put:
+ NEED(stack_top, 2);
+ {
+ int idx = (int)arg_stack[--stack_top];
+ NEED(CS_TRANS_ARRAY_MAX, idx);
+ trn_array[idx] = arg_stack[--stack_top];
+ }
+ break;
+ case cs_get:
+ NEED(stack_top, 1);
+ {
+ int idx = (int)arg_stack[stack_top-1];
+ NEED(CS_TRANS_ARRAY_MAX, idx);
+ arg_stack[stack_top-1] = trn_array[idx];
+ }
+ break;
+ case cs_ifelse:
+ NEED(stack_top, 4);
+ stack_top -= 3;
+ if (arg_stack[stack_top+1] > arg_stack[stack_top+2]) {
+ arg_stack[stack_top-1] = arg_stack[stack_top];
+ }
+ break;
+ case cs_mul:
+ NEED(stack_top, 2);
+ arg_stack[stack_top-2] = arg_stack[stack_top-2] * arg_stack[stack_top-1];
+ stack_top--;
+ break;
+ case cs_sqrt:
+ NEED(stack_top, 1);
+ arg_stack[stack_top-1] = sqrt(arg_stack[stack_top-1]);
+ break;
+ case cs_dup:
+ NEED(stack_top, 1);
+ NEED(CS_ARG_STACK_MAX, stack_top+1);
+ arg_stack[stack_top] = arg_stack[stack_top-1];
+ stack_top++;
+ break;
+ case cs_exch:
+ NEED(stack_top, 2);
+ {
+ double save = arg_stack[stack_top-2];
+ arg_stack[stack_top-2] = arg_stack[stack_top-1];
+ arg_stack[stack_top-1] = save;
+ }
+ break;
+ case cs_index:
+ NEED(stack_top, 2); /* need two arguments at least */
+ {
+ int idx = (int)arg_stack[stack_top-1];
+ if (idx < 0) {
+ arg_stack[stack_top-1] = arg_stack[stack_top-2];
+ } else {
+ NEED(stack_top, idx+2);
+ arg_stack[stack_top-1] = arg_stack[stack_top-idx-2];
+ }
+ }
+ break;
+ case cs_roll:
+ NEED(stack_top, 2);
+ {
+ int N, J;
+ J = (int)arg_stack[--stack_top];
+ N = (int)arg_stack[--stack_top];
+ NEED(stack_top, N);
+ if (J > 0) {
+ J = J % N;
+ while (J-- > 0) {
+ double save = arg_stack[stack_top-1];
+ int i = stack_top - 1;
+ while (i > stack_top-N) {
+ arg_stack[i] = arg_stack[i-1];
+ i--;
+ }
+ arg_stack[i] = save;
+ }
+ } else {
+ J = (-J) % N;
+ while (J-- > 0) {
+ double save = arg_stack[stack_top-N];
+ int i = stack_top - N;
+ while (i < stack_top-1) {
+ arg_stack[i] = arg_stack[i+1];
+ i++;
+ }
+ arg_stack[i] = save;
+ }
+ }
+ }
+ break;
+ case cs_random:
+ WARN("%s: Charstring operator \"random\" found.", CS_TYPE2_DEBUG_STR);
+ NEED(CS_ARG_STACK_MAX, stack_top+1);
+ arg_stack[stack_top++] = 1.0;
+ break;
+ default:
+ /* no-op ? */
+ WARN("%s: Unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR, op);
+ status = CS_PARSE_ERROR;
+ break;
+ }
+
+ return;
+}
+
+/*
+ * integer:
+ * exactly the same as the DICT encoding (except 29)
+ */
+static void
+get_integer (card8 **data, card8 *endptr)
+{
+ int result = 0;
+ card8 b0 = **data, b1, b2;
+
+ *data += 1;
+
+ if (b0 == 28) { /* shortint */
+ SRC_NEED(endptr, *data + 2);
+ b1 = **data;
+ b2 = *(*data+1);
+ result = b1*256+b2;
+ if (result > 0x7fff)
+ result -= 0x10000L;
+ *data += 2;
+ } else if (b0 >= 32 && b0 <= 246) { /* int (1) */
+ result = b0 - 139;
+ } else if (b0 >= 247 && b0 <= 250) { /* int (2) */
+ SRC_NEED(endptr, *data + 1);
+ b1 = **data;
+ result = (b0-247)*256+b1+108;
+ *data += 1;
+ } else if (b0 >= 251 && b0 <= 254) {
+ SRC_NEED(endptr, *data + 1);
+ b1 = **data;
+ result = -(b0-251)*256-b1-108;
+ *data += 1;
+ } else {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+
+ NEED(CS_ARG_STACK_MAX, stack_top+1);
+ arg_stack[stack_top++] = (double) result;
+
+ return;
+}
+
+/*
+ * Signed 16.16-bits fixed number for Type 2 charstring encoding
+ */
+static void
+get_fixed (card8 **data, card8 *endptr)
+{
+ int ivalue;
+ double rvalue;
+
+ *data += 1;
+
+ SRC_NEED(endptr, *data + 4);
+
+ ivalue = *(*data) * 0x100 + *(*data+1);
+ rvalue = (ivalue > 0x7fffL) ? (ivalue - 0x10000L) : ivalue;
+ ivalue = *(*data+2) * 0x100 + *(*data+3);
+ rvalue += ((double) ivalue) / 0x10000L;
+
+ NEED(CS_ARG_STACK_MAX, stack_top+1);
+ arg_stack[stack_top++] = rvalue;
+ *data += 4;
+
+ return;
+}
+
+/*
+ * Subroutines:
+ * The bias for subroutine number is introduced in type 2 charstrings.
+ *
+ * subr: set to a pointer to the subroutine charstring.
+ * len: set to the length of subroutine charstring.
+ * subr_idx: CFF INDEX data that contains subroutines.
+ * id: biased subroutine number.
+ */
+static void
+get_subr (card8 **subr, int *len, cff_index *subr_idx, int id)
+{
+ card16 count;
+
+ if (subr_idx == NULL)
+ ERROR("%s: Subroutine called but no subroutine found.", CS_TYPE2_DEBUG_STR);
+
+ count = subr_idx->count;
+
+ /* Adding bias number */
+ if (count < 1240) {
+ id += 107;
+ } else if (count < 33900) {
+ id += 1131;
+ } else {
+ id += 32768;
+ }
+
+ if (id > count)
+ ERROR("%s: Invalid Subr index: %ld (max=%u)", CS_TYPE2_DEBUG_STR, id, count);
+
+ *len = (subr_idx->offset)[id + 1] - (subr_idx->offset)[id];
+ *subr = subr_idx->data + (subr_idx->offset)[id] - 1;
+
+ return;
+}
+
+/*
+ * NOTE:
+ * The Type 2 interpretation of a number encoded in five-bytes (those with
+ * an initial byte value of 255) differs from how it is interpreted in the
+ * Type 1 format.
+ */
+
+static void
+do_charstring (card8 **dest, card8 *limit,
+ card8 **data, card8 *endptr,
+ cff_index *gsubr_idx, cff_index *subr_idx)
+{
+ card8 b0 = 0, *subr;
+ int len;
+
+ if (nest > CS_SUBR_NEST_MAX)
+ ERROR("%s: Subroutine nested too deeply.", CS_TYPE2_DEBUG_STR);
+
+ nest++;
+
+ while (*data < endptr && status == CS_PARSE_OK) {
+ b0 = **data;
+ if (b0 == 255) { /* 16-bit.16-bit fixed signed number */
+ get_fixed(data, endptr);
+ } else if (b0 == cs_return) {
+ status = CS_SUBR_RETURN;
+ } else if (b0 == cs_callgsubr) {
+ if (stack_top < 1) {
+ status = CS_STACK_ERROR;
+ } else {
+ stack_top--;
+ get_subr(&subr, &len, gsubr_idx, (int) arg_stack[stack_top]);
+ if (*dest + len > limit)
+ ERROR("%s: Possible buffer overflow.", CS_TYPE2_DEBUG_STR);
+ do_charstring(dest, limit, &subr, subr + len,
+ gsubr_idx, subr_idx);
+ *data += 1;
+ }
+ } else if (b0 == cs_callsubr) {
+ if (stack_top < 1) {
+ status = CS_STACK_ERROR;
+ } else {
+ stack_top--;
+ get_subr(&subr, &len, subr_idx, (int) arg_stack[stack_top]);
+ if (limit < *dest + len)
+ ERROR("%s: Possible buffer overflow.", CS_TYPE2_DEBUG_STR);
+ do_charstring(dest, limit, &subr, subr + len,
+ gsubr_idx, subr_idx);
+ *data += 1;
+ }
+ } else if (b0 == cs_escape) {
+ do_operator2(dest, limit, data, endptr);
+ } else if (b0 < 32 && b0 != 28) { /* 19, 20 need mask */
+ do_operator1(dest, limit, data, endptr);
+ } else if ((b0 <= 22 && b0 >= 27) || b0 == 31) { /* reserved */
+ status = CS_PARSE_ERROR; /* not an error ? */
+ } else { /* integer */
+ get_integer(data, endptr);
+ }
+ }
+
+ if (status == CS_SUBR_RETURN) {
+ status = CS_PARSE_OK;
+ } else if (status == CS_CHAR_END && *data < endptr) {
+ WARN("%s: Garbage after endchar.", CS_TYPE2_DEBUG_STR);
+ } else if (status < CS_PARSE_OK) { /* error */
+ ERROR("%s: Parsing charstring failed: (status=%d, stack=%d)",
+ CS_TYPE2_DEBUG_STR, status, stack_top);
+ }
+
+ nest--;
+
+ return;
+}
+
+static void
+cs_parse_init (void)
+{
+ status = CS_PARSE_OK;
+ nest = 0;
+ phase = 0;
+ num_stems = 0;
+ stack_top = 0;
+}
+
+/*
+ * Not just copying...
+ */
+int
+cs_copy_charstring (card8 *dst, int dstlen,
+ card8 *src, int srclen,
+ cff_index *gsubr, cff_index *subr,
+ double default_width, double nominal_width, cs_ginfo *ginfo)
+{
+ card8 *save = dst;
+
+ cs_parse_init();
+
+ width = 0.0;
+ have_width = 0;
+
+ /* expand call(g)subrs */
+ do_charstring(&dst, dst + dstlen, &src, src + srclen, gsubr, subr);
+
+ if (ginfo) {
+ ginfo->flags = 0; /* not used */
+ if (have_width) {
+ ginfo->wx = nominal_width + width;
+ } else {
+ ginfo->wx = default_width;
+ }
+ }
+
+ return (int)(dst - save);
+}
diff --git a/Build/source/texk/dvipdfm-x/cs_type2.h b/Build/source/texk/dvipdfm-x/cs_type2.h
new file mode 100644
index 00000000000..0b49464cec9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/cs_type2.h
@@ -0,0 +1,43 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _CS_TYPE2_H_
+#define _CS_TYPE2_H_
+
+#include "cff_types.h"
+
+typedef struct {
+ int flags; /* unused in Type 2 charstring */
+ double wx, wy;
+ struct {
+ double llx, lly, urx, ury;
+ } bbox;
+ struct {
+ double asb, adx, ady;
+ card8 bchar, achar;
+ } seac; /* unused in Type 2 charstring */
+} cs_ginfo;
+
+extern int cs_copy_charstring (card8 *dest, int destlen,
+ card8 *src, int srclen,
+ cff_index *gsubr, cff_index *subr,
+ double default_width, double nominal_width, cs_ginfo *ginfo);
+
+#endif /* _CS_TYPE2_H_ */
diff --git a/Build/source/texk/dvipdfm-x/data/Adobe-Japan1-YuMincho-Regular b/Build/source/texk/dvipdfm-x/data/Adobe-Japan1-YuMincho-Regular
new file mode 100644
index 00000000000..5f7a57a26cd
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/data/Adobe-Japan1-YuMincho-Regular
@@ -0,0 +1,135 @@
+%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (Adobe-Japan1-YuMincho-Regular)
+%%Title: (Adobe-Japan1-YuMincho-Regular Adobe Japan1 7)
+%%Version: 1.000
+%%EndComments
+
+/CIDInit /ProcSet findresource begin
+
+12 dict begin
+
+begincmap
+
+/CIDSystemInfo 3 dict dup begin
+ /Registry (Adobe) def
+ /Ordering (Adobe_Japan1_YuMincho_Regular) def
+ /Supplement 7 def
+end def
+
+/CMapName /Adobe-Japan1-YuMincho-Regular def
+/CMapVersion 1.000 def
+/CMapType 2 def
+
+/WMode 0 def
+
+1 begincodespacerange
+ <0000> <5AFF>
+endcodespacerange
+
+1 beginbfchar
+<0000> <0000>
+endbfchar
+
+91 beginbfrange
+<0001> <00ff> <0003>
+<0100> <01ff> <0102>
+<0200> <02ff> <0202>
+<0300> <03ff> <0302>
+<0400> <04ff> <0402>
+<0500> <05ff> <0502>
+<0600> <06ff> <0602>
+<0700> <07ff> <0702>
+<0800> <08ff> <0802>
+<0900> <09ff> <0902>
+<0a00> <0aff> <0a02>
+<0b00> <0bff> <0b02>
+<0c00> <0cff> <0c02>
+<0d00> <0dff> <0d02>
+<0e00> <0eff> <0e02>
+<0f00> <0fff> <0f02>
+<1000> <10ff> <1002>
+<1100> <11ff> <1102>
+<1200> <12ff> <1202>
+<1300> <13ff> <1302>
+<1400> <14ff> <1402>
+<1500> <15ff> <1502>
+<1600> <16ff> <1602>
+<1700> <17ff> <1702>
+<1800> <18ff> <1802>
+<1900> <19ff> <1902>
+<1a00> <1aff> <1a02>
+<1b00> <1bff> <1b02>
+<1c00> <1cff> <1c02>
+<1d00> <1dff> <1d02>
+<1e00> <1eff> <1e02>
+<1f00> <1fff> <1f02>
+<2000> <20ff> <2002>
+<2100> <21ff> <2102>
+<2200> <22ff> <2202>
+<2300> <23ff> <2302>
+<2400> <24ff> <2402>
+<2500> <25ff> <2502>
+<2600> <26ff> <2602>
+<2700> <27ff> <2702>
+<2800> <28ff> <2802>
+<2900> <29ff> <2902>
+<2a00> <2aff> <2a02>
+<2b00> <2bff> <2b02>
+<2c00> <2cff> <2c02>
+<2d00> <2dff> <2d02>
+<2e00> <2eff> <2e02>
+<2f00> <2fff> <2f02>
+<3000> <30ff> <3002>
+<3100> <31ff> <3102>
+<3200> <32ff> <3202>
+<3300> <33ff> <3302>
+<3400> <34ff> <3402>
+<3500> <35ff> <3502>
+<3600> <36ff> <3602>
+<3700> <37ff> <3702>
+<3800> <38ff> <3802>
+<3900> <39ff> <3902>
+<3a00> <3aff> <3a02>
+<3b00> <3bff> <3b02>
+<3c00> <3cff> <3c02>
+<3d00> <3dff> <3d02>
+<3e00> <3eff> <3e02>
+<3f00> <3fff> <3f02>
+<4000> <40ff> <4002>
+<4100> <41ff> <4102>
+<4200> <42ff> <4202>
+<4300> <43ff> <4302>
+<4400> <44ff> <4402>
+<4500> <45ff> <4502>
+<4600> <46ff> <4602>
+<4700> <47ff> <4702>
+<4800> <48ff> <4802>
+<4900> <49ff> <4902>
+<4a00> <4aff> <4a02>
+<4b00> <4bff> <4b02>
+<4c00> <4cff> <4c02>
+<4d00> <4dff> <4d02>
+<4e00> <4eff> <4e02>
+<4f00> <4fff> <4f02>
+<5000> <50ff> <5002>
+<5100> <51ff> <5102>
+<5200> <52ff> <5202>
+<5300> <53ff> <5302>
+<5400> <54ff> <5402>
+<5500> <55ff> <5502>
+<5600> <56ff> <5602>
+<5700> <57ff> <5702>
+<5800> <58ff> <5802>
+<5900> <59ff> <5902>
+<5a00> <5a13> <5a02>
+endbfrange
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+
+%%EndResource
+%%EOF
+
diff --git a/Build/source/texk/dvipdfm-x/data/EUC-UCS2 b/Build/source/texk/dvipdfm-x/data/EUC-UCS2
new file mode 100644
index 00000000000..d7a91685ad5
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/data/EUC-UCS2
@@ -0,0 +1,6800 @@
+%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (EUC-UCS2)
+%%Title: (EUC-UCS2)
+%%Version: 1.0
+%%Copyright:
+%% Copyright (C) 2002 by Jin-Hwan Cho <chofchof@ktug.or.kr>
+%%
+%% This program is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU General Public License as published by
+%% the Free Software Foundation; either version 2 of the License, or
+%% (at your option) any later version.
+%%
+%% This program is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this program; if not, write to the Free Software
+%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+%%EndComments
+
+/CIDInit /ProcSet findresource begin
+
+12 dict begin
+
+begincmap
+
+/CIDSystemInfo 3 dict dup begin
+ /Registry (Adobe) def
+ /Ordering (EUC_UCS2) def
+ /Supplement 1 def
+end def
+
+/CMapName /EUC-UCS2 def
+/CMapVersion 1.0 def
+/CMapType 1 def
+/WMode 0 def
+
+3 begincodespacerange
+<00> <7E>
+<8EA0> <8EDF>
+<A1A1> <FEFE>
+endcodespacerange
+
+17 beginbfrange
+<00> <5B> <0000>
+<5D> <7D> <005D>
+<8EA0> <8EDF> <FF60>
+<A1D2> <A1DB> <3008>
+<A3B0> <A3B9> <FF10>
+<A3C1> <A3DA> <FF21>
+<A3E1> <A3FA> <FF41>
+<A4A1> <A4F3> <3041>
+<A5A1> <A5F6> <30A1>
+<A6A1> <A6B1> <0391>
+<A6B2> <A6B8> <03A3>
+<A6C1> <A6D1> <03B1>
+<A6D2> <A6D8> <03C3>
+<A7A1> <A7A6> <0410>
+<A7A8> <A7C1> <0416>
+<A7D1> <A7D6> <0430>
+<A7D8> <A7F1> <0436>
+endbfrange
+
+99 beginbfchar
+<5C> <00A5>
+<7E> <203E>
+<A1A1> <3000>
+<A1A2> <3001>
+<A1A3> <3002>
+<A1A4> <FF0C>
+<A1A5> <FF0E>
+<A1A6> <30FB>
+<A1A7> <FF1A>
+<A1A8> <FF1B>
+<A1A9> <FF1F>
+<A1AA> <FF01>
+<A1AB> <309B>
+<A1AC> <309C>
+<A1AD> <00B4>
+<A1AE> <FF40>
+<A1AF> <00A8>
+<A1B0> <FF3E>
+<A1B1> <203E>
+<A1B2> <FF3F>
+<A1B3> <30FD>
+<A1B4> <30FE>
+<A1B5> <309D>
+<A1B6> <309E>
+<A1B7> <3003>
+<A1B8> <4EDD>
+<A1B9> <3005>
+<A1BA> <3006>
+<A1BB> <3007>
+<A1BC> <30FC>
+<A1BD> <2015>
+<A1BE> <2010>
+<A1BF> <FF0F>
+<A1C0> <FF3C>
+<A1C1> <FF5E>
+<A1C2> <2016>
+<A1C3> <FF5C>
+<A1C4> <2026>
+<A1C5> <2025>
+<A1C6> <2018>
+<A1C7> <2019>
+<A1C8> <201C>
+<A1C9> <201D>
+<A1CA> <FF08>
+<A1CB> <FF09>
+<A1CC> <3014>
+<A1CD> <3015>
+<A1CE> <FF3B>
+<A1CF> <FF3D>
+<A1D0> <FF5B>
+<A1D1> <FF5D>
+<A1DC> <FF0B>
+<A1DD> <FF0D>
+<A1DE> <00B1>
+<A1DF> <00D7>
+<A1E0> <00F7>
+<A1E1> <FF1D>
+<A1E2> <2260>
+<A1E3> <FF1C>
+<A1E4> <FF1E>
+<A1E5> <2266>
+<A1E6> <2267>
+<A1E7> <221E>
+<A1E8> <2234>
+<A1E9> <2642>
+<A1EA> <2640>
+<A1EB> <00B0>
+<A1EC> <2032>
+<A1ED> <2033>
+<A1EE> <2103>
+<A1EF> <FFE5>
+<A1F0> <FF04>
+<A1F1> <00A2>
+<A1F2> <00A3>
+<A1F3> <FF05>
+<A1F4> <FF03>
+<A1F5> <FF06>
+<A1F6> <FF0A>
+<A1F7> <FF20>
+<A1F8> <00A7>
+<A1F9> <2606>
+<A1FA> <2605>
+<A1FB> <25CB>
+<A1FC> <25CF>
+<A1FD> <25CE>
+<A1FE> <25C7>
+<A2A1> <25C6>
+<A2A2> <25A1>
+<A2A3> <25A0>
+<A2A4> <25B3>
+<A2A5> <25B2>
+<A2A6> <25BD>
+<A2A7> <25BC>
+<A2A8> <203B>
+<A2A9> <3012>
+<A2AA> <2192>
+<A2AB> <2190>
+<A2AC> <2191>
+<A2AD> <2193>
+endbfchar
+
+100 beginbfchar
+<A2AE> <3013>
+<A2BA> <2208>
+<A2BB> <220B>
+<A2BC> <2286>
+<A2BD> <2287>
+<A2BE> <2282>
+<A2BF> <2283>
+<A2C0> <222A>
+<A2C1> <2229>
+<A2CA> <2227>
+<A2CB> <2228>
+<A2CC> <00AC>
+<A2CD> <21D2>
+<A2CE> <21D4>
+<A2CF> <2200>
+<A2D0> <2203>
+<A2DC> <2220>
+<A2DD> <22A5>
+<A2DE> <2312>
+<A2DF> <2202>
+<A2E0> <2207>
+<A2E1> <2261>
+<A2E2> <2252>
+<A2E3> <226A>
+<A2E4> <226B>
+<A2E5> <221A>
+<A2E6> <223D>
+<A2E7> <221D>
+<A2E8> <2235>
+<A2E9> <222B>
+<A2EA> <222C>
+<A2F2> <212B>
+<A2F3> <2030>
+<A2F4> <266F>
+<A2F5> <266D>
+<A2F6> <266A>
+<A2F7> <2020>
+<A2F8> <2021>
+<A2F9> <00B6>
+<A2FE> <25EF>
+<A7A7> <0401>
+<A7D7> <0451>
+<A8A1> <2500>
+<A8A2> <2502>
+<A8A3> <250C>
+<A8A4> <2510>
+<A8A5> <2518>
+<A8A6> <2514>
+<A8A7> <251C>
+<A8A8> <252C>
+<A8A9> <2524>
+<A8AA> <2534>
+<A8AB> <253C>
+<A8AC> <2501>
+<A8AD> <2503>
+<A8AE> <250F>
+<A8AF> <2513>
+<A8B0> <251B>
+<A8B1> <2517>
+<A8B2> <2523>
+<A8B3> <2533>
+<A8B4> <252B>
+<A8B5> <253B>
+<A8B6> <254B>
+<A8B7> <2520>
+<A8B8> <252F>
+<A8B9> <2528>
+<A8BA> <2537>
+<A8BB> <253F>
+<A8BC> <251D>
+<A8BD> <2530>
+<A8BE> <2525>
+<A8BF> <2538>
+<A8C0> <2542>
+<B0A1> <4E9C>
+<B0A2> <5516>
+<B0A3> <5A03>
+<B0A4> <963F>
+<B0A5> <54C0>
+<B0A6> <611B>
+<B0A7> <6328>
+<B0A8> <59F6>
+<B0A9> <9022>
+<B0AA> <8475>
+<B0AB> <831C>
+<B0AC> <7A50>
+<B0AD> <60AA>
+<B0AE> <63E1>
+<B0AF> <6E25>
+<B0B0> <65ED>
+<B0B1> <8466>
+<B0B2> <82A6>
+<B0B3> <9BF5>
+<B0B4> <6893>
+<B0B5> <5727>
+<B0B6> <65A1>
+<B0B7> <6271>
+<B0B8> <5B9B>
+<B0B9> <59D0>
+<B0BA> <867B>
+endbfchar
+
+100 beginbfchar
+<B0BB> <98F4>
+<B0BC> <7D62>
+<B0BD> <7DBE>
+<B0BE> <9B8E>
+<B0BF> <6216>
+<B0C0> <7C9F>
+<B0C1> <88B7>
+<B0C2> <5B89>
+<B0C3> <5EB5>
+<B0C4> <6309>
+<B0C5> <6697>
+<B0C6> <6848>
+<B0C7> <95C7>
+<B0C8> <978D>
+<B0C9> <674F>
+<B0CA> <4EE5>
+<B0CB> <4F0A>
+<B0CC> <4F4D>
+<B0CD> <4F9D>
+<B0CE> <5049>
+<B0CF> <56F2>
+<B0D0> <5937>
+<B0D1> <59D4>
+<B0D2> <5A01>
+<B0D3> <5C09>
+<B0D4> <60DF>
+<B0D5> <610F>
+<B0D6> <6170>
+<B0D7> <6613>
+<B0D8> <6905>
+<B0D9> <70BA>
+<B0DA> <754F>
+<B0DB> <7570>
+<B0DC> <79FB>
+<B0DD> <7DAD>
+<B0DE> <7DEF>
+<B0DF> <80C3>
+<B0E0> <840E>
+<B0E1> <8863>
+<B0E2> <8B02>
+<B0E3> <9055>
+<B0E4> <907A>
+<B0E5> <533B>
+<B0E6> <4E95>
+<B0E7> <4EA5>
+<B0E8> <57DF>
+<B0E9> <80B2>
+<B0EA> <90C1>
+<B0EB> <78EF>
+<B0EC> <4E00>
+<B0ED> <58F1>
+<B0EE> <6EA2>
+<B0EF> <9038>
+<B0F0> <7A32>
+<B0F1> <8328>
+<B0F2> <828B>
+<B0F3> <9C2F>
+<B0F4> <5141>
+<B0F5> <5370>
+<B0F6> <54BD>
+<B0F7> <54E1>
+<B0F8> <56E0>
+<B0F9> <59FB>
+<B0FA> <5F15>
+<B0FB> <98F2>
+<B0FC> <6DEB>
+<B0FD> <80E4>
+<B0FE> <852D>
+<B1A1> <9662>
+<B1A2> <9670>
+<B1A3> <96A0>
+<B1A4> <97FB>
+<B1A5> <540B>
+<B1A6> <53F3>
+<B1A7> <5B87>
+<B1A8> <70CF>
+<B1A9> <7FBD>
+<B1AA> <8FC2>
+<B1AB> <96E8>
+<B1AC> <536F>
+<B1AD> <9D5C>
+<B1AE> <7ABA>
+<B1AF> <4E11>
+<B1B0> <7893>
+<B1B1> <81FC>
+<B1B2> <6E26>
+<B1B3> <5618>
+<B1B4> <5504>
+<B1B5> <6B1D>
+<B1B6> <851A>
+<B1B7> <9C3B>
+<B1B8> <59E5>
+<B1B9> <53A9>
+<B1BA> <6D66>
+<B1BB> <74DC>
+<B1BC> <958F>
+<B1BD> <5642>
+<B1BE> <4E91>
+<B1BF> <904B>
+<B1C0> <96F2>
+endbfchar
+
+100 beginbfchar
+<B1C1> <834F>
+<B1C2> <990C>
+<B1C3> <53E1>
+<B1C4> <55B6>
+<B1C5> <5B30>
+<B1C6> <5F71>
+<B1C7> <6620>
+<B1C8> <66F3>
+<B1C9> <6804>
+<B1CA> <6C38>
+<B1CB> <6CF3>
+<B1CC> <6D29>
+<B1CD> <745B>
+<B1CE> <76C8>
+<B1CF> <7A4E>
+<B1D0> <9834>
+<B1D1> <82F1>
+<B1D2> <885B>
+<B1D3> <8A60>
+<B1D4> <92ED>
+<B1D5> <6DB2>
+<B1D6> <75AB>
+<B1D7> <76CA>
+<B1D8> <99C5>
+<B1D9> <60A6>
+<B1DA> <8B01>
+<B1DB> <8D8A>
+<B1DC> <95B2>
+<B1DD> <698E>
+<B1DE> <53AD>
+<B1DF> <5186>
+<B1E0> <5712>
+<B1E1> <5830>
+<B1E2> <5944>
+<B1E3> <5BB4>
+<B1E4> <5EF6>
+<B1E5> <6028>
+<B1E6> <63A9>
+<B1E7> <63F4>
+<B1E8> <6CBF>
+<B1E9> <6F14>
+<B1EA> <708E>
+<B1EB> <7114>
+<B1EC> <7159>
+<B1ED> <71D5>
+<B1EE> <733F>
+<B1EF> <7E01>
+<B1F0> <8276>
+<B1F1> <82D1>
+<B1F2> <8597>
+<B1F3> <9060>
+<B1F4> <925B>
+<B1F5> <9D1B>
+<B1F6> <5869>
+<B1F7> <65BC>
+<B1F8> <6C5A>
+<B1F9> <7525>
+<B1FA> <51F9>
+<B1FB> <592E>
+<B1FC> <5965>
+<B1FD> <5F80>
+<B1FE> <5FDC>
+<B2A1> <62BC>
+<B2A2> <65FA>
+<B2A3> <6A2A>
+<B2A4> <6B27>
+<B2A5> <6BB4>
+<B2A6> <738B>
+<B2A7> <7FC1>
+<B2A8> <8956>
+<B2A9> <9D2C>
+<B2AA> <9D0E>
+<B2AB> <9EC4>
+<B2AC> <5CA1>
+<B2AD> <6C96>
+<B2AE> <837B>
+<B2AF> <5104>
+<B2B0> <5C4B>
+<B2B1> <61B6>
+<B2B2> <81C6>
+<B2B3> <6876>
+<B2B4> <7261>
+<B2B5> <4E59>
+<B2B6> <4FFA>
+<B2B7> <5378>
+<B2B8> <6069>
+<B2B9> <6E29>
+<B2BA> <7A4F>
+<B2BB> <97F3>
+<B2BC> <4E0B>
+<B2BD> <5316>
+<B2BE> <4EEE>
+<B2BF> <4F55>
+<B2C0> <4F3D>
+<B2C1> <4FA1>
+<B2C2> <4F73>
+<B2C3> <52A0>
+<B2C4> <53EF>
+<B2C5> <5609>
+<B2C6> <590F>
+endbfchar
+
+100 beginbfchar
+<B2C7> <5AC1>
+<B2C8> <5BB6>
+<B2C9> <5BE1>
+<B2CA> <79D1>
+<B2CB> <6687>
+<B2CC> <679C>
+<B2CD> <67B6>
+<B2CE> <6B4C>
+<B2CF> <6CB3>
+<B2D0> <706B>
+<B2D1> <73C2>
+<B2D2> <798D>
+<B2D3> <79BE>
+<B2D4> <7A3C>
+<B2D5> <7B87>
+<B2D6> <82B1>
+<B2D7> <82DB>
+<B2D8> <8304>
+<B2D9> <8377>
+<B2DA> <83EF>
+<B2DB> <83D3>
+<B2DC> <8766>
+<B2DD> <8AB2>
+<B2DE> <5629>
+<B2DF> <8CA8>
+<B2E0> <8FE6>
+<B2E1> <904E>
+<B2E2> <971E>
+<B2E3> <868A>
+<B2E4> <4FC4>
+<B2E5> <5CE8>
+<B2E6> <6211>
+<B2E7> <7259>
+<B2E8> <753B>
+<B2E9> <81E5>
+<B2EA> <82BD>
+<B2EB> <86FE>
+<B2EC> <8CC0>
+<B2ED> <96C5>
+<B2EE> <9913>
+<B2EF> <99D5>
+<B2F0> <4ECB>
+<B2F1> <4F1A>
+<B2F2> <89E3>
+<B2F3> <56DE>
+<B2F4> <584A>
+<B2F5> <58CA>
+<B2F6> <5EFB>
+<B2F7> <5FEB>
+<B2F8> <602A>
+<B2F9> <6094>
+<B2FA> <6062>
+<B2FB> <61D0>
+<B2FC> <6212>
+<B2FD> <62D0>
+<B2FE> <6539>
+<B3A1> <9B41>
+<B3A2> <6666>
+<B3A3> <68B0>
+<B3A4> <6D77>
+<B3A5> <7070>
+<B3A6> <754C>
+<B3A7> <7686>
+<B3A8> <7D75>
+<B3A9> <82A5>
+<B3AA> <87F9>
+<B3AB> <958B>
+<B3AC> <968E>
+<B3AD> <8C9D>
+<B3AE> <51F1>
+<B3AF> <52BE>
+<B3B0> <5916>
+<B3B1> <54B3>
+<B3B2> <5BB3>
+<B3B3> <5D16>
+<B3B4> <6168>
+<B3B5> <6982>
+<B3B6> <6DAF>
+<B3B7> <788D>
+<B3B8> <84CB>
+<B3B9> <8857>
+<B3BA> <8A72>
+<B3BB> <93A7>
+<B3BC> <9AB8>
+<B3BD> <6D6C>
+<B3BE> <99A8>
+<B3BF> <86D9>
+<B3C0> <57A3>
+<B3C1> <67FF>
+<B3C2> <86CE>
+<B3C3> <920E>
+<B3C4> <5283>
+<B3C5> <5687>
+<B3C6> <5404>
+<B3C7> <5ED3>
+<B3C8> <62E1>
+<B3C9> <64B9>
+<B3CA> <683C>
+<B3CB> <6838>
+<B3CC> <6BBB>
+endbfchar
+
+100 beginbfchar
+<B3CD> <7372>
+<B3CE> <78BA>
+<B3CF> <7A6B>
+<B3D0> <899A>
+<B3D1> <89D2>
+<B3D2> <8D6B>
+<B3D3> <8F03>
+<B3D4> <90ED>
+<B3D5> <95A3>
+<B3D6> <9694>
+<B3D7> <9769>
+<B3D8> <5B66>
+<B3D9> <5CB3>
+<B3DA> <697D>
+<B3DB> <984D>
+<B3DC> <984E>
+<B3DD> <639B>
+<B3DE> <7B20>
+<B3DF> <6A2B>
+<B3E0> <6A7F>
+<B3E1> <68B6>
+<B3E2> <9C0D>
+<B3E3> <6F5F>
+<B3E4> <5272>
+<B3E5> <559D>
+<B3E6> <6070>
+<B3E7> <62EC>
+<B3E8> <6D3B>
+<B3E9> <6E07>
+<B3EA> <6ED1>
+<B3EB> <845B>
+<B3EC> <8910>
+<B3ED> <8F44>
+<B3EE> <4E14>
+<B3EF> <9C39>
+<B3F0> <53F6>
+<B3F1> <691B>
+<B3F2> <6A3A>
+<B3F3> <9784>
+<B3F4> <682A>
+<B3F5> <515C>
+<B3F6> <7AC3>
+<B3F7> <84B2>
+<B3F8> <91DC>
+<B3F9> <938C>
+<B3FA> <565B>
+<B3FB> <9D28>
+<B3FC> <6822>
+<B3FD> <8305>
+<B3FE> <8431>
+<B4A1> <7CA5>
+<B4A2> <5208>
+<B4A3> <82C5>
+<B4A4> <74E6>
+<B4A5> <4E7E>
+<B4A6> <4F83>
+<B4A7> <51A0>
+<B4A8> <5BD2>
+<B4A9> <520A>
+<B4AA> <52D8>
+<B4AB> <52E7>
+<B4AC> <5DFB>
+<B4AD> <559A>
+<B4AE> <582A>
+<B4AF> <59E6>
+<B4B0> <5B8C>
+<B4B1> <5B98>
+<B4B2> <5BDB>
+<B4B3> <5E72>
+<B4B4> <5E79>
+<B4B5> <60A3>
+<B4B6> <611F>
+<B4B7> <6163>
+<B4B8> <61BE>
+<B4B9> <63DB>
+<B4BA> <6562>
+<B4BB> <67D1>
+<B4BC> <6853>
+<B4BD> <68FA>
+<B4BE> <6B3E>
+<B4BF> <6B53>
+<B4C0> <6C57>
+<B4C1> <6F22>
+<B4C2> <6F97>
+<B4C3> <6F45>
+<B4C4> <74B0>
+<B4C5> <7518>
+<B4C6> <76E3>
+<B4C7> <770B>
+<B4C8> <7AFF>
+<B4C9> <7BA1>
+<B4CA> <7C21>
+<B4CB> <7DE9>
+<B4CC> <7F36>
+<B4CD> <7FF0>
+<B4CE> <809D>
+<B4CF> <8266>
+<B4D0> <839E>
+<B4D1> <89B3>
+<B4D2> <8ACC>
+endbfchar
+
+100 beginbfchar
+<B4D3> <8CAB>
+<B4D4> <9084>
+<B4D5> <9451>
+<B4D6> <9593>
+<B4D7> <9591>
+<B4D8> <95A2>
+<B4D9> <9665>
+<B4DA> <97D3>
+<B4DB> <9928>
+<B4DC> <8218>
+<B4DD> <4E38>
+<B4DE> <542B>
+<B4DF> <5CB8>
+<B4E0> <5DCC>
+<B4E1> <73A9>
+<B4E2> <764C>
+<B4E3> <773C>
+<B4E4> <5CA9>
+<B4E5> <7FEB>
+<B4E6> <8D0B>
+<B4E7> <96C1>
+<B4E8> <9811>
+<B4E9> <9854>
+<B4EA> <9858>
+<B4EB> <4F01>
+<B4EC> <4F0E>
+<B4ED> <5371>
+<B4EE> <559C>
+<B4EF> <5668>
+<B4F0> <57FA>
+<B4F1> <5947>
+<B4F2> <5B09>
+<B4F3> <5BC4>
+<B4F4> <5C90>
+<B4F5> <5E0C>
+<B4F6> <5E7E>
+<B4F7> <5FCC>
+<B4F8> <63EE>
+<B4F9> <673A>
+<B4FA> <65D7>
+<B4FB> <65E2>
+<B4FC> <671F>
+<B4FD> <68CB>
+<B4FE> <68C4>
+<B5A1> <6A5F>
+<B5A2> <5E30>
+<B5A3> <6BC5>
+<B5A4> <6C17>
+<B5A5> <6C7D>
+<B5A6> <757F>
+<B5A7> <7948>
+<B5A8> <5B63>
+<B5A9> <7A00>
+<B5AA> <7D00>
+<B5AB> <5FBD>
+<B5AC> <898F>
+<B5AD> <8A18>
+<B5AE> <8CB4>
+<B5AF> <8D77>
+<B5B0> <8ECC>
+<B5B1> <8F1D>
+<B5B2> <98E2>
+<B5B3> <9A0E>
+<B5B4> <9B3C>
+<B5B5> <4E80>
+<B5B6> <507D>
+<B5B7> <5100>
+<B5B8> <5993>
+<B5B9> <5B9C>
+<B5BA> <622F>
+<B5BB> <6280>
+<B5BC> <64EC>
+<B5BD> <6B3A>
+<B5BE> <72A0>
+<B5BF> <7591>
+<B5C0> <7947>
+<B5C1> <7FA9>
+<B5C2> <87FB>
+<B5C3> <8ABC>
+<B5C4> <8B70>
+<B5C5> <63AC>
+<B5C6> <83CA>
+<B5C7> <97A0>
+<B5C8> <5409>
+<B5C9> <5403>
+<B5CA> <55AB>
+<B5CB> <6854>
+<B5CC> <6A58>
+<B5CD> <8A70>
+<B5CE> <7827>
+<B5CF> <6775>
+<B5D0> <9ECD>
+<B5D1> <5374>
+<B5D2> <5BA2>
+<B5D3> <811A>
+<B5D4> <8650>
+<B5D5> <9006>
+<B5D6> <4E18>
+<B5D7> <4E45>
+<B5D8> <4EC7>
+endbfchar
+
+100 beginbfchar
+<B5D9> <4F11>
+<B5DA> <53CA>
+<B5DB> <5438>
+<B5DC> <5BAE>
+<B5DD> <5F13>
+<B5DE> <6025>
+<B5DF> <6551>
+<B5E0> <673D>
+<B5E1> <6C42>
+<B5E2> <6C72>
+<B5E3> <6CE3>
+<B5E4> <7078>
+<B5E5> <7403>
+<B5E6> <7A76>
+<B5E7> <7AAE>
+<B5E8> <7B08>
+<B5E9> <7D1A>
+<B5EA> <7CFE>
+<B5EB> <7D66>
+<B5EC> <65E7>
+<B5ED> <725B>
+<B5EE> <53BB>
+<B5EF> <5C45>
+<B5F0> <5DE8>
+<B5F1> <62D2>
+<B5F2> <62E0>
+<B5F3> <6319>
+<B5F4> <6E20>
+<B5F5> <865A>
+<B5F6> <8A31>
+<B5F7> <8DDD>
+<B5F8> <92F8>
+<B5F9> <6F01>
+<B5FA> <79A6>
+<B5FB> <9B5A>
+<B5FC> <4EA8>
+<B5FD> <4EAB>
+<B5FE> <4EAC>
+<B6A1> <4F9B>
+<B6A2> <4FA0>
+<B6A3> <50D1>
+<B6A4> <5147>
+<B6A5> <7AF6>
+<B6A6> <5171>
+<B6A7> <51F6>
+<B6A8> <5354>
+<B6A9> <5321>
+<B6AA> <537F>
+<B6AB> <53EB>
+<B6AC> <55AC>
+<B6AD> <5883>
+<B6AE> <5CE1>
+<B6AF> <5F37>
+<B6B0> <5F4A>
+<B6B1> <602F>
+<B6B2> <6050>
+<B6B3> <606D>
+<B6B4> <631F>
+<B6B5> <6559>
+<B6B6> <6A4B>
+<B6B7> <6CC1>
+<B6B8> <72C2>
+<B6B9> <72ED>
+<B6BA> <77EF>
+<B6BB> <80F8>
+<B6BC> <8105>
+<B6BD> <8208>
+<B6BE> <854E>
+<B6BF> <90F7>
+<B6C0> <93E1>
+<B6C1> <97FF>
+<B6C2> <9957>
+<B6C3> <9A5A>
+<B6C4> <4EF0>
+<B6C5> <51DD>
+<B6C6> <5C2D>
+<B6C7> <6681>
+<B6C8> <696D>
+<B6C9> <5C40>
+<B6CA> <66F2>
+<B6CB> <6975>
+<B6CC> <7389>
+<B6CD> <6850>
+<B6CE> <7C81>
+<B6CF> <50C5>
+<B6D0> <52E4>
+<B6D1> <5747>
+<B6D2> <5DFE>
+<B6D3> <9326>
+<B6D4> <65A4>
+<B6D5> <6B23>
+<B6D6> <6B3D>
+<B6D7> <7434>
+<B6D8> <7981>
+<B6D9> <79BD>
+<B6DA> <7B4B>
+<B6DB> <7DCA>
+<B6DC> <82B9>
+<B6DD> <83CC>
+<B6DE> <887F>
+endbfchar
+
+100 beginbfchar
+<B6DF> <895F>
+<B6E0> <8B39>
+<B6E1> <8FD1>
+<B6E2> <91D1>
+<B6E3> <541F>
+<B6E4> <9280>
+<B6E5> <4E5D>
+<B6E6> <5036>
+<B6E7> <53E5>
+<B6E8> <533A>
+<B6E9> <72D7>
+<B6EA> <7396>
+<B6EB> <77E9>
+<B6EC> <82E6>
+<B6ED> <8EAF>
+<B6EE> <99C6>
+<B6EF> <99C8>
+<B6F0> <99D2>
+<B6F1> <5177>
+<B6F2> <611A>
+<B6F3> <865E>
+<B6F4> <55B0>
+<B6F5> <7A7A>
+<B6F6> <5076>
+<B6F7> <5BD3>
+<B6F8> <9047>
+<B6F9> <9685>
+<B6FA> <4E32>
+<B6FB> <6ADB>
+<B6FC> <91E7>
+<B6FD> <5C51>
+<B6FE> <5C48>
+<B7A1> <6398>
+<B7A2> <7A9F>
+<B7A3> <6C93>
+<B7A4> <9774>
+<B7A5> <8F61>
+<B7A6> <7AAA>
+<B7A7> <718A>
+<B7A8> <9688>
+<B7A9> <7C82>
+<B7AA> <6817>
+<B7AB> <7E70>
+<B7AC> <6851>
+<B7AD> <936C>
+<B7AE> <52F2>
+<B7AF> <541B>
+<B7B0> <85AB>
+<B7B1> <8A13>
+<B7B2> <7FA4>
+<B7B3> <8ECD>
+<B7B4> <90E1>
+<B7B5> <5366>
+<B7B6> <8888>
+<B7B7> <7941>
+<B7B8> <4FC2>
+<B7B9> <50BE>
+<B7BA> <5211>
+<B7BB> <5144>
+<B7BC> <5553>
+<B7BD> <572D>
+<B7BE> <73EA>
+<B7BF> <578B>
+<B7C0> <5951>
+<B7C1> <5F62>
+<B7C2> <5F84>
+<B7C3> <6075>
+<B7C4> <6176>
+<B7C5> <6167>
+<B7C6> <61A9>
+<B7C7> <63B2>
+<B7C8> <643A>
+<B7C9> <656C>
+<B7CA> <666F>
+<B7CB> <6842>
+<B7CC> <6E13>
+<B7CD> <7566>
+<B7CE> <7A3D>
+<B7CF> <7CFB>
+<B7D0> <7D4C>
+<B7D1> <7D99>
+<B7D2> <7E4B>
+<B7D3> <7F6B>
+<B7D4> <830E>
+<B7D5> <834A>
+<B7D6> <86CD>
+<B7D7> <8A08>
+<B7D8> <8A63>
+<B7D9> <8B66>
+<B7DA> <8EFD>
+<B7DB> <981A>
+<B7DC> <9D8F>
+<B7DD> <82B8>
+<B7DE> <8FCE>
+<B7DF> <9BE8>
+<B7E0> <5287>
+<B7E1> <621F>
+<B7E2> <6483>
+<B7E3> <6FC0>
+<B7E4> <9699>
+endbfchar
+
+100 beginbfchar
+<B7E5> <6841>
+<B7E6> <5091>
+<B7E7> <6B20>
+<B7E8> <6C7A>
+<B7E9> <6F54>
+<B7EA> <7A74>
+<B7EB> <7D50>
+<B7EC> <8840>
+<B7ED> <8A23>
+<B7EE> <6708>
+<B7EF> <4EF6>
+<B7F0> <5039>
+<B7F1> <5026>
+<B7F2> <5065>
+<B7F3> <517C>
+<B7F4> <5238>
+<B7F5> <5263>
+<B7F6> <55A7>
+<B7F7> <570F>
+<B7F8> <5805>
+<B7F9> <5ACC>
+<B7FA> <5EFA>
+<B7FB> <61B2>
+<B7FC> <61F8>
+<B7FD> <62F3>
+<B7FE> <6372>
+<B8A1> <691C>
+<B8A2> <6A29>
+<B8A3> <727D>
+<B8A4> <72AC>
+<B8A5> <732E>
+<B8A6> <7814>
+<B8A7> <786F>
+<B8A8> <7D79>
+<B8A9> <770C>
+<B8AA> <80A9>
+<B8AB> <898B>
+<B8AC> <8B19>
+<B8AD> <8CE2>
+<B8AE> <8ED2>
+<B8AF> <9063>
+<B8B0> <9375>
+<B8B1> <967A>
+<B8B2> <9855>
+<B8B3> <9A13>
+<B8B4> <9E78>
+<B8B5> <5143>
+<B8B6> <539F>
+<B8B7> <53B3>
+<B8B8> <5E7B>
+<B8B9> <5F26>
+<B8BA> <6E1B>
+<B8BB> <6E90>
+<B8BC> <7384>
+<B8BD> <73FE>
+<B8BE> <7D43>
+<B8BF> <8237>
+<B8C0> <8A00>
+<B8C1> <8AFA>
+<B8C2> <9650>
+<B8C3> <4E4E>
+<B8C4> <500B>
+<B8C5> <53E4>
+<B8C6> <547C>
+<B8C7> <56FA>
+<B8C8> <59D1>
+<B8C9> <5B64>
+<B8CA> <5DF1>
+<B8CB> <5EAB>
+<B8CC> <5F27>
+<B8CD> <6238>
+<B8CE> <6545>
+<B8CF> <67AF>
+<B8D0> <6E56>
+<B8D1> <72D0>
+<B8D2> <7CCA>
+<B8D3> <88B4>
+<B8D4> <80A1>
+<B8D5> <80E1>
+<B8D6> <83F0>
+<B8D7> <864E>
+<B8D8> <8A87>
+<B8D9> <8DE8>
+<B8DA> <9237>
+<B8DB> <96C7>
+<B8DC> <9867>
+<B8DD> <9F13>
+<B8DE> <4E94>
+<B8DF> <4E92>
+<B8E0> <4F0D>
+<B8E1> <5348>
+<B8E2> <5449>
+<B8E3> <543E>
+<B8E4> <5A2F>
+<B8E5> <5F8C>
+<B8E6> <5FA1>
+<B8E7> <609F>
+<B8E8> <68A7>
+<B8E9> <6A8E>
+<B8EA> <745A>
+endbfchar
+
+100 beginbfchar
+<B8EB> <7881>
+<B8EC> <8A9E>
+<B8ED> <8AA4>
+<B8EE> <8B77>
+<B8EF> <9190>
+<B8F0> <4E5E>
+<B8F1> <9BC9>
+<B8F2> <4EA4>
+<B8F3> <4F7C>
+<B8F4> <4FAF>
+<B8F5> <5019>
+<B8F6> <5016>
+<B8F7> <5149>
+<B8F8> <516C>
+<B8F9> <529F>
+<B8FA> <52B9>
+<B8FB> <52FE>
+<B8FC> <539A>
+<B8FD> <53E3>
+<B8FE> <5411>
+<B9A1> <540E>
+<B9A2> <5589>
+<B9A3> <5751>
+<B9A4> <57A2>
+<B9A5> <597D>
+<B9A6> <5B54>
+<B9A7> <5B5D>
+<B9A8> <5B8F>
+<B9A9> <5DE5>
+<B9AA> <5DE7>
+<B9AB> <5DF7>
+<B9AC> <5E78>
+<B9AD> <5E83>
+<B9AE> <5E9A>
+<B9AF> <5EB7>
+<B9B0> <5F18>
+<B9B1> <6052>
+<B9B2> <614C>
+<B9B3> <6297>
+<B9B4> <62D8>
+<B9B5> <63A7>
+<B9B6> <653B>
+<B9B7> <6602>
+<B9B8> <6643>
+<B9B9> <66F4>
+<B9BA> <676D>
+<B9BB> <6821>
+<B9BC> <6897>
+<B9BD> <69CB>
+<B9BE> <6C5F>
+<B9BF> <6D2A>
+<B9C0> <6D69>
+<B9C1> <6E2F>
+<B9C2> <6E9D>
+<B9C3> <7532>
+<B9C4> <7687>
+<B9C5> <786C>
+<B9C6> <7A3F>
+<B9C7> <7CE0>
+<B9C8> <7D05>
+<B9C9> <7D18>
+<B9CA> <7D5E>
+<B9CB> <7DB1>
+<B9CC> <8015>
+<B9CD> <8003>
+<B9CE> <80AF>
+<B9CF> <80B1>
+<B9D0> <8154>
+<B9D1> <818F>
+<B9D2> <822A>
+<B9D3> <8352>
+<B9D4> <884C>
+<B9D5> <8861>
+<B9D6> <8B1B>
+<B9D7> <8CA2>
+<B9D8> <8CFC>
+<B9D9> <90CA>
+<B9DA> <9175>
+<B9DB> <9271>
+<B9DC> <783F>
+<B9DD> <92FC>
+<B9DE> <95A4>
+<B9DF> <964D>
+<B9E0> <9805>
+<B9E1> <9999>
+<B9E2> <9AD8>
+<B9E3> <9D3B>
+<B9E4> <525B>
+<B9E5> <52AB>
+<B9E6> <53F7>
+<B9E7> <5408>
+<B9E8> <58D5>
+<B9E9> <62F7>
+<B9EA> <6FE0>
+<B9EB> <8C6A>
+<B9EC> <8F5F>
+<B9ED> <9EB9>
+<B9EE> <514B>
+<B9EF> <523B>
+<B9F0> <544A>
+endbfchar
+
+100 beginbfchar
+<B9F1> <56FD>
+<B9F2> <7A40>
+<B9F3> <9177>
+<B9F4> <9D60>
+<B9F5> <9ED2>
+<B9F6> <7344>
+<B9F7> <6F09>
+<B9F8> <8170>
+<B9F9> <7511>
+<B9FA> <5FFD>
+<B9FB> <60DA>
+<B9FC> <9AA8>
+<B9FD> <72DB>
+<B9FE> <8FBC>
+<BAA1> <6B64>
+<BAA2> <9803>
+<BAA3> <4ECA>
+<BAA4> <56F0>
+<BAA5> <5764>
+<BAA6> <58BE>
+<BAA7> <5A5A>
+<BAA8> <6068>
+<BAA9> <61C7>
+<BAAA> <660F>
+<BAAB> <6606>
+<BAAC> <6839>
+<BAAD> <68B1>
+<BAAE> <6DF7>
+<BAAF> <75D5>
+<BAB0> <7D3A>
+<BAB1> <826E>
+<BAB2> <9B42>
+<BAB3> <4E9B>
+<BAB4> <4F50>
+<BAB5> <53C9>
+<BAB6> <5506>
+<BAB7> <5D6F>
+<BAB8> <5DE6>
+<BAB9> <5DEE>
+<BABA> <67FB>
+<BABB> <6C99>
+<BABC> <7473>
+<BABD> <7802>
+<BABE> <8A50>
+<BABF> <9396>
+<BAC0> <88DF>
+<BAC1> <5750>
+<BAC2> <5EA7>
+<BAC3> <632B>
+<BAC4> <50B5>
+<BAC5> <50AC>
+<BAC6> <518D>
+<BAC7> <6700>
+<BAC8> <54C9>
+<BAC9> <585E>
+<BACA> <59BB>
+<BACB> <5BB0>
+<BACC> <5F69>
+<BACD> <624D>
+<BACE> <63A1>
+<BACF> <683D>
+<BAD0> <6B73>
+<BAD1> <6E08>
+<BAD2> <707D>
+<BAD3> <91C7>
+<BAD4> <7280>
+<BAD5> <7815>
+<BAD6> <7826>
+<BAD7> <796D>
+<BAD8> <658E>
+<BAD9> <7D30>
+<BADA> <83DC>
+<BADB> <88C1>
+<BADC> <8F09>
+<BADD> <969B>
+<BADE> <5264>
+<BADF> <5728>
+<BAE0> <6750>
+<BAE1> <7F6A>
+<BAE2> <8CA1>
+<BAE3> <51B4>
+<BAE4> <5742>
+<BAE5> <962A>
+<BAE6> <583A>
+<BAE7> <698A>
+<BAE8> <80B4>
+<BAE9> <54B2>
+<BAEA> <5D0E>
+<BAEB> <57FC>
+<BAEC> <7895>
+<BAED> <9DFA>
+<BAEE> <4F5C>
+<BAEF> <524A>
+<BAF0> <548B>
+<BAF1> <643E>
+<BAF2> <6628>
+<BAF3> <6714>
+<BAF4> <67F5>
+<BAF5> <7A84>
+<BAF6> <7B56>
+endbfchar
+
+100 beginbfchar
+<BAF7> <7D22>
+<BAF8> <932F>
+<BAF9> <685C>
+<BAFA> <9BAD>
+<BAFB> <7B39>
+<BAFC> <5319>
+<BAFD> <518A>
+<BAFE> <5237>
+<BBA1> <5BDF>
+<BBA2> <62F6>
+<BBA3> <64AE>
+<BBA4> <64E6>
+<BBA5> <672D>
+<BBA6> <6BBA>
+<BBA7> <85A9>
+<BBA8> <96D1>
+<BBA9> <7690>
+<BBAA> <9BD6>
+<BBAB> <634C>
+<BBAC> <9306>
+<BBAD> <9BAB>
+<BBAE> <76BF>
+<BBAF> <6652>
+<BBB0> <4E09>
+<BBB1> <5098>
+<BBB2> <53C2>
+<BBB3> <5C71>
+<BBB4> <60E8>
+<BBB5> <6492>
+<BBB6> <6563>
+<BBB7> <685F>
+<BBB8> <71E6>
+<BBB9> <73CA>
+<BBBA> <7523>
+<BBBB> <7B97>
+<BBBC> <7E82>
+<BBBD> <8695>
+<BBBE> <8B83>
+<BBBF> <8CDB>
+<BBC0> <9178>
+<BBC1> <9910>
+<BBC2> <65AC>
+<BBC3> <66AB>
+<BBC4> <6B8B>
+<BBC5> <4ED5>
+<BBC6> <4ED4>
+<BBC7> <4F3A>
+<BBC8> <4F7F>
+<BBC9> <523A>
+<BBCA> <53F8>
+<BBCB> <53F2>
+<BBCC> <55E3>
+<BBCD> <56DB>
+<BBCE> <58EB>
+<BBCF> <59CB>
+<BBD0> <59C9>
+<BBD1> <59FF>
+<BBD2> <5B50>
+<BBD3> <5C4D>
+<BBD4> <5E02>
+<BBD5> <5E2B>
+<BBD6> <5FD7>
+<BBD7> <601D>
+<BBD8> <6307>
+<BBD9> <652F>
+<BBDA> <5B5C>
+<BBDB> <65AF>
+<BBDC> <65BD>
+<BBDD> <65E8>
+<BBDE> <679D>
+<BBDF> <6B62>
+<BBE0> <6B7B>
+<BBE1> <6C0F>
+<BBE2> <7345>
+<BBE3> <7949>
+<BBE4> <79C1>
+<BBE5> <7CF8>
+<BBE6> <7D19>
+<BBE7> <7D2B>
+<BBE8> <80A2>
+<BBE9> <8102>
+<BBEA> <81F3>
+<BBEB> <8996>
+<BBEC> <8A5E>
+<BBED> <8A69>
+<BBEE> <8A66>
+<BBEF> <8A8C>
+<BBF0> <8AEE>
+<BBF1> <8CC7>
+<BBF2> <8CDC>
+<BBF3> <96CC>
+<BBF4> <98FC>
+<BBF5> <6B6F>
+<BBF6> <4E8B>
+<BBF7> <4F3C>
+<BBF8> <4F8D>
+<BBF9> <5150>
+<BBFA> <5B57>
+<BBFB> <5BFA>
+<BBFC> <6148>
+endbfchar
+
+100 beginbfchar
+<BBFD> <6301>
+<BBFE> <6642>
+<BCA1> <6B21>
+<BCA2> <6ECB>
+<BCA3> <6CBB>
+<BCA4> <723E>
+<BCA5> <74BD>
+<BCA6> <75D4>
+<BCA7> <78C1>
+<BCA8> <793A>
+<BCA9> <800C>
+<BCAA> <8033>
+<BCAB> <81EA>
+<BCAC> <8494>
+<BCAD> <8F9E>
+<BCAE> <6C50>
+<BCAF> <9E7F>
+<BCB0> <5F0F>
+<BCB1> <8B58>
+<BCB2> <9D2B>
+<BCB3> <7AFA>
+<BCB4> <8EF8>
+<BCB5> <5B8D>
+<BCB6> <96EB>
+<BCB7> <4E03>
+<BCB8> <53F1>
+<BCB9> <57F7>
+<BCBA> <5931>
+<BCBB> <5AC9>
+<BCBC> <5BA4>
+<BCBD> <6089>
+<BCBE> <6E7F>
+<BCBF> <6F06>
+<BCC0> <75BE>
+<BCC1> <8CEA>
+<BCC2> <5B9F>
+<BCC3> <8500>
+<BCC4> <7BE0>
+<BCC5> <5072>
+<BCC6> <67F4>
+<BCC7> <829D>
+<BCC8> <5C61>
+<BCC9> <854A>
+<BCCA> <7E1E>
+<BCCB> <820E>
+<BCCC> <5199>
+<BCCD> <5C04>
+<BCCE> <6368>
+<BCCF> <8D66>
+<BCD0> <659C>
+<BCD1> <716E>
+<BCD2> <793E>
+<BCD3> <7D17>
+<BCD4> <8005>
+<BCD5> <8B1D>
+<BCD6> <8ECA>
+<BCD7> <906E>
+<BCD8> <86C7>
+<BCD9> <90AA>
+<BCDA> <501F>
+<BCDB> <52FA>
+<BCDC> <5C3A>
+<BCDD> <6753>
+<BCDE> <707C>
+<BCDF> <7235>
+<BCE0> <914C>
+<BCE1> <91C8>
+<BCE2> <932B>
+<BCE3> <82E5>
+<BCE4> <5BC2>
+<BCE5> <5F31>
+<BCE6> <60F9>
+<BCE7> <4E3B>
+<BCE8> <53D6>
+<BCE9> <5B88>
+<BCEA> <624B>
+<BCEB> <6731>
+<BCEC> <6B8A>
+<BCED> <72E9>
+<BCEE> <73E0>
+<BCEF> <7A2E>
+<BCF0> <816B>
+<BCF1> <8DA3>
+<BCF2> <9152>
+<BCF3> <9996>
+<BCF4> <5112>
+<BCF5> <53D7>
+<BCF6> <546A>
+<BCF7> <5BFF>
+<BCF8> <6388>
+<BCF9> <6A39>
+<BCFA> <7DAC>
+<BCFB> <9700>
+<BCFC> <56DA>
+<BCFD> <53CE>
+<BCFE> <5468>
+<BDA1> <5B97>
+<BDA2> <5C31>
+<BDA3> <5DDE>
+<BDA4> <4FEE>
+endbfchar
+
+100 beginbfchar
+<BDA5> <6101>
+<BDA6> <62FE>
+<BDA7> <6D32>
+<BDA8> <79C0>
+<BDA9> <79CB>
+<BDAA> <7D42>
+<BDAB> <7E4D>
+<BDAC> <7FD2>
+<BDAD> <81ED>
+<BDAE> <821F>
+<BDAF> <8490>
+<BDB0> <8846>
+<BDB1> <8972>
+<BDB2> <8B90>
+<BDB3> <8E74>
+<BDB4> <8F2F>
+<BDB5> <9031>
+<BDB6> <914B>
+<BDB7> <916C>
+<BDB8> <96C6>
+<BDB9> <919C>
+<BDBA> <4EC0>
+<BDBB> <4F4F>
+<BDBC> <5145>
+<BDBD> <5341>
+<BDBE> <5F93>
+<BDBF> <620E>
+<BDC0> <67D4>
+<BDC1> <6C41>
+<BDC2> <6E0B>
+<BDC3> <7363>
+<BDC4> <7E26>
+<BDC5> <91CD>
+<BDC6> <9283>
+<BDC7> <53D4>
+<BDC8> <5919>
+<BDC9> <5BBF>
+<BDCA> <6DD1>
+<BDCB> <795D>
+<BDCC> <7E2E>
+<BDCD> <7C9B>
+<BDCE> <587E>
+<BDCF> <719F>
+<BDD0> <51FA>
+<BDD1> <8853>
+<BDD2> <8FF0>
+<BDD3> <4FCA>
+<BDD4> <5CFB>
+<BDD5> <6625>
+<BDD6> <77AC>
+<BDD7> <7AE3>
+<BDD8> <821C>
+<BDD9> <99FF>
+<BDDA> <51C6>
+<BDDB> <5FAA>
+<BDDC> <65EC>
+<BDDD> <696F>
+<BDDE> <6B89>
+<BDDF> <6DF3>
+<BDE0> <6E96>
+<BDE1> <6F64>
+<BDE2> <76FE>
+<BDE3> <7D14>
+<BDE4> <5DE1>
+<BDE5> <9075>
+<BDE6> <9187>
+<BDE7> <9806>
+<BDE8> <51E6>
+<BDE9> <521D>
+<BDEA> <6240>
+<BDEB> <6691>
+<BDEC> <66D9>
+<BDED> <6E1A>
+<BDEE> <5EB6>
+<BDEF> <7DD2>
+<BDF0> <7F72>
+<BDF1> <66F8>
+<BDF2> <85AF>
+<BDF3> <85F7>
+<BDF4> <8AF8>
+<BDF5> <52A9>
+<BDF6> <53D9>
+<BDF7> <5973>
+<BDF8> <5E8F>
+<BDF9> <5F90>
+<BDFA> <6055>
+<BDFB> <92E4>
+<BDFC> <9664>
+<BDFD> <50B7>
+<BDFE> <511F>
+<BEA1> <52DD>
+<BEA2> <5320>
+<BEA3> <5347>
+<BEA4> <53EC>
+<BEA5> <54E8>
+<BEA6> <5546>
+<BEA7> <5531>
+<BEA8> <5617>
+<BEA9> <5968>
+<BEAA> <59BE>
+endbfchar
+
+100 beginbfchar
+<BEAB> <5A3C>
+<BEAC> <5BB5>
+<BEAD> <5C06>
+<BEAE> <5C0F>
+<BEAF> <5C11>
+<BEB0> <5C1A>
+<BEB1> <5E84>
+<BEB2> <5E8A>
+<BEB3> <5EE0>
+<BEB4> <5F70>
+<BEB5> <627F>
+<BEB6> <6284>
+<BEB7> <62DB>
+<BEB8> <638C>
+<BEB9> <6377>
+<BEBA> <6607>
+<BEBB> <660C>
+<BEBC> <662D>
+<BEBD> <6676>
+<BEBE> <677E>
+<BEBF> <68A2>
+<BEC0> <6A1F>
+<BEC1> <6A35>
+<BEC2> <6CBC>
+<BEC3> <6D88>
+<BEC4> <6E09>
+<BEC5> <6E58>
+<BEC6> <713C>
+<BEC7> <7126>
+<BEC8> <7167>
+<BEC9> <75C7>
+<BECA> <7701>
+<BECB> <785D>
+<BECC> <7901>
+<BECD> <7965>
+<BECE> <79F0>
+<BECF> <7AE0>
+<BED0> <7B11>
+<BED1> <7CA7>
+<BED2> <7D39>
+<BED3> <8096>
+<BED4> <83D6>
+<BED5> <848B>
+<BED6> <8549>
+<BED7> <885D>
+<BED8> <88F3>
+<BED9> <8A1F>
+<BEDA> <8A3C>
+<BEDB> <8A54>
+<BEDC> <8A73>
+<BEDD> <8C61>
+<BEDE> <8CDE>
+<BEDF> <91A4>
+<BEE0> <9266>
+<BEE1> <937E>
+<BEE2> <9418>
+<BEE3> <969C>
+<BEE4> <9798>
+<BEE5> <4E0A>
+<BEE6> <4E08>
+<BEE7> <4E1E>
+<BEE8> <4E57>
+<BEE9> <5197>
+<BEEA> <5270>
+<BEEB> <57CE>
+<BEEC> <5834>
+<BEED> <58CC>
+<BEEE> <5B22>
+<BEEF> <5E38>
+<BEF0> <60C5>
+<BEF1> <64FE>
+<BEF2> <6761>
+<BEF3> <6756>
+<BEF4> <6D44>
+<BEF5> <72B6>
+<BEF6> <7573>
+<BEF7> <7A63>
+<BEF8> <84B8>
+<BEF9> <8B72>
+<BEFA> <91B8>
+<BEFB> <9320>
+<BEFC> <5631>
+<BEFD> <57F4>
+<BEFE> <98FE>
+<BFA1> <62ED>
+<BFA2> <690D>
+<BFA3> <6B96>
+<BFA4> <71ED>
+<BFA5> <7E54>
+<BFA6> <8077>
+<BFA7> <8272>
+<BFA8> <89E6>
+<BFA9> <98DF>
+<BFAA> <8755>
+<BFAB> <8FB1>
+<BFAC> <5C3B>
+<BFAD> <4F38>
+<BFAE> <4FE1>
+<BFAF> <4FB5>
+<BFB0> <5507>
+endbfchar
+
+100 beginbfchar
+<BFB1> <5A20>
+<BFB2> <5BDD>
+<BFB3> <5BE9>
+<BFB4> <5FC3>
+<BFB5> <614E>
+<BFB6> <632F>
+<BFB7> <65B0>
+<BFB8> <664B>
+<BFB9> <68EE>
+<BFBA> <699B>
+<BFBB> <6D78>
+<BFBC> <6DF1>
+<BFBD> <7533>
+<BFBE> <75B9>
+<BFBF> <771F>
+<BFC0> <795E>
+<BFC1> <79E6>
+<BFC2> <7D33>
+<BFC3> <81E3>
+<BFC4> <82AF>
+<BFC5> <85AA>
+<BFC6> <89AA>
+<BFC7> <8A3A>
+<BFC8> <8EAB>
+<BFC9> <8F9B>
+<BFCA> <9032>
+<BFCB> <91DD>
+<BFCC> <9707>
+<BFCD> <4EBA>
+<BFCE> <4EC1>
+<BFCF> <5203>
+<BFD0> <5875>
+<BFD1> <58EC>
+<BFD2> <5C0B>
+<BFD3> <751A>
+<BFD4> <5C3D>
+<BFD5> <814E>
+<BFD6> <8A0A>
+<BFD7> <8FC5>
+<BFD8> <9663>
+<BFD9> <976D>
+<BFDA> <7B25>
+<BFDB> <8ACF>
+<BFDC> <9808>
+<BFDD> <9162>
+<BFDE> <56F3>
+<BFDF> <53A8>
+<BFE0> <9017>
+<BFE1> <5439>
+<BFE2> <5782>
+<BFE3> <5E25>
+<BFE4> <63A8>
+<BFE5> <6C34>
+<BFE6> <708A>
+<BFE7> <7761>
+<BFE8> <7C8B>
+<BFE9> <7FE0>
+<BFEA> <8870>
+<BFEB> <9042>
+<BFEC> <9154>
+<BFED> <9310>
+<BFEE> <9318>
+<BFEF> <968F>
+<BFF0> <745E>
+<BFF1> <9AC4>
+<BFF2> <5D07>
+<BFF3> <5D69>
+<BFF4> <6570>
+<BFF5> <67A2>
+<BFF6> <8DA8>
+<BFF7> <96DB>
+<BFF8> <636E>
+<BFF9> <6749>
+<BFFA> <6919>
+<BFFB> <83C5>
+<BFFC> <9817>
+<BFFD> <96C0>
+<BFFE> <88FE>
+<C0A1> <6F84>
+<C0A2> <647A>
+<C0A3> <5BF8>
+<C0A4> <4E16>
+<C0A5> <702C>
+<C0A6> <755D>
+<C0A7> <662F>
+<C0A8> <51C4>
+<C0A9> <5236>
+<C0AA> <52E2>
+<C0AB> <59D3>
+<C0AC> <5F81>
+<C0AD> <6027>
+<C0AE> <6210>
+<C0AF> <653F>
+<C0B0> <6574>
+<C0B1> <661F>
+<C0B2> <6674>
+<C0B3> <68F2>
+<C0B4> <6816>
+<C0B5> <6B63>
+<C0B6> <6E05>
+endbfchar
+
+100 beginbfchar
+<C0B7> <7272>
+<C0B8> <751F>
+<C0B9> <76DB>
+<C0BA> <7CBE>
+<C0BB> <8056>
+<C0BC> <58F0>
+<C0BD> <88FD>
+<C0BE> <897F>
+<C0BF> <8AA0>
+<C0C0> <8A93>
+<C0C1> <8ACB>
+<C0C2> <901D>
+<C0C3> <9192>
+<C0C4> <9752>
+<C0C5> <9759>
+<C0C6> <6589>
+<C0C7> <7A0E>
+<C0C8> <8106>
+<C0C9> <96BB>
+<C0CA> <5E2D>
+<C0CB> <60DC>
+<C0CC> <621A>
+<C0CD> <65A5>
+<C0CE> <6614>
+<C0CF> <6790>
+<C0D0> <77F3>
+<C0D1> <7A4D>
+<C0D2> <7C4D>
+<C0D3> <7E3E>
+<C0D4> <810A>
+<C0D5> <8CAC>
+<C0D6> <8D64>
+<C0D7> <8DE1>
+<C0D8> <8E5F>
+<C0D9> <78A9>
+<C0DA> <5207>
+<C0DB> <62D9>
+<C0DC> <63A5>
+<C0DD> <6442>
+<C0DE> <6298>
+<C0DF> <8A2D>
+<C0E0> <7A83>
+<C0E1> <7BC0>
+<C0E2> <8AAC>
+<C0E3> <96EA>
+<C0E4> <7D76>
+<C0E5> <820C>
+<C0E6> <8749>
+<C0E7> <4ED9>
+<C0E8> <5148>
+<C0E9> <5343>
+<C0EA> <5360>
+<C0EB> <5BA3>
+<C0EC> <5C02>
+<C0ED> <5C16>
+<C0EE> <5DDD>
+<C0EF> <6226>
+<C0F0> <6247>
+<C0F1> <64B0>
+<C0F2> <6813>
+<C0F3> <6834>
+<C0F4> <6CC9>
+<C0F5> <6D45>
+<C0F6> <6D17>
+<C0F7> <67D3>
+<C0F8> <6F5C>
+<C0F9> <714E>
+<C0FA> <717D>
+<C0FB> <65CB>
+<C0FC> <7A7F>
+<C0FD> <7BAD>
+<C0FE> <7DDA>
+<C1A1> <7E4A>
+<C1A2> <7FA8>
+<C1A3> <817A>
+<C1A4> <821B>
+<C1A5> <8239>
+<C1A6> <85A6>
+<C1A7> <8A6E>
+<C1A8> <8CCE>
+<C1A9> <8DF5>
+<C1AA> <9078>
+<C1AB> <9077>
+<C1AC> <92AD>
+<C1AD> <9291>
+<C1AE> <9583>
+<C1AF> <9BAE>
+<C1B0> <524D>
+<C1B1> <5584>
+<C1B2> <6F38>
+<C1B3> <7136>
+<C1B4> <5168>
+<C1B5> <7985>
+<C1B6> <7E55>
+<C1B7> <81B3>
+<C1B8> <7CCE>
+<C1B9> <564C>
+<C1BA> <5851>
+<C1BB> <5CA8>
+<C1BC> <63AA>
+endbfchar
+
+100 beginbfchar
+<C1BD> <66FE>
+<C1BE> <66FD>
+<C1BF> <695A>
+<C1C0> <72D9>
+<C1C1> <758F>
+<C1C2> <758E>
+<C1C3> <790E>
+<C1C4> <7956>
+<C1C5> <79DF>
+<C1C6> <7C97>
+<C1C7> <7D20>
+<C1C8> <7D44>
+<C1C9> <8607>
+<C1CA> <8A34>
+<C1CB> <963B>
+<C1CC> <9061>
+<C1CD> <9F20>
+<C1CE> <50E7>
+<C1CF> <5275>
+<C1D0> <53CC>
+<C1D1> <53E2>
+<C1D2> <5009>
+<C1D3> <55AA>
+<C1D4> <58EE>
+<C1D5> <594F>
+<C1D6> <723D>
+<C1D7> <5B8B>
+<C1D8> <5C64>
+<C1D9> <531D>
+<C1DA> <60E3>
+<C1DB> <60F3>
+<C1DC> <635C>
+<C1DD> <6383>
+<C1DE> <633F>
+<C1DF> <63BB>
+<C1E0> <64CD>
+<C1E1> <65E9>
+<C1E2> <66F9>
+<C1E3> <5DE3>
+<C1E4> <69CD>
+<C1E5> <69FD>
+<C1E6> <6F15>
+<C1E7> <71E5>
+<C1E8> <4E89>
+<C1E9> <75E9>
+<C1EA> <76F8>
+<C1EB> <7A93>
+<C1EC> <7CDF>
+<C1ED> <7DCF>
+<C1EE> <7D9C>
+<C1EF> <8061>
+<C1F0> <8349>
+<C1F1> <8358>
+<C1F2> <846C>
+<C1F3> <84BC>
+<C1F4> <85FB>
+<C1F5> <88C5>
+<C1F6> <8D70>
+<C1F7> <9001>
+<C1F8> <906D>
+<C1F9> <9397>
+<C1FA> <971C>
+<C1FB> <9A12>
+<C1FC> <50CF>
+<C1FD> <5897>
+<C1FE> <618E>
+<C2A1> <81D3>
+<C2A2> <8535>
+<C2A3> <8D08>
+<C2A4> <9020>
+<C2A5> <4FC3>
+<C2A6> <5074>
+<C2A7> <5247>
+<C2A8> <5373>
+<C2A9> <606F>
+<C2AA> <6349>
+<C2AB> <675F>
+<C2AC> <6E2C>
+<C2AD> <8DB3>
+<C2AE> <901F>
+<C2AF> <4FD7>
+<C2B0> <5C5E>
+<C2B1> <8CCA>
+<C2B2> <65CF>
+<C2B3> <7D9A>
+<C2B4> <5352>
+<C2B5> <8896>
+<C2B6> <5176>
+<C2B7> <63C3>
+<C2B8> <5B58>
+<C2B9> <5B6B>
+<C2BA> <5C0A>
+<C2BB> <640D>
+<C2BC> <6751>
+<C2BD> <905C>
+<C2BE> <4ED6>
+<C2BF> <591A>
+<C2C0> <592A>
+<C2C1> <6C70>
+<C2C2> <8A51>
+endbfchar
+
+100 beginbfchar
+<C2C3> <553E>
+<C2C4> <5815>
+<C2C5> <59A5>
+<C2C6> <60F0>
+<C2C7> <6253>
+<C2C8> <67C1>
+<C2C9> <8235>
+<C2CA> <6955>
+<C2CB> <9640>
+<C2CC> <99C4>
+<C2CD> <9A28>
+<C2CE> <4F53>
+<C2CF> <5806>
+<C2D0> <5BFE>
+<C2D1> <8010>
+<C2D2> <5CB1>
+<C2D3> <5E2F>
+<C2D4> <5F85>
+<C2D5> <6020>
+<C2D6> <614B>
+<C2D7> <6234>
+<C2D8> <66FF>
+<C2D9> <6CF0>
+<C2DA> <6EDE>
+<C2DB> <80CE>
+<C2DC> <817F>
+<C2DD> <82D4>
+<C2DE> <888B>
+<C2DF> <8CB8>
+<C2E0> <9000>
+<C2E1> <902E>
+<C2E2> <968A>
+<C2E3> <9EDB>
+<C2E4> <9BDB>
+<C2E5> <4EE3>
+<C2E6> <53F0>
+<C2E7> <5927>
+<C2E8> <7B2C>
+<C2E9> <918D>
+<C2EA> <984C>
+<C2EB> <9DF9>
+<C2EC> <6EDD>
+<C2ED> <7027>
+<C2EE> <5353>
+<C2EF> <5544>
+<C2F0> <5B85>
+<C2F1> <6258>
+<C2F2> <629E>
+<C2F3> <62D3>
+<C2F4> <6CA2>
+<C2F5> <6FEF>
+<C2F6> <7422>
+<C2F7> <8A17>
+<C2F8> <9438>
+<C2F9> <6FC1>
+<C2FA> <8AFE>
+<C2FB> <8338>
+<C2FC> <51E7>
+<C2FD> <86F8>
+<C2FE> <53EA>
+<C3A1> <53E9>
+<C3A2> <4F46>
+<C3A3> <9054>
+<C3A4> <8FB0>
+<C3A5> <596A>
+<C3A6> <8131>
+<C3A7> <5DFD>
+<C3A8> <7AEA>
+<C3A9> <8FBF>
+<C3AA> <68DA>
+<C3AB> <8C37>
+<C3AC> <72F8>
+<C3AD> <9C48>
+<C3AE> <6A3D>
+<C3AF> <8AB0>
+<C3B0> <4E39>
+<C3B1> <5358>
+<C3B2> <5606>
+<C3B3> <5766>
+<C3B4> <62C5>
+<C3B5> <63A2>
+<C3B6> <65E6>
+<C3B7> <6B4E>
+<C3B8> <6DE1>
+<C3B9> <6E5B>
+<C3BA> <70AD>
+<C3BB> <77ED>
+<C3BC> <7AEF>
+<C3BD> <7BAA>
+<C3BE> <7DBB>
+<C3BF> <803D>
+<C3C0> <80C6>
+<C3C1> <86CB>
+<C3C2> <8A95>
+<C3C3> <935B>
+<C3C4> <56E3>
+<C3C5> <58C7>
+<C3C6> <5F3E>
+<C3C7> <65AD>
+<C3C8> <6696>
+endbfchar
+
+100 beginbfchar
+<C3C9> <6A80>
+<C3CA> <6BB5>
+<C3CB> <7537>
+<C3CC> <8AC7>
+<C3CD> <5024>
+<C3CE> <77E5>
+<C3CF> <5730>
+<C3D0> <5F1B>
+<C3D1> <6065>
+<C3D2> <667A>
+<C3D3> <6C60>
+<C3D4> <75F4>
+<C3D5> <7A1A>
+<C3D6> <7F6E>
+<C3D7> <81F4>
+<C3D8> <8718>
+<C3D9> <9045>
+<C3DA> <99B3>
+<C3DB> <7BC9>
+<C3DC> <755C>
+<C3DD> <7AF9>
+<C3DE> <7B51>
+<C3DF> <84C4>
+<C3E0> <9010>
+<C3E1> <79E9>
+<C3E2> <7A92>
+<C3E3> <8336>
+<C3E4> <5AE1>
+<C3E5> <7740>
+<C3E6> <4E2D>
+<C3E7> <4EF2>
+<C3E8> <5B99>
+<C3E9> <5FE0>
+<C3EA> <62BD>
+<C3EB> <663C>
+<C3EC> <67F1>
+<C3ED> <6CE8>
+<C3EE> <866B>
+<C3EF> <8877>
+<C3F0> <8A3B>
+<C3F1> <914E>
+<C3F2> <92F3>
+<C3F3> <99D0>
+<C3F4> <6A17>
+<C3F5> <7026>
+<C3F6> <732A>
+<C3F7> <82E7>
+<C3F8> <8457>
+<C3F9> <8CAF>
+<C3FA> <4E01>
+<C3FB> <5146>
+<C3FC> <51CB>
+<C3FD> <558B>
+<C3FE> <5BF5>
+<C4A1> <5E16>
+<C4A2> <5E33>
+<C4A3> <5E81>
+<C4A4> <5F14>
+<C4A5> <5F35>
+<C4A6> <5F6B>
+<C4A7> <5FB4>
+<C4A8> <61F2>
+<C4A9> <6311>
+<C4AA> <66A2>
+<C4AB> <671D>
+<C4AC> <6F6E>
+<C4AD> <7252>
+<C4AE> <753A>
+<C4AF> <773A>
+<C4B0> <8074>
+<C4B1> <8139>
+<C4B2> <8178>
+<C4B3> <8776>
+<C4B4> <8ABF>
+<C4B5> <8ADC>
+<C4B6> <8D85>
+<C4B7> <8DF3>
+<C4B8> <929A>
+<C4B9> <9577>
+<C4BA> <9802>
+<C4BB> <9CE5>
+<C4BC> <52C5>
+<C4BD> <6357>
+<C4BE> <76F4>
+<C4BF> <6715>
+<C4C0> <6C88>
+<C4C1> <73CD>
+<C4C2> <8CC3>
+<C4C3> <93AE>
+<C4C4> <9673>
+<C4C5> <6D25>
+<C4C6> <589C>
+<C4C7> <690E>
+<C4C8> <69CC>
+<C4C9> <8FFD>
+<C4CA> <939A>
+<C4CB> <75DB>
+<C4CC> <901A>
+<C4CD> <585A>
+<C4CE> <6802>
+endbfchar
+
+100 beginbfchar
+<C4CF> <63B4>
+<C4D0> <69FB>
+<C4D1> <4F43>
+<C4D2> <6F2C>
+<C4D3> <67D8>
+<C4D4> <8FBB>
+<C4D5> <8526>
+<C4D6> <7DB4>
+<C4D7> <9354>
+<C4D8> <693F>
+<C4D9> <6F70>
+<C4DA> <576A>
+<C4DB> <58F7>
+<C4DC> <5B2C>
+<C4DD> <7D2C>
+<C4DE> <722A>
+<C4DF> <540A>
+<C4E0> <91E3>
+<C4E1> <9DB4>
+<C4E2> <4EAD>
+<C4E3> <4F4E>
+<C4E4> <505C>
+<C4E5> <5075>
+<C4E6> <5243>
+<C4E7> <8C9E>
+<C4E8> <5448>
+<C4E9> <5824>
+<C4EA> <5B9A>
+<C4EB> <5E1D>
+<C4EC> <5E95>
+<C4ED> <5EAD>
+<C4EE> <5EF7>
+<C4EF> <5F1F>
+<C4F0> <608C>
+<C4F1> <62B5>
+<C4F2> <633A>
+<C4F3> <63D0>
+<C4F4> <68AF>
+<C4F5> <6C40>
+<C4F6> <7887>
+<C4F7> <798E>
+<C4F8> <7A0B>
+<C4F9> <7DE0>
+<C4FA> <8247>
+<C4FB> <8A02>
+<C4FC> <8AE6>
+<C4FD> <8E44>
+<C4FE> <9013>
+<C5A1> <90B8>
+<C5A2> <912D>
+<C5A3> <91D8>
+<C5A4> <9F0E>
+<C5A5> <6CE5>
+<C5A6> <6458>
+<C5A7> <64E2>
+<C5A8> <6575>
+<C5A9> <6EF4>
+<C5AA> <7684>
+<C5AB> <7B1B>
+<C5AC> <9069>
+<C5AD> <93D1>
+<C5AE> <6EBA>
+<C5AF> <54F2>
+<C5B0> <5FB9>
+<C5B1> <64A4>
+<C5B2> <8F4D>
+<C5B3> <8FED>
+<C5B4> <9244>
+<C5B5> <5178>
+<C5B6> <586B>
+<C5B7> <5929>
+<C5B8> <5C55>
+<C5B9> <5E97>
+<C5BA> <6DFB>
+<C5BB> <7E8F>
+<C5BC> <751C>
+<C5BD> <8CBC>
+<C5BE> <8EE2>
+<C5BF> <985B>
+<C5C0> <70B9>
+<C5C1> <4F1D>
+<C5C2> <6BBF>
+<C5C3> <6FB1>
+<C5C4> <7530>
+<C5C5> <96FB>
+<C5C6> <514E>
+<C5C7> <5410>
+<C5C8> <5835>
+<C5C9> <5857>
+<C5CA> <59AC>
+<C5CB> <5C60>
+<C5CC> <5F92>
+<C5CD> <6597>
+<C5CE> <675C>
+<C5CF> <6E21>
+<C5D0> <767B>
+<C5D1> <83DF>
+<C5D2> <8CED>
+<C5D3> <9014>
+<C5D4> <90FD>
+endbfchar
+
+100 beginbfchar
+<C5D5> <934D>
+<C5D6> <7825>
+<C5D7> <783A>
+<C5D8> <52AA>
+<C5D9> <5EA6>
+<C5DA> <571F>
+<C5DB> <5974>
+<C5DC> <6012>
+<C5DD> <5012>
+<C5DE> <515A>
+<C5DF> <51AC>
+<C5E0> <51CD>
+<C5E1> <5200>
+<C5E2> <5510>
+<C5E3> <5854>
+<C5E4> <5858>
+<C5E5> <5957>
+<C5E6> <5B95>
+<C5E7> <5CF6>
+<C5E8> <5D8B>
+<C5E9> <60BC>
+<C5EA> <6295>
+<C5EB> <642D>
+<C5EC> <6771>
+<C5ED> <6843>
+<C5EE> <68BC>
+<C5EF> <68DF>
+<C5F0> <76D7>
+<C5F1> <6DD8>
+<C5F2> <6E6F>
+<C5F3> <6D9B>
+<C5F4> <706F>
+<C5F5> <71C8>
+<C5F6> <5F53>
+<C5F7> <75D8>
+<C5F8> <7977>
+<C5F9> <7B49>
+<C5FA> <7B54>
+<C5FB> <7B52>
+<C5FC> <7CD6>
+<C5FD> <7D71>
+<C5FE> <5230>
+<C6A1> <8463>
+<C6A2> <8569>
+<C6A3> <85E4>
+<C6A4> <8A0E>
+<C6A5> <8B04>
+<C6A6> <8C46>
+<C6A7> <8E0F>
+<C6A8> <9003>
+<C6A9> <900F>
+<C6AA> <9419>
+<C6AB> <9676>
+<C6AC> <982D>
+<C6AD> <9A30>
+<C6AE> <95D8>
+<C6AF> <50CD>
+<C6B0> <52D5>
+<C6B1> <540C>
+<C6B2> <5802>
+<C6B3> <5C0E>
+<C6B4> <61A7>
+<C6B5> <649E>
+<C6B6> <6D1E>
+<C6B7> <77B3>
+<C6B8> <7AE5>
+<C6B9> <80F4>
+<C6BA> <8404>
+<C6BB> <9053>
+<C6BC> <9285>
+<C6BD> <5CE0>
+<C6BE> <9D07>
+<C6BF> <533F>
+<C6C0> <5F97>
+<C6C1> <5FB3>
+<C6C2> <6D9C>
+<C6C3> <7279>
+<C6C4> <7763>
+<C6C5> <79BF>
+<C6C6> <7BE4>
+<C6C7> <6BD2>
+<C6C8> <72EC>
+<C6C9> <8AAD>
+<C6CA> <6803>
+<C6CB> <6A61>
+<C6CC> <51F8>
+<C6CD> <7A81>
+<C6CE> <6934>
+<C6CF> <5C4A>
+<C6D0> <9CF6>
+<C6D1> <82EB>
+<C6D2> <5BC5>
+<C6D3> <9149>
+<C6D4> <701E>
+<C6D5> <5678>
+<C6D6> <5C6F>
+<C6D7> <60C7>
+<C6D8> <6566>
+<C6D9> <6C8C>
+<C6DA> <8C5A>
+endbfchar
+
+100 beginbfchar
+<C6DB> <9041>
+<C6DC> <9813>
+<C6DD> <5451>
+<C6DE> <66C7>
+<C6DF> <920D>
+<C6E0> <5948>
+<C6E1> <90A3>
+<C6E2> <5185>
+<C6E3> <4E4D>
+<C6E4> <51EA>
+<C6E5> <8599>
+<C6E6> <8B0E>
+<C6E7> <7058>
+<C6E8> <637A>
+<C6E9> <934B>
+<C6EA> <6962>
+<C6EB> <99B4>
+<C6EC> <7E04>
+<C6ED> <7577>
+<C6EE> <5357>
+<C6EF> <6960>
+<C6F0> <8EDF>
+<C6F1> <96E3>
+<C6F2> <6C5D>
+<C6F3> <4E8C>
+<C6F4> <5C3C>
+<C6F5> <5F10>
+<C6F6> <8FE9>
+<C6F7> <5302>
+<C6F8> <8CD1>
+<C6F9> <8089>
+<C6FA> <8679>
+<C6FB> <5EFF>
+<C6FC> <65E5>
+<C6FD> <4E73>
+<C6FE> <5165>
+<C7A1> <5982>
+<C7A2> <5C3F>
+<C7A3> <97EE>
+<C7A4> <4EFB>
+<C7A5> <598A>
+<C7A6> <5FCD>
+<C7A7> <8A8D>
+<C7A8> <6FE1>
+<C7A9> <79B0>
+<C7AA> <7962>
+<C7AB> <5BE7>
+<C7AC> <8471>
+<C7AD> <732B>
+<C7AE> <71B1>
+<C7AF> <5E74>
+<C7B0> <5FF5>
+<C7B1> <637B>
+<C7B2> <649A>
+<C7B3> <71C3>
+<C7B4> <7C98>
+<C7B5> <4E43>
+<C7B6> <5EFC>
+<C7B7> <4E4B>
+<C7B8> <57DC>
+<C7B9> <56A2>
+<C7BA> <60A9>
+<C7BB> <6FC3>
+<C7BC> <7D0D>
+<C7BD> <80FD>
+<C7BE> <8133>
+<C7BF> <81BF>
+<C7C0> <8FB2>
+<C7C1> <8997>
+<C7C2> <86A4>
+<C7C3> <5DF4>
+<C7C4> <628A>
+<C7C5> <64AD>
+<C7C6> <8987>
+<C7C7> <6777>
+<C7C8> <6CE2>
+<C7C9> <6D3E>
+<C7CA> <7436>
+<C7CB> <7834>
+<C7CC> <5A46>
+<C7CD> <7F75>
+<C7CE> <82AD>
+<C7CF> <99AC>
+<C7D0> <4FF3>
+<C7D1> <5EC3>
+<C7D2> <62DD>
+<C7D3> <6392>
+<C7D4> <6557>
+<C7D5> <676F>
+<C7D6> <76C3>
+<C7D7> <724C>
+<C7D8> <80CC>
+<C7D9> <80BA>
+<C7DA> <8F29>
+<C7DB> <914D>
+<C7DC> <500D>
+<C7DD> <57F9>
+<C7DE> <5A92>
+<C7DF> <6885>
+<C7E0> <6973>
+endbfchar
+
+100 beginbfchar
+<C7E1> <7164>
+<C7E2> <72FD>
+<C7E3> <8CB7>
+<C7E4> <58F2>
+<C7E5> <8CE0>
+<C7E6> <966A>
+<C7E7> <9019>
+<C7E8> <877F>
+<C7E9> <79E4>
+<C7EA> <77E7>
+<C7EB> <8429>
+<C7EC> <4F2F>
+<C7ED> <5265>
+<C7EE> <535A>
+<C7EF> <62CD>
+<C7F0> <67CF>
+<C7F1> <6CCA>
+<C7F2> <767D>
+<C7F3> <7B94>
+<C7F4> <7C95>
+<C7F5> <8236>
+<C7F6> <8584>
+<C7F7> <8FEB>
+<C7F8> <66DD>
+<C7F9> <6F20>
+<C7FA> <7206>
+<C7FB> <7E1B>
+<C7FC> <83AB>
+<C7FD> <99C1>
+<C7FE> <9EA6>
+<C8A1> <51FD>
+<C8A2> <7BB1>
+<C8A3> <7872>
+<C8A4> <7BB8>
+<C8A5> <8087>
+<C8A6> <7B48>
+<C8A7> <6AE8>
+<C8A8> <5E61>
+<C8A9> <808C>
+<C8AA> <7551>
+<C8AB> <7560>
+<C8AC> <516B>
+<C8AD> <9262>
+<C8AE> <6E8C>
+<C8AF> <767A>
+<C8B0> <9197>
+<C8B1> <9AEA>
+<C8B2> <4F10>
+<C8B3> <7F70>
+<C8B4> <629C>
+<C8B5> <7B4F>
+<C8B6> <95A5>
+<C8B7> <9CE9>
+<C8B8> <567A>
+<C8B9> <5859>
+<C8BA> <86E4>
+<C8BB> <96BC>
+<C8BC> <4F34>
+<C8BD> <5224>
+<C8BE> <534A>
+<C8BF> <53CD>
+<C8C0> <53DB>
+<C8C1> <5E06>
+<C8C2> <642C>
+<C8C3> <6591>
+<C8C4> <677F>
+<C8C5> <6C3E>
+<C8C6> <6C4E>
+<C8C7> <7248>
+<C8C8> <72AF>
+<C8C9> <73ED>
+<C8CA> <7554>
+<C8CB> <7E41>
+<C8CC> <822C>
+<C8CD> <85E9>
+<C8CE> <8CA9>
+<C8CF> <7BC4>
+<C8D0> <91C6>
+<C8D1> <7169>
+<C8D2> <9812>
+<C8D3> <98EF>
+<C8D4> <633D>
+<C8D5> <6669>
+<C8D6> <756A>
+<C8D7> <76E4>
+<C8D8> <78D0>
+<C8D9> <8543>
+<C8DA> <86EE>
+<C8DB> <532A>
+<C8DC> <5351>
+<C8DD> <5426>
+<C8DE> <5983>
+<C8DF> <5E87>
+<C8E0> <5F7C>
+<C8E1> <60B2>
+<C8E2> <6249>
+<C8E3> <6279>
+<C8E4> <62AB>
+<C8E5> <6590>
+<C8E6> <6BD4>
+endbfchar
+
+100 beginbfchar
+<C8E7> <6CCC>
+<C8E8> <75B2>
+<C8E9> <76AE>
+<C8EA> <7891>
+<C8EB> <79D8>
+<C8EC> <7DCB>
+<C8ED> <7F77>
+<C8EE> <80A5>
+<C8EF> <88AB>
+<C8F0> <8AB9>
+<C8F1> <8CBB>
+<C8F2> <907F>
+<C8F3> <975E>
+<C8F4> <98DB>
+<C8F5> <6A0B>
+<C8F6> <7C38>
+<C8F7> <5099>
+<C8F8> <5C3E>
+<C8F9> <5FAE>
+<C8FA> <6787>
+<C8FB> <6BD8>
+<C8FC> <7435>
+<C8FD> <7709>
+<C8FE> <7F8E>
+<C9A1> <9F3B>
+<C9A2> <67CA>
+<C9A3> <7A17>
+<C9A4> <5339>
+<C9A5> <758B>
+<C9A6> <9AED>
+<C9A7> <5F66>
+<C9A8> <819D>
+<C9A9> <83F1>
+<C9AA> <8098>
+<C9AB> <5F3C>
+<C9AC> <5FC5>
+<C9AD> <7562>
+<C9AE> <7B46>
+<C9AF> <903C>
+<C9B0> <6867>
+<C9B1> <59EB>
+<C9B2> <5A9B>
+<C9B3> <7D10>
+<C9B4> <767E>
+<C9B5> <8B2C>
+<C9B6> <4FF5>
+<C9B7> <5F6A>
+<C9B8> <6A19>
+<C9B9> <6C37>
+<C9BA> <6F02>
+<C9BB> <74E2>
+<C9BC> <7968>
+<C9BD> <8868>
+<C9BE> <8A55>
+<C9BF> <8C79>
+<C9C0> <5EDF>
+<C9C1> <63CF>
+<C9C2> <75C5>
+<C9C3> <79D2>
+<C9C4> <82D7>
+<C9C5> <9328>
+<C9C6> <92F2>
+<C9C7> <849C>
+<C9C8> <86ED>
+<C9C9> <9C2D>
+<C9CA> <54C1>
+<C9CB> <5F6C>
+<C9CC> <658C>
+<C9CD> <6D5C>
+<C9CE> <7015>
+<C9CF> <8CA7>
+<C9D0> <8CD3>
+<C9D1> <983B>
+<C9D2> <654F>
+<C9D3> <74F6>
+<C9D4> <4E0D>
+<C9D5> <4ED8>
+<C9D6> <57E0>
+<C9D7> <592B>
+<C9D8> <5A66>
+<C9D9> <5BCC>
+<C9DA> <51A8>
+<C9DB> <5E03>
+<C9DC> <5E9C>
+<C9DD> <6016>
+<C9DE> <6276>
+<C9DF> <6577>
+<C9E0> <65A7>
+<C9E1> <666E>
+<C9E2> <6D6E>
+<C9E3> <7236>
+<C9E4> <7B26>
+<C9E5> <8150>
+<C9E6> <819A>
+<C9E7> <8299>
+<C9E8> <8B5C>
+<C9E9> <8CA0>
+<C9EA> <8CE6>
+<C9EB> <8D74>
+<C9EC> <961C>
+endbfchar
+
+100 beginbfchar
+<C9ED> <9644>
+<C9EE> <4FAE>
+<C9EF> <64AB>
+<C9F0> <6B66>
+<C9F1> <821E>
+<C9F2> <8461>
+<C9F3> <856A>
+<C9F4> <90E8>
+<C9F5> <5C01>
+<C9F6> <6953>
+<C9F7> <98A8>
+<C9F8> <847A>
+<C9F9> <8557>
+<C9FA> <4F0F>
+<C9FB> <526F>
+<C9FC> <5FA9>
+<C9FD> <5E45>
+<C9FE> <670D>
+<CAA1> <798F>
+<CAA2> <8179>
+<CAA3> <8907>
+<CAA4> <8986>
+<CAA5> <6DF5>
+<CAA6> <5F17>
+<CAA7> <6255>
+<CAA8> <6CB8>
+<CAA9> <4ECF>
+<CAAA> <7269>
+<CAAB> <9B92>
+<CAAC> <5206>
+<CAAD> <543B>
+<CAAE> <5674>
+<CAAF> <58B3>
+<CAB0> <61A4>
+<CAB1> <626E>
+<CAB2> <711A>
+<CAB3> <596E>
+<CAB4> <7C89>
+<CAB5> <7CDE>
+<CAB6> <7D1B>
+<CAB7> <96F0>
+<CAB8> <6587>
+<CAB9> <805E>
+<CABA> <4E19>
+<CABB> <4F75>
+<CABC> <5175>
+<CABD> <5840>
+<CABE> <5E63>
+<CABF> <5E73>
+<CAC0> <5F0A>
+<CAC1> <67C4>
+<CAC2> <4E26>
+<CAC3> <853D>
+<CAC4> <9589>
+<CAC5> <965B>
+<CAC6> <7C73>
+<CAC7> <9801>
+<CAC8> <50FB>
+<CAC9> <58C1>
+<CACA> <7656>
+<CACB> <78A7>
+<CACC> <5225>
+<CACD> <77A5>
+<CACE> <8511>
+<CACF> <7B86>
+<CAD0> <504F>
+<CAD1> <5909>
+<CAD2> <7247>
+<CAD3> <7BC7>
+<CAD4> <7DE8>
+<CAD5> <8FBA>
+<CAD6> <8FD4>
+<CAD7> <904D>
+<CAD8> <4FBF>
+<CAD9> <52C9>
+<CADA> <5A29>
+<CADB> <5F01>
+<CADC> <97AD>
+<CADD> <4FDD>
+<CADE> <8217>
+<CADF> <92EA>
+<CAE0> <5703>
+<CAE1> <6355>
+<CAE2> <6B69>
+<CAE3> <752B>
+<CAE4> <88DC>
+<CAE5> <8F14>
+<CAE6> <7A42>
+<CAE7> <52DF>
+<CAE8> <5893>
+<CAE9> <6155>
+<CAEA> <620A>
+<CAEB> <66AE>
+<CAEC> <6BCD>
+<CAED> <7C3F>
+<CAEE> <83E9>
+<CAEF> <5023>
+<CAF0> <4FF8>
+<CAF1> <5305>
+<CAF2> <5446>
+endbfchar
+
+100 beginbfchar
+<CAF3> <5831>
+<CAF4> <5949>
+<CAF5> <5B9D>
+<CAF6> <5CF0>
+<CAF7> <5CEF>
+<CAF8> <5D29>
+<CAF9> <5E96>
+<CAFA> <62B1>
+<CAFB> <6367>
+<CAFC> <653E>
+<CAFD> <65B9>
+<CAFE> <670B>
+<CBA1> <6CD5>
+<CBA2> <6CE1>
+<CBA3> <70F9>
+<CBA4> <7832>
+<CBA5> <7E2B>
+<CBA6> <80DE>
+<CBA7> <82B3>
+<CBA8> <840C>
+<CBA9> <84EC>
+<CBAA> <8702>
+<CBAB> <8912>
+<CBAC> <8A2A>
+<CBAD> <8C4A>
+<CBAE> <90A6>
+<CBAF> <92D2>
+<CBB0> <98FD>
+<CBB1> <9CF3>
+<CBB2> <9D6C>
+<CBB3> <4E4F>
+<CBB4> <4EA1>
+<CBB5> <508D>
+<CBB6> <5256>
+<CBB7> <574A>
+<CBB8> <59A8>
+<CBB9> <5E3D>
+<CBBA> <5FD8>
+<CBBB> <5FD9>
+<CBBC> <623F>
+<CBBD> <66B4>
+<CBBE> <671B>
+<CBBF> <67D0>
+<CBC0> <68D2>
+<CBC1> <5192>
+<CBC2> <7D21>
+<CBC3> <80AA>
+<CBC4> <81A8>
+<CBC5> <8B00>
+<CBC6> <8C8C>
+<CBC7> <8CBF>
+<CBC8> <927E>
+<CBC9> <9632>
+<CBCA> <5420>
+<CBCB> <982C>
+<CBCC> <5317>
+<CBCD> <50D5>
+<CBCE> <535C>
+<CBCF> <58A8>
+<CBD0> <64B2>
+<CBD1> <6734>
+<CBD2> <7267>
+<CBD3> <7766>
+<CBD4> <7A46>
+<CBD5> <91E6>
+<CBD6> <52C3>
+<CBD7> <6CA1>
+<CBD8> <6B86>
+<CBD9> <5800>
+<CBDA> <5E4C>
+<CBDB> <5954>
+<CBDC> <672C>
+<CBDD> <7FFB>
+<CBDE> <51E1>
+<CBDF> <76C6>
+<CBE0> <6469>
+<CBE1> <78E8>
+<CBE2> <9B54>
+<CBE3> <9EBB>
+<CBE4> <57CB>
+<CBE5> <59B9>
+<CBE6> <6627>
+<CBE7> <679A>
+<CBE8> <6BCE>
+<CBE9> <54E9>
+<CBEA> <69D9>
+<CBEB> <5E55>
+<CBEC> <819C>
+<CBED> <6795>
+<CBEE> <9BAA>
+<CBEF> <67FE>
+<CBF0> <9C52>
+<CBF1> <685D>
+<CBF2> <4EA6>
+<CBF3> <4FE3>
+<CBF4> <53C8>
+<CBF5> <62B9>
+<CBF6> <672B>
+<CBF7> <6CAB>
+<CBF8> <8FC4>
+endbfchar
+
+100 beginbfchar
+<CBF9> <4FAD>
+<CBFA> <7E6D>
+<CBFB> <9EBF>
+<CBFC> <4E07>
+<CBFD> <6162>
+<CBFE> <6E80>
+<CCA1> <6F2B>
+<CCA2> <8513>
+<CCA3> <5473>
+<CCA4> <672A>
+<CCA5> <9B45>
+<CCA6> <5DF3>
+<CCA7> <7B95>
+<CCA8> <5CAC>
+<CCA9> <5BC6>
+<CCAA> <871C>
+<CCAB> <6E4A>
+<CCAC> <84D1>
+<CCAD> <7A14>
+<CCAE> <8108>
+<CCAF> <5999>
+<CCB0> <7C8D>
+<CCB1> <6C11>
+<CCB2> <7720>
+<CCB3> <52D9>
+<CCB4> <5922>
+<CCB5> <7121>
+<CCB6> <725F>
+<CCB7> <77DB>
+<CCB8> <9727>
+<CCB9> <9D61>
+<CCBA> <690B>
+<CCBB> <5A7F>
+<CCBC> <5A18>
+<CCBD> <51A5>
+<CCBE> <540D>
+<CCBF> <547D>
+<CCC0> <660E>
+<CCC1> <76DF>
+<CCC2> <8FF7>
+<CCC3> <9298>
+<CCC4> <9CF4>
+<CCC5> <59EA>
+<CCC6> <725D>
+<CCC7> <6EC5>
+<CCC8> <514D>
+<CCC9> <68C9>
+<CCCA> <7DBF>
+<CCCB> <7DEC>
+<CCCC> <9762>
+<CCCD> <9EBA>
+<CCCE> <6478>
+<CCCF> <6A21>
+<CCD0> <8302>
+<CCD1> <5984>
+<CCD2> <5B5F>
+<CCD3> <6BDB>
+<CCD4> <731B>
+<CCD5> <76F2>
+<CCD6> <7DB2>
+<CCD7> <8017>
+<CCD8> <8499>
+<CCD9> <5132>
+<CCDA> <6728>
+<CCDB> <9ED9>
+<CCDC> <76EE>
+<CCDD> <6762>
+<CCDE> <52FF>
+<CCDF> <9905>
+<CCE0> <5C24>
+<CCE1> <623B>
+<CCE2> <7C7E>
+<CCE3> <8CB0>
+<CCE4> <554F>
+<CCE5> <60B6>
+<CCE6> <7D0B>
+<CCE7> <9580>
+<CCE8> <5301>
+<CCE9> <4E5F>
+<CCEA> <51B6>
+<CCEB> <591C>
+<CCEC> <723A>
+<CCED> <8036>
+<CCEE> <91CE>
+<CCEF> <5F25>
+<CCF0> <77E2>
+<CCF1> <5384>
+<CCF2> <5F79>
+<CCF3> <7D04>
+<CCF4> <85AC>
+<CCF5> <8A33>
+<CCF6> <8E8D>
+<CCF7> <9756>
+<CCF8> <67F3>
+<CCF9> <85AE>
+<CCFA> <9453>
+<CCFB> <6109>
+<CCFC> <6108>
+<CCFD> <6CB9>
+<CCFE> <7652>
+endbfchar
+
+100 beginbfchar
+<CDA1> <8AED>
+<CDA2> <8F38>
+<CDA3> <552F>
+<CDA4> <4F51>
+<CDA5> <512A>
+<CDA6> <52C7>
+<CDA7> <53CB>
+<CDA8> <5BA5>
+<CDA9> <5E7D>
+<CDAA> <60A0>
+<CDAB> <6182>
+<CDAC> <63D6>
+<CDAD> <6709>
+<CDAE> <67DA>
+<CDAF> <6E67>
+<CDB0> <6D8C>
+<CDB1> <7336>
+<CDB2> <7337>
+<CDB3> <7531>
+<CDB4> <7950>
+<CDB5> <88D5>
+<CDB6> <8A98>
+<CDB7> <904A>
+<CDB8> <9091>
+<CDB9> <90F5>
+<CDBA> <96C4>
+<CDBB> <878D>
+<CDBC> <5915>
+<CDBD> <4E88>
+<CDBE> <4F59>
+<CDBF> <4E0E>
+<CDC0> <8A89>
+<CDC1> <8F3F>
+<CDC2> <9810>
+<CDC3> <50AD>
+<CDC4> <5E7C>
+<CDC5> <5996>
+<CDC6> <5BB9>
+<CDC7> <5EB8>
+<CDC8> <63DA>
+<CDC9> <63FA>
+<CDCA> <64C1>
+<CDCB> <66DC>
+<CDCC> <694A>
+<CDCD> <69D8>
+<CDCE> <6D0B>
+<CDCF> <6EB6>
+<CDD0> <7194>
+<CDD1> <7528>
+<CDD2> <7AAF>
+<CDD3> <7F8A>
+<CDD4> <8000>
+<CDD5> <8449>
+<CDD6> <84C9>
+<CDD7> <8981>
+<CDD8> <8B21>
+<CDD9> <8E0A>
+<CDDA> <9065>
+<CDDB> <967D>
+<CDDC> <990A>
+<CDDD> <617E>
+<CDDE> <6291>
+<CDDF> <6B32>
+<CDE0> <6C83>
+<CDE1> <6D74>
+<CDE2> <7FCC>
+<CDE3> <7FFC>
+<CDE4> <6DC0>
+<CDE5> <7F85>
+<CDE6> <87BA>
+<CDE7> <88F8>
+<CDE8> <6765>
+<CDE9> <83B1>
+<CDEA> <983C>
+<CDEB> <96F7>
+<CDEC> <6D1B>
+<CDED> <7D61>
+<CDEE> <843D>
+<CDEF> <916A>
+<CDF0> <4E71>
+<CDF1> <5375>
+<CDF2> <5D50>
+<CDF3> <6B04>
+<CDF4> <6FEB>
+<CDF5> <85CD>
+<CDF6> <862D>
+<CDF7> <89A7>
+<CDF8> <5229>
+<CDF9> <540F>
+<CDFA> <5C65>
+<CDFB> <674E>
+<CDFC> <68A8>
+<CDFD> <7406>
+<CDFE> <7483>
+<CEA1> <75E2>
+<CEA2> <88CF>
+<CEA3> <88E1>
+<CEA4> <91CC>
+<CEA5> <96E2>
+<CEA6> <9678>
+endbfchar
+
+100 beginbfchar
+<CEA7> <5F8B>
+<CEA8> <7387>
+<CEA9> <7ACB>
+<CEAA> <844E>
+<CEAB> <63A0>
+<CEAC> <7565>
+<CEAD> <5289>
+<CEAE> <6D41>
+<CEAF> <6E9C>
+<CEB0> <7409>
+<CEB1> <7559>
+<CEB2> <786B>
+<CEB3> <7C92>
+<CEB4> <9686>
+<CEB5> <7ADC>
+<CEB6> <9F8D>
+<CEB7> <4FB6>
+<CEB8> <616E>
+<CEB9> <65C5>
+<CEBA> <865C>
+<CEBB> <4E86>
+<CEBC> <4EAE>
+<CEBD> <50DA>
+<CEBE> <4E21>
+<CEBF> <51CC>
+<CEC0> <5BEE>
+<CEC1> <6599>
+<CEC2> <6881>
+<CEC3> <6DBC>
+<CEC4> <731F>
+<CEC5> <7642>
+<CEC6> <77AD>
+<CEC7> <7A1C>
+<CEC8> <7CE7>
+<CEC9> <826F>
+<CECA> <8AD2>
+<CECB> <907C>
+<CECC> <91CF>
+<CECD> <9675>
+<CECE> <9818>
+<CECF> <529B>
+<CED0> <7DD1>
+<CED1> <502B>
+<CED2> <5398>
+<CED3> <6797>
+<CED4> <6DCB>
+<CED5> <71D0>
+<CED6> <7433>
+<CED7> <81E8>
+<CED8> <8F2A>
+<CED9> <96A3>
+<CEDA> <9C57>
+<CEDB> <9E9F>
+<CEDC> <7460>
+<CEDD> <5841>
+<CEDE> <6D99>
+<CEDF> <7D2F>
+<CEE0> <985E>
+<CEE1> <4EE4>
+<CEE2> <4F36>
+<CEE3> <4F8B>
+<CEE4> <51B7>
+<CEE5> <52B1>
+<CEE6> <5DBA>
+<CEE7> <601C>
+<CEE8> <73B2>
+<CEE9> <793C>
+<CEEA> <82D3>
+<CEEB> <9234>
+<CEEC> <96B7>
+<CEED> <96F6>
+<CEEE> <970A>
+<CEEF> <9E97>
+<CEF0> <9F62>
+<CEF1> <66A6>
+<CEF2> <6B74>
+<CEF3> <5217>
+<CEF4> <52A3>
+<CEF5> <70C8>
+<CEF6> <88C2>
+<CEF7> <5EC9>
+<CEF8> <604B>
+<CEF9> <6190>
+<CEFA> <6F23>
+<CEFB> <7149>
+<CEFC> <7C3E>
+<CEFD> <7DF4>
+<CEFE> <806F>
+<CFA1> <84EE>
+<CFA2> <9023>
+<CFA3> <932C>
+<CFA4> <5442>
+<CFA5> <9B6F>
+<CFA6> <6AD3>
+<CFA7> <7089>
+<CFA8> <8CC2>
+<CFA9> <8DEF>
+<CFAA> <9732>
+<CFAB> <52B4>
+<CFAC> <5A41>
+endbfchar
+
+100 beginbfchar
+<CFAD> <5ECA>
+<CFAE> <5F04>
+<CFAF> <6717>
+<CFB0> <697C>
+<CFB1> <6994>
+<CFB2> <6D6A>
+<CFB3> <6F0F>
+<CFB4> <7262>
+<CFB5> <72FC>
+<CFB6> <7BED>
+<CFB7> <8001>
+<CFB8> <807E>
+<CFB9> <874B>
+<CFBA> <90CE>
+<CFBB> <516D>
+<CFBC> <9E93>
+<CFBD> <7984>
+<CFBE> <808B>
+<CFBF> <9332>
+<CFC0> <8AD6>
+<CFC1> <502D>
+<CFC2> <548C>
+<CFC3> <8A71>
+<CFC4> <6B6A>
+<CFC5> <8CC4>
+<CFC6> <8107>
+<CFC7> <60D1>
+<CFC8> <67A0>
+<CFC9> <9DF2>
+<CFCA> <4E99>
+<CFCB> <4E98>
+<CFCC> <9C10>
+<CFCD> <8A6B>
+<CFCE> <85C1>
+<CFCF> <8568>
+<CFD0> <6900>
+<CFD1> <6E7E>
+<CFD2> <7897>
+<CFD3> <8155>
+<D0A1> <5F0C>
+<D0A2> <4E10>
+<D0A3> <4E15>
+<D0A4> <4E2A>
+<D0A5> <4E31>
+<D0A6> <4E36>
+<D0A7> <4E3C>
+<D0A8> <4E3F>
+<D0A9> <4E42>
+<D0AA> <4E56>
+<D0AB> <4E58>
+<D0AC> <4E82>
+<D0AD> <4E85>
+<D0AE> <8C6B>
+<D0AF> <4E8A>
+<D0B0> <8212>
+<D0B1> <5F0D>
+<D0B2> <4E8E>
+<D0B3> <4E9E>
+<D0B4> <4E9F>
+<D0B5> <4EA0>
+<D0B6> <4EA2>
+<D0B7> <4EB0>
+<D0B8> <4EB3>
+<D0B9> <4EB6>
+<D0BA> <4ECE>
+<D0BB> <4ECD>
+<D0BC> <4EC4>
+<D0BD> <4EC6>
+<D0BE> <4EC2>
+<D0BF> <4ED7>
+<D0C0> <4EDE>
+<D0C1> <4EED>
+<D0C2> <4EDF>
+<D0C3> <4EF7>
+<D0C4> <4F09>
+<D0C5> <4F5A>
+<D0C6> <4F30>
+<D0C7> <4F5B>
+<D0C8> <4F5D>
+<D0C9> <4F57>
+<D0CA> <4F47>
+<D0CB> <4F76>
+<D0CC> <4F88>
+<D0CD> <4F8F>
+<D0CE> <4F98>
+<D0CF> <4F7B>
+<D0D0> <4F69>
+<D0D1> <4F70>
+<D0D2> <4F91>
+<D0D3> <4F6F>
+<D0D4> <4F86>
+<D0D5> <4F96>
+<D0D6> <5118>
+<D0D7> <4FD4>
+<D0D8> <4FDF>
+<D0D9> <4FCE>
+<D0DA> <4FD8>
+<D0DB> <4FDB>
+<D0DC> <4FD1>
+<D0DD> <4FDA>
+endbfchar
+
+100 beginbfchar
+<D0DE> <4FD0>
+<D0DF> <4FE4>
+<D0E0> <4FE5>
+<D0E1> <501A>
+<D0E2> <5028>
+<D0E3> <5014>
+<D0E4> <502A>
+<D0E5> <5025>
+<D0E6> <5005>
+<D0E7> <4F1C>
+<D0E8> <4FF6>
+<D0E9> <5021>
+<D0EA> <5029>
+<D0EB> <502C>
+<D0EC> <4FFE>
+<D0ED> <4FEF>
+<D0EE> <5011>
+<D0EF> <5006>
+<D0F0> <5043>
+<D0F1> <5047>
+<D0F2> <6703>
+<D0F3> <5055>
+<D0F4> <5050>
+<D0F5> <5048>
+<D0F6> <505A>
+<D0F7> <5056>
+<D0F8> <506C>
+<D0F9> <5078>
+<D0FA> <5080>
+<D0FB> <509A>
+<D0FC> <5085>
+<D0FD> <50B4>
+<D0FE> <50B2>
+<D1A1> <50C9>
+<D1A2> <50CA>
+<D1A3> <50B3>
+<D1A4> <50C2>
+<D1A5> <50D6>
+<D1A6> <50DE>
+<D1A7> <50E5>
+<D1A8> <50ED>
+<D1A9> <50E3>
+<D1AA> <50EE>
+<D1AB> <50F9>
+<D1AC> <50F5>
+<D1AD> <5109>
+<D1AE> <5101>
+<D1AF> <5102>
+<D1B0> <5116>
+<D1B1> <5115>
+<D1B2> <5114>
+<D1B3> <511A>
+<D1B4> <5121>
+<D1B5> <513A>
+<D1B6> <5137>
+<D1B7> <513C>
+<D1B8> <513B>
+<D1B9> <513F>
+<D1BA> <5140>
+<D1BB> <5152>
+<D1BC> <514C>
+<D1BD> <5154>
+<D1BE> <5162>
+<D1BF> <7AF8>
+<D1C0> <5169>
+<D1C1> <516A>
+<D1C2> <516E>
+<D1C3> <5180>
+<D1C4> <5182>
+<D1C5> <56D8>
+<D1C6> <518C>
+<D1C7> <5189>
+<D1C8> <518F>
+<D1C9> <5191>
+<D1CA> <5193>
+<D1CB> <5195>
+<D1CC> <5196>
+<D1CD> <51A4>
+<D1CE> <51A6>
+<D1CF> <51A2>
+<D1D0> <51A9>
+<D1D1> <51AA>
+<D1D2> <51AB>
+<D1D3> <51B3>
+<D1D4> <51B1>
+<D1D5> <51B2>
+<D1D6> <51B0>
+<D1D7> <51B5>
+<D1D8> <51BD>
+<D1D9> <51C5>
+<D1DA> <51C9>
+<D1DB> <51DB>
+<D1DC> <51E0>
+<D1DD> <8655>
+<D1DE> <51E9>
+<D1DF> <51ED>
+<D1E0> <51F0>
+<D1E1> <51F5>
+<D1E2> <51FE>
+<D1E3> <5204>
+endbfchar
+
+100 beginbfchar
+<D1E4> <520B>
+<D1E5> <5214>
+<D1E6> <520E>
+<D1E7> <5227>
+<D1E8> <522A>
+<D1E9> <522E>
+<D1EA> <5233>
+<D1EB> <5239>
+<D1EC> <524F>
+<D1ED> <5244>
+<D1EE> <524B>
+<D1EF> <524C>
+<D1F0> <525E>
+<D1F1> <5254>
+<D1F2> <526A>
+<D1F3> <5274>
+<D1F4> <5269>
+<D1F5> <5273>
+<D1F6> <527F>
+<D1F7> <527D>
+<D1F8> <528D>
+<D1F9> <5294>
+<D1FA> <5292>
+<D1FB> <5271>
+<D1FC> <5288>
+<D1FD> <5291>
+<D1FE> <8FA8>
+<D2A1> <8FA7>
+<D2A2> <52AC>
+<D2A3> <52AD>
+<D2A4> <52BC>
+<D2A5> <52B5>
+<D2A6> <52C1>
+<D2A7> <52CD>
+<D2A8> <52D7>
+<D2A9> <52DE>
+<D2AA> <52E3>
+<D2AB> <52E6>
+<D2AC> <98ED>
+<D2AD> <52E0>
+<D2AE> <52F3>
+<D2AF> <52F5>
+<D2B0> <52F8>
+<D2B1> <52F9>
+<D2B2> <5306>
+<D2B3> <5308>
+<D2B4> <7538>
+<D2B5> <530D>
+<D2B6> <5310>
+<D2B7> <530F>
+<D2B8> <5315>
+<D2B9> <531A>
+<D2BA> <5323>
+<D2BB> <532F>
+<D2BC> <5331>
+<D2BD> <5333>
+<D2BE> <5338>
+<D2BF> <5340>
+<D2C0> <5346>
+<D2C1> <5345>
+<D2C2> <4E17>
+<D2C3> <5349>
+<D2C4> <534D>
+<D2C5> <51D6>
+<D2C6> <535E>
+<D2C7> <5369>
+<D2C8> <536E>
+<D2C9> <5918>
+<D2CA> <537B>
+<D2CB> <5377>
+<D2CC> <5382>
+<D2CD> <5396>
+<D2CE> <53A0>
+<D2CF> <53A6>
+<D2D0> <53A5>
+<D2D1> <53AE>
+<D2D2> <53B0>
+<D2D3> <53B6>
+<D2D4> <53C3>
+<D2D5> <7C12>
+<D2D6> <96D9>
+<D2D7> <53DF>
+<D2D8> <66FC>
+<D2D9> <71EE>
+<D2DA> <53EE>
+<D2DB> <53E8>
+<D2DC> <53ED>
+<D2DD> <53FA>
+<D2DE> <5401>
+<D2DF> <543D>
+<D2E0> <5440>
+<D2E1> <542C>
+<D2E2> <542D>
+<D2E3> <543C>
+<D2E4> <542E>
+<D2E5> <5436>
+<D2E6> <5429>
+<D2E7> <541D>
+<D2E8> <544E>
+<D2E9> <548F>
+endbfchar
+
+100 beginbfchar
+<D2EA> <5475>
+<D2EB> <548E>
+<D2EC> <545F>
+<D2ED> <5471>
+<D2EE> <5477>
+<D2EF> <5470>
+<D2F0> <5492>
+<D2F1> <547B>
+<D2F2> <5480>
+<D2F3> <5476>
+<D2F4> <5484>
+<D2F5> <5490>
+<D2F6> <5486>
+<D2F7> <54C7>
+<D2F8> <54A2>
+<D2F9> <54B8>
+<D2FA> <54A5>
+<D2FB> <54AC>
+<D2FC> <54C4>
+<D2FD> <54C8>
+<D2FE> <54A8>
+<D3A1> <54AB>
+<D3A2> <54C2>
+<D3A3> <54A4>
+<D3A4> <54BE>
+<D3A5> <54BC>
+<D3A6> <54D8>
+<D3A7> <54E5>
+<D3A8> <54E6>
+<D3A9> <550F>
+<D3AA> <5514>
+<D3AB> <54FD>
+<D3AC> <54EE>
+<D3AD> <54ED>
+<D3AE> <54FA>
+<D3AF> <54E2>
+<D3B0> <5539>
+<D3B1> <5540>
+<D3B2> <5563>
+<D3B3> <554C>
+<D3B4> <552E>
+<D3B5> <555C>
+<D3B6> <5545>
+<D3B7> <5556>
+<D3B8> <5557>
+<D3B9> <5538>
+<D3BA> <5533>
+<D3BB> <555D>
+<D3BC> <5599>
+<D3BD> <5580>
+<D3BE> <54AF>
+<D3BF> <558A>
+<D3C0> <559F>
+<D3C1> <557B>
+<D3C2> <557E>
+<D3C3> <5598>
+<D3C4> <559E>
+<D3C5> <55AE>
+<D3C6> <557C>
+<D3C7> <5583>
+<D3C8> <55A9>
+<D3C9> <5587>
+<D3CA> <55A8>
+<D3CB> <55DA>
+<D3CC> <55C5>
+<D3CD> <55DF>
+<D3CE> <55C4>
+<D3CF> <55DC>
+<D3D0> <55E4>
+<D3D1> <55D4>
+<D3D2> <5614>
+<D3D3> <55F7>
+<D3D4> <5616>
+<D3D5> <55FE>
+<D3D6> <55FD>
+<D3D7> <561B>
+<D3D8> <55F9>
+<D3D9> <564E>
+<D3DA> <5650>
+<D3DB> <71DF>
+<D3DC> <5634>
+<D3DD> <5636>
+<D3DE> <5632>
+<D3DF> <5638>
+<D3E0> <566B>
+<D3E1> <5664>
+<D3E2> <562F>
+<D3E3> <566C>
+<D3E4> <566A>
+<D3E5> <5686>
+<D3E6> <5680>
+<D3E7> <568A>
+<D3E8> <56A0>
+<D3E9> <5694>
+<D3EA> <568F>
+<D3EB> <56A5>
+<D3EC> <56AE>
+<D3ED> <56B6>
+<D3EE> <56B4>
+<D3EF> <56C2>
+endbfchar
+
+100 beginbfchar
+<D3F0> <56BC>
+<D3F1> <56C1>
+<D3F2> <56C3>
+<D3F3> <56C0>
+<D3F4> <56C8>
+<D3F5> <56CE>
+<D3F6> <56D1>
+<D3F7> <56D3>
+<D3F8> <56D7>
+<D3F9> <56EE>
+<D3FA> <56F9>
+<D3FB> <5700>
+<D3FC> <56FF>
+<D3FD> <5704>
+<D3FE> <5709>
+<D4A1> <5708>
+<D4A2> <570B>
+<D4A3> <570D>
+<D4A4> <5713>
+<D4A5> <5718>
+<D4A6> <5716>
+<D4A7> <55C7>
+<D4A8> <571C>
+<D4A9> <5726>
+<D4AA> <5737>
+<D4AB> <5738>
+<D4AC> <574E>
+<D4AD> <573B>
+<D4AE> <5740>
+<D4AF> <574F>
+<D4B0> <5769>
+<D4B1> <57C0>
+<D4B2> <5788>
+<D4B3> <5761>
+<D4B4> <577F>
+<D4B5> <5789>
+<D4B6> <5793>
+<D4B7> <57A0>
+<D4B8> <57B3>
+<D4B9> <57A4>
+<D4BA> <57AA>
+<D4BB> <57B0>
+<D4BC> <57C3>
+<D4BD> <57C6>
+<D4BE> <57D4>
+<D4BF> <57D2>
+<D4C0> <57D3>
+<D4C1> <580A>
+<D4C2> <57D6>
+<D4C3> <57E3>
+<D4C4> <580B>
+<D4C5> <5819>
+<D4C6> <581D>
+<D4C7> <5872>
+<D4C8> <5821>
+<D4C9> <5862>
+<D4CA> <584B>
+<D4CB> <5870>
+<D4CC> <6BC0>
+<D4CD> <5852>
+<D4CE> <583D>
+<D4CF> <5879>
+<D4D0> <5885>
+<D4D1> <58B9>
+<D4D2> <589F>
+<D4D3> <58AB>
+<D4D4> <58BA>
+<D4D5> <58DE>
+<D4D6> <58BB>
+<D4D7> <58B8>
+<D4D8> <58AE>
+<D4D9> <58C5>
+<D4DA> <58D3>
+<D4DB> <58D1>
+<D4DC> <58D7>
+<D4DD> <58D9>
+<D4DE> <58D8>
+<D4DF> <58E5>
+<D4E0> <58DC>
+<D4E1> <58E4>
+<D4E2> <58DF>
+<D4E3> <58EF>
+<D4E4> <58FA>
+<D4E5> <58F9>
+<D4E6> <58FB>
+<D4E7> <58FC>
+<D4E8> <58FD>
+<D4E9> <5902>
+<D4EA> <590A>
+<D4EB> <5910>
+<D4EC> <591B>
+<D4ED> <68A6>
+<D4EE> <5925>
+<D4EF> <592C>
+<D4F0> <592D>
+<D4F1> <5932>
+<D4F2> <5938>
+<D4F3> <593E>
+<D4F4> <7AD2>
+<D4F5> <5955>
+endbfchar
+
+100 beginbfchar
+<D4F6> <5950>
+<D4F7> <594E>
+<D4F8> <595A>
+<D4F9> <5958>
+<D4FA> <5962>
+<D4FB> <5960>
+<D4FC> <5967>
+<D4FD> <596C>
+<D4FE> <5969>
+<D5A1> <5978>
+<D5A2> <5981>
+<D5A3> <599D>
+<D5A4> <4F5E>
+<D5A5> <4FAB>
+<D5A6> <59A3>
+<D5A7> <59B2>
+<D5A8> <59C6>
+<D5A9> <59E8>
+<D5AA> <59DC>
+<D5AB> <598D>
+<D5AC> <59D9>
+<D5AD> <59DA>
+<D5AE> <5A25>
+<D5AF> <5A1F>
+<D5B0> <5A11>
+<D5B1> <5A1C>
+<D5B2> <5A09>
+<D5B3> <5A1A>
+<D5B4> <5A40>
+<D5B5> <5A6C>
+<D5B6> <5A49>
+<D5B7> <5A35>
+<D5B8> <5A36>
+<D5B9> <5A62>
+<D5BA> <5A6A>
+<D5BB> <5A9A>
+<D5BC> <5ABC>
+<D5BD> <5ABE>
+<D5BE> <5ACB>
+<D5BF> <5AC2>
+<D5C0> <5ABD>
+<D5C1> <5AE3>
+<D5C2> <5AD7>
+<D5C3> <5AE6>
+<D5C4> <5AE9>
+<D5C5> <5AD6>
+<D5C6> <5AFA>
+<D5C7> <5AFB>
+<D5C8> <5B0C>
+<D5C9> <5B0B>
+<D5CA> <5B16>
+<D5CB> <5B32>
+<D5CC> <5AD0>
+<D5CD> <5B2A>
+<D5CE> <5B36>
+<D5CF> <5B3E>
+<D5D0> <5B43>
+<D5D1> <5B45>
+<D5D2> <5B40>
+<D5D3> <5B51>
+<D5D4> <5B55>
+<D5D5> <5B5A>
+<D5D6> <5B5B>
+<D5D7> <5B65>
+<D5D8> <5B69>
+<D5D9> <5B70>
+<D5DA> <5B73>
+<D5DB> <5B75>
+<D5DC> <5B78>
+<D5DD> <6588>
+<D5DE> <5B7A>
+<D5DF> <5B80>
+<D5E0> <5B83>
+<D5E1> <5BA6>
+<D5E2> <5BB8>
+<D5E3> <5BC3>
+<D5E4> <5BC7>
+<D5E5> <5BC9>
+<D5E6> <5BD4>
+<D5E7> <5BD0>
+<D5E8> <5BE4>
+<D5E9> <5BE6>
+<D5EA> <5BE2>
+<D5EB> <5BDE>
+<D5EC> <5BE5>
+<D5ED> <5BEB>
+<D5EE> <5BF0>
+<D5EF> <5BF6>
+<D5F0> <5BF3>
+<D5F1> <5C05>
+<D5F2> <5C07>
+<D5F3> <5C08>
+<D5F4> <5C0D>
+<D5F5> <5C13>
+<D5F6> <5C20>
+<D5F7> <5C22>
+<D5F8> <5C28>
+<D5F9> <5C38>
+<D5FA> <5C39>
+<D5FB> <5C41>
+endbfchar
+
+100 beginbfchar
+<D5FC> <5C46>
+<D5FD> <5C4E>
+<D5FE> <5C53>
+<D6A1> <5C50>
+<D6A2> <5C4F>
+<D6A3> <5B71>
+<D6A4> <5C6C>
+<D6A5> <5C6E>
+<D6A6> <4E62>
+<D6A7> <5C76>
+<D6A8> <5C79>
+<D6A9> <5C8C>
+<D6AA> <5C91>
+<D6AB> <5C94>
+<D6AC> <599B>
+<D6AD> <5CAB>
+<D6AE> <5CBB>
+<D6AF> <5CB6>
+<D6B0> <5CBC>
+<D6B1> <5CB7>
+<D6B2> <5CC5>
+<D6B3> <5CBE>
+<D6B4> <5CC7>
+<D6B5> <5CD9>
+<D6B6> <5CE9>
+<D6B7> <5CFD>
+<D6B8> <5CFA>
+<D6B9> <5CED>
+<D6BA> <5D8C>
+<D6BB> <5CEA>
+<D6BC> <5D0B>
+<D6BD> <5D15>
+<D6BE> <5D17>
+<D6BF> <5D5C>
+<D6C0> <5D1F>
+<D6C1> <5D1B>
+<D6C2> <5D11>
+<D6C3> <5D14>
+<D6C4> <5D22>
+<D6C5> <5D1A>
+<D6C6> <5D19>
+<D6C7> <5D18>
+<D6C8> <5D4C>
+<D6C9> <5D52>
+<D6CA> <5D4E>
+<D6CB> <5D4B>
+<D6CC> <5D6C>
+<D6CD> <5D73>
+<D6CE> <5D76>
+<D6CF> <5D87>
+<D6D0> <5D84>
+<D6D1> <5D82>
+<D6D2> <5DA2>
+<D6D3> <5D9D>
+<D6D4> <5DAC>
+<D6D5> <5DAE>
+<D6D6> <5DBD>
+<D6D7> <5D90>
+<D6D8> <5DB7>
+<D6D9> <5DBC>
+<D6DA> <5DC9>
+<D6DB> <5DCD>
+<D6DC> <5DD3>
+<D6DD> <5DD2>
+<D6DE> <5DD6>
+<D6DF> <5DDB>
+<D6E0> <5DEB>
+<D6E1> <5DF2>
+<D6E2> <5DF5>
+<D6E3> <5E0B>
+<D6E4> <5E1A>
+<D6E5> <5E19>
+<D6E6> <5E11>
+<D6E7> <5E1B>
+<D6E8> <5E36>
+<D6E9> <5E37>
+<D6EA> <5E44>
+<D6EB> <5E43>
+<D6EC> <5E40>
+<D6ED> <5E4E>
+<D6EE> <5E57>
+<D6EF> <5E54>
+<D6F0> <5E5F>
+<D6F1> <5E62>
+<D6F2> <5E64>
+<D6F3> <5E47>
+<D6F4> <5E75>
+<D6F5> <5E76>
+<D6F6> <5E7A>
+<D6F7> <9EBC>
+<D6F8> <5E7F>
+<D6F9> <5EA0>
+<D6FA> <5EC1>
+<D6FB> <5EC2>
+<D6FC> <5EC8>
+<D6FD> <5ED0>
+<D6FE> <5ECF>
+<D7A1> <5ED6>
+<D7A2> <5EE3>
+<D7A3> <5EDD>
+endbfchar
+
+100 beginbfchar
+<D7A4> <5EDA>
+<D7A5> <5EDB>
+<D7A6> <5EE2>
+<D7A7> <5EE1>
+<D7A8> <5EE8>
+<D7A9> <5EE9>
+<D7AA> <5EEC>
+<D7AB> <5EF1>
+<D7AC> <5EF3>
+<D7AD> <5EF0>
+<D7AE> <5EF4>
+<D7AF> <5EF8>
+<D7B0> <5EFE>
+<D7B1> <5F03>
+<D7B2> <5F09>
+<D7B3> <5F5D>
+<D7B4> <5F5C>
+<D7B5> <5F0B>
+<D7B6> <5F11>
+<D7B7> <5F16>
+<D7B8> <5F29>
+<D7B9> <5F2D>
+<D7BA> <5F38>
+<D7BB> <5F41>
+<D7BC> <5F48>
+<D7BD> <5F4C>
+<D7BE> <5F4E>
+<D7BF> <5F2F>
+<D7C0> <5F51>
+<D7C1> <5F56>
+<D7C2> <5F57>
+<D7C3> <5F59>
+<D7C4> <5F61>
+<D7C5> <5F6D>
+<D7C6> <5F73>
+<D7C7> <5F77>
+<D7C8> <5F83>
+<D7C9> <5F82>
+<D7CA> <5F7F>
+<D7CB> <5F8A>
+<D7CC> <5F88>
+<D7CD> <5F91>
+<D7CE> <5F87>
+<D7CF> <5F9E>
+<D7D0> <5F99>
+<D7D1> <5F98>
+<D7D2> <5FA0>
+<D7D3> <5FA8>
+<D7D4> <5FAD>
+<D7D5> <5FBC>
+<D7D6> <5FD6>
+<D7D7> <5FFB>
+<D7D8> <5FE4>
+<D7D9> <5FF8>
+<D7DA> <5FF1>
+<D7DB> <5FDD>
+<D7DC> <60B3>
+<D7DD> <5FFF>
+<D7DE> <6021>
+<D7DF> <6060>
+<D7E0> <6019>
+<D7E1> <6010>
+<D7E2> <6029>
+<D7E3> <600E>
+<D7E4> <6031>
+<D7E5> <601B>
+<D7E6> <6015>
+<D7E7> <602B>
+<D7E8> <6026>
+<D7E9> <600F>
+<D7EA> <603A>
+<D7EB> <605A>
+<D7EC> <6041>
+<D7ED> <606A>
+<D7EE> <6077>
+<D7EF> <605F>
+<D7F0> <604A>
+<D7F1> <6046>
+<D7F2> <604D>
+<D7F3> <6063>
+<D7F4> <6043>
+<D7F5> <6064>
+<D7F6> <6042>
+<D7F7> <606C>
+<D7F8> <606B>
+<D7F9> <6059>
+<D7FA> <6081>
+<D7FB> <608D>
+<D7FC> <60E7>
+<D7FD> <6083>
+<D7FE> <609A>
+<D8A1> <6084>
+<D8A2> <609B>
+<D8A3> <6096>
+<D8A4> <6097>
+<D8A5> <6092>
+<D8A6> <60A7>
+<D8A7> <608B>
+<D8A8> <60E1>
+<D8A9> <60B8>
+endbfchar
+
+100 beginbfchar
+<D8AA> <60E0>
+<D8AB> <60D3>
+<D8AC> <60B4>
+<D8AD> <5FF0>
+<D8AE> <60BD>
+<D8AF> <60C6>
+<D8B0> <60B5>
+<D8B1> <60D8>
+<D8B2> <614D>
+<D8B3> <6115>
+<D8B4> <6106>
+<D8B5> <60F6>
+<D8B6> <60F7>
+<D8B7> <6100>
+<D8B8> <60F4>
+<D8B9> <60FA>
+<D8BA> <6103>
+<D8BB> <6121>
+<D8BC> <60FB>
+<D8BD> <60F1>
+<D8BE> <610D>
+<D8BF> <610E>
+<D8C0> <6147>
+<D8C1> <613E>
+<D8C2> <6128>
+<D8C3> <6127>
+<D8C4> <614A>
+<D8C5> <613F>
+<D8C6> <613C>
+<D8C7> <612C>
+<D8C8> <6134>
+<D8C9> <613D>
+<D8CA> <6142>
+<D8CB> <6144>
+<D8CC> <6173>
+<D8CD> <6177>
+<D8CE> <6158>
+<D8CF> <6159>
+<D8D0> <615A>
+<D8D1> <616B>
+<D8D2> <6174>
+<D8D3> <616F>
+<D8D4> <6165>
+<D8D5> <6171>
+<D8D6> <615F>
+<D8D7> <615D>
+<D8D8> <6153>
+<D8D9> <6175>
+<D8DA> <6199>
+<D8DB> <6196>
+<D8DC> <6187>
+<D8DD> <61AC>
+<D8DE> <6194>
+<D8DF> <619A>
+<D8E0> <618A>
+<D8E1> <6191>
+<D8E2> <61AB>
+<D8E3> <61AE>
+<D8E4> <61CC>
+<D8E5> <61CA>
+<D8E6> <61C9>
+<D8E7> <61F7>
+<D8E8> <61C8>
+<D8E9> <61C3>
+<D8EA> <61C6>
+<D8EB> <61BA>
+<D8EC> <61CB>
+<D8ED> <7F79>
+<D8EE> <61CD>
+<D8EF> <61E6>
+<D8F0> <61E3>
+<D8F1> <61F6>
+<D8F2> <61FA>
+<D8F3> <61F4>
+<D8F4> <61FF>
+<D8F5> <61FD>
+<D8F6> <61FC>
+<D8F7> <61FE>
+<D8F8> <6200>
+<D8F9> <6208>
+<D8FA> <6209>
+<D8FB> <620D>
+<D8FC> <620C>
+<D8FD> <6214>
+<D8FE> <621B>
+<D9A1> <621E>
+<D9A2> <6221>
+<D9A3> <622A>
+<D9A4> <622E>
+<D9A5> <6230>
+<D9A6> <6232>
+<D9A7> <6233>
+<D9A8> <6241>
+<D9A9> <624E>
+<D9AA> <625E>
+<D9AB> <6263>
+<D9AC> <625B>
+<D9AD> <6260>
+<D9AE> <6268>
+<D9AF> <627C>
+endbfchar
+
+100 beginbfchar
+<D9B0> <6282>
+<D9B1> <6289>
+<D9B2> <627E>
+<D9B3> <6292>
+<D9B4> <6293>
+<D9B5> <6296>
+<D9B6> <62D4>
+<D9B7> <6283>
+<D9B8> <6294>
+<D9B9> <62D7>
+<D9BA> <62D1>
+<D9BB> <62BB>
+<D9BC> <62CF>
+<D9BD> <62FF>
+<D9BE> <62C6>
+<D9BF> <64D4>
+<D9C0> <62C8>
+<D9C1> <62DC>
+<D9C2> <62CC>
+<D9C3> <62CA>
+<D9C4> <62C2>
+<D9C5> <62C7>
+<D9C6> <629B>
+<D9C7> <62C9>
+<D9C8> <630C>
+<D9C9> <62EE>
+<D9CA> <62F1>
+<D9CB> <6327>
+<D9CC> <6302>
+<D9CD> <6308>
+<D9CE> <62EF>
+<D9CF> <62F5>
+<D9D0> <6350>
+<D9D1> <633E>
+<D9D2> <634D>
+<D9D3> <641C>
+<D9D4> <634F>
+<D9D5> <6396>
+<D9D6> <638E>
+<D9D7> <6380>
+<D9D8> <63AB>
+<D9D9> <6376>
+<D9DA> <63A3>
+<D9DB> <638F>
+<D9DC> <6389>
+<D9DD> <639F>
+<D9DE> <63B5>
+<D9DF> <636B>
+<D9E0> <6369>
+<D9E1> <63BE>
+<D9E2> <63E9>
+<D9E3> <63C0>
+<D9E4> <63C6>
+<D9E5> <63E3>
+<D9E6> <63C9>
+<D9E7> <63D2>
+<D9E8> <63F6>
+<D9E9> <63C4>
+<D9EA> <6416>
+<D9EB> <6434>
+<D9EC> <6406>
+<D9ED> <6413>
+<D9EE> <6426>
+<D9EF> <6436>
+<D9F0> <651D>
+<D9F1> <6417>
+<D9F2> <6428>
+<D9F3> <640F>
+<D9F4> <6467>
+<D9F5> <646F>
+<D9F6> <6476>
+<D9F7> <644E>
+<D9F8> <652A>
+<D9F9> <6495>
+<D9FA> <6493>
+<D9FB> <64A5>
+<D9FC> <64A9>
+<D9FD> <6488>
+<D9FE> <64BC>
+<DAA1> <64DA>
+<DAA2> <64D2>
+<DAA3> <64C5>
+<DAA4> <64C7>
+<DAA5> <64BB>
+<DAA6> <64D8>
+<DAA7> <64C2>
+<DAA8> <64F1>
+<DAA9> <64E7>
+<DAAA> <8209>
+<DAAB> <64E0>
+<DAAC> <64E1>
+<DAAD> <62AC>
+<DAAE> <64E3>
+<DAAF> <64EF>
+<DAB0> <652C>
+<DAB1> <64F6>
+<DAB2> <64F4>
+<DAB3> <64F2>
+<DAB4> <64FA>
+<DAB5> <6500>
+endbfchar
+
+100 beginbfchar
+<DAB6> <64FD>
+<DAB7> <6518>
+<DAB8> <651C>
+<DAB9> <6505>
+<DABA> <6524>
+<DABB> <6523>
+<DABC> <652B>
+<DABD> <6534>
+<DABE> <6535>
+<DABF> <6537>
+<DAC0> <6536>
+<DAC1> <6538>
+<DAC2> <754B>
+<DAC3> <6548>
+<DAC4> <6556>
+<DAC5> <6555>
+<DAC6> <654D>
+<DAC7> <6558>
+<DAC8> <655E>
+<DAC9> <655D>
+<DACA> <6572>
+<DACB> <6578>
+<DACC> <6582>
+<DACD> <6583>
+<DACE> <8B8A>
+<DACF> <659B>
+<DAD0> <659F>
+<DAD1> <65AB>
+<DAD2> <65B7>
+<DAD3> <65C3>
+<DAD4> <65C6>
+<DAD5> <65C1>
+<DAD6> <65C4>
+<DAD7> <65CC>
+<DAD8> <65D2>
+<DAD9> <65DB>
+<DADA> <65D9>
+<DADB> <65E0>
+<DADC> <65E1>
+<DADD> <65F1>
+<DADE> <6772>
+<DADF> <660A>
+<DAE0> <6603>
+<DAE1> <65FB>
+<DAE2> <6773>
+<DAE3> <6635>
+<DAE4> <6636>
+<DAE5> <6634>
+<DAE6> <661C>
+<DAE7> <664F>
+<DAE8> <6644>
+<DAE9> <6649>
+<DAEA> <6641>
+<DAEB> <665E>
+<DAEC> <665D>
+<DAED> <6664>
+<DAEE> <6667>
+<DAEF> <6668>
+<DAF0> <665F>
+<DAF1> <6662>
+<DAF2> <6670>
+<DAF3> <6683>
+<DAF4> <6688>
+<DAF5> <668E>
+<DAF6> <6689>
+<DAF7> <6684>
+<DAF8> <6698>
+<DAF9> <669D>
+<DAFA> <66C1>
+<DAFB> <66B9>
+<DAFC> <66C9>
+<DAFD> <66BE>
+<DAFE> <66BC>
+<DBA1> <66C4>
+<DBA2> <66B8>
+<DBA3> <66D6>
+<DBA4> <66DA>
+<DBA5> <66E0>
+<DBA6> <663F>
+<DBA7> <66E6>
+<DBA8> <66E9>
+<DBA9> <66F0>
+<DBAA> <66F5>
+<DBAB> <66F7>
+<DBAC> <670F>
+<DBAD> <6716>
+<DBAE> <671E>
+<DBAF> <6726>
+<DBB0> <6727>
+<DBB1> <9738>
+<DBB2> <672E>
+<DBB3> <673F>
+<DBB4> <6736>
+<DBB5> <6741>
+<DBB6> <6738>
+<DBB7> <6737>
+<DBB8> <6746>
+<DBB9> <675E>
+<DBBA> <6760>
+<DBBB> <6759>
+endbfchar
+
+100 beginbfchar
+<DBBC> <6763>
+<DBBD> <6764>
+<DBBE> <6789>
+<DBBF> <6770>
+<DBC0> <67A9>
+<DBC1> <677C>
+<DBC2> <676A>
+<DBC3> <678C>
+<DBC4> <678B>
+<DBC5> <67A6>
+<DBC6> <67A1>
+<DBC7> <6785>
+<DBC8> <67B7>
+<DBC9> <67EF>
+<DBCA> <67B4>
+<DBCB> <67EC>
+<DBCC> <67B3>
+<DBCD> <67E9>
+<DBCE> <67B8>
+<DBCF> <67E4>
+<DBD0> <67DE>
+<DBD1> <67DD>
+<DBD2> <67E2>
+<DBD3> <67EE>
+<DBD4> <67B9>
+<DBD5> <67CE>
+<DBD6> <67C6>
+<DBD7> <67E7>
+<DBD8> <6A9C>
+<DBD9> <681E>
+<DBDA> <6846>
+<DBDB> <6829>
+<DBDC> <6840>
+<DBDD> <684D>
+<DBDE> <6832>
+<DBDF> <684E>
+<DBE0> <68B3>
+<DBE1> <682B>
+<DBE2> <6859>
+<DBE3> <6863>
+<DBE4> <6877>
+<DBE5> <687F>
+<DBE6> <689F>
+<DBE7> <688F>
+<DBE8> <68AD>
+<DBE9> <6894>
+<DBEA> <689D>
+<DBEB> <689B>
+<DBEC> <6883>
+<DBED> <6AAE>
+<DBEE> <68B9>
+<DBEF> <6874>
+<DBF0> <68B5>
+<DBF1> <68A0>
+<DBF2> <68BA>
+<DBF3> <690F>
+<DBF4> <688D>
+<DBF5> <687E>
+<DBF6> <6901>
+<DBF7> <68CA>
+<DBF8> <6908>
+<DBF9> <68D8>
+<DBFA> <6922>
+<DBFB> <6926>
+<DBFC> <68E1>
+<DBFD> <690C>
+<DBFE> <68CD>
+<DCA1> <68D4>
+<DCA2> <68E7>
+<DCA3> <68D5>
+<DCA4> <6936>
+<DCA5> <6912>
+<DCA6> <6904>
+<DCA7> <68D7>
+<DCA8> <68E3>
+<DCA9> <6925>
+<DCAA> <68F9>
+<DCAB> <68E0>
+<DCAC> <68EF>
+<DCAD> <6928>
+<DCAE> <692A>
+<DCAF> <691A>
+<DCB0> <6923>
+<DCB1> <6921>
+<DCB2> <68C6>
+<DCB3> <6979>
+<DCB4> <6977>
+<DCB5> <695C>
+<DCB6> <6978>
+<DCB7> <696B>
+<DCB8> <6954>
+<DCB9> <697E>
+<DCBA> <696E>
+<DCBB> <6939>
+<DCBC> <6974>
+<DCBD> <693D>
+<DCBE> <6959>
+<DCBF> <6930>
+<DCC0> <6961>
+<DCC1> <695E>
+endbfchar
+
+100 beginbfchar
+<DCC2> <695D>
+<DCC3> <6981>
+<DCC4> <696A>
+<DCC5> <69B2>
+<DCC6> <69AE>
+<DCC7> <69D0>
+<DCC8> <69BF>
+<DCC9> <69C1>
+<DCCA> <69D3>
+<DCCB> <69BE>
+<DCCC> <69CE>
+<DCCD> <5BE8>
+<DCCE> <69CA>
+<DCCF> <69DD>
+<DCD0> <69BB>
+<DCD1> <69C3>
+<DCD2> <69A7>
+<DCD3> <6A2E>
+<DCD4> <6991>
+<DCD5> <69A0>
+<DCD6> <699C>
+<DCD7> <6995>
+<DCD8> <69B4>
+<DCD9> <69DE>
+<DCDA> <69E8>
+<DCDB> <6A02>
+<DCDC> <6A1B>
+<DCDD> <69FF>
+<DCDE> <6B0A>
+<DCDF> <69F9>
+<DCE0> <69F2>
+<DCE1> <69E7>
+<DCE2> <6A05>
+<DCE3> <69B1>
+<DCE4> <6A1E>
+<DCE5> <69ED>
+<DCE6> <6A14>
+<DCE7> <69EB>
+<DCE8> <6A0A>
+<DCE9> <6A12>
+<DCEA> <6AC1>
+<DCEB> <6A23>
+<DCEC> <6A13>
+<DCED> <6A44>
+<DCEE> <6A0C>
+<DCEF> <6A72>
+<DCF0> <6A36>
+<DCF1> <6A78>
+<DCF2> <6A47>
+<DCF3> <6A62>
+<DCF4> <6A59>
+<DCF5> <6A66>
+<DCF6> <6A48>
+<DCF7> <6A38>
+<DCF8> <6A22>
+<DCF9> <6A90>
+<DCFA> <6A8D>
+<DCFB> <6AA0>
+<DCFC> <6A84>
+<DCFD> <6AA2>
+<DCFE> <6AA3>
+<DDA1> <6A97>
+<DDA2> <8617>
+<DDA3> <6ABB>
+<DDA4> <6AC3>
+<DDA5> <6AC2>
+<DDA6> <6AB8>
+<DDA7> <6AB3>
+<DDA8> <6AAC>
+<DDA9> <6ADE>
+<DDAA> <6AD1>
+<DDAB> <6ADF>
+<DDAC> <6AAA>
+<DDAD> <6ADA>
+<DDAE> <6AEA>
+<DDAF> <6AFB>
+<DDB0> <6B05>
+<DDB1> <8616>
+<DDB2> <6AFA>
+<DDB3> <6B12>
+<DDB4> <6B16>
+<DDB5> <9B31>
+<DDB6> <6B1F>
+<DDB7> <6B38>
+<DDB8> <6B37>
+<DDB9> <76DC>
+<DDBA> <6B39>
+<DDBB> <98EE>
+<DDBC> <6B47>
+<DDBD> <6B43>
+<DDBE> <6B49>
+<DDBF> <6B50>
+<DDC0> <6B59>
+<DDC1> <6B54>
+<DDC2> <6B5B>
+<DDC3> <6B5F>
+<DDC4> <6B61>
+<DDC5> <6B78>
+<DDC6> <6B79>
+<DDC7> <6B7F>
+endbfchar
+
+100 beginbfchar
+<DDC8> <6B80>
+<DDC9> <6B84>
+<DDCA> <6B83>
+<DDCB> <6B8D>
+<DDCC> <6B98>
+<DDCD> <6B95>
+<DDCE> <6B9E>
+<DDCF> <6BA4>
+<DDD0> <6BAA>
+<DDD1> <6BAB>
+<DDD2> <6BAF>
+<DDD3> <6BB2>
+<DDD4> <6BB1>
+<DDD5> <6BB3>
+<DDD6> <6BB7>
+<DDD7> <6BBC>
+<DDD8> <6BC6>
+<DDD9> <6BCB>
+<DDDA> <6BD3>
+<DDDB> <6BDF>
+<DDDC> <6BEC>
+<DDDD> <6BEB>
+<DDDE> <6BF3>
+<DDDF> <6BEF>
+<DDE0> <9EBE>
+<DDE1> <6C08>
+<DDE2> <6C13>
+<DDE3> <6C14>
+<DDE4> <6C1B>
+<DDE5> <6C24>
+<DDE6> <6C23>
+<DDE7> <6C5E>
+<DDE8> <6C55>
+<DDE9> <6C62>
+<DDEA> <6C6A>
+<DDEB> <6C82>
+<DDEC> <6C8D>
+<DDED> <6C9A>
+<DDEE> <6C81>
+<DDEF> <6C9B>
+<DDF0> <6C7E>
+<DDF1> <6C68>
+<DDF2> <6C73>
+<DDF3> <6C92>
+<DDF4> <6C90>
+<DDF5> <6CC4>
+<DDF6> <6CF1>
+<DDF7> <6CD3>
+<DDF8> <6CBD>
+<DDF9> <6CD7>
+<DDFA> <6CC5>
+<DDFB> <6CDD>
+<DDFC> <6CAE>
+<DDFD> <6CB1>
+<DDFE> <6CBE>
+<DEA1> <6CBA>
+<DEA2> <6CDB>
+<DEA3> <6CEF>
+<DEA4> <6CD9>
+<DEA5> <6CEA>
+<DEA6> <6D1F>
+<DEA7> <884D>
+<DEA8> <6D36>
+<DEA9> <6D2B>
+<DEAA> <6D3D>
+<DEAB> <6D38>
+<DEAC> <6D19>
+<DEAD> <6D35>
+<DEAE> <6D33>
+<DEAF> <6D12>
+<DEB0> <6D0C>
+<DEB1> <6D63>
+<DEB2> <6D93>
+<DEB3> <6D64>
+<DEB4> <6D5A>
+<DEB5> <6D79>
+<DEB6> <6D59>
+<DEB7> <6D8E>
+<DEB8> <6D95>
+<DEB9> <6FE4>
+<DEBA> <6D85>
+<DEBB> <6DF9>
+<DEBC> <6E15>
+<DEBD> <6E0A>
+<DEBE> <6DB5>
+<DEBF> <6DC7>
+<DEC0> <6DE6>
+<DEC1> <6DB8>
+<DEC2> <6DC6>
+<DEC3> <6DEC>
+<DEC4> <6DDE>
+<DEC5> <6DCC>
+<DEC6> <6DE8>
+<DEC7> <6DD2>
+<DEC8> <6DC5>
+<DEC9> <6DFA>
+<DECA> <6DD9>
+<DECB> <6DE4>
+<DECC> <6DD5>
+<DECD> <6DEA>
+endbfchar
+
+100 beginbfchar
+<DECE> <6DEE>
+<DECF> <6E2D>
+<DED0> <6E6E>
+<DED1> <6E2E>
+<DED2> <6E19>
+<DED3> <6E72>
+<DED4> <6E5F>
+<DED5> <6E3E>
+<DED6> <6E23>
+<DED7> <6E6B>
+<DED8> <6E2B>
+<DED9> <6E76>
+<DEDA> <6E4D>
+<DEDB> <6E1F>
+<DEDC> <6E43>
+<DEDD> <6E3A>
+<DEDE> <6E4E>
+<DEDF> <6E24>
+<DEE0> <6EFF>
+<DEE1> <6E1D>
+<DEE2> <6E38>
+<DEE3> <6E82>
+<DEE4> <6EAA>
+<DEE5> <6E98>
+<DEE6> <6EC9>
+<DEE7> <6EB7>
+<DEE8> <6ED3>
+<DEE9> <6EBD>
+<DEEA> <6EAF>
+<DEEB> <6EC4>
+<DEEC> <6EB2>
+<DEED> <6ED4>
+<DEEE> <6ED5>
+<DEEF> <6E8F>
+<DEF0> <6EA5>
+<DEF1> <6EC2>
+<DEF2> <6E9F>
+<DEF3> <6F41>
+<DEF4> <6F11>
+<DEF5> <704C>
+<DEF6> <6EEC>
+<DEF7> <6EF8>
+<DEF8> <6EFE>
+<DEF9> <6F3F>
+<DEFA> <6EF2>
+<DEFB> <6F31>
+<DEFC> <6EEF>
+<DEFD> <6F32>
+<DEFE> <6ECC>
+<DFA1> <6F3E>
+<DFA2> <6F13>
+<DFA3> <6EF7>
+<DFA4> <6F86>
+<DFA5> <6F7A>
+<DFA6> <6F78>
+<DFA7> <6F81>
+<DFA8> <6F80>
+<DFA9> <6F6F>
+<DFAA> <6F5B>
+<DFAB> <6FF3>
+<DFAC> <6F6D>
+<DFAD> <6F82>
+<DFAE> <6F7C>
+<DFAF> <6F58>
+<DFB0> <6F8E>
+<DFB1> <6F91>
+<DFB2> <6FC2>
+<DFB3> <6F66>
+<DFB4> <6FB3>
+<DFB5> <6FA3>
+<DFB6> <6FA1>
+<DFB7> <6FA4>
+<DFB8> <6FB9>
+<DFB9> <6FC6>
+<DFBA> <6FAA>
+<DFBB> <6FDF>
+<DFBC> <6FD5>
+<DFBD> <6FEC>
+<DFBE> <6FD4>
+<DFBF> <6FD8>
+<DFC0> <6FF1>
+<DFC1> <6FEE>
+<DFC2> <6FDB>
+<DFC3> <7009>
+<DFC4> <700B>
+<DFC5> <6FFA>
+<DFC6> <7011>
+<DFC7> <7001>
+<DFC8> <700F>
+<DFC9> <6FFE>
+<DFCA> <701B>
+<DFCB> <701A>
+<DFCC> <6F74>
+<DFCD> <701D>
+<DFCE> <7018>
+<DFCF> <701F>
+<DFD0> <7030>
+<DFD1> <703E>
+<DFD2> <7032>
+<DFD3> <7051>
+endbfchar
+
+100 beginbfchar
+<DFD4> <7063>
+<DFD5> <7099>
+<DFD6> <7092>
+<DFD7> <70AF>
+<DFD8> <70F1>
+<DFD9> <70AC>
+<DFDA> <70B8>
+<DFDB> <70B3>
+<DFDC> <70AE>
+<DFDD> <70DF>
+<DFDE> <70CB>
+<DFDF> <70DD>
+<DFE0> <70D9>
+<DFE1> <7109>
+<DFE2> <70FD>
+<DFE3> <711C>
+<DFE4> <7119>
+<DFE5> <7165>
+<DFE6> <7155>
+<DFE7> <7188>
+<DFE8> <7166>
+<DFE9> <7162>
+<DFEA> <714C>
+<DFEB> <7156>
+<DFEC> <716C>
+<DFED> <718F>
+<DFEE> <71FB>
+<DFEF> <7184>
+<DFF0> <7195>
+<DFF1> <71A8>
+<DFF2> <71AC>
+<DFF3> <71D7>
+<DFF4> <71B9>
+<DFF5> <71BE>
+<DFF6> <71D2>
+<DFF7> <71C9>
+<DFF8> <71D4>
+<DFF9> <71CE>
+<DFFA> <71E0>
+<DFFB> <71EC>
+<DFFC> <71E7>
+<DFFD> <71F5>
+<DFFE> <71FC>
+<E0A1> <71F9>
+<E0A2> <71FF>
+<E0A3> <720D>
+<E0A4> <7210>
+<E0A5> <721B>
+<E0A6> <7228>
+<E0A7> <722D>
+<E0A8> <722C>
+<E0A9> <7230>
+<E0AA> <7232>
+<E0AB> <723B>
+<E0AC> <723C>
+<E0AD> <723F>
+<E0AE> <7240>
+<E0AF> <7246>
+<E0B0> <724B>
+<E0B1> <7258>
+<E0B2> <7274>
+<E0B3> <727E>
+<E0B4> <7282>
+<E0B5> <7281>
+<E0B6> <7287>
+<E0B7> <7292>
+<E0B8> <7296>
+<E0B9> <72A2>
+<E0BA> <72A7>
+<E0BB> <72B9>
+<E0BC> <72B2>
+<E0BD> <72C3>
+<E0BE> <72C6>
+<E0BF> <72C4>
+<E0C0> <72CE>
+<E0C1> <72D2>
+<E0C2> <72E2>
+<E0C3> <72E0>
+<E0C4> <72E1>
+<E0C5> <72F9>
+<E0C6> <72F7>
+<E0C7> <500F>
+<E0C8> <7317>
+<E0C9> <730A>
+<E0CA> <731C>
+<E0CB> <7316>
+<E0CC> <731D>
+<E0CD> <7334>
+<E0CE> <732F>
+<E0CF> <7329>
+<E0D0> <7325>
+<E0D1> <733E>
+<E0D2> <734E>
+<E0D3> <734F>
+<E0D4> <9ED8>
+<E0D5> <7357>
+<E0D6> <736A>
+<E0D7> <7368>
+<E0D8> <7370>
+<E0D9> <7378>
+endbfchar
+
+100 beginbfchar
+<E0DA> <7375>
+<E0DB> <737B>
+<E0DC> <737A>
+<E0DD> <73C8>
+<E0DE> <73B3>
+<E0DF> <73CE>
+<E0E0> <73BB>
+<E0E1> <73C0>
+<E0E2> <73E5>
+<E0E3> <73EE>
+<E0E4> <73DE>
+<E0E5> <74A2>
+<E0E6> <7405>
+<E0E7> <746F>
+<E0E8> <7425>
+<E0E9> <73F8>
+<E0EA> <7432>
+<E0EB> <743A>
+<E0EC> <7455>
+<E0ED> <743F>
+<E0EE> <745F>
+<E0EF> <7459>
+<E0F0> <7441>
+<E0F1> <745C>
+<E0F2> <7469>
+<E0F3> <7470>
+<E0F4> <7463>
+<E0F5> <746A>
+<E0F6> <7476>
+<E0F7> <747E>
+<E0F8> <748B>
+<E0F9> <749E>
+<E0FA> <74A7>
+<E0FB> <74CA>
+<E0FC> <74CF>
+<E0FD> <74D4>
+<E0FE> <73F1>
+<E1A1> <74E0>
+<E1A2> <74E3>
+<E1A3> <74E7>
+<E1A4> <74E9>
+<E1A5> <74EE>
+<E1A6> <74F2>
+<E1A7> <74F0>
+<E1A8> <74F1>
+<E1A9> <74F8>
+<E1AA> <74F7>
+<E1AB> <7504>
+<E1AC> <7503>
+<E1AD> <7505>
+<E1AE> <750C>
+<E1AF> <750E>
+<E1B0> <750D>
+<E1B1> <7515>
+<E1B2> <7513>
+<E1B3> <751E>
+<E1B4> <7526>
+<E1B5> <752C>
+<E1B6> <753C>
+<E1B7> <7544>
+<E1B8> <754D>
+<E1B9> <754A>
+<E1BA> <7549>
+<E1BB> <755B>
+<E1BC> <7546>
+<E1BD> <755A>
+<E1BE> <7569>
+<E1BF> <7564>
+<E1C0> <7567>
+<E1C1> <756B>
+<E1C2> <756D>
+<E1C3> <7578>
+<E1C4> <7576>
+<E1C5> <7586>
+<E1C6> <7587>
+<E1C7> <7574>
+<E1C8> <758A>
+<E1C9> <7589>
+<E1CA> <7582>
+<E1CB> <7594>
+<E1CC> <759A>
+<E1CD> <759D>
+<E1CE> <75A5>
+<E1CF> <75A3>
+<E1D0> <75C2>
+<E1D1> <75B3>
+<E1D2> <75C3>
+<E1D3> <75B5>
+<E1D4> <75BD>
+<E1D5> <75B8>
+<E1D6> <75BC>
+<E1D7> <75B1>
+<E1D8> <75CD>
+<E1D9> <75CA>
+<E1DA> <75D2>
+<E1DB> <75D9>
+<E1DC> <75E3>
+<E1DD> <75DE>
+<E1DE> <75FE>
+<E1DF> <75FF>
+endbfchar
+
+100 beginbfchar
+<E1E0> <75FC>
+<E1E1> <7601>
+<E1E2> <75F0>
+<E1E3> <75FA>
+<E1E4> <75F2>
+<E1E5> <75F3>
+<E1E6> <760B>
+<E1E7> <760D>
+<E1E8> <7609>
+<E1E9> <761F>
+<E1EA> <7627>
+<E1EB> <7620>
+<E1EC> <7621>
+<E1ED> <7622>
+<E1EE> <7624>
+<E1EF> <7634>
+<E1F0> <7630>
+<E1F1> <763B>
+<E1F2> <7647>
+<E1F3> <7648>
+<E1F4> <7646>
+<E1F5> <765C>
+<E1F6> <7658>
+<E1F7> <7661>
+<E1F8> <7662>
+<E1F9> <7668>
+<E1FA> <7669>
+<E1FB> <766A>
+<E1FC> <7667>
+<E1FD> <766C>
+<E1FE> <7670>
+<E2A1> <7672>
+<E2A2> <7676>
+<E2A3> <7678>
+<E2A4> <767C>
+<E2A5> <7680>
+<E2A6> <7683>
+<E2A7> <7688>
+<E2A8> <768B>
+<E2A9> <768E>
+<E2AA> <7696>
+<E2AB> <7693>
+<E2AC> <7699>
+<E2AD> <769A>
+<E2AE> <76B0>
+<E2AF> <76B4>
+<E2B0> <76B8>
+<E2B1> <76B9>
+<E2B2> <76BA>
+<E2B3> <76C2>
+<E2B4> <76CD>
+<E2B5> <76D6>
+<E2B6> <76D2>
+<E2B7> <76DE>
+<E2B8> <76E1>
+<E2B9> <76E5>
+<E2BA> <76E7>
+<E2BB> <76EA>
+<E2BC> <862F>
+<E2BD> <76FB>
+<E2BE> <7708>
+<E2BF> <7707>
+<E2C0> <7704>
+<E2C1> <7729>
+<E2C2> <7724>
+<E2C3> <771E>
+<E2C4> <7725>
+<E2C5> <7726>
+<E2C6> <771B>
+<E2C7> <7737>
+<E2C8> <7738>
+<E2C9> <7747>
+<E2CA> <775A>
+<E2CB> <7768>
+<E2CC> <776B>
+<E2CD> <775B>
+<E2CE> <7765>
+<E2CF> <777F>
+<E2D0> <777E>
+<E2D1> <7779>
+<E2D2> <778E>
+<E2D3> <778B>
+<E2D4> <7791>
+<E2D5> <77A0>
+<E2D6> <779E>
+<E2D7> <77B0>
+<E2D8> <77B6>
+<E2D9> <77B9>
+<E2DA> <77BF>
+<E2DB> <77BC>
+<E2DC> <77BD>
+<E2DD> <77BB>
+<E2DE> <77C7>
+<E2DF> <77CD>
+<E2E0> <77D7>
+<E2E1> <77DA>
+<E2E2> <77DC>
+<E2E3> <77E3>
+<E2E4> <77EE>
+<E2E5> <77FC>
+endbfchar
+
+100 beginbfchar
+<E2E6> <780C>
+<E2E7> <7812>
+<E2E8> <7926>
+<E2E9> <7820>
+<E2EA> <792A>
+<E2EB> <7845>
+<E2EC> <788E>
+<E2ED> <7874>
+<E2EE> <7886>
+<E2EF> <787C>
+<E2F0> <789A>
+<E2F1> <788C>
+<E2F2> <78A3>
+<E2F3> <78B5>
+<E2F4> <78AA>
+<E2F5> <78AF>
+<E2F6> <78D1>
+<E2F7> <78C6>
+<E2F8> <78CB>
+<E2F9> <78D4>
+<E2FA> <78BE>
+<E2FB> <78BC>
+<E2FC> <78C5>
+<E2FD> <78CA>
+<E2FE> <78EC>
+<E3A1> <78E7>
+<E3A2> <78DA>
+<E3A3> <78FD>
+<E3A4> <78F4>
+<E3A5> <7907>
+<E3A6> <7912>
+<E3A7> <7911>
+<E3A8> <7919>
+<E3A9> <792C>
+<E3AA> <792B>
+<E3AB> <7940>
+<E3AC> <7960>
+<E3AD> <7957>
+<E3AE> <795F>
+<E3AF> <795A>
+<E3B0> <7955>
+<E3B1> <7953>
+<E3B2> <797A>
+<E3B3> <797F>
+<E3B4> <798A>
+<E3B5> <799D>
+<E3B6> <79A7>
+<E3B7> <9F4B>
+<E3B8> <79AA>
+<E3B9> <79AE>
+<E3BA> <79B3>
+<E3BB> <79B9>
+<E3BC> <79BA>
+<E3BD> <79C9>
+<E3BE> <79D5>
+<E3BF> <79E7>
+<E3C0> <79EC>
+<E3C1> <79E1>
+<E3C2> <79E3>
+<E3C3> <7A08>
+<E3C4> <7A0D>
+<E3C5> <7A18>
+<E3C6> <7A19>
+<E3C7> <7A20>
+<E3C8> <7A1F>
+<E3C9> <7980>
+<E3CA> <7A31>
+<E3CB> <7A3B>
+<E3CC> <7A3E>
+<E3CD> <7A37>
+<E3CE> <7A43>
+<E3CF> <7A57>
+<E3D0> <7A49>
+<E3D1> <7A61>
+<E3D2> <7A62>
+<E3D3> <7A69>
+<E3D4> <9F9D>
+<E3D5> <7A70>
+<E3D6> <7A79>
+<E3D7> <7A7D>
+<E3D8> <7A88>
+<E3D9> <7A97>
+<E3DA> <7A95>
+<E3DB> <7A98>
+<E3DC> <7A96>
+<E3DD> <7AA9>
+<E3DE> <7AC8>
+<E3DF> <7AB0>
+<E3E0> <7AB6>
+<E3E1> <7AC5>
+<E3E2> <7AC4>
+<E3E3> <7ABF>
+<E3E4> <9083>
+<E3E5> <7AC7>
+<E3E6> <7ACA>
+<E3E7> <7ACD>
+<E3E8> <7ACF>
+<E3E9> <7AD5>
+<E3EA> <7AD3>
+<E3EB> <7AD9>
+endbfchar
+
+100 beginbfchar
+<E3EC> <7ADA>
+<E3ED> <7ADD>
+<E3EE> <7AE1>
+<E3EF> <7AE2>
+<E3F0> <7AE6>
+<E3F1> <7AED>
+<E3F2> <7AF0>
+<E3F3> <7B02>
+<E3F4> <7B0F>
+<E3F5> <7B0A>
+<E3F6> <7B06>
+<E3F7> <7B33>
+<E3F8> <7B18>
+<E3F9> <7B19>
+<E3FA> <7B1E>
+<E3FB> <7B35>
+<E3FC> <7B28>
+<E3FD> <7B36>
+<E3FE> <7B50>
+<E4A1> <7B7A>
+<E4A2> <7B04>
+<E4A3> <7B4D>
+<E4A4> <7B0B>
+<E4A5> <7B4C>
+<E4A6> <7B45>
+<E4A7> <7B75>
+<E4A8> <7B65>
+<E4A9> <7B74>
+<E4AA> <7B67>
+<E4AB> <7B70>
+<E4AC> <7B71>
+<E4AD> <7B6C>
+<E4AE> <7B6E>
+<E4AF> <7B9D>
+<E4B0> <7B98>
+<E4B1> <7B9F>
+<E4B2> <7B8D>
+<E4B3> <7B9C>
+<E4B4> <7B9A>
+<E4B5> <7B8B>
+<E4B6> <7B92>
+<E4B7> <7B8F>
+<E4B8> <7B5D>
+<E4B9> <7B99>
+<E4BA> <7BCB>
+<E4BB> <7BC1>
+<E4BC> <7BCC>
+<E4BD> <7BCF>
+<E4BE> <7BB4>
+<E4BF> <7BC6>
+<E4C0> <7BDD>
+<E4C1> <7BE9>
+<E4C2> <7C11>
+<E4C3> <7C14>
+<E4C4> <7BE6>
+<E4C5> <7BE5>
+<E4C6> <7C60>
+<E4C7> <7C00>
+<E4C8> <7C07>
+<E4C9> <7C13>
+<E4CA> <7BF3>
+<E4CB> <7BF7>
+<E4CC> <7C17>
+<E4CD> <7C0D>
+<E4CE> <7BF6>
+<E4CF> <7C23>
+<E4D0> <7C27>
+<E4D1> <7C2A>
+<E4D2> <7C1F>
+<E4D3> <7C37>
+<E4D4> <7C2B>
+<E4D5> <7C3D>
+<E4D6> <7C4C>
+<E4D7> <7C43>
+<E4D8> <7C54>
+<E4D9> <7C4F>
+<E4DA> <7C40>
+<E4DB> <7C50>
+<E4DC> <7C58>
+<E4DD> <7C5F>
+<E4DE> <7C64>
+<E4DF> <7C56>
+<E4E0> <7C65>
+<E4E1> <7C6C>
+<E4E2> <7C75>
+<E4E3> <7C83>
+<E4E4> <7C90>
+<E4E5> <7CA4>
+<E4E6> <7CAD>
+<E4E7> <7CA2>
+<E4E8> <7CAB>
+<E4E9> <7CA1>
+<E4EA> <7CA8>
+<E4EB> <7CB3>
+<E4EC> <7CB2>
+<E4ED> <7CB1>
+<E4EE> <7CAE>
+<E4EF> <7CB9>
+<E4F0> <7CBD>
+<E4F1> <7CC0>
+endbfchar
+
+100 beginbfchar
+<E4F2> <7CC5>
+<E4F3> <7CC2>
+<E4F4> <7CD8>
+<E4F5> <7CD2>
+<E4F6> <7CDC>
+<E4F7> <7CE2>
+<E4F8> <9B3B>
+<E4F9> <7CEF>
+<E4FA> <7CF2>
+<E4FB> <7CF4>
+<E4FC> <7CF6>
+<E4FD> <7CFA>
+<E4FE> <7D06>
+<E5A1> <7D02>
+<E5A2> <7D1C>
+<E5A3> <7D15>
+<E5A4> <7D0A>
+<E5A5> <7D45>
+<E5A6> <7D4B>
+<E5A7> <7D2E>
+<E5A8> <7D32>
+<E5A9> <7D3F>
+<E5AA> <7D35>
+<E5AB> <7D46>
+<E5AC> <7D73>
+<E5AD> <7D56>
+<E5AE> <7D4E>
+<E5AF> <7D72>
+<E5B0> <7D68>
+<E5B1> <7D6E>
+<E5B2> <7D4F>
+<E5B3> <7D63>
+<E5B4> <7D93>
+<E5B5> <7D89>
+<E5B6> <7D5B>
+<E5B7> <7D8F>
+<E5B8> <7D7D>
+<E5B9> <7D9B>
+<E5BA> <7DBA>
+<E5BB> <7DAE>
+<E5BC> <7DA3>
+<E5BD> <7DB5>
+<E5BE> <7DC7>
+<E5BF> <7DBD>
+<E5C0> <7DAB>
+<E5C1> <7E3D>
+<E5C2> <7DA2>
+<E5C3> <7DAF>
+<E5C4> <7DDC>
+<E5C5> <7DB8>
+<E5C6> <7D9F>
+<E5C7> <7DB0>
+<E5C8> <7DD8>
+<E5C9> <7DDD>
+<E5CA> <7DE4>
+<E5CB> <7DDE>
+<E5CC> <7DFB>
+<E5CD> <7DF2>
+<E5CE> <7DE1>
+<E5CF> <7E05>
+<E5D0> <7E0A>
+<E5D1> <7E23>
+<E5D2> <7E21>
+<E5D3> <7E12>
+<E5D4> <7E31>
+<E5D5> <7E1F>
+<E5D6> <7E09>
+<E5D7> <7E0B>
+<E5D8> <7E22>
+<E5D9> <7E46>
+<E5DA> <7E66>
+<E5DB> <7E3B>
+<E5DC> <7E35>
+<E5DD> <7E39>
+<E5DE> <7E43>
+<E5DF> <7E37>
+<E5E0> <7E32>
+<E5E1> <7E3A>
+<E5E2> <7E67>
+<E5E3> <7E5D>
+<E5E4> <7E56>
+<E5E5> <7E5E>
+<E5E6> <7E59>
+<E5E7> <7E5A>
+<E5E8> <7E79>
+<E5E9> <7E6A>
+<E5EA> <7E69>
+<E5EB> <7E7C>
+<E5EC> <7E7B>
+<E5ED> <7E83>
+<E5EE> <7DD5>
+<E5EF> <7E7D>
+<E5F0> <8FAE>
+<E5F1> <7E7F>
+<E5F2> <7E88>
+<E5F3> <7E89>
+<E5F4> <7E8C>
+<E5F5> <7E92>
+<E5F6> <7E90>
+<E5F7> <7E93>
+endbfchar
+
+100 beginbfchar
+<E5F8> <7E94>
+<E5F9> <7E96>
+<E5FA> <7E8E>
+<E5FB> <7E9B>
+<E5FC> <7E9C>
+<E5FD> <7F38>
+<E5FE> <7F3A>
+<E6A1> <7F45>
+<E6A2> <7F4C>
+<E6A3> <7F4D>
+<E6A4> <7F4E>
+<E6A5> <7F50>
+<E6A6> <7F51>
+<E6A7> <7F55>
+<E6A8> <7F54>
+<E6A9> <7F58>
+<E6AA> <7F5F>
+<E6AB> <7F60>
+<E6AC> <7F68>
+<E6AD> <7F69>
+<E6AE> <7F67>
+<E6AF> <7F78>
+<E6B0> <7F82>
+<E6B1> <7F86>
+<E6B2> <7F83>
+<E6B3> <7F88>
+<E6B4> <7F87>
+<E6B5> <7F8C>
+<E6B6> <7F94>
+<E6B7> <7F9E>
+<E6B8> <7F9D>
+<E6B9> <7F9A>
+<E6BA> <7FA3>
+<E6BB> <7FAF>
+<E6BC> <7FB2>
+<E6BD> <7FB9>
+<E6BE> <7FAE>
+<E6BF> <7FB6>
+<E6C0> <7FB8>
+<E6C1> <8B71>
+<E6C2> <7FC5>
+<E6C3> <7FC6>
+<E6C4> <7FCA>
+<E6C5> <7FD5>
+<E6C6> <7FD4>
+<E6C7> <7FE1>
+<E6C8> <7FE6>
+<E6C9> <7FE9>
+<E6CA> <7FF3>
+<E6CB> <7FF9>
+<E6CC> <98DC>
+<E6CD> <8006>
+<E6CE> <8004>
+<E6CF> <800B>
+<E6D0> <8012>
+<E6D1> <8018>
+<E6D2> <8019>
+<E6D3> <801C>
+<E6D4> <8021>
+<E6D5> <8028>
+<E6D6> <803F>
+<E6D7> <803B>
+<E6D8> <804A>
+<E6D9> <8046>
+<E6DA> <8052>
+<E6DB> <8058>
+<E6DC> <805A>
+<E6DD> <805F>
+<E6DE> <8062>
+<E6DF> <8068>
+<E6E0> <8073>
+<E6E1> <8072>
+<E6E2> <8070>
+<E6E3> <8076>
+<E6E4> <8079>
+<E6E5> <807D>
+<E6E6> <807F>
+<E6E7> <8084>
+<E6E8> <8086>
+<E6E9> <8085>
+<E6EA> <809B>
+<E6EB> <8093>
+<E6EC> <809A>
+<E6ED> <80AD>
+<E6EE> <5190>
+<E6EF> <80AC>
+<E6F0> <80DB>
+<E6F1> <80E5>
+<E6F2> <80D9>
+<E6F3> <80DD>
+<E6F4> <80C4>
+<E6F5> <80DA>
+<E6F6> <80D6>
+<E6F7> <8109>
+<E6F8> <80EF>
+<E6F9> <80F1>
+<E6FA> <811B>
+<E6FB> <8129>
+<E6FC> <8123>
+<E6FD> <812F>
+endbfchar
+
+100 beginbfchar
+<E6FE> <814B>
+<E7A1> <968B>
+<E7A2> <8146>
+<E7A3> <813E>
+<E7A4> <8153>
+<E7A5> <8151>
+<E7A6> <80FC>
+<E7A7> <8171>
+<E7A8> <816E>
+<E7A9> <8165>
+<E7AA> <8166>
+<E7AB> <8174>
+<E7AC> <8183>
+<E7AD> <8188>
+<E7AE> <818A>
+<E7AF> <8180>
+<E7B0> <8182>
+<E7B1> <81A0>
+<E7B2> <8195>
+<E7B3> <81A4>
+<E7B4> <81A3>
+<E7B5> <815F>
+<E7B6> <8193>
+<E7B7> <81A9>
+<E7B8> <81B0>
+<E7B9> <81B5>
+<E7BA> <81BE>
+<E7BB> <81B8>
+<E7BC> <81BD>
+<E7BD> <81C0>
+<E7BE> <81C2>
+<E7BF> <81BA>
+<E7C0> <81C9>
+<E7C1> <81CD>
+<E7C2> <81D1>
+<E7C3> <81D9>
+<E7C4> <81D8>
+<E7C5> <81C8>
+<E7C6> <81DA>
+<E7C7> <81DF>
+<E7C8> <81E0>
+<E7C9> <81E7>
+<E7CA> <81FA>
+<E7CB> <81FB>
+<E7CC> <81FE>
+<E7CD> <8201>
+<E7CE> <8202>
+<E7CF> <8205>
+<E7D0> <8207>
+<E7D1> <820A>
+<E7D2> <820D>
+<E7D3> <8210>
+<E7D4> <8216>
+<E7D5> <8229>
+<E7D6> <822B>
+<E7D7> <8238>
+<E7D8> <8233>
+<E7D9> <8240>
+<E7DA> <8259>
+<E7DB> <8258>
+<E7DC> <825D>
+<E7DD> <825A>
+<E7DE> <825F>
+<E7DF> <8264>
+<E7E0> <8262>
+<E7E1> <8268>
+<E7E2> <826A>
+<E7E3> <826B>
+<E7E4> <822E>
+<E7E5> <8271>
+<E7E6> <8277>
+<E7E7> <8278>
+<E7E8> <827E>
+<E7E9> <828D>
+<E7EA> <8292>
+<E7EB> <82AB>
+<E7EC> <829F>
+<E7ED> <82BB>
+<E7EE> <82AC>
+<E7EF> <82E1>
+<E7F0> <82E3>
+<E7F1> <82DF>
+<E7F2> <82D2>
+<E7F3> <82F4>
+<E7F4> <82F3>
+<E7F5> <82FA>
+<E7F6> <8393>
+<E7F7> <8303>
+<E7F8> <82FB>
+<E7F9> <82F9>
+<E7FA> <82DE>
+<E7FB> <8306>
+<E7FC> <82DC>
+<E7FD> <8309>
+<E7FE> <82D9>
+<E8A1> <8335>
+<E8A2> <8334>
+<E8A3> <8316>
+<E8A4> <8332>
+<E8A5> <8331>
+endbfchar
+
+100 beginbfchar
+<E8A6> <8340>
+<E8A7> <8339>
+<E8A8> <8350>
+<E8A9> <8345>
+<E8AA> <832F>
+<E8AB> <832B>
+<E8AC> <8317>
+<E8AD> <8318>
+<E8AE> <8385>
+<E8AF> <839A>
+<E8B0> <83AA>
+<E8B1> <839F>
+<E8B2> <83A2>
+<E8B3> <8396>
+<E8B4> <8323>
+<E8B5> <838E>
+<E8B6> <8387>
+<E8B7> <838A>
+<E8B8> <837C>
+<E8B9> <83B5>
+<E8BA> <8373>
+<E8BB> <8375>
+<E8BC> <83A0>
+<E8BD> <8389>
+<E8BE> <83A8>
+<E8BF> <83F4>
+<E8C0> <8413>
+<E8C1> <83EB>
+<E8C2> <83CE>
+<E8C3> <83FD>
+<E8C4> <8403>
+<E8C5> <83D8>
+<E8C6> <840B>
+<E8C7> <83C1>
+<E8C8> <83F7>
+<E8C9> <8407>
+<E8CA> <83E0>
+<E8CB> <83F2>
+<E8CC> <840D>
+<E8CD> <8422>
+<E8CE> <8420>
+<E8CF> <83BD>
+<E8D0> <8438>
+<E8D1> <8506>
+<E8D2> <83FB>
+<E8D3> <846D>
+<E8D4> <842A>
+<E8D5> <843C>
+<E8D6> <855A>
+<E8D7> <8484>
+<E8D8> <8477>
+<E8D9> <846B>
+<E8DA> <84AD>
+<E8DB> <846E>
+<E8DC> <8482>
+<E8DD> <8469>
+<E8DE> <8446>
+<E8DF> <842C>
+<E8E0> <846F>
+<E8E1> <8479>
+<E8E2> <8435>
+<E8E3> <84CA>
+<E8E4> <8462>
+<E8E5> <84B9>
+<E8E6> <84BF>
+<E8E7> <849F>
+<E8E8> <84D9>
+<E8E9> <84CD>
+<E8EA> <84BB>
+<E8EB> <84DA>
+<E8EC> <84D0>
+<E8ED> <84C1>
+<E8EE> <84C6>
+<E8EF> <84D6>
+<E8F0> <84A1>
+<E8F1> <8521>
+<E8F2> <84FF>
+<E8F3> <84F4>
+<E8F4> <8517>
+<E8F5> <8518>
+<E8F6> <852C>
+<E8F7> <851F>
+<E8F8> <8515>
+<E8F9> <8514>
+<E8FA> <84FC>
+<E8FB> <8540>
+<E8FC> <8563>
+<E8FD> <8558>
+<E8FE> <8548>
+<E9A1> <8541>
+<E9A2> <8602>
+<E9A3> <854B>
+<E9A4> <8555>
+<E9A5> <8580>
+<E9A6> <85A4>
+<E9A7> <8588>
+<E9A8> <8591>
+<E9A9> <858A>
+<E9AA> <85A8>
+<E9AB> <856D>
+endbfchar
+
+100 beginbfchar
+<E9AC> <8594>
+<E9AD> <859B>
+<E9AE> <85EA>
+<E9AF> <8587>
+<E9B0> <859C>
+<E9B1> <8577>
+<E9B2> <857E>
+<E9B3> <8590>
+<E9B4> <85C9>
+<E9B5> <85BA>
+<E9B6> <85CF>
+<E9B7> <85B9>
+<E9B8> <85D0>
+<E9B9> <85D5>
+<E9BA> <85DD>
+<E9BB> <85E5>
+<E9BC> <85DC>
+<E9BD> <85F9>
+<E9BE> <860A>
+<E9BF> <8613>
+<E9C0> <860B>
+<E9C1> <85FE>
+<E9C2> <85FA>
+<E9C3> <8606>
+<E9C4> <8622>
+<E9C5> <861A>
+<E9C6> <8630>
+<E9C7> <863F>
+<E9C8> <864D>
+<E9C9> <4E55>
+<E9CA> <8654>
+<E9CB> <865F>
+<E9CC> <8667>
+<E9CD> <8671>
+<E9CE> <8693>
+<E9CF> <86A3>
+<E9D0> <86A9>
+<E9D1> <86AA>
+<E9D2> <868B>
+<E9D3> <868C>
+<E9D4> <86B6>
+<E9D5> <86AF>
+<E9D6> <86C4>
+<E9D7> <86C6>
+<E9D8> <86B0>
+<E9D9> <86C9>
+<E9DA> <8823>
+<E9DB> <86AB>
+<E9DC> <86D4>
+<E9DD> <86DE>
+<E9DE> <86E9>
+<E9DF> <86EC>
+<E9E0> <86DF>
+<E9E1> <86DB>
+<E9E2> <86EF>
+<E9E3> <8712>
+<E9E4> <8706>
+<E9E5> <8708>
+<E9E6> <8700>
+<E9E7> <8703>
+<E9E8> <86FB>
+<E9E9> <8711>
+<E9EA> <8709>
+<E9EB> <870D>
+<E9EC> <86F9>
+<E9ED> <870A>
+<E9EE> <8734>
+<E9EF> <873F>
+<E9F0> <8737>
+<E9F1> <873B>
+<E9F2> <8725>
+<E9F3> <8729>
+<E9F4> <871A>
+<E9F5> <8760>
+<E9F6> <875F>
+<E9F7> <8778>
+<E9F8> <874C>
+<E9F9> <874E>
+<E9FA> <8774>
+<E9FB> <8757>
+<E9FC> <8768>
+<E9FD> <876E>
+<E9FE> <8759>
+<EAA1> <8753>
+<EAA2> <8763>
+<EAA3> <876A>
+<EAA4> <8805>
+<EAA5> <87A2>
+<EAA6> <879F>
+<EAA7> <8782>
+<EAA8> <87AF>
+<EAA9> <87CB>
+<EAAA> <87BD>
+<EAAB> <87C0>
+<EAAC> <87D0>
+<EAAD> <96D6>
+<EAAE> <87AB>
+<EAAF> <87C4>
+<EAB0> <87B3>
+<EAB1> <87C7>
+endbfchar
+
+100 beginbfchar
+<EAB2> <87C6>
+<EAB3> <87BB>
+<EAB4> <87EF>
+<EAB5> <87F2>
+<EAB6> <87E0>
+<EAB7> <880F>
+<EAB8> <880D>
+<EAB9> <87FE>
+<EABA> <87F6>
+<EABB> <87F7>
+<EABC> <880E>
+<EABD> <87D2>
+<EABE> <8811>
+<EABF> <8816>
+<EAC0> <8815>
+<EAC1> <8822>
+<EAC2> <8821>
+<EAC3> <8831>
+<EAC4> <8836>
+<EAC5> <8839>
+<EAC6> <8827>
+<EAC7> <883B>
+<EAC8> <8844>
+<EAC9> <8842>
+<EACA> <8852>
+<EACB> <8859>
+<EACC> <885E>
+<EACD> <8862>
+<EACE> <886B>
+<EACF> <8881>
+<EAD0> <887E>
+<EAD1> <889E>
+<EAD2> <8875>
+<EAD3> <887D>
+<EAD4> <88B5>
+<EAD5> <8872>
+<EAD6> <8882>
+<EAD7> <8897>
+<EAD8> <8892>
+<EAD9> <88AE>
+<EADA> <8899>
+<EADB> <88A2>
+<EADC> <888D>
+<EADD> <88A4>
+<EADE> <88B0>
+<EADF> <88BF>
+<EAE0> <88B1>
+<EAE1> <88C3>
+<EAE2> <88C4>
+<EAE3> <88D4>
+<EAE4> <88D8>
+<EAE5> <88D9>
+<EAE6> <88DD>
+<EAE7> <88F9>
+<EAE8> <8902>
+<EAE9> <88FC>
+<EAEA> <88F4>
+<EAEB> <88E8>
+<EAEC> <88F2>
+<EAED> <8904>
+<EAEE> <890C>
+<EAEF> <890A>
+<EAF0> <8913>
+<EAF1> <8943>
+<EAF2> <891E>
+<EAF3> <8925>
+<EAF4> <892A>
+<EAF5> <892B>
+<EAF6> <8941>
+<EAF7> <8944>
+<EAF8> <893B>
+<EAF9> <8936>
+<EAFA> <8938>
+<EAFB> <894C>
+<EAFC> <891D>
+<EAFD> <8960>
+<EAFE> <895E>
+<EBA1> <8966>
+<EBA2> <8964>
+<EBA3> <896D>
+<EBA4> <896A>
+<EBA5> <896F>
+<EBA6> <8974>
+<EBA7> <8977>
+<EBA8> <897E>
+<EBA9> <8983>
+<EBAA> <8988>
+<EBAB> <898A>
+<EBAC> <8993>
+<EBAD> <8998>
+<EBAE> <89A1>
+<EBAF> <89A9>
+<EBB0> <89A6>
+<EBB1> <89AC>
+<EBB2> <89AF>
+<EBB3> <89B2>
+<EBB4> <89BA>
+<EBB5> <89BD>
+<EBB6> <89BF>
+<EBB7> <89C0>
+endbfchar
+
+100 beginbfchar
+<EBB8> <89DA>
+<EBB9> <89DC>
+<EBBA> <89DD>
+<EBBB> <89E7>
+<EBBC> <89F4>
+<EBBD> <89F8>
+<EBBE> <8A03>
+<EBBF> <8A16>
+<EBC0> <8A10>
+<EBC1> <8A0C>
+<EBC2> <8A1B>
+<EBC3> <8A1D>
+<EBC4> <8A25>
+<EBC5> <8A36>
+<EBC6> <8A41>
+<EBC7> <8A5B>
+<EBC8> <8A52>
+<EBC9> <8A46>
+<EBCA> <8A48>
+<EBCB> <8A7C>
+<EBCC> <8A6D>
+<EBCD> <8A6C>
+<EBCE> <8A62>
+<EBCF> <8A85>
+<EBD0> <8A82>
+<EBD1> <8A84>
+<EBD2> <8AA8>
+<EBD3> <8AA1>
+<EBD4> <8A91>
+<EBD5> <8AA5>
+<EBD6> <8AA6>
+<EBD7> <8A9A>
+<EBD8> <8AA3>
+<EBD9> <8AC4>
+<EBDA> <8ACD>
+<EBDB> <8AC2>
+<EBDC> <8ADA>
+<EBDD> <8AEB>
+<EBDE> <8AF3>
+<EBDF> <8AE7>
+<EBE0> <8AE4>
+<EBE1> <8AF1>
+<EBE2> <8B14>
+<EBE3> <8AE0>
+<EBE4> <8AE2>
+<EBE5> <8AF7>
+<EBE6> <8ADE>
+<EBE7> <8ADB>
+<EBE8> <8B0C>
+<EBE9> <8B07>
+<EBEA> <8B1A>
+<EBEB> <8AE1>
+<EBEC> <8B16>
+<EBED> <8B10>
+<EBEE> <8B17>
+<EBEF> <8B20>
+<EBF0> <8B33>
+<EBF1> <97AB>
+<EBF2> <8B26>
+<EBF3> <8B2B>
+<EBF4> <8B3E>
+<EBF5> <8B28>
+<EBF6> <8B41>
+<EBF7> <8B4C>
+<EBF8> <8B4F>
+<EBF9> <8B4E>
+<EBFA> <8B49>
+<EBFB> <8B56>
+<EBFC> <8B5B>
+<EBFD> <8B5A>
+<EBFE> <8B6B>
+<ECA1> <8B5F>
+<ECA2> <8B6C>
+<ECA3> <8B6F>
+<ECA4> <8B74>
+<ECA5> <8B7D>
+<ECA6> <8B80>
+<ECA7> <8B8C>
+<ECA8> <8B8E>
+<ECA9> <8B92>
+<ECAA> <8B93>
+<ECAB> <8B96>
+<ECAC> <8B99>
+<ECAD> <8B9A>
+<ECAE> <8C3A>
+<ECAF> <8C41>
+<ECB0> <8C3F>
+<ECB1> <8C48>
+<ECB2> <8C4C>
+<ECB3> <8C4E>
+<ECB4> <8C50>
+<ECB5> <8C55>
+<ECB6> <8C62>
+<ECB7> <8C6C>
+<ECB8> <8C78>
+<ECB9> <8C7A>
+<ECBA> <8C82>
+<ECBB> <8C89>
+<ECBC> <8C85>
+<ECBD> <8C8A>
+endbfchar
+
+100 beginbfchar
+<ECBE> <8C8D>
+<ECBF> <8C8E>
+<ECC0> <8C94>
+<ECC1> <8C7C>
+<ECC2> <8C98>
+<ECC3> <621D>
+<ECC4> <8CAD>
+<ECC5> <8CAA>
+<ECC6> <8CBD>
+<ECC7> <8CB2>
+<ECC8> <8CB3>
+<ECC9> <8CAE>
+<ECCA> <8CB6>
+<ECCB> <8CC8>
+<ECCC> <8CC1>
+<ECCD> <8CE4>
+<ECCE> <8CE3>
+<ECCF> <8CDA>
+<ECD0> <8CFD>
+<ECD1> <8CFA>
+<ECD2> <8CFB>
+<ECD3> <8D04>
+<ECD4> <8D05>
+<ECD5> <8D0A>
+<ECD6> <8D07>
+<ECD7> <8D0F>
+<ECD8> <8D0D>
+<ECD9> <8D10>
+<ECDA> <9F4E>
+<ECDB> <8D13>
+<ECDC> <8CCD>
+<ECDD> <8D14>
+<ECDE> <8D16>
+<ECDF> <8D67>
+<ECE0> <8D6D>
+<ECE1> <8D71>
+<ECE2> <8D73>
+<ECE3> <8D81>
+<ECE4> <8D99>
+<ECE5> <8DC2>
+<ECE6> <8DBE>
+<ECE7> <8DBA>
+<ECE8> <8DCF>
+<ECE9> <8DDA>
+<ECEA> <8DD6>
+<ECEB> <8DCC>
+<ECEC> <8DDB>
+<ECED> <8DCB>
+<ECEE> <8DEA>
+<ECEF> <8DEB>
+<ECF0> <8DDF>
+<ECF1> <8DE3>
+<ECF2> <8DFC>
+<ECF3> <8E08>
+<ECF4> <8E09>
+<ECF5> <8DFF>
+<ECF6> <8E1D>
+<ECF7> <8E1E>
+<ECF8> <8E10>
+<ECF9> <8E1F>
+<ECFA> <8E42>
+<ECFB> <8E35>
+<ECFC> <8E30>
+<ECFD> <8E34>
+<ECFE> <8E4A>
+<EDA1> <8E47>
+<EDA2> <8E49>
+<EDA3> <8E4C>
+<EDA4> <8E50>
+<EDA5> <8E48>
+<EDA6> <8E59>
+<EDA7> <8E64>
+<EDA8> <8E60>
+<EDA9> <8E2A>
+<EDAA> <8E63>
+<EDAB> <8E55>
+<EDAC> <8E76>
+<EDAD> <8E72>
+<EDAE> <8E7C>
+<EDAF> <8E81>
+<EDB0> <8E87>
+<EDB1> <8E85>
+<EDB2> <8E84>
+<EDB3> <8E8B>
+<EDB4> <8E8A>
+<EDB5> <8E93>
+<EDB6> <8E91>
+<EDB7> <8E94>
+<EDB8> <8E99>
+<EDB9> <8EAA>
+<EDBA> <8EA1>
+<EDBB> <8EAC>
+<EDBC> <8EB0>
+<EDBD> <8EC6>
+<EDBE> <8EB1>
+<EDBF> <8EBE>
+<EDC0> <8EC5>
+<EDC1> <8EC8>
+<EDC2> <8ECB>
+<EDC3> <8EDB>
+endbfchar
+
+100 beginbfchar
+<EDC4> <8EE3>
+<EDC5> <8EFC>
+<EDC6> <8EFB>
+<EDC7> <8EEB>
+<EDC8> <8EFE>
+<EDC9> <8F0A>
+<EDCA> <8F05>
+<EDCB> <8F15>
+<EDCC> <8F12>
+<EDCD> <8F19>
+<EDCE> <8F13>
+<EDCF> <8F1C>
+<EDD0> <8F1F>
+<EDD1> <8F1B>
+<EDD2> <8F0C>
+<EDD3> <8F26>
+<EDD4> <8F33>
+<EDD5> <8F3B>
+<EDD6> <8F39>
+<EDD7> <8F45>
+<EDD8> <8F42>
+<EDD9> <8F3E>
+<EDDA> <8F4C>
+<EDDB> <8F49>
+<EDDC> <8F46>
+<EDDD> <8F4E>
+<EDDE> <8F57>
+<EDDF> <8F5C>
+<EDE0> <8F62>
+<EDE1> <8F63>
+<EDE2> <8F64>
+<EDE3> <8F9C>
+<EDE4> <8F9F>
+<EDE5> <8FA3>
+<EDE6> <8FAD>
+<EDE7> <8FAF>
+<EDE8> <8FB7>
+<EDE9> <8FDA>
+<EDEA> <8FE5>
+<EDEB> <8FE2>
+<EDEC> <8FEA>
+<EDED> <8FEF>
+<EDEE> <9087>
+<EDEF> <8FF4>
+<EDF0> <9005>
+<EDF1> <8FF9>
+<EDF2> <8FFA>
+<EDF3> <9011>
+<EDF4> <9015>
+<EDF5> <9021>
+<EDF6> <900D>
+<EDF7> <901E>
+<EDF8> <9016>
+<EDF9> <900B>
+<EDFA> <9027>
+<EDFB> <9036>
+<EDFC> <9035>
+<EDFD> <9039>
+<EDFE> <8FF8>
+<EEA1> <904F>
+<EEA2> <9050>
+<EEA3> <9051>
+<EEA4> <9052>
+<EEA5> <900E>
+<EEA6> <9049>
+<EEA7> <903E>
+<EEA8> <9056>
+<EEA9> <9058>
+<EEAA> <905E>
+<EEAB> <9068>
+<EEAC> <906F>
+<EEAD> <9076>
+<EEAE> <96A8>
+<EEAF> <9072>
+<EEB0> <9082>
+<EEB1> <907D>
+<EEB2> <9081>
+<EEB3> <9080>
+<EEB4> <908A>
+<EEB5> <9089>
+<EEB6> <908F>
+<EEB7> <90A8>
+<EEB8> <90AF>
+<EEB9> <90B1>
+<EEBA> <90B5>
+<EEBB> <90E2>
+<EEBC> <90E4>
+<EEBD> <6248>
+<EEBE> <90DB>
+<EEBF> <9102>
+<EEC0> <9112>
+<EEC1> <9119>
+<EEC2> <9132>
+<EEC3> <9130>
+<EEC4> <914A>
+<EEC5> <9156>
+<EEC6> <9158>
+<EEC7> <9163>
+<EEC8> <9165>
+<EEC9> <9169>
+endbfchar
+
+100 beginbfchar
+<EECA> <9173>
+<EECB> <9172>
+<EECC> <918B>
+<EECD> <9189>
+<EECE> <9182>
+<EECF> <91A2>
+<EED0> <91AB>
+<EED1> <91AF>
+<EED2> <91AA>
+<EED3> <91B5>
+<EED4> <91B4>
+<EED5> <91BA>
+<EED6> <91C0>
+<EED7> <91C1>
+<EED8> <91C9>
+<EED9> <91CB>
+<EEDA> <91D0>
+<EEDB> <91D6>
+<EEDC> <91DF>
+<EEDD> <91E1>
+<EEDE> <91DB>
+<EEDF> <91FC>
+<EEE0> <91F5>
+<EEE1> <91F6>
+<EEE2> <921E>
+<EEE3> <91FF>
+<EEE4> <9214>
+<EEE5> <922C>
+<EEE6> <9215>
+<EEE7> <9211>
+<EEE8> <925E>
+<EEE9> <9257>
+<EEEA> <9245>
+<EEEB> <9249>
+<EEEC> <9264>
+<EEED> <9248>
+<EEEE> <9295>
+<EEEF> <923F>
+<EEF0> <924B>
+<EEF1> <9250>
+<EEF2> <929C>
+<EEF3> <9296>
+<EEF4> <9293>
+<EEF5> <929B>
+<EEF6> <925A>
+<EEF7> <92CF>
+<EEF8> <92B9>
+<EEF9> <92B7>
+<EEFA> <92E9>
+<EEFB> <930F>
+<EEFC> <92FA>
+<EEFD> <9344>
+<EEFE> <932E>
+<EFA1> <9319>
+<EFA2> <9322>
+<EFA3> <931A>
+<EFA4> <9323>
+<EFA5> <933A>
+<EFA6> <9335>
+<EFA7> <933B>
+<EFA8> <935C>
+<EFA9> <9360>
+<EFAA> <937C>
+<EFAB> <936E>
+<EFAC> <9356>
+<EFAD> <93B0>
+<EFAE> <93AC>
+<EFAF> <93AD>
+<EFB0> <9394>
+<EFB1> <93B9>
+<EFB2> <93D6>
+<EFB3> <93D7>
+<EFB4> <93E8>
+<EFB5> <93E5>
+<EFB6> <93D8>
+<EFB7> <93C3>
+<EFB8> <93DD>
+<EFB9> <93D0>
+<EFBA> <93C8>
+<EFBB> <93E4>
+<EFBC> <941A>
+<EFBD> <9414>
+<EFBE> <9413>
+<EFBF> <9403>
+<EFC0> <9407>
+<EFC1> <9410>
+<EFC2> <9436>
+<EFC3> <942B>
+<EFC4> <9435>
+<EFC5> <9421>
+<EFC6> <943A>
+<EFC7> <9441>
+<EFC8> <9452>
+<EFC9> <9444>
+<EFCA> <945B>
+<EFCB> <9460>
+<EFCC> <9462>
+<EFCD> <945E>
+<EFCE> <946A>
+<EFCF> <9229>
+endbfchar
+
+100 beginbfchar
+<EFD0> <9470>
+<EFD1> <9475>
+<EFD2> <9477>
+<EFD3> <947D>
+<EFD4> <945A>
+<EFD5> <947C>
+<EFD6> <947E>
+<EFD7> <9481>
+<EFD8> <947F>
+<EFD9> <9582>
+<EFDA> <9587>
+<EFDB> <958A>
+<EFDC> <9594>
+<EFDD> <9596>
+<EFDE> <9598>
+<EFDF> <9599>
+<EFE0> <95A0>
+<EFE1> <95A8>
+<EFE2> <95A7>
+<EFE3> <95AD>
+<EFE4> <95BC>
+<EFE5> <95BB>
+<EFE6> <95B9>
+<EFE7> <95BE>
+<EFE8> <95CA>
+<EFE9> <6FF6>
+<EFEA> <95C3>
+<EFEB> <95CD>
+<EFEC> <95CC>
+<EFED> <95D5>
+<EFEE> <95D4>
+<EFEF> <95D6>
+<EFF0> <95DC>
+<EFF1> <95E1>
+<EFF2> <95E5>
+<EFF3> <95E2>
+<EFF4> <9621>
+<EFF5> <9628>
+<EFF6> <962E>
+<EFF7> <962F>
+<EFF8> <9642>
+<EFF9> <964C>
+<EFFA> <964F>
+<EFFB> <964B>
+<EFFC> <9677>
+<EFFD> <965C>
+<EFFE> <965E>
+<F0A1> <965D>
+<F0A2> <965F>
+<F0A3> <9666>
+<F0A4> <9672>
+<F0A5> <966C>
+<F0A6> <968D>
+<F0A7> <9698>
+<F0A8> <9695>
+<F0A9> <9697>
+<F0AA> <96AA>
+<F0AB> <96A7>
+<F0AC> <96B1>
+<F0AD> <96B2>
+<F0AE> <96B0>
+<F0AF> <96B4>
+<F0B0> <96B6>
+<F0B1> <96B8>
+<F0B2> <96B9>
+<F0B3> <96CE>
+<F0B4> <96CB>
+<F0B5> <96C9>
+<F0B6> <96CD>
+<F0B7> <894D>
+<F0B8> <96DC>
+<F0B9> <970D>
+<F0BA> <96D5>
+<F0BB> <96F9>
+<F0BC> <9704>
+<F0BD> <9706>
+<F0BE> <9708>
+<F0BF> <9713>
+<F0C0> <970E>
+<F0C1> <9711>
+<F0C2> <970F>
+<F0C3> <9716>
+<F0C4> <9719>
+<F0C5> <9724>
+<F0C6> <972A>
+<F0C7> <9730>
+<F0C8> <9739>
+<F0C9> <973D>
+<F0CA> <973E>
+<F0CB> <9744>
+<F0CC> <9746>
+<F0CD> <9748>
+<F0CE> <9742>
+<F0CF> <9749>
+<F0D0> <975C>
+<F0D1> <9760>
+<F0D2> <9764>
+<F0D3> <9766>
+<F0D4> <9768>
+<F0D5> <52D2>
+endbfchar
+
+100 beginbfchar
+<F0D6> <976B>
+<F0D7> <9771>
+<F0D8> <9779>
+<F0D9> <9785>
+<F0DA> <977C>
+<F0DB> <9781>
+<F0DC> <977A>
+<F0DD> <9786>
+<F0DE> <978B>
+<F0DF> <978F>
+<F0E0> <9790>
+<F0E1> <979C>
+<F0E2> <97A8>
+<F0E3> <97A6>
+<F0E4> <97A3>
+<F0E5> <97B3>
+<F0E6> <97B4>
+<F0E7> <97C3>
+<F0E8> <97C6>
+<F0E9> <97C8>
+<F0EA> <97CB>
+<F0EB> <97DC>
+<F0EC> <97ED>
+<F0ED> <9F4F>
+<F0EE> <97F2>
+<F0EF> <7ADF>
+<F0F0> <97F6>
+<F0F1> <97F5>
+<F0F2> <980F>
+<F0F3> <980C>
+<F0F4> <9838>
+<F0F5> <9824>
+<F0F6> <9821>
+<F0F7> <9837>
+<F0F8> <983D>
+<F0F9> <9846>
+<F0FA> <984F>
+<F0FB> <984B>
+<F0FC> <986B>
+<F0FD> <986F>
+<F0FE> <9870>
+<F1A1> <9871>
+<F1A2> <9874>
+<F1A3> <9873>
+<F1A4> <98AA>
+<F1A5> <98AF>
+<F1A6> <98B1>
+<F1A7> <98B6>
+<F1A8> <98C4>
+<F1A9> <98C3>
+<F1AA> <98C6>
+<F1AB> <98E9>
+<F1AC> <98EB>
+<F1AD> <9903>
+<F1AE> <9909>
+<F1AF> <9912>
+<F1B0> <9914>
+<F1B1> <9918>
+<F1B2> <9921>
+<F1B3> <991D>
+<F1B4> <991E>
+<F1B5> <9924>
+<F1B6> <9920>
+<F1B7> <992C>
+<F1B8> <992E>
+<F1B9> <993D>
+<F1BA> <993E>
+<F1BB> <9942>
+<F1BC> <9949>
+<F1BD> <9945>
+<F1BE> <9950>
+<F1BF> <994B>
+<F1C0> <9951>
+<F1C1> <9952>
+<F1C2> <994C>
+<F1C3> <9955>
+<F1C4> <9997>
+<F1C5> <9998>
+<F1C6> <99A5>
+<F1C7> <99AD>
+<F1C8> <99AE>
+<F1C9> <99BC>
+<F1CA> <99DF>
+<F1CB> <99DB>
+<F1CC> <99DD>
+<F1CD> <99D8>
+<F1CE> <99D1>
+<F1CF> <99ED>
+<F1D0> <99EE>
+<F1D1> <99F1>
+<F1D2> <99F2>
+<F1D3> <99FB>
+<F1D4> <99F8>
+<F1D5> <9A01>
+<F1D6> <9A0F>
+<F1D7> <9A05>
+<F1D8> <99E2>
+<F1D9> <9A19>
+<F1DA> <9A2B>
+<F1DB> <9A37>
+endbfchar
+
+100 beginbfchar
+<F1DC> <9A45>
+<F1DD> <9A42>
+<F1DE> <9A40>
+<F1DF> <9A43>
+<F1E0> <9A3E>
+<F1E1> <9A55>
+<F1E2> <9A4D>
+<F1E3> <9A5B>
+<F1E4> <9A57>
+<F1E5> <9A5F>
+<F1E6> <9A62>
+<F1E7> <9A65>
+<F1E8> <9A64>
+<F1E9> <9A69>
+<F1EA> <9A6B>
+<F1EB> <9A6A>
+<F1EC> <9AAD>
+<F1ED> <9AB0>
+<F1EE> <9ABC>
+<F1EF> <9AC0>
+<F1F0> <9ACF>
+<F1F1> <9AD1>
+<F1F2> <9AD3>
+<F1F3> <9AD4>
+<F1F4> <9ADE>
+<F1F5> <9ADF>
+<F1F6> <9AE2>
+<F1F7> <9AE3>
+<F1F8> <9AE6>
+<F1F9> <9AEF>
+<F1FA> <9AEB>
+<F1FB> <9AEE>
+<F1FC> <9AF4>
+<F1FD> <9AF1>
+<F1FE> <9AF7>
+<F2A1> <9AFB>
+<F2A2> <9B06>
+<F2A3> <9B18>
+<F2A4> <9B1A>
+<F2A5> <9B1F>
+<F2A6> <9B22>
+<F2A7> <9B23>
+<F2A8> <9B25>
+<F2A9> <9B27>
+<F2AA> <9B28>
+<F2AB> <9B29>
+<F2AC> <9B2A>
+<F2AD> <9B2E>
+<F2AE> <9B2F>
+<F2AF> <9B32>
+<F2B0> <9B44>
+<F2B1> <9B43>
+<F2B2> <9B4F>
+<F2B3> <9B4D>
+<F2B4> <9B4E>
+<F2B5> <9B51>
+<F2B6> <9B58>
+<F2B7> <9B74>
+<F2B8> <9B93>
+<F2B9> <9B83>
+<F2BA> <9B91>
+<F2BB> <9B96>
+<F2BC> <9B97>
+<F2BD> <9B9F>
+<F2BE> <9BA0>
+<F2BF> <9BA8>
+<F2C0> <9BB4>
+<F2C1> <9BC0>
+<F2C2> <9BCA>
+<F2C3> <9BB9>
+<F2C4> <9BC6>
+<F2C5> <9BCF>
+<F2C6> <9BD1>
+<F2C7> <9BD2>
+<F2C8> <9BE3>
+<F2C9> <9BE2>
+<F2CA> <9BE4>
+<F2CB> <9BD4>
+<F2CC> <9BE1>
+<F2CD> <9C3A>
+<F2CE> <9BF2>
+<F2CF> <9BF1>
+<F2D0> <9BF0>
+<F2D1> <9C15>
+<F2D2> <9C14>
+<F2D3> <9C09>
+<F2D4> <9C13>
+<F2D5> <9C0C>
+<F2D6> <9C06>
+<F2D7> <9C08>
+<F2D8> <9C12>
+<F2D9> <9C0A>
+<F2DA> <9C04>
+<F2DB> <9C2E>
+<F2DC> <9C1B>
+<F2DD> <9C25>
+<F2DE> <9C24>
+<F2DF> <9C21>
+<F2E0> <9C30>
+<F2E1> <9C47>
+endbfchar
+
+100 beginbfchar
+<F2E2> <9C32>
+<F2E3> <9C46>
+<F2E4> <9C3E>
+<F2E5> <9C5A>
+<F2E6> <9C60>
+<F2E7> <9C67>
+<F2E8> <9C76>
+<F2E9> <9C78>
+<F2EA> <9CE7>
+<F2EB> <9CEC>
+<F2EC> <9CF0>
+<F2ED> <9D09>
+<F2EE> <9D08>
+<F2EF> <9CEB>
+<F2F0> <9D03>
+<F2F1> <9D06>
+<F2F2> <9D2A>
+<F2F3> <9D26>
+<F2F4> <9DAF>
+<F2F5> <9D23>
+<F2F6> <9D1F>
+<F2F7> <9D44>
+<F2F8> <9D15>
+<F2F9> <9D12>
+<F2FA> <9D41>
+<F2FB> <9D3F>
+<F2FC> <9D3E>
+<F2FD> <9D46>
+<F2FE> <9D48>
+<F3A1> <9D5D>
+<F3A2> <9D5E>
+<F3A3> <9D64>
+<F3A4> <9D51>
+<F3A5> <9D50>
+<F3A6> <9D59>
+<F3A7> <9D72>
+<F3A8> <9D89>
+<F3A9> <9D87>
+<F3AA> <9DAB>
+<F3AB> <9D6F>
+<F3AC> <9D7A>
+<F3AD> <9D9A>
+<F3AE> <9DA4>
+<F3AF> <9DA9>
+<F3B0> <9DB2>
+<F3B1> <9DC4>
+<F3B2> <9DC1>
+<F3B3> <9DBB>
+<F3B4> <9DB8>
+<F3B5> <9DBA>
+<F3B6> <9DC6>
+<F3B7> <9DCF>
+<F3B8> <9DC2>
+<F3B9> <9DD9>
+<F3BA> <9DD3>
+<F3BB> <9DF8>
+<F3BC> <9DE6>
+<F3BD> <9DED>
+<F3BE> <9DEF>
+<F3BF> <9DFD>
+<F3C0> <9E1A>
+<F3C1> <9E1B>
+<F3C2> <9E1E>
+<F3C3> <9E75>
+<F3C4> <9E79>
+<F3C5> <9E7D>
+<F3C6> <9E81>
+<F3C7> <9E88>
+<F3C8> <9E8B>
+<F3C9> <9E8C>
+<F3CA> <9E92>
+<F3CB> <9E95>
+<F3CC> <9E91>
+<F3CD> <9E9D>
+<F3CE> <9EA5>
+<F3CF> <9EA9>
+<F3D0> <9EB8>
+<F3D1> <9EAA>
+<F3D2> <9EAD>
+<F3D3> <9761>
+<F3D4> <9ECC>
+<F3D5> <9ECE>
+<F3D6> <9ECF>
+<F3D7> <9ED0>
+<F3D8> <9ED4>
+<F3D9> <9EDC>
+<F3DA> <9EDE>
+<F3DB> <9EDD>
+<F3DC> <9EE0>
+<F3DD> <9EE5>
+<F3DE> <9EE8>
+<F3DF> <9EEF>
+<F3E0> <9EF4>
+<F3E1> <9EF6>
+<F3E2> <9EF7>
+<F3E3> <9EF9>
+<F3E4> <9EFB>
+<F3E5> <9EFC>
+<F3E6> <9EFD>
+<F3E7> <9F07>
+endbfchar
+
+29 beginbfchar
+<F3E8> <9F08>
+<F3E9> <76B7>
+<F3EA> <9F15>
+<F3EB> <9F21>
+<F3EC> <9F2C>
+<F3ED> <9F3E>
+<F3EE> <9F4A>
+<F3EF> <9F52>
+<F3F0> <9F54>
+<F3F1> <9F63>
+<F3F2> <9F5F>
+<F3F3> <9F60>
+<F3F4> <9F61>
+<F3F5> <9F66>
+<F3F6> <9F67>
+<F3F7> <9F6C>
+<F3F8> <9F6A>
+<F3F9> <9F77>
+<F3FA> <9F72>
+<F3FB> <9F76>
+<F3FC> <9F95>
+<F3FD> <9F9C>
+<F3FE> <9FA0>
+<F4A1> <582F>
+<F4A2> <69C7>
+<F4A3> <9059>
+<F4A4> <7464>
+<F4A5> <51DC>
+<F4A6> <7199>
+endbfchar
+
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+
+%%EndResource
+%%EOF
diff --git a/Build/source/texk/dvipdfm-x/data/cid-x.map b/Build/source/texk/dvipdfm-x/data/cid-x.map
new file mode 100644
index 00000000000..40f45d540ff
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/data/cid-x.map
@@ -0,0 +1,152 @@
+%% This file 'cid-x.map' is read by dvipdfmx for default
+%% dvipdfmx.cfg setting. Please append fontmap entries here.
+%%
+%% FONTMAP: CID-keyed font mapping file for dvipdfmx
+%% =================================================
+%%
+%% Last modified: April 4, 2004
+%%
+%% FORMAT
+%% ------
+%%
+%% TFMNAME[@SFDNAME@] ENCNAME|CMapNAME [:INDEX:][!]FONTNAME[/CSI][,VARIANT] [OPTIONS]
+%%
+%%
+%% DESCRIPTION
+%% -----------
+%%
+%% 1) TFMNAME[@SFDNAME@]
+%%
+%% TFMNAME is a name of TeX fonts in usual if no SFDNAME is attached.
+%% Otherwise, TFMNAME is the basename of TeX fonts, for example,
+%% cyberb@Unicode@ expands to cyberb00 -- cyberbff, where Unicode.sfd
+%% contains subfont definitions with name from 00 to ff.
+%% Moreover, both TFMNAME and SFDNAME do not contain file extensions.
+%%
+%% 2) ENCNAME|CMapNAME
+%%
+%% ENCNAME is the name of an 8-bit encoding file, e.g., 8r.enc.
+%% CMapNAME is the name of a CMap file which is used as a 16-bit
+%% encoding file. In particular, if UCS2 (2-byte Unicode) is used
+%% as a 16-bit encoding, it suffices to set CMapNAME to unicode
+%% even if no corresponding CMap file exists.
+%%
+%% 3) [:INDEX:][!]FONTNAME[/CSI][,VARIANT]
+%%
+%% Font name is specified in the field FONTNAME with or without
+%% extension. The field INDEX is used for TrueType collections (.ttc)
+%% to specify the font index number. The character `!' enables the
+%% no-embedding option. The /CSI option is required for TrueType fonts
+%% when Identity CMap is specified in the ENCNAME. The stylistic variants
+%% (Bold, Italic, BoldItalic) are specified in the filed VARIANT.
+%% See examples below.
+%%
+%% 4) [OPTIONS]
+%%
+%% All options available in the original dvipdfm are also valid here.
+%% The remap option [-r] is simply ignored.
+
+%%
+%% Omega Examples
+%%
+
+%% Chinese
+%% Arphic TrueType fonts as Adobe-{CNS1,GB1} CID-keyed font.
+%ombkai UniCNS-UCS2-H bkai00mp
+%ombsmi UniCNS-UCS2-H bsmi00lp
+%omgkai UniGB-UCS2-H gkai00mp
+%omgbsn UniGB-UCS2-H gbsn00lp
+
+%% Japanese
+%% Adobe-Japan1
+omrml UniJIS-UCS2-H Ryumin-Light
+omgbm UniJIS-UCS2-H GothicBBB-Medium
+
+%% Korean
+%omgtm UniKS-UCS2-H HYGoThic-Medium
+%ombtr UniKS-UCS2-H batang
+
+%%
+%% ASCII pTeX Examples
+%%
+
+%% Ryumin and GothicBBB found in PostScript printers:
+rml H Ryumin-Light
+gbm H GothicBBB-Medium
+rmlv V Ryumin-Light
+gbmv V GothicBBB-Medium
+
+rml-jis H Ryumin-Light
+gbm-jis H GothicBBB-Medium
+
+%% Synthetic font used for futo* family.
+%% jun101 not available.
+%ryumin-l H Ryumin-Light
+%gtbbb-m H GothicBBB-Medium
+%futomin-b H Ryumin-Light,Bold
+%futogo-b H GothicBBB-Medium,Bold
+%ryumin-l-v V Ryumin-Light
+%gtbbb-m-v V GothicBBB-Medium
+%futomin-b-v V Ryumin-Light,Bold
+%futogo-b-v V GothicBBB-Medium,Bold
+
+%% Morisawa OpenType Basic 7 Family Pack
+%%
+%ryumin-l H A-OTF-RyuminPro-Light
+%ryumin-l-v V A-OTF-RyuminPro-Light
+%gtbbb-m H A-OTF-GothicBBBPro-Medium
+%gtbbb-m-v V A-OTF-GothicBBBPro-Medium
+%futomin-b H A-OTF-FutoMinA101Pro-Bold
+%futomin-b-v V A-OTF-FutoMinA101Pro-Bold
+%futogo-b H A-OTF-FutoGoB101Pro-Bold
+%futogo-b-v V A-OTF-FutoGoB101Pro-Bold
+%jun101-l H A-OTF-Jun101Pro-Light
+%jun101-l-v V A-OTF-Jun101Pro-Light
+
+%% MS Mincho/Gothic
+%msmin H msmincho
+%msgot H msgothic
+
+%% MS-Mincho with proportional latin and kana:
+%msminp H :1:msmincho
+
+%% Hojo-Kanji (JIS X 0212-1990): Adobe-Japan2
+%hmin Hojo-H msmincho
+%hminv Hojo-V msmincho
+
+%%
+%% CJK-LaTeX/HLaTeX Examples
+%%
+
+%% Arphic Public Licence fonts:
+%% AR PL KaitiM, AR PL Mingti2L, AR PL SungtiL
+
+%bsmi@Big5@ ETen-B5-H bsmi00lp
+%bkai@Big5@ ETen-B5-H bkai00mp
+%gbsn@EUC@ GB-EUC-H gbsn00lp
+%gkai@EUC@ GB-EUC-H gkai00mp
+%bsmir@Big5@ ETen-B5-V bsmi00lp
+%bkair@Big5@ ETen-B5-V bkai00mp
+%gbsnr@EUC@ GB-EUC-V gbsn00lp
+%gkair@EUC@ GB-EUC-V gkai00mp
+
+%% Korean MS-Windows fonts with stylistic variants
+%jbtm@UKS@ UniKS-UCS2-H !batang
+%jbtmo@UKS@ UniKS-UCS2-H !batang,Italic
+%jbtb@UKS@ UniKS-UCS2-H !batang,Bold
+%jbtbo@UKS@ UniKS-UCS2-H !batang,BoldItalic
+
+%% Baekmuk fonts (used with HLaTeX package)
+%bbtm@KS-HLaTeX@ KSCms-UHC-H batang
+%bbtmo@UKS-HLaTeX@ UniKS-UCS2-H batang -s .167
+
+%% Heisei family of Acrobat Asian Font Packs:
+%% Not embedded.
+%mincho@UJIS@ UniJIS-UCS2-H HeiseiMin-W3-Acro
+%gothic@UJIS@ UniJIS-UCS2-H HeiseiKakuGo-W5-Acro
+
+%% Bitstream Cyberbit
+%% Available at:
+%% http://ftp.netscape.com/pub/communicator/extras/fonts/windows/ReadMe.htm
+
+%cyberb@Unicode@ unicode cyberbit
diff --git a/Build/source/texk/dvipdfm-x/data/dvipdfmx.cfg b/Build/source/texk/dvipdfm-x/data/dvipdfmx.cfg
new file mode 100644
index 00000000000..2f10e13536c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/data/dvipdfmx.cfg
@@ -0,0 +1,228 @@
+%% $Id$
+%% dvipdfmx.cfg for dvipdfmx and xdvipdfmx. (Public domain.)
+%% (maintained in TeX Live /source/ tree, copied to Master.)
+%%
+%% PDF Version Setting
+%%
+%% PDF (minor) version stamp to use in output file.
+%% This also implies maximal version of PDF file allowed to be included.
+%% Dvipdfmx does not support 1.0, 1.1, 1.2 since TrueType font embedded
+%% as CIDFontType2 requires at least version 1.3. Transparent imaging
+%% model requires version 1.4. So if you want soft-masking support for
+%% PNG image with alpha channels, you should set version to 4 or higher.
+%% PDF 1.5 enables object compression.
+
+V 5
+
+%% Dvipdfmx Compatibility Flags
+%%
+%% 0x0002 Use semi-transparent filling for tpic shading command,
+%% instead of opaque gray color. (requires PDF 1.4)
+%% 0x0004 Treat all CIDFont as fixed-pitch font.
+%% This is only for backward compatibility. Don't use that.
+%% 0x0008 Do not replace duplicate fontmap entries.
+%% Dvipdfm's (not 'x') behaviour.
+%% 0x0010 Do not optimize PDF destinations. Use this if you want to
+%% refer from other files to destinations in the current file.
+
+%C 0x0000
+
+%% PDF Document Settings
+%%
+%% Papersize Option:
+%%
+%% p papersize-spec
+%%
+%% papersize-spec is 'paper-format' or length-pair, e.g., 'a4', 'letter',
+%% '20cm,30cm'. Recognized unit is 'cm', 'mm', 'bp', 'pt', 'in'.
+
+p a4
+
+%% Annotation Box Margin:
+%%
+%% g length
+%%
+%% Add margin to annotation rectangle created via various \specials. Many
+%% TeX macro packages set the annotation bounding box equal to the TeX box
+%% that encloses the material. That's not always what you want.
+%% Annotations created by pdf:bannot/pdf:eannot is also affected.
+
+%g 0
+
+%% Bookmark Open Level:
+%%
+%% O integer
+%%
+%% Mark bookmark (outline) item as initial state 'open' if the depth
+%% of that item (from root node) is less than or equal to the integer
+%% specified with this option.
+
+O 0
+
+%% PDF Security (Encryption) Setting
+%%
+%% Those options won't take effects unless you use flag 'S'.
+%%
+%% Key bits for PDF encryption (40 - 128)
+
+K 40
+
+%% Permission flag for PDF encryption: Revision will be 3 if the key size
+%% is greater than 40 bits.
+%%
+%% 0x0004 (Revision 2) Print the document.
+%% (Revision 3) Print the document (possibly not at the highest quality
+%% level, depending on whether bit 12[0x0800] is also set).
+%% 0x0008 Modify the contents of the document by operations other than those
+%% controlled by bits 6[0x0020], 9[0x0100], and 11[0x0400].
+%% 0x0010 (Revision 2) Copy or otherwise extract text and graphics from the
+%% document, including extracting text and graphics (in support of
+%% accessibility to disabled users or for other purposes).
+%% (Revision 3) Copy or otherwise extract text and grphics from the
+%% document by operations other than that controlled by bit 10[0x0200].
+%% 0x0020 Add or modify text annotations, fill in interactive form fields,
+%% and, if bit 4[0x0008] is also set, create or modify interactive
+%% form fields (including signature fields).
+%%
+%% (Revision 3 only)
+%% 0x0100 Fill in existing interactive form fields (including signature
+%% fields), even if bit 6 is clear.
+%% 0x0200 Extract text and graphics (in support of accessibility to disabled
+%% users or for other purposes).
+%% 0x0400 Assemble the document (insert, rotate, or delete pages and create
+%% bookmarks or thumbnail images), even if bit 4 is clear.
+%% 0x0800 Print the document to a representation from which a faithful digital
+%% copy of the PDF content could be generated. When this bit is clear
+%% (and bit 3 is set), printing is limited to a low-level representation
+%% of the appearance, possibly of degraded quality.
+
+P 0x003C
+
+%% Image Handler
+%%
+%% With 'D' option dvipdfmx may invoke shell command via system()
+%% function call.
+%%
+%% Command-line template for a-to-b conversion:
+%%
+%% Supported target format ('b') is currently PDF.
+%% Percent sign '%' is special character:
+%%
+%% %i Input file name (FQPN). Name of file to be converted to PDF.
+%% %o Output file name (FQPN). Temporary file to store conversion
+%% result. Removed after inclusion is finished. (regardless of
+%% success or failure)
+%% %b The "base" name of the input file, e.g., "foo" instead of
+%% "foo.eps".
+%% %v The PDF version to be converted to, e.g. "1.4" for PDF 1.4.
+%% %% Replaced with single '%'.
+
+%% Ghostscript (PS-to-PDF and PDF-to-PDF):
+%%
+%% ps2pdf is a front-end to gs. For a complete list of options, see
+%% http://ghostscript.com/doc/current/Ps2pdf.htm#Options
+%%
+%% In TeX Live, we use the rungs wrapper instead of ps2pdf, becuse we
+%% must omit the -dSAFER which ps2pdf specifies: in order for pstricks
+%% to work with xetex,
+%% /usr/local/texlive/*/texmf-dist/dvips/pstricks/pstricks.pro (for
+%% example) needs to be accessed. Also, it is better to use our
+%% supplied gs on Windows.
+%%
+%% Without the -dEPSCROP below, an eps file with negative llx/lly (as
+%% created by MetaPost, for example) fails. In 2013, changes were made
+%% to the drivers xetex.def, dvipdfmx.def, etc., to handle non-zero
+%% llx/lly so we could use it. The file epsf-dvipdfmx.tex is available
+%% from CTAN/TL/etc. to support plain's epsf.tex.
+%%
+%% In 2014, we discovered that -sPAPERSIZE=a0 was needed to support
+%% pstricks under xetex; otherwise, images were cropped (see thread at
+%% http://tug.org/pipermail/xetex/2014-November/025664.html).
+%% Happily, it seems that using both -dEPSCROP and -sPAPERSIZE=a0
+%% simultaneously works ok. So that's we do below.
+%%
+%% By default, gs encodes all images contained in a PS file using
+%% the lossy DCT (i.e., JPEG) filter. This often leads to inferior
+%% result (see the discussion at http://electron.mit.edu/~gsteele/pdf/).
+%% The "-dAutoFilterXXXImages" and "-dXXXImageFilter" options used
+%% below force all images to be encoded with the lossless Flate (zlib,
+%% same as PNG) filter. Note that if the PS file already contains DCT
+%% encoded images (which is possible in PS level 2), then these images
+%% will also be re-encoded using Flate. To turn the conversion off,
+%% simply remove the options mentioned above.
+%%
+%% Incidentally, especially in TL, more than one dvipdfmx.cfg may be
+%% extant. You can find the one that is active by running:
+%% kpsewhich -progname=dvipdfmx -format='other text files' dvipdfmx.cfg
+%% and control which one is found by setting DVIPDFMXINPUTS.
+%%
+D "rungs -q -dALLOWPSTRANSPARENCY -dDELAYSAFER -dNOPAUSE -dBATCH -dEPSCrop -sPAPERSIZE=a0 -sDEVICE=pdfwrite -dCompatibilityLevel=%v -dAutoFilterGrayImages=false -dGrayImageFilter=/FlateEncode -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dAutoRotatePages=/None -sOutputFile='%o' '%i' -c quit"
+
+% other random ps converters people have experimented with.
+%D "/usr/local/bin/ps2pdf -dEPSCrop '%i' '%o'"
+%D "/usr/texbin/epstopdf '%i' -o '%o'"
+%D "/usr/bin/pstopdf '%i' -o '%o'"
+%
+%% Frank Siegert's PStill:
+%D "/usr/local/bin/pstill -c -o '%o' '%i'"
+%
+%% Batik + Fop (SVG-to-PDF):
+%% If you want both PS and SVG, you need to write a script or program
+%% that selectively invokes converters.
+%D "java -classpath classpaths -jar /path/to/batik-rasterizer.jar -m application/pdf -d '%o' '%i'"
+%
+%% There are no way to directly know suggested size of (raster) images.
+%% You may want to use %b here, since you can try reading the ebb file
+%% to see what is natural (physical) size of images.
+%D "ras2pdf -r 300x300 -b '%b.bb' -o '%o' '%i'"
+%
+%% ImageMagick:
+%% Easiest way to support various file formats.
+%D "convert '%i' 'epdf:%o'"
+
+%% Other Options
+%%
+%% DPI for PK font creation
+
+%r 600
+
+%% Set number of fractional digit kept for various numbers in PDF page
+%% content output. By setting this to 2 (default), dvipdfmx rounds
+%% real numbers at 2nd fractional (decimal) digit; e.g., "3.14159" is
+%% written as "3.14". Increasing this to more than 2 isn't meaningful
+%% for old Acrobat due to implementation limit of Acrobat.
+%% Length 0.01 in unscaled coordinate system amount to width of 1 pixel
+%% in 7200ppi display.
+
+%d 5
+
+%% Image cache life in hours
+%% 0 means erase all old images and leave new images
+%% -1 means erase all old images and also erase new images
+%% -2 means ignore image cache
+%I -2
+
+%% Font Map Files
+%%
+%% teTeX 2.x and TeX Live using updmap (pdfTeX format)
+f pdftex.map
+
+%% teTeX 2.x and TeX Live using updmap (DVIPDFM format)
+%f dvipdfm.map
+
+%% teTeX 2.x and TeX Live using updmap (DVIPS format)
+%% MiKTeX 2.2 and 2.3
+%f psfonts.map
+
+%% Put additional fontmap files here (usually for Type0 fonts)
+%f cid-x.map
+
+% the following file is generated by updmap(-sys) from the
+% KanjiMap entries in the updmap.cfg file.
+f kanjix.map
+% minimal example for Chinese and Korean users
+% improvements please to tex-live@tug.org
+f ckx.map
+
+%% Include other config files
+%i <filename>
diff --git a/Build/source/texk/dvipdfm-x/data/glyphlist.txt b/Build/source/texk/dvipdfm-x/data/glyphlist.txt
new file mode 100644
index 00000000000..0304ffc6674
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/data/glyphlist.txt
@@ -0,0 +1,4322 @@
+# ###################################################################################
+# Copyright (c) 1997,1998,2002,2007 Adobe Systems Incorporated
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this documentation file to use, copy, publish, distribute,
+# sublicense, and/or sell copies of the documentation, and to permit
+# others to do the same, provided that:
+# - No modification, editing or other alteration of this document is
+# allowed; and
+# - The above copyright notice and this permission notice shall be
+# included in all copies of the documentation.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this documentation file, to create their own derivative works
+# from the content of this document to use, copy, publish, distribute,
+# sublicense, and/or sell the derivative works, and to permit others to do
+# the same, provided that the derived work is not represented as being a
+# copy or version of this document.
+#
+# Adobe shall not be liable to any party for any loss of revenue or profit
+# or for indirect, incidental, special, consequential, or other similar
+# damages, whether based on tort (including without limitation negligence
+# or strict liability), contract or other legal or equitable grounds even
+# if Adobe has been advised or had reason to know of the possibility of
+# such damages.Ê The Adobe materials are provided on an "AS IS" basis.Ê
+# Adobe specifically disclaims all express, statutory, or implied
+# warranties relating to the Adobe materials, including but not limited to
+# those concerning merchantability or fitness for a particular purpose or
+# non-infringement of any third party rights regarding the Adobe
+# materials.
+# ###################################################################################
+# Name: Adobe Glyph List
+# Table version: 2.0
+# Date: September 20, 2002
+#
+# See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html
+#
+# Format: Semicolon-delimited fields:
+# (1) glyph name
+# (2) Unicode scalar value
+A;0041
+AE;00C6
+AEacute;01FC
+AEmacron;01E2
+AEsmall;F7E6
+Aacute;00C1
+Aacutesmall;F7E1
+Abreve;0102
+Abreveacute;1EAE
+Abrevecyrillic;04D0
+Abrevedotbelow;1EB6
+Abrevegrave;1EB0
+Abrevehookabove;1EB2
+Abrevetilde;1EB4
+Acaron;01CD
+Acircle;24B6
+Acircumflex;00C2
+Acircumflexacute;1EA4
+Acircumflexdotbelow;1EAC
+Acircumflexgrave;1EA6
+Acircumflexhookabove;1EA8
+Acircumflexsmall;F7E2
+Acircumflextilde;1EAA
+Acute;F6C9
+Acutesmall;F7B4
+Acyrillic;0410
+Adblgrave;0200
+Adieresis;00C4
+Adieresiscyrillic;04D2
+Adieresismacron;01DE
+Adieresissmall;F7E4
+Adotbelow;1EA0
+Adotmacron;01E0
+Agrave;00C0
+Agravesmall;F7E0
+Ahookabove;1EA2
+Aiecyrillic;04D4
+Ainvertedbreve;0202
+Alpha;0391
+Alphatonos;0386
+Amacron;0100
+Amonospace;FF21
+Aogonek;0104
+Aring;00C5
+Aringacute;01FA
+Aringbelow;1E00
+Aringsmall;F7E5
+Asmall;F761
+Atilde;00C3
+Atildesmall;F7E3
+Aybarmenian;0531
+B;0042
+Bcircle;24B7
+Bdotaccent;1E02
+Bdotbelow;1E04
+Becyrillic;0411
+Benarmenian;0532
+Beta;0392
+Bhook;0181
+Blinebelow;1E06
+Bmonospace;FF22
+Brevesmall;F6F4
+Bsmall;F762
+Btopbar;0182
+C;0043
+Caarmenian;053E
+Cacute;0106
+Caron;F6CA
+Caronsmall;F6F5
+Ccaron;010C
+Ccedilla;00C7
+Ccedillaacute;1E08
+Ccedillasmall;F7E7
+Ccircle;24B8
+Ccircumflex;0108
+Cdot;010A
+Cdotaccent;010A
+Cedillasmall;F7B8
+Chaarmenian;0549
+Cheabkhasiancyrillic;04BC
+Checyrillic;0427
+Chedescenderabkhasiancyrillic;04BE
+Chedescendercyrillic;04B6
+Chedieresiscyrillic;04F4
+Cheharmenian;0543
+Chekhakassiancyrillic;04CB
+Cheverticalstrokecyrillic;04B8
+Chi;03A7
+Chook;0187
+Circumflexsmall;F6F6
+Cmonospace;FF23
+Coarmenian;0551
+Csmall;F763
+D;0044
+DZ;01F1
+DZcaron;01C4
+Daarmenian;0534
+Dafrican;0189
+Dcaron;010E
+Dcedilla;1E10
+Dcircle;24B9
+Dcircumflexbelow;1E12
+Dcroat;0110
+Ddotaccent;1E0A
+Ddotbelow;1E0C
+Decyrillic;0414
+Deicoptic;03EE
+Delta;2206
+Deltagreek;0394
+Dhook;018A
+Dieresis;F6CB
+DieresisAcute;F6CC
+DieresisGrave;F6CD
+Dieresissmall;F7A8
+Digammagreek;03DC
+Djecyrillic;0402
+Dlinebelow;1E0E
+Dmonospace;FF24
+Dotaccentsmall;F6F7
+Dslash;0110
+Dsmall;F764
+Dtopbar;018B
+Dz;01F2
+Dzcaron;01C5
+Dzeabkhasiancyrillic;04E0
+Dzecyrillic;0405
+Dzhecyrillic;040F
+E;0045
+Eacute;00C9
+Eacutesmall;F7E9
+Ebreve;0114
+Ecaron;011A
+Ecedillabreve;1E1C
+Echarmenian;0535
+Ecircle;24BA
+Ecircumflex;00CA
+Ecircumflexacute;1EBE
+Ecircumflexbelow;1E18
+Ecircumflexdotbelow;1EC6
+Ecircumflexgrave;1EC0
+Ecircumflexhookabove;1EC2
+Ecircumflexsmall;F7EA
+Ecircumflextilde;1EC4
+Ecyrillic;0404
+Edblgrave;0204
+Edieresis;00CB
+Edieresissmall;F7EB
+Edot;0116
+Edotaccent;0116
+Edotbelow;1EB8
+Efcyrillic;0424
+Egrave;00C8
+Egravesmall;F7E8
+Eharmenian;0537
+Ehookabove;1EBA
+Eightroman;2167
+Einvertedbreve;0206
+Eiotifiedcyrillic;0464
+Elcyrillic;041B
+Elevenroman;216A
+Emacron;0112
+Emacronacute;1E16
+Emacrongrave;1E14
+Emcyrillic;041C
+Emonospace;FF25
+Encyrillic;041D
+Endescendercyrillic;04A2
+Eng;014A
+Enghecyrillic;04A4
+Enhookcyrillic;04C7
+Eogonek;0118
+Eopen;0190
+Epsilon;0395
+Epsilontonos;0388
+Ercyrillic;0420
+Ereversed;018E
+Ereversedcyrillic;042D
+Escyrillic;0421
+Esdescendercyrillic;04AA
+Esh;01A9
+Esmall;F765
+Eta;0397
+Etarmenian;0538
+Etatonos;0389
+Eth;00D0
+Ethsmall;F7F0
+Etilde;1EBC
+Etildebelow;1E1A
+Euro;20AC
+Ezh;01B7
+Ezhcaron;01EE
+Ezhreversed;01B8
+F;0046
+Fcircle;24BB
+Fdotaccent;1E1E
+Feharmenian;0556
+Feicoptic;03E4
+Fhook;0191
+Fitacyrillic;0472
+Fiveroman;2164
+Fmonospace;FF26
+Fourroman;2163
+Fsmall;F766
+G;0047
+GBsquare;3387
+Gacute;01F4
+Gamma;0393
+Gammaafrican;0194
+Gangiacoptic;03EA
+Gbreve;011E
+Gcaron;01E6
+Gcedilla;0122
+Gcircle;24BC
+Gcircumflex;011C
+Gcommaaccent;0122
+Gdot;0120
+Gdotaccent;0120
+Gecyrillic;0413
+Ghadarmenian;0542
+Ghemiddlehookcyrillic;0494
+Ghestrokecyrillic;0492
+Gheupturncyrillic;0490
+Ghook;0193
+Gimarmenian;0533
+Gjecyrillic;0403
+Gmacron;1E20
+Gmonospace;FF27
+Grave;F6CE
+Gravesmall;F760
+Gsmall;F767
+Gsmallhook;029B
+Gstroke;01E4
+H;0048
+H18533;25CF
+H18543;25AA
+H18551;25AB
+H22073;25A1
+HPsquare;33CB
+Haabkhasiancyrillic;04A8
+Hadescendercyrillic;04B2
+Hardsigncyrillic;042A
+Hbar;0126
+Hbrevebelow;1E2A
+Hcedilla;1E28
+Hcircle;24BD
+Hcircumflex;0124
+Hdieresis;1E26
+Hdotaccent;1E22
+Hdotbelow;1E24
+Hmonospace;FF28
+Hoarmenian;0540
+Horicoptic;03E8
+Hsmall;F768
+Hungarumlaut;F6CF
+Hungarumlautsmall;F6F8
+Hzsquare;3390
+I;0049
+IAcyrillic;042F
+IJ;0132
+IUcyrillic;042E
+Iacute;00CD
+Iacutesmall;F7ED
+Ibreve;012C
+Icaron;01CF
+Icircle;24BE
+Icircumflex;00CE
+Icircumflexsmall;F7EE
+Icyrillic;0406
+Idblgrave;0208
+Idieresis;00CF
+Idieresisacute;1E2E
+Idieresiscyrillic;04E4
+Idieresissmall;F7EF
+Idot;0130
+Idotaccent;0130
+Idotbelow;1ECA
+Iebrevecyrillic;04D6
+Iecyrillic;0415
+Ifraktur;2111
+Igrave;00CC
+Igravesmall;F7EC
+Ihookabove;1EC8
+Iicyrillic;0418
+Iinvertedbreve;020A
+Iishortcyrillic;0419
+Imacron;012A
+Imacroncyrillic;04E2
+Imonospace;FF29
+Iniarmenian;053B
+Iocyrillic;0401
+Iogonek;012E
+Iota;0399
+Iotaafrican;0196
+Iotadieresis;03AA
+Iotatonos;038A
+Ismall;F769
+Istroke;0197
+Itilde;0128
+Itildebelow;1E2C
+Izhitsacyrillic;0474
+Izhitsadblgravecyrillic;0476
+J;004A
+Jaarmenian;0541
+Jcircle;24BF
+Jcircumflex;0134
+Jecyrillic;0408
+Jheharmenian;054B
+Jmonospace;FF2A
+Jsmall;F76A
+K;004B
+KBsquare;3385
+KKsquare;33CD
+Kabashkircyrillic;04A0
+Kacute;1E30
+Kacyrillic;041A
+Kadescendercyrillic;049A
+Kahookcyrillic;04C3
+Kappa;039A
+Kastrokecyrillic;049E
+Kaverticalstrokecyrillic;049C
+Kcaron;01E8
+Kcedilla;0136
+Kcircle;24C0
+Kcommaaccent;0136
+Kdotbelow;1E32
+Keharmenian;0554
+Kenarmenian;053F
+Khacyrillic;0425
+Kheicoptic;03E6
+Khook;0198
+Kjecyrillic;040C
+Klinebelow;1E34
+Kmonospace;FF2B
+Koppacyrillic;0480
+Koppagreek;03DE
+Ksicyrillic;046E
+Ksmall;F76B
+L;004C
+LJ;01C7
+LL;F6BF
+Lacute;0139
+Lambda;039B
+Lcaron;013D
+Lcedilla;013B
+Lcircle;24C1
+Lcircumflexbelow;1E3C
+Lcommaaccent;013B
+Ldot;013F
+Ldotaccent;013F
+Ldotbelow;1E36
+Ldotbelowmacron;1E38
+Liwnarmenian;053C
+Lj;01C8
+Ljecyrillic;0409
+Llinebelow;1E3A
+Lmonospace;FF2C
+Lslash;0141
+Lslashsmall;F6F9
+Lsmall;F76C
+M;004D
+MBsquare;3386
+Macron;F6D0
+Macronsmall;F7AF
+Macute;1E3E
+Mcircle;24C2
+Mdotaccent;1E40
+Mdotbelow;1E42
+Menarmenian;0544
+Mmonospace;FF2D
+Msmall;F76D
+Mturned;019C
+Mu;039C
+N;004E
+NJ;01CA
+Nacute;0143
+Ncaron;0147
+Ncedilla;0145
+Ncircle;24C3
+Ncircumflexbelow;1E4A
+Ncommaaccent;0145
+Ndotaccent;1E44
+Ndotbelow;1E46
+Nhookleft;019D
+Nineroman;2168
+Nj;01CB
+Njecyrillic;040A
+Nlinebelow;1E48
+Nmonospace;FF2E
+Nowarmenian;0546
+Nsmall;F76E
+Ntilde;00D1
+Ntildesmall;F7F1
+Nu;039D
+O;004F
+OE;0152
+OEsmall;F6FA
+Oacute;00D3
+Oacutesmall;F7F3
+Obarredcyrillic;04E8
+Obarreddieresiscyrillic;04EA
+Obreve;014E
+Ocaron;01D1
+Ocenteredtilde;019F
+Ocircle;24C4
+Ocircumflex;00D4
+Ocircumflexacute;1ED0
+Ocircumflexdotbelow;1ED8
+Ocircumflexgrave;1ED2
+Ocircumflexhookabove;1ED4
+Ocircumflexsmall;F7F4
+Ocircumflextilde;1ED6
+Ocyrillic;041E
+Odblacute;0150
+Odblgrave;020C
+Odieresis;00D6
+Odieresiscyrillic;04E6
+Odieresissmall;F7F6
+Odotbelow;1ECC
+Ogoneksmall;F6FB
+Ograve;00D2
+Ogravesmall;F7F2
+Oharmenian;0555
+Ohm;2126
+Ohookabove;1ECE
+Ohorn;01A0
+Ohornacute;1EDA
+Ohorndotbelow;1EE2
+Ohorngrave;1EDC
+Ohornhookabove;1EDE
+Ohorntilde;1EE0
+Ohungarumlaut;0150
+Oi;01A2
+Oinvertedbreve;020E
+Omacron;014C
+Omacronacute;1E52
+Omacrongrave;1E50
+Omega;2126
+Omegacyrillic;0460
+Omegagreek;03A9
+Omegaroundcyrillic;047A
+Omegatitlocyrillic;047C
+Omegatonos;038F
+Omicron;039F
+Omicrontonos;038C
+Omonospace;FF2F
+Oneroman;2160
+Oogonek;01EA
+Oogonekmacron;01EC
+Oopen;0186
+Oslash;00D8
+Oslashacute;01FE
+Oslashsmall;F7F8
+Osmall;F76F
+Ostrokeacute;01FE
+Otcyrillic;047E
+Otilde;00D5
+Otildeacute;1E4C
+Otildedieresis;1E4E
+Otildesmall;F7F5
+P;0050
+Pacute;1E54
+Pcircle;24C5
+Pdotaccent;1E56
+Pecyrillic;041F
+Peharmenian;054A
+Pemiddlehookcyrillic;04A6
+Phi;03A6
+Phook;01A4
+Pi;03A0
+Piwrarmenian;0553
+Pmonospace;FF30
+Psi;03A8
+Psicyrillic;0470
+Psmall;F770
+Q;0051
+Qcircle;24C6
+Qmonospace;FF31
+Qsmall;F771
+R;0052
+Raarmenian;054C
+Racute;0154
+Rcaron;0158
+Rcedilla;0156
+Rcircle;24C7
+Rcommaaccent;0156
+Rdblgrave;0210
+Rdotaccent;1E58
+Rdotbelow;1E5A
+Rdotbelowmacron;1E5C
+Reharmenian;0550
+Rfraktur;211C
+Rho;03A1
+Ringsmall;F6FC
+Rinvertedbreve;0212
+Rlinebelow;1E5E
+Rmonospace;FF32
+Rsmall;F772
+Rsmallinverted;0281
+Rsmallinvertedsuperior;02B6
+S;0053
+SF010000;250C
+SF020000;2514
+SF030000;2510
+SF040000;2518
+SF050000;253C
+SF060000;252C
+SF070000;2534
+SF080000;251C
+SF090000;2524
+SF100000;2500
+SF110000;2502
+SF190000;2561
+SF200000;2562
+SF210000;2556
+SF220000;2555
+SF230000;2563
+SF240000;2551
+SF250000;2557
+SF260000;255D
+SF270000;255C
+SF280000;255B
+SF360000;255E
+SF370000;255F
+SF380000;255A
+SF390000;2554
+SF400000;2569
+SF410000;2566
+SF420000;2560
+SF430000;2550
+SF440000;256C
+SF450000;2567
+SF460000;2568
+SF470000;2564
+SF480000;2565
+SF490000;2559
+SF500000;2558
+SF510000;2552
+SF520000;2553
+SF530000;256B
+SF540000;256A
+Sacute;015A
+Sacutedotaccent;1E64
+Sampigreek;03E0
+Scaron;0160
+Scarondotaccent;1E66
+Scaronsmall;F6FD
+Scedilla;015E
+Schwa;018F
+Schwacyrillic;04D8
+Schwadieresiscyrillic;04DA
+Scircle;24C8
+Scircumflex;015C
+Scommaaccent;0218
+Sdotaccent;1E60
+Sdotbelow;1E62
+Sdotbelowdotaccent;1E68
+Seharmenian;054D
+Sevenroman;2166
+Shaarmenian;0547
+Shacyrillic;0428
+Shchacyrillic;0429
+Sheicoptic;03E2
+Shhacyrillic;04BA
+Shimacoptic;03EC
+Sigma;03A3
+Sixroman;2165
+Smonospace;FF33
+Softsigncyrillic;042C
+Ssmall;F773
+Stigmagreek;03DA
+T;0054
+Tau;03A4
+Tbar;0166
+Tcaron;0164
+Tcedilla;0162
+Tcircle;24C9
+Tcircumflexbelow;1E70
+Tcommaaccent;0162
+Tdotaccent;1E6A
+Tdotbelow;1E6C
+Tecyrillic;0422
+Tedescendercyrillic;04AC
+Tenroman;2169
+Tetsecyrillic;04B4
+Theta;0398
+Thook;01AC
+Thorn;00DE
+Thornsmall;F7FE
+Threeroman;2162
+Tildesmall;F6FE
+Tiwnarmenian;054F
+Tlinebelow;1E6E
+Tmonospace;FF34
+Toarmenian;0539
+Tonefive;01BC
+Tonesix;0184
+Tonetwo;01A7
+Tretroflexhook;01AE
+Tsecyrillic;0426
+Tshecyrillic;040B
+Tsmall;F774
+Twelveroman;216B
+Tworoman;2161
+U;0055
+Uacute;00DA
+Uacutesmall;F7FA
+Ubreve;016C
+Ucaron;01D3
+Ucircle;24CA
+Ucircumflex;00DB
+Ucircumflexbelow;1E76
+Ucircumflexsmall;F7FB
+Ucyrillic;0423
+Udblacute;0170
+Udblgrave;0214
+Udieresis;00DC
+Udieresisacute;01D7
+Udieresisbelow;1E72
+Udieresiscaron;01D9
+Udieresiscyrillic;04F0
+Udieresisgrave;01DB
+Udieresismacron;01D5
+Udieresissmall;F7FC
+Udotbelow;1EE4
+Ugrave;00D9
+Ugravesmall;F7F9
+Uhookabove;1EE6
+Uhorn;01AF
+Uhornacute;1EE8
+Uhorndotbelow;1EF0
+Uhorngrave;1EEA
+Uhornhookabove;1EEC
+Uhorntilde;1EEE
+Uhungarumlaut;0170
+Uhungarumlautcyrillic;04F2
+Uinvertedbreve;0216
+Ukcyrillic;0478
+Umacron;016A
+Umacroncyrillic;04EE
+Umacrondieresis;1E7A
+Umonospace;FF35
+Uogonek;0172
+Upsilon;03A5
+Upsilon1;03D2
+Upsilonacutehooksymbolgreek;03D3
+Upsilonafrican;01B1
+Upsilondieresis;03AB
+Upsilondieresishooksymbolgreek;03D4
+Upsilonhooksymbol;03D2
+Upsilontonos;038E
+Uring;016E
+Ushortcyrillic;040E
+Usmall;F775
+Ustraightcyrillic;04AE
+Ustraightstrokecyrillic;04B0
+Utilde;0168
+Utildeacute;1E78
+Utildebelow;1E74
+V;0056
+Vcircle;24CB
+Vdotbelow;1E7E
+Vecyrillic;0412
+Vewarmenian;054E
+Vhook;01B2
+Vmonospace;FF36
+Voarmenian;0548
+Vsmall;F776
+Vtilde;1E7C
+W;0057
+Wacute;1E82
+Wcircle;24CC
+Wcircumflex;0174
+Wdieresis;1E84
+Wdotaccent;1E86
+Wdotbelow;1E88
+Wgrave;1E80
+Wmonospace;FF37
+Wsmall;F777
+X;0058
+Xcircle;24CD
+Xdieresis;1E8C
+Xdotaccent;1E8A
+Xeharmenian;053D
+Xi;039E
+Xmonospace;FF38
+Xsmall;F778
+Y;0059
+Yacute;00DD
+Yacutesmall;F7FD
+Yatcyrillic;0462
+Ycircle;24CE
+Ycircumflex;0176
+Ydieresis;0178
+Ydieresissmall;F7FF
+Ydotaccent;1E8E
+Ydotbelow;1EF4
+Yericyrillic;042B
+Yerudieresiscyrillic;04F8
+Ygrave;1EF2
+Yhook;01B3
+Yhookabove;1EF6
+Yiarmenian;0545
+Yicyrillic;0407
+Yiwnarmenian;0552
+Ymonospace;FF39
+Ysmall;F779
+Ytilde;1EF8
+Yusbigcyrillic;046A
+Yusbigiotifiedcyrillic;046C
+Yuslittlecyrillic;0466
+Yuslittleiotifiedcyrillic;0468
+Z;005A
+Zaarmenian;0536
+Zacute;0179
+Zcaron;017D
+Zcaronsmall;F6FF
+Zcircle;24CF
+Zcircumflex;1E90
+Zdot;017B
+Zdotaccent;017B
+Zdotbelow;1E92
+Zecyrillic;0417
+Zedescendercyrillic;0498
+Zedieresiscyrillic;04DE
+Zeta;0396
+Zhearmenian;053A
+Zhebrevecyrillic;04C1
+Zhecyrillic;0416
+Zhedescendercyrillic;0496
+Zhedieresiscyrillic;04DC
+Zlinebelow;1E94
+Zmonospace;FF3A
+Zsmall;F77A
+Zstroke;01B5
+a;0061
+aabengali;0986
+aacute;00E1
+aadeva;0906
+aagujarati;0A86
+aagurmukhi;0A06
+aamatragurmukhi;0A3E
+aarusquare;3303
+aavowelsignbengali;09BE
+aavowelsigndeva;093E
+aavowelsigngujarati;0ABE
+abbreviationmarkarmenian;055F
+abbreviationsigndeva;0970
+abengali;0985
+abopomofo;311A
+abreve;0103
+abreveacute;1EAF
+abrevecyrillic;04D1
+abrevedotbelow;1EB7
+abrevegrave;1EB1
+abrevehookabove;1EB3
+abrevetilde;1EB5
+acaron;01CE
+acircle;24D0
+acircumflex;00E2
+acircumflexacute;1EA5
+acircumflexdotbelow;1EAD
+acircumflexgrave;1EA7
+acircumflexhookabove;1EA9
+acircumflextilde;1EAB
+acute;00B4
+acutebelowcmb;0317
+acutecmb;0301
+acutecomb;0301
+acutedeva;0954
+acutelowmod;02CF
+acutetonecmb;0341
+acyrillic;0430
+adblgrave;0201
+addakgurmukhi;0A71
+adeva;0905
+adieresis;00E4
+adieresiscyrillic;04D3
+adieresismacron;01DF
+adotbelow;1EA1
+adotmacron;01E1
+ae;00E6
+aeacute;01FD
+aekorean;3150
+aemacron;01E3
+afii00208;2015
+afii08941;20A4
+afii10017;0410
+afii10018;0411
+afii10019;0412
+afii10020;0413
+afii10021;0414
+afii10022;0415
+afii10023;0401
+afii10024;0416
+afii10025;0417
+afii10026;0418
+afii10027;0419
+afii10028;041A
+afii10029;041B
+afii10030;041C
+afii10031;041D
+afii10032;041E
+afii10033;041F
+afii10034;0420
+afii10035;0421
+afii10036;0422
+afii10037;0423
+afii10038;0424
+afii10039;0425
+afii10040;0426
+afii10041;0427
+afii10042;0428
+afii10043;0429
+afii10044;042A
+afii10045;042B
+afii10046;042C
+afii10047;042D
+afii10048;042E
+afii10049;042F
+afii10050;0490
+afii10051;0402
+afii10052;0403
+afii10053;0404
+afii10054;0405
+afii10055;0406
+afii10056;0407
+afii10057;0408
+afii10058;0409
+afii10059;040A
+afii10060;040B
+afii10061;040C
+afii10062;040E
+afii10063;F6C4
+afii10064;F6C5
+afii10065;0430
+afii10066;0431
+afii10067;0432
+afii10068;0433
+afii10069;0434
+afii10070;0435
+afii10071;0451
+afii10072;0436
+afii10073;0437
+afii10074;0438
+afii10075;0439
+afii10076;043A
+afii10077;043B
+afii10078;043C
+afii10079;043D
+afii10080;043E
+afii10081;043F
+afii10082;0440
+afii10083;0441
+afii10084;0442
+afii10085;0443
+afii10086;0444
+afii10087;0445
+afii10088;0446
+afii10089;0447
+afii10090;0448
+afii10091;0449
+afii10092;044A
+afii10093;044B
+afii10094;044C
+afii10095;044D
+afii10096;044E
+afii10097;044F
+afii10098;0491
+afii10099;0452
+afii10100;0453
+afii10101;0454
+afii10102;0455
+afii10103;0456
+afii10104;0457
+afii10105;0458
+afii10106;0459
+afii10107;045A
+afii10108;045B
+afii10109;045C
+afii10110;045E
+afii10145;040F
+afii10146;0462
+afii10147;0472
+afii10148;0474
+afii10192;F6C6
+afii10193;045F
+afii10194;0463
+afii10195;0473
+afii10196;0475
+afii10831;F6C7
+afii10832;F6C8
+afii10846;04D9
+afii299;200E
+afii300;200F
+afii301;200D
+afii57381;066A
+afii57388;060C
+afii57392;0660
+afii57393;0661
+afii57394;0662
+afii57395;0663
+afii57396;0664
+afii57397;0665
+afii57398;0666
+afii57399;0667
+afii57400;0668
+afii57401;0669
+afii57403;061B
+afii57407;061F
+afii57409;0621
+afii57410;0622
+afii57411;0623
+afii57412;0624
+afii57413;0625
+afii57414;0626
+afii57415;0627
+afii57416;0628
+afii57417;0629
+afii57418;062A
+afii57419;062B
+afii57420;062C
+afii57421;062D
+afii57422;062E
+afii57423;062F
+afii57424;0630
+afii57425;0631
+afii57426;0632
+afii57427;0633
+afii57428;0634
+afii57429;0635
+afii57430;0636
+afii57431;0637
+afii57432;0638
+afii57433;0639
+afii57434;063A
+afii57440;0640
+afii57441;0641
+afii57442;0642
+afii57443;0643
+afii57444;0644
+afii57445;0645
+afii57446;0646
+afii57448;0648
+afii57449;0649
+afii57450;064A
+afii57451;064B
+afii57452;064C
+afii57453;064D
+afii57454;064E
+afii57455;064F
+afii57456;0650
+afii57457;0651
+afii57458;0652
+afii57470;0647
+afii57505;06A4
+afii57506;067E
+afii57507;0686
+afii57508;0698
+afii57509;06AF
+afii57511;0679
+afii57512;0688
+afii57513;0691
+afii57514;06BA
+afii57519;06D2
+afii57534;06D5
+afii57636;20AA
+afii57645;05BE
+afii57658;05C3
+afii57664;05D0
+afii57665;05D1
+afii57666;05D2
+afii57667;05D3
+afii57668;05D4
+afii57669;05D5
+afii57670;05D6
+afii57671;05D7
+afii57672;05D8
+afii57673;05D9
+afii57674;05DA
+afii57675;05DB
+afii57676;05DC
+afii57677;05DD
+afii57678;05DE
+afii57679;05DF
+afii57680;05E0
+afii57681;05E1
+afii57682;05E2
+afii57683;05E3
+afii57684;05E4
+afii57685;05E5
+afii57686;05E6
+afii57687;05E7
+afii57688;05E8
+afii57689;05E9
+afii57690;05EA
+afii57694;FB2A
+afii57695;FB2B
+afii57700;FB4B
+afii57705;FB1F
+afii57716;05F0
+afii57717;05F1
+afii57718;05F2
+afii57723;FB35
+afii57793;05B4
+afii57794;05B5
+afii57795;05B6
+afii57796;05BB
+afii57797;05B8
+afii57798;05B7
+afii57799;05B0
+afii57800;05B2
+afii57801;05B1
+afii57802;05B3
+afii57803;05C2
+afii57804;05C1
+afii57806;05B9
+afii57807;05BC
+afii57839;05BD
+afii57841;05BF
+afii57842;05C0
+afii57929;02BC
+afii61248;2105
+afii61289;2113
+afii61352;2116
+afii61573;202C
+afii61574;202D
+afii61575;202E
+afii61664;200C
+afii63167;066D
+afii64937;02BD
+agrave;00E0
+agujarati;0A85
+agurmukhi;0A05
+ahiragana;3042
+ahookabove;1EA3
+aibengali;0990
+aibopomofo;311E
+aideva;0910
+aiecyrillic;04D5
+aigujarati;0A90
+aigurmukhi;0A10
+aimatragurmukhi;0A48
+ainarabic;0639
+ainfinalarabic;FECA
+aininitialarabic;FECB
+ainmedialarabic;FECC
+ainvertedbreve;0203
+aivowelsignbengali;09C8
+aivowelsigndeva;0948
+aivowelsigngujarati;0AC8
+akatakana;30A2
+akatakanahalfwidth;FF71
+akorean;314F
+alef;05D0
+alefarabic;0627
+alefdageshhebrew;FB30
+aleffinalarabic;FE8E
+alefhamzaabovearabic;0623
+alefhamzaabovefinalarabic;FE84
+alefhamzabelowarabic;0625
+alefhamzabelowfinalarabic;FE88
+alefhebrew;05D0
+aleflamedhebrew;FB4F
+alefmaddaabovearabic;0622
+alefmaddaabovefinalarabic;FE82
+alefmaksuraarabic;0649
+alefmaksurafinalarabic;FEF0
+alefmaksurainitialarabic;FEF3
+alefmaksuramedialarabic;FEF4
+alefpatahhebrew;FB2E
+alefqamatshebrew;FB2F
+aleph;2135
+allequal;224C
+alpha;03B1
+alphatonos;03AC
+amacron;0101
+amonospace;FF41
+ampersand;0026
+ampersandmonospace;FF06
+ampersandsmall;F726
+amsquare;33C2
+anbopomofo;3122
+angbopomofo;3124
+angkhankhuthai;0E5A
+angle;2220
+anglebracketleft;3008
+anglebracketleftvertical;FE3F
+anglebracketright;3009
+anglebracketrightvertical;FE40
+angleleft;2329
+angleright;232A
+angstrom;212B
+anoteleia;0387
+anudattadeva;0952
+anusvarabengali;0982
+anusvaradeva;0902
+anusvaragujarati;0A82
+aogonek;0105
+apaatosquare;3300
+aparen;249C
+apostrophearmenian;055A
+apostrophemod;02BC
+apple;F8FF
+approaches;2250
+approxequal;2248
+approxequalorimage;2252
+approximatelyequal;2245
+araeaekorean;318E
+araeakorean;318D
+arc;2312
+arighthalfring;1E9A
+aring;00E5
+aringacute;01FB
+aringbelow;1E01
+arrowboth;2194
+arrowdashdown;21E3
+arrowdashleft;21E0
+arrowdashright;21E2
+arrowdashup;21E1
+arrowdblboth;21D4
+arrowdbldown;21D3
+arrowdblleft;21D0
+arrowdblright;21D2
+arrowdblup;21D1
+arrowdown;2193
+arrowdownleft;2199
+arrowdownright;2198
+arrowdownwhite;21E9
+arrowheaddownmod;02C5
+arrowheadleftmod;02C2
+arrowheadrightmod;02C3
+arrowheadupmod;02C4
+arrowhorizex;F8E7
+arrowleft;2190
+arrowleftdbl;21D0
+arrowleftdblstroke;21CD
+arrowleftoverright;21C6
+arrowleftwhite;21E6
+arrowright;2192
+arrowrightdblstroke;21CF
+arrowrightheavy;279E
+arrowrightoverleft;21C4
+arrowrightwhite;21E8
+arrowtableft;21E4
+arrowtabright;21E5
+arrowup;2191
+arrowupdn;2195
+arrowupdnbse;21A8
+arrowupdownbase;21A8
+arrowupleft;2196
+arrowupleftofdown;21C5
+arrowupright;2197
+arrowupwhite;21E7
+arrowvertex;F8E6
+asciicircum;005E
+asciicircummonospace;FF3E
+asciitilde;007E
+asciitildemonospace;FF5E
+ascript;0251
+ascriptturned;0252
+asmallhiragana;3041
+asmallkatakana;30A1
+asmallkatakanahalfwidth;FF67
+asterisk;002A
+asteriskaltonearabic;066D
+asteriskarabic;066D
+asteriskmath;2217
+asteriskmonospace;FF0A
+asterisksmall;FE61
+asterism;2042
+asuperior;F6E9
+asymptoticallyequal;2243
+at;0040
+atilde;00E3
+atmonospace;FF20
+atsmall;FE6B
+aturned;0250
+aubengali;0994
+aubopomofo;3120
+audeva;0914
+augujarati;0A94
+augurmukhi;0A14
+aulengthmarkbengali;09D7
+aumatragurmukhi;0A4C
+auvowelsignbengali;09CC
+auvowelsigndeva;094C
+auvowelsigngujarati;0ACC
+avagrahadeva;093D
+aybarmenian;0561
+ayin;05E2
+ayinaltonehebrew;FB20
+ayinhebrew;05E2
+b;0062
+babengali;09AC
+backslash;005C
+backslashmonospace;FF3C
+badeva;092C
+bagujarati;0AAC
+bagurmukhi;0A2C
+bahiragana;3070
+bahtthai;0E3F
+bakatakana;30D0
+bar;007C
+barmonospace;FF5C
+bbopomofo;3105
+bcircle;24D1
+bdotaccent;1E03
+bdotbelow;1E05
+beamedsixteenthnotes;266C
+because;2235
+becyrillic;0431
+beharabic;0628
+behfinalarabic;FE90
+behinitialarabic;FE91
+behiragana;3079
+behmedialarabic;FE92
+behmeeminitialarabic;FC9F
+behmeemisolatedarabic;FC08
+behnoonfinalarabic;FC6D
+bekatakana;30D9
+benarmenian;0562
+bet;05D1
+beta;03B2
+betasymbolgreek;03D0
+betdagesh;FB31
+betdageshhebrew;FB31
+bethebrew;05D1
+betrafehebrew;FB4C
+bhabengali;09AD
+bhadeva;092D
+bhagujarati;0AAD
+bhagurmukhi;0A2D
+bhook;0253
+bihiragana;3073
+bikatakana;30D3
+bilabialclick;0298
+bindigurmukhi;0A02
+birusquare;3331
+blackcircle;25CF
+blackdiamond;25C6
+blackdownpointingtriangle;25BC
+blackleftpointingpointer;25C4
+blackleftpointingtriangle;25C0
+blacklenticularbracketleft;3010
+blacklenticularbracketleftvertical;FE3B
+blacklenticularbracketright;3011
+blacklenticularbracketrightvertical;FE3C
+blacklowerlefttriangle;25E3
+blacklowerrighttriangle;25E2
+blackrectangle;25AC
+blackrightpointingpointer;25BA
+blackrightpointingtriangle;25B6
+blacksmallsquare;25AA
+blacksmilingface;263B
+blacksquare;25A0
+blackstar;2605
+blackupperlefttriangle;25E4
+blackupperrighttriangle;25E5
+blackuppointingsmalltriangle;25B4
+blackuppointingtriangle;25B2
+blank;2423
+blinebelow;1E07
+block;2588
+bmonospace;FF42
+bobaimaithai;0E1A
+bohiragana;307C
+bokatakana;30DC
+bparen;249D
+bqsquare;33C3
+braceex;F8F4
+braceleft;007B
+braceleftbt;F8F3
+braceleftmid;F8F2
+braceleftmonospace;FF5B
+braceleftsmall;FE5B
+bracelefttp;F8F1
+braceleftvertical;FE37
+braceright;007D
+bracerightbt;F8FE
+bracerightmid;F8FD
+bracerightmonospace;FF5D
+bracerightsmall;FE5C
+bracerighttp;F8FC
+bracerightvertical;FE38
+bracketleft;005B
+bracketleftbt;F8F0
+bracketleftex;F8EF
+bracketleftmonospace;FF3B
+bracketlefttp;F8EE
+bracketright;005D
+bracketrightbt;F8FB
+bracketrightex;F8FA
+bracketrightmonospace;FF3D
+bracketrighttp;F8F9
+breve;02D8
+brevebelowcmb;032E
+brevecmb;0306
+breveinvertedbelowcmb;032F
+breveinvertedcmb;0311
+breveinverteddoublecmb;0361
+bridgebelowcmb;032A
+bridgeinvertedbelowcmb;033A
+brokenbar;00A6
+bstroke;0180
+bsuperior;F6EA
+btopbar;0183
+buhiragana;3076
+bukatakana;30D6
+bullet;2022
+bulletinverse;25D8
+bulletoperator;2219
+bullseye;25CE
+c;0063
+caarmenian;056E
+cabengali;099A
+cacute;0107
+cadeva;091A
+cagujarati;0A9A
+cagurmukhi;0A1A
+calsquare;3388
+candrabindubengali;0981
+candrabinducmb;0310
+candrabindudeva;0901
+candrabindugujarati;0A81
+capslock;21EA
+careof;2105
+caron;02C7
+caronbelowcmb;032C
+caroncmb;030C
+carriagereturn;21B5
+cbopomofo;3118
+ccaron;010D
+ccedilla;00E7
+ccedillaacute;1E09
+ccircle;24D2
+ccircumflex;0109
+ccurl;0255
+cdot;010B
+cdotaccent;010B
+cdsquare;33C5
+cedilla;00B8
+cedillacmb;0327
+cent;00A2
+centigrade;2103
+centinferior;F6DF
+centmonospace;FFE0
+centoldstyle;F7A2
+centsuperior;F6E0
+chaarmenian;0579
+chabengali;099B
+chadeva;091B
+chagujarati;0A9B
+chagurmukhi;0A1B
+chbopomofo;3114
+cheabkhasiancyrillic;04BD
+checkmark;2713
+checyrillic;0447
+chedescenderabkhasiancyrillic;04BF
+chedescendercyrillic;04B7
+chedieresiscyrillic;04F5
+cheharmenian;0573
+chekhakassiancyrillic;04CC
+cheverticalstrokecyrillic;04B9
+chi;03C7
+chieuchacirclekorean;3277
+chieuchaparenkorean;3217
+chieuchcirclekorean;3269
+chieuchkorean;314A
+chieuchparenkorean;3209
+chochangthai;0E0A
+chochanthai;0E08
+chochingthai;0E09
+chochoethai;0E0C
+chook;0188
+cieucacirclekorean;3276
+cieucaparenkorean;3216
+cieuccirclekorean;3268
+cieuckorean;3148
+cieucparenkorean;3208
+cieucuparenkorean;321C
+circle;25CB
+circlemultiply;2297
+circleot;2299
+circleplus;2295
+circlepostalmark;3036
+circlewithlefthalfblack;25D0
+circlewithrighthalfblack;25D1
+circumflex;02C6
+circumflexbelowcmb;032D
+circumflexcmb;0302
+clear;2327
+clickalveolar;01C2
+clickdental;01C0
+clicklateral;01C1
+clickretroflex;01C3
+club;2663
+clubsuitblack;2663
+clubsuitwhite;2667
+cmcubedsquare;33A4
+cmonospace;FF43
+cmsquaredsquare;33A0
+coarmenian;0581
+colon;003A
+colonmonetary;20A1
+colonmonospace;FF1A
+colonsign;20A1
+colonsmall;FE55
+colontriangularhalfmod;02D1
+colontriangularmod;02D0
+comma;002C
+commaabovecmb;0313
+commaaboverightcmb;0315
+commaaccent;F6C3
+commaarabic;060C
+commaarmenian;055D
+commainferior;F6E1
+commamonospace;FF0C
+commareversedabovecmb;0314
+commareversedmod;02BD
+commasmall;FE50
+commasuperior;F6E2
+commaturnedabovecmb;0312
+commaturnedmod;02BB
+compass;263C
+congruent;2245
+contourintegral;222E
+control;2303
+controlACK;0006
+controlBEL;0007
+controlBS;0008
+controlCAN;0018
+controlCR;000D
+controlDC1;0011
+controlDC2;0012
+controlDC3;0013
+controlDC4;0014
+controlDEL;007F
+controlDLE;0010
+controlEM;0019
+controlENQ;0005
+controlEOT;0004
+controlESC;001B
+controlETB;0017
+controlETX;0003
+controlFF;000C
+controlFS;001C
+controlGS;001D
+controlHT;0009
+controlLF;000A
+controlNAK;0015
+controlRS;001E
+controlSI;000F
+controlSO;000E
+controlSOT;0002
+controlSTX;0001
+controlSUB;001A
+controlSYN;0016
+controlUS;001F
+controlVT;000B
+copyright;00A9
+copyrightsans;F8E9
+copyrightserif;F6D9
+cornerbracketleft;300C
+cornerbracketlefthalfwidth;FF62
+cornerbracketleftvertical;FE41
+cornerbracketright;300D
+cornerbracketrighthalfwidth;FF63
+cornerbracketrightvertical;FE42
+corporationsquare;337F
+cosquare;33C7
+coverkgsquare;33C6
+cparen;249E
+cruzeiro;20A2
+cstretched;0297
+curlyand;22CF
+curlyor;22CE
+currency;00A4
+cyrBreve;F6D1
+cyrFlex;F6D2
+cyrbreve;F6D4
+cyrflex;F6D5
+d;0064
+daarmenian;0564
+dabengali;09A6
+dadarabic;0636
+dadeva;0926
+dadfinalarabic;FEBE
+dadinitialarabic;FEBF
+dadmedialarabic;FEC0
+dagesh;05BC
+dageshhebrew;05BC
+dagger;2020
+daggerdbl;2021
+dagujarati;0AA6
+dagurmukhi;0A26
+dahiragana;3060
+dakatakana;30C0
+dalarabic;062F
+dalet;05D3
+daletdagesh;FB33
+daletdageshhebrew;FB33
+dalethatafpatah;05D3 05B2
+dalethatafpatahhebrew;05D3 05B2
+dalethatafsegol;05D3 05B1
+dalethatafsegolhebrew;05D3 05B1
+dalethebrew;05D3
+dalethiriq;05D3 05B4
+dalethiriqhebrew;05D3 05B4
+daletholam;05D3 05B9
+daletholamhebrew;05D3 05B9
+daletpatah;05D3 05B7
+daletpatahhebrew;05D3 05B7
+daletqamats;05D3 05B8
+daletqamatshebrew;05D3 05B8
+daletqubuts;05D3 05BB
+daletqubutshebrew;05D3 05BB
+daletsegol;05D3 05B6
+daletsegolhebrew;05D3 05B6
+daletsheva;05D3 05B0
+daletshevahebrew;05D3 05B0
+dalettsere;05D3 05B5
+dalettserehebrew;05D3 05B5
+dalfinalarabic;FEAA
+dammaarabic;064F
+dammalowarabic;064F
+dammatanaltonearabic;064C
+dammatanarabic;064C
+danda;0964
+dargahebrew;05A7
+dargalefthebrew;05A7
+dasiapneumatacyrilliccmb;0485
+dblGrave;F6D3
+dblanglebracketleft;300A
+dblanglebracketleftvertical;FE3D
+dblanglebracketright;300B
+dblanglebracketrightvertical;FE3E
+dblarchinvertedbelowcmb;032B
+dblarrowleft;21D4
+dblarrowright;21D2
+dbldanda;0965
+dblgrave;F6D6
+dblgravecmb;030F
+dblintegral;222C
+dbllowline;2017
+dbllowlinecmb;0333
+dbloverlinecmb;033F
+dblprimemod;02BA
+dblverticalbar;2016
+dblverticallineabovecmb;030E
+dbopomofo;3109
+dbsquare;33C8
+dcaron;010F
+dcedilla;1E11
+dcircle;24D3
+dcircumflexbelow;1E13
+dcroat;0111
+ddabengali;09A1
+ddadeva;0921
+ddagujarati;0AA1
+ddagurmukhi;0A21
+ddalarabic;0688
+ddalfinalarabic;FB89
+dddhadeva;095C
+ddhabengali;09A2
+ddhadeva;0922
+ddhagujarati;0AA2
+ddhagurmukhi;0A22
+ddotaccent;1E0B
+ddotbelow;1E0D
+decimalseparatorarabic;066B
+decimalseparatorpersian;066B
+decyrillic;0434
+degree;00B0
+dehihebrew;05AD
+dehiragana;3067
+deicoptic;03EF
+dekatakana;30C7
+deleteleft;232B
+deleteright;2326
+delta;03B4
+deltaturned;018D
+denominatorminusonenumeratorbengali;09F8
+dezh;02A4
+dhabengali;09A7
+dhadeva;0927
+dhagujarati;0AA7
+dhagurmukhi;0A27
+dhook;0257
+dialytikatonos;0385
+dialytikatonoscmb;0344
+diamond;2666
+diamondsuitwhite;2662
+dieresis;00A8
+dieresisacute;F6D7
+dieresisbelowcmb;0324
+dieresiscmb;0308
+dieresisgrave;F6D8
+dieresistonos;0385
+dihiragana;3062
+dikatakana;30C2
+dittomark;3003
+divide;00F7
+divides;2223
+divisionslash;2215
+djecyrillic;0452
+dkshade;2593
+dlinebelow;1E0F
+dlsquare;3397
+dmacron;0111
+dmonospace;FF44
+dnblock;2584
+dochadathai;0E0E
+dodekthai;0E14
+dohiragana;3069
+dokatakana;30C9
+dollar;0024
+dollarinferior;F6E3
+dollarmonospace;FF04
+dollaroldstyle;F724
+dollarsmall;FE69
+dollarsuperior;F6E4
+dong;20AB
+dorusquare;3326
+dotaccent;02D9
+dotaccentcmb;0307
+dotbelowcmb;0323
+dotbelowcomb;0323
+dotkatakana;30FB
+dotlessi;0131
+dotlessj;F6BE
+dotlessjstrokehook;0284
+dotmath;22C5
+dottedcircle;25CC
+doubleyodpatah;FB1F
+doubleyodpatahhebrew;FB1F
+downtackbelowcmb;031E
+downtackmod;02D5
+dparen;249F
+dsuperior;F6EB
+dtail;0256
+dtopbar;018C
+duhiragana;3065
+dukatakana;30C5
+dz;01F3
+dzaltone;02A3
+dzcaron;01C6
+dzcurl;02A5
+dzeabkhasiancyrillic;04E1
+dzecyrillic;0455
+dzhecyrillic;045F
+e;0065
+eacute;00E9
+earth;2641
+ebengali;098F
+ebopomofo;311C
+ebreve;0115
+ecandradeva;090D
+ecandragujarati;0A8D
+ecandravowelsigndeva;0945
+ecandravowelsigngujarati;0AC5
+ecaron;011B
+ecedillabreve;1E1D
+echarmenian;0565
+echyiwnarmenian;0587
+ecircle;24D4
+ecircumflex;00EA
+ecircumflexacute;1EBF
+ecircumflexbelow;1E19
+ecircumflexdotbelow;1EC7
+ecircumflexgrave;1EC1
+ecircumflexhookabove;1EC3
+ecircumflextilde;1EC5
+ecyrillic;0454
+edblgrave;0205
+edeva;090F
+edieresis;00EB
+edot;0117
+edotaccent;0117
+edotbelow;1EB9
+eegurmukhi;0A0F
+eematragurmukhi;0A47
+efcyrillic;0444
+egrave;00E8
+egujarati;0A8F
+eharmenian;0567
+ehbopomofo;311D
+ehiragana;3048
+ehookabove;1EBB
+eibopomofo;311F
+eight;0038
+eightarabic;0668
+eightbengali;09EE
+eightcircle;2467
+eightcircleinversesansserif;2791
+eightdeva;096E
+eighteencircle;2471
+eighteenparen;2485
+eighteenperiod;2499
+eightgujarati;0AEE
+eightgurmukhi;0A6E
+eighthackarabic;0668
+eighthangzhou;3028
+eighthnotebeamed;266B
+eightideographicparen;3227
+eightinferior;2088
+eightmonospace;FF18
+eightoldstyle;F738
+eightparen;247B
+eightperiod;248F
+eightpersian;06F8
+eightroman;2177
+eightsuperior;2078
+eightthai;0E58
+einvertedbreve;0207
+eiotifiedcyrillic;0465
+ekatakana;30A8
+ekatakanahalfwidth;FF74
+ekonkargurmukhi;0A74
+ekorean;3154
+elcyrillic;043B
+element;2208
+elevencircle;246A
+elevenparen;247E
+elevenperiod;2492
+elevenroman;217A
+ellipsis;2026
+ellipsisvertical;22EE
+emacron;0113
+emacronacute;1E17
+emacrongrave;1E15
+emcyrillic;043C
+emdash;2014
+emdashvertical;FE31
+emonospace;FF45
+emphasismarkarmenian;055B
+emptyset;2205
+enbopomofo;3123
+encyrillic;043D
+endash;2013
+endashvertical;FE32
+endescendercyrillic;04A3
+eng;014B
+engbopomofo;3125
+enghecyrillic;04A5
+enhookcyrillic;04C8
+enspace;2002
+eogonek;0119
+eokorean;3153
+eopen;025B
+eopenclosed;029A
+eopenreversed;025C
+eopenreversedclosed;025E
+eopenreversedhook;025D
+eparen;24A0
+epsilon;03B5
+epsilontonos;03AD
+equal;003D
+equalmonospace;FF1D
+equalsmall;FE66
+equalsuperior;207C
+equivalence;2261
+erbopomofo;3126
+ercyrillic;0440
+ereversed;0258
+ereversedcyrillic;044D
+escyrillic;0441
+esdescendercyrillic;04AB
+esh;0283
+eshcurl;0286
+eshortdeva;090E
+eshortvowelsigndeva;0946
+eshreversedloop;01AA
+eshsquatreversed;0285
+esmallhiragana;3047
+esmallkatakana;30A7
+esmallkatakanahalfwidth;FF6A
+estimated;212E
+esuperior;F6EC
+eta;03B7
+etarmenian;0568
+etatonos;03AE
+eth;00F0
+etilde;1EBD
+etildebelow;1E1B
+etnahtafoukhhebrew;0591
+etnahtafoukhlefthebrew;0591
+etnahtahebrew;0591
+etnahtalefthebrew;0591
+eturned;01DD
+eukorean;3161
+euro;20AC
+evowelsignbengali;09C7
+evowelsigndeva;0947
+evowelsigngujarati;0AC7
+exclam;0021
+exclamarmenian;055C
+exclamdbl;203C
+exclamdown;00A1
+exclamdownsmall;F7A1
+exclammonospace;FF01
+exclamsmall;F721
+existential;2203
+ezh;0292
+ezhcaron;01EF
+ezhcurl;0293
+ezhreversed;01B9
+ezhtail;01BA
+f;0066
+fadeva;095E
+fagurmukhi;0A5E
+fahrenheit;2109
+fathaarabic;064E
+fathalowarabic;064E
+fathatanarabic;064B
+fbopomofo;3108
+fcircle;24D5
+fdotaccent;1E1F
+feharabic;0641
+feharmenian;0586
+fehfinalarabic;FED2
+fehinitialarabic;FED3
+fehmedialarabic;FED4
+feicoptic;03E5
+female;2640
+ff;FB00
+ffi;FB03
+ffl;FB04
+fi;FB01
+fifteencircle;246E
+fifteenparen;2482
+fifteenperiod;2496
+figuredash;2012
+filledbox;25A0
+filledrect;25AC
+finalkaf;05DA
+finalkafdagesh;FB3A
+finalkafdageshhebrew;FB3A
+finalkafhebrew;05DA
+finalkafqamats;05DA 05B8
+finalkafqamatshebrew;05DA 05B8
+finalkafsheva;05DA 05B0
+finalkafshevahebrew;05DA 05B0
+finalmem;05DD
+finalmemhebrew;05DD
+finalnun;05DF
+finalnunhebrew;05DF
+finalpe;05E3
+finalpehebrew;05E3
+finaltsadi;05E5
+finaltsadihebrew;05E5
+firsttonechinese;02C9
+fisheye;25C9
+fitacyrillic;0473
+five;0035
+fivearabic;0665
+fivebengali;09EB
+fivecircle;2464
+fivecircleinversesansserif;278E
+fivedeva;096B
+fiveeighths;215D
+fivegujarati;0AEB
+fivegurmukhi;0A6B
+fivehackarabic;0665
+fivehangzhou;3025
+fiveideographicparen;3224
+fiveinferior;2085
+fivemonospace;FF15
+fiveoldstyle;F735
+fiveparen;2478
+fiveperiod;248C
+fivepersian;06F5
+fiveroman;2174
+fivesuperior;2075
+fivethai;0E55
+fl;FB02
+florin;0192
+fmonospace;FF46
+fmsquare;3399
+fofanthai;0E1F
+fofathai;0E1D
+fongmanthai;0E4F
+forall;2200
+four;0034
+fourarabic;0664
+fourbengali;09EA
+fourcircle;2463
+fourcircleinversesansserif;278D
+fourdeva;096A
+fourgujarati;0AEA
+fourgurmukhi;0A6A
+fourhackarabic;0664
+fourhangzhou;3024
+fourideographicparen;3223
+fourinferior;2084
+fourmonospace;FF14
+fournumeratorbengali;09F7
+fouroldstyle;F734
+fourparen;2477
+fourperiod;248B
+fourpersian;06F4
+fourroman;2173
+foursuperior;2074
+fourteencircle;246D
+fourteenparen;2481
+fourteenperiod;2495
+fourthai;0E54
+fourthtonechinese;02CB
+fparen;24A1
+fraction;2044
+franc;20A3
+g;0067
+gabengali;0997
+gacute;01F5
+gadeva;0917
+gafarabic;06AF
+gaffinalarabic;FB93
+gafinitialarabic;FB94
+gafmedialarabic;FB95
+gagujarati;0A97
+gagurmukhi;0A17
+gahiragana;304C
+gakatakana;30AC
+gamma;03B3
+gammalatinsmall;0263
+gammasuperior;02E0
+gangiacoptic;03EB
+gbopomofo;310D
+gbreve;011F
+gcaron;01E7
+gcedilla;0123
+gcircle;24D6
+gcircumflex;011D
+gcommaaccent;0123
+gdot;0121
+gdotaccent;0121
+gecyrillic;0433
+gehiragana;3052
+gekatakana;30B2
+geometricallyequal;2251
+gereshaccenthebrew;059C
+gereshhebrew;05F3
+gereshmuqdamhebrew;059D
+germandbls;00DF
+gershayimaccenthebrew;059E
+gershayimhebrew;05F4
+getamark;3013
+ghabengali;0998
+ghadarmenian;0572
+ghadeva;0918
+ghagujarati;0A98
+ghagurmukhi;0A18
+ghainarabic;063A
+ghainfinalarabic;FECE
+ghaininitialarabic;FECF
+ghainmedialarabic;FED0
+ghemiddlehookcyrillic;0495
+ghestrokecyrillic;0493
+gheupturncyrillic;0491
+ghhadeva;095A
+ghhagurmukhi;0A5A
+ghook;0260
+ghzsquare;3393
+gihiragana;304E
+gikatakana;30AE
+gimarmenian;0563
+gimel;05D2
+gimeldagesh;FB32
+gimeldageshhebrew;FB32
+gimelhebrew;05D2
+gjecyrillic;0453
+glottalinvertedstroke;01BE
+glottalstop;0294
+glottalstopinverted;0296
+glottalstopmod;02C0
+glottalstopreversed;0295
+glottalstopreversedmod;02C1
+glottalstopreversedsuperior;02E4
+glottalstopstroke;02A1
+glottalstopstrokereversed;02A2
+gmacron;1E21
+gmonospace;FF47
+gohiragana;3054
+gokatakana;30B4
+gparen;24A2
+gpasquare;33AC
+gradient;2207
+grave;0060
+gravebelowcmb;0316
+gravecmb;0300
+gravecomb;0300
+gravedeva;0953
+gravelowmod;02CE
+gravemonospace;FF40
+gravetonecmb;0340
+greater;003E
+greaterequal;2265
+greaterequalorless;22DB
+greatermonospace;FF1E
+greaterorequivalent;2273
+greaterorless;2277
+greateroverequal;2267
+greatersmall;FE65
+gscript;0261
+gstroke;01E5
+guhiragana;3050
+guillemotleft;00AB
+guillemotright;00BB
+guilsinglleft;2039
+guilsinglright;203A
+gukatakana;30B0
+guramusquare;3318
+gysquare;33C9
+h;0068
+haabkhasiancyrillic;04A9
+haaltonearabic;06C1
+habengali;09B9
+hadescendercyrillic;04B3
+hadeva;0939
+hagujarati;0AB9
+hagurmukhi;0A39
+haharabic;062D
+hahfinalarabic;FEA2
+hahinitialarabic;FEA3
+hahiragana;306F
+hahmedialarabic;FEA4
+haitusquare;332A
+hakatakana;30CF
+hakatakanahalfwidth;FF8A
+halantgurmukhi;0A4D
+hamzaarabic;0621
+hamzadammaarabic;0621 064F
+hamzadammatanarabic;0621 064C
+hamzafathaarabic;0621 064E
+hamzafathatanarabic;0621 064B
+hamzalowarabic;0621
+hamzalowkasraarabic;0621 0650
+hamzalowkasratanarabic;0621 064D
+hamzasukunarabic;0621 0652
+hangulfiller;3164
+hardsigncyrillic;044A
+harpoonleftbarbup;21BC
+harpoonrightbarbup;21C0
+hasquare;33CA
+hatafpatah;05B2
+hatafpatah16;05B2
+hatafpatah23;05B2
+hatafpatah2f;05B2
+hatafpatahhebrew;05B2
+hatafpatahnarrowhebrew;05B2
+hatafpatahquarterhebrew;05B2
+hatafpatahwidehebrew;05B2
+hatafqamats;05B3
+hatafqamats1b;05B3
+hatafqamats28;05B3
+hatafqamats34;05B3
+hatafqamatshebrew;05B3
+hatafqamatsnarrowhebrew;05B3
+hatafqamatsquarterhebrew;05B3
+hatafqamatswidehebrew;05B3
+hatafsegol;05B1
+hatafsegol17;05B1
+hatafsegol24;05B1
+hatafsegol30;05B1
+hatafsegolhebrew;05B1
+hatafsegolnarrowhebrew;05B1
+hatafsegolquarterhebrew;05B1
+hatafsegolwidehebrew;05B1
+hbar;0127
+hbopomofo;310F
+hbrevebelow;1E2B
+hcedilla;1E29
+hcircle;24D7
+hcircumflex;0125
+hdieresis;1E27
+hdotaccent;1E23
+hdotbelow;1E25
+he;05D4
+heart;2665
+heartsuitblack;2665
+heartsuitwhite;2661
+hedagesh;FB34
+hedageshhebrew;FB34
+hehaltonearabic;06C1
+heharabic;0647
+hehebrew;05D4
+hehfinalaltonearabic;FBA7
+hehfinalalttwoarabic;FEEA
+hehfinalarabic;FEEA
+hehhamzaabovefinalarabic;FBA5
+hehhamzaaboveisolatedarabic;FBA4
+hehinitialaltonearabic;FBA8
+hehinitialarabic;FEEB
+hehiragana;3078
+hehmedialaltonearabic;FBA9
+hehmedialarabic;FEEC
+heiseierasquare;337B
+hekatakana;30D8
+hekatakanahalfwidth;FF8D
+hekutaarusquare;3336
+henghook;0267
+herutusquare;3339
+het;05D7
+hethebrew;05D7
+hhook;0266
+hhooksuperior;02B1
+hieuhacirclekorean;327B
+hieuhaparenkorean;321B
+hieuhcirclekorean;326D
+hieuhkorean;314E
+hieuhparenkorean;320D
+hihiragana;3072
+hikatakana;30D2
+hikatakanahalfwidth;FF8B
+hiriq;05B4
+hiriq14;05B4
+hiriq21;05B4
+hiriq2d;05B4
+hiriqhebrew;05B4
+hiriqnarrowhebrew;05B4
+hiriqquarterhebrew;05B4
+hiriqwidehebrew;05B4
+hlinebelow;1E96
+hmonospace;FF48
+hoarmenian;0570
+hohipthai;0E2B
+hohiragana;307B
+hokatakana;30DB
+hokatakanahalfwidth;FF8E
+holam;05B9
+holam19;05B9
+holam26;05B9
+holam32;05B9
+holamhebrew;05B9
+holamnarrowhebrew;05B9
+holamquarterhebrew;05B9
+holamwidehebrew;05B9
+honokhukthai;0E2E
+hookabovecomb;0309
+hookcmb;0309
+hookpalatalizedbelowcmb;0321
+hookretroflexbelowcmb;0322
+hoonsquare;3342
+horicoptic;03E9
+horizontalbar;2015
+horncmb;031B
+hotsprings;2668
+house;2302
+hparen;24A3
+hsuperior;02B0
+hturned;0265
+huhiragana;3075
+huiitosquare;3333
+hukatakana;30D5
+hukatakanahalfwidth;FF8C
+hungarumlaut;02DD
+hungarumlautcmb;030B
+hv;0195
+hyphen;002D
+hypheninferior;F6E5
+hyphenmonospace;FF0D
+hyphensmall;FE63
+hyphensuperior;F6E6
+hyphentwo;2010
+i;0069
+iacute;00ED
+iacyrillic;044F
+ibengali;0987
+ibopomofo;3127
+ibreve;012D
+icaron;01D0
+icircle;24D8
+icircumflex;00EE
+icyrillic;0456
+idblgrave;0209
+ideographearthcircle;328F
+ideographfirecircle;328B
+ideographicallianceparen;323F
+ideographiccallparen;323A
+ideographiccentrecircle;32A5
+ideographicclose;3006
+ideographiccomma;3001
+ideographiccommaleft;FF64
+ideographiccongratulationparen;3237
+ideographiccorrectcircle;32A3
+ideographicearthparen;322F
+ideographicenterpriseparen;323D
+ideographicexcellentcircle;329D
+ideographicfestivalparen;3240
+ideographicfinancialcircle;3296
+ideographicfinancialparen;3236
+ideographicfireparen;322B
+ideographichaveparen;3232
+ideographichighcircle;32A4
+ideographiciterationmark;3005
+ideographiclaborcircle;3298
+ideographiclaborparen;3238
+ideographicleftcircle;32A7
+ideographiclowcircle;32A6
+ideographicmedicinecircle;32A9
+ideographicmetalparen;322E
+ideographicmoonparen;322A
+ideographicnameparen;3234
+ideographicperiod;3002
+ideographicprintcircle;329E
+ideographicreachparen;3243
+ideographicrepresentparen;3239
+ideographicresourceparen;323E
+ideographicrightcircle;32A8
+ideographicsecretcircle;3299
+ideographicselfparen;3242
+ideographicsocietyparen;3233
+ideographicspace;3000
+ideographicspecialparen;3235
+ideographicstockparen;3231
+ideographicstudyparen;323B
+ideographicsunparen;3230
+ideographicsuperviseparen;323C
+ideographicwaterparen;322C
+ideographicwoodparen;322D
+ideographiczero;3007
+ideographmetalcircle;328E
+ideographmooncircle;328A
+ideographnamecircle;3294
+ideographsuncircle;3290
+ideographwatercircle;328C
+ideographwoodcircle;328D
+ideva;0907
+idieresis;00EF
+idieresisacute;1E2F
+idieresiscyrillic;04E5
+idotbelow;1ECB
+iebrevecyrillic;04D7
+iecyrillic;0435
+ieungacirclekorean;3275
+ieungaparenkorean;3215
+ieungcirclekorean;3267
+ieungkorean;3147
+ieungparenkorean;3207
+igrave;00EC
+igujarati;0A87
+igurmukhi;0A07
+ihiragana;3044
+ihookabove;1EC9
+iibengali;0988
+iicyrillic;0438
+iideva;0908
+iigujarati;0A88
+iigurmukhi;0A08
+iimatragurmukhi;0A40
+iinvertedbreve;020B
+iishortcyrillic;0439
+iivowelsignbengali;09C0
+iivowelsigndeva;0940
+iivowelsigngujarati;0AC0
+ij;0133
+ikatakana;30A4
+ikatakanahalfwidth;FF72
+ikorean;3163
+ilde;02DC
+iluyhebrew;05AC
+imacron;012B
+imacroncyrillic;04E3
+imageorapproximatelyequal;2253
+imatragurmukhi;0A3F
+imonospace;FF49
+increment;2206
+infinity;221E
+iniarmenian;056B
+integral;222B
+integralbottom;2321
+integralbt;2321
+integralex;F8F5
+integraltop;2320
+integraltp;2320
+intersection;2229
+intisquare;3305
+invbullet;25D8
+invcircle;25D9
+invsmileface;263B
+iocyrillic;0451
+iogonek;012F
+iota;03B9
+iotadieresis;03CA
+iotadieresistonos;0390
+iotalatin;0269
+iotatonos;03AF
+iparen;24A4
+irigurmukhi;0A72
+ismallhiragana;3043
+ismallkatakana;30A3
+ismallkatakanahalfwidth;FF68
+issharbengali;09FA
+istroke;0268
+isuperior;F6ED
+iterationhiragana;309D
+iterationkatakana;30FD
+itilde;0129
+itildebelow;1E2D
+iubopomofo;3129
+iucyrillic;044E
+ivowelsignbengali;09BF
+ivowelsigndeva;093F
+ivowelsigngujarati;0ABF
+izhitsacyrillic;0475
+izhitsadblgravecyrillic;0477
+j;006A
+jaarmenian;0571
+jabengali;099C
+jadeva;091C
+jagujarati;0A9C
+jagurmukhi;0A1C
+jbopomofo;3110
+jcaron;01F0
+jcircle;24D9
+jcircumflex;0135
+jcrossedtail;029D
+jdotlessstroke;025F
+jecyrillic;0458
+jeemarabic;062C
+jeemfinalarabic;FE9E
+jeeminitialarabic;FE9F
+jeemmedialarabic;FEA0
+jeharabic;0698
+jehfinalarabic;FB8B
+jhabengali;099D
+jhadeva;091D
+jhagujarati;0A9D
+jhagurmukhi;0A1D
+jheharmenian;057B
+jis;3004
+jmonospace;FF4A
+jparen;24A5
+jsuperior;02B2
+k;006B
+kabashkircyrillic;04A1
+kabengali;0995
+kacute;1E31
+kacyrillic;043A
+kadescendercyrillic;049B
+kadeva;0915
+kaf;05DB
+kafarabic;0643
+kafdagesh;FB3B
+kafdageshhebrew;FB3B
+kaffinalarabic;FEDA
+kafhebrew;05DB
+kafinitialarabic;FEDB
+kafmedialarabic;FEDC
+kafrafehebrew;FB4D
+kagujarati;0A95
+kagurmukhi;0A15
+kahiragana;304B
+kahookcyrillic;04C4
+kakatakana;30AB
+kakatakanahalfwidth;FF76
+kappa;03BA
+kappasymbolgreek;03F0
+kapyeounmieumkorean;3171
+kapyeounphieuphkorean;3184
+kapyeounpieupkorean;3178
+kapyeounssangpieupkorean;3179
+karoriisquare;330D
+kashidaautoarabic;0640
+kashidaautonosidebearingarabic;0640
+kasmallkatakana;30F5
+kasquare;3384
+kasraarabic;0650
+kasratanarabic;064D
+kastrokecyrillic;049F
+katahiraprolongmarkhalfwidth;FF70
+kaverticalstrokecyrillic;049D
+kbopomofo;310E
+kcalsquare;3389
+kcaron;01E9
+kcedilla;0137
+kcircle;24DA
+kcommaaccent;0137
+kdotbelow;1E33
+keharmenian;0584
+kehiragana;3051
+kekatakana;30B1
+kekatakanahalfwidth;FF79
+kenarmenian;056F
+kesmallkatakana;30F6
+kgreenlandic;0138
+khabengali;0996
+khacyrillic;0445
+khadeva;0916
+khagujarati;0A96
+khagurmukhi;0A16
+khaharabic;062E
+khahfinalarabic;FEA6
+khahinitialarabic;FEA7
+khahmedialarabic;FEA8
+kheicoptic;03E7
+khhadeva;0959
+khhagurmukhi;0A59
+khieukhacirclekorean;3278
+khieukhaparenkorean;3218
+khieukhcirclekorean;326A
+khieukhkorean;314B
+khieukhparenkorean;320A
+khokhaithai;0E02
+khokhonthai;0E05
+khokhuatthai;0E03
+khokhwaithai;0E04
+khomutthai;0E5B
+khook;0199
+khorakhangthai;0E06
+khzsquare;3391
+kihiragana;304D
+kikatakana;30AD
+kikatakanahalfwidth;FF77
+kiroguramusquare;3315
+kiromeetorusquare;3316
+kirosquare;3314
+kiyeokacirclekorean;326E
+kiyeokaparenkorean;320E
+kiyeokcirclekorean;3260
+kiyeokkorean;3131
+kiyeokparenkorean;3200
+kiyeoksioskorean;3133
+kjecyrillic;045C
+klinebelow;1E35
+klsquare;3398
+kmcubedsquare;33A6
+kmonospace;FF4B
+kmsquaredsquare;33A2
+kohiragana;3053
+kohmsquare;33C0
+kokaithai;0E01
+kokatakana;30B3
+kokatakanahalfwidth;FF7A
+kooposquare;331E
+koppacyrillic;0481
+koreanstandardsymbol;327F
+koroniscmb;0343
+kparen;24A6
+kpasquare;33AA
+ksicyrillic;046F
+ktsquare;33CF
+kturned;029E
+kuhiragana;304F
+kukatakana;30AF
+kukatakanahalfwidth;FF78
+kvsquare;33B8
+kwsquare;33BE
+l;006C
+labengali;09B2
+lacute;013A
+ladeva;0932
+lagujarati;0AB2
+lagurmukhi;0A32
+lakkhangyaothai;0E45
+lamaleffinalarabic;FEFC
+lamalefhamzaabovefinalarabic;FEF8
+lamalefhamzaaboveisolatedarabic;FEF7
+lamalefhamzabelowfinalarabic;FEFA
+lamalefhamzabelowisolatedarabic;FEF9
+lamalefisolatedarabic;FEFB
+lamalefmaddaabovefinalarabic;FEF6
+lamalefmaddaaboveisolatedarabic;FEF5
+lamarabic;0644
+lambda;03BB
+lambdastroke;019B
+lamed;05DC
+lameddagesh;FB3C
+lameddageshhebrew;FB3C
+lamedhebrew;05DC
+lamedholam;05DC 05B9
+lamedholamdagesh;05DC 05B9 05BC
+lamedholamdageshhebrew;05DC 05B9 05BC
+lamedholamhebrew;05DC 05B9
+lamfinalarabic;FEDE
+lamhahinitialarabic;FCCA
+laminitialarabic;FEDF
+lamjeeminitialarabic;FCC9
+lamkhahinitialarabic;FCCB
+lamlamhehisolatedarabic;FDF2
+lammedialarabic;FEE0
+lammeemhahinitialarabic;FD88
+lammeeminitialarabic;FCCC
+lammeemjeeminitialarabic;FEDF FEE4 FEA0
+lammeemkhahinitialarabic;FEDF FEE4 FEA8
+largecircle;25EF
+lbar;019A
+lbelt;026C
+lbopomofo;310C
+lcaron;013E
+lcedilla;013C
+lcircle;24DB
+lcircumflexbelow;1E3D
+lcommaaccent;013C
+ldot;0140
+ldotaccent;0140
+ldotbelow;1E37
+ldotbelowmacron;1E39
+leftangleabovecmb;031A
+lefttackbelowcmb;0318
+less;003C
+lessequal;2264
+lessequalorgreater;22DA
+lessmonospace;FF1C
+lessorequivalent;2272
+lessorgreater;2276
+lessoverequal;2266
+lesssmall;FE64
+lezh;026E
+lfblock;258C
+lhookretroflex;026D
+lira;20A4
+liwnarmenian;056C
+lj;01C9
+ljecyrillic;0459
+ll;F6C0
+lladeva;0933
+llagujarati;0AB3
+llinebelow;1E3B
+llladeva;0934
+llvocalicbengali;09E1
+llvocalicdeva;0961
+llvocalicvowelsignbengali;09E3
+llvocalicvowelsigndeva;0963
+lmiddletilde;026B
+lmonospace;FF4C
+lmsquare;33D0
+lochulathai;0E2C
+logicaland;2227
+logicalnot;00AC
+logicalnotreversed;2310
+logicalor;2228
+lolingthai;0E25
+longs;017F
+lowlinecenterline;FE4E
+lowlinecmb;0332
+lowlinedashed;FE4D
+lozenge;25CA
+lparen;24A7
+lslash;0142
+lsquare;2113
+lsuperior;F6EE
+ltshade;2591
+luthai;0E26
+lvocalicbengali;098C
+lvocalicdeva;090C
+lvocalicvowelsignbengali;09E2
+lvocalicvowelsigndeva;0962
+lxsquare;33D3
+m;006D
+mabengali;09AE
+macron;00AF
+macronbelowcmb;0331
+macroncmb;0304
+macronlowmod;02CD
+macronmonospace;FFE3
+macute;1E3F
+madeva;092E
+magujarati;0AAE
+magurmukhi;0A2E
+mahapakhhebrew;05A4
+mahapakhlefthebrew;05A4
+mahiragana;307E
+maichattawalowleftthai;F895
+maichattawalowrightthai;F894
+maichattawathai;0E4B
+maichattawaupperleftthai;F893
+maieklowleftthai;F88C
+maieklowrightthai;F88B
+maiekthai;0E48
+maiekupperleftthai;F88A
+maihanakatleftthai;F884
+maihanakatthai;0E31
+maitaikhuleftthai;F889
+maitaikhuthai;0E47
+maitholowleftthai;F88F
+maitholowrightthai;F88E
+maithothai;0E49
+maithoupperleftthai;F88D
+maitrilowleftthai;F892
+maitrilowrightthai;F891
+maitrithai;0E4A
+maitriupperleftthai;F890
+maiyamokthai;0E46
+makatakana;30DE
+makatakanahalfwidth;FF8F
+male;2642
+mansyonsquare;3347
+maqafhebrew;05BE
+mars;2642
+masoracirclehebrew;05AF
+masquare;3383
+mbopomofo;3107
+mbsquare;33D4
+mcircle;24DC
+mcubedsquare;33A5
+mdotaccent;1E41
+mdotbelow;1E43
+meemarabic;0645
+meemfinalarabic;FEE2
+meeminitialarabic;FEE3
+meemmedialarabic;FEE4
+meemmeeminitialarabic;FCD1
+meemmeemisolatedarabic;FC48
+meetorusquare;334D
+mehiragana;3081
+meizierasquare;337E
+mekatakana;30E1
+mekatakanahalfwidth;FF92
+mem;05DE
+memdagesh;FB3E
+memdageshhebrew;FB3E
+memhebrew;05DE
+menarmenian;0574
+merkhahebrew;05A5
+merkhakefulahebrew;05A6
+merkhakefulalefthebrew;05A6
+merkhalefthebrew;05A5
+mhook;0271
+mhzsquare;3392
+middledotkatakanahalfwidth;FF65
+middot;00B7
+mieumacirclekorean;3272
+mieumaparenkorean;3212
+mieumcirclekorean;3264
+mieumkorean;3141
+mieumpansioskorean;3170
+mieumparenkorean;3204
+mieumpieupkorean;316E
+mieumsioskorean;316F
+mihiragana;307F
+mikatakana;30DF
+mikatakanahalfwidth;FF90
+minus;2212
+minusbelowcmb;0320
+minuscircle;2296
+minusmod;02D7
+minusplus;2213
+minute;2032
+miribaarusquare;334A
+mirisquare;3349
+mlonglegturned;0270
+mlsquare;3396
+mmcubedsquare;33A3
+mmonospace;FF4D
+mmsquaredsquare;339F
+mohiragana;3082
+mohmsquare;33C1
+mokatakana;30E2
+mokatakanahalfwidth;FF93
+molsquare;33D6
+momathai;0E21
+moverssquare;33A7
+moverssquaredsquare;33A8
+mparen;24A8
+mpasquare;33AB
+mssquare;33B3
+msuperior;F6EF
+mturned;026F
+mu;00B5
+mu1;00B5
+muasquare;3382
+muchgreater;226B
+muchless;226A
+mufsquare;338C
+mugreek;03BC
+mugsquare;338D
+muhiragana;3080
+mukatakana;30E0
+mukatakanahalfwidth;FF91
+mulsquare;3395
+multiply;00D7
+mumsquare;339B
+munahhebrew;05A3
+munahlefthebrew;05A3
+musicalnote;266A
+musicalnotedbl;266B
+musicflatsign;266D
+musicsharpsign;266F
+mussquare;33B2
+muvsquare;33B6
+muwsquare;33BC
+mvmegasquare;33B9
+mvsquare;33B7
+mwmegasquare;33BF
+mwsquare;33BD
+n;006E
+nabengali;09A8
+nabla;2207
+nacute;0144
+nadeva;0928
+nagujarati;0AA8
+nagurmukhi;0A28
+nahiragana;306A
+nakatakana;30CA
+nakatakanahalfwidth;FF85
+napostrophe;0149
+nasquare;3381
+nbopomofo;310B
+nbspace;00A0
+ncaron;0148
+ncedilla;0146
+ncircle;24DD
+ncircumflexbelow;1E4B
+ncommaaccent;0146
+ndotaccent;1E45
+ndotbelow;1E47
+nehiragana;306D
+nekatakana;30CD
+nekatakanahalfwidth;FF88
+newsheqelsign;20AA
+nfsquare;338B
+ngabengali;0999
+ngadeva;0919
+ngagujarati;0A99
+ngagurmukhi;0A19
+ngonguthai;0E07
+nhiragana;3093
+nhookleft;0272
+nhookretroflex;0273
+nieunacirclekorean;326F
+nieunaparenkorean;320F
+nieuncieuckorean;3135
+nieuncirclekorean;3261
+nieunhieuhkorean;3136
+nieunkorean;3134
+nieunpansioskorean;3168
+nieunparenkorean;3201
+nieunsioskorean;3167
+nieuntikeutkorean;3166
+nihiragana;306B
+nikatakana;30CB
+nikatakanahalfwidth;FF86
+nikhahitleftthai;F899
+nikhahitthai;0E4D
+nine;0039
+ninearabic;0669
+ninebengali;09EF
+ninecircle;2468
+ninecircleinversesansserif;2792
+ninedeva;096F
+ninegujarati;0AEF
+ninegurmukhi;0A6F
+ninehackarabic;0669
+ninehangzhou;3029
+nineideographicparen;3228
+nineinferior;2089
+ninemonospace;FF19
+nineoldstyle;F739
+nineparen;247C
+nineperiod;2490
+ninepersian;06F9
+nineroman;2178
+ninesuperior;2079
+nineteencircle;2472
+nineteenparen;2486
+nineteenperiod;249A
+ninethai;0E59
+nj;01CC
+njecyrillic;045A
+nkatakana;30F3
+nkatakanahalfwidth;FF9D
+nlegrightlong;019E
+nlinebelow;1E49
+nmonospace;FF4E
+nmsquare;339A
+nnabengali;09A3
+nnadeva;0923
+nnagujarati;0AA3
+nnagurmukhi;0A23
+nnnadeva;0929
+nohiragana;306E
+nokatakana;30CE
+nokatakanahalfwidth;FF89
+nonbreakingspace;00A0
+nonenthai;0E13
+nonuthai;0E19
+noonarabic;0646
+noonfinalarabic;FEE6
+noonghunnaarabic;06BA
+noonghunnafinalarabic;FB9F
+noonhehinitialarabic;FEE7 FEEC
+nooninitialarabic;FEE7
+noonjeeminitialarabic;FCD2
+noonjeemisolatedarabic;FC4B
+noonmedialarabic;FEE8
+noonmeeminitialarabic;FCD5
+noonmeemisolatedarabic;FC4E
+noonnoonfinalarabic;FC8D
+notcontains;220C
+notelement;2209
+notelementof;2209
+notequal;2260
+notgreater;226F
+notgreaternorequal;2271
+notgreaternorless;2279
+notidentical;2262
+notless;226E
+notlessnorequal;2270
+notparallel;2226
+notprecedes;2280
+notsubset;2284
+notsucceeds;2281
+notsuperset;2285
+nowarmenian;0576
+nparen;24A9
+nssquare;33B1
+nsuperior;207F
+ntilde;00F1
+nu;03BD
+nuhiragana;306C
+nukatakana;30CC
+nukatakanahalfwidth;FF87
+nuktabengali;09BC
+nuktadeva;093C
+nuktagujarati;0ABC
+nuktagurmukhi;0A3C
+numbersign;0023
+numbersignmonospace;FF03
+numbersignsmall;FE5F
+numeralsigngreek;0374
+numeralsignlowergreek;0375
+numero;2116
+nun;05E0
+nundagesh;FB40
+nundageshhebrew;FB40
+nunhebrew;05E0
+nvsquare;33B5
+nwsquare;33BB
+nyabengali;099E
+nyadeva;091E
+nyagujarati;0A9E
+nyagurmukhi;0A1E
+o;006F
+oacute;00F3
+oangthai;0E2D
+obarred;0275
+obarredcyrillic;04E9
+obarreddieresiscyrillic;04EB
+obengali;0993
+obopomofo;311B
+obreve;014F
+ocandradeva;0911
+ocandragujarati;0A91
+ocandravowelsigndeva;0949
+ocandravowelsigngujarati;0AC9
+ocaron;01D2
+ocircle;24DE
+ocircumflex;00F4
+ocircumflexacute;1ED1
+ocircumflexdotbelow;1ED9
+ocircumflexgrave;1ED3
+ocircumflexhookabove;1ED5
+ocircumflextilde;1ED7
+ocyrillic;043E
+odblacute;0151
+odblgrave;020D
+odeva;0913
+odieresis;00F6
+odieresiscyrillic;04E7
+odotbelow;1ECD
+oe;0153
+oekorean;315A
+ogonek;02DB
+ogonekcmb;0328
+ograve;00F2
+ogujarati;0A93
+oharmenian;0585
+ohiragana;304A
+ohookabove;1ECF
+ohorn;01A1
+ohornacute;1EDB
+ohorndotbelow;1EE3
+ohorngrave;1EDD
+ohornhookabove;1EDF
+ohorntilde;1EE1
+ohungarumlaut;0151
+oi;01A3
+oinvertedbreve;020F
+okatakana;30AA
+okatakanahalfwidth;FF75
+okorean;3157
+olehebrew;05AB
+omacron;014D
+omacronacute;1E53
+omacrongrave;1E51
+omdeva;0950
+omega;03C9
+omega1;03D6
+omegacyrillic;0461
+omegalatinclosed;0277
+omegaroundcyrillic;047B
+omegatitlocyrillic;047D
+omegatonos;03CE
+omgujarati;0AD0
+omicron;03BF
+omicrontonos;03CC
+omonospace;FF4F
+one;0031
+onearabic;0661
+onebengali;09E7
+onecircle;2460
+onecircleinversesansserif;278A
+onedeva;0967
+onedotenleader;2024
+oneeighth;215B
+onefitted;F6DC
+onegujarati;0AE7
+onegurmukhi;0A67
+onehackarabic;0661
+onehalf;00BD
+onehangzhou;3021
+oneideographicparen;3220
+oneinferior;2081
+onemonospace;FF11
+onenumeratorbengali;09F4
+oneoldstyle;F731
+oneparen;2474
+oneperiod;2488
+onepersian;06F1
+onequarter;00BC
+oneroman;2170
+onesuperior;00B9
+onethai;0E51
+onethird;2153
+oogonek;01EB
+oogonekmacron;01ED
+oogurmukhi;0A13
+oomatragurmukhi;0A4B
+oopen;0254
+oparen;24AA
+openbullet;25E6
+option;2325
+ordfeminine;00AA
+ordmasculine;00BA
+orthogonal;221F
+oshortdeva;0912
+oshortvowelsigndeva;094A
+oslash;00F8
+oslashacute;01FF
+osmallhiragana;3049
+osmallkatakana;30A9
+osmallkatakanahalfwidth;FF6B
+ostrokeacute;01FF
+osuperior;F6F0
+otcyrillic;047F
+otilde;00F5
+otildeacute;1E4D
+otildedieresis;1E4F
+oubopomofo;3121
+overline;203E
+overlinecenterline;FE4A
+overlinecmb;0305
+overlinedashed;FE49
+overlinedblwavy;FE4C
+overlinewavy;FE4B
+overscore;00AF
+ovowelsignbengali;09CB
+ovowelsigndeva;094B
+ovowelsigngujarati;0ACB
+p;0070
+paampssquare;3380
+paasentosquare;332B
+pabengali;09AA
+pacute;1E55
+padeva;092A
+pagedown;21DF
+pageup;21DE
+pagujarati;0AAA
+pagurmukhi;0A2A
+pahiragana;3071
+paiyannoithai;0E2F
+pakatakana;30D1
+palatalizationcyrilliccmb;0484
+palochkacyrillic;04C0
+pansioskorean;317F
+paragraph;00B6
+parallel;2225
+parenleft;0028
+parenleftaltonearabic;FD3E
+parenleftbt;F8ED
+parenleftex;F8EC
+parenleftinferior;208D
+parenleftmonospace;FF08
+parenleftsmall;FE59
+parenleftsuperior;207D
+parenlefttp;F8EB
+parenleftvertical;FE35
+parenright;0029
+parenrightaltonearabic;FD3F
+parenrightbt;F8F8
+parenrightex;F8F7
+parenrightinferior;208E
+parenrightmonospace;FF09
+parenrightsmall;FE5A
+parenrightsuperior;207E
+parenrighttp;F8F6
+parenrightvertical;FE36
+partialdiff;2202
+paseqhebrew;05C0
+pashtahebrew;0599
+pasquare;33A9
+patah;05B7
+patah11;05B7
+patah1d;05B7
+patah2a;05B7
+patahhebrew;05B7
+patahnarrowhebrew;05B7
+patahquarterhebrew;05B7
+patahwidehebrew;05B7
+pazerhebrew;05A1
+pbopomofo;3106
+pcircle;24DF
+pdotaccent;1E57
+pe;05E4
+pecyrillic;043F
+pedagesh;FB44
+pedageshhebrew;FB44
+peezisquare;333B
+pefinaldageshhebrew;FB43
+peharabic;067E
+peharmenian;057A
+pehebrew;05E4
+pehfinalarabic;FB57
+pehinitialarabic;FB58
+pehiragana;307A
+pehmedialarabic;FB59
+pekatakana;30DA
+pemiddlehookcyrillic;04A7
+perafehebrew;FB4E
+percent;0025
+percentarabic;066A
+percentmonospace;FF05
+percentsmall;FE6A
+period;002E
+periodarmenian;0589
+periodcentered;00B7
+periodhalfwidth;FF61
+periodinferior;F6E7
+periodmonospace;FF0E
+periodsmall;FE52
+periodsuperior;F6E8
+perispomenigreekcmb;0342
+perpendicular;22A5
+perthousand;2030
+peseta;20A7
+pfsquare;338A
+phabengali;09AB
+phadeva;092B
+phagujarati;0AAB
+phagurmukhi;0A2B
+phi;03C6
+phi1;03D5
+phieuphacirclekorean;327A
+phieuphaparenkorean;321A
+phieuphcirclekorean;326C
+phieuphkorean;314D
+phieuphparenkorean;320C
+philatin;0278
+phinthuthai;0E3A
+phisymbolgreek;03D5
+phook;01A5
+phophanthai;0E1E
+phophungthai;0E1C
+phosamphaothai;0E20
+pi;03C0
+pieupacirclekorean;3273
+pieupaparenkorean;3213
+pieupcieuckorean;3176
+pieupcirclekorean;3265
+pieupkiyeokkorean;3172
+pieupkorean;3142
+pieupparenkorean;3205
+pieupsioskiyeokkorean;3174
+pieupsioskorean;3144
+pieupsiostikeutkorean;3175
+pieupthieuthkorean;3177
+pieuptikeutkorean;3173
+pihiragana;3074
+pikatakana;30D4
+pisymbolgreek;03D6
+piwrarmenian;0583
+plus;002B
+plusbelowcmb;031F
+pluscircle;2295
+plusminus;00B1
+plusmod;02D6
+plusmonospace;FF0B
+plussmall;FE62
+plussuperior;207A
+pmonospace;FF50
+pmsquare;33D8
+pohiragana;307D
+pointingindexdownwhite;261F
+pointingindexleftwhite;261C
+pointingindexrightwhite;261E
+pointingindexupwhite;261D
+pokatakana;30DD
+poplathai;0E1B
+postalmark;3012
+postalmarkface;3020
+pparen;24AB
+precedes;227A
+prescription;211E
+primemod;02B9
+primereversed;2035
+product;220F
+projective;2305
+prolongedkana;30FC
+propellor;2318
+propersubset;2282
+propersuperset;2283
+proportion;2237
+proportional;221D
+psi;03C8
+psicyrillic;0471
+psilipneumatacyrilliccmb;0486
+pssquare;33B0
+puhiragana;3077
+pukatakana;30D7
+pvsquare;33B4
+pwsquare;33BA
+q;0071
+qadeva;0958
+qadmahebrew;05A8
+qafarabic;0642
+qaffinalarabic;FED6
+qafinitialarabic;FED7
+qafmedialarabic;FED8
+qamats;05B8
+qamats10;05B8
+qamats1a;05B8
+qamats1c;05B8
+qamats27;05B8
+qamats29;05B8
+qamats33;05B8
+qamatsde;05B8
+qamatshebrew;05B8
+qamatsnarrowhebrew;05B8
+qamatsqatanhebrew;05B8
+qamatsqatannarrowhebrew;05B8
+qamatsqatanquarterhebrew;05B8
+qamatsqatanwidehebrew;05B8
+qamatsquarterhebrew;05B8
+qamatswidehebrew;05B8
+qarneyparahebrew;059F
+qbopomofo;3111
+qcircle;24E0
+qhook;02A0
+qmonospace;FF51
+qof;05E7
+qofdagesh;FB47
+qofdageshhebrew;FB47
+qofhatafpatah;05E7 05B2
+qofhatafpatahhebrew;05E7 05B2
+qofhatafsegol;05E7 05B1
+qofhatafsegolhebrew;05E7 05B1
+qofhebrew;05E7
+qofhiriq;05E7 05B4
+qofhiriqhebrew;05E7 05B4
+qofholam;05E7 05B9
+qofholamhebrew;05E7 05B9
+qofpatah;05E7 05B7
+qofpatahhebrew;05E7 05B7
+qofqamats;05E7 05B8
+qofqamatshebrew;05E7 05B8
+qofqubuts;05E7 05BB
+qofqubutshebrew;05E7 05BB
+qofsegol;05E7 05B6
+qofsegolhebrew;05E7 05B6
+qofsheva;05E7 05B0
+qofshevahebrew;05E7 05B0
+qoftsere;05E7 05B5
+qoftserehebrew;05E7 05B5
+qparen;24AC
+quarternote;2669
+qubuts;05BB
+qubuts18;05BB
+qubuts25;05BB
+qubuts31;05BB
+qubutshebrew;05BB
+qubutsnarrowhebrew;05BB
+qubutsquarterhebrew;05BB
+qubutswidehebrew;05BB
+question;003F
+questionarabic;061F
+questionarmenian;055E
+questiondown;00BF
+questiondownsmall;F7BF
+questiongreek;037E
+questionmonospace;FF1F
+questionsmall;F73F
+quotedbl;0022
+quotedblbase;201E
+quotedblleft;201C
+quotedblmonospace;FF02
+quotedblprime;301E
+quotedblprimereversed;301D
+quotedblright;201D
+quoteleft;2018
+quoteleftreversed;201B
+quotereversed;201B
+quoteright;2019
+quoterightn;0149
+quotesinglbase;201A
+quotesingle;0027
+quotesinglemonospace;FF07
+r;0072
+raarmenian;057C
+rabengali;09B0
+racute;0155
+radeva;0930
+radical;221A
+radicalex;F8E5
+radoverssquare;33AE
+radoverssquaredsquare;33AF
+radsquare;33AD
+rafe;05BF
+rafehebrew;05BF
+ragujarati;0AB0
+ragurmukhi;0A30
+rahiragana;3089
+rakatakana;30E9
+rakatakanahalfwidth;FF97
+ralowerdiagonalbengali;09F1
+ramiddlediagonalbengali;09F0
+ramshorn;0264
+ratio;2236
+rbopomofo;3116
+rcaron;0159
+rcedilla;0157
+rcircle;24E1
+rcommaaccent;0157
+rdblgrave;0211
+rdotaccent;1E59
+rdotbelow;1E5B
+rdotbelowmacron;1E5D
+referencemark;203B
+reflexsubset;2286
+reflexsuperset;2287
+registered;00AE
+registersans;F8E8
+registerserif;F6DA
+reharabic;0631
+reharmenian;0580
+rehfinalarabic;FEAE
+rehiragana;308C
+rehyehaleflamarabic;0631 FEF3 FE8E 0644
+rekatakana;30EC
+rekatakanahalfwidth;FF9A
+resh;05E8
+reshdageshhebrew;FB48
+reshhatafpatah;05E8 05B2
+reshhatafpatahhebrew;05E8 05B2
+reshhatafsegol;05E8 05B1
+reshhatafsegolhebrew;05E8 05B1
+reshhebrew;05E8
+reshhiriq;05E8 05B4
+reshhiriqhebrew;05E8 05B4
+reshholam;05E8 05B9
+reshholamhebrew;05E8 05B9
+reshpatah;05E8 05B7
+reshpatahhebrew;05E8 05B7
+reshqamats;05E8 05B8
+reshqamatshebrew;05E8 05B8
+reshqubuts;05E8 05BB
+reshqubutshebrew;05E8 05BB
+reshsegol;05E8 05B6
+reshsegolhebrew;05E8 05B6
+reshsheva;05E8 05B0
+reshshevahebrew;05E8 05B0
+reshtsere;05E8 05B5
+reshtserehebrew;05E8 05B5
+reversedtilde;223D
+reviahebrew;0597
+reviamugrashhebrew;0597
+revlogicalnot;2310
+rfishhook;027E
+rfishhookreversed;027F
+rhabengali;09DD
+rhadeva;095D
+rho;03C1
+rhook;027D
+rhookturned;027B
+rhookturnedsuperior;02B5
+rhosymbolgreek;03F1
+rhotichookmod;02DE
+rieulacirclekorean;3271
+rieulaparenkorean;3211
+rieulcirclekorean;3263
+rieulhieuhkorean;3140
+rieulkiyeokkorean;313A
+rieulkiyeoksioskorean;3169
+rieulkorean;3139
+rieulmieumkorean;313B
+rieulpansioskorean;316C
+rieulparenkorean;3203
+rieulphieuphkorean;313F
+rieulpieupkorean;313C
+rieulpieupsioskorean;316B
+rieulsioskorean;313D
+rieulthieuthkorean;313E
+rieultikeutkorean;316A
+rieulyeorinhieuhkorean;316D
+rightangle;221F
+righttackbelowcmb;0319
+righttriangle;22BF
+rihiragana;308A
+rikatakana;30EA
+rikatakanahalfwidth;FF98
+ring;02DA
+ringbelowcmb;0325
+ringcmb;030A
+ringhalfleft;02BF
+ringhalfleftarmenian;0559
+ringhalfleftbelowcmb;031C
+ringhalfleftcentered;02D3
+ringhalfright;02BE
+ringhalfrightbelowcmb;0339
+ringhalfrightcentered;02D2
+rinvertedbreve;0213
+rittorusquare;3351
+rlinebelow;1E5F
+rlongleg;027C
+rlonglegturned;027A
+rmonospace;FF52
+rohiragana;308D
+rokatakana;30ED
+rokatakanahalfwidth;FF9B
+roruathai;0E23
+rparen;24AD
+rrabengali;09DC
+rradeva;0931
+rragurmukhi;0A5C
+rreharabic;0691
+rrehfinalarabic;FB8D
+rrvocalicbengali;09E0
+rrvocalicdeva;0960
+rrvocalicgujarati;0AE0
+rrvocalicvowelsignbengali;09C4
+rrvocalicvowelsigndeva;0944
+rrvocalicvowelsigngujarati;0AC4
+rsuperior;F6F1
+rtblock;2590
+rturned;0279
+rturnedsuperior;02B4
+ruhiragana;308B
+rukatakana;30EB
+rukatakanahalfwidth;FF99
+rupeemarkbengali;09F2
+rupeesignbengali;09F3
+rupiah;F6DD
+ruthai;0E24
+rvocalicbengali;098B
+rvocalicdeva;090B
+rvocalicgujarati;0A8B
+rvocalicvowelsignbengali;09C3
+rvocalicvowelsigndeva;0943
+rvocalicvowelsigngujarati;0AC3
+s;0073
+sabengali;09B8
+sacute;015B
+sacutedotaccent;1E65
+sadarabic;0635
+sadeva;0938
+sadfinalarabic;FEBA
+sadinitialarabic;FEBB
+sadmedialarabic;FEBC
+sagujarati;0AB8
+sagurmukhi;0A38
+sahiragana;3055
+sakatakana;30B5
+sakatakanahalfwidth;FF7B
+sallallahoualayhewasallamarabic;FDFA
+samekh;05E1
+samekhdagesh;FB41
+samekhdageshhebrew;FB41
+samekhhebrew;05E1
+saraaathai;0E32
+saraaethai;0E41
+saraaimaimalaithai;0E44
+saraaimaimuanthai;0E43
+saraamthai;0E33
+saraathai;0E30
+saraethai;0E40
+saraiileftthai;F886
+saraiithai;0E35
+saraileftthai;F885
+saraithai;0E34
+saraothai;0E42
+saraueeleftthai;F888
+saraueethai;0E37
+saraueleftthai;F887
+sarauethai;0E36
+sarauthai;0E38
+sarauuthai;0E39
+sbopomofo;3119
+scaron;0161
+scarondotaccent;1E67
+scedilla;015F
+schwa;0259
+schwacyrillic;04D9
+schwadieresiscyrillic;04DB
+schwahook;025A
+scircle;24E2
+scircumflex;015D
+scommaaccent;0219
+sdotaccent;1E61
+sdotbelow;1E63
+sdotbelowdotaccent;1E69
+seagullbelowcmb;033C
+second;2033
+secondtonechinese;02CA
+section;00A7
+seenarabic;0633
+seenfinalarabic;FEB2
+seeninitialarabic;FEB3
+seenmedialarabic;FEB4
+segol;05B6
+segol13;05B6
+segol1f;05B6
+segol2c;05B6
+segolhebrew;05B6
+segolnarrowhebrew;05B6
+segolquarterhebrew;05B6
+segoltahebrew;0592
+segolwidehebrew;05B6
+seharmenian;057D
+sehiragana;305B
+sekatakana;30BB
+sekatakanahalfwidth;FF7E
+semicolon;003B
+semicolonarabic;061B
+semicolonmonospace;FF1B
+semicolonsmall;FE54
+semivoicedmarkkana;309C
+semivoicedmarkkanahalfwidth;FF9F
+sentisquare;3322
+sentosquare;3323
+seven;0037
+sevenarabic;0667
+sevenbengali;09ED
+sevencircle;2466
+sevencircleinversesansserif;2790
+sevendeva;096D
+seveneighths;215E
+sevengujarati;0AED
+sevengurmukhi;0A6D
+sevenhackarabic;0667
+sevenhangzhou;3027
+sevenideographicparen;3226
+seveninferior;2087
+sevenmonospace;FF17
+sevenoldstyle;F737
+sevenparen;247A
+sevenperiod;248E
+sevenpersian;06F7
+sevenroman;2176
+sevensuperior;2077
+seventeencircle;2470
+seventeenparen;2484
+seventeenperiod;2498
+seventhai;0E57
+sfthyphen;00AD
+shaarmenian;0577
+shabengali;09B6
+shacyrillic;0448
+shaddaarabic;0651
+shaddadammaarabic;FC61
+shaddadammatanarabic;FC5E
+shaddafathaarabic;FC60
+shaddafathatanarabic;0651 064B
+shaddakasraarabic;FC62
+shaddakasratanarabic;FC5F
+shade;2592
+shadedark;2593
+shadelight;2591
+shademedium;2592
+shadeva;0936
+shagujarati;0AB6
+shagurmukhi;0A36
+shalshelethebrew;0593
+shbopomofo;3115
+shchacyrillic;0449
+sheenarabic;0634
+sheenfinalarabic;FEB6
+sheeninitialarabic;FEB7
+sheenmedialarabic;FEB8
+sheicoptic;03E3
+sheqel;20AA
+sheqelhebrew;20AA
+sheva;05B0
+sheva115;05B0
+sheva15;05B0
+sheva22;05B0
+sheva2e;05B0
+shevahebrew;05B0
+shevanarrowhebrew;05B0
+shevaquarterhebrew;05B0
+shevawidehebrew;05B0
+shhacyrillic;04BB
+shimacoptic;03ED
+shin;05E9
+shindagesh;FB49
+shindageshhebrew;FB49
+shindageshshindot;FB2C
+shindageshshindothebrew;FB2C
+shindageshsindot;FB2D
+shindageshsindothebrew;FB2D
+shindothebrew;05C1
+shinhebrew;05E9
+shinshindot;FB2A
+shinshindothebrew;FB2A
+shinsindot;FB2B
+shinsindothebrew;FB2B
+shook;0282
+sigma;03C3
+sigma1;03C2
+sigmafinal;03C2
+sigmalunatesymbolgreek;03F2
+sihiragana;3057
+sikatakana;30B7
+sikatakanahalfwidth;FF7C
+siluqhebrew;05BD
+siluqlefthebrew;05BD
+similar;223C
+sindothebrew;05C2
+siosacirclekorean;3274
+siosaparenkorean;3214
+sioscieuckorean;317E
+sioscirclekorean;3266
+sioskiyeokkorean;317A
+sioskorean;3145
+siosnieunkorean;317B
+siosparenkorean;3206
+siospieupkorean;317D
+siostikeutkorean;317C
+six;0036
+sixarabic;0666
+sixbengali;09EC
+sixcircle;2465
+sixcircleinversesansserif;278F
+sixdeva;096C
+sixgujarati;0AEC
+sixgurmukhi;0A6C
+sixhackarabic;0666
+sixhangzhou;3026
+sixideographicparen;3225
+sixinferior;2086
+sixmonospace;FF16
+sixoldstyle;F736
+sixparen;2479
+sixperiod;248D
+sixpersian;06F6
+sixroman;2175
+sixsuperior;2076
+sixteencircle;246F
+sixteencurrencydenominatorbengali;09F9
+sixteenparen;2483
+sixteenperiod;2497
+sixthai;0E56
+slash;002F
+slashmonospace;FF0F
+slong;017F
+slongdotaccent;1E9B
+smileface;263A
+smonospace;FF53
+sofpasuqhebrew;05C3
+softhyphen;00AD
+softsigncyrillic;044C
+sohiragana;305D
+sokatakana;30BD
+sokatakanahalfwidth;FF7F
+soliduslongoverlaycmb;0338
+solidusshortoverlaycmb;0337
+sorusithai;0E29
+sosalathai;0E28
+sosothai;0E0B
+sosuathai;0E2A
+space;0020
+spacehackarabic;0020
+spade;2660
+spadesuitblack;2660
+spadesuitwhite;2664
+sparen;24AE
+squarebelowcmb;033B
+squarecc;33C4
+squarecm;339D
+squarediagonalcrosshatchfill;25A9
+squarehorizontalfill;25A4
+squarekg;338F
+squarekm;339E
+squarekmcapital;33CE
+squareln;33D1
+squarelog;33D2
+squaremg;338E
+squaremil;33D5
+squaremm;339C
+squaremsquared;33A1
+squareorthogonalcrosshatchfill;25A6
+squareupperlefttolowerrightfill;25A7
+squareupperrighttolowerleftfill;25A8
+squareverticalfill;25A5
+squarewhitewithsmallblack;25A3
+srsquare;33DB
+ssabengali;09B7
+ssadeva;0937
+ssagujarati;0AB7
+ssangcieuckorean;3149
+ssanghieuhkorean;3185
+ssangieungkorean;3180
+ssangkiyeokkorean;3132
+ssangnieunkorean;3165
+ssangpieupkorean;3143
+ssangsioskorean;3146
+ssangtikeutkorean;3138
+ssuperior;F6F2
+sterling;00A3
+sterlingmonospace;FFE1
+strokelongoverlaycmb;0336
+strokeshortoverlaycmb;0335
+subset;2282
+subsetnotequal;228A
+subsetorequal;2286
+succeeds;227B
+suchthat;220B
+suhiragana;3059
+sukatakana;30B9
+sukatakanahalfwidth;FF7D
+sukunarabic;0652
+summation;2211
+sun;263C
+superset;2283
+supersetnotequal;228B
+supersetorequal;2287
+svsquare;33DC
+syouwaerasquare;337C
+t;0074
+tabengali;09A4
+tackdown;22A4
+tackleft;22A3
+tadeva;0924
+tagujarati;0AA4
+tagurmukhi;0A24
+taharabic;0637
+tahfinalarabic;FEC2
+tahinitialarabic;FEC3
+tahiragana;305F
+tahmedialarabic;FEC4
+taisyouerasquare;337D
+takatakana;30BF
+takatakanahalfwidth;FF80
+tatweelarabic;0640
+tau;03C4
+tav;05EA
+tavdages;FB4A
+tavdagesh;FB4A
+tavdageshhebrew;FB4A
+tavhebrew;05EA
+tbar;0167
+tbopomofo;310A
+tcaron;0165
+tccurl;02A8
+tcedilla;0163
+tcheharabic;0686
+tchehfinalarabic;FB7B
+tchehinitialarabic;FB7C
+tchehmedialarabic;FB7D
+tchehmeeminitialarabic;FB7C FEE4
+tcircle;24E3
+tcircumflexbelow;1E71
+tcommaaccent;0163
+tdieresis;1E97
+tdotaccent;1E6B
+tdotbelow;1E6D
+tecyrillic;0442
+tedescendercyrillic;04AD
+teharabic;062A
+tehfinalarabic;FE96
+tehhahinitialarabic;FCA2
+tehhahisolatedarabic;FC0C
+tehinitialarabic;FE97
+tehiragana;3066
+tehjeeminitialarabic;FCA1
+tehjeemisolatedarabic;FC0B
+tehmarbutaarabic;0629
+tehmarbutafinalarabic;FE94
+tehmedialarabic;FE98
+tehmeeminitialarabic;FCA4
+tehmeemisolatedarabic;FC0E
+tehnoonfinalarabic;FC73
+tekatakana;30C6
+tekatakanahalfwidth;FF83
+telephone;2121
+telephoneblack;260E
+telishagedolahebrew;05A0
+telishaqetanahebrew;05A9
+tencircle;2469
+tenideographicparen;3229
+tenparen;247D
+tenperiod;2491
+tenroman;2179
+tesh;02A7
+tet;05D8
+tetdagesh;FB38
+tetdageshhebrew;FB38
+tethebrew;05D8
+tetsecyrillic;04B5
+tevirhebrew;059B
+tevirlefthebrew;059B
+thabengali;09A5
+thadeva;0925
+thagujarati;0AA5
+thagurmukhi;0A25
+thalarabic;0630
+thalfinalarabic;FEAC
+thanthakhatlowleftthai;F898
+thanthakhatlowrightthai;F897
+thanthakhatthai;0E4C
+thanthakhatupperleftthai;F896
+theharabic;062B
+thehfinalarabic;FE9A
+thehinitialarabic;FE9B
+thehmedialarabic;FE9C
+thereexists;2203
+therefore;2234
+theta;03B8
+theta1;03D1
+thetasymbolgreek;03D1
+thieuthacirclekorean;3279
+thieuthaparenkorean;3219
+thieuthcirclekorean;326B
+thieuthkorean;314C
+thieuthparenkorean;320B
+thirteencircle;246C
+thirteenparen;2480
+thirteenperiod;2494
+thonangmonthothai;0E11
+thook;01AD
+thophuthaothai;0E12
+thorn;00FE
+thothahanthai;0E17
+thothanthai;0E10
+thothongthai;0E18
+thothungthai;0E16
+thousandcyrillic;0482
+thousandsseparatorarabic;066C
+thousandsseparatorpersian;066C
+three;0033
+threearabic;0663
+threebengali;09E9
+threecircle;2462
+threecircleinversesansserif;278C
+threedeva;0969
+threeeighths;215C
+threegujarati;0AE9
+threegurmukhi;0A69
+threehackarabic;0663
+threehangzhou;3023
+threeideographicparen;3222
+threeinferior;2083
+threemonospace;FF13
+threenumeratorbengali;09F6
+threeoldstyle;F733
+threeparen;2476
+threeperiod;248A
+threepersian;06F3
+threequarters;00BE
+threequartersemdash;F6DE
+threeroman;2172
+threesuperior;00B3
+threethai;0E53
+thzsquare;3394
+tihiragana;3061
+tikatakana;30C1
+tikatakanahalfwidth;FF81
+tikeutacirclekorean;3270
+tikeutaparenkorean;3210
+tikeutcirclekorean;3262
+tikeutkorean;3137
+tikeutparenkorean;3202
+tilde;02DC
+tildebelowcmb;0330
+tildecmb;0303
+tildecomb;0303
+tildedoublecmb;0360
+tildeoperator;223C
+tildeoverlaycmb;0334
+tildeverticalcmb;033E
+timescircle;2297
+tipehahebrew;0596
+tipehalefthebrew;0596
+tippigurmukhi;0A70
+titlocyrilliccmb;0483
+tiwnarmenian;057F
+tlinebelow;1E6F
+tmonospace;FF54
+toarmenian;0569
+tohiragana;3068
+tokatakana;30C8
+tokatakanahalfwidth;FF84
+tonebarextrahighmod;02E5
+tonebarextralowmod;02E9
+tonebarhighmod;02E6
+tonebarlowmod;02E8
+tonebarmidmod;02E7
+tonefive;01BD
+tonesix;0185
+tonetwo;01A8
+tonos;0384
+tonsquare;3327
+topatakthai;0E0F
+tortoiseshellbracketleft;3014
+tortoiseshellbracketleftsmall;FE5D
+tortoiseshellbracketleftvertical;FE39
+tortoiseshellbracketright;3015
+tortoiseshellbracketrightsmall;FE5E
+tortoiseshellbracketrightvertical;FE3A
+totaothai;0E15
+tpalatalhook;01AB
+tparen;24AF
+trademark;2122
+trademarksans;F8EA
+trademarkserif;F6DB
+tretroflexhook;0288
+triagdn;25BC
+triaglf;25C4
+triagrt;25BA
+triagup;25B2
+ts;02A6
+tsadi;05E6
+tsadidagesh;FB46
+tsadidageshhebrew;FB46
+tsadihebrew;05E6
+tsecyrillic;0446
+tsere;05B5
+tsere12;05B5
+tsere1e;05B5
+tsere2b;05B5
+tserehebrew;05B5
+tserenarrowhebrew;05B5
+tserequarterhebrew;05B5
+tserewidehebrew;05B5
+tshecyrillic;045B
+tsuperior;F6F3
+ttabengali;099F
+ttadeva;091F
+ttagujarati;0A9F
+ttagurmukhi;0A1F
+tteharabic;0679
+ttehfinalarabic;FB67
+ttehinitialarabic;FB68
+ttehmedialarabic;FB69
+tthabengali;09A0
+tthadeva;0920
+tthagujarati;0AA0
+tthagurmukhi;0A20
+tturned;0287
+tuhiragana;3064
+tukatakana;30C4
+tukatakanahalfwidth;FF82
+tusmallhiragana;3063
+tusmallkatakana;30C3
+tusmallkatakanahalfwidth;FF6F
+twelvecircle;246B
+twelveparen;247F
+twelveperiod;2493
+twelveroman;217B
+twentycircle;2473
+twentyhangzhou;5344
+twentyparen;2487
+twentyperiod;249B
+two;0032
+twoarabic;0662
+twobengali;09E8
+twocircle;2461
+twocircleinversesansserif;278B
+twodeva;0968
+twodotenleader;2025
+twodotleader;2025
+twodotleadervertical;FE30
+twogujarati;0AE8
+twogurmukhi;0A68
+twohackarabic;0662
+twohangzhou;3022
+twoideographicparen;3221
+twoinferior;2082
+twomonospace;FF12
+twonumeratorbengali;09F5
+twooldstyle;F732
+twoparen;2475
+twoperiod;2489
+twopersian;06F2
+tworoman;2171
+twostroke;01BB
+twosuperior;00B2
+twothai;0E52
+twothirds;2154
+u;0075
+uacute;00FA
+ubar;0289
+ubengali;0989
+ubopomofo;3128
+ubreve;016D
+ucaron;01D4
+ucircle;24E4
+ucircumflex;00FB
+ucircumflexbelow;1E77
+ucyrillic;0443
+udattadeva;0951
+udblacute;0171
+udblgrave;0215
+udeva;0909
+udieresis;00FC
+udieresisacute;01D8
+udieresisbelow;1E73
+udieresiscaron;01DA
+udieresiscyrillic;04F1
+udieresisgrave;01DC
+udieresismacron;01D6
+udotbelow;1EE5
+ugrave;00F9
+ugujarati;0A89
+ugurmukhi;0A09
+uhiragana;3046
+uhookabove;1EE7
+uhorn;01B0
+uhornacute;1EE9
+uhorndotbelow;1EF1
+uhorngrave;1EEB
+uhornhookabove;1EED
+uhorntilde;1EEF
+uhungarumlaut;0171
+uhungarumlautcyrillic;04F3
+uinvertedbreve;0217
+ukatakana;30A6
+ukatakanahalfwidth;FF73
+ukcyrillic;0479
+ukorean;315C
+umacron;016B
+umacroncyrillic;04EF
+umacrondieresis;1E7B
+umatragurmukhi;0A41
+umonospace;FF55
+underscore;005F
+underscoredbl;2017
+underscoremonospace;FF3F
+underscorevertical;FE33
+underscorewavy;FE4F
+union;222A
+universal;2200
+uogonek;0173
+uparen;24B0
+upblock;2580
+upperdothebrew;05C4
+upsilon;03C5
+upsilondieresis;03CB
+upsilondieresistonos;03B0
+upsilonlatin;028A
+upsilontonos;03CD
+uptackbelowcmb;031D
+uptackmod;02D4
+uragurmukhi;0A73
+uring;016F
+ushortcyrillic;045E
+usmallhiragana;3045
+usmallkatakana;30A5
+usmallkatakanahalfwidth;FF69
+ustraightcyrillic;04AF
+ustraightstrokecyrillic;04B1
+utilde;0169
+utildeacute;1E79
+utildebelow;1E75
+uubengali;098A
+uudeva;090A
+uugujarati;0A8A
+uugurmukhi;0A0A
+uumatragurmukhi;0A42
+uuvowelsignbengali;09C2
+uuvowelsigndeva;0942
+uuvowelsigngujarati;0AC2
+uvowelsignbengali;09C1
+uvowelsigndeva;0941
+uvowelsigngujarati;0AC1
+v;0076
+vadeva;0935
+vagujarati;0AB5
+vagurmukhi;0A35
+vakatakana;30F7
+vav;05D5
+vavdagesh;FB35
+vavdagesh65;FB35
+vavdageshhebrew;FB35
+vavhebrew;05D5
+vavholam;FB4B
+vavholamhebrew;FB4B
+vavvavhebrew;05F0
+vavyodhebrew;05F1
+vcircle;24E5
+vdotbelow;1E7F
+vecyrillic;0432
+veharabic;06A4
+vehfinalarabic;FB6B
+vehinitialarabic;FB6C
+vehmedialarabic;FB6D
+vekatakana;30F9
+venus;2640
+verticalbar;007C
+verticallineabovecmb;030D
+verticallinebelowcmb;0329
+verticallinelowmod;02CC
+verticallinemod;02C8
+vewarmenian;057E
+vhook;028B
+vikatakana;30F8
+viramabengali;09CD
+viramadeva;094D
+viramagujarati;0ACD
+visargabengali;0983
+visargadeva;0903
+visargagujarati;0A83
+vmonospace;FF56
+voarmenian;0578
+voicediterationhiragana;309E
+voicediterationkatakana;30FE
+voicedmarkkana;309B
+voicedmarkkanahalfwidth;FF9E
+vokatakana;30FA
+vparen;24B1
+vtilde;1E7D
+vturned;028C
+vuhiragana;3094
+vukatakana;30F4
+w;0077
+wacute;1E83
+waekorean;3159
+wahiragana;308F
+wakatakana;30EF
+wakatakanahalfwidth;FF9C
+wakorean;3158
+wasmallhiragana;308E
+wasmallkatakana;30EE
+wattosquare;3357
+wavedash;301C
+wavyunderscorevertical;FE34
+wawarabic;0648
+wawfinalarabic;FEEE
+wawhamzaabovearabic;0624
+wawhamzaabovefinalarabic;FE86
+wbsquare;33DD
+wcircle;24E6
+wcircumflex;0175
+wdieresis;1E85
+wdotaccent;1E87
+wdotbelow;1E89
+wehiragana;3091
+weierstrass;2118
+wekatakana;30F1
+wekorean;315E
+weokorean;315D
+wgrave;1E81
+whitebullet;25E6
+whitecircle;25CB
+whitecircleinverse;25D9
+whitecornerbracketleft;300E
+whitecornerbracketleftvertical;FE43
+whitecornerbracketright;300F
+whitecornerbracketrightvertical;FE44
+whitediamond;25C7
+whitediamondcontainingblacksmalldiamond;25C8
+whitedownpointingsmalltriangle;25BF
+whitedownpointingtriangle;25BD
+whiteleftpointingsmalltriangle;25C3
+whiteleftpointingtriangle;25C1
+whitelenticularbracketleft;3016
+whitelenticularbracketright;3017
+whiterightpointingsmalltriangle;25B9
+whiterightpointingtriangle;25B7
+whitesmallsquare;25AB
+whitesmilingface;263A
+whitesquare;25A1
+whitestar;2606
+whitetelephone;260F
+whitetortoiseshellbracketleft;3018
+whitetortoiseshellbracketright;3019
+whiteuppointingsmalltriangle;25B5
+whiteuppointingtriangle;25B3
+wihiragana;3090
+wikatakana;30F0
+wikorean;315F
+wmonospace;FF57
+wohiragana;3092
+wokatakana;30F2
+wokatakanahalfwidth;FF66
+won;20A9
+wonmonospace;FFE6
+wowaenthai;0E27
+wparen;24B2
+wring;1E98
+wsuperior;02B7
+wturned;028D
+wynn;01BF
+x;0078
+xabovecmb;033D
+xbopomofo;3112
+xcircle;24E7
+xdieresis;1E8D
+xdotaccent;1E8B
+xeharmenian;056D
+xi;03BE
+xmonospace;FF58
+xparen;24B3
+xsuperior;02E3
+y;0079
+yaadosquare;334E
+yabengali;09AF
+yacute;00FD
+yadeva;092F
+yaekorean;3152
+yagujarati;0AAF
+yagurmukhi;0A2F
+yahiragana;3084
+yakatakana;30E4
+yakatakanahalfwidth;FF94
+yakorean;3151
+yamakkanthai;0E4E
+yasmallhiragana;3083
+yasmallkatakana;30E3
+yasmallkatakanahalfwidth;FF6C
+yatcyrillic;0463
+ycircle;24E8
+ycircumflex;0177
+ydieresis;00FF
+ydotaccent;1E8F
+ydotbelow;1EF5
+yeharabic;064A
+yehbarreearabic;06D2
+yehbarreefinalarabic;FBAF
+yehfinalarabic;FEF2
+yehhamzaabovearabic;0626
+yehhamzaabovefinalarabic;FE8A
+yehhamzaaboveinitialarabic;FE8B
+yehhamzaabovemedialarabic;FE8C
+yehinitialarabic;FEF3
+yehmedialarabic;FEF4
+yehmeeminitialarabic;FCDD
+yehmeemisolatedarabic;FC58
+yehnoonfinalarabic;FC94
+yehthreedotsbelowarabic;06D1
+yekorean;3156
+yen;00A5
+yenmonospace;FFE5
+yeokorean;3155
+yeorinhieuhkorean;3186
+yerahbenyomohebrew;05AA
+yerahbenyomolefthebrew;05AA
+yericyrillic;044B
+yerudieresiscyrillic;04F9
+yesieungkorean;3181
+yesieungpansioskorean;3183
+yesieungsioskorean;3182
+yetivhebrew;059A
+ygrave;1EF3
+yhook;01B4
+yhookabove;1EF7
+yiarmenian;0575
+yicyrillic;0457
+yikorean;3162
+yinyang;262F
+yiwnarmenian;0582
+ymonospace;FF59
+yod;05D9
+yoddagesh;FB39
+yoddageshhebrew;FB39
+yodhebrew;05D9
+yodyodhebrew;05F2
+yodyodpatahhebrew;FB1F
+yohiragana;3088
+yoikorean;3189
+yokatakana;30E8
+yokatakanahalfwidth;FF96
+yokorean;315B
+yosmallhiragana;3087
+yosmallkatakana;30E7
+yosmallkatakanahalfwidth;FF6E
+yotgreek;03F3
+yoyaekorean;3188
+yoyakorean;3187
+yoyakthai;0E22
+yoyingthai;0E0D
+yparen;24B4
+ypogegrammeni;037A
+ypogegrammenigreekcmb;0345
+yr;01A6
+yring;1E99
+ysuperior;02B8
+ytilde;1EF9
+yturned;028E
+yuhiragana;3086
+yuikorean;318C
+yukatakana;30E6
+yukatakanahalfwidth;FF95
+yukorean;3160
+yusbigcyrillic;046B
+yusbigiotifiedcyrillic;046D
+yuslittlecyrillic;0467
+yuslittleiotifiedcyrillic;0469
+yusmallhiragana;3085
+yusmallkatakana;30E5
+yusmallkatakanahalfwidth;FF6D
+yuyekorean;318B
+yuyeokorean;318A
+yyabengali;09DF
+yyadeva;095F
+z;007A
+zaarmenian;0566
+zacute;017A
+zadeva;095B
+zagurmukhi;0A5B
+zaharabic;0638
+zahfinalarabic;FEC6
+zahinitialarabic;FEC7
+zahiragana;3056
+zahmedialarabic;FEC8
+zainarabic;0632
+zainfinalarabic;FEB0
+zakatakana;30B6
+zaqefgadolhebrew;0595
+zaqefqatanhebrew;0594
+zarqahebrew;0598
+zayin;05D6
+zayindagesh;FB36
+zayindageshhebrew;FB36
+zayinhebrew;05D6
+zbopomofo;3117
+zcaron;017E
+zcircle;24E9
+zcircumflex;1E91
+zcurl;0291
+zdot;017C
+zdotaccent;017C
+zdotbelow;1E93
+zecyrillic;0437
+zedescendercyrillic;0499
+zedieresiscyrillic;04DF
+zehiragana;305C
+zekatakana;30BC
+zero;0030
+zeroarabic;0660
+zerobengali;09E6
+zerodeva;0966
+zerogujarati;0AE6
+zerogurmukhi;0A66
+zerohackarabic;0660
+zeroinferior;2080
+zeromonospace;FF10
+zerooldstyle;F730
+zeropersian;06F0
+zerosuperior;2070
+zerothai;0E50
+zerowidthjoiner;FEFF
+zerowidthnonjoiner;200C
+zerowidthspace;200B
+zeta;03B6
+zhbopomofo;3113
+zhearmenian;056A
+zhebrevecyrillic;04C2
+zhecyrillic;0436
+zhedescendercyrillic;0497
+zhedieresiscyrillic;04DD
+zihiragana;3058
+zikatakana;30B8
+zinorhebrew;05AE
+zlinebelow;1E95
+zmonospace;FF5A
+zohiragana;305E
+zokatakana;30BE
+zparen;24B5
+zretroflexhook;0290
+zstroke;01B6
+zuhiragana;305A
+zukatakana;30BA
+#--end
diff --git a/Build/source/texk/dvipdfm-x/data/pdfglyphlist.txt b/Build/source/texk/dvipdfm-x/data/pdfglyphlist.txt
new file mode 100644
index 00000000000..25596f152dd
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/data/pdfglyphlist.txt
@@ -0,0 +1,385 @@
+# Entries of the Adobe Glyph List contained
+# in the PDF Latin Character Set and Symbol Set.
+#
+# Compiled from the Adobe Glyph List 2.0 and the
+# PDF 1.5 reference.
+#
+# See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html
+#
+# Format: Semicolon-delimited fields:
+# (1) glyph name
+# (2) Unicode scalar value
+A;0041
+AE;00C6
+Aacute;00C1
+Acircumflex;00C2
+Adieresis;00C4
+Agrave;00C0
+Alpha;0391
+Aring;00C5
+Atilde;00C3
+B;0042
+Beta;0392
+C;0043
+Ccedilla;00C7
+Chi;03A7
+D;0044
+Delta;2206
+E;0045
+Eacute;00C9
+Ecircumflex;00CA
+Edieresis;00CB
+Egrave;00C8
+Epsilon;0395
+Eta;0397
+Eth;00D0
+Euro;20AC
+F;0046
+G;0047
+Gamma;0393
+H;0048
+I;0049
+Iacute;00CD
+Icircumflex;00CE
+Idieresis;00CF
+Ifraktur;2111
+Igrave;00CC
+Iota;0399
+J;004A
+K;004B
+Kappa;039A
+L;004C
+Lambda;039B
+Lslash;0141
+M;004D
+Mu;039C
+N;004E
+Ntilde;00D1
+Nu;039D
+O;004F
+OE;0152
+Oacute;00D3
+Ocircumflex;00D4
+Odieresis;00D6
+Ograve;00D2
+Omega;2126
+Omicron;039F
+Oslash;00D8
+Otilde;00D5
+P;0050
+Phi;03A6
+Pi;03A0
+Psi;03A8
+Q;0051
+R;0052
+Rfraktur;211C
+Rho;03A1
+S;0053
+Scaron;0160
+Sigma;03A3
+T;0054
+Tau;03A4
+Theta;0398
+Thorn;00DE
+U;0055
+Uacute;00DA
+Ucircumflex;00DB
+Udieresis;00DC
+Ugrave;00D9
+Upsilon1;03D2
+Upsilon;03A5
+V;0056
+W;0057
+X;0058
+Xi;039E
+Y;0059
+Yacute;00DD
+Ydieresis;0178
+Z;005A
+Zcaron;017D
+Zeta;0396
+a;0061
+aacute;00E1
+acircumflex;00E2
+acute;00B4
+adieresis;00E4
+ae;00E6
+agrave;00E0
+aleph;2135
+alpha;03B1
+ampersand;0026
+angle;2220
+angleleft;2329
+angleright;232A
+approxequal;2248
+aring;00E5
+arrowboth;2194
+arrowdblboth;21D4
+arrowdbldown;21D3
+arrowdblleft;21D0
+arrowdblright;21D2
+arrowdblup;21D1
+arrowdown;2193
+arrowhorizex;F8E7
+arrowleft;2190
+arrowright;2192
+arrowup;2191
+arrowvertex;F8E6
+asciicircum;005E
+asciitilde;007E
+asterisk;002A
+asteriskmath;2217
+at;0040
+atilde;00E3
+b;0062
+backslash;005C
+bar;007C
+beta;03B2
+braceex;F8F4
+braceleft;007B
+braceleftbt;F8F3
+braceleftmid;F8F2
+bracelefttp;F8F1
+braceright;007D
+bracerightbt;F8FE
+bracerightmid;F8FD
+bracerighttp;F8FC
+bracketleft;005B
+bracketleftbt;F8F0
+bracketleftex;F8EF
+bracketlefttp;F8EE
+bracketright;005D
+bracketrightbt;F8FB
+bracketrightex;F8FA
+bracketrighttp;F8F9
+breve;02D8
+brokenbar;00A6
+bullet;2022
+c;0063
+caron;02C7
+carriagereturn;21B5
+ccedilla;00E7
+cedilla;00B8
+cent;00A2
+chi;03C7
+circlemultiply;2297
+circleplus;2295
+circumflex;02C6
+club;2663
+colon;003A
+comma;002C
+congruent;2245
+copyright;00A9
+copyrightsans;F8E9
+copyrightserif;F6D9
+currency;00A4
+d;0064
+dagger;2020
+daggerdbl;2021
+degree;00B0
+delta;03B4
+diamond;2666
+dieresis;00A8
+divide;00F7
+dollar;0024
+dotaccent;02D9
+dotlessi;0131
+dotmath;22C5
+e;0065
+eacute;00E9
+ecircumflex;00EA
+edieresis;00EB
+egrave;00E8
+eight;0038
+element;2208
+ellipsis;2026
+emdash;2014
+emptyset;2205
+endash;2013
+epsilon;03B5
+equal;003D
+equivalence;2261
+eta;03B7
+eth;00F0
+exclam;0021
+exclamdown;00A1
+existential;2203
+f;0066
+fi;FB01
+five;0035
+fl;FB02
+florin;0192
+four;0034
+fraction;2044
+g;0067
+gamma;03B3
+germandbls;00DF
+gradient;2207
+grave;0060
+greater;003E
+greaterequal;2265
+guillemotleft;00AB
+guillemotright;00BB
+guilsinglleft;2039
+guilsinglright;203A
+h;0068
+heart;2665
+hungarumlaut;02DD
+hyphen;002D
+i;0069
+iacute;00ED
+icircumflex;00EE
+idieresis;00EF
+igrave;00EC
+infinity;221E
+integral;222B
+integralbt;2321
+integralex;F8F5
+integraltp;2320
+intersection;2229
+iota;03B9
+j;006A
+k;006B
+kappa;03BA
+l;006C
+lambda;03BB
+less;003C
+lessequal;2264
+logicaland;2227
+logicalnot;00AC
+logicalor;2228
+lozenge;25CA
+lslash;0142
+m;006D
+macron;00AF
+minus;2212
+minute;2032
+mu;00B5
+multiply;00D7
+n;006E
+nine;0039
+notelement;2209
+notequal;2260
+notsubset;2284
+ntilde;00F1
+nu;03BD
+numbersign;0023
+o;006F
+oacute;00F3
+ocircumflex;00F4
+odieresis;00F6
+oe;0153
+ogonek;02DB
+ograve;00F2
+omega1;03D6
+omega;03C9
+omicron;03BF
+one;0031
+onehalf;00BD
+onequarter;00BC
+onesuperior;00B9
+ordfeminine;00AA
+ordmasculine;00BA
+oslash;00F8
+otilde;00F5
+p;0070
+paragraph;00B6
+parenleft;0028
+parenleftbt;F8ED
+parenleftex;F8EC
+parenlefttp;F8EB
+parenright;0029
+parenrightbt;F8F8
+parenrightex;F8F7
+parenrighttp;F8F6
+partialdiff;2202
+percent;0025
+period;002E
+periodcentered;00B7
+perpendicular;22A5
+perthousand;2030
+phi1;03D5
+phi;03C6
+pi;03C0
+plus;002B
+plusminus;00B1
+product;220F
+propersubset;2282
+propersuperset;2283
+proportional;221D
+psi;03C8
+q;0071
+question;003F
+questiondown;00BF
+quotedbl;0022
+quotedblbase;201E
+quotedblleft;201C
+quotedblright;201D
+quoteleft;2018
+quoteright;2019
+quotesinglbase;201A
+quotesingle;0027
+r;0072
+radical;221A
+radicalex;F8E5
+reflexsubset;2286
+reflexsuperset;2287
+registered;00AE
+registersans;F8E8
+registerserif;F6DA
+rho;03C1
+ring;02DA
+s;0073
+scaron;0161
+second;2033
+section;00A7
+semicolon;003B
+seven;0037
+sigma1;03C2
+sigma;03C3
+similar;223C
+six;0036
+slash;002F
+space;0020
+spade;2660
+sterling;00A3
+suchthat;220B
+summation;2211
+t;0074
+tau;03C4
+therefore;2234
+theta1;03D1
+theta;03B8
+thorn;00FE
+three;0033
+threequarters;00BE
+threesuperior;00B3
+tilde;02DC
+trademark;2122
+trademarksans;F8EA
+trademarkserif;F6DB
+two;0032
+twosuperior;00B2
+u;0075
+uacute;00FA
+ucircumflex;00FB
+udieresis;00FC
+ugrave;00F9
+underscore;005F
+union;222A
+universal;2200
+upsilon;03C5
+v;0076
+w;0077
+weierstrass;2118
+x;0078
+xi;03BE
+y;0079
+yacute;00FD
+ydieresis;00FF
+yen;00A5
+z;007A
+zcaron;017E
+zero;0030
+zeta;03B6
+#--end
diff --git a/Build/source/texk/dvipdfm-x/dpxconf.c b/Build/source/texk/dvipdfm-x/dpxconf.c
new file mode 100644
index 00000000000..ab7f6693ac8
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxconf.c
@@ -0,0 +1,110 @@
+/* This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+
+struct _dpx_conf dpx_conf = {0, 0, dpx_mode_normal_mode, 0, {0}};
+
+#ifndef HAVE_LIBPAPER
+const struct paper paperspecs[] = {
+ {"letter", 612.00, 792.00},
+ {"legal" , 612.00, 1008.00},
+ {"ledger", 1224.00, 792.00},
+ {"tabloid", 792.00, 1224.00},
+ {"a6", 297.638, 419.528},
+ {"a5", 419.528, 595.276},
+ {"a4", 595.276, 841.890},
+ {"a3", 841.890, 1190.550},
+ /*
+ * The B series paper formats were first introduced in Japanese
+ * patch (jpatch). The size of b6, ..., b5var paper is JIS paper
+ * size for this reason. Please modify the following line or use
+ * libpaper if you need ISO paper sizes.
+ */
+#if defined(USE_ISO_PAPERSIZE) || defined(ISO_PAPERSIZE)
+ {"b6", 354.331, 498.898},
+ {"b5", 498.898, 708.661},
+ {"b4", 708.661, 1000.630},
+ {"b3", 1000.630, 1417.320},
+#else
+ {"b6", 364.25, 515.91},
+ {"b5", 515.91, 728.50},
+ {"b4", 728.50, 1031.81},
+ {"b3", 1031.81, 1457.00},
+ {"b5var", 515.91, 651.97},
+#endif /* USE_ISO_PAPERSIZE */
+ /* Alias for JIS and ISO */
+ {"jisb6", 364.25, 515.91},
+ {"jisb5", 515.91, 728.50},
+ {"jisb4", 728.50, 1031.81},
+ {"jisb3", 1031.81, 1457.00},
+ {"isob6", 354.331, 498.898},
+ {"isob5", 498.898, 708.661},
+ {"isob4", 708.661, 1000.630},
+ {"isob3", 1000.630, 1417.320},
+ /* -- */
+ {NULL, 0, 0},
+};
+
+const struct paper *
+paperinfo (const char *ppformat)
+{
+ const struct paper *ppinfo;
+
+ if (!ppformat)
+ return NULL;
+
+ ppinfo = paperfirst();
+ while (ppinfo && papername(ppinfo)) {
+ if (!strcmp(ppformat, ppinfo->name))
+ /* ppinfo->name == papername(ppinfo), but gcc doesn't like the latter */
+ break;
+ ppinfo = papernext(ppinfo);
+ }
+
+ return ((ppinfo && papername(ppinfo)) ? ppinfo : NULL);
+}
+
+#endif /* HAVE_LIBPAPER */
+
+void
+dumppaperinfo (void)
+{
+ const struct paper *ppinfo;
+ ppinfo = paperfirst();
+ while (ppinfo && papername(ppinfo)) {
+ double wd, ht;
+ wd = paperpswidth (ppinfo);
+ ht = paperpsheight(ppinfo);
+ fprintf(stdout, "%s: %.2f %.2f (%.2fmm %.2fmm)\n",
+ papername(ppinfo), wd, ht, 25.4 * wd / 72.0, 25.4 * ht / 72.0);
+ ppinfo = papernext(ppinfo);
+ }
+}
diff --git a/Build/source/texk/dvipdfm-x/dpxconf.h b/Build/source/texk/dvipdfm-x/dpxconf.h
new file mode 100644
index 00000000000..e0785a1e42d
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxconf.h
@@ -0,0 +1,75 @@
+/* This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _DPXCONF_H_
+#define _DPXCONF_H_
+
+enum dpx_mode {
+ dpx_mode_normal_mode,
+ dpx_mode_compat_mode,
+ dpx_mode_xdv_mode,
+ dpx_mode_mpost_mode
+};
+
+extern struct _dpx_conf {
+ int is_xbb;
+ int verbose_level;
+ enum dpx_mode compat_mode;
+ int ignore_font_license;
+ struct {
+ int keep_cache;
+ } file;
+} dpx_conf;
+
+#ifdef HAVE_LIBPAPER
+#include <paper.h>
+#else
+struct paper {
+ const char* name;
+ double pswidth, psheight;
+};
+
+#ifndef DEFAULT_PAPER_NAME
+#define DEFAULT_PAPER_NAME "a4"
+#endif
+
+extern const struct paper paperspecs[];
+extern const struct paper *paperinfo (const char *ppformat);
+
+#define paperinit()
+#define paperdone()
+#define paperpswidth(p) (((p) && (p)->name) ? p->pswidth : 0.0)
+#define paperpsheight(p) (((p) && (p)->name) ? p->psheight : 0.0)
+#define papername(p) (((p) && (p)->name) ? p->name : NULL)
+#define paperfirst() &(paperspecs[0])
+#define papernext(p) ((((p)+1) && ((p)+1)->name) ? (p+1) : NULL)
+
+#define defaultpapername() DEFAULT_PAPER_NAME
+#define systempapername() DEFAULT_PAPER_NAME
+
+#define defaultpapersizefile() NULL
+#define systempapersizefile() NULL
+#endif /* HAVE_LIBPAPER */
+
+extern void dumppaperinfo (void);
+
+#endif /* _DPXCONF_H_ */
diff --git a/Build/source/texk/dvipdfm-x/dpxcrypt.c b/Build/source/texk/dvipdfm-x/dpxcrypt.c
new file mode 100644
index 00000000000..31eea440214
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxcrypt.c
@@ -0,0 +1,1941 @@
+/* This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
+
+ Copyright (C) 2003-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+
+#include "mem.h"
+#include "error.h"
+#include "numbers.h"
+#include "dpxcrypt.h"
+
+static void _gcry_burn_stack (int bytes)
+{
+ char buf[64];
+
+ memset(buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0) _gcry_burn_stack(bytes);
+}
+
+
+/* Rotate a 32 bit integer by n bytes */
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#define ror(x,n) ( ((x) >> ((n)&(32-1))) | ((x) << ((32-(n))&(32-1))) )
+
+/*
+ * The following codes for MD5 Message-Digest Algorithm were modified
+ * by Jin-Hwan Cho on August 5, 2003 based on libgrypt-1.1.42.
+ *
+ * Copyright (C) 1995,1996,1998,1999,2001,2002,2003 Free Software Foundation, Inc.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * According to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ * heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
+ */
+
+void MD5_init (MD5_CONTEXT *ctx)
+{
+ ctx->A = 0x67452301U;
+ ctx->B = 0xefcdab89U;
+ ctx->C = 0x98badcfeU;
+ ctx->D = 0x10325476U;
+
+ ctx->nblocks = 0;
+ ctx->count = 0;
+}
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ * and defined in the RFC 1321. The first function is a little bit optimized
+ * (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF(d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* transform n*64 bytes */
+static void transform (MD5_CONTEXT *ctx, const unsigned char *data)
+{
+ uint32_t correct_words[16];
+ uint32_t A = ctx->A;
+ uint32_t B = ctx->B;
+ uint32_t C = ctx->C;
+ uint32_t D = ctx->D;
+ uint32_t *cwp = correct_words;
+
+#ifdef WORDS_BIGENDIAN
+ { int i; const unsigned char *p1; unsigned char *p2;
+ for (i = 0, p1 = data, p2 = (unsigned char *)correct_words; i < 16; i++, p2 += 4 ) {
+ p2[3] = *p1++; p2[2] = *p1++; p2[1] = *p1++; p2[0] = *p1++;
+ }
+ }
+#else
+ memcpy(correct_words, data, sizeof(uint32_t) * 16);
+#endif
+
+#define OP(a, b, c, d, s, T) \
+ do { a += FF(b, c, d) + (*cwp++) + T; a = rol(a, s); a += b; } while (0)
+
+ /* Before we start, one word about the strange constants.
+ * They are defined in RFC 1321 as
+ *
+ * T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP(A, B, C, D, 7, 0xd76aa478);
+ OP(D, A, B, C, 12, 0xe8c7b756);
+ OP(C, D, A, B, 17, 0x242070db);
+ OP(B, C, D, A, 22, 0xc1bdceee);
+ OP(A, B, C, D, 7, 0xf57c0faf);
+ OP(D, A, B, C, 12, 0x4787c62a);
+ OP(C, D, A, B, 17, 0xa8304613);
+ OP(B, C, D, A, 22, 0xfd469501);
+ OP(A, B, C, D, 7, 0x698098d8);
+ OP(D, A, B, C, 12, 0x8b44f7af);
+ OP(C, D, A, B, 17, 0xffff5bb1);
+ OP(B, C, D, A, 22, 0x895cd7be);
+ OP(A, B, C, D, 7, 0x6b901122);
+ OP(D, A, B, C, 12, 0xfd987193);
+ OP(C, D, A, B, 17, 0xa679438e);
+ OP(B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do { a += f(b, c, d) + correct_words[k] + T; a = rol(a, s); a += b; } while (0)
+
+ /* Round 2. */
+ OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP(FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP(FG, D, A, B, C, 10, 9, 0x02441453);
+ OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP(FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP(FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP(FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP(FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP(FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Put checksum in context given as argument. */
+ ctx->A += A;
+ ctx->B += B;
+ ctx->C += C;
+ ctx->D += D;
+}
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed. */
+void MD5_write (MD5_CONTEXT *hd, const unsigned char *inbuf, unsigned int inlen)
+{
+ if (hd->count == 64) { /* flush the buffer */
+ transform(hd, hd->buf);
+ _gcry_burn_stack(80+6*sizeof(void*));
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf) return;
+ if (hd->count) {
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+ MD5_write(hd, NULL, 0);
+ if (!inlen) return;
+ }
+ _gcry_burn_stack(80+6*sizeof(void*));
+
+ while (inlen >= 64) {
+ transform(hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 bytes representing the digest. */
+
+void MD5_final (unsigned char *outbuf, MD5_CONTEXT *hd)
+{
+ uint32_t t, msb, lsb;
+ unsigned char *p;
+
+ MD5_write(hd, NULL, 0); /* flush */
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->count) < t) msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->count < 56) { /* enough room */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 56) hd->buf[hd->count++] = 0; /* pad */
+ } else { /* need one extra block */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 64) hd->buf[hd->count++] = 0;
+ MD5_write(hd, NULL, 0); /* flush */
+ memset(hd->buf, 0, 56); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = lsb & 0xff;
+ hd->buf[57] = (lsb >> 8) & 0xff;
+ hd->buf[58] = (lsb >> 16) & 0xff;
+ hd->buf[59] = (lsb >> 24) & 0xff;
+ hd->buf[60] = msb & 0xff;
+ hd->buf[61] = (msb >> 8) & 0xff;
+ hd->buf[62] = (msb >> 16) & 0xff;
+ hd->buf[63] = (msb >> 24) & 0xff;
+ transform(hd, hd->buf);
+ _gcry_burn_stack(80+6*sizeof(void*));
+
+ p = outbuf; /* p = hd->buf; */
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->a; *p++ = hd->a >> 8; \
+ *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while (0)
+#else /* little endian */
+#define X(a) do { *(uint32_t *)p = (*hd).a ; p += sizeof(uint32_t); } while (0)
+#endif
+ X(A);
+ X(B);
+ X(C);
+ X(D);
+#undef X
+}
+
+/*
+ * The following codes for the SHA256 hash function are taken from
+ * libgrypt-1.6.3. (slightly modified)
+ *
+ * sha256.c - SHA256 hash function
+ * Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+static uint32_t
+_gcry_bswap32(uint32_t x)
+{
+ return ((rol(x, 8) & 0x00ff00ffL) | (ror(x, 8) & 0xff00ff00L));
+}
+
+static uint64_t
+_gcry_bswap64(uint64_t x)
+{
+ return ((uint64_t)_gcry_bswap32(x) << 32) | (_gcry_bswap32(x >> 32));
+}
+
+/* Endian dependent byte swap operations. */
+#ifdef WORDS_BIGENDIAN
+# define le_bswap32(x) _gcry_bswap32(x)
+# define be_bswap32(x) ((uint32_t)(x))
+# define le_bswap64(x) _gcry_bswap64(x)
+# define be_bswap64(x) ((uint64_t)(x))
+#else
+# define le_bswap32(x) ((uint32_t)(x))
+# define be_bswap32(x) _gcry_bswap32(x)
+# define le_bswap64(x) ((uint64_t)(x))
+# define be_bswap64(x) _gcry_bswap64(x)
+#endif
+
+static uint32_t buf_get_be32(const void *_buf)
+{
+ const uint8_t *in = _buf;
+ return ((uint32_t)in[0] << 24) | ((uint32_t)in[1] << 16) | \
+ ((uint32_t)in[2] << 8) | (uint32_t)in[3];
+}
+
+static void buf_put_be32(void *_buf, uint32_t val)
+{
+ uint8_t *out = _buf;
+ out[0] = val >> 24;
+ out[1] = val >> 16;
+ out[2] = val >> 8;
+ out[3] = val;
+}
+
+static uint64_t buf_get_be64(const void *_buf)
+{
+ const uint8_t *in = _buf;
+ return ((uint64_t)in[0] << 56) | ((uint64_t)in[1] << 48) | \
+ ((uint64_t)in[2] << 40) | ((uint64_t)in[3] << 32) | \
+ ((uint64_t)in[4] << 24) | ((uint64_t)in[5] << 16) | \
+ ((uint64_t)in[6] << 8) | (uint64_t)in[7];
+}
+
+static void buf_put_be64(void *_buf, uint64_t val)
+{
+ uint8_t *out = _buf;
+ out[0] = val >> 56;
+ out[1] = val >> 48;
+ out[2] = val >> 40;
+ out[3] = val >> 32;
+ out[4] = val >> 24;
+ out[5] = val >> 16;
+ out[6] = val >> 8;
+ out[7] = val;
+}
+
+void
+SHA256_init (SHA256_CONTEXT *hd)
+{
+ hd->h0 = 0x6a09e667;
+ hd->h1 = 0xbb67ae85;
+ hd->h2 = 0x3c6ef372;
+ hd->h3 = 0xa54ff53a;
+ hd->h4 = 0x510e527f;
+ hd->h5 = 0x9b05688c;
+ hd->h6 = 0x1f83d9ab;
+ hd->h7 = 0x5be0cd19;
+
+ hd->nblocks = 0;
+ hd->count = 0;
+}
+
+/*
+ Transform the message X which consists of 16 32-bit-words. See FIPS
+ 180-2 for details. */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ h = g; \
+ g = f; \
+ f = e; \
+ e = d + t1; \
+ d = c; \
+ c = b; \
+ b = a; \
+ a = t1 + t2; \
+ } while (0)
+
+
+#define Cho(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
+#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x)|(y))))
+#define Sum0(x) (ror((x), 2) ^ ror((x), 13) ^ ror((x), 22))
+#define Sum1(x) (ror((x), 6) ^ ror((x), 11) ^ ror((x), 25))
+
+static unsigned int
+_SHA256_transform (SHA256_CONTEXT *hd, const unsigned char *data)
+{
+ static const uint32_t K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ uint32_t a,b,c,d,e,f,g,h,t1,t2;
+ uint32_t w[64];
+ int i;
+
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+ for (i=0; i < 16; i++)
+ w[i] = buf_get_be32(data + i * 4);
+ for (; i < 64; i++)
+ w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
+
+ for (i=0; i < 64;)
+ {
+#if 0
+ R(a,b,c,d,e,f,g,h,K[i],w[i]);
+ i++;
+#else
+ t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Cho (d, e, f) + K[i+1] + w[i+1];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Cho (c, d, e) + K[i+2] + w[i+2];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Cho (b, c, d) + K[i+3] + w[i+3];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Cho (a, b, c) + K[i+4] + w[i+4];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Cho (h, a, b) + K[i+5] + w[i+5];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Cho (g, h, a) + K[i+6] + w[i+6];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Cho (f, g, h) + K[i+7] + w[i+7];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ i += 8;
+#endif
+ }
+
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+
+ return /*burn_stack*/ 74*4+32;
+}
+#undef S0
+#undef S1
+#undef R
+
+void SHA256_write (SHA256_CONTEXT *hd, const unsigned char *inbuf, unsigned int inlen)
+{
+ unsigned int stack_burn = 0;
+
+ if (hd->count == 64) { /* flush the buffer */
+ stack_burn = _SHA256_transform(hd, hd->buf);
+ _gcry_burn_stack(stack_burn);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf) return;
+ if (hd->count) {
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+ SHA256_write(hd, NULL, 0);
+ if (!inlen) return;
+ }
+ _gcry_burn_stack(stack_burn);
+
+ while (inlen >= 64) {
+ stack_burn = _SHA256_transform(hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+/*
+ The routine finally terminates the computation and returns the
+ digest. The handle is prepared for a new cycle, but adding bytes
+ to the handle will the destroy the returned buffer. Returns: 32
+ bytes with the message the digest. */
+void
+SHA256_final(unsigned char *outbuf, SHA256_CONTEXT *hd)
+{
+ uint32_t t, msb, lsb;
+ unsigned char *p;
+ unsigned int burn;
+
+ SHA256_write(hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->count < 56)
+ { /* enough room */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 56)
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else
+ { /* need one extra block */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 64)
+ hd->buf[hd->count++] = 0;
+ SHA256_write(hd, NULL, 0); /* flush */;
+ memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ buf_put_be32(hd->buf + 56, msb);
+ buf_put_be32(hd->buf + 60, lsb);
+ burn = _SHA256_transform(hd, hd->buf);
+ _gcry_burn_stack(burn);
+
+ p = outbuf;
+#define X(a) do { *(uint32_t*)p = be_bswap32(hd->h##a); p += 4; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+ X(5);
+ X(6);
+ X(7);
+#undef X
+}
+
+#undef Cho
+#undef Maj
+#undef Sum0
+#undef Sum1
+
+/* The following code are taken from libgcrypt-1.6.3. (slightly modified):
+ *
+ * sha512.c - SHA384 and SHA512 hash functions
+ * Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define ROTR(x,n) (((x) >> (n)) | ((x) << (64 - (n))))
+#define Ch(x,y,z) (((x) & (y)) ^ ( ~(x) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+#define Sum0(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
+#define Sum1(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
+#define U64_C(c) (c ## UL)
+
+void
+SHA512_init (SHA512_CONTEXT *ctx)
+{
+ SHA512_STATE *hd = &ctx->state;
+
+ hd->h0 = U64_C(0x6a09e667f3bcc908);
+ hd->h1 = U64_C(0xbb67ae8584caa73b);
+ hd->h2 = U64_C(0x3c6ef372fe94f82b);
+ hd->h3 = U64_C(0xa54ff53a5f1d36f1);
+ hd->h4 = U64_C(0x510e527fade682d1);
+ hd->h5 = U64_C(0x9b05688c2b3e6c1f);
+ hd->h6 = U64_C(0x1f83d9abfb41bd6b);
+ hd->h7 = U64_C(0x5be0cd19137e2179);
+
+ ctx->nblocks = 0;
+ ctx->count = 0;
+}
+
+void
+SHA384_init (SHA512_CONTEXT *ctx)
+{
+ SHA512_STATE *hd = &ctx->state;
+
+ hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
+ hd->h1 = U64_C(0x629a292a367cd507);
+ hd->h2 = U64_C(0x9159015a3070dd17);
+ hd->h3 = U64_C(0x152fecd8f70e5939);
+ hd->h4 = U64_C(0x67332667ffc00b31);
+ hd->h5 = U64_C(0x8eb44a8768581511);
+ hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
+ hd->h7 = U64_C(0x47b5481dbefa4fa4);
+
+ ctx->nblocks = 0;
+ ctx->count = 0;
+}
+
+
+static const uint64_t k[] =
+ {
+ U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
+ U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
+ U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
+ U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
+ U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
+ U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
+ U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
+ U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
+ U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
+ U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
+ U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
+ U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
+ U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
+ U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
+ U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
+ U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
+ U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
+ U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
+ U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
+ U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
+ U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
+ U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
+ U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
+ U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
+ U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
+ U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
+ U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
+ U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
+ U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
+ U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
+ U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
+ U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
+ U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
+ U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
+ U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
+ U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
+ U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
+ U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
+ U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
+ U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
+ };
+
+/****************
+ * Transform the message W which consists of 16 64-bit-words
+ */
+static unsigned int
+__transform (SHA512_STATE *hd, const unsigned char *data)
+{
+ uint64_t a, b, c, d, e, f, g, h;
+ uint64_t w[16];
+ int t;
+
+ /* get values from the chaining vars */
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+ for ( t = 0; t < 16; t++ )
+ w[t] = buf_get_be64(data + t * 8);
+
+#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
+#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+
+
+ for (t = 0; t < 80 - 16; )
+ {
+ uint64_t t1, t2;
+
+ /* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
+ with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
+ initialized to 0,1,2,3...255,0,... and 1000 iterations:
+
+ Not unrolled with macros: 440ms
+ Unrolled with macros: 350ms
+ Unrolled with inline: 330ms
+ */
+#if 0 /* Not unrolled. */
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t%16];
+ w[t%16] += S1 (w[(t - 2)%16]) + w[(t - 7)%16] + S0 (w[(t - 15)%16]);
+ t2 = Sum0 (a) + Maj (a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ t++;
+#else /* Unrolled to interweave the chain variables. */
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
+ w[0] += S1 (w[14]) + w[9] + S0 (w[1]);
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
+ w[1] += S1 (w[15]) + w[10] + S0 (w[2]);
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
+ w[2] += S1 (w[0]) + w[11] + S0 (w[3]);
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
+ w[3] += S1 (w[1]) + w[12] + S0 (w[4]);
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
+ w[4] += S1 (w[2]) + w[13] + S0 (w[5]);
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
+ w[5] += S1 (w[3]) + w[14] + S0 (w[6]);
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
+ w[6] += S1 (w[4]) + w[15] + S0 (w[7]);
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
+ w[7] += S1 (w[5]) + w[0] + S0 (w[8]);
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
+ w[8] += S1 (w[6]) + w[1] + S0 (w[9]);
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
+ w[9] += S1 (w[7]) + w[2] + S0 (w[10]);
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
+ w[10] += S1 (w[8]) + w[3] + S0 (w[11]);
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
+ w[11] += S1 (w[9]) + w[4] + S0 (w[12]);
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
+ w[12] += S1 (w[10]) + w[5] + S0 (w[13]);
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
+ w[13] += S1 (w[11]) + w[6] + S0 (w[14]);
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
+ w[14] += S1 (w[12]) + w[7] + S0 (w[15]);
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
+ w[15] += S1 (w[13]) + w[8] + S0 (w[0]);
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t += 16;
+#endif
+ }
+
+ for (; t < 80; )
+ {
+ uint64_t t1, t2;
+
+#if 0 /* Not unrolled. */
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t%16];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ t++;
+#else /* Unrolled to interweave the chain variables. */
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t += 16;
+#endif
+ }
+
+ /* Update chaining vars. */
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+
+ return /* burn_stack */ (8 + 16) * sizeof(uint64_t) + sizeof(uint32_t) +
+ 3 * sizeof(void*);
+}
+
+
+static unsigned int
+_SHA512_transform (SHA512_CONTEXT *ctx, const unsigned char *data)
+{
+ return __transform(&ctx->state, data) + 3 * sizeof(void*);
+}
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 64 bytes representing the digest. When used for sha384,
+ * we take the leftmost 48 of those bytes.
+ */
+
+void SHA512_write (SHA512_CONTEXT *hd, const unsigned char *inbuf, unsigned int inlen)
+{
+ unsigned int stack_burn = 0;
+
+ if (hd->count == 128) { /* flush the buffer */
+ stack_burn = _SHA512_transform(hd, hd->buf);
+ _gcry_burn_stack(stack_burn);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf) return;
+ if (hd->count) {
+ for (; inlen && hd->count < 128; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+ SHA512_write(hd, NULL, 0);
+ if (!inlen) return;
+ }
+ _gcry_burn_stack(stack_burn);
+
+ while (inlen >= 128) {
+ stack_burn = _SHA512_transform(hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 128;
+ inbuf += 128;
+ }
+ for (; inlen && hd->count < 128; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+void
+SHA512_final (unsigned char *outbuf, SHA512_CONTEXT *hd)
+{
+ unsigned int stack_burn_depth;
+ uint64_t t, msb, lsb;
+ unsigned char *p;
+
+ SHA512_write(hd, NULL, 0); /* flush */ ;
+
+ t = hd->nblocks;
+ /* multiply by 128 to make a byte count */
+ lsb = t << 7;
+ msb = t >> 57;
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 61;
+
+ if (hd->count < 112)
+ { /* enough room */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 112)
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else
+ { /* need one extra block */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 128)
+ hd->buf[hd->count++] = 0;
+ SHA512_write(hd, NULL, 0); /* flush */ ;
+ memset(hd->buf, 0, 112); /* fill next block with zeroes */
+ }
+ /* append the 128 bit count */
+ buf_put_be64(hd->buf + 112, msb);
+ buf_put_be64(hd->buf + 120, lsb);
+ stack_burn_depth = _SHA512_transform(hd, hd->buf);
+ _gcry_burn_stack(stack_burn_depth);
+
+ p = outbuf;
+#define X(a) do { *(uint64_t*)p = be_bswap64(hd->state.h##a) ; p += 8; } while (0)
+ X (0);
+ X (1);
+ X (2);
+ X (3);
+ X (4);
+ X (5);
+ /* Note that these last two chunks are included even for SHA384.
+ We just ignore them. */
+ X (6);
+ X (7);
+#undef X
+}
+
+#undef ROTR
+#undef Ch
+#undef Maj
+#undef Sum0
+#undef Sum1
+
+/*
+ * The following codes for the arcfour stream cipher were modified
+ * by Jin-Hwan Cho on August 5, 2003 based on libgrypt-1.1.42.
+ *
+ * Copyright (C) 2000,2001,2002,2003 Free Software Foundation, Inc.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * According to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ * heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
+ */
+
+static void do_encrypt_stream (ARC4_CONTEXT *ctx, unsigned char *outbuf, const unsigned char *inbuf, unsigned int len)
+{
+ int i = ctx->idx_i;
+ int j = ctx->idx_j;
+ unsigned char *sbox = ctx->sbox;
+ int t;
+
+ while (len--) {
+ i++;
+ i = i & 255; /* and seems to be faster than mod */
+ j += sbox[i];
+ j &= 255;
+ t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
+ *outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
+ }
+
+ ctx->idx_i = i;
+ ctx->idx_j = j;
+}
+
+void ARC4 (ARC4_CONTEXT *ctx, unsigned int len, const unsigned char *inbuf, unsigned char *outbuf)
+{
+ do_encrypt_stream(ctx, outbuf, inbuf, len);
+ _gcry_burn_stack(64);
+}
+
+static void do_arcfour_setkey (ARC4_CONTEXT *ctx, const unsigned char *key, unsigned int keylen)
+{
+ int i, j;
+ unsigned char karr[256];
+
+ ctx->idx_i = ctx->idx_j = 0;
+ for (i = 0; i < 256; i++) ctx->sbox[i] = i;
+ for (i = 0; i < 256; i++) karr[i] = key[i%keylen];
+ for (i = j = 0; i < 256; i++) {
+ int t;
+ j = (j + ctx->sbox[i] + karr[i]) % 256;
+ t = ctx->sbox[i];
+ ctx->sbox[i] = ctx->sbox[j];
+ ctx->sbox[j] = t;
+ }
+ memset(karr, 0, 256);
+}
+
+void ARC4_set_key (ARC4_CONTEXT *ctx, unsigned int keylen, const unsigned char *key)
+{
+ do_arcfour_setkey(ctx, key, keylen);
+ _gcry_burn_stack(300);
+}
+
+/* AES Support */
+
+static int rijndaelSetupEncrypt(uint32_t *rk, const uint8_t *key, int keybits);
+static void rijndaelEncrypt(const uint32_t *rk, int nrounds,
+ const uint8_t plaintext[16], uint8_t ciphertext[16]);
+
+#define KEYLENGTH(keybits) ((keybits)/8)
+#define RKLENGTH(keybits) ((keybits)/8+28)
+#define NROUNDS(keybits) ((keybits)/32+6)
+
+#define KEYBITS 256
+
+typedef struct {
+ int nrounds;
+ uint32_t rk[60];
+ unsigned char iv[AES_BLOCKSIZE];
+} AES_CONTEXT;
+
+void
+AES_ecb_encrypt (const unsigned char *key, size_t key_len,
+ const unsigned char *plain, size_t plain_len,
+ unsigned char **cipher, size_t *cipher_len)
+{
+ AES_CONTEXT *ctx, aes;
+ const unsigned char *inptr;
+ unsigned char *outptr;
+ size_t len;
+
+ ctx = &aes;
+
+ *cipher_len = plain_len;
+ *cipher = NEW(*cipher_len, unsigned char);
+
+ ctx->nrounds = rijndaelSetupEncrypt(ctx->rk, key, key_len * 8);
+
+ inptr = plain; outptr = *cipher;
+ for (len = plain_len; len >= AES_BLOCKSIZE; len -= AES_BLOCKSIZE) {
+ rijndaelEncrypt(ctx->rk, ctx->nrounds, inptr, outptr);
+ inptr += AES_BLOCKSIZE;
+ outptr += AES_BLOCKSIZE;
+ }
+ if (len > 0) {
+ unsigned char block[AES_BLOCKSIZE];
+
+ memcpy(block, inptr, len);
+ rijndaelEncrypt(ctx->rk, ctx->nrounds, block, outptr);
+ inptr += len;
+ outptr += AES_BLOCKSIZE;
+ }
+}
+
+/* NULL iv means here "use random IV". */
+void
+AES_cbc_encrypt (const unsigned char *key, size_t key_len,
+ const unsigned char *iv, int padding,
+ const unsigned char *plain, size_t plain_len,
+ unsigned char **cipher, size_t *cipher_len)
+{
+ AES_CONTEXT *ctx, aes;
+ const unsigned char *inptr;
+ unsigned char *outptr, block[AES_BLOCKSIZE];
+ size_t len;
+ int i;
+ int padbytes;
+
+ ctx = &aes;
+
+ if (iv)
+ memcpy(ctx->iv, iv, AES_BLOCKSIZE);
+ else {
+ for (i = 0; i < AES_BLOCKSIZE; i++)
+ ctx->iv[i] = rand() % 256;
+ }
+ /* 16 bytes aligned.
+ * Note that when padding is enabled there can be excess 16-byte
+ * filled with 0x10. It occurs when size of the input data is multiple
+ * of 16.
+ */
+ padbytes = padding ? AES_BLOCKSIZE - (plain_len % AES_BLOCKSIZE) : \
+ ((plain_len % AES_BLOCKSIZE) ? \
+ AES_BLOCKSIZE - (plain_len % AES_BLOCKSIZE) : 0);
+
+ /* We do NOT write IV to the output stream if IV is explicitly specified. */
+ *cipher_len = plain_len + (iv ? 0 : AES_BLOCKSIZE) + padbytes;
+ *cipher = NEW(*cipher_len, unsigned char);
+
+ ctx->nrounds = rijndaelSetupEncrypt(ctx->rk, key, key_len * 8);
+
+ inptr = plain; outptr = *cipher;
+ if (!iv) {
+ memcpy(outptr, ctx->iv, AES_BLOCKSIZE);
+ outptr += AES_BLOCKSIZE;
+ }
+ for (len = plain_len; len >= AES_BLOCKSIZE; len -= AES_BLOCKSIZE) {
+ for (i = 0; i < AES_BLOCKSIZE; i++)
+ block[i] = inptr[i] ^ ctx->iv[i];
+ rijndaelEncrypt(ctx->rk, ctx->nrounds, block, outptr);
+ memcpy(ctx->iv, outptr, AES_BLOCKSIZE);
+ inptr += AES_BLOCKSIZE;
+ outptr += AES_BLOCKSIZE;
+ }
+ if (len > 0 || padding) {
+ for (i = 0; i < len; i++)
+ block[i] = inptr[i] ^ ctx->iv[i];
+ for (i = len; i < AES_BLOCKSIZE; i++)
+ block[i] = padbytes ^ ctx->iv[i];
+ rijndaelEncrypt(ctx->rk, ctx->nrounds, block, outptr);
+ memcpy(ctx->iv, outptr, AES_BLOCKSIZE);
+ inptr += AES_BLOCKSIZE;
+ outptr += AES_BLOCKSIZE;
+ }
+}
+
+/* The following section contains a Rijndael encryption implementation
+ * based on code from Philip J. Erdelsky's public domain one.
+ * They can be obtained from
+ *
+ * http://www.efgh.com/software/rijndael.htm
+ * http://www.efgh.com/software/rijndael.txt
+ */
+
+#define FULL_UNROLL
+
+static const uint32_t Te0[256] =
+{
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+
+static const uint32_t Te1[256] =
+{
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+
+static const uint32_t Te2[256] =
+{
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+
+static const uint32_t Te3[256] =
+{
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const uint32_t Te4[256] =
+{
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+
+static const uint32_t rcon[] =
+{
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000,
+ /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+#define GETU32(plaintext) (((uint32_t)(plaintext)[0] << 24) ^ \
+ ((uint32_t)(plaintext)[1] << 16) ^ \
+ ((uint32_t)(plaintext)[2] << 8) ^ \
+ ((uint32_t)(plaintext)[3]))
+
+#define PUTU32(ciphertext, st) { (ciphertext)[0] = (uint8_t)((st) >> 24); \
+ (ciphertext)[1] = (uint8_t)((st) >> 16); \
+ (ciphertext)[2] = (uint8_t)((st) >> 8); \
+ (ciphertext)[3] = (uint8_t)(st); }
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+int rijndaelSetupEncrypt(uint32_t *rk, const uint8_t *key, int keybits)
+{
+ int i = 0;
+ uint32_t temp;
+
+ rk[0] = GETU32(key );
+ rk[1] = GETU32(key + 4);
+ rk[2] = GETU32(key + 8);
+ rk[3] = GETU32(key + 12);
+ if (keybits == 128)
+ {
+ for (;;)
+ {
+ temp = rk[3];
+ rk[4] = rk[0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ if (++i == 10)
+ return 10;
+ rk += 4;
+ }
+ }
+ rk[4] = GETU32(key + 16);
+ rk[5] = GETU32(key + 20);
+ if (keybits == 192)
+ {
+ for (;;)
+ {
+ temp = rk[ 5];
+ rk[ 6] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 7] = rk[ 1] ^ rk[ 6];
+ rk[ 8] = rk[ 2] ^ rk[ 7];
+ rk[ 9] = rk[ 3] ^ rk[ 8];
+ if (++i == 8)
+ return 12;
+ rk[10] = rk[ 4] ^ rk[ 9];
+ rk[11] = rk[ 5] ^ rk[10];
+ rk += 6;
+ }
+ }
+ rk[6] = GETU32(key + 24);
+ rk[7] = GETU32(key + 28);
+ if (keybits == 256)
+ {
+ for (;;)
+ {
+ temp = rk[ 7];
+ rk[ 8] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 9] = rk[ 1] ^ rk[ 8];
+ rk[10] = rk[ 2] ^ rk[ 9];
+ rk[11] = rk[ 3] ^ rk[10];
+ if (++i == 7)
+ return 14;
+ temp = rk[11];
+ rk[12] = rk[ 4] ^
+ (Te4[(temp >> 24) ] & 0xff000000) ^
+ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp ) & 0xff] & 0x000000ff);
+ rk[13] = rk[ 5] ^ rk[12];
+ rk[14] = rk[ 6] ^ rk[13];
+ rk[15] = rk[ 7] ^ rk[14];
+ rk += 8;
+ }
+ }
+ return 0;
+}
+
+void rijndaelEncrypt(const uint32_t *rk, int nrounds,
+ const uint8_t plaintext[16], uint8_t ciphertext[16])
+{
+ uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
+ #ifndef FULL_UNROLL
+ int r;
+ #endif /* ?FULL_UNROLL */
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(plaintext ) ^ rk[0];
+ s1 = GETU32(plaintext + 4) ^ rk[1];
+ s2 = GETU32(plaintext + 8) ^ rk[2];
+ s3 = GETU32(plaintext + 12) ^ rk[3];
+ #ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+ if (nrounds > 10)
+ {
+ /* round 10: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+ if (nrounds > 12)
+ {
+ /* round 12: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+ }
+ }
+ rk += nrounds << 2;
+ #else /* !FULL_UNROLL */
+ /*
+ * nrounds - 1 full rounds:
+ */
+ r = nrounds >> 1;
+ for (;;)
+ {
+ t0 =
+ Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[7];
+ rk += 8;
+ if (--r == 0)
+ break;
+ s0 =
+ Te0[(t0 >> 24) ] ^
+ Te1[(t1 >> 16) & 0xff] ^
+ Te2[(t2 >> 8) & 0xff] ^
+ Te3[(t3 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Te0[(t1 >> 24) ] ^
+ Te1[(t2 >> 16) & 0xff] ^
+ Te2[(t3 >> 8) & 0xff] ^
+ Te3[(t0 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Te0[(t2 >> 24) ] ^
+ Te1[(t3 >> 16) & 0xff] ^
+ Te2[(t0 >> 8) & 0xff] ^
+ Te3[(t1 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Te0[(t3 >> 24) ] ^
+ Te1[(t0 >> 16) & 0xff] ^
+ Te2[(t1 >> 8) & 0xff] ^
+ Te3[(t2 ) & 0xff] ^
+ rk[3];
+ }
+ #endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Te4[(t0 >> 24) ] & 0xff000000) ^
+ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(ciphertext , s0);
+ s1 =
+ (Te4[(t1 >> 24) ] & 0xff000000) ^
+ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(ciphertext + 4, s1);
+ s2 =
+ (Te4[(t2 >> 24) ] & 0xff000000) ^
+ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(ciphertext + 8, s2);
+ s3 =
+ (Te4[(t3 >> 24) ] & 0xff000000) ^
+ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(ciphertext + 12, s3);
+}
diff --git a/Build/source/texk/dvipdfm-x/dpxcrypt.h b/Build/source/texk/dvipdfm-x/dpxcrypt.h
new file mode 100644
index 00000000000..2ae8234627d
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxcrypt.h
@@ -0,0 +1,97 @@
+/* This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
+
+ Copyright (C) 2003-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _DPXCRYPT_H_
+#define _DPXCRYPT_H_
+
+#include <stdio.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+/* libgcrypt md5 */
+typedef struct {
+ uint32_t A, B, C, D; /* chaining variables */
+ size_t nblocks;
+ unsigned char buf[64];
+ int count;
+} MD5_CONTEXT;
+
+void MD5_init (MD5_CONTEXT *ctx);
+void MD5_write(MD5_CONTEXT *ctx, const unsigned char *inbuf, unsigned int inlen);
+void MD5_final(unsigned char *outbuf, MD5_CONTEXT *ctx);
+
+typedef struct {
+ uint32_t h0,h1,h2,h3,h4,h5,h6,h7;
+ size_t nblocks;
+ unsigned char buf[64];
+ int count;
+} SHA256_CONTEXT;
+
+typedef struct
+{
+ uint64_t h0, h1, h2, h3, h4, h5, h6, h7;
+} SHA512_STATE;
+
+typedef struct
+{
+ SHA512_STATE state;
+ size_t nblocks;
+ unsigned char buf[128];
+ int count;
+} SHA512_CONTEXT;
+
+void SHA256_init (SHA256_CONTEXT *ctx);
+void SHA256_write(SHA256_CONTEXT *ctx,
+ const unsigned char *inbuf, unsigned int inlen);
+void SHA256_final(unsigned char *outbuf, SHA256_CONTEXT *ctx);
+
+void SHA384_init (SHA512_CONTEXT *ctx);
+#define SHA384_write(c,b,l) SHA512_write((c),(b),(l))
+#define SHA384_final(b,c) SHA512_final((b),(c))
+void SHA512_init (SHA512_CONTEXT *ctx);
+void SHA512_write(SHA512_CONTEXT *ctx,
+ const unsigned char *inbuf, unsigned int inlen);
+void SHA512_final(unsigned char *outbuf, SHA512_CONTEXT *ctx);
+
+/* libgcrypt arcfour */
+typedef struct {
+ int idx_i, idx_j;
+ unsigned char sbox[256];
+} ARC4_CONTEXT;
+
+#define AES_BLOCKSIZE 16
+
+void ARC4 (ARC4_CONTEXT *ctx, unsigned int len, const unsigned char *inbuf, unsigned char *outbuf);
+void ARC4_set_key (ARC4_CONTEXT *ctx, unsigned int keylen, const unsigned char *key);
+
+void AES_ecb_encrypt (const unsigned char *key, size_t key_len,
+ const unsigned char *plain, size_t plain_len,
+ unsigned char **cipher, size_t *cipher_len);
+
+void AES_cbc_encrypt (const unsigned char *key, size_t key_len,
+ const unsigned char *iv, int padding,
+ const unsigned char *plain, size_t plain_len,
+ unsigned char **cipher, size_t *cipher_len);
+
+#endif /* _DPXCRYPT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/dpxfile.c b/Build/source/texk/dvipdfm-x/dpxfile.c
new file mode 100644
index 00000000000..2ffa2460498
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxfile.c
@@ -0,0 +1,1324 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef _MSC_VER
+#include <kpathsea/dirent.h>
+#endif
+
+#if defined(MIKTEX_WINDOWS)
+#include <miktex/unxemu.h>
+#endif
+
+#include <time.h>
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+#include "dpxutil.h"
+#include "mfileio.h"
+
+#include "dpxfile.h"
+#include "dpxcrypt.h"
+#define MAX_KEY_LEN 16
+
+#include <kpathsea/lib.h>
+#include <string.h>
+#ifdef WIN32
+#include <io.h>
+#include <process.h>
+#include <wchar.h>
+#else
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(val) ((unsigned)(val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(val) (((val) & 255) == 0)
+#endif
+#endif
+
+#if defined(MIKTEX) || defined(TESTCOMPILE)
+#if defined(__APPLE__)
+# include <sys/syslimits.h>
+#endif
+#if !defined(PATH_MAX)
+# define PATH_MAX 256
+#endif
+#endif /* MIKTEX || TESTCOMPILE */
+
+/* Kpathsea library does not check file type. */
+static int qcheck_filetype (const char *fqpn, dpx_res_type type);
+
+/* For testing MIKTEX enabled compilation */
+#if defined(TESTCOMPILE) && !defined(MIKTEX)
+# define MIKTEX 1
+# define PATH_SEP_CHR '/'
+
+static int
+miktex_get_acrobat_font_dir (char *buf)
+{
+ strcpy(buf, "/usr/share/ghostscript/Resource/Font/");
+ return 1;
+}
+
+static int
+miktex_find_file (const char *filename, const char *dirlist, char *buf)
+{
+ int r = 0;
+ char *fqpn;
+
+ fqpn = kpse_path_search(dirlist, filename, 0);
+ if (!fqpn)
+ return 0;
+ if (strlen(fqpn) > PATH_MAX)
+ r = 0;
+ else {
+ strcpy(buf, fqpn);
+ r = 1;
+ }
+ RELEASE(fqpn);
+
+ return r;
+}
+
+static int
+miktex_find_app_input_file (const char *progname, const char *filename, char *buf)
+{
+ int r = 0;
+ char *fqpn;
+
+ kpse_reset_program_name(progname);
+ fqpn = kpse_find_file (filename, kpse_program_text_format, false);
+ kpse_reset_program_name("dvipdfmx");
+
+ if (!fqpn)
+ return 0;
+ if (strlen(fqpn) > PATH_MAX)
+ r = 0;
+ else {
+ strcpy(buf, fqpn);
+ r = 1;
+ }
+ RELEASE(fqpn);
+
+ return r;
+}
+
+static int
+miktex_find_psheader_file (const char *filename, char *buf)
+{
+ int r;
+ char *fqpn;
+
+ fqpn = kpse_find_file(filename, kpse_tex_ps_header_format, 0);
+
+ if (!fqpn)
+ return 0;
+ if (strlen(fqpn) > PATH_MAX)
+ r = 0;
+ else {
+ strcpy(buf, fqpn);
+ r = 1;
+ }
+ RELEASE(fqpn);
+
+ return r;
+}
+
+#endif /* TESTCOMPILE */
+
+#ifdef MIKTEX_NO_KPATHSEA
+#ifndef PATH_SEP_CHR
+# define PATH_SEP_CHR '\\'
+#endif
+static char _tmpbuf[PATH_MAX+1];
+#endif /* MIKTEX */
+
+#if defined(_WIN32)
+extern int utf8name_failed;
+int fsyscp_stat(const char *path, struct stat *buffer)
+{
+ wchar_t *wpath;
+ int ret;
+ wpath = get_wstring_from_mbstring(file_system_codepage,
+ path, wpath = NULL);
+ if (wpath == NULL)
+ return -1;
+ ret = _wstat(wpath, buffer);
+ free(wpath);
+ return ret;
+}
+#endif /* _WIN32 */
+
+#define CMDBUFSIZ 1024
+static int exec_spawn (char *cmd)
+{
+ char **cmdv, **qv;
+ char *p, *pp;
+ char buf[CMDBUFSIZ];
+ int charcnt;
+ int i, ret = -1;
+#ifdef WIN32
+ wchar_t **cmdvw, **qvw;
+#endif
+
+ if (!cmd)
+ return -1;
+ while (*cmd == ' ' || *cmd == '\t')
+ cmd++;
+ if (*cmd == '\0')
+ return -1;
+ i = 0;
+ p = cmd;
+ while (*p) {
+ if (*p == ' ' || *p == '\t')
+ i++;
+ p++;
+ }
+ cmdv = xcalloc (i + 4, sizeof (char *));
+ p = cmd;
+ qv = cmdv;
+ while (*p) {
+ pp = buf;
+ charcnt = 0;
+ if (*p == '"') {
+ p++;
+ while (*p != '"') {
+ if (*p == '\0') {
+ goto done;
+ }
+ *pp++ = *p++;
+ charcnt++;
+ if (charcnt > CMDBUFSIZ - 1) {
+ ERROR("Too long a command line.");
+ }
+ }
+ p++;
+ } else if (*p == '\'') {
+ p++;
+ while (*p != '\'') {
+ if (*p == '\0') {
+ goto done;
+ }
+ *pp++ = *p++;
+ charcnt++;
+ if (charcnt > CMDBUFSIZ - 1) {
+ ERROR("Too long a command line.");
+ }
+ }
+ p++;
+ } else {
+ while (*p != ' ' && *p != '\t' && *p) {
+ if (*p == '\'') {
+ p++;
+ while (*p != '\'') {
+ if (*p == '\0') {
+ goto done;
+ }
+ *pp++ = *p++;
+ charcnt++;
+ if (charcnt > CMDBUFSIZ - 1) {
+ ERROR("Too long a command line.");
+ }
+ }
+ p++;
+ } else {
+ *pp++ = *p++;
+ charcnt++;
+ if (charcnt > CMDBUFSIZ - 1) {
+ ERROR("Too long a command line.");
+ }
+ }
+ }
+ }
+ *pp = '\0';
+#ifdef WIN32
+ if (strchr (buf, ' ') || strchr (buf, '\t'))
+ *qv = concat3 ("\"", buf, "\"");
+ else
+#endif
+ *qv = xstrdup (buf);
+/*
+ fprintf(stderr,"\n%s", *qv);
+*/
+ while (*p == ' ' || *p == '\t')
+ p++;
+ qv++;
+ }
+ *qv = NULL;
+
+#ifdef WIN32
+#if defined(MIKTEX)
+ ret = _spawnvp(_P_WAIT, *cmdv, (const char* const*)cmdv);
+#else
+ cmdvw = xcalloc (i + 4, sizeof (wchar_t *));
+ if (utf8name_failed == 0) {
+ qv = cmdv;
+ qvw = cmdvw;
+ while (*qv) {
+ *qvw = get_wstring_from_fsyscp(*qv, *qvw=NULL);
+ qv++;
+ qvw++;
+ }
+ *qvw = NULL;
+ ret = _wspawnvp (_P_WAIT, *cmdvw, (const wchar_t* const*) cmdvw);
+ } else {
+ int tmpcp;
+ tmpcp = file_system_codepage;
+ file_system_codepage = win32_codepage;
+ qv = cmdv;
+ qvw = cmdvw;
+ while (*qv) {
+ *qvw = get_wstring_from_fsyscp(*qv, *qvw=NULL);
+ qv++;
+ qvw++;
+ }
+ *qvw = NULL;
+ file_system_codepage = tmpcp;
+ utf8name_failed = 0;
+ ret = _wspawnvp (_P_WAIT, *cmdvw, (const wchar_t* const*) cmdvw);
+ }
+ if (cmdvw) {
+ qvw = cmdvw;
+ while (*qvw) {
+ free (*qvw);
+ qvw++;
+ }
+ free (cmdvw);
+ }
+#endif
+#else
+ i = fork ();
+ if (i < 0)
+ ret = -1;
+ else if (i == 0) {
+ if (execvp (*cmdv, cmdv))
+ _exit (-1);
+ } else {
+ if (wait (&ret) == i) {
+ ret = (WIFEXITED (ret) ? WEXITSTATUS (ret) : -1);
+ } else {
+ ret = -1;
+ }
+ }
+#endif
+done:
+ qv = cmdv;
+ while (*qv) {
+ free (*qv);
+ qv++;
+ }
+ free (cmdv);
+ return ret;
+}
+
+/* ensuresuffix() returns a copy of basename if sfx is "". */
+static char *
+ensuresuffix (const char *basename, const char *sfx)
+{
+ char *q, *p;
+
+ p = NEW(strlen(basename) + strlen(sfx) + 1, char);
+ strcpy(p, basename);
+ q = strrchr(p, '.');
+ if (!q && sfx[0])
+ strcat(p, sfx);
+
+ return p;
+}
+
+#ifdef MIKTEX_NO_KPATHSEA
+static char *
+dpx_find__app__xyz (const char *filename,
+ const char *suffix, int is_text)
+{
+ char *fqpn = NULL;
+ int r;
+ char *q;
+
+ q = ensuresuffix(filename, suffix);
+ r = miktex_find_app_input_file("dvipdfmx", q, _tmpbuf);
+ if (!r && strcmp(q, filename))
+ r = miktex_find_app_input_file("dvipdfmx", filename, _tmpbuf);
+ if (r) {
+ fqpn = NEW(strlen(_tmpbuf) + 1, char);
+ strcpy(fqpn, _tmpbuf);
+ }
+ RELEASE(q);
+
+ return fqpn;
+}
+
+static char *
+dpx_foolsearch (const char *foolname,
+ const char *filename,
+ int is_text)
+{
+ char *fqpn = NULL;
+ int r;
+
+ r = miktex_find_app_input_file(foolname, filename, _tmpbuf);
+ if (r) {
+ fqpn = NEW(strlen(_tmpbuf) + 1, char);
+ strcpy(fqpn, _tmpbuf);
+ }
+
+ return fqpn;
+}
+#else /* !MIKTEX */
+# define TDS11DOC "http://www.tug.org/ftp/tex/tds-1.1/tds.html#Fonts"
+static void
+insistupdate (const char *filename,
+ const char *fqpn,
+ const char *foolname,
+ kpse_file_format_type foolformat,
+ kpse_file_format_type realformat)
+{
+#if defined(MIKTEX)
+ /* users are not fools */
+#else
+ kpse_format_info_type *fif;
+ kpse_format_info_type *fir;
+ if (dpx_conf.verbose_level < 1)
+ return;
+ fif = &kpse_format_info[foolformat];
+ fir = &kpse_format_info[realformat];
+ WARN("File name=\"%s\" format=\"%s\" might be found in different location than I expected:",
+ filename, fir->type);
+ WARN(">> %s", fqpn);
+ WARN(">> Please adjust your TEXMF as conformant with:");
+ WARN(">> " TDS11DOC);
+ WARN(">> I searched it with fooling kpathsea as progname=\"%s\" format=\"%s\".",
+ foolname, fif->type);
+ WARN(">> Default search path for this format file is:");
+ WARN(">> %s", fir->default_path);
+ WARN(">> Please read \"README\" file.");
+#endif
+}
+
+static char *
+dpx_find__app__xyz (const char *filename,
+ const char *suffix, int is_text)
+{
+ char *fqpn = NULL;
+ char *q;
+
+ q = ensuresuffix(filename, suffix);
+ fqpn = kpse_find_file(q,
+ (is_text ?
+ kpse_program_text_format : kpse_program_binary_format), 0);
+ if (!fqpn && strcmp(q, filename))
+ fqpn = kpse_find_file(filename,
+ (is_text ?
+ kpse_program_text_format : kpse_program_binary_format), 0);
+ RELEASE(q);
+
+ return fqpn;
+}
+
+static char *
+dpx_foolsearch (const char *foolname,
+ const char *filename,
+ int is_text)
+{
+ char *fqpn = NULL;
+
+ kpse_reset_program_name(foolname);
+ fqpn = kpse_find_file (filename,
+ (is_text ?
+ kpse_program_text_format :
+ kpse_program_binary_format),
+ false);
+ kpse_reset_program_name("dvipdfmx");
+
+ return fqpn;
+}
+#endif /* MIKTEX */
+
+static char *dpx_find_fontmap_file (const char *filename);
+static char *dpx_find_agl_file (const char *filename);
+static char *dpx_find_sfd_file (const char *filename);
+static char *dpx_find_cmap_file (const char *filename);
+static char *dpx_find_enc_file (const char *filename);
+static char *dpx_find_iccp_file (const char *filename);
+
+FILE *
+dpx_open_file (const char *filename, dpx_res_type type)
+{
+ FILE *fp = NULL;
+ char *fqpn = NULL;
+
+ switch (type) {
+ case DPX_RES_TYPE_FONTMAP:
+ fqpn = dpx_find_fontmap_file(filename);
+ if (dpx_conf.verbose_level > 0) {
+ if (fqpn != NULL)
+ MESG(fqpn);
+ }
+ break;
+ case DPX_RES_TYPE_T1FONT:
+ fqpn = dpx_find_type1_file(filename);
+ break;
+ case DPX_RES_TYPE_TTFONT:
+ fqpn = dpx_find_truetype_file(filename);
+ break;
+ case DPX_RES_TYPE_OTFONT:
+ fqpn = dpx_find_opentype_file(filename);
+ break;
+ case DPX_RES_TYPE_PKFONT:
+ break;
+ case DPX_RES_TYPE_CMAP:
+ fqpn = dpx_find_cmap_file(filename);
+ break;
+ case DPX_RES_TYPE_ENC:
+ fqpn = dpx_find_enc_file(filename);
+ break;
+ case DPX_RES_TYPE_SFD:
+ fqpn = dpx_find_sfd_file(filename);
+ break;
+ case DPX_RES_TYPE_AGL:
+ fqpn = dpx_find_agl_file(filename);
+ break;
+ case DPX_RES_TYPE_ICCPROFILE:
+ fqpn = dpx_find_iccp_file(filename);
+ break;
+ case DPX_RES_TYPE_DFONT:
+ fqpn = dpx_find_dfont_file(filename);
+ break;
+ case DPX_RES_TYPE_BINARY:
+ fqpn = dpx_find__app__xyz(filename, "", 0);
+ break;
+ case DPX_RES_TYPE_TEXT:
+ fqpn = dpx_find__app__xyz(filename, "", 1);
+ break;
+ }
+ if (fqpn) {
+ fp = MFOPEN(fqpn, FOPEN_RBIN_MODE);
+ RELEASE(fqpn);
+ }
+
+ return fp;
+}
+
+
+static char *
+dpx_find_iccp_file (const char *filename)
+{
+ char *fqpn = NULL;
+
+ fqpn = dpx_find__app__xyz(filename, "", 0);
+ if (fqpn || strrchr(filename, '.'))
+ return fqpn;
+
+ fqpn = dpx_find__app__xyz(filename, ".icc", 0);
+ if (fqpn)
+ return fqpn;
+
+ fqpn = dpx_find__app__xyz(filename, ".icm", 0);
+
+ return fqpn;
+}
+
+
+static char *
+dpx_find_fontmap_file (const char *filename)
+{
+ char *fqpn = NULL;
+ char *q;
+
+ q = ensuresuffix(filename, ".map");
+#ifdef MIKTEX_NO_KPATHSEA
+ fqpn = dpx_find__app__xyz(q, ".map", 1);
+#else /* !MIKTEX */
+ fqpn = kpse_find_file(q, kpse_fontmap_format, 0);
+ if (!fqpn) {
+ fqpn = dpx_find__app__xyz(q, ".map", 1);
+ if (fqpn)
+ insistupdate(q, fqpn, "dvipdfmx",
+ kpse_program_text_format, kpse_fontmap_format);
+ }
+#endif /* MIKETEX */
+ RELEASE(q);
+
+ return fqpn;
+}
+
+
+static char *
+dpx_find_agl_file (const char *filename)
+{
+ char *fqpn = NULL;
+ char *q;
+
+ q = ensuresuffix(filename, ".txt");
+#ifdef MIKTEX_NO_KPATHSEA
+ fqpn = dpx_find__app__xyz(q, ".txt", 1);
+#else /* !MIKTEX */
+ fqpn = kpse_find_file(q, kpse_fontmap_format, 0);
+ if (!fqpn) {
+ fqpn = dpx_find__app__xyz(q, ".txt", 1);
+ if (fqpn)
+ insistupdate(q, fqpn, "dvipdfmx",
+ kpse_program_text_format, kpse_fontmap_format);
+ }
+#endif /* MIKETEX */
+ RELEASE(q);
+
+ return fqpn;
+}
+
+
+/* cmap.sty put files into tex/latex/cmap */
+static char *
+dpx_find_cmap_file (const char *filename)
+{
+ char *fqpn = NULL;
+ static const char *fools[] = {
+ "cmap", "tex", NULL
+ };
+ int i;
+
+#if defined(MIKTEX_NO_KPATHSEA)
+ /* Find in Acrobat's Resource/CMap dir */
+ {
+ char _acrodir[PATH_MAX+1];
+ char *q;
+ int r;
+
+ memset(_acrodir, 0, PATH_MAX+1);
+ r = miktex_get_acrobat_font_dir(_acrodir);
+ if (r &&
+ strlen(_acrodir) > strlen("Font")) {
+ /* ....\Font\ */
+ q = strrchr(_acrodir, PATH_SEP_CHR);
+ if (q && q[1] == '\0')
+ q[0] = '\0';
+ q = strrchr(_acrodir, PATH_SEP_CHR);
+ if (q && !strcmp(q + 1, "Font")) {
+ sprintf(q, "%cCMap%c", PATH_SEP_CHR, PATH_SEP_CHR);
+ r = miktex_find_file(filename, _acrodir, _tmpbuf);
+ if (r) {
+ fqpn = NEW(strlen(_tmpbuf) + 1, char);
+ strcpy(fqpn, _tmpbuf);
+ }
+ }
+ }
+ memset(_tmpbuf, 0, PATH_MAX+1);
+ }
+#else
+ fqpn = kpse_find_file(filename, kpse_cmap_format, 0);
+#endif
+
+ /* Files found above are assumed to be CMap,
+ * if it's not really CMap it will cause an error.
+ */
+ for (i = 0; !fqpn && fools[i]; i++) {
+ fqpn = dpx_foolsearch(fools[i], filename, 1);
+ if (fqpn) {
+#ifndef MIKTEX_NO_KPATHSEA
+ insistupdate(filename, fqpn, fools[i],
+ kpse_program_text_format, kpse_cmap_format);
+#endif
+ if (!qcheck_filetype(fqpn, DPX_RES_TYPE_CMAP)) {
+ WARN("Found file \"%s\" for PostScript CMap but it doesn't look like a CMap...", fqpn);
+ RELEASE(fqpn);
+ fqpn = NULL;
+ }
+ }
+ }
+
+ return fqpn;
+}
+
+
+/* Search order:
+ * SFDFONTS (TDS 1.1)
+ * ttf2pk (text file)
+ * ttf2tfm (text file)
+ * dvipdfm (text file)
+ */
+static char *
+dpx_find_sfd_file (const char *filename)
+{
+ char *fqpn = NULL;
+ char *q;
+ static const char *fools[] = {
+ "ttf2pk", "ttf2tfm", NULL
+ };
+ int i;
+
+ q = ensuresuffix(filename, ".sfd");
+#ifndef MIKTEX_NO_KPATHSEA
+ fqpn = kpse_find_file(q, kpse_sfd_format, 0);
+#endif /* !MIKTEX */
+
+ for (i = 0; !fqpn && fools[i]; i++) {
+ fqpn = dpx_foolsearch(fools[i], q, 1);
+#ifndef MIKTEX_NO_KPATHSEA
+ if (fqpn)
+ insistupdate(filename, fqpn, fools[i],
+ kpse_program_text_format, kpse_sfd_format);
+#endif
+ }
+ RELEASE(q);
+
+ return fqpn;
+}
+
+
+static char *
+dpx_find_enc_file (const char *filename)
+{
+ char *fqpn = NULL;
+ char *q;
+ static const char *fools[] = {
+ "dvips", NULL
+ };
+ int i;
+
+ q = ensuresuffix(filename, ".enc");
+#ifdef MIKTEX_NO_KPATHSEA
+ if (miktex_find_psheader_file(q, _tmpbuf)) {
+ fqpn = NEW(strlen(_tmpbuf) + 1, char);
+ strcpy(fqpn, _tmpbuf);
+ }
+#else
+ fqpn = kpse_find_file(q, kpse_enc_format, 0);
+#endif /* MIKTEX */
+
+ for (i = 0; !fqpn && fools[i]; i++) {
+ fqpn = dpx_foolsearch(fools[i], q, 1);
+#ifndef MIKTEX_NO_KPATHSEA
+ if (fqpn)
+ insistupdate(filename, fqpn, fools[i],
+ kpse_program_text_format, kpse_enc_format);
+#endif
+ }
+ RELEASE(q);
+
+ return fqpn;
+}
+
+static int
+is_absolute_path(const char *filename)
+{
+#ifdef WIN32
+ if (isalpha(filename[0]) && filename[1] == ':')
+ return 1;
+ if (filename[0] == '\\' && filename[1] == '\\')
+ return 1;
+ if (filename[0] == '/' && filename[1] == '/')
+ return 1;
+#else
+ if (filename[0] == '/')
+ return 1;
+#endif
+ return 0;
+}
+
+char *
+dpx_find_type1_file (const char *filename)
+{
+ char *fqpn = NULL;
+
+ if (is_absolute_path(filename))
+ fqpn = xstrdup(filename);
+ else
+ fqpn = kpse_find_file(filename, kpse_type1_format, 0);
+ if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_T1FONT)) {
+ RELEASE(fqpn);
+ fqpn = NULL;
+ }
+
+ return fqpn;
+}
+
+
+char *
+dpx_find_truetype_file (const char *filename)
+{
+ char *fqpn = NULL;
+
+ if (is_absolute_path(filename))
+ fqpn = xstrdup(filename);
+ else
+ fqpn = kpse_find_file(filename, kpse_truetype_format, 0);
+ if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_TTFONT)) {
+ RELEASE(fqpn);
+ fqpn = NULL;
+ }
+
+ return fqpn;
+}
+
+
+char *
+dpx_find_opentype_file (const char *filename)
+{
+ char *fqpn = NULL;
+ char *q;
+
+ q = ensuresuffix(filename, ".otf");
+#ifndef MIKTEX_NO_KPATHSEA
+ if (is_absolute_path(q))
+ fqpn = xstrdup(q);
+ else
+ fqpn = kpse_find_file(q, kpse_opentype_format, 0);
+ if (!fqpn) {
+#endif
+ fqpn = dpx_foolsearch("dvipdfmx", q, 0);
+#ifndef MIKTEX_NO_KPATHSEA
+ if (fqpn)
+ insistupdate(filename, fqpn, "dvipdfmx",
+ kpse_program_binary_format, kpse_opentype_format);
+ }
+#endif
+ RELEASE(q);
+
+ /* *We* use "opentype" for ".otf" (CFF). */
+ if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_OTFONT)) {
+ RELEASE(fqpn);
+ fqpn = NULL;
+ }
+
+ return fqpn;
+}
+
+
+char *
+dpx_find_dfont_file (const char *filename)
+{
+ char *fqpn = NULL;
+
+ fqpn = kpse_find_file(filename, kpse_truetype_format, 0);
+ if (fqpn) {
+ int len = strlen(fqpn);
+ if (len > 6 && strncmp(fqpn+len-6, ".dfont", 6)) {
+ fqpn = RENEW(fqpn, len+6, char);
+ strcat(fqpn, "/rsrc");
+ }
+ }
+ if (!qcheck_filetype(fqpn, DPX_RES_TYPE_DFONT)) {
+ RELEASE(fqpn);
+ fqpn = NULL;
+ }
+ return fqpn;
+}
+
+static char *
+dpx_get_tmpdir (void)
+{
+#ifdef WIN32
+# define __TMPDIR "."
+#else /* WIN32 */
+# define __TMPDIR "/tmp"
+#endif /* WIN32 */
+ size_t i;
+ char *ret;
+ const char *_tmpd;
+
+#ifdef HAVE_GETENV
+ _tmpd = getenv("TMPDIR");
+# ifdef WIN32
+ if (!_tmpd)
+ _tmpd = getenv("TMP");
+ if (!_tmpd)
+ _tmpd = getenv("TEMP");
+# endif /* WIN32 */
+ if (!_tmpd)
+ _tmpd = __TMPDIR;
+#else /* HAVE_GETENV */
+ _tmpd = __TMPDIR;
+#endif /* HAVE_GETENV */
+ ret = xstrdup(_tmpd);
+ i = strlen(ret);
+ while(i > 1 && IS_DIR_SEP(ret[i-1])) {
+ ret[i-1] = '\0';
+ i--;
+ }
+ return ret;
+}
+
+#ifdef HAVE_MKSTEMP
+# include <stdlib.h>
+#endif
+
+char *
+dpx_create_temp_file (void)
+{
+ char *tmp = NULL;
+
+#if defined(MIKTEX)
+ {
+ tmp = NEW(PATH_MAX + 1, char);
+ miktex_create_temp_file_name(tmp); /* FIXME_FIXME */
+#if defined(MIKTEX_WINDOWS)
+ {
+ char * lpsz;
+ for (lpsz = tmp; *lpsz != 0; ++ lpsz)
+ {
+ if (*lpsz == '\\')
+ {
+ *lpsz = '/';
+ }
+ }
+ }
+#endif
+ }
+#elif defined(HAVE_MKSTEMP)
+# define TEMPLATE "/dvipdfmx.XXXXXX"
+ {
+ char *_tmpd;
+ int _fd = -1;
+ _tmpd = dpx_get_tmpdir();
+ tmp = NEW(strlen(_tmpd) + strlen(TEMPLATE) + 1, char);
+ strcpy(tmp, _tmpd);
+ RELEASE(_tmpd);
+ strcat(tmp, TEMPLATE);
+ _fd = mkstemp(tmp);
+ if (_fd != -1) {
+# ifdef WIN32
+ char *p;
+ for (p = tmp; *p; p++) {
+ if (IS_KANJI (p))
+ p++;
+ else if (*p == '\\')
+ *p = '/';
+ }
+ _close(_fd);
+# else
+ close(_fd);
+# endif /* WIN32 */
+ } else {
+ RELEASE(tmp);
+ tmp = NULL;
+ }
+ }
+#else /* use _tempnam or tmpnam */
+ {
+# ifdef WIN32
+ char *_tmpd;
+ char *p;
+ _tmpd = dpx_get_tmpdir();
+ tmp = _tempnam (_tmpd, "dvipdfmx.");
+ RELEASE(_tmpd);
+ for (p = tmp; *p; p++) {
+ if (IS_KANJI(p))
+ p++;
+ else if (*p == '\\')
+ *p = '/';
+ }
+# else /* WIN32 */
+ char *_tmpa = NEW(L_tmpnam + 1, char);
+ tmp = tmpnam(_tmpa);
+ if (!tmp)
+ RELEASE(_tmpa);
+# endif /* WIN32 */
+ }
+#endif /* MIKTEX */
+
+ return tmp;
+}
+
+char *
+dpx_create_fix_temp_file (const char *filename)
+{
+#define PREFIX "dvipdfm-x."
+ static char *dir = NULL;
+ static char *cwd = NULL;
+ char *ret, *s;
+ int i;
+ MD5_CONTEXT state;
+ unsigned char digest[MAX_KEY_LEN];
+#ifdef WIN32
+ char *p;
+#endif
+
+ if (!dir) {
+ dir = dpx_get_tmpdir();
+ cwd = xgetcwd();
+ }
+
+ MD5_init(&state);
+ MD5_write(&state, (unsigned char *)cwd, strlen(cwd));
+ MD5_write(&state, (unsigned const char *)filename, strlen(filename));
+ MD5_final(digest, &state);
+
+ ret = NEW(strlen(dir)+1+strlen(PREFIX)+MAX_KEY_LEN*2 + 1, char);
+ sprintf(ret, "%s/%s", dir, PREFIX);
+ s = ret + strlen(ret);
+ for (i=0; i<MAX_KEY_LEN; i++) {
+ sprintf(s, "%02x", digest[i]);
+ s += 2;
+ }
+#ifdef WIN32
+ for (p = ret; *p; p++) {
+#if defined(MIKTEX)
+ if (*p == '\\')
+ *p = '/';
+#else
+ if (IS_KANJI (p))
+ p++;
+ else if (*p == '\\')
+ *p = '/';
+#endif
+ }
+#endif
+ /* printf("dpx_create_fix_temp_file: %s\n", ret); */
+ return ret;
+}
+
+static int
+dpx_clear_cache_filter (const struct dirent *ent) {
+ int plen = strlen(PREFIX);
+ if (strlen(ent->d_name) != plen + MAX_KEY_LEN * 2) return 0;
+#ifdef WIN32
+ return strncasecmp(ent->d_name, PREFIX, plen) == 0;
+#else
+ return strncmp(ent->d_name, PREFIX, plen) == 0;
+#endif
+}
+
+void
+dpx_delete_old_cache (int life)
+{
+ char *dir;
+ char *pathname;
+ DIR *dp;
+ struct dirent *de;
+ time_t limit;
+
+ if (life == -2) {
+ dpx_conf.file.keep_cache = -1;
+ return;
+ }
+
+ dir = dpx_get_tmpdir();
+ pathname = NEW(strlen(dir)+1+strlen(PREFIX)+MAX_KEY_LEN*2 + 1, char);
+ limit = time(NULL) - life * 60 * 60;
+
+ if (life >= 0) dpx_conf.file.keep_cache = 1;
+ if ((dp = opendir(dir)) != NULL) {
+ while((de = readdir(dp)) != NULL) {
+ if (dpx_clear_cache_filter(de)) {
+ struct stat sb;
+ sprintf(pathname, "%s/%s", dir, de->d_name);
+/* Here pathname is always ASCII only. So fsyscp_stat() is
+ * not necessary for Windows.
+ */
+ stat(pathname, &sb);
+ if (sb.st_mtime < limit) {
+ remove(pathname);
+ /* printf("remove: %s\n", pathname); */
+ }
+ }
+ }
+ closedir(dp);
+ }
+ RELEASE(dir);
+ RELEASE(pathname);
+}
+
+void
+dpx_delete_temp_file (char *tmp, int force)
+{
+ if (!tmp)
+ return;
+ if (force || dpx_conf.file.keep_cache != 1) remove (tmp);
+ RELEASE(tmp);
+
+ return;
+}
+
+/* dpx_file_apply_filter() is used for converting unsupported graphics
+ * format to one of the formats that dvipdfmx can natively handle.
+ * 'input' is the filename of the original file and 'output' is actually
+ * temporal files 'generated' by the above routine.
+ * This should be system dependent. (MiKTeX may want something different)
+ * Please modify as appropriate (see also pdfximage.c and dvipdfmx.c).
+ */
+int
+dpx_file_apply_filter (const char *cmdtmpl,
+ const char *input, const char *output, int version)
+{
+ char *cmd = NULL;
+ const char *p, *q;
+ size_t n, size;
+ int error = 0;
+
+ if (!cmdtmpl)
+ return -1;
+ else if (!input || !output)
+ return -1;
+
+ size = strlen(cmdtmpl) + strlen(input) + strlen(output) + 3;
+ cmd = NEW(size, char);
+ memset(cmd, 0, size);
+ for (n = 0, p = cmdtmpl; *p != 0; p++) {
+#define need(s,l,m,n) \
+if ((l) + (n) >= (m)) { \
+ (m) += (n) + 128; \
+ (s) = RENEW((s), (m), char); \
+}
+ if (p[0] == '%') {
+ p++;
+ switch (p[0]) {
+ case 'o': /* Output file name */
+ need(cmd, n, size, strlen(output));
+ strcpy(cmd + n, output); n += strlen(output);
+ break;
+ case 'i': /* Input filename */
+ need(cmd, n, size, strlen(input));
+ strcpy(cmd + n, input); n += strlen(input);
+ break;
+ case 'b':
+ need(cmd, n, size, strlen(input));
+ q = strrchr(input, '.'); /* wrong */
+ if (q) {
+ memcpy(cmd + n, input, (int) (q - input));
+ n += (int) (q - input);
+ } else {
+ strcpy(cmd + n, input); n += strlen(input);
+ }
+ break;
+ case 'v': /* Version number, e.g. 1.4 */ {
+ char buf[256];
+ sprintf(buf, "%d.%d", version/10, version%10);
+ need(cmd, n, size, strlen(buf));
+ strcpy(cmd + n, buf); n += strlen(buf);
+ break;
+ }
+ case 0:
+ break;
+ case '%':
+ need(cmd, n, size, 1);
+ cmd[n] = '%'; n++;
+ break;
+ }
+ } else {
+ need(cmd, n, size, 1);
+ cmd[n] = p[0]; n++;
+ }
+ }
+ need(cmd, n, size, 1);
+ cmd[n] = '\0';
+ if (strlen(cmd) == 0) {
+ RELEASE(cmd);
+ return -1;
+ }
+
+ error = exec_spawn(cmd);
+ if (error)
+ WARN("Filtering file via command -->%s<-- failed.", cmd);
+ RELEASE(cmd);
+
+ return error;
+}
+
+static char _sbuf[128];
+/*
+ * SFNT type sigs:
+ * `true' (0x74727565): TrueType (Mac)
+ * `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper
+ * 0x00010000: TrueType (Win)/OpenType
+ * `OTTO': PostScript CFF font with OpenType wrapper
+ * `ttcf': TrueType Collection
+ */
+static int
+istruetype (FILE *fp)
+{
+ int n;
+
+ rewind(fp);
+ n = fread(_sbuf, 1, 4, fp);
+ rewind(fp);
+
+ if (n != 4)
+ return 0;
+ else if (!memcmp(_sbuf, "true", 4) ||
+ !memcmp(_sbuf, "\0\1\0\0", 4)) /* This doesn't help... */
+ return 1;
+ else if (!memcmp(_sbuf, "ttcf", 4))
+ return 1;
+
+ return 0;
+}
+
+/* "OpenType" is only for ".otf" here */
+static int
+isopentype (FILE *fp)
+{
+ int n;
+
+ rewind(fp);
+ n = fread(_sbuf, 1, 4, fp);
+ rewind(fp);
+
+ if (n != 4)
+ return 0;
+ else if (!memcmp(_sbuf, "OTTO", 4))
+ return 1;
+ else
+ return 0;
+}
+
+static int
+ist1binary (FILE *fp)
+{
+ char *p;
+ int n;
+
+ rewind(fp);
+ n = fread(_sbuf, 1, 21, fp);
+ rewind(fp);
+
+ p = _sbuf;
+ if (n != 21)
+ return 0;
+ else if (p[0] != (char) 0x80 || p[1] < 0 || p[1] > 3)
+ return 0;
+ else if (!memcmp(p + 6, "%!PS-AdobeFont", 14) ||
+ !memcmp(p + 6, "%!FontType1", 11))
+ return 1;
+ else if (!memcmp(p + 6, "%!PS", 4)) {
+#if 0
+ p[20] = '\0'; p += 6;
+ WARN("Ambiguous PostScript resource type: %s", (char *) p);
+#endif
+ return 1;
+ }
+ /* Otherwise ambiguious */
+ return 0;
+}
+
+/* %!PS-Adobe-x.y Resource-CMap */
+static int
+ispscmap (FILE *fp)
+{
+ char *p;
+ p = mfgets(_sbuf, 128, fp); p[127] = '\0';
+ if (!p || strlen(p) < 4 || memcmp(p, "%!PS", 4))
+ return 0;
+ for (p += 4; *p && !isspace((unsigned char)*p); p++);
+ for ( ; *p && (*p == ' ' || *p == '\t'); p++);
+ if (*p == '\0' || strlen(p) < strlen("Resource-CMap"))
+ return 0;
+ else if (!memcmp(p, "Resource-CMap", strlen("Resource-CMap")))
+ return 1;
+ /* Otherwise ambiguious */
+ return 0;
+}
+
+static int
+isdfont (FILE *fp)
+{
+ int i, n;
+ uint32_t pos;
+
+ rewind(fp);
+
+ get_unsigned_quad(fp);
+ seek_absolute(fp, (pos = get_unsigned_quad(fp)) + 0x18);
+ seek_absolute(fp, pos + get_unsigned_pair(fp));
+ n = get_unsigned_pair(fp);
+ for (i = 0; i <= n; i++) {
+ if (get_unsigned_quad(fp) == 0x73666e74UL) /* "sfnt" */
+ return 1;
+ get_unsigned_quad(fp);
+ }
+ return 0;
+}
+
+/* This actually opens files. */
+static int
+qcheck_filetype (const char *fqpn, dpx_res_type type)
+{
+ int r = 1;
+ FILE *fp;
+ struct stat sb;
+
+ if (!fqpn)
+ return 0;
+
+#if defined(_WIN32)
+ if (fsyscp_stat(fqpn, &sb) != 0 && stat(fqpn, &sb) != 0)
+ return 0;
+#else
+ if (stat(fqpn, &sb) != 0)
+ return 0;
+#endif /* _WIN32 */
+
+ if (sb.st_size == 0)
+ return 0;
+
+ fp = MFOPEN(fqpn, FOPEN_RBIN_MODE);
+ if (!fp) {
+ WARN("File \"%s\" found but I could not open that...", fqpn);
+ return 0;
+ }
+ switch (type) {
+ case DPX_RES_TYPE_T1FONT:
+ r = ist1binary(fp);
+ break;
+ case DPX_RES_TYPE_TTFONT:
+ r = istruetype(fp);
+ break;
+ case DPX_RES_TYPE_OTFONT:
+ r = isopentype(fp);
+ break;
+ case DPX_RES_TYPE_CMAP:
+ r = ispscmap(fp);
+ break;
+ case DPX_RES_TYPE_DFONT:
+ r = isdfont(fp);
+ break;
+ default:
+ break;
+ }
+ MFCLOSE(fp);
+
+ return r;
+}
+
+#if defined(WIN32)
+FILE *generic_fsyscp_fopen (const char *filename, const char *mode)
+{
+ FILE *f;
+
+ f = fsyscp_fopen (filename, mode);
+
+ if (f == NULL && file_system_codepage != win32_codepage) {
+ int tmpcp = file_system_codepage;
+ file_system_codepage = win32_codepage;
+ f = fsyscp_fopen (filename, mode);
+ file_system_codepage = tmpcp;
+ }
+
+ return f;
+}
+#endif /* WIN32 */
diff --git a/Build/source/texk/dvipdfm-x/dpxfile.h b/Build/source/texk/dvipdfm-x/dpxfile.h
new file mode 100644
index 00000000000..4c719145589
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxfile.h
@@ -0,0 +1,67 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _DPXFILE_H_
+#define _DPXFILE_H_
+
+#define DPX_CONFIG_FILE "dvipdfmx.cfg"
+
+typedef enum {
+ DPX_RES_TYPE_FONTMAP = 0,
+
+ DPX_RES_TYPE_T1FONT,
+ DPX_RES_TYPE_TTFONT,
+ DPX_RES_TYPE_OTFONT,
+ DPX_RES_TYPE_PKFONT,
+ DPX_RES_TYPE_DFONT,
+
+ DPX_RES_TYPE_ENC,
+ DPX_RES_TYPE_CMAP,
+ DPX_RES_TYPE_SFD,
+ DPX_RES_TYPE_AGL,
+
+ DPX_RES_TYPE_ICCPROFILE,
+
+ DPX_RES_TYPE_BINARY,
+ DPX_RES_TYPE_TEXT
+} dpx_res_type;
+
+#include "mfileio.h"
+extern FILE *dpx_open_file (const char *filename, dpx_res_type type);
+
+extern char * dpx_find_type1_file (const char *filename);
+extern char * dpx_find_truetype_file (const char *filename);
+extern char * dpx_find_opentype_file (const char *filename);
+extern char * dpx_find_dfont_file (const char *filename);
+
+#define DPXFOPEN(n,t) dpx_open_file((const char *)(n),(t))
+#define DPXFCLOSE(f) MFCLOSE((f))
+
+extern int dpx_file_apply_filter (const char *cmdtmpl,
+ const char *input, const char *output,
+ int version);
+extern char *dpx_create_temp_file (void);
+extern char *dpx_create_fix_temp_file (const char *filename);
+extern void dpx_delete_old_cache (int life);
+extern void dpx_delete_temp_file (char *tmp, int force); /* tmp freed here */
+
+#endif /* _DPXFILE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/dpxutil.c b/Build/source/texk/dvipdfm-x/dpxutil.c
new file mode 100644
index 00000000000..379fb515058
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxutil.c
@@ -0,0 +1,893 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxutil.h"
+
+int
+xtoi (char c)
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ else if (c >= 'a' && c <= 'f')
+ return (c - 'W');
+ else if (c >= 'A' && c <= 'F')
+ return (c - '7');
+ else
+ return -1;
+}
+
+double
+min4 (double x1, double x2, double x3, double x4)
+{
+ double v = x1;
+ if (x2 < v) v = x2;
+ if (x3 < v) v = x3;
+ if (x4 < v) v = x4;
+ return v;
+}
+
+double
+max4 (double x1, double x2, double x3, double x4)
+{
+ double v = x1;
+ if (x2 > v) v = x2;
+ if (x3 > v) v = x3;
+ if (x4 > v) v = x4;
+ return v;
+}
+
+/* Duplicate from pdfparse.c */
+static void
+skip_white (const char **pp, const char *endptr)
+{
+ while (*pp < endptr &&
+ (**pp == ' ' || **pp == '\t' || **pp == '\f' ||
+ **pp == '\r' || **pp == '\n' || **pp == '\0')) {
+ (*pp)++;
+ }
+}
+
+/* This need to allow 'true' prefix for unit and length value must be divided
+ * by current magnification.
+ */
+int
+dpx_util_read_length (double *vp, double mag, const char **pp, const char *endptr)
+{
+ char *q;
+ const char *p = *pp;
+ double v, u = 1.0;
+ const char *_ukeys[] = {
+#define K_UNIT__PT 0
+#define K_UNIT__IN 1
+#define K_UNIT__CM 2
+#define K_UNIT__MM 3
+#define K_UNIT__BP 4
+#define K_UNIT__PC 5
+#define K_UNIT__DD 6
+#define K_UNIT__CC 7
+#define K_UNIT__SP 8
+ "pt", "in", "cm", "mm", "bp", "pc", "dd", "cc", "sp",
+ NULL
+ };
+ int k, error = 0;
+
+ q = parse_float_decimal(&p, endptr);
+ if (!q) {
+ *vp = 0.0; *pp = p;
+ return -1;
+ }
+
+ v = atof(q);
+ RELEASE(q);
+
+ skip_white(&p, endptr);
+ q = parse_c_ident(&p, endptr);
+ if (q) {
+ char *qq = q; /* remember this for RELEASE, because q may be advanced */
+ if (strlen(q) >= strlen("true") &&
+ !memcmp(q, "true", strlen("true"))) {
+ u /= mag != 0.0 ? mag : 1.0; /* inverse magnify */
+ q += strlen("true");
+ }
+ if (strlen(q) == 0) { /* "true" was a separate word from the units */
+ RELEASE(qq);
+ skip_white(&p, endptr);
+ qq = q = parse_c_ident(&p, endptr);
+ }
+ if (q) {
+ for (k = 0; _ukeys[k] && strcmp(_ukeys[k], q); k++);
+ switch (k) {
+ case K_UNIT__PT: u *= 72.0 / 72.27; break;
+ case K_UNIT__IN: u *= 72.0; break;
+ case K_UNIT__CM: u *= 72.0 / 2.54 ; break;
+ case K_UNIT__MM: u *= 72.0 / 25.4 ; break;
+ case K_UNIT__BP: u *= 1.0 ; break;
+ case K_UNIT__PC: u *= 12.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__DD: u *= 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__CC: u *= 12.0 * 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__SP: u *= 72.0 / (72.27 * 65536) ; break;
+ default:
+ WARN("Unknown unit of measure: %s", q);
+ error = -1;
+ break;
+ }
+ RELEASE(qq);
+ }
+ else {
+ WARN("Missing unit of measure after \"true\"");
+ error = -1;
+ }
+ }
+
+ *vp = v * u; *pp = p;
+ return error;
+}
+
+#if defined(_MSC_VER)
+#define strtoll _strtoi64
+#endif
+
+/* If an environment variable SOURCE_DATE_EPOCH is correctly defined like
+ * SOURCE_DATE_EPOCH=1456304492, then returns this value, to be used as the
+ * 'current time', otherwise returns INVALID_EPOCH_VALUE (= (time_t)-1).
+ * In the case of Microsoft Visual Studio 2010, the value should be less
+ * than 32535291600.
+ */
+
+time_t
+dpx_util_get_unique_time_if_given(void)
+{
+ const char *source_date_epoch;
+ int64_t epoch;
+ char *endptr;
+ time_t ret = INVALID_EPOCH_VALUE;
+
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+ if (source_date_epoch) {
+ errno = 0;
+ epoch = strtoll(source_date_epoch, &endptr, 10);
+ if (!(epoch < 0 || *endptr != '\0' || errno != 0)) {
+ ret = (time_t) epoch;
+#if defined(_MSC_VER)
+ if (ret > 32535291599ULL)
+ ret = 32535291599ULL;
+#endif
+ }
+ }
+ return ret;
+}
+
+
+#ifndef HAVE_TM_GMTOFF
+#ifndef HAVE_TIMEZONE
+
+/* auxiliary function to compute timezone offset on
+ systems that do not support the tm_gmtoff in struct tm,
+ or have a timezone variable. Such as i386-solaris. */
+
+static int32_t
+compute_timezone_offset()
+{
+ time_t now;
+ struct tm tm;
+ struct tm local;
+ time_t gmtoff;
+
+ now = get_unique_time_if_given();
+ if (now == INVALID_EPOCH_VALUE) {
+ now = time(NULL);
+ localtime_r(&now, &local);
+ gmtime_r(&now, &tm);
+ return (mktime(&local) - mktime(&tm));
+ } else {
+ return(0);
+ }
+}
+
+#endif /* HAVE_TIMEZONE */
+#endif /* HAVE_TM_GMTOFF */
+
+/*
+ * Docinfo
+ */
+int
+dpx_util_format_asn_date (char *date_string, int need_timezone)
+{
+ int32_t tz_offset;
+ time_t current_time;
+ struct tm *bd_time;
+
+ current_time = dpx_util_get_unique_time_if_given();
+ if (current_time == INVALID_EPOCH_VALUE) {
+ time(&current_time);
+ bd_time = localtime(&current_time);
+
+#ifdef HAVE_TM_GMTOFF
+ tz_offset = bd_time->tm_gmtoff;
+#else
+# ifdef HAVE_TIMEZONE
+ tz_offset = -timezone;
+# else
+ tz_offset = compute_timezone_offset();
+# endif /* HAVE_TIMEZONE */
+#endif /* HAVE_TM_GMTOFF */
+ } else {
+ bd_time = gmtime(&current_time);
+ tz_offset = 0;
+ }
+ if (need_timezone) {
+ if (bd_time->tm_isdst > 0) {
+ tz_offset += 3600;
+ }
+ sprintf(date_string, "D:%04d%02d%02d%02d%02d%02d%c%02d'%02d'",
+ bd_time->tm_year + 1900, bd_time->tm_mon + 1, bd_time->tm_mday,
+ bd_time->tm_hour, bd_time->tm_min, bd_time->tm_sec,
+ (tz_offset > 0) ? '+' : '-', abs(tz_offset) / 3600,
+ (abs(tz_offset) / 60) % 60);
+ } else {
+ sprintf(date_string, "D:%04d%02d%02d%02d%02d%02d",
+ bd_time->tm_year + 1900, bd_time->tm_mon + 1, bd_time->tm_mday,
+ bd_time->tm_hour, bd_time->tm_min, bd_time->tm_sec);
+ }
+
+ return strlen(date_string);
+}
+
+void
+skip_white_spaces (unsigned char **s, unsigned char *endptr)
+{
+ while (*s < endptr)
+ if (!is_space(**s))
+ break;
+ else
+ (*s)++;
+}
+
+void
+dpx_stack_init (dpx_stack *stack)
+{
+ stack->size = 0;
+ stack->top = NULL;
+ stack->bottom = NULL;
+}
+
+void
+dpx_stack_push (dpx_stack *stack, void *data)
+{
+ stack_elem *elem;
+
+ ASSERT(stack);
+
+ elem = NEW(1, stack_elem);
+ elem->prev = stack->top;
+ elem->data = data;
+
+ stack->top = elem;
+ if (stack->size == 0)
+ stack->bottom = elem;
+
+ stack->size++;
+
+ return;
+}
+
+void *
+dpx_stack_pop (dpx_stack *stack)
+{
+ stack_elem *elem;
+ void *data;
+
+ ASSERT(stack);
+
+ if (stack->size == 0)
+ return NULL;
+
+ data = stack->top->data;
+ elem = stack->top;
+ stack->top = elem->prev;
+ if (stack->size == 1)
+ stack->bottom = NULL;
+ RELEASE(elem);
+
+ stack->size--;
+
+ return data;
+}
+
+void *
+dpx_stack_top (dpx_stack *stack)
+{
+ void *data;
+
+ ASSERT(stack);
+
+ if (stack->size == 0)
+ return NULL;
+
+ data = stack->top->data;
+
+ return data;
+}
+
+void *
+dpx_stack_at (dpx_stack *stack, int pos)
+{
+ void *data = NULL;
+ stack_elem *elem;
+
+ if (stack->size == 0)
+ return NULL;
+
+ elem = stack->top;
+ while (pos > 0) {
+ elem = elem->prev;
+ pos--;
+ }
+ if (elem)
+ data = elem->data;
+
+ return data;
+}
+
+void
+dpx_stack_roll (dpx_stack *stack, int n, int j)
+{
+ if (n > stack->size)
+ return;
+ if (n == 1)
+ return;
+ j = j % n;
+ if (j < 0)
+ j = n + j;
+ while (j-- > 0) {
+ int m = n;
+ stack_elem *elem, *prev, *top;
+
+ elem = top = stack->top;
+ while (--m > 0) {
+ elem = elem->prev;
+ }
+ prev = elem->prev;
+ stack->top = top->prev;
+ elem->prev = top;
+ top->prev = prev;
+ }
+}
+
+int
+dpx_stack_depth (dpx_stack *stack)
+{
+ ASSERT(stack);
+
+ return stack->size;
+}
+
+void
+ht_init_table (struct ht_table *ht, hval_free_func hval_free_fn)
+{
+ int i;
+
+ ASSERT(ht);
+
+ for (i = 0; i < HASH_TABLE_SIZE; i++) {
+ ht->table[i] = NULL;
+ }
+ ht->count = 0;
+ ht->hval_free_fn = hval_free_fn;
+}
+
+void
+ht_clear_table (struct ht_table *ht)
+{
+ int i;
+
+ ASSERT(ht);
+
+ for (i = 0; i < HASH_TABLE_SIZE; i++) {
+ struct ht_entry *hent, *next;
+
+ hent = ht->table[i];
+ while (hent) {
+ if (hent->value && ht->hval_free_fn) {
+ ht->hval_free_fn(hent->value);
+ }
+ hent->value = NULL;
+ if (hent->key) {
+ RELEASE(hent->key);
+ }
+ hent->key = NULL;
+ next = hent->next;
+ RELEASE(hent);
+ hent = next;
+ }
+ ht->table[i] = NULL;
+ }
+ ht->count = 0;
+ ht->hval_free_fn = NULL;
+}
+
+int ht_table_size (struct ht_table *ht)
+{
+ ASSERT(ht);
+
+ return ht->count;
+}
+
+static unsigned int
+get_hash (const void *key, int keylen)
+{
+ unsigned int hkey = 0;
+ int i;
+
+ for (i = 0; i < keylen; i++) {
+ hkey = (hkey << 5) + hkey + ((const char *)key)[i];
+ }
+
+ return (hkey % HASH_TABLE_SIZE);
+}
+
+void *
+ht_lookup_table (struct ht_table *ht, const void *key, int keylen)
+{
+ struct ht_entry *hent;
+ unsigned int hkey;
+
+ ASSERT(ht && key);
+
+ hkey = get_hash(key, keylen);
+ hent = ht->table[hkey];
+ while (hent) {
+ if (hent->keylen == keylen &&
+ !memcmp(hent->key, key, keylen)) {
+ return hent->value;
+ }
+ hent = hent->next;
+ }
+
+ return NULL;
+}
+
+int
+ht_remove_table (struct ht_table *ht,
+ const void *key, int keylen)
+/* returns 1 if the element was found and removed and 0 otherwise */
+{
+ struct ht_entry *hent, *prev;
+ unsigned int hkey;
+
+ ASSERT(ht && key);
+
+ hkey = get_hash(key, keylen);
+ hent = ht->table[hkey];
+ prev = NULL;
+ while (hent) {
+ if (hent->keylen == keylen &&
+ !memcmp(hent->key, key, keylen)) {
+ break;
+ }
+ prev = hent;
+ hent = hent->next;
+ }
+ if (hent) {
+ if (hent->key)
+ RELEASE(hent->key);
+ hent->key = NULL;
+ hent->keylen = 0;
+ if (hent->value && ht->hval_free_fn) {
+ ht->hval_free_fn(hent->value);
+ }
+ hent->value = NULL;
+ if (prev) {
+ prev->next = hent->next;
+ } else {
+ ht->table[hkey] = hent->next;
+ }
+ RELEASE(hent);
+ ht->count--;
+ return 1;
+ } else
+ return 0;
+}
+
+/* replace... */
+void
+ht_insert_table (struct ht_table *ht,
+ const void *key, int keylen, void *value)
+{
+ struct ht_entry *hent, *prev;
+ unsigned int hkey;
+
+ ASSERT(ht && key);
+
+ hkey = get_hash(key, keylen);
+ hent = ht->table[hkey];
+ prev = NULL;
+ while (hent) {
+ if (hent->keylen == keylen &&
+ !memcmp(hent->key, key, keylen)) {
+ break;
+ }
+ prev = hent;
+ hent = hent->next;
+ }
+ if (hent) {
+ if (hent->value && ht->hval_free_fn)
+ ht->hval_free_fn(hent->value);
+ hent->value = value;
+ } else {
+ hent = NEW(1, struct ht_entry);
+ hent->key = NEW(keylen, char);
+ memcpy(hent->key, key, keylen);
+ hent->keylen = keylen;
+ hent->value = value;
+ hent->next = NULL;
+ if (prev) {
+ prev->next = hent;
+ } else {
+ ht->table[hkey] = hent;
+ }
+ ht->count++;
+ }
+}
+
+void
+ht_append_table (struct ht_table *ht,
+ const void *key, int keylen, void *value)
+{
+ struct ht_entry *hent, *last;
+ unsigned int hkey;
+
+ hkey = get_hash(key, keylen);
+ hent = ht->table[hkey];
+ if (!hent) {
+ hent = NEW(1, struct ht_entry);
+ ht->table[hkey] = hent;
+ } else {
+ while (hent) {
+ last = hent;
+ hent = hent->next;
+ }
+ hent = NEW(1, struct ht_entry);
+ last->next = hent;
+ }
+ hent->key = NEW(keylen, char);
+ memcpy(hent->key, key, keylen);
+ hent->keylen = keylen;
+ hent->value = value;
+ hent->next = NULL;
+
+ ht->count++;
+}
+
+int
+ht_set_iter (struct ht_table *ht, struct ht_iter *iter)
+{
+ int i;
+
+ ASSERT(ht && iter);
+
+ for (i = 0; i < HASH_TABLE_SIZE; i++) {
+ if (ht->table[i]) {
+ iter->index = i;
+ iter->curr = ht->table[i];
+ iter->hash = ht;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+void
+ht_clear_iter (struct ht_iter *iter)
+{
+ if (iter) {
+ iter->index = HASH_TABLE_SIZE;
+ iter->curr = NULL;
+ iter->hash = NULL;
+ }
+}
+
+char *
+ht_iter_getkey (struct ht_iter *iter, int *keylen)
+{
+ struct ht_entry *hent;
+
+ hent = (struct ht_entry *) iter->curr;
+ if (iter && hent) {
+ *keylen = hent->keylen;
+ return hent->key;
+ } else {
+ *keylen = 0;
+ return NULL;
+ }
+}
+
+void *
+ht_iter_getval (struct ht_iter *iter)
+{
+ struct ht_entry *hent;
+
+ hent = (struct ht_entry *) iter->curr;
+ if (iter && hent) {
+ return hent->value;
+ } else {
+ return NULL;
+ }
+}
+
+int
+ht_iter_next (struct ht_iter *iter)
+{
+ struct ht_entry *hent;
+ struct ht_table *ht;
+
+ ASSERT(iter);
+
+ ht = iter->hash;
+ hent = (struct ht_entry *) iter->curr;
+ hent = hent->next;
+ while (!hent &&
+ ++iter->index < HASH_TABLE_SIZE) {
+ hent = ht->table[iter->index];
+ }
+ iter->curr = hent;
+
+ return (hent ? 0 : -1);
+}
+
+
+static int
+read_c_escchar (char *r, const char **pp, const char *endptr)
+{
+ int c = 0, l = 1;
+ const char *p = *pp;
+
+ switch (p[0]) {
+ case 'a' : c = '\a'; p++; break;
+ case 'b' : c = '\b'; p++; break;
+ case 'f' : c = '\f'; p++; break;
+ case 'n' : c = '\n'; p++; break;
+ case 'r' : c = '\r'; p++; break;
+ case 't' : c = '\t'; p++; break;
+ case 'v' : c = '\v'; p++; break;
+ case '\\': case '?': case '\'': case '\"':
+ c = p[0]; p++;
+ break;
+ case '\n': l = 0; p++; break;
+ case '\r':
+ {
+ p++;
+ if (p < endptr && p[0] == '\n')
+ p++;
+ l = 0;
+ }
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ {
+ int i;
+ for (c = 0, i = 0;
+ i < 3 && p < endptr &&
+ p[0] >= '0' && p[0] <= '7'; i++, p++)
+ c = (c << 3) + (p[0] - '0');
+ }
+ break;
+ case 'x':
+ {
+ int i;
+ for (c = 0, i = 0, p++;
+ i < 2 && p < endptr && isxdigit((unsigned char)p[0]);
+ i++, p++)
+ c = (c << 4) +
+ (isdigit((unsigned char)p[0]) ?
+ p[0] - '0' :
+ (islower((unsigned char)p[0]) ? p[0] - 'a' + 10: p[0] - 'A' + 10));
+ }
+ break;
+ default:
+ WARN("Unknown escape char sequence: \\%c", p[0]);
+ l = 0; p++;
+ break;
+ }
+
+ if (r)
+ *r = (char) c;
+ *pp = p;
+ return l;
+}
+
+#define C_QUOTE '"'
+#define C_ESCAPE '\\'
+static int
+read_c_litstrc (char *q, int len, const char **pp, const char *endptr)
+{
+ const char *p;
+ int l = 0;
+#define Q_TERM 0
+#define Q_CONT -1
+#define Q_ERROR_UNTERM -1
+#define Q_ERROR_INVAL -2
+#define Q_ERROR_BUFF -3
+ int s = Q_CONT;
+
+ for (l = 0, p = *pp;
+ s == Q_CONT && p < endptr; ) {
+ switch (p[0]) {
+ case C_QUOTE:
+ s = Q_TERM; p++;
+ break;
+ case C_ESCAPE:
+ if (q && l == len)
+ s = Q_ERROR_BUFF;
+ else {
+ p++;
+ l += read_c_escchar(q ? &q[l] : NULL, &p, endptr);
+ }
+ break;
+ case '\n': case '\r':
+ s = Q_ERROR_INVAL;
+ break;
+ default:
+ if (q && l == len)
+ s = Q_ERROR_BUFF;
+ else {
+ if (!q)
+ l++;
+ else
+ q[l++] = p[0];
+ p++;
+ }
+ break;
+ }
+ }
+ if (s == Q_TERM) {
+ if (q && l == len)
+ s = Q_ERROR_BUFF;
+ else if (q)
+ q[l++] = '\0';
+ }
+
+ *pp = p;
+ return ((s == Q_TERM) ? l : s);
+}
+
+char *
+parse_c_string (const char **pp, const char *endptr)
+{
+ char *q = NULL;
+ const char *p = *pp;
+ int l = 0;
+
+ if (p >= endptr || p[0] != C_QUOTE)
+ return NULL;
+
+ p++;
+ l = read_c_litstrc(NULL, 0, &p, endptr);
+ if (l >= 0) {
+ q = NEW(l + 1, char);
+ p = *pp + 1;
+ l = read_c_litstrc(q, l + 1, &p, endptr);
+ }
+
+ *pp = p;
+ return q;
+}
+
+#define ISCNONDIGITS(c) ( \
+ (c) == '_' || \
+ ((c) >= 'a' && (c) <= 'z') || \
+ ((c) >= 'A' && (c) <= 'Z') \
+)
+#define ISCIDENTCHAR(c) ( \
+ ISCNONDIGITS((c)) || \
+ ((c) >= '0' && (c) <= '9') \
+)
+
+char *
+parse_c_ident (const char **pp, const char *endptr)
+{
+ char *q = NULL;
+ const char *p = *pp;
+ int n;
+
+ if (p >= endptr || !ISCNONDIGITS(*p))
+ return NULL;
+
+ for (n = 0; p < endptr && ISCIDENTCHAR(*p); p++, n++);
+ q = NEW(n + 1, char);
+ memcpy(q, *pp, n); q[n] = '\0';
+
+ *pp = p;
+ return q;
+}
+
+char *
+parse_float_decimal (const char **pp, const char *endptr)
+{
+ char *q = NULL;
+ const char *p = *pp;
+ int s = 0, n = 0;
+
+ if (p >= endptr)
+ return NULL;
+
+ if (p[0] == '+' || p[0] == '-')
+ p++;
+
+ /* 1. .01 001 001E-001 */
+ for (s = 0, n = 0; p < endptr && s >= 0; ) {
+ switch (p[0]) {
+ case '+': case '-':
+ if (s != 2)
+ s = -1;
+ else {
+ s = 3; p++;
+ }
+ break;
+ case '.':
+ if (s > 0)
+ s = -1;
+ else {
+ s = 1; p++;
+ }
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n++; p++;
+ break;
+ case 'E': case 'e':
+ if (n == 0 || s == 2)
+ s = -1;
+ else {
+ s = 2; p++;
+ }
+ break;
+ default:
+ s = -1;
+ break;
+ }
+ }
+
+ if (n != 0) {
+ n = (int) (p - *pp);
+ q = NEW(n + 1, char);
+ memcpy(q, *pp, n); q[n] = '\0';
+ }
+
+ *pp = p;
+ return q;
+}
diff --git a/Build/source/texk/dvipdfm-x/dpxutil.h b/Build/source/texk/dvipdfm-x/dpxutil.h
new file mode 100644
index 00000000000..b31eb97a638
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dpxutil.h
@@ -0,0 +1,131 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _DPXUTIL_H_
+#define _DPXUTIL_H_
+
+#include <time.h>
+
+#undef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#undef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#undef ABS
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+
+extern double min4(double v1, double v2, double v3, double v4);
+extern double max4(double v1, double v2, double v3, double v4);
+
+extern int dpx_util_read_length (double *vp, double mag,
+ const char **curptr, const char *endptr);
+
+#define INVALID_EPOCH_VALUE ((time_t)-1)
+extern time_t dpx_util_get_unique_time_if_given (void);
+extern int dpx_util_format_asn_date (char *date_string, int need_timezone);
+
+#ifndef is_space
+#define is_space(c) ((c) == ' ' || (c) == '\t' || (c) == '\f' || \
+ (c) == '\r' || (c) == '\n' || (c) == '\0')
+#endif
+#ifndef is_delim
+#define is_delim(c) ((c) == '(' || (c) == ')' || \
+ (c) == '/' || \
+ (c) == '<' || (c) == '>' || \
+ (c) == '[' || (c) == ']' || \
+ (c) == '{' || (c) == '}' || \
+ (c) == '%')
+#endif
+
+extern void skip_white_spaces (unsigned char **s, unsigned char *endptr);
+extern int xtoi (char c);
+
+typedef struct stack_elem
+{
+ void *data;
+ struct stack_elem *prev;
+} stack_elem;
+
+typedef struct dpx_stack
+{
+ int size;
+ stack_elem *top;
+ stack_elem *bottom;
+} dpx_stack;
+
+extern void dpx_stack_init (dpx_stack *st);
+extern void *dpx_stack_pop (dpx_stack *st);
+extern void dpx_stack_push (dpx_stack *st, void *data);
+extern int dpx_stack_depth (dpx_stack *st);
+extern void *dpx_stack_top (dpx_stack *st);
+extern void *dpx_stack_at (dpx_stack *st, int pos);
+extern void dpx_stack_roll (dpx_stack *st, int n, int j);
+
+
+#define HASH_TABLE_SIZE 503
+
+struct ht_entry {
+ char *key;
+ int keylen;
+
+ void *value;
+
+ struct ht_entry *next;
+};
+
+typedef void (*hval_free_func) (void *);
+
+struct ht_table {
+ int count;
+ hval_free_func hval_free_fn;
+ struct ht_entry *table[HASH_TABLE_SIZE];
+};
+
+extern void ht_init_table (struct ht_table *ht,
+ hval_free_func hval_free_fn);
+extern void ht_clear_table (struct ht_table *ht);
+extern int ht_table_size (struct ht_table *ht);
+extern void *ht_lookup_table (struct ht_table *ht,
+ const void *key, int keylen);
+extern void ht_append_table (struct ht_table *ht,
+ const void *key, int keylen, void *value) ;
+extern int ht_remove_table (struct ht_table *ht,
+ const void *key, int keylen);
+extern void ht_insert_table (struct ht_table *ht,
+ const void *key, int keylen, void *value);
+
+struct ht_iter {
+ int index;
+ void *curr;
+ struct ht_table *hash;
+};
+
+extern int ht_set_iter (struct ht_table *ht, struct ht_iter *iter);
+extern void ht_clear_iter (struct ht_iter *iter);
+extern char *ht_iter_getkey (struct ht_iter *iter, int *keylen);
+extern void *ht_iter_getval (struct ht_iter *iter);
+extern int ht_iter_next (struct ht_iter *iter);
+
+extern char *parse_float_decimal (const char **pp, const char *endptr);
+extern char *parse_c_string (const char **pp, const char *endptr);
+extern char *parse_c_ident (const char **pp, const char *endptr);
+
+#endif /* _DPXUTIL_H_ */
diff --git a/Build/source/texk/dvipdfm-x/dvi.c b/Build/source/texk/dvipdfm-x/dvi.c
new file mode 100644
index 00000000000..473c52e8c3c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dvi.c
@@ -0,0 +1,2884 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 2012-2015 by Khaled Hosny <khaledhosny@eglug.org>
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef WIN32
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+#include "numbers.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "pdfdev.h"
+#include "pdfdoc.h"
+#include "pdfparse.h"
+#include "pdfresource.h"
+#include "pdfdraw.h"
+
+#include "fontmap.h"
+
+#include "dvicodes.h"
+#include "tfm.h"
+#include "vf.h"
+#include "subfont.h"
+
+#include "spc_util.h"
+#include "specials.h"
+
+#include "dvi.h"
+#include "dvipdfmx.h"
+
+#include "dpxfile.h"
+#include "pdfximage.h"
+#include "tt_aux.h"
+#include "tt_table.h"
+#include "t1_load.h"
+#include "t1_char.h"
+#include "cff_dict.h"
+
+#define DVI_STACK_DEPTH_MAX 256u
+#define TEX_FONTS_ALLOC_SIZE 16u
+#define VF_NESTING_MAX 16u
+
+/* UTF-32 over U+FFFF -> UTF-16 surrogate pair */
+#define UTF32toUTF16HS(x) (0xd800 + (((x-0x10000) >> 10) & 0x3ff))
+#define UTF32toUTF16LS(x) (0xdc00 + ( x & 0x3ff))
+
+/* Interal Variables */
+static FILE *dvi_file = NULL;
+static char linear = 0; /* set to 1 for strict linear processing of the input */
+
+static int32_t *page_loc = NULL;
+static unsigned int num_pages = 0;
+
+static uint32_t dvi_file_size = 0;
+
+static struct dvi_header
+{
+ uint32_t unit_num;
+ uint32_t unit_den;
+ uint32_t mag;
+ uint32_t media_width, media_height;
+ unsigned int stackdepth;
+ char comment[257];
+} dvi_info = {
+ 25400000 , /* num */
+ 473628672, /* den */
+ 1000, /* mag */
+ 0, 0, /* media width and height */
+ 0, /* stackdepth */
+ {'\0'} /* comment */
+};
+
+static double dev_origin_x = 72.0, dev_origin_y = 770.0;
+
+double get_origin (int x)
+{
+ return x ? dev_origin_x : dev_origin_y;
+}
+
+#define LTYPESETTING 0 /* typesetting from left to right */
+#define RTYPESETTING 1 /* typesetting from right to left */
+#define SKIMMING 2 /* skimming through reflected segment measuring its width */
+#define REVERSE(MODE) (LTYPESETTING + RTYPESETTING - MODE)
+
+struct dvi_lr
+{
+ int state, font;
+ unsigned int buf_index;
+};
+
+static struct dvi_lr lr_state; /* state at start of current skimming */
+static int lr_mode; /* current direction or skimming depth */
+static uint32_t lr_width; /* total width of reflected segment */
+static uint32_t lr_width_stack[DVI_STACK_DEPTH_MAX];
+static unsigned lr_width_stack_depth = 0;
+
+#define PHYSICAL 1
+#define VIRTUAL 2
+#define SUBFONT 3
+#define NATIVE 4
+#define DVI 1
+#define VF 2
+
+struct gm {
+ spt_t advance, ascent, descent;
+};
+
+static struct loaded_font
+{
+ int type; /* Type is physical or virtual */
+ int font_id; /* id returned by dev (for PHYSICAL fonts)
+ * or by vf module for (VIRTUAL fonts)
+ */
+ int subfont_id; /* id returned by subfont_locate_font() */
+ int tfm_id;
+ spt_t size;
+ int source; /* Source is either DVI or VF */
+ uint32_t rgba_color;
+ uint8_t rgba_used;
+ /* Indicates that rgba_color is used or not.
+ * It enables full range of opacity: 0-255.
+ */
+ int xgs_id; /* Transparency ExtGState */
+
+ /* XeTeX requires glyph metrics */
+ struct gm *gm;
+ int shift_gid;
+ uint16_t num_glyphs;
+
+ int layout_dir;
+
+ float extend;
+ float slant;
+ float embolden;
+
+ int is_unicode;
+ int minbytes;
+ char padbytes[4];
+} *loaded_fonts = NULL;
+static int num_loaded_fonts = 0, max_loaded_fonts = 0;
+
+static void
+need_more_fonts (unsigned n)
+{
+ if (num_loaded_fonts + n > max_loaded_fonts) {
+ max_loaded_fonts += TEX_FONTS_ALLOC_SIZE;
+ loaded_fonts = RENEW (loaded_fonts, max_loaded_fonts, struct loaded_font);
+ }
+}
+
+static struct font_def
+{
+ int32_t tex_id;
+ spt_t point_size;
+ spt_t design_size;
+ char *font_name;
+ int font_id; /* index of _loaded_ font in loaded_fonts array */
+ int used;
+ int native; /* boolean */
+ uint32_t rgba_color; /* only used for native fonts in XeTeX */
+ uint8_t rgba_used; /* Indicates that rgba_color is used or not.
+ * It enables full range of opacity: 0-255.
+ */
+ uint32_t face_index;
+ int layout_dir; /* 1 = vertical, 0 = horizontal */
+ int extend;
+ int slant;
+ int embolden;
+} *def_fonts = NULL;
+
+#define XDV_FLAG_VERTICAL 0x0100
+#define XDV_FLAG_COLORED 0x0200
+#define XDV_FLAG_FEATURES 0x0400
+#define XDV_FLAG_EXTEND 0x1000
+#define XDV_FLAG_SLANT 0x2000
+#define XDV_FLAG_EMBOLDEN 0x4000
+
+static int num_def_fonts = 0, max_def_fonts = 0;
+static int compute_boxes = 0, link_annot = 1;
+/* If "catch_phantom" is non-zero, dvipdfmx try to catch phantom texts.
+ * Dvipdfmx treats DVI horizontal movement instructions (x, w, right) differently
+ * when "catch_phantom" is non-zero. Amount of horizontal move will be added to
+ * the current annotation rectangle with "height" and "depth" estimated as,
+ *
+ * catch_phantom=1: with current font size
+ * catch_phantom=2: with specified height and depth
+ */
+static int catch_phantom = 0;
+static double phantom_height = 0.0;
+static double phantom_depth = 0.0;
+
+#define DVI_PAGE_BUF_CHUNK 0x10000U /* 64K should be plenty for most pages */
+
+static unsigned char* dvi_page_buffer;
+static unsigned int dvi_page_buf_size;
+static unsigned int dvi_page_buf_index;
+
+/* functions to read numbers from the dvi file and store them in dvi_page_buffer */
+static int get_and_buffer_unsigned_byte (FILE *file)
+{
+ int ch;
+ if ((ch = fgetc (file)) < 0)
+ ERROR ("File ended prematurely\n");
+ if (dvi_page_buf_index >= dvi_page_buf_size) {
+ dvi_page_buf_size += DVI_PAGE_BUF_CHUNK;
+ dvi_page_buffer = RENEW(dvi_page_buffer, dvi_page_buf_size, unsigned char);
+ }
+ dvi_page_buffer[dvi_page_buf_index++] = ch;
+ return ch;
+}
+
+static unsigned int get_and_buffer_unsigned_pair (FILE *file)
+{
+ unsigned int pair = get_and_buffer_unsigned_byte(file);
+ pair = (pair << 8) | get_and_buffer_unsigned_byte(file);
+ return pair;
+}
+
+static void get_and_buffer_bytes(FILE *file, unsigned int count)
+{
+ if (dvi_page_buf_index + count >= dvi_page_buf_size) {
+ dvi_page_buf_size = dvi_page_buf_index + count + DVI_PAGE_BUF_CHUNK;
+ dvi_page_buffer = RENEW(dvi_page_buffer, dvi_page_buf_size, unsigned char);
+ }
+ if (fread(dvi_page_buffer + dvi_page_buf_index, 1, count, file) != count)
+ ERROR ("File ended prematurely\n");
+ dvi_page_buf_index += count;
+}
+
+/* functions to fetch values from dvi_page_buffer */
+
+static int get_buffered_unsigned_byte (void)
+{
+ return dvi_page_buffer[dvi_page_buf_index++];
+}
+
+static unsigned int get_buffered_unsigned_pair (void)
+{
+ unsigned int pair = dvi_page_buffer[dvi_page_buf_index++];
+ pair = (pair << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ return pair;
+}
+
+static int32_t get_buffered_signed_quad(void)
+{
+ int i;
+ int32_t quad = dvi_page_buffer[dvi_page_buf_index++];
+ /* Check sign on first byte before reading others */
+ if (quad >= 0x80)
+ quad -= 0x100;
+ for (i=0; i<3; i++) {
+ quad = (quad << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ }
+ return quad;
+}
+
+static int32_t get_buffered_signed_num(unsigned char num)
+{
+ int32_t quad = dvi_page_buffer[dvi_page_buf_index++];
+ if (quad > 0x7f)
+ quad -= 0x100;
+ switch (num) {
+ case 3: quad = (quad << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ case 2: quad = (quad << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ case 1: quad = (quad << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ default: break;
+ }
+ return quad;
+}
+
+static int32_t get_buffered_unsigned_num(unsigned char num)
+{
+ int32_t quad = dvi_page_buffer[dvi_page_buf_index++];
+ switch (num) {
+ case 3: if (quad > 0x7f)
+ quad -= 0x100;
+ quad = (quad << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ case 2: quad = (quad << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ case 1: quad = (quad << 8) | dvi_page_buffer[dvi_page_buf_index++];
+ default: break;
+ }
+ return quad;
+}
+
+#define skip_bufferd_bytes(n) dvi_page_buf_index += n
+
+unsigned int
+dvi_npages (void)
+{
+ return num_pages;
+}
+
+static const char invalid_signature[] =
+"Something is wrong. Are you sure this is a DVI file?";
+
+#define range_check_loc(loc) \
+ if ((loc) > dvi_file_size) {\
+ ERROR(invalid_signature); \
+ }
+
+static int pre_id_byte, post_id_byte, is_ptex = 0, has_ptex = 0;
+
+static void
+check_id_bytes (void) {
+ if (pre_id_byte != post_id_byte && (pre_id_byte != DVI_ID || post_id_byte != DVIV_ID))
+ ERROR ("Inconsistent DVI id_bytes %d (pre) and %d (post)", pre_id_byte, post_id_byte);
+}
+
+static void
+need_XeTeX (int c) {
+ if (dpx_conf.compat_mode != dpx_mode_xdv_mode)
+ ERROR ("DVI opcode %i only valid for XeTeX", c);
+}
+
+static void
+need_pTeX (int c) {
+ if (!is_ptex)
+ ERROR ("DVI opcode %i only valid for Ascii pTeX", c);
+ has_ptex = 1;
+}
+
+static int32_t
+find_post (void)
+{
+ off_t dvi_size;
+ int32_t current;
+ int ch;
+
+ /* First find end of file */
+ dvi_size = xfile_size (dvi_file, "DVI");
+ if (dvi_size > 0x7fffffff)
+ ERROR("DVI file size exceeds 31-bit");
+ dvi_file_size = dvi_size;
+ current = dvi_size;
+
+ /* Scan backwards through PADDING */
+ do {
+ xseek_absolute (dvi_file, --current, "DVI");
+ } while ((ch = fgetc(dvi_file)) == PADDING &&
+ current > 0);
+
+ /* file_position now points to last non padding character or
+ * beginning of file */
+ if (dvi_file_size - current < 4 || current == 0 ||
+ !(ch == DVI_ID || ch == DVIV_ID || ch == XDV_ID || ch == XDV_ID_OLD)) {
+ MESG("DVI ID = %d\n", ch);
+ ERROR(invalid_signature);
+ }
+
+ post_id_byte = ch;
+ if (ch == XDV_ID || ch == XDV_ID_OLD)
+ dpx_conf.compat_mode = dpx_mode_xdv_mode;
+ is_ptex = ch == DVIV_ID;
+
+ /* Make sure post_post is really there */
+ current = current - 5;
+ xseek_absolute (dvi_file, current, "DVI");
+ if ((ch = fgetc(dvi_file)) != POST_POST) {
+ MESG("Found %d where post_post opcode should be\n", ch);
+ ERROR(invalid_signature);
+ }
+ current = get_signed_quad(dvi_file);
+ xseek_absolute (dvi_file, current, "DVI");
+ if ((ch = fgetc(dvi_file)) != POST) {
+ MESG("Found %d where post_post opcode should be\n", ch);
+ ERROR(invalid_signature);
+ }
+
+ /* Finally check the ID byte in the preamble */
+ /* An Ascii pTeX DVI file has id_byte DVI_ID in the preamble but DVIV_ID in the postamble. */
+ xseek_absolute (dvi_file, 0, "DVI");
+ if ((ch = get_unsigned_byte(dvi_file)) != PRE) {
+ MESG("Found %d where PRE was expected\n", ch);
+ ERROR(invalid_signature);
+ }
+ ch = get_unsigned_byte(dvi_file);
+ if (!(ch == DVI_ID || ch == XDV_ID || ch == XDV_ID_OLD)) {
+ MESG("DVI ID = %d\n", ch);
+ ERROR(invalid_signature);
+ }
+ pre_id_byte = ch;
+ check_id_bytes();
+
+ return current;
+}
+
+static void
+get_page_info (int32_t post_location)
+{
+ int i;
+
+ xseek_absolute (dvi_file, post_location + 27, "DVI");
+ num_pages = get_unsigned_pair(dvi_file);
+ if (num_pages == 0) {
+ ERROR("Page count is 0!");
+ }
+ if (dpx_conf.verbose_level > 2) {
+ MESG("Page count:\t %4d\n", num_pages);
+ }
+
+ page_loc = NEW(num_pages, int32_t);
+
+ xseek_absolute (dvi_file, post_location + 1, "DVI");
+ page_loc[num_pages-1] = get_unsigned_quad(dvi_file);
+ range_check_loc(page_loc[num_pages-1] + 41);
+ for (i = num_pages - 2; i >= 0; i--) {
+ xseek_absolute (dvi_file, page_loc[i+1] + 41, "DVI");
+ page_loc[i] = get_unsigned_quad(dvi_file);
+ range_check_loc(page_loc[num_pages-1] + 41);
+ }
+}
+
+/* Following are computed "constants" used for unit conversion */
+static double dvi2pts = 1.52018, total_mag = 1.0;
+
+double
+dvi_tell_mag (void)
+{
+ return total_mag;
+}
+
+static void
+do_scales (double mag)
+{
+ total_mag = (double) dvi_info.mag / 1000.0 * mag;
+ dvi2pts = (double) dvi_info.unit_num / (double) dvi_info.unit_den;
+ dvi2pts *= (72.0 / 254000.0);
+}
+
+static void
+get_dvi_info (int32_t post_location)
+{
+ xseek_absolute (dvi_file, post_location + 5, "DVI");
+
+ dvi_info.unit_num = get_unsigned_quad(dvi_file);
+ dvi_info.unit_den = get_unsigned_quad(dvi_file);
+ dvi_info.mag = get_unsigned_quad(dvi_file);
+
+ dvi_info.media_height = get_unsigned_quad(dvi_file);
+ dvi_info.media_width = get_unsigned_quad(dvi_file);
+
+ dvi_info.stackdepth = get_unsigned_pair(dvi_file);
+
+ if (dvi_info.stackdepth > DVI_STACK_DEPTH_MAX) {
+ WARN("DVI need stack depth of %d,", dvi_info.stackdepth);
+ WARN("but DVI_STACK_DEPTH_MAX is %d.", DVI_STACK_DEPTH_MAX);
+ ERROR("Capacity exceeded.");
+ }
+
+ if (dpx_conf.verbose_level > 2) {
+ MESG("DVI File Info\n");
+ MESG("Unit: %ld / %ld\n", dvi_info.unit_num, dvi_info.unit_den);
+ MESG("Magnification: %ld\n", dvi_info.mag);
+ MESG("Media Height: %ld\n", dvi_info.media_height);
+ MESG("Media Width: %ld\n", dvi_info.media_width);
+ MESG("Stack Depth: %d\n", dvi_info.stackdepth);
+ }
+}
+
+static void
+get_preamble_dvi_info (void)
+{
+ int ch;
+
+ ch = get_unsigned_byte(dvi_file);
+ if (ch != PRE) {
+ MESG("Found %d where PRE was expected\n", ch);
+ ERROR(invalid_signature);
+ }
+
+ /* An Ascii pTeX DVI file has id_byte DVI_ID in the preamble but DVIV_ID in the postamble. */
+ ch = get_unsigned_byte(dvi_file);
+ if (!(ch == DVI_ID || ch == XDV_ID || ch == XDV_ID_OLD)) {
+ MESG("DVI ID = %d\n", ch);
+ ERROR(invalid_signature);
+ }
+
+ pre_id_byte = ch;
+ if (ch == XDV_ID || ch == XDV_ID_OLD)
+ dpx_conf.compat_mode = dpx_mode_xdv_mode;
+ is_ptex = ch == DVI_ID; /* maybe */
+
+ dvi_info.unit_num = get_positive_quad(dvi_file, "DVI", "unit_num");
+ dvi_info.unit_den = get_positive_quad(dvi_file, "DVI", "unit_den");
+ dvi_info.mag = get_positive_quad(dvi_file, "DVI", "mag");
+
+ ch = get_unsigned_byte(dvi_file);
+ if (fread(dvi_info.comment,
+ 1, ch, dvi_file) != ch) {
+ ERROR(invalid_signature);
+ }
+ dvi_info.comment[ch] = '\0';
+
+ if (dpx_conf.verbose_level > 2) {
+ MESG("DVI File Info\n");
+ MESG("Unit: %ld / %ld\n", dvi_info.unit_num, dvi_info.unit_den);
+ MESG("Magnification: %ld\n", dvi_info.mag);
+ }
+
+ if (dpx_conf.verbose_level > 0) {
+ MESG("DVI Comment: %s\n", dvi_info.comment);
+ }
+
+ num_pages = 0x7FFFFFFU; /* for linear processing: we just keep going! */
+}
+
+const char *
+dvi_comment (void)
+{
+ return dvi_info.comment;
+}
+
+static void
+proc_dvilua_font_record (int32_t tex_id, const char *font_name, uint32_t point_size, uint32_t design_size)
+{
+ char *file_name, *p, *q, *endptr;
+ uint32_t index = 0;
+ uint32_t embolden = 0;
+ int32_t slant = 0, extend = 0x00010000;
+
+ ASSERT(font_name[0] == '[');
+
+ /* redundant check but leave this here anyway */
+ if (num_def_fonts >= max_def_fonts) {
+ max_def_fonts += TEX_FONTS_ALLOC_SIZE;
+ def_fonts = RENEW (def_fonts, max_def_fonts, struct font_def);
+ }
+
+ file_name = NEW(strlen(font_name) + 1, char);
+ strcpy(file_name, font_name + 1);
+ endptr = file_name + strlen(file_name);
+ q = strchr(file_name, ']');
+ if (q == NULL) {
+ ERROR("Syntax error in dvilua fnt_def: no ']' found in font name.");
+ }
+ *q = '\0';
+
+ p = q + 1;
+ if (p < endptr && *p == ':') {
+ for (p++; *p != '\0' && p < endptr; ) {
+ char *kvsep, *delim;
+
+ delim = strchr(p, ';');
+ kvsep = strchr(p, '=');
+ if (delim == NULL)
+ delim = endptr;
+ if (kvsep == NULL || kvsep >= delim) {
+ ERROR("Syntax error in dvilua fnt_def: not in key=value format: %s", font_name);
+ }
+ *kvsep = '\0';
+ if (!strcmp(p, "index")) {
+ uint32_t value = strtoul(kvsep + 1, &q, 10);
+ if (q != delim) {
+ WARN("Syntax error in dvilua fnt_def: invalid value specified for \"%s\": %s", p, font_name);
+ } else {
+ index = value;
+ }
+ } else if (!strcmp(p, "embolden")) {
+ int32_t value = strtol(kvsep + 1, &q, 10);
+ if (q != delim) {
+ WARN("Syntax error in dvilua fnt_def: invalid value specified for \"%s\": %s", p, font_name);
+ } else {
+ embolden = value;
+ }
+ } else if (!strcmp(p, "slant")) {
+ int32_t value = strtol(kvsep + 1, &q, 10);
+ if (q != delim) {
+ WARN("Syntax error in dvilua fnt_def: invalid value specified for \"%s\": %s", p, font_name);
+ } else {
+ slant = value;
+ }
+ } else if (!strcmp(p, "extend")) {
+ int32_t value = strtol(kvsep + 1, &q, 10);
+ if (q != delim) {
+ WARN("Syntax error in dvilua fnt_def: invalid value specified for \"%s\": %s", p, font_name);
+ } else {
+ extend = value;
+ }
+ } else {
+ WARN("Ignoring unrecognized/unsupported key \"%s\" in dvilua fnt_def: %s", p, font_name);
+ }
+ p = delim + 1;
+ }
+ }
+
+ def_fonts[num_def_fonts].tex_id = tex_id;
+ def_fonts[num_def_fonts].font_name = file_name;
+ def_fonts[num_def_fonts].face_index = index;
+ def_fonts[num_def_fonts].point_size = point_size;
+ def_fonts[num_def_fonts].design_size = design_size;
+ def_fonts[num_def_fonts].used = 0;
+ def_fonts[num_def_fonts].native = 1;
+
+ def_fonts[num_def_fonts].layout_dir = 0;
+ def_fonts[num_def_fonts].rgba_color = 0xffffffff;
+ def_fonts[num_def_fonts].rgba_used = 0;
+ def_fonts[num_def_fonts].extend = extend;
+ def_fonts[num_def_fonts].slant = slant;
+ def_fonts[num_def_fonts].embolden = embolden;
+
+ num_def_fonts++;
+
+ return;
+}
+
+#define SIG_DVILUA_FNT_DEF ('L' << 24|'u' << 16|'a' << 8|'F')
+
+static void
+read_font_record (int32_t tex_id)
+{
+ int dir_length, name_length;
+ uint32_t checksum;
+ uint32_t point_size, design_size;
+ char *directory, *font_name;
+
+ if (num_def_fonts >= max_def_fonts) {
+ max_def_fonts += TEX_FONTS_ALLOC_SIZE;
+ def_fonts = RENEW (def_fonts, max_def_fonts, struct font_def);
+ }
+ checksum = get_unsigned_quad(dvi_file);
+ point_size = get_positive_quad(dvi_file, "DVI", "point_size");
+ design_size = get_positive_quad(dvi_file, "DVI", "design_size");
+ dir_length = get_unsigned_byte(dvi_file);
+ name_length = get_unsigned_byte(dvi_file);
+
+ directory = NEW(dir_length + 1, char);
+ if (fread(directory, 1, dir_length, dvi_file) != dir_length) {
+ ERROR(invalid_signature);
+ }
+ directory[dir_length] = '\0';
+ RELEASE(directory); /* unused */
+
+ font_name = NEW(name_length + 1, char);
+ if (fread(font_name, 1, name_length, dvi_file) != name_length) {
+ ERROR(invalid_signature);
+ }
+ font_name[name_length] = '\0';
+
+ if (checksum == SIG_DVILUA_FNT_DEF && name_length > 0 && font_name[0] == '[') {
+ proc_dvilua_font_record(tex_id, font_name, point_size, design_size);
+ RELEASE(font_name);
+ return;
+ }
+ def_fonts[num_def_fonts].tex_id = tex_id;
+ def_fonts[num_def_fonts].font_name = font_name;
+ def_fonts[num_def_fonts].point_size = point_size;
+ def_fonts[num_def_fonts].design_size = design_size;
+ def_fonts[num_def_fonts].used = 0;
+ def_fonts[num_def_fonts].native = 0;
+ def_fonts[num_def_fonts].rgba_color = 0xffffffff;
+ def_fonts[num_def_fonts].rgba_used = 0;
+ def_fonts[num_def_fonts].face_index = 0;
+ def_fonts[num_def_fonts].layout_dir = 0;
+ def_fonts[num_def_fonts].extend = 0x00010000; /* 1.0 */
+ def_fonts[num_def_fonts].slant = 0;
+ def_fonts[num_def_fonts].embolden = 0;
+ num_def_fonts++;
+
+ return;
+}
+
+static void
+read_native_font_record (int32_t tex_id)
+{
+ unsigned int flags;
+ uint32_t point_size;
+ char *font_name;
+ int len;
+ uint32_t index;
+
+ if (num_def_fonts >= max_def_fonts) {
+ max_def_fonts += TEX_FONTS_ALLOC_SIZE;
+ def_fonts = RENEW (def_fonts, max_def_fonts, struct font_def);
+ }
+ point_size = get_positive_quad(dvi_file, "DVI", "point_size");
+ flags = get_unsigned_pair(dvi_file);
+
+ len = (int) get_unsigned_byte(dvi_file); /* font name length */
+ font_name = NEW(len + 1, char);
+ if (fread(font_name, 1, len, dvi_file) != len) {
+ ERROR(invalid_signature);
+ }
+ font_name[len] = '\0';
+
+ index = get_positive_quad(dvi_file, "DVI", "index");
+
+ def_fonts[num_def_fonts].tex_id = tex_id;
+ def_fonts[num_def_fonts].font_name = font_name;
+ def_fonts[num_def_fonts].face_index = index;
+ def_fonts[num_def_fonts].point_size = point_size;
+ def_fonts[num_def_fonts].design_size = 655360; /* hard-code as 10pt for now, not used anyway */
+ def_fonts[num_def_fonts].used = 0;
+ def_fonts[num_def_fonts].native = 1;
+
+ def_fonts[num_def_fonts].layout_dir = 0;
+ def_fonts[num_def_fonts].rgba_color = 0xffffffff;
+ def_fonts[num_def_fonts].rgba_used = 0;
+ def_fonts[num_def_fonts].extend = 0x00010000;
+ def_fonts[num_def_fonts].slant = 0;
+ def_fonts[num_def_fonts].embolden = 0;
+
+ if (flags & XDV_FLAG_VERTICAL)
+ def_fonts[num_def_fonts].layout_dir = 1;
+
+ if (flags & XDV_FLAG_COLORED) {
+ def_fonts[num_def_fonts].rgba_color = get_unsigned_quad(dvi_file);
+ def_fonts[num_def_fonts].rgba_used = 1;
+ }
+
+ if (flags & XDV_FLAG_EXTEND)
+ def_fonts[num_def_fonts].extend = get_signed_quad(dvi_file);
+
+ if (flags & XDV_FLAG_SLANT)
+ def_fonts[num_def_fonts].slant = get_signed_quad(dvi_file);
+
+ if (flags & XDV_FLAG_EMBOLDEN)
+ def_fonts[num_def_fonts].embolden = get_signed_quad(dvi_file);
+
+ num_def_fonts++;
+
+ return;
+}
+
+static void
+get_dvi_fonts (int32_t post_location)
+{
+ int code;
+
+ xseek_absolute (dvi_file, post_location + 29, "DVI");
+ while ((code = get_unsigned_byte(dvi_file)) != POST_POST) {
+ switch (code) {
+ case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
+ read_font_record(get_unsigned_num(dvi_file, code-FNT_DEF1));
+ break;
+ case XDV_NATIVE_FONT_DEF:
+ need_XeTeX(code);
+ read_native_font_record(get_signed_quad(dvi_file));
+ break;
+ default:
+ MESG("Unexpected op code: %3d\n", code);
+ ERROR(invalid_signature);
+ }
+ }
+ if (dpx_conf.verbose_level > 2) {
+ unsigned i;
+
+ MESG("\n");
+ MESG("DVI file font info\n");
+ for (i = 0; i < num_def_fonts; i++) {
+ MESG("TeX Font: %10s loaded at ID=%5d, ",
+ def_fonts[i].font_name, def_fonts[i].tex_id);
+ MESG("size=%5.2fpt (scaled %4.1f%%)",
+ def_fonts[i].point_size * dvi2pts,
+ 100.0 * ((double) def_fonts[i].point_size / def_fonts[i].design_size));
+ MESG("\n");
+ }
+ }
+}
+
+static void get_comment (void)
+{
+ int length;
+
+ xseek_absolute (dvi_file, 14, "DVI");
+ length = get_unsigned_byte(dvi_file);
+ if (fread(dvi_info.comment,
+ 1, length, dvi_file) != length) {
+ ERROR(invalid_signature);
+ }
+ dvi_info.comment[length] = '\0';
+ if (dpx_conf.verbose_level > 0) {
+ MESG("DVI Comment: %s\n", dvi_info.comment);
+ }
+}
+
+/*
+ * The section below this line deals with the actual processing of the
+ * dvi file.
+ *
+ * The dvi file processor state is contained in the following variables:
+ */
+
+struct dvi_registers
+{
+ int32_t h, v, w, x, y, z;
+ unsigned int d;
+};
+
+static struct dvi_registers dvi_state;
+static struct dvi_registers dvi_stack[DVI_STACK_DEPTH_MAX];
+static unsigned dvi_stack_depth = 0 ;
+static int current_font = -1;
+static int processing_page = 0 ;
+
+static void
+clear_state (void)
+{
+ dvi_state.h = 0; dvi_state.v = 0; dvi_state.w = 0;
+ dvi_state.x = 0; dvi_state.y = 0; dvi_state.z = 0;
+ dvi_state.d = 0; /* direction */
+ pdf_dev_set_dirmode(0);
+ dvi_stack_depth = 0;
+ current_font = -1;
+}
+
+/* Migrated from pdfdev.c:
+ * The following codes are originally put into pdfdev.c.
+ * But they are moved to here to make PDF output independent
+ * from DVI input.
+ * pdfdoc, pdfspecial and htex are also modified. pdfspecial
+ * and htex does tag/untag depth. pdfdev and pdfdoc now does
+ * not care about line-breaking at all.
+ */
+static unsigned marked_depth = 0;
+static int tagged_depth = -1;
+
+static void
+dvi_mark_depth (void)
+{
+ /* If decreasing below tagged_depth */
+ if (link_annot &&
+ marked_depth == tagged_depth &&
+ dvi_stack_depth == tagged_depth - 1) {
+ /*
+ * See if this appears to be the end of a "logical unit"
+ * that's been broken. If so, flush the logical unit.
+ */
+ pdf_doc_break_annot();
+ }
+ marked_depth = dvi_stack_depth;
+}
+
+/*
+ * The following routines setup and tear down a callback at a
+ * certain stack depth. This is used to handle broken (linewise)
+ * links.
+ */
+void
+dvi_tag_depth (void)
+{
+ tagged_depth = marked_depth;
+ dvi_compute_boxes(1);
+}
+
+void
+dvi_untag_depth (void)
+{
+ tagged_depth = -1;
+ dvi_compute_boxes(0);
+}
+
+void
+dvi_compute_boxes (int flag)
+{
+ compute_boxes = flag;
+}
+
+void
+dvi_link_annot (int flag)
+{
+ link_annot = flag;
+}
+
+int
+dvi_is_tracking_boxes(void)
+{
+ return (compute_boxes && link_annot && marked_depth >= tagged_depth);
+}
+
+void
+dvi_set_linkmode (int mode)
+{
+ catch_phantom = mode != 0 ? 1 : 0;
+}
+
+void
+dvi_set_phantom_height (double height, double depth)
+{
+ phantom_height = height;
+ phantom_depth = depth;
+ catch_phantom = 2;
+}
+
+/* All those things related to "compensation" is intruduced due to
+ * bcontent/econtent specials. They are originally implemented with
+ * modification to very important part of pdfdev functions such as
+ * pdf_dev_set_string(), and it made things very unclear.
+ *
+ * It is not good idea to modify the core part of PDF output routines
+ * just for implementing DVI "special" command. They do not make sense
+ * and just look odd when PDF output routines are separated from dvipdfmx.
+ */
+static struct spt_coord {
+ spt_t x, y;
+} compensation = { 0, 0 };
+
+void dvi_set_compensation (double x, double y)
+{
+ compensation.x = (spt_t) round(x / dvi2pts);
+ compensation.y = (spt_t) round(y / dvi2pts);
+}
+
+static void
+set_string (spt_t xpos,
+ spt_t ypos,
+ const void *instr_ptr,
+ int instr_len,
+ spt_t width,
+ int font_id)
+{
+ xpos -= compensation.x;
+ ypos -= compensation.y;
+ pdf_dev_set_string(xpos, ypos, instr_ptr, instr_len, width, font_id);
+}
+
+static void
+set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
+{
+ xpos -= compensation.x;
+ ypos -= compensation.y;
+ pdf_dev_set_rule(xpos, ypos, width, height);
+}
+
+static void
+calc_rect (pdf_rect *r, spt_t xpos, spt_t ypos, spt_t width, spt_t height, spt_t depth)
+{
+ xpos -= compensation.x;
+ ypos -= compensation.y;
+ pdf_dev_set_rect(r, xpos, ypos, width, height, depth);
+}
+
+void
+dvi_do_special (const void *buffer, int32_t size)
+{
+ double x_user, y_user, mag;
+ const char *p;
+ int is_drawable = 0;
+ pdf_rect rect = {0.0, 0.0, 0.0, 0.0};
+
+ graphics_mode();
+
+ p = (const char *) buffer;
+
+ x_user = dvi_state.h * dvi2pts;
+ y_user = -dvi_state.v * dvi2pts;
+ mag = dvi_tell_mag();
+
+ if (spc_exec_special(p, size, x_user, y_user, mag, &is_drawable, &rect) < 0) {
+ if (dpx_conf.verbose_level > 0) {
+ dump(p, p + size);
+ }
+ return;
+ }
+
+ if (dvi_is_tracking_boxes() && is_drawable) {
+ pdf_doc_expand_box(&rect);
+ }
+
+ return;
+}
+
+double
+dvi_unit_size (void)
+{
+ return dvi2pts;
+}
+
+
+int
+dvi_locate_font (const char *tfm_name, spt_t ptsize)
+{
+ int cur_id = -1;
+ const char *name = tfm_name;
+ int subfont_id = -1, font_id; /* VF or device font ID */
+ fontmap_rec *mrec;
+
+ if (dpx_conf.verbose_level > 0)
+ MESG("<%s@%.2fpt", tfm_name, ptsize * dvi2pts);
+
+ need_more_fonts(1);
+
+ /* This routine needs to be recursive/reentrant. Load current high water
+ * mark into an automatic variable.
+ */
+ cur_id = num_loaded_fonts++;
+
+ mrec = pdf_lookup_fontmap_record(tfm_name);
+ /* Load subfont mapping table */
+ if (mrec && mrec->charmap.sfd_name && mrec->charmap.subfont_id) {
+ subfont_id = sfd_load_record(mrec->charmap.sfd_name, mrec->charmap.subfont_id);
+ }
+
+ memset(&loaded_fonts[cur_id], 0, sizeof (struct loaded_font));
+
+ /* TFM must exist here. */
+ loaded_fonts[cur_id].tfm_id = tfm_open(tfm_name, 1);
+ loaded_fonts[cur_id].subfont_id = subfont_id;
+ loaded_fonts[cur_id].size = ptsize;
+ /* This will be reset later if it was really generated by the dvi file. */
+ loaded_fonts[cur_id].source = VF;
+
+ /* The order of searching fonts is as follows:
+ *
+ * 1. If mrec is null, that is, there is no map entry matching
+ * with tfm_name, then search a virtual font matching with
+ * tfm_name at first. If no virtual font is found, search a
+ * PK font matching with tfm_name.
+ *
+ * 2. If mrec is non-null, search a physical scalable font.
+ *
+ * 3. Notice that every subfont gets non-null mrec. In this case,
+ * enc_name corresponding to mrec will be used instead of mrec.
+ * That is enc_name is NULL, search a virtual font for Omega (.ovf)
+ * matching with the base name of the subfont. If no virtual font
+ * for Omega is found, it is a fatal error because there is no PK font
+ * for Omega.
+ */
+ if (!mrec) {
+ font_id = vf_locate_font(tfm_name, ptsize);
+ if (font_id >= 0) {
+ loaded_fonts[cur_id].type = VIRTUAL;
+ loaded_fonts[cur_id].font_id = font_id;
+ if (dpx_conf.verbose_level > 0)
+ MESG("(VF)>");
+ return cur_id;
+ }
+ }
+#if 1
+ /* Sorry, I don't understand this well... Please fix.
+ * The purpose of this seems to be:
+ *
+ * Map 8-bit char codes in subfont to 16-bit code with SFD mapping
+ * and map subfonts to single OVF font.
+ *
+ * But it apparently only does TFM -> OVF mapping but no character
+ * code mapping. Please see dvi_set(), you can't have both font->type
+ * VIRTUAL and font->subfont_id >= 0. Am I missing something?
+ */
+ else if (subfont_id >= 0 && mrec->map_name)
+ {
+ fontmap_rec *mrec1 = pdf_lookup_fontmap_record(mrec->map_name);
+ /* enc_name=NULL should be used only for 'built-in' encoding.
+ * Please fix this!
+ */
+ if (mrec1 && !mrec1->enc_name) {
+ font_id = vf_locate_font(mrec1->font_name, ptsize);
+ if (font_id < 0)
+ WARN("Could not locate Omega Virtual Font \"%s\" for \"%s\".",
+ mrec1->font_name, tfm_name);
+ else {
+ loaded_fonts[cur_id].type = VIRTUAL;
+ loaded_fonts[cur_id].font_id = font_id;
+ if (dpx_conf.verbose_level > 0)
+ MESG("(OVF)>");
+ return cur_id;
+ }
+ }
+ }
+#endif /* 1 */
+
+ /* Failed to load a virtual font so we try to load a physical font. */
+
+ /* If mrec->map_name is not NULL, font name identified in PDF output
+ * is different than tfm_name, this can happen for subfonts grouped
+ * into a single "intermediate" font foo@SFD@.
+ * This is necessary for optimal output; to avoid unnecessary creation
+ * of multiple instances of a same font, to avoid frequent font selection
+ * and break of string_mode.
+ */
+ if (mrec && mrec->map_name) {
+ name = mrec->map_name;
+ } else {
+ name = tfm_name;
+ }
+
+ /* We need ptsize for PK font creation. */
+ font_id = pdf_dev_locate_font(name, ptsize);
+ if (font_id < 0) {
+ WARN("Could not locate a virtual/physical font for TFM \"%s\".", tfm_name);
+ if (mrec && mrec->map_name) { /* has map_name */
+ fontmap_rec *mrec1 = pdf_lookup_fontmap_record(mrec->map_name);
+ WARN(">> This font is mapped to an intermediate 16-bit font \"%s\" with SFD charmap=<%s,%s>,",
+ mrec->map_name, mrec->charmap.sfd_name, mrec->charmap.subfont_id);
+ if (!mrec1)
+ WARN(">> but I couldn't find font mapping for \"%s\".", mrec->map_name);
+ else {
+ WARN(">> and then mapped to a physical font \"%s\" by fontmap.", mrec1->font_name);
+ WARN(">> Please check if kpathsea library can find this font: %s", mrec1->font_name);
+ }
+ } else if (mrec && !mrec->map_name) {
+ char *finaldot = strrchr(mrec->font_name, '.');
+ if (finaldot && strcasecmp(finaldot, ".pfa") == 0) {
+ /* type1 fonts with pfa format are not supported */
+ WARN("This font is mapped to a physical font \"%s\".", mrec->font_name);
+ ERROR("Sorry, pfa format not supported; please convert the font to pfb, e.g., with t1binary.");
+ } else {
+ WARN(">> This font is mapped to a physical font \"%s\".", mrec->font_name);
+ WARN(">> Please check if kpathsea library can find this font: %s", mrec->font_name);
+ }
+ } else {
+ WARN(">> There are no valid font mapping entry for this font.");
+ WARN(">> Font file name \"%s\" was assumed but failed to locate that font.", tfm_name);
+ }
+ ERROR("Cannot proceed without .vf or \"physical\" font for PDF output...");
+ }
+ memset(loaded_fonts[cur_id].padbytes, 0, 4);
+ if (mrec) {
+ if (mrec->opt.mapc >= 0) {
+ loaded_fonts[cur_id].padbytes[2] = (mrec->opt.mapc >> 8) & 0xff;
+ }
+ if (mrec->enc_name && !strcmp(mrec->enc_name, "unicode")) {
+ loaded_fonts[cur_id].is_unicode = 1;
+ if (mrec->opt.mapc >= 0) {
+ loaded_fonts[cur_id].padbytes[0] = (mrec->opt.mapc >> 24) & 0xff;
+ loaded_fonts[cur_id].padbytes[1] = (mrec->opt.mapc >> 16) & 0xff;
+ }
+ }
+ }
+ loaded_fonts[cur_id].minbytes = pdf_dev_font_minbytes(font_id);
+ loaded_fonts[cur_id].type = PHYSICAL;
+ loaded_fonts[cur_id].font_id = font_id;
+ if (loaded_fonts[cur_id].minbytes > 4) {
+ WARN("Input encoding requries more than 4 bytes per char... (unsupported)");
+ loaded_fonts[cur_id].minbytes = 4;
+ }
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(">");
+
+ return cur_id;
+}
+
+#if defined(LIBDPX)
+int
+#else
+static int
+#endif /* LIBDPX */
+dvi_locate_native_font (const char *filename, uint32_t index,
+ spt_t ptsize, int layout_dir, int extend, int slant, int embolden)
+{
+ int cur_id = -1;
+ fontmap_rec *mrec;
+ char *fontmap_key;
+ FILE *fp;
+ char *path;
+ sfnt *sfont;
+ ULONG offset = 0;
+ int is_dfont = 0, is_type1 = 0;
+
+ if (dpx_conf.verbose_level > 0)
+ MESG("<%s@%.2fpt", filename, ptsize * dvi2pts);
+
+ if ((path = dpx_find_dfont_file(filename)) != NULL &&
+ (fp = MFOPEN(path, "rb")) != NULL)
+ is_dfont = 1;
+ else if ((path = dpx_find_type1_file(filename)) != NULL)
+ is_type1 = 1;
+ else if (((path = dpx_find_opentype_file(filename)) == NULL
+ && (path = dpx_find_truetype_file(filename)) == NULL)
+ || (fp = MFOPEN(path, "rb")) == NULL) {
+ ERROR("Cannot proceed without the font: %s", filename);
+ }
+ need_more_fonts(1);
+
+ cur_id = num_loaded_fonts++;
+
+ fontmap_key = malloc(strlen(path) + 40); // CHECK this is enough
+ sprintf(fontmap_key, "%s/%u/%c/%d/%d/%d", path, index, layout_dir == 0 ? 'H' : 'V', extend, slant, embolden);
+ mrec = pdf_lookup_fontmap_record(fontmap_key);
+ if (mrec == NULL) {
+ if ((mrec = pdf_insert_native_fontmap_record(path, index, layout_dir, extend, slant, embolden)) == NULL) {
+ ERROR("Failed to insert font record for font: %s", filename);
+ }
+ }
+
+ memset(&loaded_fonts[cur_id], 0, sizeof (struct loaded_font));
+
+ loaded_fonts[cur_id].font_id = pdf_dev_locate_font(fontmap_key, ptsize);
+ loaded_fonts[cur_id].size = ptsize;
+ loaded_fonts[cur_id].type = NATIVE;
+ loaded_fonts[cur_id].minbytes = pdf_dev_font_minbytes(loaded_fonts[cur_id].font_id);
+ if (loaded_fonts[cur_id].minbytes > 4) {
+ WARN("Input encoding requries more than 4 bytes per char... (unsupprted)");
+ loaded_fonts[cur_id].minbytes = 4;
+ }
+ RELEASE(fontmap_key);
+
+ if (is_type1) {
+ cff_font *cffont;
+ char *enc_vec[256];
+ uint16_t num_glyphs;
+ int i;
+
+ fp = DPXFOPEN(filename, DPX_RES_TYPE_T1FONT);
+ if (!fp)
+ return -1;
+
+ if (!is_pfb(fp))
+ ERROR("Failed to read Type 1 font \"%s\".", filename);
+
+ memset(enc_vec, 0, 256 * sizeof(char *));
+ cffont = t1_load_font(enc_vec, 0, fp);
+ if (!cffont)
+ ERROR("Failed to read Type 1 font \"%s\".", filename);
+ for (i = 0; i < 256; i++) {
+ if (enc_vec[i])
+ RELEASE(enc_vec[i]);
+ }
+ loaded_fonts[cur_id].shift_gid = cffont->is_notdef_notzero;
+ loaded_fonts[cur_id].num_glyphs = num_glyphs = cffont->num_glyphs;
+ loaded_fonts[cur_id].gm = NEW(num_glyphs + 1, struct gm);
+ for (i = 0; i < num_glyphs; i++) {
+ double advance, ascent, descent;
+ cff_index *cstrings = cffont->cstrings;
+ t1_ginfo gm;
+ uint16_t gid;
+
+ /* If .notdef is not the 1st glyph in CharStrings, glyph_id given by
+ * FreeType should be increased by 1
+ */
+ gid = (cffont->is_notdef_notzero) ? i + 1 : i;
+ if (gid == num_glyphs)
+ break;
+ t1char_get_metrics(cstrings->data + cstrings->offset[gid] - 1,
+ cstrings->offset[gid + 1] - cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+
+ advance = layout_dir == 0 ? gm.wx : gm.wy;
+ ascent = gm.bbox.ury;
+ descent = gm.bbox.lly;
+ loaded_fonts[cur_id].gm[gid].advance = (spt_t) (ptsize * ((advance / 1000.0) * mrec->opt.extend));
+ loaded_fonts[cur_id].gm[gid].ascent = (spt_t) (ptsize * ((ascent / 1000.0)));
+ loaded_fonts[cur_id].gm[gid].descent = (spt_t) (ptsize * ((descent / 1000.0)));
+ }
+ cff_close(cffont);
+ DPXFCLOSE(fp);
+ } else {
+ struct tt_head_table *head;
+ struct tt_maxp_table *maxp;
+ struct tt_hhea_table *hhea;
+ struct tt_longMetrics *gm;
+ spt_t ascent, descent;
+ uint16_t num_glyphs;
+ int i;
+
+ if (is_dfont)
+ sfont = dfont_open(fp, index);
+ else
+ sfont = sfnt_open(fp);
+ if (sfont->type == SFNT_TYPE_TTC)
+ offset = ttc_read_offset(sfont, index);
+ else if (sfont->type == SFNT_TYPE_DFONT)
+ offset = sfont->offset;
+
+ sfnt_read_table_directory(sfont, offset);
+ head = tt_read_head_table(sfont);
+ maxp = tt_read_maxp_table(sfont);
+ hhea = tt_read_hhea_table(sfont);
+ ascent = (spt_t) (ptsize * ((double) hhea->ascent / (double) head->unitsPerEm));
+ descent = (spt_t) (ptsize * ((double) hhea->descent / (double) head->unitsPerEm));
+ loaded_fonts[cur_id].num_glyphs = num_glyphs = maxp->numGlyphs;
+ if (layout_dir == 1 && sfnt_find_table_pos(sfont, "vmtx") > 0) {
+ struct tt_vhea_table *vhea = tt_read_vhea_table(sfont);
+ sfnt_locate_table(sfont, "vmtx");
+ gm = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics, vhea->numOfExSideBearings);
+ RELEASE(vhea);
+ } else {
+ sfnt_locate_table(sfont, "hmtx");
+ gm = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings);
+ }
+ if (!gm)
+ ERROR("Failed to read TrueType/OpenType glyph metrics table.");
+ loaded_fonts[cur_id].gm = NEW(num_glyphs, struct gm);
+ for (i = 0; i < num_glyphs; i++) {
+ loaded_fonts[cur_id].gm[i].advance = (spt_t) (ptsize * ((double) gm[i].advance / (double) head->unitsPerEm) * mrec->opt.extend);
+ loaded_fonts[cur_id].gm[i].ascent = ascent;
+ loaded_fonts[cur_id].gm[i].descent = descent;
+
+ }
+ RELEASE(gm);
+ RELEASE(hhea);
+ RELEASE(maxp);
+ RELEASE(head);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ }
+
+ RELEASE(path);
+
+ loaded_fonts[cur_id].layout_dir = layout_dir;
+ loaded_fonts[cur_id].extend = mrec->opt.extend;
+ loaded_fonts[cur_id].slant = mrec->opt.slant;
+ loaded_fonts[cur_id].embolden = mrec->opt.bold;
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(">");
+
+ return cur_id;
+}
+
+double
+dvi_dev_xpos (void)
+{
+ return dvi_state.h * dvi2pts;
+}
+
+double
+dvi_dev_ypos (void)
+{
+ return -(dvi_state.v * dvi2pts);
+}
+
+static void do_moveto (int32_t x, int32_t y)
+{
+ dvi_state.h = x;
+ dvi_state.v = y;
+}
+
+void dvi_right (int32_t x)
+{
+ spt_t save_h, save_v;
+
+ if (lr_mode >= SKIMMING) {
+ lr_width += x;
+ return;
+ }
+
+ if (lr_mode == RTYPESETTING)
+ x = -x;
+
+ save_h = dvi_state.h;
+ save_v = dvi_state.v;
+
+ switch (dvi_state.d) {
+ case 0:
+ dvi_state.h += x; break;
+ case 1:
+ dvi_state.v += x; break;
+ case 3:
+ dvi_state.v -= x; break;
+ }
+
+ if (dvi_is_tracking_boxes() && catch_phantom > 0) {
+ pdf_rect rect;
+ spt_t width, height, depth;
+ if (catch_phantom == 1) {
+ if (current_font >= 0 && current_font < num_loaded_fonts) {
+ height = loaded_fonts[current_font].size;
+ } else {
+ if (dpx_conf.verbose_level > 0) {
+ WARN("Don't know how to calculate the box height since current font is not set...");
+ }
+ height = 0.0;
+ }
+ depth = 0.0;
+ } else {
+ height = phantom_height / dvi2pts;
+ depth = phantom_depth / dvi2pts;
+ }
+ switch (dvi_state.d) {
+ case 0:
+ width = dvi_state.h - save_h;
+ break;
+ case 1:
+ case 2:
+ width = dvi_state.v - save_v;
+ break;
+ default:
+ width = dvi_state.h - save_h;
+ }
+ calc_rect(&rect, save_h, -save_v, width, height, depth);
+ pdf_doc_expand_box(&rect);
+ }
+}
+
+void dvi_down (int32_t y)
+{
+ if (lr_mode < SKIMMING) {
+ switch (dvi_state.d) {
+ case 0:
+ dvi_state.v += y; break;
+ case 1:
+ dvi_state.h -= y; break;
+ case 3:
+ dvi_state.h += y; break;
+ }
+ }
+}
+
+/* _FIXME_
+ * CMap decoder wants multibyte strings as input but
+ * how DVI char codes are converted to multibyte sting
+ * is not clear.
+ */
+void
+dvi_set (int32_t ch)
+{
+ struct loaded_font *font;
+ spt_t width, height, depth;
+ unsigned char wbuf[4];
+ int n, cbytes;
+
+ if (current_font < 0) {
+ ERROR("No font selected!");
+ }
+ /* The division by dvi2pts seems strange since we actually know the
+ * "dvi" size of the fonts contained in the DVI file. In other
+ * words, we converted from DVI units to pts and back again!
+ * The problem comes from fonts defined in VF files where we don't know
+ * the DVI size. It's keeping me sane to keep *point sizes* of *all*
+ * fonts in the dev.c file and convert them back if necessary.
+ */
+ font = &loaded_fonts[current_font];
+
+ if (font->type == NATIVE) {
+ if (ch >= 0 && ch < font->num_glyphs) {
+ width = font->gm[ch].advance;
+ } else {
+ WARN("Invalid char for dvilua font (ignored): %04x", ch);
+ return;
+ }
+ } else {
+ width = tfm_get_fw_width(font->tfm_id, ch);
+ width = sqxfw(font->size, width);
+ }
+
+ if (lr_mode >= SKIMMING) {
+ lr_width += width;
+ return;
+ }
+
+ if (lr_mode == RTYPESETTING)
+ dvi_right(width); /* Will actually move left */
+
+ memcpy(wbuf, font->padbytes, 4);
+ switch (font->type) {
+ case PHYSICAL:
+ if (ch > 65535) {
+ /* FIXME: uptex specific undocumented */
+ if (!font->is_unicode && tfm_is_jfm(font->tfm_id)) {
+ wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff;
+ wbuf[1] = UTF32toUTF16HS(ch) & 0xff;
+ wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff;
+ wbuf[3] = UTF32toUTF16LS(ch) & 0xff;
+ } else {
+ wbuf[0] = (ch >> 24) & 0xff;
+ wbuf[1] = (ch >> 16) & 0xff;
+ wbuf[2] = (ch >> 8) & 0xff;
+ wbuf[3] = ch & 0xff;
+ }
+ n = 4;
+ } else if (ch > 255) {
+ wbuf[2] = (ch >> 8) & 0xff;
+ wbuf[3] = ch & 0xff;
+ n = 2;
+ } else if (font->subfont_id >= 0) {
+ uint16_t uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
+ wbuf[2] = (uch >> 8) & 0xff;
+ wbuf[3] = uch & 0xff;
+ n = 2;
+ } else {
+ wbuf[3] = (unsigned char) ch;
+ n = 1;
+ }
+ cbytes = font->minbytes > n ? font->minbytes : n;
+ set_string(dvi_state.h, -dvi_state.v, wbuf + 4 - cbytes, cbytes, width, font->font_id);
+ if (dvi_is_tracking_boxes()) {
+ pdf_rect rect;
+
+ height = tfm_get_fw_height(font->tfm_id, ch);
+ depth = tfm_get_fw_depth (font->tfm_id, ch);
+ height = sqxfw(font->size, height);
+ depth = sqxfw(font->size, depth);
+
+ calc_rect(&rect, dvi_state.h, -dvi_state.v, width, height, depth);
+ pdf_doc_expand_box(&rect);
+ }
+ break;
+ case NATIVE:
+ wbuf[0] = (ch >> 8) & 0xff;
+ wbuf[1] = ch & 0xff;
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id);
+ if (dvi_is_tracking_boxes()) {
+ pdf_rect rect;
+
+ height = font->gm[ch].ascent;
+ depth = font->gm[ch].descent;
+ calc_rect(&rect, dvi_state.h, -dvi_state.v, width, height, depth);
+ pdf_doc_expand_box(&rect);
+ }
+ break;
+ case VIRTUAL:
+#if 0
+ /* See comment in locate_font() */
+ if (font->subfont_id >= 0)
+ ch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
+#endif /* 0 */
+ vf_set_char(ch, font->font_id); /* push/pop invoked */
+ break;
+ }
+
+ if (lr_mode == LTYPESETTING)
+ dvi_right(width);
+
+}
+
+void
+dvi_put (int32_t ch)
+{
+ struct loaded_font *font;
+ spt_t width, height, depth;
+ unsigned char wbuf[4];
+ int n, cbytes;
+
+ if (current_font < 0) {
+ ERROR("No font selected!");
+ }
+
+ font = &loaded_fonts[current_font];
+
+ memcpy(wbuf, font->padbytes, 4);
+ switch (font->type) {
+ case PHYSICAL:
+ width = tfm_get_fw_width(font->tfm_id, ch);
+ width = sqxfw(font->size, width);
+ /* Treat a single character as a one byte string and use the
+ * string routine.
+ */
+ if (ch > 65535) {
+ /* FIXME: uptex specific undocumented */
+ if (!font->is_unicode && tfm_is_jfm(font->tfm_id)) {
+ wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff;
+ wbuf[1] = UTF32toUTF16HS(ch) & 0xff;
+ wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff;
+ wbuf[3] = UTF32toUTF16LS(ch) & 0xff;
+ } else {
+ wbuf[0] = (ch >> 24) & 0xff;
+ wbuf[1] = (ch >> 16) & 0xff;
+ wbuf[2] = (ch >> 8) & 0xff;
+ wbuf[3] = ch & 0xff;
+ }
+ n = 4;
+ } else if (ch > 255) {
+ wbuf[2] = (ch >> 8) & 0xff;
+ wbuf[3] = ch & 0xff;
+ n = 2;
+ } else if (font->subfont_id >= 0) {
+ uint16_t uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
+ wbuf[2] = (uch >> 8) & 0xff;
+ wbuf[3] = uch & 0xff;
+ n = 2;
+ } else {
+ wbuf[3] = (unsigned char) ch;
+ n = 1;
+ }
+ cbytes = font->minbytes > n ? font->minbytes : n;
+ set_string(dvi_state.h, -dvi_state.v, wbuf + 4 - cbytes, cbytes, width, font->font_id);
+ if (dvi_is_tracking_boxes()) {
+ pdf_rect rect;
+
+ height = tfm_get_fw_height(font->tfm_id, ch);
+ depth = tfm_get_fw_depth (font->tfm_id, ch);
+ height = sqxfw(font->size, height);
+ depth = sqxfw(font->size, depth);
+
+ calc_rect(&rect, dvi_state.h, -dvi_state.v, width, height, depth);
+ pdf_doc_expand_box(&rect);
+ }
+ break;
+ case VIRTUAL:
+#if 0
+ /* See comment in locate_font() */
+ if (font->subfont_id >= 0)
+ ch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
+#endif /* 0 */
+ vf_set_char(ch, font->font_id);
+ break;
+ }
+
+ return;
+}
+
+
+void
+dvi_rule (int32_t width, int32_t height)
+{
+ if (width > 0 && height > 0) {
+ do_moveto(dvi_state.h, dvi_state.v);
+
+ switch (dvi_state.d) {
+ case 0:
+ set_rule(dvi_state.h, -dvi_state.v, width, height);
+ break;
+ case 1:
+ set_rule(dvi_state.h, -dvi_state.v - width, height, width);
+ break;
+ case 3:
+ set_rule(dvi_state.h - height, -dvi_state.v , height, width);
+ break;
+ }
+ }
+}
+
+void
+dvi_dirchg (unsigned char dir)
+{
+ if (dpx_conf.verbose_level > 0)
+ fprintf(stderr, " > dvi_dirchg %d\n", dir);
+ dvi_state.d = dir;
+ pdf_dev_set_dirmode(dvi_state.d); /* 0: horizontal, 1,3: vertical */
+}
+
+static void
+do_setrule (void)
+{
+ int32_t width, height;
+
+ height = get_buffered_signed_quad();
+ width = get_buffered_signed_quad();
+ switch (lr_mode) {
+ case LTYPESETTING:
+ dvi_rule(width, height);
+ dvi_right(width);
+ break;
+ case RTYPESETTING:
+ dvi_right(width);
+ dvi_rule(width, height);
+ break;
+ default:
+ lr_width += width;
+ break;
+ }
+}
+
+static void
+do_putrule (void)
+{
+ int32_t width, height;
+
+ height = get_buffered_signed_quad ();
+ width = get_buffered_signed_quad ();
+ switch (lr_mode) {
+ case LTYPESETTING:
+ dvi_rule(width, height);
+ break;
+ case RTYPESETTING:
+ dvi_right(width);
+ dvi_rule(width, height);
+ dvi_right(-width);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+dvi_push (void)
+{
+ if (dvi_stack_depth >= DVI_STACK_DEPTH_MAX)
+ ERROR("DVI stack exceeded limit.");
+
+ dvi_stack[dvi_stack_depth++] = dvi_state;
+}
+
+void
+dvi_pop (void)
+{
+ if (dvi_stack_depth <= 0)
+ ERROR ("Tried to pop an empty stack.");
+
+ dvi_state = dvi_stack[--dvi_stack_depth];
+ do_moveto(dvi_state.h, dvi_state.v);
+ pdf_dev_set_dirmode(dvi_state.d); /* 0: horizontal, 1,3: vertical */
+}
+
+
+void
+dvi_w (int32_t ch)
+{
+ dvi_state.w = ch;
+ dvi_right(ch);
+}
+
+void
+dvi_w0 (void)
+{
+ dvi_right(dvi_state.w);
+}
+
+void
+dvi_x (int32_t ch)
+{
+ dvi_state.x = ch;
+ dvi_right(ch);
+}
+
+void
+dvi_x0 (void)
+{
+ dvi_right(dvi_state.x);
+}
+
+void
+dvi_y (int32_t ch)
+{
+ dvi_state.y = ch;
+ dvi_down(ch);
+}
+
+void
+dvi_y0 (void)
+{
+ dvi_down(dvi_state.y);
+}
+
+void
+dvi_z (int32_t ch)
+{
+ dvi_state.z = ch;
+ dvi_down(ch);
+}
+
+void
+dvi_z0 (void)
+{
+ dvi_down(dvi_state.z);
+}
+
+static void
+skip_fntdef (void)
+{
+ int area_len, name_len;
+
+ skip_bytes(12, dvi_file);
+ area_len = get_unsigned_byte(dvi_file);
+ name_len = get_unsigned_byte(dvi_file);
+ skip_bytes(area_len + name_len, dvi_file);
+}
+
+/* when pre-scanning the page, we process fntdef
+ and remove the fntdef opcode from the buffer */
+static void
+do_fntdef (int32_t tex_id)
+{
+ if (linear)
+ read_font_record(tex_id);
+ else
+ skip_fntdef();
+ --dvi_page_buf_index;
+}
+
+void
+dvi_set_font (int font_id)
+{
+ current_font = font_id;
+}
+
+static void
+do_fnt (int32_t tex_id)
+{
+ int i;
+
+ for (i = 0; i < num_def_fonts; i++) {
+ if (def_fonts[i].tex_id == tex_id)
+ break;
+ }
+
+ if (i == num_def_fonts) {
+ ERROR("Tried to select a font that hasn't been defined: id=%d", tex_id);
+ }
+
+ if (!def_fonts[i].used) {
+ int font_id;
+
+ if (def_fonts[i].native) {
+ font_id = dvi_locate_native_font(def_fonts[i].font_name,
+ def_fonts[i].face_index,
+ def_fonts[i].point_size,
+ def_fonts[i].layout_dir,
+ def_fonts[i].extend,
+ def_fonts[i].slant,
+ def_fonts[i].embolden);
+ } else {
+ font_id = dvi_locate_font(def_fonts[i].font_name,
+ def_fonts[i].point_size);
+ }
+ loaded_fonts[font_id].rgba_color = def_fonts[i].rgba_color;
+ loaded_fonts[font_id].rgba_used = def_fonts[i].rgba_used;
+ /* if rgba_used == 0, not a colored font */
+ if (loaded_fonts[font_id].rgba_used == 0) {
+ loaded_fonts[font_id].xgs_id = -1;
+ } else {
+ pdf_obj *xgs_dict;
+ int a = loaded_fonts[font_id].rgba_color & 0xff;
+
+ /* Inefficient but don't care as transparency is not expected to be frequently used. */
+ xgs_dict = pdf_new_dict();
+ pdf_add_dict(xgs_dict, pdf_new_name("Type"), pdf_new_name("ExtGState"));
+ pdf_add_dict(xgs_dict, pdf_new_name("ca"), pdf_new_number(a/255.0));
+ pdf_add_dict(xgs_dict, pdf_new_name("CA"), pdf_new_number(a/255.0));
+ loaded_fonts[font_id].xgs_id = pdf_defineresource("ExtGState", NULL, xgs_dict, 0);
+ }
+ loaded_fonts[font_id].source = DVI;
+ def_fonts[i].used = 1;
+ def_fonts[i].font_id = font_id;
+ }
+ current_font = def_fonts[i].font_id;
+}
+
+static void
+do_xxx (int32_t size)
+{
+ if (lr_mode < SKIMMING)
+ dvi_do_special(dvi_page_buffer + dvi_page_buf_index, size);
+ dvi_page_buf_index += size;
+}
+
+static void
+do_bop (void)
+{
+ int i;
+
+ if (processing_page)
+ ERROR("Got a bop in the middle of a page!");
+
+ /* For now, ignore TeX's count registers */
+ for (i = 0; i < 10; i++) {
+ skip_bufferd_bytes(4);
+ }
+ /* Ignore previous page pointer since we have already
+ * saved this information
+ */
+ skip_bufferd_bytes(4);
+ clear_state();
+ processing_page = 1;
+
+ pdf_doc_begin_page(dvi_tell_mag(), dev_origin_x, dev_origin_y);
+ spc_exec_at_begin_page();
+
+ return;
+}
+
+static void
+do_eop (void)
+{
+ processing_page = 0;
+
+ if (dvi_stack_depth != 0) {
+ ERROR("DVI stack depth is not zero at end of page");
+ }
+ spc_exec_at_end_page();
+
+ pdf_doc_end_page();
+
+ return;
+}
+
+static void
+do_dir (void)
+{
+ dvi_state.d = get_buffered_unsigned_byte();
+ pdf_dev_set_dirmode(dvi_state.d); /* 0: horizontal, 1,3: vertical */
+}
+
+static void
+lr_width_push (void)
+{
+ if (lr_width_stack_depth >= DVI_STACK_DEPTH_MAX)
+ ERROR("Segment width stack exceeded limit.");
+
+ lr_width_stack[lr_width_stack_depth++] = lr_width;
+}
+
+static void
+lr_width_pop (void)
+{
+ if (lr_width_stack_depth <= 0)
+ ERROR("Tried to pop an empty segment width stack.");
+
+ lr_width = lr_width_stack[--lr_width_stack_depth];
+}
+
+static void
+dvi_begin_reflect (void)
+{
+ if (lr_mode >= SKIMMING) {
+ ++lr_mode;
+ } else {
+ lr_state.buf_index = dvi_page_buf_index;
+ lr_state.font = current_font;
+ lr_state.state = lr_mode;
+ lr_mode = SKIMMING;
+ lr_width = 0;
+ }
+}
+
+static void
+dvi_end_reflect (void)
+{
+ switch (lr_mode) {
+ case SKIMMING:
+ current_font = lr_state.font;
+ dvi_page_buf_index = lr_state.buf_index;
+ lr_mode = REVERSE(lr_state.state); /* must precede dvi_right */
+ dvi_right(-(int32_t)lr_width);
+ lr_width_push();
+ break;
+ case LTYPESETTING:
+ case RTYPESETTING:
+ lr_width_pop();
+ dvi_right(-(int32_t)lr_width);
+ lr_mode = REVERSE(lr_mode);
+ break;
+ default: /* lr_mode > SKIMMING */
+ lr_mode--;
+ }
+}
+
+static void
+skip_native_font_def (void)
+{
+ unsigned int flags;
+ int name_length;
+
+ skip_bytes(4, dvi_file); /* skip point size */
+ flags = get_unsigned_pair(dvi_file);
+ name_length = get_unsigned_byte(dvi_file);
+ skip_bytes(name_length + 4, dvi_file);
+
+ if (flags & XDV_FLAG_COLORED)
+ skip_bytes(4, dvi_file);
+
+ if (flags & XDV_FLAG_EXTEND)
+ skip_bytes(4, dvi_file);
+
+ if (flags & XDV_FLAG_SLANT)
+ skip_bytes(4, dvi_file);
+
+ if (flags & XDV_FLAG_EMBOLDEN)
+ skip_bytes(4, dvi_file);
+}
+
+static void
+do_native_font_def (int32_t tex_id)
+{
+ if (linear)
+ read_native_font_record(tex_id);
+ else
+ skip_native_font_def();
+ --dvi_page_buf_index; /* don't buffer the opcode */
+}
+
+static void
+skip_glyphs (void)
+{
+ unsigned int i, slen = 0;
+ slen = (unsigned int) get_buffered_unsigned_pair();
+ for (i = 0; i < slen; i++) {
+ skip_bufferd_bytes(4);
+ skip_bufferd_bytes(4);
+ skip_bufferd_bytes(2);
+ }
+}
+
+static void
+do_glyphs (int do_actual_text)
+{
+ struct loaded_font *font;
+ spt_t width, height, depth, *xloc, *yloc;
+ unsigned char wbuf[2];
+ int32_t i;
+ uint16_t glyph_id, slen = 0;
+
+ if (current_font < 0)
+ ERROR("No font selected!");
+
+ font = &loaded_fonts[current_font];
+
+ if (do_actual_text) {
+ slen = (unsigned int) get_buffered_unsigned_pair();
+ if (lr_mode >= SKIMMING) {
+ for (i = 0; i < slen; i++) {
+ skip_bufferd_bytes(2);
+ }
+ } else {
+ uint16_t *unicodes = NEW(slen, uint16_t);
+ for (i = 0; i < slen; i++) {
+ unicodes[i] = (uint16_t) get_buffered_unsigned_pair();
+ }
+ pdf_dev_begin_actualtext (unicodes, slen);
+ RELEASE(unicodes);
+ }
+ }
+
+ width = get_buffered_signed_quad();
+
+ if (lr_mode >= SKIMMING) {
+ lr_width += width;
+ skip_glyphs();
+ return;
+ }
+
+ if (lr_mode == RTYPESETTING)
+ dvi_right(width); /* Will actually move left */
+
+ slen = (unsigned int) get_buffered_unsigned_pair();
+ xloc = NEW(slen, spt_t);
+ yloc = NEW(slen, spt_t);
+ for (i = 0; i < slen; i++) {
+ xloc[i] = get_buffered_signed_quad();
+ yloc[i] = get_buffered_signed_quad();
+ }
+
+ if (font->rgba_used == 1) {
+ pdf_color color;
+ pdf_color_rgbcolor(&color,
+ (double)((unsigned char)(font->rgba_color >> 24) & 0xff) / 255,
+ (double)((unsigned char)(font->rgba_color >> 16) & 0xff) / 255,
+ (double)((unsigned char)(font->rgba_color >> 8) & 0xff) / 255);
+ pdf_color_push(&color, &color);
+ /* Opacity:
+ * Enter graphics_mode and then enclose with save/resotre
+ * since pdf_color_pop() may not restore graphics state.
+ */
+ if (font->xgs_id >= 0) {
+ pdf_obj *ref;
+ char resname[16];
+ char content[22];
+
+ sprintf(resname, "Xtx_Gs_%08x", current_font);
+ ref = pdf_get_resource_reference(font->xgs_id);
+ pdf_doc_add_page_resource("ExtGState", resname, ref);
+ graphics_mode();
+ pdf_dev_gsave();
+ sprintf(content, " /%s gs ", resname);
+ pdf_doc_add_page_content(content, strlen(content));
+ }
+ }
+
+ for (i = 0; i < slen; i++) {
+ spt_t advance = 0;
+
+ glyph_id = get_buffered_unsigned_pair(); /* freetype glyph index */
+ if (glyph_id < font->num_glyphs) {
+ if (font->shift_gid)
+ glyph_id++;
+ advance = font->gm[glyph_id].advance;
+ if (dvi_is_tracking_boxes()) {
+ pdf_rect rect;
+ height = font->gm[glyph_id].ascent ;
+ depth = -font->gm[glyph_id].descent;
+ calc_rect(&rect, dvi_state.h + xloc[i], -dvi_state.v - yloc[i], advance, height, depth);
+ pdf_doc_expand_box(&rect);
+ }
+ }
+ wbuf[0] = glyph_id >> 8;
+ wbuf[1] = glyph_id & 0xff;
+ set_string(dvi_state.h + xloc[i], -dvi_state.v - yloc[i], wbuf, 2, advance, font->font_id);
+ }
+
+ if (font->rgba_used == 1) {
+ if (font->xgs_id >= 0) {
+ graphics_mode();
+ pdf_dev_grestore();
+ }
+ pdf_color_pop();
+ }
+ RELEASE(xloc);
+ RELEASE(yloc);
+
+ if (do_actual_text) {
+ pdf_dev_end_actualtext();
+ }
+
+ if (lr_mode == LTYPESETTING)
+ dvi_right(width);
+
+ return;
+}
+
+static void
+check_postamble (void)
+{
+ int code;
+
+ skip_bytes(28, dvi_file);
+ while ((code = get_unsigned_byte(dvi_file)) != POST_POST) {
+ switch (code) {
+ case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
+ skip_bytes(code + 1 - FNT_DEF1, dvi_file);
+ skip_fntdef();
+ break;
+ case XDV_NATIVE_FONT_DEF:
+ skip_bytes(4, dvi_file);
+ skip_native_font_def();
+ break;
+ default:
+ ERROR("Unexpected op code (%u) in postamble", code);
+ }
+ }
+ skip_bytes(4, dvi_file);
+ post_id_byte = get_unsigned_byte(dvi_file);
+ if (!(post_id_byte == DVI_ID || post_id_byte == DVIV_ID || post_id_byte == XDV_ID || post_id_byte == XDV_ID_OLD)) {
+ MESG("DVI ID = %d\n", post_id_byte);
+ ERROR(invalid_signature);
+ }
+ check_id_bytes();
+ if (has_ptex && post_id_byte != DVIV_ID)
+ ERROR ("Saw opcode %i in DVI file not for Ascii pTeX", PTEXDIR);
+
+ num_pages = 0; /* force loop to terminate */
+}
+
+/* Most of the work of actually interpreting
+ * the dvi file is here.
+ */
+void
+dvi_do_page (double page_paper_height, double hmargin, double vmargin)
+{
+ unsigned char opcode;
+
+ /* before this is called, we have scanned the page for papersize specials
+ and the complete DVI data is now in dvi_page_buffer */
+ dvi_page_buf_index = 0;
+
+ /* DVI coordinate */
+ dev_origin_x = hmargin;
+ dev_origin_y = page_paper_height - vmargin;
+
+ dvi_stack_depth = 0;
+ for (;;) {
+ opcode = get_buffered_unsigned_byte();
+
+ if (opcode <= SET_CHAR_127) {
+ dvi_set(opcode);
+ continue;
+ }
+
+ /* If we are here, we have an opcode that is something
+ * other than SET_CHAR.
+ */
+ if (opcode >= FNT_NUM_0 && opcode <= FNT_NUM_63) {
+ do_fnt(opcode-FNT_NUM_0);
+ continue;
+ }
+
+ switch (opcode) {
+ case SET1: case SET2: case SET3:
+ dvi_set(get_buffered_unsigned_num(opcode-SET1)); break;
+ case SET4:
+ ERROR("Multibyte (>24 bits) character not supported!");
+ break;
+
+ case SET_RULE:
+ do_setrule();
+ break;
+
+ case PUT1: case PUT2: case PUT3:
+ dvi_put(get_buffered_unsigned_num(opcode-PUT1)); break;
+ case PUT4:
+ ERROR("Multibyte (>24 bits) character not supported!");
+ break;
+
+ case PUT_RULE:
+ do_putrule();
+ break;
+
+ case NOP:
+ break;
+
+ case BOP:
+ do_bop();
+ break;
+ case EOP:
+ do_eop();
+ if (linear) {
+ if ((opcode = get_unsigned_byte(dvi_file)) == POST)
+ check_postamble();
+ else
+ ungetc(opcode, dvi_file);
+ }
+ return;
+
+ case PUSH:
+ dvi_push();
+ if (lr_mode >= SKIMMING)
+ lr_width_push();
+ /* The following line needs to go here instead of in
+ * dvi_push() since logical structure of document is
+ * oblivous to virtual fonts. For example the last line on a
+ * page could be at stack level 3 and the page footer should
+ * be at stack level 3. However, if the page footer contains
+ * virtual fonts (or other nested constructions), it could
+ * fool the link breaker into thinking it was a continuation
+ * of the link */
+ dvi_mark_depth();
+ break;
+ case POP:
+ dvi_pop();
+ if (lr_mode >= SKIMMING)
+ lr_width_pop();
+ /* Above explanation holds for following line too */
+ dvi_mark_depth();
+ break;
+
+ case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4:
+ dvi_right(get_buffered_signed_num(opcode-RIGHT1)); break;
+
+ case W0: dvi_w0(); break;
+ case W1: case W2: case W3: case W4:
+ dvi_w(get_buffered_signed_num(opcode-W1)); break;
+
+ case X0: dvi_x0(); break;
+ case X1: case X2: case X3: case X4:
+ dvi_x(get_buffered_signed_num(opcode-X1)); break;
+
+ case DOWN1: case DOWN2: case DOWN3: case DOWN4:
+ dvi_down(get_buffered_signed_num(opcode-DOWN1)); break;
+
+ case Y0: dvi_y0(); break;
+ case Y1: case Y2: case Y3: case Y4:
+ dvi_y(get_buffered_signed_num(opcode-Y1)); break;
+
+ case Z0: dvi_z0(); break;
+ case Z1: case Z2: case Z3: case Z4:
+ dvi_z(get_buffered_signed_num(opcode-Z1)); break;
+
+ case FNT1: case FNT2: case FNT3: case FNT4:
+ do_fnt(get_buffered_unsigned_num(opcode-FNT1)); break;
+
+ /* Specials */
+ case XXX1: case XXX2: case XXX3: case XXX4:
+ {
+ int32_t size = get_buffered_unsigned_num(opcode-XXX1);
+ if (size < 0)
+ WARN("DVI: Special with %d bytes???", size);
+ else
+ do_xxx(size);
+ break;
+ }
+
+ /* These should not occur - processed during pre-scanning */
+ case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
+ break;
+
+ /* pTeX extension */
+ case PTEXDIR:
+ need_pTeX(opcode);
+ do_dir();
+ break;
+
+ /* XeTeX extensions */
+ case XDV_GLYPHS:
+ need_XeTeX(opcode);
+ do_glyphs(0);
+ break;
+ case XDV_TEXT_AND_GLYPHS:
+ need_XeTeX(opcode);
+ do_glyphs(1);
+ break;
+ /* should not occur - processed during pre-scanning */
+ case XDV_NATIVE_FONT_DEF:
+ need_XeTeX(opcode);
+ break;
+ case BEGIN_REFLECT:
+ need_XeTeX(opcode);
+ dvi_begin_reflect();
+ break;
+ case END_REFLECT:
+ need_XeTeX(opcode);
+ dvi_end_reflect();
+ break;
+
+ case POST:
+ if (linear && !processing_page) {
+ /* for linear processing, this means there are no more pages */
+ num_pages = 0; /* force loop to terminate */
+ return;
+ }
+ /* else fall through to error case */
+ case PRE: case POST_POST:
+ ERROR("Unexpected preamble or postamble in dvi file");
+ break;
+ default:
+ ERROR("Unexpected opcode or DVI file ended prematurely");
+ }
+ }
+}
+
+double
+dvi_init (char *dvi_filename, double mag)
+{
+ int32_t post_location;
+
+ if (!dvi_filename) { /* no filename: reading from stdin, probably a pipe */
+ int ch;
+#ifdef WIN32
+ setmode(fileno(stdin), _O_BINARY);
+#endif
+ dvi_file = stdin;
+ linear = 1;
+
+ get_preamble_dvi_info();
+ do_scales(mag);
+ if ((ch = get_unsigned_byte(dvi_file)) == POST)
+ check_postamble();
+ else
+ ungetc(ch, dvi_file);
+ } else {
+ char *p, *saved_orig_name;
+ dvi_file = NULL;
+ saved_orig_name = xstrdup(dvi_filename);
+ p = strrchr(dvi_filename, '.');
+ if (p == NULL || (!FILESTRCASEEQ(p, ".dvi") &&
+ !FILESTRCASEEQ(p, ".xdv"))) {
+ strcat(dvi_filename, ".xdv");
+ dvi_file = MFOPEN(dvi_filename, FOPEN_RBIN_MODE);
+ if (!dvi_file) {
+ dvi_filename[strlen(dvi_filename) - 4] = '\0';
+ strcat(dvi_filename, ".dvi");
+ dvi_file = MFOPEN(dvi_filename, FOPEN_RBIN_MODE);
+ }
+ }
+ if (!dvi_file)
+ dvi_file = MFOPEN(saved_orig_name, FOPEN_RBIN_MODE);
+ free(saved_orig_name);
+
+ if (!dvi_file) {
+ ERROR("Could not open specified DVI (or XDV) file: %s",
+ dvi_filename);
+ return 0.0;
+ }
+
+ /* DVI files are most easily read backwards by
+ * searching for post_post and then post opcode.
+ */
+ post_location = find_post();
+ get_dvi_info(post_location);
+ do_scales(mag);
+ get_page_info(post_location);
+ get_comment();
+ get_dvi_fonts(post_location);
+ }
+ clear_state();
+
+ dvi_page_buf_size = DVI_PAGE_BUF_CHUNK;
+ dvi_page_buffer = NEW(dvi_page_buf_size, unsigned char);
+
+ return dvi2pts;
+}
+
+void
+dvi_close (void)
+{
+ int i;
+
+ if (linear) {
+ /* probably reading a pipe from xetex; consume any remaining data */
+ while (fgetc(dvi_file) != EOF)
+ ;
+ }
+
+ /* We add comment in dvi_close instead of dvi_init so user
+ * has a change to overwrite it. The docinfo dictionary is
+ * treated as a write-once record.
+ */
+
+ /* Do some house cleaning */
+ MFCLOSE(dvi_file);
+ dvi_file = NULL;
+
+ if (def_fonts) {
+ for (i = 0; i < num_def_fonts; i++) {
+ if (def_fonts[i].font_name)
+ RELEASE(def_fonts[i].font_name);
+ def_fonts[i].font_name = NULL;
+ }
+ RELEASE(def_fonts);
+ }
+ def_fonts = NULL;
+
+ if (page_loc)
+ RELEASE(page_loc);
+ page_loc = NULL;
+ num_pages = 0;
+
+ for (i = 0; i < num_loaded_fonts; i++)
+ {
+ if (loaded_fonts[i].gm != NULL)
+ RELEASE(loaded_fonts[i].gm);
+
+ loaded_fonts[i].gm = NULL;
+ }
+
+ if (loaded_fonts)
+ RELEASE(loaded_fonts);
+ loaded_fonts = NULL;
+ num_loaded_fonts = 0;
+
+ vf_close_all_fonts();
+ tfm_close_all ();
+
+ if (dvi_page_buffer) {
+ RELEASE(dvi_page_buffer);
+ dvi_page_buffer = NULL;
+ dvi_page_buf_size = 0;
+ }
+}
+
+/* The following are need to implement virtual fonts
+ According to documentation, the vf "subroutine"
+ must have state pushed and must have
+ w,v,y, and z set to zero. The current font
+ is determined by the virtual font header, which
+ may be undefined */
+
+static int saved_dvi_font[VF_NESTING_MAX];
+static int num_saved_fonts = 0;
+
+void
+dvi_vf_init (int dev_font_id)
+{
+ dvi_push();
+
+ dvi_state.w = 0; dvi_state.x = 0;
+ dvi_state.y = 0; dvi_state.z = 0;
+
+ /* do not reset dvi_state.d. */
+ if (num_saved_fonts < VF_NESTING_MAX) {
+ saved_dvi_font[num_saved_fonts++] = current_font;
+ } else
+ ERROR("Virtual fonts nested too deeply!");
+ current_font = dev_font_id;
+}
+
+/* After VF subroutine is finished, we simply pop the DVI stack */
+void
+dvi_vf_finish (void)
+{
+ dvi_pop();
+ if (num_saved_fonts > 0)
+ current_font = saved_dvi_font[--num_saved_fonts];
+ else {
+ ERROR("Tried to pop an empty font stack");
+ }
+}
+
+
+/* Scan various specials */
+#include "dpxutil.h"
+/* For MAX_PWD_LEN */
+#include "pdfencrypt.h"
+
+static int
+scan_special_encrypt (int *key_bits, int32_t *permission, char *opassword, char *upassword,
+ const char **curptr, const char *endptr)
+{
+ int error = 0;
+ const char *p = *curptr;
+
+ skip_white(&p, endptr);
+
+ opassword[0] = '\0';
+ upassword[0] = '\0';
+ while (!error && p < endptr) {
+ char *kp = parse_c_ident(&p, endptr);
+ if (!kp)
+ break;
+ else {
+ pdf_obj *obj;
+ skip_white(&p, endptr);
+ if (!strcmp(kp, "ownerpw")) {
+ if ((obj = parse_pdf_string(&p, endptr))) {
+ if (pdf_string_value(obj)) {
+ int str_length = (MAX_PWD_LEN - 1 > pdf_string_length(obj)
+ ? pdf_string_length(obj) : MAX_PWD_LEN - 1);
+ strncpy(opassword, pdf_string_value(obj), str_length);
+ opassword[str_length] = '\0';
+ }
+ pdf_release_obj(obj);
+ } else
+ error = -1;
+ } else if (!strcmp(kp, "userpw")) {
+ if ((obj = parse_pdf_string(&p, endptr))) {
+ if (pdf_string_value(obj)) {
+ int str_length = (MAX_PWD_LEN - 1 > pdf_string_length(obj)
+ ? pdf_string_length(obj) : MAX_PWD_LEN - 1);
+ strncpy(upassword, pdf_string_value(obj), str_length);
+ upassword[str_length] = '\0';
+ }
+ pdf_release_obj(obj);
+ } else
+ error = -1;
+ } else if (!strcmp(kp, "length")) {
+ if ((obj = parse_pdf_number(&p, endptr)) && PDF_OBJ_NUMBERTYPE(obj)) {
+ *key_bits = (unsigned) pdf_number_value(obj);
+ } else
+ error = -1;
+ if (obj)
+ pdf_release_obj(obj);
+ } else if (!strcmp(kp, "perm")) {
+ if ((obj = parse_pdf_number(&p, endptr)) && PDF_OBJ_NUMBERTYPE(obj)) {
+ *permission = (unsigned) pdf_number_value(obj);
+ } else
+ error = -1;
+ if (obj)
+ pdf_release_obj(obj);
+ } else
+ error = -1;
+ RELEASE(kp);
+ }
+ skip_white(&p, endptr);
+ }
+ *curptr = p;
+
+ return error;
+}
+
+static int
+scan_special_trailerid (unsigned char *id1, unsigned char *id2,
+ const char **curptr, const char *endptr)
+{
+ int error = 0;
+ pdf_obj *id_array;
+ const char *p = *curptr;
+
+ skip_white(&p, endptr);
+ id_array = parse_pdf_array(&p, endptr, NULL);
+ if (id_array) {
+ if (pdf_array_length(id_array) == 2) {
+ pdf_obj *tmp1, *tmp2;
+ tmp1 = pdf_get_array(id_array, 0);
+ tmp2 = pdf_get_array(id_array, 1);
+ if (PDF_OBJ_STRINGTYPE(tmp1) && pdf_string_length(tmp1) == 16 &&
+ PDF_OBJ_STRINGTYPE(tmp2) && pdf_string_length(tmp2) == 16) {
+ memcpy(id1, pdf_string_value(tmp1), 16);
+ memcpy(id2, pdf_string_value(tmp2), 16);
+ } else {
+ error = -1;
+ }
+ } else {
+ error = -1;
+ }
+ pdf_release_obj(id_array);
+ } else {
+ error = -1;
+ }
+ skip_white(&p, endptr);
+ *curptr = p;
+
+ return error;
+}
+
+static int
+scan_special (double *wd, double *ht, double *xo, double *yo, int *lm,
+ int *majorversion, int *minorversion,
+ int *enable_encryption, int *key_bits, int32_t *permission,
+ char *opassword, char *upassword,
+ int *has_id, unsigned char *id1, unsigned char *id2,
+ const char *buf, uint32_t size)
+{
+ char *q;
+ const char *p = buf, *endptr;
+ int ns_pdf = 0, ns_dvipdfmx = 0, error = 0;
+ double tmp;
+
+ endptr = p + size;
+
+ skip_white(&p, endptr);
+
+ q = parse_c_ident(&p, endptr);
+ if (q && !strcmp(q, "pdf")) {
+ skip_white(&p, endptr);
+ if (p < endptr && *p == ':') {
+ p++;
+ skip_white(&p, endptr);
+ RELEASE(q);
+ q = parse_c_ident(&p, endptr); ns_pdf = 1;
+ }
+ }
+ else if (q && !strcmp(q, "x")) {
+ skip_white(&p, endptr);
+ if (p < endptr && *p == ':') {
+ p++;
+ skip_white(&p, endptr);
+ RELEASE(q);
+ q = parse_c_ident(&p, endptr);
+ }
+ }
+ else if (q && !strcmp(q, "dvipdfmx")) {
+ skip_white(&p, endptr);
+ if (p < endptr && *p == ':') {
+ p++;
+ skip_white(&p, endptr);
+ RELEASE(q);
+ q = parse_c_ident(&p, endptr); ns_dvipdfmx = 1;
+ }
+ }
+ skip_white(&p, endptr);
+
+ if (q) {
+ if (!strcmp(q, "landscape")) {
+ *lm = 1;
+ } else if (ns_pdf && !strcmp(q, "pagesize")) {
+ while (!error && p < endptr) {
+ char *kp = parse_c_ident(&p, endptr);
+ if (!kp)
+ break;
+ else {
+ skip_white(&p, endptr);
+ if (!strcmp(kp, "width")) {
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ if (!error)
+ *wd = tmp * dvi_tell_mag();
+ } else if (!strcmp(kp, "height")) {
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ if (!error)
+ *ht = tmp * dvi_tell_mag();
+ } else if (!strcmp(kp, "xoffset")) {
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ if (!error)
+ *xo = tmp * dvi_tell_mag();
+ } else if (!strcmp(kp, "yoffset")) {
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ if (!error)
+ *yo = tmp * dvi_tell_mag();
+ } else if (!strcmp(kp, "default")) {
+ *wd = paper_width;
+ *ht = paper_height;
+ *lm = landscape_mode;
+ *xo = *yo = 72.0;
+ }
+ RELEASE(kp);
+ }
+ skip_white(&p, endptr);
+ }
+ } else if (!strcmp(q, "papersize")) {
+ char qchr = 0;
+ if (*p == '=') p++;
+ skip_white(&p, endptr);
+ if (p < endptr && (*p == '\'' || *p == '\"')) {
+ qchr = *p; p++;
+ skip_white(&p, endptr);
+ }
+ error = dpx_util_read_length(&tmp, 1.0, &p, endptr);
+ if (!error) {
+ double tmp1;
+
+ skip_white(&p, endptr);
+ if (p < endptr && *p == ',') {
+ p++; skip_white(&p, endptr);
+ }
+ error = dpx_util_read_length(&tmp1, 1.0, &p, endptr);
+ if (!error) {
+ *wd = tmp;
+ *ht = tmp1;
+ skip_white(&p, endptr);
+ }
+ }
+ if (!error && qchr) { /* Check if properly quoted */
+ if (p >= endptr || *p != qchr)
+ error = -1;
+ }
+ if (error == 0) {
+ paper_width = *wd;
+ paper_height = *ht;
+ }
+ } else if (minorversion && ns_pdf && !strcmp(q, "minorversion")) {
+ char *kv;
+ if (*p == '=') p++;
+ skip_white(&p, endptr);
+ kv = parse_float_decimal(&p, endptr);
+ if (kv) {
+ *minorversion = (int)strtol(kv, NULL, 10);
+ RELEASE(kv);
+ }
+ } else if (majorversion && ns_pdf && !strcmp(q, "majorversion")) {
+ char *kv;
+ if (*p == '=') p++;
+ skip_white(&p, endptr);
+ kv = parse_float_decimal(&p, endptr);
+ if (kv) {
+ *majorversion = (int)strtol(kv, NULL, 10);
+ RELEASE(kv);
+ }
+ } else if (enable_encryption && ns_pdf && !strcmp(q, "encrypt")) {
+ *enable_encryption = 1;
+ error = scan_special_encrypt(key_bits, permission, opassword, upassword, &p, endptr);
+ } else if (ns_dvipdfmx && !strcmp(q, "config")) {
+ read_config_special(&p, endptr);
+ } else if (has_id && id1 && id2 && ns_pdf && !strcmp(q, "trailerid")) {
+ error = scan_special_trailerid(id1, id2, &p, endptr);
+ if (error) {
+ WARN("Invalid argument for pdf:trailerid special.");
+ *has_id = 0;
+ } else {
+ *has_id = 1;
+ }
+ }
+ RELEASE(q);
+ }
+
+ return error;
+}
+
+
+void
+dvi_scan_specials (int page_no,
+ double *page_width, double *page_height,
+ double *x_offset, double *y_offset, int *landscape,
+ int *majorversion, int *minorversion,
+ int *do_enc, int *key_bits, int32_t *permission,
+ char *owner_pw, char *user_pw,
+ int *has_id, unsigned char *id1, unsigned char *id2)
+{
+ FILE *fp = dvi_file;
+ int32_t offset;
+ unsigned char opcode;
+ static int buffered_page = -1;
+ unsigned int len;
+
+ if (page_no == buffered_page || num_pages == 0)
+ return; /* because dvipdfmx wants to scan first page twice! */
+ buffered_page = page_no;
+
+ dvi_page_buf_index = 0;
+
+ if (!linear) {
+ if (page_no >= num_pages)
+ ERROR("Invalid page number: %u", page_no);
+ offset = page_loc[page_no];
+
+ xseek_absolute (fp, offset, "DVI");
+ }
+
+ while ((opcode = get_and_buffer_unsigned_byte(fp)) != EOP) {
+ if (opcode <= SET_CHAR_127 ||
+ (opcode >= FNT_NUM_0 && opcode <= FNT_NUM_63))
+ continue;
+ else if (opcode == XXX1 || opcode == XXX2 ||
+ opcode == XXX3 || opcode == XXX4) {
+ uint32_t size = get_and_buffer_unsigned_byte(fp);
+ switch (opcode) {
+ case XXX4: size = size * 0x100u + get_and_buffer_unsigned_byte(fp);
+ if (size > 0x7fff)
+ WARN("Unsigned number starting with %x exceeds 0x7fffffff", size);
+ case XXX3: size = size * 0x100u + get_and_buffer_unsigned_byte(fp);
+ case XXX2: size = size * 0x100u + get_and_buffer_unsigned_byte(fp);
+ default: break;
+ }
+ if (dvi_page_buf_index + size >= dvi_page_buf_size) {
+ dvi_page_buf_size = (dvi_page_buf_index + size + DVI_PAGE_BUF_CHUNK);
+ dvi_page_buffer = RENEW(dvi_page_buffer, dvi_page_buf_size, unsigned char);
+ }
+#define buf ((char*)(dvi_page_buffer + dvi_page_buf_index))
+ if (fread(buf, sizeof(char), size, fp) != size)
+ ERROR("Reading DVI file failed!");
+ if (scan_special(page_width, page_height, x_offset, y_offset, landscape,
+ majorversion, minorversion,
+ do_enc, key_bits, permission, owner_pw, user_pw,
+ has_id, id1, id2,
+ buf, size))
+ WARN("Reading special command failed: \"%.*s\"", size, buf);
+#undef buf
+ dvi_page_buf_index += size;
+ continue;
+ }
+
+ /* Skipping... */
+ switch (opcode) {
+ case BOP:
+ get_and_buffer_bytes(fp, 44);
+ break;
+ case NOP: case PUSH: case POP:
+ case W0: case X0: case Y0: case Z0:
+ break;
+ case SET1: case PUT1: case RIGHT1: case DOWN1:
+ case W1: case X1: case Y1: case Z1: case FNT1:
+ get_and_buffer_bytes(fp, 1);
+ break;
+
+ case SET2: case PUT2: case RIGHT2: case DOWN2:
+ case W2: case X2: case Y2: case Z2: case FNT2:
+ get_and_buffer_bytes(fp, 2);
+ break;
+
+ case SET3: case PUT3: case RIGHT3: case DOWN3:
+ case W3: case X3: case Y3: case Z3: case FNT3:
+ get_and_buffer_bytes(fp, 3);
+ break;
+
+ case SET4: case PUT4: case RIGHT4: case DOWN4:
+ case W4: case X4: case Y4: case Z4: case FNT4:
+ get_and_buffer_bytes(fp, 4);
+ break;
+
+ case SET_RULE: case PUT_RULE:
+ get_and_buffer_bytes(fp, 8);
+ break;
+
+ case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
+ do_fntdef(get_unsigned_num(fp, opcode-FNT_DEF1));
+ break;
+ case XDV_GLYPHS:
+ need_XeTeX(opcode);
+ get_and_buffer_bytes(fp, 4); /* width */
+ len = get_and_buffer_unsigned_pair(fp); /* glyph count */
+ get_and_buffer_bytes(fp, len * 10); /* 2 bytes ID + 8 bytes x,y-location per glyph */
+ break;
+ case XDV_TEXT_AND_GLYPHS:
+ need_XeTeX(opcode);
+ len = get_and_buffer_unsigned_pair(fp); /* utf16 code unit count */
+ get_and_buffer_bytes(fp, len * 2); /* 2 bytes per code unit */
+ get_and_buffer_bytes(fp, 4); /* width */
+ len = get_and_buffer_unsigned_pair(fp); /* glyph count */
+ get_and_buffer_bytes(fp, len * 10); /* 2 bytes ID + 8 bytes x,y-location per glyph */
+ break;
+ case XDV_NATIVE_FONT_DEF:
+ need_XeTeX(opcode);
+ do_native_font_def(get_signed_quad(dvi_file));
+ break;
+ case BEGIN_REFLECT:
+ case END_REFLECT:
+ need_XeTeX(opcode);
+ break;
+
+ case PTEXDIR:
+ need_pTeX(opcode);
+ get_and_buffer_bytes(fp, 1);
+ break;
+
+ case POST:
+ if (linear && dvi_page_buf_index == 1) {
+ /* this is actually an indication that we've reached the end of the input */
+ return;
+ }
+ /* else fall through to error case */
+ default: /* case PRE: case POST_POST: and others */
+ ERROR("Unexpected opcode %d at pos=0x%x", opcode, tell_position(fp));
+ break;
+ }
+ }
+
+ return;
+}
+#if defined(LIBDPX)
+#include "dvi_ng.c"
+#endif /* LIBDPX */
diff --git a/Build/source/texk/dvipdfm-x/dvi.h b/Build/source/texk/dvipdfm-x/dvi.h
new file mode 100644
index 00000000000..569a30c1087
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dvi.h
@@ -0,0 +1,111 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _DVI_H_
+#define _DVI_H_
+
+#include "error.h"
+#include "numbers.h"
+/* spt_t */
+#include "pdfdev.h"
+
+/* instantiated in dvipdfmx.c */
+extern double paper_width, paper_height;
+extern int landscape_mode;
+
+extern double get_origin (int x);
+
+/* returns scale (dvi2pts) */
+extern double dvi_init (char *dvi_filename, double mag); /* may append .dvi or .xdv to filename */
+extern void dvi_close (void); /* Closes data structures created by dvi_open */
+
+extern double dvi_tell_mag (void);
+extern double dvi_unit_size (void);
+extern double dvi_dev_xpos (void);
+extern double dvi_dev_ypos (void);
+extern unsigned int dvi_npages (void);
+extern const char *dvi_comment (void);
+
+extern void dvi_vf_init (int dev_font_id);
+extern void dvi_vf_finish (void);
+
+extern void dvi_set_font (int font_id);
+extern void dvi_set (int32_t ch);
+extern void dvi_rule (int32_t width, int32_t height);
+
+extern void dvi_right (int32_t x);
+extern void dvi_put (int32_t ch);
+extern void dvi_push (void);
+extern void dvi_pop (void);
+extern void dvi_w0 (void);
+extern void dvi_w (int32_t ch);
+extern void dvi_x0 (void);
+extern void dvi_x (int32_t ch);
+extern void dvi_down (int32_t y);
+extern void dvi_y (int32_t ch);
+extern void dvi_y0 (void);
+extern void dvi_z (int32_t ch);
+extern void dvi_z0 (void);
+extern void dvi_dirchg(unsigned char dir);
+
+extern void dvi_do_page (double paper_height, double x_offset, double y_offset);
+extern void dvi_scan_specials (int page_no,
+ double *width, double *height,
+ double *x_offset, double *y_offset, int *landscape,
+ int *majorversion, int *minorversion,
+ int *do_enc, int *keybits, int32_t *perm,
+ char *opasswd, char *upasswd, int *has_id, unsigned char *id1, unsigned char *id2);
+extern int dvi_locate_font (const char *name, spt_t ptsize);
+
+/* link or nolink:
+ * See dvipdfm (not x) user's manual on pdf:link and pdf:nolink.
+ * This is workaround for preventing inclusion of pagenation artifact such as
+ * footnote and page number in link annotation.
+ */
+extern void dvi_link_annot (int flag);
+
+/* linkmode
+ * To capture \phantom's, DVI "right" instructions are also taken into
+ * account in calculation of annotaion rectangle.
+ * Mode 1 for catching phantoms.
+ * dvi_set_phantom_height() specifies the height of phantom box (default
+ * is the current font size).
+ */
+extern void dvi_set_linkmode (int mode);
+extern void dvi_set_phantom_height (double height, double depth);
+
+/* The followings are for calculating bounding box of text for annotation.
+ * DVI uses push/pop to do line-feed-carriage-return. So line breaking is
+ * handled by inspecting current depth of DVI register stack.
+ */
+extern void dvi_tag_depth (void);
+extern void dvi_untag_depth (void);
+extern void dvi_compute_boxes (int flag);
+
+extern void dvi_do_special (const void *buffer, int32_t size);
+
+/* allow other modules (pdfdev) to ask whether we're collecting box areas */
+extern int dvi_is_tracking_boxes(void);
+
+extern void dvi_set_compensation (double x, double y);
+
+#endif /* _DVI_H_ */
diff --git a/Build/source/texk/dvipdfm-x/dvicodes.h b/Build/source/texk/dvipdfm-x/dvicodes.h
new file mode 100644
index 00000000000..34f09831898
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dvicodes.h
@@ -0,0 +1,130 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _DVICODES_H_
+#define _DVICODES_H_
+
+/* DVI op codes */
+#define SET_CHAR_0 0
+#define SET_CHAR_1 1
+/* etc. */
+#define SET_CHAR_127 127
+#define SET1 128 /* Typesets its single operand between 128 and 255 */
+#define SET2 129 /* Typesets its single two byte unsigned operand */
+#define SET3 130 /* Typesets its single three byte unsigned operand */
+#define SET4 131 /* Typesets its single four byte signed operand */
+#define SET_RULE 132 /* Sets a rule of height param1(four bytes) and width param2(four bytes) */
+ /* These are *signed*. Nothing typeset for nonpositive values */
+ /* However, negative value *do* change current point */
+#define PUT1 133 /* Like SET1, but point doesn't change */
+#define PUT2 134 /* Like SET2 */
+#define PUT3 135 /* Like SET3 */
+#define PUT4 136 /* Like SET4 */
+#define PUT_RULE 137 /* Like SET_RULE */
+#define NOP 138
+#define BOP 139 /* Followed by 10 four byte count registers (signed?). Last parameter points to */
+ /* previous BOP (backward linked, first BOP has -1). BOP clears stack and resets current point. */
+#define EOP 140
+#define PUSH 141 /* Pushes h,v,w,x,y,z */
+#define POP 142 /* Opposite of push*/
+#define RIGHT1 143 /* Move right by one byte signed operand */
+#define RIGHT2 144 /* Move right by two byte signed operand */
+#define RIGHT3 145 /* Move right by three byte signed operand */
+#define RIGHT4 146 /* Move right by four byte signed operand */
+#define W0 147 /* Move right w */
+#define W1 148 /* w <- single byte signed operand. Move right by same amount */
+#define W2 149 /* Same as W1 with two byte signed operand */
+#define W3 150 /* Three byte signed operand */
+#define W4 151 /* Four byte signed operand */
+#define X0 152 /* Move right x */
+#define X1 153 /* Like W1 */
+#define X2 154 /* Like W2 */
+#define X3 155 /* Like W3 */
+#define X4 156 /* Like W4 */
+#define DOWN1 157 /* Move down by one byte signed operand */
+#define DOWN2 158 /* Two byte signed operand */
+#define DOWN3 159 /* Three byte signed operand */
+#define DOWN4 160 /* Four byte signed operand */
+#define Y0 161 /* Move down by y */
+#define Y1 162 /* Move down by one byte signed operand, which replaces Y */
+#define Y2 163 /* Two byte signed operand */
+#define Y3 164 /* Three byte signed operand */
+#define Y4 165 /* Four byte signed operand */
+#define Z0 166 /* Like Y0, but use z */
+#define Z1 167 /* Like Y1 */
+#define Z2 168 /* Like Y2 */
+#define Z3 169 /* Like Y3 */
+#define Z4 170 /* Like Y4 */
+#define FNT_NUM_0 171 /* Switch to font 0 */
+#define FNT_NUM_1 172 /* Switch to font 1 */
+/* etc. */
+#define FNT_NUM_63 234 /* Switch to font 63 */
+#define FNT1 235 /* Switch to font described by single byte unsigned operand */
+#define FNT2 236 /* Switch to font described by two byte unsigned operand */
+#define FNT3 237 /* Three byte font descriptor */
+#define FNT4 238 /* Four byte operator (Knuth says signed, but what would be the point? */
+#define XXX1 239 /* Special. Operand is one byte length. Special follows immediately */
+#define XXX2 240 /* Two byte operand */
+#define XXX3 241 /* Three byte operand */
+#define XXX4 242 /* Four byte operand (Knuth says TeX uses only XXX1 and XXX4 */
+#define FNT_DEF1 243 /* One byte font number, four byte checksum, four byte magnified size (DVI units),
+ four byte designed size, single byte directory length, single byte name length,
+ followed by complete name (area+name) */
+#define FNT_DEF2 244 /* Same for two byte font number */
+#define FNT_DEF3 245 /* Same for three byte font number */
+#define FNT_DEF4 246 /* Four byte font number (Knuth says signed) */
+#define PRE 247 /* Preamble:
+ one byte DVI version (should be 2)
+ four byte unsigned numerator
+ four byte unsigned denominator -- one DVI unit = den/num*10^(-7) m
+ four byte magnification (multiplied by 1000)
+ one byte unsigned comment length followed by comment. */
+#define DVI_ID 2 /* ID Byte for current DVI file */
+#define DVIV_ID 3 /* with Ascii pTeX VW mode extension */
+#define XDV_ID_OLD 6 /* older XeTeX ".xdv" output that does not have XDV_TEXT_AND_GLYPHS */
+#define XDV_ID 7 /* XeTeX ".xdv" output that uses XDV opcodes below */
+#define POST 248 /* Postamble- -- similar to preamble
+ four byte pointer to final bop
+ four byte numerator
+ four byte denominator
+ four byte mag
+ four byte maximum height (signed?)
+ four byte maximum width
+ two byte max stack depth required to process file
+ two byte number of pages */
+#define POST_POST 249 /* End of postamble
+ four byte pointer to POST command
+ Version byte (same as preamble)
+ Padded by four or more 223's to the end of the file. */
+#define PADDING 223
+
+#define BEGIN_REFLECT 250 /* TeX-XeT begin_reflect */
+#define END_REFLECT 251 /* TeX-XeT end_reflect */
+
+ /* XeTeX ".xdv" codes */
+#define XDV_NATIVE_FONT_DEF 252 /* fontdef for native platform font */
+#define XDV_GLYPHS 253 /* string of glyph IDs with X and Y positions */
+#define XDV_TEXT_AND_GLYPHS 254 /* like XDV_GLYPHS plus original Unicode text */
+
+#define PTEXDIR 255 /* Ascii pTeX DIR command */
+
+#endif /* _DVICODES_H_ */
diff --git a/Build/source/texk/dvipdfm-x/dvipdfmx-upjf.test b/Build/source/texk/dvipdfm-x/dvipdfmx-upjf.test
new file mode 100755
index 00000000000..8fe96839710
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dvipdfmx-upjf.test
@@ -0,0 +1,38 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2020 Japanese TeX Development Community <issue@texjp.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+TEXFONTS="$srcdir/tests;."
+SOURCE_DATE_EPOCH=1588474800
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS TEXFONTS SOURCE_DATE_EPOCH
+
+failed=
+
+echo "*** dvipdfmx: test for upjf_full.pdf" && echo \
+ && cp $srcdir/tests/upjf_full.vf ./upjf.vf \
+ && ./xdvipdfmx --dvipdfmx -vv -f upjf.map -o upjf.pdf $srcdir/tests/upjf.dvi \
+ && mv ./upjf.pdf ./upjf_full.pdf \
+ && echo && echo "dvipdfmx-upjf-vf_full tests OK" && echo \
+ || failed="$failed dvipdfmx-upjf-vf_full"
+
+echo "*** dvipdfmx: test for upjf_omit.pdf" && echo \
+ && cp $srcdir/tests/upjf_omit.vf ./upjf.vf \
+ && ./xdvipdfmx --dvipdfmx -vv -f upjf.map -o upjf.pdf $srcdir/tests/upjf.dvi \
+ && mv ./upjf.pdf ./upjf_omit.pdf \
+ && echo && echo "dvipdfmx-upjf-vf_omit tests OK" && echo \
+ || failed="$failed dvipdfmx-upjf-vf_omit"
+
+cmp ./upjf_full.pdf ./upjf_omit.pdf || failed="$failed dvipdfmx-upjf-cmp"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/dvipdfmx.c b/Build/source/texk/dvipdfm-x/dvipdfmx.c
new file mode 100644
index 00000000000..f56c1d44ed3
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dvipdfmx.c
@@ -0,0 +1,1252 @@
+/* This is (x)dvipdfmx, an extended version of...
+
+ DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+ the DVIPDFMx project team.
+
+ Copyright (c) 2006 SIL. (xdvipdfmx extensions for XeTeX support)
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+
+#include "system.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+#include "dpxfile.h"
+#include "dpxutil.h"
+#include "dpxcrypt.h"
+
+#include "dvi.h"
+
+#include "pdflimits.h"
+#include "pdfdoc.h"
+#include "pdfdev.h"
+#include "pdfparse.h"
+#include "pdfencrypt.h"
+
+#include "spc_tpic.h"
+#include "specials.h"
+
+#include "mpost.h"
+
+#include "fontmap.h"
+#include "pdffont.h"
+#include "pdfximage.h"
+#include "cid.h"
+
+#include "dvipdfmx.h"
+#include "tt_aux.h"
+
+#include "error.h"
+
+#if defined(LIBDPX)
+const char *my_name = "ApTeX";
+#else
+const char *my_name;
+#endif /* LIBDPX */
+
+/* Verbosity level */
+static int verbose = 0;
+static int really_quiet = 0;
+
+/* Compatibility option flags */
+static int opt_flags = 0;
+#define OPT_TPIC_TRANSPARENT_FILL (1 << 1)
+#define OPT_CIDFONT_FIXEDPITCH (1 << 2)
+#define OPT_FONTMAP_FIRST_MATCH (1 << 3)
+#define OPT_PDFDOC_NO_DEST_REMOVE (1 << 4)
+#define OPT_PDFOBJ_NO_PREDICTOR (1 << 5)
+#define OPT_PDFOBJ_NO_OBJSTM (1 << 6)
+
+/* Basic PDF output settings */
+static int pdf_version_major = 1;
+static int pdf_version_minor = 5;
+static int compression_level = 9;
+
+/* PDF document navigation feature settings */
+static double annot_grow_x = 0.0;
+static double annot_grow_y = 0.0;
+static int bookmark_open = 0;
+static double mag = 1.0;
+static int enable_thumbnail = 0;
+
+static int font_dpi = 600;
+
+/* PDF output device settings */
+static int pdfdecimaldigits = 3;
+static char ignore_colors = 0;
+
+/* Image cache life in hours
+ * 0 means erase all old images and leave new images
+ * -1 means erase all old images and also erase new images
+ * -2 means ignore image cache (default)
+ */
+static int image_cache_life = -2;
+/* Image format conversion filter template */
+static char *filter_template = NULL;
+
+/* Encryption */
+static int do_encryption = 0;
+static int key_bits = 40;
+static int32_t permission = 0x003C;
+
+/* Page device */
+double paper_width = 595.0;
+double paper_height = 842.0;
+static double x_offset = 72.0;
+static double y_offset = 72.0;
+int landscape_mode = 0;
+static int translate_origin = 0;
+
+static int has_paper_option = 0;
+
+/* Input and output filenames */
+static char *dvi_filename = NULL, *pdf_filename = NULL;
+
+static void read_config_file (const char *config);
+
+static void
+set_default_pdf_filename (void)
+{
+ const char *dvi_base;
+ const char *suffix;
+ size_t len = 0;
+
+ dvi_base = xbasename(dvi_filename);
+
+ suffix = strrchr(dvi_base, '.');
+ /* suffix can be dvi_base if dvi_base is like ".abcde" */
+
+ if (suffix == NULL || suffix == dvi_base) {
+ suffix = dvi_base + strlen(dvi_base);
+ }
+ len = strlen(dvi_base) - strlen(suffix);
+
+ if (dpx_conf.compat_mode == dpx_mode_mpost_mode &&
+ FILESTRCASEEQ(".mps", suffix)) {
+ pdf_filename = NEW(len+strlen(".pdf")+1, char);
+ strncpy(pdf_filename, dvi_base, len);
+ pdf_filename[len] = '\0';
+ } else if ((FILESTRCASEEQ(".dvi", suffix) ||
+ FILESTRCASEEQ(".xdv", suffix))) {
+ pdf_filename = NEW(len+strlen(".pdf")+1, char);
+ strncpy(pdf_filename, dvi_base, len);
+ pdf_filename[len] = '\0';
+ } else {
+ pdf_filename = NEW(strlen(dvi_base)+strlen(".pdf")+1, char);
+ strcpy(pdf_filename, dvi_base);
+ }
+
+ strcat (pdf_filename, ".pdf");
+}
+
+static void
+show_version (void)
+{
+ printf ("This is %s Version " VERSION " by the DVIPDFMx project team,\n",
+ my_name);
+ printf ("modified for TeX Live,\n");
+ if (*my_name == 'x')
+ printf ("an extended version of DVIPDFMx, which in turn was\n");
+ printf ("an extended version of dvipdfm-0.13.2c developed by Mark A. Wicks.\n");
+ printf ("\nCopyright (C) 2002-2021 the DVIPDFMx project team\n");
+ printf ("Copyright (C) 2006-2021 SIL International.\n");
+ printf ("\nThis is free software; you can redistribute it and/or modify\n");
+ printf ("it under the terms of the GNU General Public License as published by\n");
+ printf ("the Free Software Foundation; either version 2 of the License, or\n");
+ printf ("(at your option) any later version.\n");
+}
+
+static void
+show_usage (void)
+{
+ printf ("\nUsage: %s [OPTION]... [DVIFILE[.dvi|.xdv]]\n", my_name);
+ printf (" %s --extractbb|--xbb|--ebb [OPTION]...\tBe \"extractbb\"\n",
+ my_name);
+ printf (" %s --help|--showpaper|--version\n", my_name);
+ printf ("Convert DVI or XDV input to PDF; defaults given below.\n");
+ printf ("\nOptions:\n");
+ printf (" -c \t\tIgnore color specials (for B&W printing)\n");
+ printf (" --dvipdfm\tEnable DVIPDFM emulation mode\n");
+ printf (" -d number\tSet PDF decimal digits (0-5) [3]\n");
+ printf (" -f filename\tLoad additional font map filename[.map]\n");
+ printf (" -g dimension\tAnnotation \"grow\" amount [0.0in]\n");
+ printf (" -h | --help \tShow this help message and exit\n");
+ printf (" -l \t\tLandscape mode\n");
+ printf (" -m number\tSet additional magnification [1.0]\n");
+ printf (" --mvorigin\tTranslate the origin for MP inclusion\n");
+ printf (" -o filename\tSet output file name, \"-\" for stdout [DVIFILE.pdf]\n");
+ printf (" -p papersize\tSet papersize [a4]\n");
+ printf (" -q \t\tBe quiet\n");
+ printf (" -r resolution\tSet resolution (in DPI) for raster fonts [600]\n");
+ printf (" -s pages\tSelect page ranges [all pages]\n");
+ printf (" --showpaper\tShow available paper formats and exit\n");
+ printf (" -t \t\tEmbed thumbnail images of PNG format (DVIFILE.pageno, pageno=int) \n");
+ printf (" --version\tOutput version information and exit\n");
+ printf (" -v \t\tBe verbose\n");
+ printf (" -vv\t\tBe more verbose\n");
+ printf (" --kpathsea-debug number\tSet kpathsea debugging flags [0]\n");
+ printf (" -x dimension\tSet horizontal offset [1.0in]\n");
+ printf (" -y dimension\tSet vertical offset [1.0in]\n");
+ printf (" -z number \tSet zlib compression level (0-9) [9]\n");
+
+ printf (" -C number\tSpecify miscellaneous option flags [0]:\n");
+ printf ("\t\t 0x0001 reserved\n");
+ printf ("\t\t 0x0002 Use semi-transparent filling for tpic shading command,\n");
+ printf ("\t\t\t instead of opaque gray color; requires PDF 1.4.\n");
+ printf ("\t\t 0x0004 Treat all CIDFont as fixed-pitch font.\n");
+ printf ("\t\t 0x0008 Do not replace duplicate fontmap entries.\n");
+ printf ("\t\t 0x0010 Do not optimize PDF destinations.\n");
+ printf ("\t\t 0x0020 Do not use predictor filter for Flate compression.\n");
+ printf ("\t\t 0x0040 Do not use object stream.\n");
+ printf ("\t\tPositive values are always ORed with previously given flags.\n");
+ printf ("\t\tAnd negative values replace old values.\n");
+ printf (" -D template\tPS->PDF conversion command line template [none]\n");
+ printf (" -E \t\tAlways try to embed fonts, regardless of licensing flags.\n");
+ printf (" -I number\tImage cache life in hours [-2]\n");
+ printf (" \t 0: erase all old images and leave new images\n");
+ printf (" \t-1: erase all old images and also erase new images\n");
+ printf (" \t-2: ignore image cache\n");
+ printf (" -K number\tEncryption key length [40]\n");
+ printf (" -M \t\tProcess MetaPost PostScript output\n");
+ printf (" -O number\tSet maximum depth of open bookmark items [0]\n");
+ printf (" -P number\tSet permission flags for PDF encryption [0x003C]\n");
+ printf (" -S \t\tEnable PDF encryption\n");
+ printf (" -V number\tSet PDF version [%d.%d]\n",
+ PDF_VERSION_DEFAULT/10,PDF_VERSION_DEFAULT%10);
+ printf ("\nAll dimensions entered on the command line are \"true\" TeX dimensions.\n");
+ printf ("Argument of \"-s\" lists physical page ranges separated by commas,\n");
+ printf ("\te.g., \"-s 1-3,5-6\".\n");
+ printf ("Papersize is specified by paper format (e.g., \"a4\")\n");
+ printf ("\tor by w<unit>,h<unit> (e.g., \"20cm,30cm\").\n");
+ printf ("\n");
+ printf ("Email bug reports to dvipdfmx@tug.org.\n");
+}
+
+static void
+usage (void)
+{
+ fprintf (stderr, "\nTry \"%s --help\" for more information.\n", my_name);
+ exit(1);
+}
+
+static void
+select_paper (const char *paperspec)
+{
+ const struct paper *pi;
+ int error = 0;
+
+ pi = paperinfo(paperspec);
+ if (pi && papername(pi)) {
+ paper_width = paperpswidth (pi);
+ paper_height = paperpsheight(pi);
+ } else {
+ const char *p = paperspec, *endptr, *comma;
+ comma = strchr(p, ',');
+ endptr = p + strlen(p);
+ if (!comma)
+ ERROR("Unrecognized paper format: %s", paperspec);
+ error = dpx_util_read_length(&paper_width, 1.0, &p, comma);
+ p = comma + 1;
+ error = dpx_util_read_length(&paper_height, 1.0, &p, endptr);
+ }
+ if (error || paper_width <= 0.0 || paper_height <= 0.0)
+ ERROR("Invalid paper size: %s (%.2fx%.2f)", paperspec, paper_width, paper_height);
+}
+
+struct page_range
+{
+ int first, last;
+} *page_ranges = NULL;
+
+int num_page_ranges = 0;
+int max_page_ranges = 0;
+
+static void
+select_pages (const char *pagespec)
+{
+ char *q;
+ const char *p = pagespec;
+
+ while (*p != '\0') {
+ /* Enlarge page range table if necessary */
+ if (num_page_ranges >= max_page_ranges) {
+ max_page_ranges += 4;
+ page_ranges = RENEW(page_ranges, max_page_ranges, struct page_range);
+ }
+
+ page_ranges[num_page_ranges].first = 0;
+ page_ranges[num_page_ranges].last = 0;
+
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ q = parse_unsigned(&p, p + strlen(p)); /* Can't be signed. */
+ if (q) { /* '-' is allowed here */
+ page_ranges[num_page_ranges].first = atoi(q) - 1;
+ page_ranges[num_page_ranges].last = page_ranges[num_page_ranges].first;
+ RELEASE(q);
+ }
+ for ( ; *p && isspace((unsigned char)*p); p++);
+
+ if (*p == '-') {
+ for (++p; *p && isspace((unsigned char)*p); p++);
+ page_ranges[num_page_ranges].last = -1;
+ if (*p) {
+ q = parse_unsigned(&p, p + strlen(p));
+ if (q) {
+ page_ranges[num_page_ranges].last = atoi(q) - 1;
+ RELEASE(q);
+ }
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ }
+ } else {
+ page_ranges[num_page_ranges].last = page_ranges[num_page_ranges].first;
+ }
+
+ num_page_ranges++;
+
+ if (*p == ',')
+ p++;
+ else {
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ if (*p)
+ ERROR("Bad page range specification: %s", p);
+ }
+ }
+ return;
+}
+
+/* Ask passwords for encryption */
+#ifdef WIN32
+/* Broken on mintty? */
+#include <conio.h>
+#define getch _getch
+static char *
+getpass (const char *prompt)
+{
+ static char pwd_buf[MAX_PWD_LEN];
+ size_t i;
+
+ fputs(prompt, stderr);
+ fflush(stderr);
+ for (i = 0; i < sizeof(pwd_buf)-1; i++) {
+ pwd_buf[i] = getch();
+ if (pwd_buf[i] == '\r' || pwd_buf[i] == '\n')
+ break;
+ fputs("*", stderr);
+ fflush(stderr);
+ }
+ pwd_buf[i] = '\0';
+ fputs("\n", stderr);
+ return pwd_buf;
+}
+#else /* !WIN32 */
+#include <unistd.h>
+#endif /* WIN32 */
+
+static int
+get_enc_password (char *oplain, char *uplain)
+{
+ char *retry_passwd;
+
+ while (1) {
+ strncpy(oplain, getpass("Owner password: "), MAX_PWD_LEN);
+ retry_passwd = getpass("Re-enter owner password: ");
+ if (!strncmp(oplain, retry_passwd, MAX_PWD_LEN))
+ break;
+ fputs("Password is not identical.\nTry again.\n", stderr);
+ fflush(stderr);
+ }
+ while (1) {
+ strncpy(uplain, getpass("User password: "), MAX_PWD_LEN);
+ retry_passwd = getpass("Re-enter user password: ");
+ if (!strncmp(uplain, retry_passwd, MAX_PWD_LEN))
+ break;
+ fputs("Password is not identical.\nTry again.\n", stderr);
+ fflush(stderr);
+ }
+
+ return 0;
+}
+
+static void
+compute_id_string (unsigned char *id, const char *producer,
+ const char *dviname, const char *pdfname)
+{
+ char datestr[32];
+ MD5_CONTEXT md5;
+
+ MD5_init(&md5);
+ /* Don't use timezone for compatibility */
+ dpx_util_format_asn_date(datestr, 0);
+ MD5_write(&md5, (const unsigned char *)datestr, strlen(datestr));
+ if (producer)
+ MD5_write(&md5, (const unsigned char *)producer, strlen(producer));
+ if (dviname)
+ MD5_write(&md5, (const unsigned char *)dviname, strlen(dviname));
+ if (pdfname)
+ MD5_write(&md5, (const unsigned char *)pdfname, strlen(pdfname));
+ MD5_final(id, &md5);
+}
+
+static const char *optstrig = ":hD:r:m:g:x:y:o:s:p:clf:i:qtvV:z:d:I:K:P:O:MSC:Ee";
+
+static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 130},
+ {"showpaper", 0, 0, 131},
+ {"dvipdfm", 0, 0, 132},
+ {"mvorigin", 0, 0, 1000},
+ {"kpathsea-debug", 1, 0, 133},
+ {0, 0, 0, 0}
+};
+
+static void
+do_args_first_pass (int argc, char *argv[], const char *source, int unsafe)
+{
+ int c;
+
+ optind = 1;
+ while ((c = getopt_long(argc, argv, optstrig, long_options, NULL)) != -1) {
+ switch(c) {
+ case 'h':
+ show_usage();
+ exit(0);
+ break;
+
+ case 130: /* --version */
+ show_version();
+ exit(0);
+ break;
+
+ case 131: /* --showpaper */
+ dumppaperinfo();
+ exit(0);
+ break;
+
+ case 132: /* --dvipdfm */
+ dpx_conf.compat_mode = dpx_mode_compat_mode;
+ break;
+
+ case 133: /* --kpathsea-debug */
+ kpathsea_debug = atoi(optarg);
+ break;
+
+ case 1000: /* --mvorigin */
+ translate_origin = 1;
+ break;
+
+ case 'q':
+ really_quiet = 2;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ case 'M':
+ dpx_conf.compat_mode = dpx_mode_mpost_mode;
+ break;
+
+ /* 'm' option placed here since other options set via special
+ * requires magnification already being determined for interpreting
+ * various length values.
+ */
+ case 'm':
+ {
+ char *nextptr;
+ if ((mag = strtod(optarg, &nextptr)) < 0.0 || nextptr == optarg)
+ ERROR("Invalid magnification specified: %s", optarg);
+ }
+ break;
+
+ default: /* ignore everything else */
+ break;
+ }
+ }
+
+ if (really_quiet)
+ shut_up(really_quiet);
+ else {
+ int i;
+
+ for (i = 0; i < verbose; i++) {
+ dpx_conf.verbose_level++;
+ }
+ }
+
+ if (argc > optind + 1) {
+ fprintf(stderr, "%s: Multiple dvi filenames?", my_name);
+ usage();
+ } else if (argc > optind) { /* last argument */
+ dvi_filename = NEW(strlen(argv[optind]) + 5, char); /* space to append ".dvi" */
+ strcpy(dvi_filename, argv[optind]);
+ }
+}
+
+/* Set "unsafe" to non-zero value when parsing config specials to
+ * disallow overriding "D" option value.
+ */
+static void
+do_args_second_pass (int argc, char *argv[], const char *source, int unsafe)
+{
+ int c, error = 0;
+ char *nextptr;
+ const char *nnextptr;
+
+ optind = 1;
+ while ((c = getopt_long(argc, argv, optstrig, long_options, NULL)) != -1) {
+ switch(c) {
+ case 'h': case 130: case 131: case 132: case 133: case 1000: case 'q': case 'v': case 'M': /* already done */
+ break;
+
+ /* 'm' option handled in first_pass */
+ case 'm':
+ if (unsafe) { /* FIXME: it's not actually 'unsafe'... just to know it's called from special */
+ WARN("Ignoring \"m\" option for dvipdfmx:config special. (too late)");
+ }
+ break;
+
+ case 'D':
+ if (unsafe) {
+ WARN("Ignoring \"D\" option for dvipdfmx:config special. (unsafe)");
+ } else {
+ if (filter_template)
+ RELEASE(filter_template);
+ filter_template = NEW(strlen(optarg)+1, char);
+ strcpy(filter_template, optarg);
+ }
+ break;
+
+ case 'r':
+ if ((font_dpi = atoi(optarg)) <= 0)
+ ERROR("Invalid bitmap font dpi specified: %s", optarg);
+ break;
+
+ case 'g':
+ nnextptr = nextptr = optarg;
+ {
+ const char *comma;
+
+ comma = strchr(optarg, ',');
+ if (comma) {
+ error = dpx_util_read_length(&annot_grow_x, 1.0, &nnextptr, comma);
+ nnextptr = comma + 1;
+ if (!error)
+ error = dpx_util_read_length(&annot_grow_y, 1.0, &nnextptr, nextptr + strlen(nextptr));
+ } else {
+ error = dpx_util_read_length(&annot_grow_x, 1.0, &nnextptr, nextptr + strlen(nextptr));
+ if (!error)
+ annot_grow_y = annot_grow_x;
+ }
+ if (error) {
+ WARN("Error reading argument for \"-g\" option: %s", optarg);
+ }
+ }
+ break;
+
+ case 'x':
+ nnextptr = nextptr = optarg;
+ dpx_util_read_length(&x_offset, 1.0, &nnextptr, nextptr + strlen(nextptr));
+ break;
+
+ case 'y':
+ nnextptr = nextptr = optarg;
+ dpx_util_read_length(&y_offset, 1.0, &nnextptr, nextptr + strlen(nextptr));
+ break;
+
+ case 'o':
+ pdf_filename = NEW (strlen(optarg)+1, char);
+ strcpy(pdf_filename, optarg);
+ break;
+
+ case 's':
+ select_pages(optarg);
+ break;
+
+ case 't':
+ enable_thumbnail = 1;
+ break;
+
+ case 'p':
+ select_paper(optarg);
+ has_paper_option = 1;
+ break;
+
+ case 'c':
+ ignore_colors = 1;
+ break;
+
+ case 'l':
+ landscape_mode = 1;
+ break;
+
+ case 'f':
+ if (opt_flags & OPT_FONTMAP_FIRST_MATCH)
+ pdf_load_fontmap_file(optarg, FONTMAP_RMODE_APPEND);
+ else
+ pdf_load_fontmap_file(optarg, FONTMAP_RMODE_REPLACE);
+ break;
+
+ case 'i':
+ {
+ int optind_save= optind;
+ read_config_file(optarg);
+ optind = optind_save;
+ break;
+ }
+
+ case 'V':
+ {
+ if (strchr(optarg, '.')) { /* new format X.X */
+ double tmp = atof(optarg);
+ pdf_version_major = (int) tmp;
+ pdf_version_minor = (int) (10 * (tmp - pdf_version_major) + 0.5);
+ } else {
+ pdf_version_major = 1;
+ pdf_version_minor = atoi(optarg);
+ }
+ break;
+ }
+
+ case 'z':
+ compression_level = atoi(optarg);
+ break;
+
+ case 'd':
+ pdfdecimaldigits = atoi(optarg);
+ break;
+
+ case 'I':
+ image_cache_life = atoi(optarg);
+ break;
+
+ case 'S':
+ do_encryption = 1;
+ break;
+
+ case 'K':
+ key_bits = (unsigned) atoi(optarg);
+ if (!(key_bits >= 40 && key_bits <= 128 && (key_bits % 8 == 0)) &&
+ key_bits != 256)
+ ERROR("Invalid encryption key length specified: %s", optarg);
+ break;
+
+ case 'P':
+ permission = (unsigned) strtoul(optarg, &nextptr, 0);
+ if (nextptr == optarg)
+ ERROR("Invalid encryption permission flag: %s", optarg);
+ break;
+
+ case 'O':
+ bookmark_open = atoi(optarg);
+ break;
+
+ case 'C':
+ {
+ int flags = (unsigned) strtol(optarg, &nextptr, 0);
+ if (nextptr == optarg)
+ ERROR("Invalid flag: %s", optarg);
+ if (flags < 0)
+ opt_flags = -flags;
+ else
+ opt_flags |= flags;
+ break;
+ }
+
+ case 'E':
+ dpx_conf.ignore_font_license = 1;
+ break;
+
+ case 'e':
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode) {
+ WARN("dvipdfm \"-e\" option not supported.");
+ break;
+ } /* else fall through */
+
+ default:
+ fprintf(stderr, "%s: %s \"-%c\"\n", source ? source : my_name,
+ c == ':' ? "Missing argument for" : "Unknown option",
+ optopt);
+ usage();
+ }
+ }
+
+ if (source) {
+ if (argc > optind)
+ fprintf(stderr, "%s: Unexpected argument in \"%s %s\".\n", source, argv[1], argv[2]);
+ return;
+ }
+
+ return;
+}
+
+static void
+cleanup (void)
+{
+ if (dvi_filename)
+ RELEASE(dvi_filename);
+ if (pdf_filename)
+ RELEASE(pdf_filename);
+ if (page_ranges)
+ RELEASE(page_ranges);
+ if (filter_template)
+ RELEASE(filter_template);
+}
+
+static void
+read_config_file (const char *config)
+{
+ const char *start, *end;
+ char *option;
+ FILE *fp;
+ static char argv0[] = "config_file";
+ char *argv[3];
+
+ fp = DPXFOPEN(config, DPX_RES_TYPE_TEXT);
+ if (!fp) {
+ WARN("Could not open config file \"%s\".", config);
+ return;
+ }
+ argv[0] = argv0;
+ while ((start = mfgets (work_buffer, WORK_BUFFER_SIZE, fp)) != NULL) {
+ int argc = 1;
+
+ end = work_buffer + strlen(work_buffer);
+ skip_white (&start, end);
+ if (start >= end)
+ continue;
+ /* Build up an argument list as if it were passed on the command
+ line */
+ if ((option = parse_ident (&start, end))) {
+ argc = 2;
+ argv[1] = NEW (strlen(option)+2, char);
+ strcpy (argv[1]+1, option);
+ RELEASE (option);
+ *argv[1] = '-';
+ skip_white (&start, end);
+ if (start < end) {
+ argc += 1;
+ if (*start == '"') {
+ argv[2] = parse_c_string (&start, end);
+ }
+ else
+ argv[2] = parse_ident (&start, end);
+ }
+ }
+ do_args_second_pass (argc, argv, config, 0);
+ while (argc > 1) {
+ RELEASE (argv[--argc]);
+ }
+ }
+ if (fp)
+ MFCLOSE(fp);
+}
+
+void
+read_config_special (const char **start, const char *end)
+{
+ char *option;
+ static char argv0[] = "config_special";
+ char *argv[3];
+ int argc = 1;
+
+ argv[0] = argv0;
+
+ skip_white (start, end);
+ if (*start >= end)
+ return;
+ /* Build up an argument list as if it were passed on the command
+ line */
+ if ((option = parse_ident (start, end))) {
+ argc = 2;
+ argv[1] = NEW (strlen(option)+2, char);
+ strcpy (argv[1]+1, option);
+ RELEASE (option);
+ *argv[1] = '-';
+ skip_white (start, end);
+ if (*start < end) {
+ argc += 1;
+ if (**start == '"') {
+ argv[2] = parse_c_string (start, end);
+ }
+ else
+ argv[2] = parse_ident (start, end);
+ }
+ }
+ do_args_second_pass (argc, argv, argv0, 1); /* Set to unsafe */
+ while (argc > 1) {
+ RELEASE (argv[--argc]);
+ }
+}
+
+static void
+system_default (void)
+{
+ if (systempapername() != NULL) {
+ select_paper(systempapername());
+ } else if (defaultpapername() != NULL) {
+ select_paper(defaultpapername());
+ }
+}
+
+void
+error_cleanup (void)
+{
+ /* Fixed a stupid bug...
+ * Please don't put an ordinay function which may call ERROR() inside it.
+ * It may result in error cleanup routine being called recursively.
+ */
+ pdf_error_cleanup_cache(); /* delete temporary files */
+ pdf_error_cleanup();
+ if (pdf_filename) {
+ if (pdf_get_output_file()) {
+ remove(pdf_filename);
+ fprintf(stderr, "\nOutput file removed.\n");
+ } else {
+ fprintf(stderr, "\nNo output PDF file written.\n");
+ }
+ }
+}
+
+#define SWAP(v1,v2) do {\
+ double _tmp = (v1);\
+ (v1) = (v2);\
+ (v2) = _tmp;\
+ } while (0)
+
+static void
+do_dvi_pages (void)
+{
+ int page_no, page_count, i, step;
+ double page_width, page_height;
+ double init_paper_width, init_paper_height;
+ pdf_rect mediabox;
+
+ spc_exec_at_begin_document();
+
+ if (num_page_ranges == 0) {
+ if (!page_ranges) {
+ page_ranges = NEW(1, struct page_range);
+ max_page_ranges = 1;
+ }
+ page_ranges[0].first = 0;
+ page_ranges[0].last = -1; /* last page */
+ num_page_ranges = 1;
+ }
+
+ init_paper_width = page_width = paper_width;
+ init_paper_height = page_height = paper_height;
+ page_count = 0;
+
+ mediabox.llx = 0.0;
+ mediabox.lly = 0.0;
+ mediabox.urx = paper_width;
+ mediabox.ury = paper_height;
+
+ pdf_doc_set_mediabox(0, &mediabox); /* Root node */
+
+ for (i = 0; i < num_page_ranges && dvi_npages(); i++) {
+ if (page_ranges[i].last < 0)
+ page_ranges[i].last += dvi_npages();
+
+ step = (page_ranges[i].first <= page_ranges[i].last) ? 1 : -1;
+ page_no = page_ranges[i].first;
+ while (dvi_npages()) {
+ if (page_no < dvi_npages()) {
+ double w, h, xo, yo;
+ int lm;
+
+ MESG("[%d", page_no+1);
+ /* FIXME: incompatibility here.... In older versions of dvipdfmx page sizes
+ * are inherited from the previous page but in the current implementation
+ * pagesize special only takes effect to the current page.
+ * The following line resets page sizes to the paper size...
+ */
+ page_width = paper_width; page_height = paper_height;
+ w = page_width; h = page_height; lm = landscape_mode;
+ xo = x_offset; yo = y_offset;
+ dvi_scan_specials(page_no,
+ &w, &h, &xo, &yo, &lm,
+ /* No need for encryption options */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ /* No trailer IDs */
+ NULL, NULL, NULL);
+ if (lm != landscape_mode) {
+ /* The first page was already scanned once and SWAP() was applied there.
+ * Do not apply SWAP() twice!
+ * FIXME: SWAP() not applied to paper_width and paper_height. Why?
+ */
+ SWAP(w, h);
+ landscape_mode = lm;
+ }
+ /* Specified as a command line option */
+ if (!has_paper_option) {
+ if (page_width != w || page_height != h) {
+ page_width = w;
+ page_height = h;
+ }
+ }
+ if (x_offset != xo || y_offset != yo) {
+ x_offset = xo;
+ y_offset = yo;
+ }
+ if (page_width != init_paper_width ||
+ page_height != init_paper_height) {
+ mediabox.llx = 0.0;
+ mediabox.lly = 0.0;
+ mediabox.urx = page_width;
+ mediabox.ury = page_height;
+ pdf_doc_set_mediabox(page_count+1, &mediabox);
+ }
+ dvi_do_page(page_height, x_offset, y_offset);
+ page_count++;
+ MESG("]");
+ }
+
+ if (step > 0 &&
+ page_no >= page_ranges[i].last)
+ break;
+ else if (step < 0 &&
+ page_no <= page_ranges[i].last)
+ break;
+ else {
+ page_no += step;
+ }
+ }
+ }
+
+ if (page_count < 1) {
+ ERROR("No pages fall in range!");
+ }
+
+ spc_exec_at_end_document();
+}
+
+static void
+do_mps_pages (void)
+{
+ FILE *fp;
+
+ /* _FIXME_ */
+ fp = MFOPEN(dvi_filename, FOPEN_RBIN_MODE);
+ if (fp) {
+ mps_do_page(fp);
+ MFCLOSE(fp);
+ } else {
+ int i, page_no, step, page_count = 0;
+ char *filename;
+ /* Process filename.1, filename.2,... */
+ filename = NEW(strlen(dvi_filename) + 16 + 1, char);
+ for (i = 0; i < num_page_ranges; i++) {
+ step = (page_ranges[i].first <= page_ranges[i].last) ? 1 : -1;
+ page_no = page_ranges[i].first;
+ for (;;) {
+ if (page_no < 0)
+ ERROR("Invalid page number for MPS input: %d", page_no);
+
+ sprintf(filename, "%s.%d", dvi_filename, page_no + 1);
+ fp = MFOPEN(filename, FOPEN_RBIN_MODE);
+ if (fp) {
+ MESG("[%ld<%s>", page_no + 1, filename);
+ mps_do_page(fp);
+ page_count++;
+ MESG("]");
+ MFCLOSE(fp);
+ }
+ if (step > 0 &&
+ page_no >= page_ranges[i].last)
+ break;
+ else if (step < 0 &&
+ page_no <= page_ranges[i].last)
+ break;
+ else {
+ page_no += step;
+ }
+ }
+ }
+ RELEASE(filename);
+ if (page_count == 0)
+ ERROR("No page output for \"%s\".", dvi_filename);
+ }
+}
+
+#if !defined(LIBDPX)
+/* Support to make DLL in W32TeX */
+#define DLLPROC dlldvipdfmxmain
+
+#if defined(WIN32) && !defined(__MINGW32__) && !defined(MIKTEX) && defined(DLLPROC)
+extern __declspec(dllexport) int DLLPROC (int argc, char *argv[]);
+#else
+#undef DLLPROC
+#endif
+#endif /* !LIBDPX */
+
+#if defined(MIKTEX)
+# define main Main
+#endif
+
+int
+#if defined(DLLPROC)
+DLLPROC (int argc, char *argv[])
+#else
+#if defined(LIBDPX)
+dvipdfmx_main (int argc, char *argv[])
+#else
+main (int argc, char *argv[])
+#endif /* LIBDPX */
+#endif
+{
+ double dvi2pts;
+ char *base;
+ struct pdf_setting settings;
+ char uplain[MAX_PWD_LEN+1], oplain[MAX_PWD_LEN+1]; /* encryption password */
+ const char *creator = NULL;
+ unsigned char id1[16], id2[16];
+ int has_id = 0;
+
+#ifdef WIN32
+ int ac;
+ char **av, *enc;
+#endif
+
+#ifdef MIKTEX
+ miktex_initialize();
+#else
+ kpse_set_program_name(argv[0], "dvipdfmx"); /* we pretend to be dvipdfmx for kpse purposes */
+#ifdef WIN32
+ texlive_gs_init ();
+ enc = kpse_var_value("command_line_encoding");
+ if (get_command_line_args_utf8(enc, &ac, &av)) {
+ argc = ac;
+ argv = av;
+ }
+#endif
+#endif
+
+ if (argc > 1 &&
+ (STREQ (argv[1], "--xbb") ||
+ STREQ (argv[1], "--extractbb") ||
+ STREQ (argv[1], "--dvipdfm") ||
+ STREQ (argv[1], "--dvipdfmx") ||
+ STREQ (argv[1], "--ebb"))) {
+ argc--;
+ base = argv++[1]+2;
+ } else {
+ base = kpse_program_basename (argv[0]);
+ }
+
+ if (FILESTRCASEEQ (base, "extractbb") || FILESTRCASEEQ (base, "xbb")) {
+ my_name = "extractbb";
+ return extractbb (argc, argv);
+ } else if (FILESTRCASEEQ (base, "ebb")) {
+ my_name = "ebb";
+ dpx_conf.compat_mode = dpx_mode_compat_mode;
+ return extractbb (argc, argv);
+ } else if (FILESTRCASEEQ (base, "dvipdfm")) {
+ dpx_conf.compat_mode = dpx_mode_compat_mode;
+ } else if (FILESTRCASEEQ (base, "dvipdfmx")) {
+ my_name = "dvipdfmx";
+ } else {
+ my_name = "xdvipdfmx";
+ }
+
+ opterr = 0;
+ /* Special-case single option --mvorigin, --help, --showpaper, or --version,
+ * to avoid possible diagnostics about config files, etc.
+ * Also handle -q and -v that cannot be set in config file.
+ * Get input DVI file name too.
+ */
+ do_args_first_pass(argc, argv, NULL, 0);
+
+ paperinit();
+ system_default();
+
+ pdf_init_fontmaps(); /* This must come before parsing options... */
+
+ read_config_file(DPX_CONFIG_FILE);
+
+ /* Current implementation seems to be assuming that paper size read from config
+ * is for "default" and explicitly specified one via command-line option must be
+ * used for all pages regardless of papersize specials.
+ */
+ has_paper_option = 0;
+
+#ifndef MIKTEX
+ kpse_init_prog("", font_dpi, NULL, NULL);
+ kpse_set_program_enabled(kpse_pk_format, true, kpse_src_texmf_cnf);
+#endif
+ pdf_font_set_dpi(font_dpi);
+ if (!dvi_filename) {
+ if (verbose)
+ MESG("No dvi filename specified, reading standard input.\n");
+ if (!pdf_filename)
+ if (verbose)
+ MESG("No pdf filename specified, writing to standard output.\n");
+ } else if (!pdf_filename)
+ set_default_pdf_filename();
+
+ if (pdf_filename && !strcmp(pdf_filename, "-")) {
+ RELEASE(pdf_filename);
+ pdf_filename = NULL;
+ }
+
+ if (dpx_conf.compat_mode == dpx_mode_mpost_mode) {
+ x_offset = 0.0;
+ y_offset = 0.0;
+ dvi2pts = 0.01; /* dvi2pts controls accuracy. */
+ } else {
+ dvi2pts = dvi_init(dvi_filename, mag);
+ if (dvi2pts == 0.0)
+ ERROR("dvi_init() failed!");
+ creator = dvi_comment(); /* Set PDF Creator entry */
+ dvi_scan_specials(0,
+ &paper_width, &paper_height,
+ &x_offset, &y_offset, &landscape_mode,
+ &pdf_version_major, &pdf_version_minor,
+ &do_encryption, &key_bits, &permission, oplain, uplain,
+ &has_id, id1, id2);
+ }
+
+ /* Command-line options take precedence */
+ {
+ int has_encrypt_special = do_encryption;
+
+ do_args_second_pass(argc, argv, NULL, 0);
+ if (do_encryption && !has_encrypt_special) {
+ get_enc_password(oplain, uplain);
+ }
+ }
+
+ /* moved to here because image caching was not effective */
+ dpx_delete_old_cache(image_cache_life);
+
+ MESG("%s -> %s\n", dvi_filename ? dvi_filename : "stdin",
+ pdf_filename ? pdf_filename : "stdout");
+
+ /* Kpathsea messages:
+ * really_quiet > 1 is actually for suppressing error messages in dvipdfmx.
+ */
+ kpse_make_tex_discard_errors = really_quiet;
+
+ /* Setup Options */
+ settings.ver_major = pdf_version_major;
+ settings.ver_minor = pdf_version_minor;
+
+ /* PDF trailer ID. */
+ if (!has_id) {
+#define PRODUCER \
+"%s-%s, Copyright 2002-2021 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata"
+ char producer[256];
+
+ sprintf(producer, PRODUCER, my_name, VERSION);
+ compute_id_string(id1, producer, dvi_filename, pdf_filename);
+ memcpy(id2, id1, 16);
+ }
+
+ /* Encryption and Other Settings */
+ {
+ memset(&settings.encrypt, 0, sizeof(struct pdf_enc_setting));
+ settings.enable_encrypt = do_encryption;
+ settings.encrypt.use_aes = 1;
+ settings.encrypt.encrypt_metadata = 1;
+ settings.encrypt.key_size = key_bits;
+ settings.encrypt.permission = permission;
+ settings.encrypt.uplain = uplain;
+ settings.encrypt.oplain = oplain;
+ }
+
+ /* PDF object settings */
+ settings.object.compression_level = compression_level;
+ if (opt_flags & OPT_PDFOBJ_NO_OBJSTM) {
+ settings.object.enable_objstm = 0;
+ } else {
+ settings.object.enable_objstm = 1;
+ }
+ if (opt_flags & OPT_PDFOBJ_NO_PREDICTOR) {
+ settings.object.enable_predictor = 0;
+ } else {
+ settings.object.enable_predictor = 1;
+ }
+
+ /* PDF document settings
+ * Set default paper size here so that all page's can inherite it.
+ * annot_grow: Margin of annotation.
+ * bookmark_open: Miximal depth of open bookmarks.
+ */
+ if (landscape_mode) {
+ SWAP(paper_width, paper_height);
+ }
+ settings.media_width = paper_width;
+ settings.media_height = paper_height;
+ settings.annot_grow_amount.x = annot_grow_x;
+ settings.annot_grow_amount.y = annot_grow_y;
+ settings.outline_open_depth = bookmark_open;
+ settings.check_gotos = !(opt_flags & OPT_PDFDOC_NO_DEST_REMOVE);
+ settings.enable_manual_thumb = enable_thumbnail;
+
+ /* PDF page output settings */
+ settings.device.dvi2pts = dvi2pts;
+ settings.device.precision = pdfdecimaldigits;
+ settings.device.ignore_colors = ignore_colors;
+
+ set_distiller_template(filter_template);
+
+ /* Initialize PDF document creation routine. */
+ pdf_open_document(pdf_filename, creator, id1, id2, settings);
+
+ if (opt_flags & OPT_CIDFONT_FIXEDPITCH)
+ CIDFont_set_flags(CIDFONT_FORCE_FIXEDPITCH);
+ /* Please move this to spc_init_specials(). */
+ if (opt_flags & OPT_TPIC_TRANSPARENT_FILL)
+ tpic_set_fill_mode(1);
+ if (translate_origin)
+ mps_set_translate_origin(1);
+
+ if (dpx_conf.compat_mode == dpx_mode_mpost_mode) {
+ do_mps_pages();
+ } else {
+ do_dvi_pages();
+ }
+
+ pdf_close_document();
+
+ pdf_close_fontmaps(); /* pdf_font may depend on fontmap. */
+
+ if (dpx_conf.compat_mode != dpx_mode_mpost_mode)
+ dvi_close();
+
+ MESG("\n");
+ cleanup();
+
+ paperdone();
+#ifdef MIKTEX
+ miktex_uninitialize ();
+#endif
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/dvipdfmx.h b/Build/source/texk/dvipdfm-x/dvipdfmx.h
new file mode 100644
index 00000000000..7b19ba2d24f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dvipdfmx.h
@@ -0,0 +1,33 @@
+/* DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+ the DVIPDFMx project team.
+
+ Copyright (c) 2006 SIL. (xdvipdfmx extensions for XeTeX support)
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _DVIPDFMX_H_
+#define _DVIPDFMX_H_
+
+extern const char *my_name;
+
+extern int extractbb(int argc, char *argv[]);
+extern void read_config_special(const char **start, const char *end);
+
+#endif /* _DVIPDFMX_H_ */
diff --git a/Build/source/texk/dvipdfm-x/dvipdft b/Build/source/texk/dvipdfm-x/dvipdft
new file mode 100755
index 00000000000..3bcd0027db1
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/dvipdft
@@ -0,0 +1,105 @@
+#!/bin/sh
+# dvipdft, completely rewritten by Thomas Esser for teTeX after an
+# original script by Mark A. Wicks
+#
+# Thomas Esser. Public Domain.
+#
+# Modified by Matthias Franz for dvipdfmx (when running as dvipdfm) and
+# TeX Live.
+
+# This script makes a first (fast) run with dvipdfm, then calls gs on
+# the resulting pdf file to get the thumbnails and finally calls dvipdfm.
+
+progname=dvipdft
+version=20090604.0046
+
+# set trap for error
+trap '
+ echo "$progname: fatal error." >&2
+ exit 1
+' 1
+
+test -f /bin/sh5 && test -z "$RUNNING_SH5" \
+ && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
+ && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
+unset RUNNING_SH5
+
+test -f /bin/bsh && test -z "$RUNNING_BSH" \
+ && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
+ && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
+unset RUNNING_BSH
+
+# hack around a bug in zsh:
+test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
+
+help="Usage: $progname [options] dvifile
+ $progname --help
+ $progname --version"
+
+quoteit()
+{
+ echo "x$1" | sed "s@.@@; s@'@'\\\\''@; s@^@'@; s@\$@'@"
+}
+
+# process args 1 to (n-1) and scan for a -o argument keep a properly
+# quoted backup of the options, so that they can be restored later
+unset s outfile
+while test $# -gt 1; do
+ case $1 in
+ -o) outfile=$2;;
+ esac
+ s="$s${s+ }"`quoteit "$1"`
+ shift
+done
+
+# check for last argument
+case $1 in
+ --help)
+ echo "$help"
+ exit 0
+ ;;
+ --version)
+ echo "$progname version $version by Thomas Esser and others"
+ exit 0
+ ;;
+ "")
+ echo "$help"
+ exit 1
+ ;;
+esac
+
+# args 1 to (n-1) are gone, last one must be the dvifile
+dvifile="$1"
+
+# outfile comes from -o argument, else it is derived from the input file
+test -n "$outfile" \
+ || outfile=`echo "$dvifile" | sed 's@.*/@@; s@\.dvi$@@; s@$@.pdf@'`
+
+# outBase is part of the thumbname files just as dvipdfm expects them:
+outBase=`echo "$outfile" | sed 's@\.pdf$@@'`
+
+ls "$outBase".[1-9]* >/dev/null 2>&1 && {
+ echo "$progname: Please move the following files out of the way:" >&2
+ ls "$outBase".[1-9]* >&2
+ exit 1
+}
+
+# restore args 1 to (n-1):
+eval set x "$s"; shift
+
+# set trap for cleanup
+trap '
+ rm -f "$outBase".[1-9]*
+' 0
+
+# Run dvipdfm with the fastest options for the first pass
+echo "$progname: running dvipdfm $@ -z0 $dvifile" >&2
+dvipdfm ${1+"$@"} -z0 "$dvifile"
+
+# run gs
+echo "$progname: running gs" >&2
+gs -r10 -dNOPAUSE -dBATCH -sDEVICE=png256 -sOutputFile="$outBase.%d" "$outfile"
+
+# run dvipdfm with the users specified options for the last pass
+echo "$progname: running dvipdfm -t $@ $dvifile" >&2
+dvipdfm ${1+"$@"} -t "$dvifile"
diff --git a/Build/source/texk/dvipdfm-x/epdf.c b/Build/source/texk/dvipdfm-x/epdf.c
new file mode 100644
index 00000000000..95094823c7b
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/epdf.c
@@ -0,0 +1,518 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * Concatinating content streams are only supported for streams that only uses
+ * single FlateDecode filter, i.e.,
+ *
+ * /Filter /FlateDecode or /Filter [/FlateDecode]
+ *
+ * TrimBox, BleedBox, ArtBox, Rotate ...
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "mfileio.h"
+#include "error.h"
+#include "dvipdfmx.h"
+
+#include "pdfobj.h"
+#include "pdfdev.h"
+#include "pdfdoc.h"
+
+#include "pdfdraw.h"
+#include "pdfparse.h"
+
+#include "pdfximage.h"
+
+#include "epdf.h"
+
+static pdf_obj*
+get_page_content (pdf_file *pf, pdf_obj* page)
+{
+ pdf_obj *contents, *content_new;
+
+ contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents"));
+ if (!contents)
+ return NULL;
+
+ if (PDF_OBJ_NULLTYPE(contents)) {
+ /* empty page */
+ pdf_release_obj(contents);
+ /* TODO: better don't include anything if the page is empty */
+ contents = pdf_new_stream(0);
+ } else if (PDF_OBJ_ARRAYTYPE(contents)) {
+ /*
+ * Concatenate all content streams.
+ */
+ pdf_obj *content_seg;
+ int i;
+ content_new = pdf_new_stream(STREAM_COMPRESS);
+ for (i = 0; i < pdf_array_length(contents); i++) {
+ content_seg = pdf_deref_obj(pdf_get_array(contents, i));
+ if (!content_seg) {
+ WARN("Could not read page content stream.");
+ pdf_release_obj(content_new);
+ pdf_release_obj(contents);
+ return NULL;
+ }
+ if (PDF_OBJ_STREAMTYPE(content_seg)) {
+ pdf_concat_stream(content_new, content_seg);
+ } else if (!PDF_OBJ_NULLTYPE(content_seg)) {
+ WARN("Page content not a stream object. Broken PDF file?");
+ pdf_release_obj(content_seg);
+ pdf_release_obj(content_new);
+ pdf_release_obj(contents);
+ return NULL;
+ }
+ pdf_release_obj(content_seg);
+ }
+ pdf_release_obj(contents);
+ contents = content_new;
+ } else {
+ if (!PDF_OBJ_STREAMTYPE(contents)) {
+ WARN("Page content not a stream object. Broken PDF file?");
+ pdf_release_obj(contents);
+ return NULL;
+ }
+ /* Flate the contents if necessary. */
+ content_new = pdf_new_stream(STREAM_COMPRESS);
+ pdf_concat_stream(content_new, contents);
+ pdf_release_obj(contents);
+ contents = content_new;
+ }
+
+ return contents;
+}
+
+/* ximage here is the result. DONT USE IT FOR PASSING OPTIONS! */
+int
+pdf_include_page (pdf_ximage *ximage,
+ FILE *image_file,
+ const char *ident,
+ load_options options)
+{
+ pdf_file *pf;
+ xform_info info;
+ pdf_obj *contents = NULL, *catalog;
+ pdf_obj *page = NULL, *resources = NULL, *markinfo = NULL;
+
+ pf = pdf_open(ident, image_file);
+ if (!pf)
+ return -1;
+
+ pdf_ximage_init_form_info(&info);
+
+ if (options.page_no == 0)
+ options.page_no = 1;
+ page = pdf_doc_get_page(pf,
+ options.page_no, options.bbox_type,
+ &info.bbox, &info.matrix, &resources);
+
+ if(!page)
+ goto error_silent;
+
+ catalog = pdf_file_get_catalog(pf);
+ markinfo = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo"));
+ if (markinfo) {
+ pdf_obj *tmp = pdf_deref_obj(pdf_lookup_dict(markinfo, "Marked"));
+ pdf_release_obj(markinfo);
+ if (!PDF_OBJ_BOOLEANTYPE(tmp)) {
+ if (tmp)
+ pdf_release_obj(tmp);
+ goto error;
+ } else if (pdf_boolean_value(tmp)) {
+ WARN("PDF file is tagged... Ignoring tags.");
+ }
+ pdf_release_obj(tmp);
+ }
+
+ /*
+ * Handle page content stream.
+ */
+ contents = get_page_content(pf, page);
+ pdf_release_obj(page);
+ page = NULL;
+
+ /*
+ * Add entries to contents stream dictionary.
+ */
+ {
+ pdf_obj *contents_dict, *bbox, *matrix;
+
+ contents_dict = pdf_stream_dict(contents);
+ pdf_add_dict(contents_dict,
+ pdf_new_name("Type"), pdf_new_name("XObject"));
+ pdf_add_dict(contents_dict,
+ pdf_new_name("Subtype"), pdf_new_name("Form"));
+ pdf_add_dict(contents_dict,
+ pdf_new_name("FormType"), pdf_new_number(1.0));
+
+ bbox = pdf_new_array();
+ pdf_add_array(bbox, pdf_new_number(info.bbox.llx));
+ pdf_add_array(bbox, pdf_new_number(info.bbox.lly));
+ pdf_add_array(bbox, pdf_new_number(info.bbox.urx));
+ pdf_add_array(bbox, pdf_new_number(info.bbox.ury));
+
+ pdf_add_dict(contents_dict, pdf_new_name("BBox"), bbox);
+
+ matrix = pdf_new_array();
+ pdf_add_array(matrix, pdf_new_number(info.matrix.a));
+ pdf_add_array(matrix, pdf_new_number(info.matrix.b));
+ pdf_add_array(matrix, pdf_new_number(info.matrix.c));
+ pdf_add_array(matrix, pdf_new_number(info.matrix.d));
+ pdf_add_array(matrix, pdf_new_number(info.matrix.e));
+ pdf_add_array(matrix, pdf_new_number(info.matrix.f));
+
+ pdf_add_dict(contents_dict, pdf_new_name("Matrix"), matrix);
+
+ pdf_add_dict(contents_dict, pdf_new_name("Resources"),
+ pdf_import_object(resources));
+ pdf_release_obj(resources);
+ }
+
+ pdf_close(pf);
+
+ pdf_ximage_set_form(ximage, &info, contents);
+
+ return 0;
+
+ error:
+ WARN("Cannot parse document. Broken PDF file?");
+ error_silent:
+ if (resources)
+ pdf_release_obj(resources);
+ if (markinfo)
+ pdf_release_obj(markinfo);
+ if (page)
+ pdf_release_obj(page);
+ if (contents)
+ pdf_release_obj(contents);
+
+ pdf_close(pf);
+
+ return -1;
+}
+
+enum action {
+ action_unknown,
+ action_discard,
+ action_path,
+ action_rect,
+ action_trans,
+ action_clip,
+ action_save,
+ action_restore
+};
+
+static struct operator
+{
+ const char *token;
+ enum action action;
+ int n_args;
+} operators[] = {
+ {"b*", action_clip, 0},
+ {"B*", action_clip, 0},
+ {"cm", action_trans, 6},
+ {"f*", action_clip, 0},
+ {"re", action_rect, 4},
+ {"W*", action_path, 0},
+ {"b", action_clip, 0},
+ {"B", action_clip, 0},
+ {"c", action_path, 6},
+ {"f", action_clip, 0},
+ {"F", action_clip, 0},
+ {"h", action_path, 0},
+ {"l", action_path, 2},
+ {"m", action_path, 2},
+ {"n", action_path, 0},
+ {"q", action_save, 0},
+ {"Q", action_restore, 0},
+ {"s", action_clip, 0},
+ {"S", action_clip, 0},
+ {"v", action_path, 4},
+ {"W", action_path, 0},
+ {"y", action_path, 4}
+};
+
+#include "dpxutil.h"
+
+static int
+get_numbers_from_stack (dpx_stack *stack, double *v, int n)
+{
+ int error = 0;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ pdf_obj *obj;
+ obj = dpx_stack_pop(stack);
+ if (!obj) {
+ error = -1;
+ break;
+ } else if (!PDF_OBJ_NUMBERTYPE(obj)) {
+ pdf_release_obj(obj);
+ error = -1;
+ break;
+ }
+ v[n-i-1] = pdf_number_value(obj);
+ pdf_release_obj(obj);
+ }
+ return error;
+}
+
+int
+pdf_copy_clip (FILE *image_file, int pageNo, double x_user, double y_user)
+{
+ pdf_obj *page_tree, *contents;
+ int depth = 0;
+ const char *p, *endptr;
+ pdf_tmatrix M;
+ pdf_rect bbox;
+ pdf_tmatrix mtrx;
+ pdf_file *pf;
+ dpx_stack stack;
+ int error = 0;
+
+ pf = pdf_open(NULL, image_file);
+ if (!pf)
+ return -1;
+
+ pdf_dev_currentmatrix(&M);
+ pdf_invertmatrix(&M);
+ M.e += x_user; M.f += y_user;
+
+ page_tree = pdf_doc_get_page(pf, pageNo, 0, &bbox, &mtrx, NULL);
+ if (!page_tree) {
+ pdf_close(pf);
+ return -1;
+ }
+
+ contents = get_page_content(pf, page_tree);
+ pdf_release_obj(page_tree);
+ if (!contents) {
+ pdf_close(pf);
+ return -1;
+ }
+
+ pdf_doc_add_page_content(" ", 1);
+
+ p = pdf_stream_dataptr(contents);
+ endptr = p + pdf_stream_length(contents);
+ depth = 0;
+ dpx_stack_init(&stack);
+
+ skip_white(&p, endptr);
+ while (p < endptr && !error) {
+ enum action action = action_discard;
+ char *token = NULL;
+ pdf_obj *obj = NULL;
+ int n_args = 0;
+ char buf[1024];
+ size_t len = 0;
+
+ if (depth > 1) {
+ if (*p == 'q')
+ depth++;
+ if (*p == 'Q')
+ depth--;
+ token = parse_ident(&p, endptr);
+ skip_white(&p, endptr);
+ RELEASE(token);
+ continue;
+ }
+
+ switch (*p) {
+ case '-': case '+': case'.':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ obj = parse_pdf_number(&p, endptr);
+ break;
+ case '[':
+ obj = parse_pdf_array(&p, endptr, NULL); /* No indirect reference allowed here */
+ break;
+ case '/':
+ obj = parse_pdf_name(&p, endptr);
+ break;
+ case '(':
+ obj = parse_pdf_string(&p, endptr);
+ break;
+ case '<':
+ if (p < endptr - 1 && p[1] == '<') {
+ obj = parse_pdf_dict(&p, endptr, NULL);
+ } else {
+ obj = parse_pdf_string(&p, endptr);
+ }
+ break;
+ }
+ if (obj) {
+ skip_white(&p, endptr);
+ dpx_stack_push(&stack, obj);
+ continue;
+ }
+
+ /* operator */
+ token = parse_ident(&p, endptr);
+ skip_white(&p, endptr);
+ if (!token) {
+ break;
+ } else {
+ int i;
+ for (i = 0; i < sizeof(operators) / sizeof(operators[0]); i++) {
+ if (!strcmp(token, operators[i].token)) {
+ action = operators[i].action;
+ n_args = operators[i].n_args;
+ break;
+ }
+ }
+ }
+ switch (action) {
+ case action_rect:
+ {
+ double v[4];
+
+ error = get_numbers_from_stack(&stack, v, n_args); /* n_args = 4 */
+ if (!error) {
+ /* Not sure if this switch is required */
+ if (M.b == 0.0 && M.c == 0.0) {
+ /* Use "re" operator */
+ pdf_coord p0;
+ double w, h;
+
+ p0.x = v[0]; p0.y = v[1];
+ w = M.a * v[2]; h = M.d * v[3];
+ pdf_dev_transform(&p0, &M);
+ buf[len++] = ' ';
+ len += pdf_sprint_coord(buf+len, &p0);
+ buf[len++] = ' ';
+ len += pdf_sprint_length(buf+len, w);
+ buf[len++] = ' ';
+ len += pdf_sprint_length(buf+len, h);
+ len += sprintf(buf+len, " re");
+ } else {
+ /* Converted to lineto */
+ pdf_coord p0, p1, p2, p3;
+ double w, h;
+
+ w = v[2]; h = v[3];
+ p0.x = v[0]; p0.y = v[1];
+ p1.x = p0.x + w; p1.y = p0.y;
+ p2.x = p1.x; p2.y = p1.y + h;
+ p3.x = p0.x; p3.y = p2.y;
+ pdf_dev_transform(&p0, &M);
+ pdf_dev_transform(&p1, &M);
+ pdf_dev_transform(&p2, &M);
+ pdf_dev_transform(&p3, &M);
+ buf[len++] = ' ';
+ len += pdf_sprint_coord(buf+len, &p0);
+ len += sprintf(buf+len, " m");
+ buf[len++] = ' ';
+ len += pdf_sprint_coord(buf+len, &p1);
+ len += sprintf(buf+len, " l");
+ buf[len++] = ' ';
+ len += pdf_sprint_coord(buf+len, &p2);
+ len += sprintf(buf+len, " l");
+ buf[len++] = ' ';
+ len += pdf_sprint_coord(buf+len, &p3);
+ len += sprintf(buf+len, " l h");
+ }
+ pdf_doc_add_page_content(buf, len);
+ }
+ }
+ break;
+ case action_path:
+ {
+ double v[6];
+ pdf_coord pt;
+ int i;
+
+ error = get_numbers_from_stack(&stack, v, n_args);
+ if (!error) {
+ for (i = 0; i < n_args/2; i++) {
+ pt.x = v[2*i];
+ pt.y = v[2*i+1];
+ pdf_dev_transform(&pt, &M);
+ buf[len++] = ' ';
+ len += pdf_sprint_coord(buf+len, &pt);
+ }
+ len += sprintf(buf+len, " %s", token);
+ pdf_doc_add_page_content(buf, len);
+ }
+ }
+ break;
+ case action_trans:
+ {
+ double v[6];
+ pdf_tmatrix T;
+ error = get_numbers_from_stack(&stack, v, n_args);
+ if (!error) {
+ T.a = v[0]; T.b = v[1]; T.c = v[2]; T.d = v[3];
+ T.e = v[4]; T.f = v[5];
+ pdf_concatmatrix(&M, &T);
+ }
+ }
+ break;
+ case action_clip:
+ if (token[0] >= 'a' && token[0] <= 'z') {
+ /* close path */
+ len += sprintf(buf+len, " h");
+ }
+ if (strlen(token) >= 2 && token[1] == '*') {
+ len += sprintf(buf+len, " W* n");
+ } else {
+ len += sprintf(buf+len, " W n");
+ }
+ pdf_doc_add_page_content(buf, len);
+ break;
+ case action_save:
+ depth++;
+ break;
+ case action_restore:
+ depth--;
+ break;
+ case action_discard:
+ /* stack clearing behavior */
+ while ((obj = dpx_stack_pop(&stack)) != NULL) {
+ pdf_release_obj(obj);
+ }
+ break;
+ case action_unknown:
+ error = -1;
+ break;
+ }
+ RELEASE(token);
+ }
+ {
+ pdf_obj *obj;
+
+ while ((obj = dpx_stack_pop(&stack)) != NULL) {
+ pdf_release_obj(obj);
+ }
+ }
+ pdf_release_obj(contents);
+ pdf_close(pf);
+
+ return error;
+}
diff --git a/Build/source/texk/dvipdfm-x/epdf.h b/Build/source/texk/dvipdfm-x/epdf.h
new file mode 100644
index 00000000000..26f637c6545
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/epdf.h
@@ -0,0 +1,41 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _EPDF_H_
+#define _EPDF_H_
+
+#include "mfileio.h"
+#include "pdfximage.h"
+
+#define pdfbox_crop 1
+#define pdfbox_media 2
+#define pdfbox_bleed 3
+#define pdfbox_trim 4
+#define pdfbox_art 5
+
+extern int pdf_copy_clip (FILE *image_file, int page_index,
+ double x_user, double y_user);
+
+extern int pdf_include_page (pdf_ximage * ximage, FILE *file,
+ const char *ident, load_options options);
+
+#endif /* _EPDF_H_ */
diff --git a/Build/source/texk/dvipdfm-x/error.c b/Build/source/texk/dvipdfm-x/error.c
new file mode 100644
index 00000000000..40b79519354
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/error.c
@@ -0,0 +1,95 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "dvipdfmx.h"
+#include "error.h"
+
+#define DPX_MESG 0
+#define DPX_MESG_WARN 1
+#define DPX_MESG_ERROR 2
+
+static int _mesg_type = DPX_MESG;
+#define WANT_NEWLINE() (_mesg_type != DPX_MESG_WARN && _mesg_type != DPX_MESG_ERROR)
+
+static int really_quiet = 0;
+
+void
+shut_up (int quietness)
+{
+ really_quiet = quietness;
+}
+
+void
+MESG (const char *fmt, ...)
+{
+ va_list argp;
+
+ if (really_quiet < 1) {
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+ _mesg_type = DPX_MESG;
+ }
+}
+
+void
+WARN (const char *fmt, ...)
+{
+ va_list argp;
+
+ if (really_quiet < 2) {
+ if (WANT_NEWLINE())
+ fprintf(stderr, "\n");
+ fprintf(stderr, "%s:warning: ", my_name);
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+ fprintf(stderr, "\n");
+
+ _mesg_type = DPX_MESG_WARN;
+ }
+}
+
+void
+ERROR (const char *fmt, ...)
+{
+ va_list argp;
+
+ if (really_quiet < 3) {
+ if (WANT_NEWLINE())
+ fprintf(stderr, "\n");
+ fprintf(stderr, "%s:fatal: ", my_name);
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+ fprintf(stderr, "\n");
+ }
+ error_cleanup();
+ exit( 1 );
+}
diff --git a/Build/source/texk/dvipdfm-x/error.h b/Build/source/texk/dvipdfm-x/error.h
new file mode 100644
index 00000000000..0ae308a754f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/error.h
@@ -0,0 +1,55 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _ERROR_H_
+#define _ERROR_H_
+
+#include "system.h"
+
+extern void error_cleanup (void);
+
+/* Acoid conflict with NO_ERROR from <winerror.h>. */
+#undef NO_ERROR
+
+#define FATAL_ERROR -1
+#define NO_ERROR 0
+
+#include <assert.h>
+#include <stdio.h>
+
+extern void shut_up (int quietness);
+
+/* Acoid conflict with ERROR from <winnt.h>. */
+#undef ERROR
+
+extern void ERROR (const char *fmt, ...);
+extern void MESG (const char *fmt, ...);
+extern void WARN (const char *fmt, ...);
+
+#define ASSERT(e) assert(e)
+
+#if defined(WIN32)
+#undef vfprintf
+#define vfprintf win32_vfprintf
+#endif
+
+#endif /* _ERROR_H_ */
diff --git a/Build/source/texk/dvipdfm-x/fontmap.c b/Build/source/texk/dvipdfm-x/fontmap.c
new file mode 100644
index 00000000000..9647fe453da
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/fontmap.c
@@ -0,0 +1,1433 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxconf.h"
+#include "dpxfile.h"
+#include "dpxutil.h"
+
+#include "subfont.h"
+
+#include "fontmap.h"
+
+/* CIDFont */
+static char *strip_options (const char *map_name, fontmap_opt *opt);
+
+void
+pdf_init_fontmap_record (fontmap_rec *mrec)
+{
+ ASSERT(mrec);
+
+ mrec->map_name = NULL;
+
+ /* SFD char mapping */
+ mrec->charmap.sfd_name = NULL;
+ mrec->charmap.subfont_id = NULL;
+ /* for OFM */
+ mrec->opt.mapc = -1; /* compatibility */
+
+ mrec->font_name = NULL;
+ mrec->enc_name = NULL;
+
+ mrec->opt.slant = 0.0;
+ mrec->opt.extend = 1.0;
+ mrec->opt.bold = 0.0;
+
+ mrec->opt.flags = 0;
+
+ mrec->opt.design_size = -1.0;
+
+ mrec->opt.tounicode = NULL;
+ mrec->opt.otl_tags = NULL;
+ mrec->opt.index = 0;
+ mrec->opt.charcoll = NULL;
+ mrec->opt.style = FONTMAP_STYLE_NONE;
+ mrec->opt.stemv = -1; /* not given explicitly by an option */
+ mrec->opt.use_glyph_encoding = 0;
+}
+
+void
+pdf_clear_fontmap_record (fontmap_rec *mrec)
+{
+ ASSERT(mrec);
+
+ if (mrec->map_name)
+ RELEASE(mrec->map_name);
+ if (mrec->charmap.sfd_name)
+ RELEASE(mrec->charmap.sfd_name);
+ if (mrec->charmap.subfont_id)
+ RELEASE(mrec->charmap.subfont_id);
+ if (mrec->enc_name)
+ RELEASE(mrec->enc_name);
+ if (mrec->font_name)
+ RELEASE(mrec->font_name);
+
+ if (mrec->opt.tounicode)
+ RELEASE(mrec->opt.tounicode);
+ if (mrec->opt.otl_tags)
+ RELEASE(mrec->opt.otl_tags);
+ if (mrec->opt.charcoll)
+ RELEASE(mrec->opt.charcoll);
+ pdf_init_fontmap_record(mrec);
+}
+
+/* strdup: just returns NULL for NULL */
+static char *
+mstrdup (const char *s)
+{
+ char *r;
+ if (!s)
+ return NULL;
+ r = NEW(strlen(s) + 1, char);
+ strcpy(r, s);
+ return r;
+}
+
+static void
+pdf_copy_fontmap_record (fontmap_rec *dst, const fontmap_rec *src)
+{
+ ASSERT( dst && src );
+
+ dst->map_name = mstrdup(src->map_name);
+
+ dst->charmap.sfd_name = mstrdup(src->charmap.sfd_name);
+ dst->charmap.subfont_id = mstrdup(src->charmap.subfont_id);
+
+ dst->font_name = mstrdup(src->font_name);
+ dst->enc_name = mstrdup(src->enc_name);
+
+ dst->opt.slant = src->opt.slant;
+ dst->opt.extend = src->opt.extend;
+ dst->opt.bold = src->opt.bold;
+
+ dst->opt.flags = src->opt.flags;
+ dst->opt.mapc = src->opt.mapc;
+
+ dst->opt.tounicode = mstrdup(src->opt.tounicode);
+ dst->opt.otl_tags = mstrdup(src->opt.otl_tags);
+ dst->opt.index = src->opt.index;
+ dst->opt.charcoll = mstrdup(src->opt.charcoll);
+ dst->opt.style = src->opt.style;
+ dst->opt.stemv = src->opt.stemv;
+ dst->opt.use_glyph_encoding = src->opt.use_glyph_encoding;
+}
+
+
+static void
+hval_free (void *vp)
+{
+ fontmap_rec *mrec = (fontmap_rec *) vp;
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+}
+
+
+static void
+fill_in_defaults (fontmap_rec *mrec, const char *tex_name)
+{
+ if (mrec->enc_name &&
+ (!strcmp(mrec->enc_name, "default") ||
+ !strcmp(mrec->enc_name, "none"))) {
+ RELEASE(mrec->enc_name);
+ mrec->enc_name = NULL;
+ }
+ if (mrec->font_name &&
+ (!strcmp(mrec->font_name, "default") ||
+ !strcmp(mrec->font_name, "none"))) {
+ RELEASE(mrec->font_name);
+ mrec->font_name = NULL;
+ }
+ /* We *must* fill font_name either explicitly or by default */
+ if (!mrec->font_name) {
+ mrec->font_name = NEW(strlen(tex_name)+1, char);
+ strcpy(mrec->font_name, tex_name);
+ }
+
+ mrec->map_name = NEW(strlen(tex_name)+1, char);
+ strcpy(mrec->map_name, tex_name);
+
+#ifndef WITHOUT_COMPAT
+ /* Use "UCS" character collection for Unicode SFD
+ * and Identity CMap combination. For backward
+ * compatibility.
+ */
+ if (mrec->charmap.sfd_name && mrec->enc_name &&
+ !mrec->opt.charcoll) {
+ if ((!strcmp(mrec->enc_name, "Identity-H") ||
+ !strcmp(mrec->enc_name, "Identity-V"))
+ &&
+ (strstr(mrec->charmap.sfd_name, "Uni") ||
+ strstr(mrec->charmap.sfd_name, "UBig") ||
+ strstr(mrec->charmap.sfd_name, "UBg") ||
+ strstr(mrec->charmap.sfd_name, "UGB") ||
+ strstr(mrec->charmap.sfd_name, "UKS") ||
+ strstr(mrec->charmap.sfd_name, "UJIS"))) {
+ mrec->opt.charcoll = NEW(strlen("UCS")+1, char);
+ strcpy(mrec->opt.charcoll, "UCS");
+ }
+ }
+#endif /* WITHOUT_COMPAT */
+
+ return;
+}
+
+static char *
+readline (char *buf, int buf_len, FILE *fp)
+{
+ char *p, *q;
+ ASSERT( buf && buf_len > 0 && fp );
+ p = mfgets(buf, buf_len, fp);
+ if (!p)
+ return NULL;
+ q = strchr(p, '%'); /* we don't have quoted string */
+ if (q)
+ *q = '\0';
+ return p;
+}
+
+#ifndef ISBLANK
+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+static void
+skip_blank (const char **pp, const char *endptr)
+{
+ const char *p = *pp;
+ if (!p || p >= endptr)
+ return;
+ for ( ; p < endptr && ISBLANK(*p); p++);
+ *pp = p;
+}
+
+static char *
+parse_string_value (const char **pp, const char *endptr)
+{
+ char *q = NULL;
+ const char *p = *pp;
+ int n;
+
+ if (!p || p >= endptr)
+ return NULL;
+ if (*p == '"')
+ q = parse_c_string(&p, endptr);
+ else {
+ for (n = 0; p < endptr && !isspace((unsigned char)*p); p++, n++);
+ if (n == 0)
+ return NULL;
+ q = NEW(n + 1, char);
+ memcpy(q, *pp, n); q[n] = '\0';
+ }
+
+ *pp = p;
+ return q;
+}
+
+/* no preceeding spaces allowed */
+static char *
+parse_integer_value (const char **pp, const char *endptr, int base)
+{
+ char *q;
+ const char *p = *pp;
+ int has_sign = 0, has_prefix = 0, n;
+
+ ASSERT( base == 0 || (base >= 2 && base <= 36) );
+
+ if (!p || p >= endptr)
+ return NULL;
+
+ if (*p == '-' || *p == '+') {
+ p++; has_sign = 1;
+ }
+ if ((base == 0 || base == 16) &&
+ p + 2 <= endptr &&
+ p[0] == '0' && p[1] == 'x') {
+ p += 2; has_prefix = 1;
+ }
+ if (base == 0) {
+ if (has_prefix)
+ base = 16;
+ else if (p < endptr && *p == '0')
+ base = 8;
+ else {
+ base = 10;
+ }
+ }
+#define ISDIGIT_WB(c,b) ( \
+ ((b) <= 10 && (c) >= '0' && (c) < '0' + (b)) || \
+ ((b) > 10 && ( \
+ ((c) >= '0' && (c) <= '9') || \
+ ((c) >= 'a' && (c) < 'a' + ((b) - 10)) || \
+ ((c) >= 'A' && (c) < 'A' + ((b) - 10)) \
+ ) \
+ ) \
+)
+ for (n = 0; p < endptr && ISDIGIT_WB(*p, base); p++, n++);
+ if (n == 0)
+ return NULL;
+ if (has_sign)
+ n += 1;
+ if (has_prefix)
+ n += 2;
+
+ q = NEW(n + 1, char);
+ memcpy(q, *pp, n); q[n] = '\0';
+
+ *pp = p;
+ return q;
+}
+
+static int
+fontmap_parse_mapdef_dpm (fontmap_rec *mrec,
+ const char *mapdef, const char *endptr)
+{
+ const char *p = mapdef;
+
+ /*
+ * Parse record line in map file. First two fields (after TeX font
+ * name) are position specific. Arguments start at the first token
+ * beginning with a '-'.
+ *
+ * NOTE:
+ * Dvipdfm basically uses parse_ident() for parsing enc_name,
+ * font_name, and other string values which assumes PostScript-like
+ * syntax.
+ * skip_white() skips '\r' and '\n' but they should terminate
+ * fontmap line here.
+ */
+
+ skip_blank(&p, endptr);
+ /* encoding field */
+ if (p < endptr && *p != '-') { /* May be NULL */
+ mrec->enc_name = parse_string_value(&p, endptr);
+ skip_blank(&p, endptr);
+ }
+
+ /* fontname or font filename field */
+ if (p < endptr && *p != '-') { /* May be NULL */
+ mrec->font_name = parse_string_value(&p, endptr);
+ skip_blank(&p, endptr);
+ }
+ if (mrec->font_name) {
+ char *tmp;
+ /* Several options are encoded in font_name for
+ * compatibility with dvipdfm.
+ */
+ tmp = strip_options(mrec->font_name, &mrec->opt);
+ if (tmp) {
+ RELEASE(mrec->font_name);
+ mrec->font_name = tmp;
+ }
+ }
+
+ skip_blank(&p, endptr);
+ /* Parse any remaining arguments */
+ while (p + 1 < endptr &&
+ *p != '\r' && *p != '\n' && *p == '-') {
+ char *q, mopt = p[1];
+ int v;
+
+ p += 2; skip_blank(&p, endptr);
+ switch (mopt) {
+
+ case 's': /* Slant option */
+ q = parse_float_decimal(&p, endptr);
+ if (!q) {
+ WARN("Missing a number value for 's' option.");
+ return -1;
+ }
+ mrec->opt.slant = atof(q);
+ RELEASE(q);
+ break;
+
+ case 'e': /* Extend option */
+ q = parse_float_decimal(&p, endptr);
+ if (!q) {
+ WARN("Missing a number value for 'e' option.");
+ return -1;
+ }
+ mrec->opt.extend = atof(q);
+ if (mrec->opt.extend <= 0.0) {
+ WARN("Invalid value for 'e' option: %s", q);
+ return -1;
+ }
+ RELEASE(q);
+ break;
+
+ case 'b': /* Fake-bold option */
+ q = parse_float_decimal(&p, endptr);
+ if (!q) {
+ WARN("Missing a number value for 'b' option.");
+ return -1;
+ }
+ mrec->opt.bold = atof(q);
+ if (mrec->opt.bold <= 0.0) {
+ WARN("Invalid value for 'b' option: %s", q);
+ return -1;
+ }
+ RELEASE(q);
+ break;
+
+ case 'r': /* Remap option; obsolete; just ignore */
+ break;
+
+ case 'i': /* TTC index */
+ q = parse_integer_value(&p, endptr, 10);
+ if (!q) {
+ WARN("Missing TTC index number...");
+ return -1;
+ }
+ mrec->opt.index = strtoul(q, NULL, 10);
+ RELEASE(q);
+ break;
+
+ case 'p': /* UCS plane: just for testing */
+ q = parse_integer_value(&p, endptr, 0);
+ if (!q) {
+ WARN("Missing a number for 'p' option.");
+ return -1;
+ }
+ v = strtol(q, NULL, 0);
+ if (v < 0 || v > 16)
+ WARN("Invalid value for option 'p': %s", q);
+ else {
+ mrec->opt.mapc = v << 16;
+ }
+ RELEASE(q);
+ break;
+
+ case 'u': /* ToUnicode */
+ q = parse_string_value(&p, endptr);
+ if (q)
+ mrec->opt.tounicode = q;
+ else {
+ WARN("Missing string value for option 'u'.");
+ return -1;
+ }
+ break;
+
+ case 'v': /* StemV */
+ q = parse_integer_value(&p, endptr, 10);
+ if (!q) {
+ WARN("Missing a number for 'v' option.");
+ return -1;
+ }
+ mrec->opt.stemv = strtol(q, NULL, 0);
+ RELEASE(q);
+ break;
+
+ /* 2017.4.15 back again */
+ case 'l':
+ q = parse_string_value(&p, endptr);
+ if (q)
+ mrec->opt.otl_tags = q;
+ else {
+ WARN("Missing string value for option 'l'.");
+ return -1;
+ }
+ break;
+
+ /* Omega uses both single-byte and double-byte set_char command
+ * even for double-byte OFMs. This confuses CMap decoder.
+ */
+ case 'm':
+ /* Map single bytes char 0xab to double byte char 0xcdab */
+ if (p + 4 <= endptr &&
+ p[0] == '<' && p[3] == '>') {
+ p++;
+ q = parse_integer_value(&p, endptr, 16);
+ if (!q) {
+ WARN("Invalid value for option 'm'.");
+ return -1;
+ } else if (p < endptr && *p != '>') {
+ WARN("Invalid value for option 'm': %s", q);
+ RELEASE(q);
+ return -1;
+ }
+ v = strtol(q, NULL, 16);
+ mrec->opt.mapc = ((v << 8) & 0x0000ff00L);
+ RELEASE(q); p++;
+ } else if (p + 4 <= endptr &&
+ !memcmp(p, "sfd:", strlen("sfd:"))) {
+ char *r;
+ const char *rr;
+ /* SFD mapping: sfd:Big5,00 */
+ p += 4; skip_blank(&p, endptr);
+ q = parse_string_value(&p, endptr);
+ if (!q) {
+ WARN("Missing value for option 'm'.");
+ return -1;
+ }
+ r = strchr(q, ',');
+ if (!r) {
+ WARN("Invalid value for option 'm': %s", q);
+ RELEASE(q);
+ return -1;
+ }
+ *r = 0; rr = ++r; skip_blank(&rr, r + strlen(r));
+ if (*rr == '\0') {
+ WARN("Invalid value for option 'm': %s,", q);
+ RELEASE(q);
+ return -1;
+ }
+ mrec->charmap.sfd_name = mstrdup(q);
+ mrec->charmap.subfont_id = mstrdup(rr);
+ RELEASE(q);
+ } else if (p + 4 < endptr &&
+ !memcmp(p, "pad:", strlen("pad:"))) {
+ p += 4; skip_blank(&p, endptr);
+ q = parse_integer_value(&p, endptr, 16);
+ if (!q) {
+ WARN("Invalid value for option 'm'.");
+ return -1;
+ } else if (p < endptr && !isspace((unsigned char)*p)) {
+ WARN("Invalid value for option 'm': %s", q);
+ RELEASE(q);
+ return -1;
+ }
+ v = strtol(q, NULL, 16);
+ mrec->opt.mapc = ((v << 8) & 0x0000ff00L);
+ RELEASE(q);
+ } else {
+ WARN("Invalid value for option 'm'.");
+ return -1;
+ }
+ break;
+
+ case 'w': /* Writing mode (for unicode encoding) */
+ if (!mrec->enc_name ||
+ strcmp(mrec->enc_name, "unicode")) {
+ WARN("Fontmap option 'w' meaningless for encoding other than \"unicode\".");
+ return -1;
+ }
+ q = parse_integer_value(&p, endptr, 10);
+ if (!q) {
+ WARN("Missing wmode value...");
+ return -1;
+ }
+ if (atoi(q) == 1)
+ mrec->opt.flags |= FONTMAP_OPT_VERT;
+ else if (atoi(q) == 0)
+ mrec->opt.flags &= ~FONTMAP_OPT_VERT;
+ else {
+ WARN("Invalid value for option 'w': %s", q);
+ }
+ RELEASE(q);
+ break;
+
+ default:
+ WARN("Unrecognized font map option: '%c'", mopt);
+ return -1;
+ }
+ skip_blank(&p, endptr);
+ }
+
+ if (p < endptr && *p != '\r' && *p != '\n') {
+ WARN("Invalid char in fontmap line: %c", *p);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* Parse record line in map file of DVIPS/pdfTeX format. */
+static int
+fontmap_parse_mapdef_dps (fontmap_rec *mrec,
+ const char *mapdef, const char *endptr)
+{
+ const char *p = mapdef;
+ char *q;
+
+ skip_blank(&p, endptr);
+
+ /* The first field (after TFM name) must be PostScript name. */
+ /* However, pdftex.map allows a line without PostScript name. */
+
+ if (*p != '"' && *p != '<') {
+ if (p < endptr) {
+ q = parse_string_value(&p, endptr);
+ if (q) RELEASE(q);
+ skip_blank(&p, endptr);
+ } else {
+ WARN("Missing a PostScript font name.");
+ return -1;
+ }
+ }
+
+ if (p >= endptr) return 0;
+
+ /* Parse any remaining arguments */
+ while (p < endptr && *p != '\r' && *p != '\n' && (*p == '<' || *p == '"')) {
+ switch (*p) {
+ case '<': /* encoding or fontfile field */
+ /* If we see <[ or <<, just ignore the second char instead
+ of doing as directed (define encoding file, fully embed); sorry. */
+ if (++p < endptr && (*p == '[' || *p == '<')) p++; /*skip */
+ skip_blank(&p, endptr);
+ if ((q = parse_string_value(&p, endptr))) {
+ int n = strlen(q);
+ if (n > 4 && strncmp(q+n-4, ".enc", 4) == 0)
+ mrec->enc_name = q;
+ else
+ mrec->font_name = q;
+ }
+ skip_blank(&p, endptr);
+ break;
+
+ case '"': /* Options */
+ if ((q = parse_string_value(&p, endptr))) {
+ const char *r = q, *e = q+strlen(q);
+ char *s, *t;
+ skip_blank(&r, e);
+ while (r < e) {
+ if ((s = parse_float_decimal(&r, e))) {
+ skip_blank(&r, e);
+ if ((t = parse_string_value(&r, e))) {
+ if (strcmp(t, "SlantFont") == 0)
+ mrec->opt.slant = atof(s);
+ else if (strcmp(t, "ExtendFont") == 0)
+ mrec->opt.extend = atof(s);
+ RELEASE(t);
+ }
+ RELEASE(s);
+ } else if ((s = parse_string_value(&r, e))) { /* skip */
+ RELEASE(s);
+ }
+ skip_blank(&r, e);
+ }
+ RELEASE(q);
+ }
+ skip_blank(&p, endptr);
+ break;
+
+ default:
+ WARN("Found an invalid entry: %s", p);
+ return -1;
+ }
+ skip_blank(&p, endptr);
+ }
+
+ if (p < endptr && *p != '\r' && *p != '\n') {
+ WARN("Invalid char in fontmap line: %c", *p);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static struct ht_table *fontmap = NULL;
+
+#define fontmap_invalid(m) (!(m) || !(m)->map_name || !(m)->font_name)
+static char *
+chop_sfd_name (const char *tex_name, char **sfd_name)
+{
+ char *fontname;
+ char *p, *q;
+ int m, n, len;
+
+ *sfd_name = NULL;
+
+ p = strchr(tex_name, '@');
+ if (!p ||
+ p[1] == '\0' || p == tex_name) {
+ return NULL;
+ }
+ m = (int) (p - tex_name);
+ p++;
+ q = strchr(p, '@');
+ if (!q || q == p) {
+ return NULL;
+ }
+ n = (int) (q - p);
+ q++;
+
+ len = strlen(tex_name) - n;
+ fontname = NEW(len+1, char);
+ memcpy(fontname, tex_name, m);
+ fontname[m] = '\0';
+ if (*q)
+ strcat(fontname, q);
+
+ *sfd_name = NEW(n+1, char);
+ memcpy(*sfd_name, p, n);
+ (*sfd_name)[n] = '\0';
+
+ return fontname;
+}
+
+static char *
+make_subfont_name (const char *map_name, const char *sfd_name, const char *sub_id)
+{
+ char *tfm_name;
+ int n, m;
+ char *p, *q;
+
+ p = strchr(map_name, '@');
+ if (!p || p == map_name)
+ return NULL;
+ m = (int) (p - map_name);
+ q = strchr(p + 1, '@');
+ if (!q || q == p + 1)
+ return NULL;
+ n = (int) (q - p) + 1; /* including two '@' */
+ if (strlen(sfd_name) != n - 2 ||
+ memcmp(p + 1, sfd_name, n - 2))
+ return NULL;
+ tfm_name = NEW(strlen(map_name) - n + strlen(sub_id) + 1, char);
+ memcpy(tfm_name, map_name, m);
+ tfm_name[m] = '\0';
+ strcat(tfm_name, sub_id);
+ if (q[1]) /* not ending with '@' */
+ strcat(tfm_name, q + 1);
+
+ return tfm_name;
+}
+
+/* "foo@A@ ..." is expanded to
+ * fooab ... -m sfd:A,ab
+ * ...
+ * fooyz ... -m sfd:A,yz
+ * where 'ab' ... 'yz' is subfont IDs in SFD 'A'.
+ */
+int
+pdf_append_fontmap_record (const char *kp, const fontmap_rec *vp)
+{
+ fontmap_rec *mrec;
+ char *fnt_name, *sfd_name = NULL;
+
+ if (!kp || fontmap_invalid(vp)) {
+ WARN("Invalid fontmap record...");
+ return -1;
+ }
+
+ if (dpx_conf.verbose_level > 3)
+ MESG("fontmap>> append key=\"%s\"...", kp);
+
+ fnt_name = chop_sfd_name(kp, &sfd_name);
+ if (fnt_name && sfd_name) {
+ char *tfm_name;
+ char **subfont_ids;
+ int n = 0;
+ subfont_ids = sfd_get_subfont_ids(sfd_name, &n);
+ if (!subfont_ids)
+ return -1;
+ while (n-- > 0) {
+ tfm_name = make_subfont_name(kp, sfd_name, subfont_ids[n]);
+ if (!tfm_name)
+ continue;
+ mrec = ht_lookup_table(fontmap, tfm_name, strlen(tfm_name));
+ if (!mrec) {
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+ mrec->map_name = mstrdup(kp); /* link */
+ mrec->charmap.sfd_name = mstrdup(sfd_name);
+ mrec->charmap.subfont_id = mstrdup(subfont_ids[n]);
+ ht_insert_table(fontmap, tfm_name, strlen(tfm_name), mrec);
+ }
+ RELEASE(tfm_name);
+ }
+ RELEASE(fnt_name);
+ RELEASE(sfd_name);
+ }
+
+ mrec = ht_lookup_table(fontmap, kp, strlen(kp));
+ if (!mrec) {
+ mrec = NEW(1, fontmap_rec);
+ pdf_copy_fontmap_record(mrec, vp);
+ if (mrec->map_name && !strcmp(kp, mrec->map_name)) {
+ RELEASE(mrec->map_name);
+ mrec->map_name = NULL;
+ }
+ ht_insert_table(fontmap, kp, strlen(kp), mrec);
+ }
+ if (dpx_conf.verbose_level > 3)
+ MESG("\n");
+
+ return 0;
+}
+
+int
+pdf_remove_fontmap_record (const char *kp)
+{
+ char *fnt_name, *sfd_name = NULL;
+
+ if (!kp)
+ return -1;
+
+ if (dpx_conf.verbose_level > 3)
+ MESG("fontmap>> remove key=\"%s\"...", kp);
+
+ fnt_name = chop_sfd_name(kp, &sfd_name);
+ if (fnt_name && sfd_name) {
+ char *tfm_name;
+ char **subfont_ids;
+ int n = 0;
+ subfont_ids = sfd_get_subfont_ids(sfd_name, &n);
+ if (!subfont_ids)
+ return -1;
+ if (dpx_conf.verbose_level > 3)
+ MESG("\nfontmap>> Expand @%s@:", sfd_name);
+ while (n-- > 0) {
+ tfm_name = make_subfont_name(kp, sfd_name, subfont_ids[n]);
+ if (!tfm_name)
+ continue;
+ if (dpx_conf.verbose_level > 3)
+ MESG(" %s", tfm_name);
+ ht_remove_table(fontmap, tfm_name, strlen(tfm_name));
+ RELEASE(tfm_name);
+ }
+ RELEASE(fnt_name);
+ RELEASE(sfd_name);
+ }
+
+ ht_remove_table(fontmap, kp, strlen(kp));
+
+ if (dpx_conf.verbose_level > 3)
+ MESG("\n");
+
+ return 0;
+}
+
+fontmap_rec *
+pdf_insert_fontmap_record (const char *kp, const fontmap_rec *vp)
+{
+ fontmap_rec *mrec;
+ char *fnt_name, *sfd_name;
+
+ if (!kp || fontmap_invalid(vp)) {
+ WARN("Invalid fontmap record...");
+ return NULL;
+ }
+
+ if (dpx_conf.verbose_level > 3)
+ MESG("fontmap>> insert key=\"%s\"...", kp);
+
+ fnt_name = chop_sfd_name(kp, &sfd_name);
+ if (fnt_name && sfd_name) {
+ char *tfm_name;
+ char **subfont_ids;
+ int n = 0;
+ subfont_ids = sfd_get_subfont_ids(sfd_name, &n);
+ if (!subfont_ids) {
+ RELEASE(fnt_name);
+ RELEASE(sfd_name);
+ WARN("Could not open SFD file: %s", sfd_name);
+ return NULL;
+ }
+ if (dpx_conf.verbose_level > 3)
+ MESG("\nfontmap>> Expand @%s@:", sfd_name);
+ while (n-- > 0) {
+ tfm_name = make_subfont_name(kp, sfd_name, subfont_ids[n]);
+ if (!tfm_name)
+ continue;
+ if (dpx_conf.verbose_level > 3)
+ MESG(" %s", tfm_name);
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+ mrec->map_name = mstrdup(kp); /* link to this entry */
+ mrec->charmap.sfd_name = mstrdup(sfd_name);
+ mrec->charmap.subfont_id = mstrdup(subfont_ids[n]);
+ ht_insert_table(fontmap, tfm_name, strlen(tfm_name), mrec);
+ RELEASE(tfm_name);
+ }
+ RELEASE(fnt_name);
+ RELEASE(sfd_name);
+ }
+
+ mrec = NEW(1, fontmap_rec);
+ pdf_copy_fontmap_record(mrec, vp);
+ if (mrec->map_name && !strcmp(kp, mrec->map_name)) {
+ RELEASE(mrec->map_name);
+ mrec->map_name = NULL;
+ }
+ ht_insert_table(fontmap, kp, strlen(kp), mrec);
+
+ if (dpx_conf.verbose_level > 3)
+ MESG("\n");
+
+ return mrec;
+}
+
+
+int
+pdf_read_fontmap_line (fontmap_rec *mrec, const char *mline, int mline_len, int format)
+{
+ int error;
+ char *q;
+ const char *p, *endptr;
+
+ ASSERT(mrec);
+
+ p = mline;
+ endptr = p + mline_len;
+
+ skip_blank(&p, endptr);
+ if (p >= endptr)
+ return -1;
+
+ q = parse_string_value(&p, endptr);
+ if (!q)
+ return -1;
+
+ if (format > 0) /* DVIPDFM format */
+ error = fontmap_parse_mapdef_dpm(mrec, p, endptr);
+ else /* DVIPS/pdfTeX format */
+ error = fontmap_parse_mapdef_dps(mrec, p, endptr);
+ if (!error) {
+ char *fnt_name, *sfd_name = NULL;
+ fnt_name = chop_sfd_name(q, &sfd_name);
+ if (fnt_name && sfd_name) {
+ if (!mrec->font_name) {
+ /* In the case of subfonts, the base name (before the character '@')
+ * will be used as a font_name by default.
+ * Otherwise tex_name will be used as a font_name by default.
+ */
+ mrec->font_name = fnt_name;
+ } else {
+ RELEASE(fnt_name);
+ }
+ if (mrec->charmap.sfd_name)
+ RELEASE(mrec->charmap.sfd_name);
+ mrec->charmap.sfd_name = sfd_name ;
+ }
+ fill_in_defaults(mrec, q);
+ }
+ RELEASE(q);
+
+ return error;
+}
+
+/* DVIPS/pdfTeX fontmap line if one of the following three cases found:
+ *
+ * (1) any line including the character '"'
+ * (2) any line including the character '<'
+ * (3) if the line consists of two entries (tfmname and psname)
+ *
+ * DVIPDFM fontmap line otherwise.
+ */
+int
+is_pdfm_mapline (const char *mline) /* NULL terminated. */
+{
+ int n = 0;
+ const char *p, *endptr;
+
+ if (strchr(mline, '"') || strchr(mline, '<'))
+ return -1; /* DVIPS/pdfTeX format */
+
+ p = mline;
+ endptr = p + strlen(mline);
+
+ skip_blank(&p, endptr);
+
+ while (p < endptr) {
+ /* Break if '-' preceeded by blanks is found. (DVIPDFM format) */
+ if (*p == '-') return 1;
+ for (n++; p < endptr && !ISBLANK(*p); p++);
+ skip_blank(&p, endptr);
+ }
+
+ /* Two entries: TFM_NAME PS_NAME only (DVIPS format)
+ * Otherwise (DVIPDFM format) */
+ return (n == 2 ? 0 : 1);
+}
+
+int
+pdf_load_fontmap_file (const char *filename, int mode)
+{
+ fontmap_rec *mrec;
+ FILE *fp;
+ const char *p = NULL, *endptr;
+ int llen, lpos = 0;
+ int error = 0, format = 0;
+
+ ASSERT(filename);
+ ASSERT(fontmap) ;
+
+ if (dpx_conf.verbose_level > 0)
+ MESG("<FONTMAP:");
+ fp = DPXFOPEN(filename, DPX_RES_TYPE_FONTMAP); /* outputs path if verbose */
+ if (!fp) {
+ WARN("Couldn't open font map file \"%s\".", filename);
+ return -1;
+ }
+
+ while (!error &&
+ (p = readline(work_buffer, WORK_BUFFER_SIZE, fp)) != NULL) {
+ int m;
+
+ lpos++;
+ llen = strlen(work_buffer);
+ endptr = p + llen;
+
+ skip_blank(&p, endptr);
+ if (p == endptr)
+ continue;
+
+ m = is_pdfm_mapline(p);
+
+ if (format * m < 0) { /* mismatch */
+ WARN("Found a mismatched fontmap line %d from %s.", lpos, filename);
+ WARN("-- Ignore the current input buffer: %s", p);
+ continue;
+ } else
+ format += m;
+
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+
+ /* format > 0: DVIPDFM, format <= 0: DVIPS/pdfTeX */
+ error = pdf_read_fontmap_line(mrec, p, llen, format);
+ if (error) {
+ WARN("Invalid map record in fontmap line %d from %s.", lpos, filename);
+ WARN("-- Ignore the current input buffer: %s", p);
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+ continue;
+ } else {
+ switch (mode) {
+ case FONTMAP_RMODE_REPLACE:
+ pdf_insert_fontmap_record(mrec->map_name, mrec);
+ break;
+ case FONTMAP_RMODE_APPEND:
+ pdf_append_fontmap_record(mrec->map_name, mrec);
+ break;
+ case FONTMAP_RMODE_REMOVE:
+ pdf_remove_fontmap_record(mrec->map_name);
+ break;
+ }
+ }
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+ }
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(">");
+
+ return error;
+}
+
+fontmap_rec *
+pdf_insert_native_fontmap_record (const char *path, uint32_t index,
+ int layout_dir, int extend, int slant, int embolden)
+{
+ char *fontmap_key;
+ fontmap_rec *mrec;
+ fontmap_rec *ret;
+
+ ASSERT(path);
+
+ fontmap_key = malloc(strlen(path) + 40); // CHECK
+ sprintf(fontmap_key, "%s/%d/%c/%d/%d/%d", path, index, layout_dir == 0 ? 'H' : 'V', extend, slant, embolden);
+
+ if (dpx_conf.verbose_level > 0)
+ MESG("<NATIVE-FONTMAP:%s", fontmap_key);
+
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+
+ mrec->map_name = fontmap_key;
+ mrec->enc_name = mstrdup(layout_dir == 0 ? "Identity-H" : "Identity-V");
+ mrec->font_name = mstrdup(path);
+ mrec->opt.index = index;
+ if (layout_dir != 0)
+ mrec->opt.flags |= FONTMAP_OPT_VERT;
+
+ fill_in_defaults(mrec, fontmap_key);
+
+ mrec->opt.extend = extend / 65536.0;
+ mrec->opt.slant = slant / 65536.0;
+ mrec->opt.bold = embolden / 65536.0;
+ mrec->opt.use_glyph_encoding = 1;
+
+ ret = pdf_insert_fontmap_record(mrec->map_name, mrec);
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(">");
+
+ return ret;
+}
+
+#if 0
+/* tfm_name="dmjhira10", map_name="dmj@DNP@10", sfd_name="DNP"
+ * --> sub_id="hira"
+ * Test if tfm_name can be really considered as subfont.
+ */
+static int
+test_subfont (const char *tfm_name, const char *map_name, const char *sfd_name)
+{
+ int r = 0;
+ char **ids;
+ int n, m;
+ char *p = (char *) map_name;
+ char *q = (char *) tfm_name;
+
+ ASSERT( tfm_name && map_name && sfd_name );
+
+ /* until first occurence of '@' */
+ for ( ; *p && *q && *p == *q && *p != '@'; p++, q++);
+ if (*p != '@')
+ return 0;
+ p++;
+ /* compare sfd_name (should be always true here) */
+ if (strlen(p) <= strlen(sfd_name) ||
+ memcmp(p, sfd_name, strlen(sfd_name)) ||
+ p[strlen(sfd_name)] != '@')
+ return 0;
+ /* check tfm_name follows second '@' */
+ p += strlen(sfd_name) + 1;
+ if (*p) {
+ char *r = (char *) tfm_name;
+ r += strlen(tfm_name) - strlen(p);
+ if (strcmp(r, p))
+ return 0;
+ }
+ /* Now 'p' is located at next to SFD name terminator
+ * (second '@') in map_name and 'q' is at first char
+ * of subfont_id substring in tfm_name.
+ */
+ n = strlen(q) - strlen(p); /* length of subfont_id string */
+ if (n <= 0)
+ return 0;
+ /* check if n-length substring 'q' is valid as subfont ID */
+ ids = sfd_get_subfont_ids(sfd_name, &m);
+ if (!ids)
+ return 0;
+ while (!r && m-- > 0) {
+ if (strlen(ids[m]) == n &&
+ !memcmp(q, ids[m], n)) {
+ r = 1;
+ }
+ }
+
+ return r;
+}
+#endif /* 0 */
+
+
+fontmap_rec *
+pdf_lookup_fontmap_record (const char *tfm_name)
+{
+ fontmap_rec *mrec = NULL;
+
+ if (fontmap && tfm_name)
+ mrec = ht_lookup_table(fontmap, tfm_name, strlen(tfm_name));
+
+ return mrec;
+}
+
+
+void
+pdf_init_fontmaps (void)
+{
+ fontmap = NEW(1, struct ht_table);
+ ht_init_table(fontmap, hval_free);
+}
+
+void
+pdf_close_fontmaps (void)
+{
+ if (fontmap) {
+ ht_clear_table(fontmap);
+ RELEASE(fontmap);
+ }
+ fontmap = NULL;
+
+ release_sfd_record();
+}
+
+#if 0
+void
+pdf_clear_fontmaps (void)
+{
+ pdf_close_fontmaps();
+ pdf_init_fontmaps();
+}
+#endif
+
+/* CIDFont options
+ *
+ * FORMAT:
+ *
+ * (:int:)?!?string(/string)?(,string)?
+ */
+
+static char *
+substr (const char **str, char stop)
+{
+ char *sstr;
+ const char *endptr;
+
+ endptr = strchr(*str, stop);
+ if (!endptr || endptr == *str)
+ return NULL;
+ sstr = NEW(endptr-(*str)+1, char);
+ memcpy(sstr, *str, endptr-(*str));
+ sstr[endptr-(*str)] = '\0';
+
+ *str = endptr+1;
+ return sstr;
+}
+
+#include <ctype.h>
+#define CID_MAPREC_CSI_DELIM '/'
+
+static char *
+strip_options (const char *map_name, fontmap_opt *opt)
+{
+ char *font_name;
+ const char *p;
+ char *next = NULL;
+ int have_csi = 0, have_style = 0;
+
+ ASSERT(opt);
+
+ p = map_name;
+ font_name = NULL;
+ opt->charcoll = NULL;
+ opt->index = 0;
+ opt->style = FONTMAP_STYLE_NONE;
+ opt->flags = 0;
+
+ if (*p == ':' && isdigit((unsigned char)*(p+1))) {
+ opt->index = strtoul(p+1, &next, 10);
+ if (*next == ':')
+ p = next + 1;
+ else {
+ opt->index = 0;
+ }
+ }
+ if (*p == '!') { /* no-embedding */
+ if (*(++p) == '\0')
+ ERROR("Invalid map record: %s (--> %s)", map_name, p);
+ opt->flags |= FONTMAP_OPT_NOEMBED;
+ }
+
+ if ((next = strchr(p, CID_MAPREC_CSI_DELIM)) != NULL) {
+ if (next == p)
+ ERROR("Invalid map record: %s (--> %s)", map_name, p);
+ font_name = substr(&p, CID_MAPREC_CSI_DELIM);
+ have_csi = 1;
+ } else if ((next = strchr(p, ',')) != NULL) {
+ if (next == p)
+ ERROR("Invalid map record: %s (--> %s)", map_name, p);
+ font_name = substr(&p, ',');
+ have_style = 1;
+ } else {
+ font_name = NEW(strlen(p)+1, char);
+ strcpy(font_name, p);
+ }
+
+ if (have_csi) {
+ if ((next = strchr(p, ',')) != NULL) {
+ opt->charcoll = substr(&p, ',');
+ have_style = 1;
+ } else if (p[0] == '\0') {
+ ERROR("Invalid map record: %s.", map_name);
+ } else {
+ opt->charcoll = NEW(strlen(p)+1, char);
+ strcpy(opt->charcoll, p);
+ }
+ }
+
+ if (have_style) {
+ if (!strncmp(p, "BoldItalic", 10)) {
+ if (*(p+10))
+ ERROR("Invalid map record: %s (--> %s)", map_name, p);
+ opt->style = FONTMAP_STYLE_BOLDITALIC;
+ } else if (!strncmp(p, "Bold", 4)) {
+ if (*(p+4))
+ ERROR("Invalid map record: %s (--> %s)", map_name, p);
+ opt->style = FONTMAP_STYLE_BOLD;
+ } else if (!strncmp(p, "Italic", 6)) {
+ if (*(p+6))
+ ERROR("Invalid map record: %s (--> %s)", map_name, p);
+ opt->style = FONTMAP_STYLE_ITALIC;
+ }
+ }
+
+ return font_name;
+}
+
+#if DPXTEST
+static void
+dump_fontmap_rec (const char *key, const fontmap_rec *mrec)
+{
+ fontmap_opt *opt = (fontmap_opt *) &mrec->opt;
+
+ if (mrec->map_name)
+ fprintf(stdout, " <!-- subfont");
+ else
+ fprintf(stdout, " <insert");
+ fprintf(stdout, " id=\"%s\"", key);
+ if (mrec->map_name)
+ fprintf(stdout, " map-name=\"%s\"", mrec->map_name);
+ if (mrec->enc_name)
+ fprintf(stdout, " enc-name=\"%s\"", mrec->enc_name);
+ if (mrec->font_name)
+ fprintf(stdout, " font-name=\"%s\"", mrec->font_name);
+ if (mrec->charmap.sfd_name && mrec->charmap.subfont_id) {
+ fprintf(stdout, " charmap=\"sfd:%s,%s\"",
+ mrec->charmap.sfd_name, mrec->charmap.subfont_id);
+ }
+ if (opt->slant != 0.0)
+ fprintf(stdout, " font-slant=\"%g\"", opt->slant);
+ if (opt->extend != 1.0)
+ fprintf(stdout, " font-extend=\"%g\"", opt->extend);
+ if (opt->charcoll)
+ fprintf(stdout, " glyph-order=\"%s\"", opt->charcoll);
+ if (opt->tounicode)
+ fprintf(stdout, " tounicode=\"%s\"", opt->tounicode);
+ if (opt->index != 0)
+ fprintf(stdout, " ttc-index=\"%d\"", opt->index);
+ if (opt->flags & FONTMAP_OPT_NOEMBED)
+ fprintf(stdout, " embedding=\"no\"");
+ if (opt->mapc >= 0) {
+ fprintf(stdout, " charmap=\"pad:");
+ if (opt->mapc > 0xffff)
+ fprintf(stdout, "%02x %02x", (opt->mapc >> 16) & 0xff, (opt->mapc >> 8) & 0xff);
+ else
+ fprintf(stdout, "%02x", (opt->mapc >> 8) & 0xff);
+ fprintf(stdout, "\"");
+ }
+ if (opt->flags & FONTMAP_OPT_VERT)
+ fprintf(stdout, " writing-mode=\"vertical\"");
+ if (opt->style != FONTMAP_STYLE_NONE) {
+ fprintf(stdout, " font-style=\"");
+ switch (opt->style) {
+ case FONTMAP_STYLE_BOLD:
+ fprintf(stdout, "bold");
+ break;
+ case FONTMAP_STYLE_ITALIC:
+ fprintf(stdout, "italic");
+ break;
+ case FONTMAP_STYLE_BOLDITALIC:
+ fprintf(stdout, "bolditalic");
+ break;
+ }
+ fprintf(stdout, "\"");
+ }
+ if (mrec->map_name)
+ fprintf(stdout, " / -->\n");
+ else
+ fprintf(stdout, " />\n");
+}
+
+void
+dump_fontmaps (void)
+{
+ struct ht_iter iter;
+ fontmap_rec *mrec;
+ char key[128], *kp;
+ int kl;
+
+ if (!fontmap)
+ return;
+
+ fprintf(stdout, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ fprintf(stdout, "<!DOCTYPE fontmap SYSTEM \"fontmap.dtd\">\n");
+ fprintf(stdout, "<fontmap id=\"%s\">\n", "foo");
+ if (ht_set_iter(fontmap, &iter) == 0) {
+ do {
+ kp = ht_iter_getkey(&iter, &kl);
+ mrec = ht_iter_getval(&iter);
+ if (kl > 127)
+ continue;
+ memcpy(key, kp, kl); key[kl] = 0;
+ dump_fontmap_rec(key, mrec);
+ } while (!ht_iter_next(&iter));
+ }
+ ht_clear_iter(&iter);
+ fprintf(stdout, "</fontmap>\n");
+
+ return;
+}
+
+void
+test_fontmap_help (void)
+{
+ fprintf(stdout, "usage: fontmap [options] [mapfile...]\n");
+ fprintf(stdout, "-l, --lookup string\n");
+ fprintf(stdout, " Lookup fontmap entry for 'string' after loading mapfile(s).\n");
+}
+
+int
+test_fontmap_main (int argc, char *argv[])
+{
+ int i;
+ char *key = NULL;
+
+ for (;;) {
+ int c, optidx = 0;
+ static struct option long_options[] = {
+ {"lookup", 1, 0, 'l'},
+ {"help", 0, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "l:h", long_options, &optidx);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'l':
+ key = optarg;
+ break;
+ case 'h':
+ test_fontmap_help();
+ return 0;
+ break;
+ default:
+ test_fontmap_help();
+ return -1;
+ break;
+ }
+ }
+
+ pdf_init_fontmaps();
+ for (i = optind; i < argc; i++)
+ pdf_load_fontmap_file(argv[i], FONTMAP_RMODE_REPLACE);
+
+ if (key == NULL)
+ dump_fontmaps();
+ else {
+ fontmap_rec *mrec;
+ mrec = pdf_lookup_fontmap_record(key);
+ if (mrec)
+ dump_fontmap_rec(key, mrec);
+ else {
+ WARN("Fontmap entry \"%s\" not found.", key);
+ }
+ }
+ pdf_close_fontmaps();
+
+ return 0;
+}
+#endif /* DPXTEST */
diff --git a/Build/source/texk/dvipdfm-x/fontmap.h b/Build/source/texk/dvipdfm-x/fontmap.h
new file mode 100644
index 00000000000..64932127e89
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/fontmap.h
@@ -0,0 +1,96 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _FONTMAP_H_
+#define _FONTMAP_H_
+
+#define FONTMAP_RMODE_REPLACE 0
+#define FONTMAP_RMODE_APPEND '+'
+#define FONTMAP_RMODE_REMOVE '-'
+
+#define FONTMAP_OPT_NOEMBED (1 << 1)
+#define FONTMAP_OPT_VERT (1 << 2)
+
+#define FONTMAP_STYLE_NONE 0
+#define FONTMAP_STYLE_BOLD 1
+#define FONTMAP_STYLE_ITALIC 2
+#define FONTMAP_STYLE_BOLDITALIC 3
+
+/* Options */
+typedef struct fontmap_opt {
+ /* Synthetic font */
+ double slant, extend, bold;
+ /* comaptibility and other flags */
+ int mapc, flags;
+
+ char *otl_tags;
+ char *tounicode; /* not implemented yet */
+
+ double design_size; /* unused */
+
+ char *charcoll; /* Adobe-Japan1-4, etc. */
+ uint32_t index; /* TTC index */
+ int style; /* ,Bold, etc. */
+ int stemv; /* StemV value especially for CJK fonts */
+ int use_glyph_encoding; /* XeTeX support */
+} fontmap_opt;
+
+typedef struct fontmap_rec {
+ char *map_name;
+
+ char *font_name;
+ char *enc_name;
+
+ /* Subfont mapping: translate 8-bit charcode to 16-bit charcode
+ * via SFD.
+ */
+ struct {
+ char *sfd_name;
+ char *subfont_id;
+ } charmap;
+
+ fontmap_opt opt;
+} fontmap_rec;
+
+extern void pdf_init_fontmaps (void);
+#if 0
+extern void pdf_clear_fontmaps (void);
+#endif
+extern void pdf_close_fontmaps (void);
+
+extern void pdf_init_fontmap_record (fontmap_rec *mrec);
+extern void pdf_clear_fontmap_record (fontmap_rec *mrec);
+
+extern int pdf_load_fontmap_file (const char *filename, int mode);
+extern int pdf_read_fontmap_line (fontmap_rec *mrec, const char *mline, int mline_strlen, int format);
+
+extern int pdf_append_fontmap_record (const char *kp, const fontmap_rec *mrec);
+extern int pdf_remove_fontmap_record (const char *kp);
+extern fontmap_rec *pdf_insert_fontmap_record (const char *kp, const fontmap_rec *mrec);
+extern fontmap_rec *pdf_lookup_fontmap_record (const char *kp);
+
+extern int is_pdfm_mapline (const char *mline);
+
+extern fontmap_rec *pdf_insert_native_fontmap_record (const char *filename, uint32_t index,
+ int layout_dir, int extend, int slant, int embolden);
+
+#endif /* _FONTMAP_H_ */
diff --git a/Build/source/texk/dvipdfm-x/jp2image.c b/Build/source/texk/dvipdfm-x/jp2image.c
new file mode 100644
index 00000000000..f94d460db96
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/jp2image.c
@@ -0,0 +1,422 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Matthias Franz,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * JP2 & JPX baseline support
+ *
+ * 20150412 Added opacity (transparency) support.
+ * TODO: XMP Metadata
+ */
+
+#include <math.h>
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+
+#include "pdfobj.h"
+
+#include "jp2image.h"
+
+/* Box types. */
+#define JP2_BOX_JP__ 0x6a502020 /* Signature */
+#define JP2_BOX_FTYP 0x66747970 /* File Type */
+
+#define JP2_BOX_JP2H 0x6a703268 /* JP2 Header */
+#define JP2_BOX_IHDR 0x69686472 /* Image Header */
+#define JP2_BOX_BPCC 0x62706363 /* Bits Per Component */
+#define JP2_BOX_COLR 0x636f6c72 /* Color Specification */
+#define JP2_BOX_PCLR 0x70636c72 /* Palette */
+#define JP2_BOX_CMAP 0x636d6170 /* Component Mapping */
+#define JP2_BOX_CDEF 0x63646566 /* Channel Definition */
+#define JP2_BOX_RES_ 0x72657320 /* Resolution */
+#define JP2_BOX_RESC 0x72657363 /* Capture Resolution */
+#define JP2_BOX_RESD 0x72657364 /* Default Display Resolution */
+
+#define JP2_BOX_JP2C 0x6a703263 /* Contiguous Code Stream */
+
+#define JPX_BOX_LBL_ 0x6c626c20 /* Label */
+
+
+static unsigned int
+read_box_hdr (FILE *fp, unsigned int *lbox, unsigned int *tbox)
+{
+ unsigned int bytesread = 0;
+
+ *lbox = get_unsigned_quad(fp);
+ *tbox = get_unsigned_quad(fp);
+ bytesread += 8;
+ if (*lbox == 1) {
+ if (get_unsigned_quad(fp) != 0)
+ ERROR("JPEG2000: LBox value in JP2 file >32 bits.\nI can't handle this!");
+ *lbox = get_unsigned_quad(fp);
+ bytesread += 8;
+ } else if (*lbox > 1 && *lbox < 8) {
+ WARN("JPEG2000: Unknown LBox value %lu in JP2 file!", lbox);
+ }
+
+ return bytesread;
+}
+
+#define FTYP_BR_JP2_ 0x6a703220
+#define FTYP_BR_JPX_ 0x6a707820
+#define FTYP_CL_JPXB 0x6a707862
+
+static int
+check_jp___box (FILE *fp)
+{
+ if (get_unsigned_quad(fp) != 0x0c)
+ return 0;
+ if (get_unsigned_quad(fp) != JP2_BOX_JP__)
+ return 0;
+ /* Next 4 bytes shall be 0D 0A 87 0A */
+ if (get_unsigned_quad(fp) != 0x0D0A870A)
+ return 0;
+ return 1;
+}
+
+static int
+check_ftyp_data (FILE *fp, unsigned int size)
+{
+ int supported = 0;
+ unsigned int BR, CLi;
+
+ BR = get_unsigned_quad(fp);
+ size -= 4;
+ /* MinV = */ get_unsigned_quad(fp);
+ size -= 4;
+ switch (BR) {
+ case FTYP_BR_JP2_: /* "jp2 " ... supported */
+ seek_relative(fp, size);
+ size = 0;
+ supported = 1;
+ break;
+ case FTYP_BR_JPX_: /* "jpx " ... baseline subset supported */
+ while (size > 0) {
+ CLi = get_unsigned_quad(fp);
+ if (CLi == FTYP_CL_JPXB)
+ supported = 1;
+ size -= 4;
+ }
+ break;
+ default:
+ WARN("JPEG2000: Unknown JPEG 2000 File Type box Brand field value.");
+ seek_relative(fp, size);
+ size = 0;
+ supported = 0;
+ }
+
+ return supported;
+}
+
+
+static void
+read_res__data (ximage_info *info, FILE *fp, unsigned int size)
+{
+ unsigned int VR_N, VR_D, HR_N, HR_D;
+ unsigned char VR_E, HR_E;
+
+ VR_N = get_unsigned_pair(fp);
+ VR_D = get_unsigned_pair(fp);
+ HR_N = get_unsigned_pair(fp);
+ HR_D = get_unsigned_pair(fp);
+ VR_E = get_unsigned_byte(fp);
+ HR_E = get_unsigned_byte(fp);
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode)
+ info->xdensity = info->ydensity = 72.0 / 100.0;
+ else {
+ info->xdensity = 72.0/(((double) HR_N / HR_D) * pow(10.0, HR_E) * 0.0254);
+ info->ydensity = 72.0/(((double) VR_N / VR_D) * pow(10.0, VR_E) * 0.0254);
+ }
+}
+
+static int
+scan_res_ (ximage_info *info, FILE *fp, unsigned int size)
+{
+ unsigned int len, lbox, tbox;
+ int have_resd = 0;
+
+ while (size > 0) {
+ len = read_box_hdr(fp, &lbox, &tbox);
+ if (lbox == 0) {
+ WARN("JPEG2000: Unexpected lbox value 0 in JP2 Resolution box.");
+ break;
+ }
+ switch (tbox) {
+ case JP2_BOX_RESC:
+ if (!have_resd) {
+ read_res__data(info, fp, lbox - len);
+ } else {
+ seek_relative(fp, lbox - len);
+ }
+ break;
+ case JP2_BOX_RESD:
+ read_res__data(info, fp, lbox - len);
+ have_resd = 1;
+ break;
+ default:
+ WARN("JPEG2000: Unknown JPEG 2000 box type in Resolution box.");
+ seek_relative(fp, lbox - len);
+ }
+ size -= lbox;
+ }
+
+ return size == 0 ? 0 : -1;
+}
+
+/* Acrobat seems require Channel Definition box to be defined when image data
+ * contains opacity channel. However, OpenJPEG (and maybe most of JPEG 2000 coders?)
+ * does not write Channel Definition box so transparency will be ignored.
+ */
+static int
+scan_cdef (ximage_info *info, int *smask, FILE *fp, unsigned int size)
+{
+ int opacity_channels = 0;
+ int have_type0 = 0;
+ unsigned int i, Cn, N, Typ, Asoc;
+
+ *smask = 0;
+
+ N = get_unsigned_pair(fp);
+ if (size < N * 6 + 2) {
+ WARN("JPEG2000: Inconsistent N value in Channel Definition box.");
+ return -1;
+ }
+ for (i = 0; i < N; i++) {
+ Cn = get_unsigned_pair(fp); /* Cn */
+ Typ = get_unsigned_pair(fp);
+ Asoc = get_unsigned_pair(fp); /* must be 0 for SMask */
+ if (Cn > N)
+ WARN("JPEG2000: Invalid Cn value in Channel Definition box.");
+ if (Typ == 1) {
+ if (Asoc == 0)
+ have_type0 = 1;
+ opacity_channels++;
+ } else if (Typ == 2) {
+ opacity_channels++;
+ }
+ }
+
+ if (opacity_channels == 1)
+ *smask = have_type0 ? 1 : 0;
+ else if (opacity_channels > 1) {
+ WARN("JPEG2000: Unsupported transparency type. (ignored)");
+ }
+
+ return 0;
+}
+
+static int
+scan_jp2h (ximage_info *info, int *smask, FILE *fp, unsigned int size)
+{
+ int error = 0, have_ihdr = 0;
+ unsigned int len, lbox, tbox;
+
+ while (size > 0 && !error) {
+ len = read_box_hdr(fp, &lbox, &tbox);
+ if (lbox == 0) {
+ WARN("JPEG2000: Unexpected lbox value 0 in JP2 Header box...");
+ error = -1;
+ break;
+ }
+ switch (tbox) {
+ case JP2_BOX_IHDR:
+ info->height = get_unsigned_quad(fp);
+ info->width = get_unsigned_quad(fp);
+ info->num_components = get_unsigned_pair(fp);
+ /* c = */ get_unsigned_byte(fp); /* BPC - 1 */
+ /* c = */ get_unsigned_byte(fp); /* C: Compression type */
+ /* c = */ get_unsigned_byte(fp); /* UnkC */
+ /* c = */ get_unsigned_byte(fp); /* IPR */
+ have_ihdr = 1;
+ break;
+ case JP2_BOX_RES_:
+ error = scan_res_(info, fp, lbox - len);
+ break;
+ case JP2_BOX_CDEF:
+ error = scan_cdef(info, smask, fp, lbox - len);
+ break;
+ case JP2_BOX_BPCC: case JP2_BOX_COLR: case JP2_BOX_PCLR:
+ case JP2_BOX_CMAP:
+ case JPX_BOX_LBL_:
+ seek_relative(fp, lbox - len);
+ break;
+ default:
+ WARN("JPEG2000: Unknown JPEG 2000 box in JP2 Header box.");
+ seek_relative(fp, lbox - len);
+ error = -1;
+ }
+ size -= lbox;
+ }
+
+ if (!have_ihdr)
+ WARN("JPEG2000: Expecting JPEG 2000 Image Header box but could not find.");
+ return (!error && have_ihdr && size == 0) ? 0 : -1;
+}
+
+static int
+scan_file (ximage_info *info, int *smask, FILE *fp)
+{
+ int error = 0, have_jp2h = 0;
+ int size;
+ unsigned int len, lbox, tbox;
+
+
+ size = file_size(fp);
+
+ /* Should have already been checked before. */
+ /* JPEG 2000 Singature box */
+ if (!check_jp___box(fp))
+ return -1;
+ size -= 12;
+ /* File Type box shall immediately follow */
+ len = read_box_hdr(fp, &lbox, &tbox);
+ if (tbox != JP2_BOX_FTYP)
+ return -1;
+ if (!check_ftyp_data(fp, lbox - len))
+ return -1;
+ size -= lbox;
+
+ /* Search for JP2 Header box */
+ while (size > 0 && !error) {
+ len = read_box_hdr(fp, &lbox, &tbox);
+ if (lbox == 0)
+ lbox = size;
+ switch (tbox) {
+ case JP2_BOX_JP2H:
+ error = scan_jp2h(info, smask, fp, lbox - len);
+ have_jp2h = 1;
+ break;
+ case JP2_BOX_JP2C:
+ /* JP2 requires JP2H appears before JP2C. */
+ if (!have_jp2h)
+ WARN("JPEG2000: JPEG 2000 Codestream box found before JP2 Header box.");
+ seek_relative(fp, lbox - len);
+ break;
+ default:
+ seek_relative(fp, lbox - len);
+ }
+ size -= lbox;
+ }
+
+ /* From ISO/IEC 15444-2 M.9.2.7
+ * The JP2 Header box shall be found in the file before the first
+ * Contiguous Codestream box, Fragment Table box, Media Data box,
+ * Codestream Header box, and Compositing Layer Header box. ...
+ */
+ if (!have_jp2h && !error) {
+ WARN("JPEG2000: No JP2 Header box found. Not a JP2/JPX baseline file?");
+ error = -1;
+ }
+ return error;
+}
+
+int
+check_for_jp2 (FILE *fp)
+{
+ unsigned int len, lbox, tbox;
+
+ if (!fp)
+ return 0;
+
+ rewind(fp);
+
+ /* JPEG 2000 Singature box */
+ if (!check_jp___box(fp))
+ return 0;
+
+ /* File Type box shall immediately follow */
+ len = read_box_hdr(fp, &lbox, &tbox);
+ if (tbox != JP2_BOX_FTYP)
+ return 0;
+ if (!check_ftyp_data(fp, lbox - len))
+ return 0;
+
+ return 1;
+}
+
+int
+jp2_include_image (pdf_ximage *ximage, FILE *fp)
+{
+ int smask = 0;
+ pdf_obj *stream, *stream_dict;
+ ximage_info info;
+
+ if (pdf_check_version(1, 5) < 0) {
+ WARN("JPEG 2000 support requires PDF version >= 1.5 (Current setting %d.%d)\n", pdf_get_version_major(), pdf_get_version_minor());
+ return -1;
+ }
+
+ pdf_ximage_init_image_info(&info);
+ stream = stream_dict = NULL;
+
+ rewind(fp);
+ if (scan_file(&info, &smask, fp) < 0) {
+ WARN("JPEG2000: Reading JPEG 2000 file failed.");
+ return -1;
+ }
+
+ stream = pdf_new_stream(0);
+ stream_dict = pdf_stream_dict(stream);
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Filter"), pdf_new_name("JPXDecode"));
+ if (smask)
+ pdf_add_dict(stream_dict,
+ pdf_new_name("SMaskInData"), pdf_new_number(1));
+ /* Read whole file */
+ {
+ int nb_read;
+ rewind(fp);
+ while ((nb_read =
+ fread(work_buffer, sizeof(char), WORK_BUFFER_SIZE, fp)) > 0)
+ pdf_add_stream(stream, work_buffer, nb_read);
+ }
+
+ pdf_ximage_set_image(ximage, &info, stream);
+
+ return 0;
+}
+
+int
+jp2_get_bbox (FILE *fp, int *width, int *height,
+ double *xdensity, double *ydensity)
+{
+ int r, smask = 0;
+ ximage_info info;
+
+ pdf_ximage_init_image_info(&info);
+
+ rewind(fp);
+ r = scan_file(&info, &smask, fp);
+
+ *width = info.width;
+ *height = info.height;
+ *xdensity = info.xdensity;
+ *ydensity = info.ydensity;
+
+ return r;
+}
diff --git a/Build/source/texk/dvipdfm-x/jp2image.h b/Build/source/texk/dvipdfm-x/jp2image.h
new file mode 100644
index 00000000000..068305a6cfc
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/jp2image.h
@@ -0,0 +1,36 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Matthias Franz,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _JP2IMAGE_H_
+#define _JP2IMAGE_H_
+
+#include "mfileio.h"
+#include "pdfximage.h"
+
+extern int check_for_jp2 (FILE *fp);
+extern int jp2_include_image (pdf_ximage *ximage, FILE *fp);
+extern int jp2_get_bbox (FILE *fp, int *width, int *height,
+ double *xdensity, double *ydensity);
+
+#endif /* _JP2IMAGE_H_ */
+
+
diff --git a/Build/source/texk/dvipdfm-x/jpegimage.c b/Build/source/texk/dvipdfm-x/jpegimage.c
new file mode 100644
index 00000000000..b7a4a5275cc
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/jpegimage.c
@@ -0,0 +1,1102 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * JPEG SUPPORT
+ *
+ * Accroding to Libjpeg document:
+ *
+ * CAUTION: it appears that Adobe Photoshop writes inverted data in CMYK
+ * JPEG files: 0 represents 100% ink coverage, rather than 0% ink as you'd
+ * expect....
+ *
+ * To wrok with this problem, we must detect whether CMYK JPEG file is
+ * created by Photoshop. But there are no reliable way to determine this.
+ *
+ * According to Adobe Technical Note #5516,
+ * "Supporting the DCT Filters in PostScript Level 2", Section 18, p.27.
+ *
+ * DCTDecode ignores and skips any APPE marker segment does not begin with
+ * the `Adobe' 5-character string.
+ *
+ * PDF Reference Manual 4th ed., p.61-62.
+ *
+ * The JPEG filter implementation in Adobe Acrobat products does not
+ * support features of the JPEG standard that are irrelevant to images.
+ * In addition, certain choices have been made regarding reserved marker
+ * codes and other optional features of the standard. For details, see
+ * Adobe Technical Note #5116, Supporting the DCT Filters in PostScript
+ * Level 2.
+ */
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "mfileio.h"
+#include "numbers.h"
+
+#include "dpxconf.h"
+
+#include "pdfobj.h"
+
+#include "jpegimage.h"
+#include "pdfcolor.h"
+
+#include "pdfximage.h"
+
+#define JPEG_DEBUG_STR "JPEG"
+#define JPEG_DEBUG 3
+
+#ifdef HAVE_LIBJPEG
+#include <jpeglib.h>
+#endif /* HAVE_LIBJPEG */
+
+/* JPEG Markers */
+typedef enum {
+ JM_SOF0 = 0xc0,
+ JM_SOF1 = 0xc1,
+ JM_SOF2 = 0xc2,
+ JM_SOF3 = 0xc3,
+ JM_SOF5 = 0xc5,
+ JM_DHT = 0xc4,
+ JM_SOF6 = 0xc6,
+ JM_SOF7 = 0xc7,
+ JM_SOF9 = 0xc9,
+ JM_SOF10 = 0xca,
+ JM_SOF11 = 0xcb,
+ JM_DAC = 0xcc,
+ JM_SOF13 = 0xcd,
+ JM_SOF14 = 0xce,
+ JM_SOF15 = 0xcf,
+
+ JM_RST0 = 0xd0,
+ JM_RST1 = 0xd1,
+ JM_RST2 = 0xd2,
+ JM_RST3 = 0xd3,
+ JM_RST4 = 0xd4,
+ JM_RST5 = 0xd5,
+ JM_RST6 = 0xd6,
+ JM_RST7 = 0xd7,
+
+ JM_SOI = 0xd8,
+ JM_EOI = 0xd9,
+ JM_SOS = 0xda,
+ JM_DQT = 0xdb,
+ JM_DNL = 0xdc,
+ JM_DRI = 0xdd,
+ JM_DHP = 0xde,
+ JM_EXP = 0xdf,
+
+ JM_APP0 = 0xe0,
+ JM_APP1 = 0xe1,
+ JM_APP2 = 0xe2,
+ JM_APP14 = 0xee,
+ JM_APP15 = 0xef,
+
+ JM_COM = 0xfe
+} JPEG_marker;
+
+typedef enum {
+ JS_APPn_JFIF,
+ JS_APPn_ADOBE,
+ JS_APPn_ICC,
+ JS_APPn_XMP
+} JPEG_APPn_sig;
+
+struct JPEG_APPn_JFIF /* APP0 */
+{
+ uint16_t version;
+ uint8_t units; /* 0: only aspect ratio
+ * 1: dots per inch
+ * 2: dots per cm
+ */
+ uint16_t Xdensity;
+ uint16_t Ydensity;
+ uint8_t Xthumbnail;
+ uint8_t Ythumbnail;
+ unsigned char *thumbnail; /* Thumbnail data. */
+};
+
+struct JPEG_APPn_ICC /* APP2 */
+{
+ uint8_t seq_id;
+ uint8_t num_chunks;
+ unsigned char *chunk;
+
+ /* Length of ICC profile data in this chunk. */
+ size_t length;
+};
+
+struct JPEG_APPn_Adobe /* APP14 */
+{
+ uint16_t version;
+ uint16_t flag0;
+ uint16_t flag1;
+ uint8_t transform; /* color transform code */
+};
+
+struct JPEG_APPn_XMP /* APP1 */
+{
+ unsigned char *packet; /* XMP packet */
+
+ /* Length of XMP packet data */
+ size_t length;
+};
+
+struct JPEG_ext
+{
+ JPEG_marker marker;
+ JPEG_APPn_sig app_sig;
+ void *app_data;
+};
+
+#define MAX_COUNT 1024
+struct JPEG_info
+{
+ uint16_t height;
+ uint16_t width;
+
+ uint8_t bits_per_component;
+ uint8_t num_components;
+
+ double xdpi;
+ double ydpi;
+
+ /* Application specific extensions */
+ int flags;
+ int num_appn, max_appn;
+ struct JPEG_ext *appn;
+
+ /* Skip chunks not necessary. */
+ char skipbits[MAX_COUNT / 8 + 1];
+};
+
+#define HAVE_APPn_JFIF (1 << 0)
+#define HAVE_APPn_ADOBE (1 << 1)
+#define HAVE_APPn_ICC (1 << 2)
+#define HAVE_APPn_Exif (1 << 3)
+#define HAVE_APPn_XMP (1 << 4)
+
+static int JPEG_scan_file (struct JPEG_info *j_info, FILE *fp);
+static int JPEG_copy_stream (struct JPEG_info *j_info, pdf_obj *stream, FILE *fp);
+
+static void JPEG_info_init (struct JPEG_info *j_info);
+static void JPEG_info_clear (struct JPEG_info *j_info);
+static pdf_obj *JPEG_get_XMP (struct JPEG_info *j_info);
+static pdf_obj *JPEG_get_iccp (struct JPEG_info *j_info);
+static void jpeg_get_density (struct JPEG_info *j_info, double *xdensity, double *ydensity);
+
+int
+check_for_jpeg (FILE *fp)
+{
+ unsigned char jpeg_sig[2];
+
+ rewind(fp);
+ if (fread(jpeg_sig, sizeof(unsigned char), 2, fp) != 2)
+ return 0;
+ else if (jpeg_sig[0] != 0xff || jpeg_sig[1] != JM_SOI)
+ return 0;
+
+ return 1;
+}
+
+int
+jpeg_include_image (pdf_ximage *ximage, FILE *fp)
+{
+ pdf_obj *stream;
+ pdf_obj *stream_dict;
+ pdf_obj *colorspace;
+ int colortype;
+ ximage_info info;
+ struct JPEG_info j_info;
+
+ if (!check_for_jpeg(fp)) {
+ WARN("%s: Not a JPEG file?", JPEG_DEBUG_STR);
+ rewind(fp);
+ return -1;
+ }
+ /* File position is 2 here... */
+
+ pdf_ximage_init_image_info(&info);
+
+ JPEG_info_init(&j_info);
+
+ if (JPEG_scan_file(&j_info, fp) < 0) {
+ WARN("%s: Not a JPEG file?", JPEG_DEBUG_STR);
+ JPEG_info_clear(&j_info);
+ return -1;
+ }
+
+ switch (j_info.num_components) {
+ case 1:
+ colortype = PDF_COLORSPACE_TYPE_GRAY;
+ break;
+ case 3:
+ colortype = PDF_COLORSPACE_TYPE_RGB;
+ break;
+ case 4:
+ colortype = PDF_COLORSPACE_TYPE_CMYK;
+ break;
+ default:
+ WARN("%s: Unknown color space (num components: %d)", JPEG_DEBUG_STR, info.num_components);
+ JPEG_info_clear(&j_info);
+ return -1;
+ }
+
+ /* JPEG image use DCTDecode. */
+ stream = pdf_new_stream (0);
+ stream_dict = pdf_stream_dict(stream);
+ pdf_add_dict(stream_dict, pdf_new_name("Filter"), pdf_new_name("DCTDecode"));
+
+ /* XMP Metadata */
+ if (pdf_check_version(1, 4) >= 0) {
+ if (j_info.flags & HAVE_APPn_XMP) {
+ pdf_obj *XMP_stream;
+
+ XMP_stream = JPEG_get_XMP(&j_info);
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Metadata"), pdf_ref_obj(XMP_stream));
+ pdf_release_obj(XMP_stream);
+ }
+ }
+
+ /* Check embedded ICC Profile */
+ colorspace = NULL;
+ if (j_info.flags & HAVE_APPn_ICC) {
+ pdf_obj *icc_stream, *intent;
+ int cspc_id;
+
+ icc_stream = JPEG_get_iccp(&j_info);
+ if (!icc_stream)
+ colorspace = NULL;
+ else {
+ if (iccp_check_colorspace(colortype,
+ pdf_stream_dataptr(icc_stream), pdf_stream_length (icc_stream)) < 0)
+ colorspace = NULL;
+ else {
+ cspc_id = iccp_load_profile(NULL, /* noname */
+ pdf_stream_dataptr(icc_stream),
+ pdf_stream_length (icc_stream));
+ if (cspc_id < 0)
+ colorspace = NULL;
+ else {
+ colorspace = pdf_get_colorspace_reference(cspc_id);
+ intent = iccp_get_rendering_intent(pdf_stream_dataptr(icc_stream),
+ pdf_stream_length (icc_stream));
+ if (intent)
+ pdf_add_dict(stream_dict, pdf_new_name("Intent"), intent);
+ }
+ }
+ pdf_release_obj(icc_stream);
+ }
+ }
+ /* No ICC or invalid ICC profile. */
+ if (!colorspace) {
+ switch (colortype) {
+ case PDF_COLORSPACE_TYPE_GRAY:
+ colorspace = pdf_new_name("DeviceGray");
+ break;
+ case PDF_COLORSPACE_TYPE_RGB:
+ colorspace = pdf_new_name("DeviceRGB");
+ break;
+ case PDF_COLORSPACE_TYPE_CMYK:
+ colorspace = pdf_new_name("DeviceCMYK");
+ break;
+ }
+ }
+ pdf_add_dict(stream_dict, pdf_new_name("ColorSpace"), colorspace);
+
+#define IS_ADOBE_CMYK(j) (((j).flags & HAVE_APPn_ADOBE) && (j).num_components == 4)
+ if (IS_ADOBE_CMYK(j_info)) {
+ pdf_obj *decode;
+ int i;
+
+ WARN("Adobe CMYK JPEG: Inverted color assumed.");
+ decode = pdf_new_array();
+ for (i = 0; i < j_info.num_components; i++) {
+ pdf_add_array(decode, pdf_new_number(1.0));
+ pdf_add_array(decode, pdf_new_number(0.0));
+ }
+ pdf_add_dict(stream_dict, pdf_new_name("Decode"), decode);
+ }
+
+ /* Copy file */
+ JPEG_copy_stream(&j_info, stream, fp);
+
+ info.width = j_info.width;
+ info.height = j_info.height;
+ info.bits_per_component = j_info.bits_per_component;
+ info.num_components = j_info.num_components;
+
+ jpeg_get_density(&j_info, &info.xdensity, &info.ydensity);
+
+ pdf_ximage_set_image(ximage, &info, stream);
+ JPEG_info_clear(&j_info);
+
+ return 0;
+}
+
+static void
+jpeg_get_density (struct JPEG_info *j_info, double *xdensity, double *ydensity)
+{
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode) {
+ *xdensity = *ydensity = 72.0 / 100.0;
+ return;
+ }
+
+/*
+ * j_info->xdpi and j_info->ydpi are determined in most cases
+ * in JPEG_scan_file(). FIXME: However, in some kinds of JPEG files,
+ * j_info->xdpi, and j_info->ydpi are not determined in
+ * JPEG_scan_file(). In this case we assume
+ * that j_info->xdpi = j_info->ydpi = 72.0.
+ */
+ if (j_info->xdpi < 0.1 && j_info->ydpi < 0.1) {
+ j_info->xdpi = j_info->ydpi = 72.0;
+ }
+ *xdensity = 72.0 / j_info->xdpi;
+ *ydensity = 72.0 / j_info->ydpi;
+
+ return;
+}
+
+static void
+JPEG_info_init (struct JPEG_info *j_info)
+{
+ j_info->width = 0;
+ j_info->height = 0;
+ j_info->bits_per_component = 0;
+ j_info->num_components = 0;
+
+ j_info->xdpi = 0.0;
+ j_info->ydpi = 0.0;
+
+ j_info->flags = 0;
+ j_info->num_appn = 0;
+ j_info->max_appn = 0;
+ j_info->appn = NULL;
+
+ memset(j_info->skipbits, 0, MAX_COUNT / 8 + 1);
+}
+
+static void
+JPEG_release_APPn_data (JPEG_marker marker, JPEG_APPn_sig app_sig, void *app_data)
+{
+ if (marker == JM_APP0 &&
+ app_sig == JS_APPn_JFIF) {
+ struct JPEG_APPn_JFIF *data;
+
+ data = (struct JPEG_APPn_JFIF *) app_data;
+ if (data->thumbnail)
+ RELEASE(data->thumbnail);
+ data->thumbnail = NULL;
+
+ RELEASE(data);
+ } else if (marker == JM_APP2 && app_sig == JS_APPn_ICC) {
+ struct JPEG_APPn_ICC *data;
+
+ data = (struct JPEG_APPn_ICC *) app_data;
+ if (data->chunk)
+ RELEASE(data->chunk);
+ data->chunk = NULL;
+
+ RELEASE(data);
+ } else if (marker == JM_APP14 && app_sig == JS_APPn_ADOBE) {
+ struct JPEG_APPn_Adobe *data;
+
+ data = (struct JPEG_APPn_Adobe *) app_data;
+
+ RELEASE(data);
+ } else if (marker == JM_APP1 && app_sig == JS_APPn_XMP) {
+ struct JPEG_APPn_XMP *data;
+
+ data = (struct JPEG_APPn_XMP *) app_data;
+ if (data->packet)
+ RELEASE(data->packet);
+
+ RELEASE(data);
+ }
+}
+
+static void
+JPEG_info_clear (struct JPEG_info *j_info)
+{
+ if (j_info->num_appn > 0 &&
+ j_info->appn != NULL) {
+ int i;
+
+ for (i = 0; i < j_info->num_appn; i++)
+ JPEG_release_APPn_data(j_info->appn[i].marker,
+ j_info->appn[i].app_sig, j_info->appn[i].app_data);
+ RELEASE(j_info->appn);
+ }
+ j_info->appn = NULL;
+ j_info->num_appn = 0;
+ j_info->max_appn = 0;
+ j_info->flags = 0;
+}
+
+static pdf_obj *
+JPEG_get_iccp (struct JPEG_info *j_info)
+{
+ pdf_obj *icc_stream;
+ struct JPEG_APPn_ICC *icc;
+ int i, prev_id = 0, num_icc_seg = -1;
+
+ icc_stream = pdf_new_stream(STREAM_COMPRESS);
+ for (i = 0; i < j_info->num_appn; i++) {
+ if (j_info->appn[i].marker != JM_APP2 ||
+ j_info->appn[i].app_sig != JS_APPn_ICC)
+ continue;
+ icc = (struct JPEG_APPn_ICC *) j_info->appn[i].app_data;
+ if (num_icc_seg < 0 && prev_id == 0) {
+ num_icc_seg = icc->num_chunks;
+ /* ICC chunks are sorted? */
+ } else if (icc->seq_id != prev_id + 1 ||
+ num_icc_seg != icc->num_chunks || icc->seq_id > icc->num_chunks) {
+ WARN("Invalid JPEG ICC chunk: %d (p:%d, n:%d)", icc->seq_id, prev_id, icc->num_chunks);
+ pdf_release_obj(icc_stream);
+ icc_stream = NULL;
+ break;
+ }
+ pdf_add_stream(icc_stream, icc->chunk, icc->length);
+ prev_id = icc->seq_id;
+ num_icc_seg = icc->num_chunks;
+ }
+
+ return icc_stream;
+}
+
+static pdf_obj *
+JPEG_get_XMP (struct JPEG_info *j_info)
+{
+ pdf_obj *XMP_stream, *stream_dict;
+ struct JPEG_APPn_XMP *XMP;
+ int i, count = 0;
+
+ /* I don't know if XMP Metadata should be compressed here.*/
+ XMP_stream = pdf_new_stream(STREAM_COMPRESS);
+ stream_dict = pdf_stream_dict(XMP_stream);
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Type"), pdf_new_name("Metadata"));
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Subtype"), pdf_new_name("XML"));
+ for (i = 0; i < j_info->num_appn; i++) {
+ /* Not sure for the case of multiple segments */
+ if (j_info->appn[i].marker != JM_APP1 ||
+ j_info->appn[i].app_sig != JS_APPn_XMP)
+ continue;
+ XMP = (struct JPEG_APPn_XMP *) j_info->appn[i].app_data;
+ pdf_add_stream(XMP_stream, XMP->packet, XMP->length);
+ count++;
+ }
+ if (count > 1)
+ WARN("%s: Multiple XMP segments found in JPEG file. (untested)", JPEG_DEBUG_STR);
+
+ return XMP_stream;
+}
+
+static JPEG_marker
+JPEG_get_marker (FILE *fp)
+{
+ int c;
+
+ c = fgetc(fp);
+ if (c != 255)
+ return -1;
+
+ for (;;) {
+ c = fgetc(fp);
+ if (c < 0)
+ return -1;
+ else if (c > 0 && c < 255) {
+ return c;
+ }
+ }
+}
+
+static int
+add_APPn_marker (struct JPEG_info *j_info, JPEG_marker marker, int app_sig, void *app_data)
+{
+ int n;
+
+ if (j_info->num_appn >= j_info->max_appn) {
+ j_info->max_appn += 16;
+ j_info->appn = RENEW(j_info->appn, j_info->max_appn, struct JPEG_ext);
+ }
+ n = j_info->num_appn;
+
+ j_info->appn[n].marker = marker;
+ j_info->appn[n].app_sig = app_sig;
+ j_info->appn[n].app_data = app_data;
+
+ j_info->num_appn += 1;
+
+ return n;
+}
+
+static unsigned short
+read_APP14_Adobe (struct JPEG_info *j_info, FILE *fp)
+{
+ struct JPEG_APPn_Adobe *app_data;
+
+ app_data = NEW(1, struct JPEG_APPn_Adobe);
+ app_data->version = get_unsigned_pair(fp);
+ app_data->flag0 = get_unsigned_pair(fp);
+ app_data->flag1 = get_unsigned_pair(fp);
+ app_data->transform = get_unsigned_byte(fp);
+
+ add_APPn_marker(j_info, JM_APP14, JS_APPn_ADOBE, app_data);
+
+ return 7;
+}
+
+#define JPEG_EXIF_BIGENDIAN 0
+#define JPEG_EXIF_LITTLEENDIAN 1
+static int
+read_exif_bytes (unsigned char **pp, int n, int endian)
+{
+ int rval = 0;
+ unsigned char *p = *pp;
+ int i;
+
+ switch (endian) {
+ case JPEG_EXIF_BIGENDIAN:
+ for (i = 0; i < n; i++) {
+ rval = (rval << 8) + p[i];
+ }
+ break;
+ case JPEG_EXIF_LITTLEENDIAN:
+ for (i = n - 1; i >= 0; i--) {
+ rval = (rval << 8) + p[i];
+ }
+ break;
+ }
+
+ *pp += n;
+ return rval;
+}
+
+#define JPEG_EXIF_TYPE_BYTE 1
+#define JPEG_EXIF_TYPE_ASCII 2
+#define JPEG_EXIF_TYPE_SHORT 3
+#define JPEG_EXIF_TYPE_LONG 4
+#define JPEG_EXIF_TYPE_RATIONAL 5
+#define JPEG_EXIF_TYPE_UNDEFINED 7
+#define JPEG_EXIF_TYPE_SLONG 9
+#define JPEG_EXIF_TYPE_SRATIONAL 10
+
+#define JPEG_EXIF_TAG_XRESOLUTION 282
+#define JPEG_EXIF_TAG_YRESOLUTION 283
+#define JPEG_EXIF_TAG_RESOLUTIONUNIT 296
+#define JPEG_EXIF_TAG_RESUNIT_MS 0x5110
+#define JPEG_EXIF_TAG_XRES_MS 0x5111
+#define JPEG_EXIF_TAG_YRES_MS 0x5112
+static size_t
+read_APP1_Exif (struct JPEG_info *j_info, FILE *fp, size_t length)
+{
+ /* this doesn't save the data, just reads the tags we need */
+ /* based on info from http://www.exif.org/Exif2-2.PDF */
+ unsigned char *buffer = NEW(length, unsigned char);
+ unsigned char *p, *endptr;
+ unsigned char *tiff_header;
+ int endian;
+ int num_fields;
+ int value = 0, offset;
+ double xres = 0.0, yres = 0.0;
+ double res_unit = 1.0;
+ unsigned int xres_ms = 0;
+ unsigned int yres_ms = 0;
+ double res_unit_ms = 0.0;
+ double exifxdpi = 0.0, exifydpi = 0.0;
+
+ fread(buffer, length, 1, fp);
+ if (length < 10)
+ goto err;
+
+ p = buffer; endptr = buffer + length;
+ while ((p < endptr) && (*p == 0))
+ p++;
+
+ if (p + 8 >= endptr)
+ goto err;
+ /* TIFF header */
+ tiff_header = p;
+ if ((p[0] == 'M') && (p[1] == 'M'))
+ endian = JPEG_EXIF_BIGENDIAN;
+ else if ((p[0] == 'I') && (p[1] == 'I'))
+ endian = JPEG_EXIF_LITTLEENDIAN;
+ else {
+ WARN("%s: Invalid value in Exif TIFF header.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ p += 2;
+ value = read_exif_bytes(&p, 2, endian);
+ if (value != 42) {
+ WARN("%s: Invalid value in Exif TIFF header.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ /* Offset to 0th IFD */
+ offset = read_exif_bytes(&p, 4, endian);
+
+ p = tiff_header + offset;
+ if (p + 2 >= endptr)
+ goto err;
+ num_fields = read_exif_bytes(&p, 2, endian);
+ while (num_fields-- > 0 && p < endptr) {
+ int tag, type;
+ int count;
+ unsigned int den, num;
+
+ if (p + 12 > endptr) {
+ WARN("%s: Truncated Exif data...", JPEG_DEBUG_STR);
+ goto err;
+ }
+ tag = (int) read_exif_bytes(&p, 2, endian);
+ type = (int) read_exif_bytes(&p, 2, endian);
+ count = read_exif_bytes(&p, 4, endian);
+ /* Exif data is redundant... */
+ switch (tag) {
+ case JPEG_EXIF_TAG_XRESOLUTION:
+ if (type != JPEG_EXIF_TYPE_RATIONAL || count != 1) {
+ WARN("%s: Invalid data for XResolution in Exif chunk.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ offset = read_exif_bytes(&p, 4, endian);
+ if (tiff_header + offset + 8 > buffer + length) {
+ WARN("%s: Invalid offset value in Exif data.", JPEG_DEBUG_STR);
+ goto err;
+ } else {
+ unsigned char *vp = tiff_header + offset;
+ num = (unsigned int) read_exif_bytes(&vp, 4, endian);
+ den = (unsigned int) read_exif_bytes(&vp, 4, endian);
+ }
+ if (den > 0)
+ xres = (double) num / den;
+ break;
+ case JPEG_EXIF_TAG_YRESOLUTION:
+ if (type != JPEG_EXIF_TYPE_RATIONAL || count != 1) {
+ WARN("%s: Invalid data for XResolution in Exif chunk.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ offset = read_exif_bytes(&p, 4, endian);
+ if (tiff_header + offset + 8 > buffer + length) {
+ WARN("%s: Invalid offset value in Exif data.", JPEG_DEBUG_STR);
+ goto err;
+ } else {
+ unsigned char *vp = tiff_header + offset;
+ num = (unsigned int) read_exif_bytes(&vp, 4, endian);
+ den = (unsigned int) read_exif_bytes(&vp, 4, endian);
+ }
+ if (den > 0)
+ yres = (double) num / den;
+ break;
+ case JPEG_EXIF_TAG_RESOLUTIONUNIT:
+ if (type != JPEG_EXIF_TYPE_SHORT || count != 1) {
+ WARN("%s: Invalid data for ResolutionUnit in Exif chunk.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ value = read_exif_bytes(&p, 2, endian);
+ p += 2;
+ if (value == 2)
+ res_unit = 1.0 ; /* inch */
+ else if (value == 3)
+ res_unit = 2.54; /* cm */
+ break;
+ case JPEG_EXIF_TAG_RESUNIT_MS: /* PixelUnit */
+ if (type != JPEG_EXIF_TYPE_BYTE || count != 1) {
+ WARN("%s: Invalid data for ResolutionUnit in Exif chunk.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ value = read_exif_bytes(&p, 1, endian);
+ p += 3;
+ if (value == 1)
+ res_unit_ms = 0.0254; /* Unit is meter */
+ else
+ res_unit_ms = 0.0;
+ break;
+ case JPEG_EXIF_TAG_XRES_MS: /* PixelPerUnitX */
+ if (type != JPEG_EXIF_TYPE_LONG || count != 1) {
+ WARN("%s: Invalid data for PixelPerUnitX in Exif chunk.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ value = read_exif_bytes(&p, 4, endian);
+ xres_ms = value;
+ break;
+ case JPEG_EXIF_TAG_YRES_MS: /* PixelPerUnitY */
+ if (type != JPEG_EXIF_TYPE_LONG || count != 1) {
+ WARN("%s: Invalid data for PixelPerUnitY in Exif chunk.", JPEG_DEBUG_STR);
+ goto err;
+ }
+ value = read_exif_bytes(&p, 4, endian);
+ yres_ms = value;
+ break;
+ default:
+ /* 40901 ColorSpace and 42240 Gamma unsupported... */
+ p += 4;
+ break;
+ }
+ }
+ if (num_fields > 0) {
+ WARN("%s: Truncated Exif data...", JPEG_DEBUG_STR);
+ goto err;
+ }
+
+/* Calculate Exif resolution, if given.
+ */
+ if (xres > 0.0 && yres > 0.0) {
+ exifxdpi = xres * res_unit;
+ exifydpi = yres * res_unit;
+ } else if (xres_ms > 0 && yres_ms > 0 && res_unit_ms > 0.0) {
+ exifxdpi = xres_ms * res_unit_ms;
+ exifydpi = yres_ms * res_unit_ms;
+ } else {
+ exifxdpi = 72.0 * res_unit;
+ exifydpi = 72.0 * res_unit;
+ }
+
+/* Do not overwrite j_info->xdpi and j_info->ydpi if they are
+ * already determined in JFIF.
+ */
+ if (j_info->xdpi < 0.1 && j_info->ydpi < 0.1) {
+ j_info->xdpi = exifxdpi;
+ j_info->ydpi = exifydpi;
+ } else {
+ double xxx1 = floor(exifxdpi+0.5);
+ double xxx2 = floor(j_info->xdpi+0.5);
+ double yyy1 = floor(exifydpi+0.5);
+ double yyy2 = floor(j_info->ydpi+0.5);
+
+ if (xxx1 != xxx2 || yyy1 != yyy2) {
+ WARN("%s: Inconsistent resolution may have " \
+ "specified in Exif and JFIF: %gx%g - %gx%g", JPEG_DEBUG_STR,
+ xxx1, yyy1, xxx2, yyy2);
+ }
+ }
+
+err:
+ RELEASE(buffer);
+ return length;
+}
+
+static size_t
+read_APP0_JFIF (struct JPEG_info *j_info, FILE *fp)
+{
+ struct JPEG_APPn_JFIF *app_data;
+ size_t thumb_data_len;
+
+ app_data = NEW(1, struct JPEG_APPn_JFIF);
+ app_data->version = get_unsigned_pair(fp);
+ app_data->units = get_unsigned_byte(fp);
+ app_data->Xdensity = get_unsigned_pair(fp);
+ app_data->Ydensity = get_unsigned_pair(fp);
+ app_data->Xthumbnail = get_unsigned_byte(fp);
+ app_data->Ythumbnail = get_unsigned_byte(fp);
+ thumb_data_len = 3 * app_data->Xthumbnail * app_data->Ythumbnail;
+ if (thumb_data_len > 0) {
+ app_data->thumbnail = NEW(thumb_data_len, unsigned char);
+ fread(app_data->thumbnail, 1, thumb_data_len, fp);
+ } else {
+ app_data->thumbnail = NULL;
+ }
+
+ add_APPn_marker(j_info, JM_APP0, JS_APPn_JFIF, app_data);
+
+ switch (app_data->units) {
+ case 1:
+ j_info->xdpi = app_data->Xdensity;
+ j_info->ydpi = app_data->Ydensity;
+ break;
+ case 2: /* density is in pixels per cm */
+ j_info->xdpi = app_data->Xdensity * 2.54;
+ j_info->ydpi = app_data->Ydensity * 2.54;
+ break;
+ default: /* FIXME: not sure what to do with this.... */
+ j_info->xdpi = 72.0;
+ j_info->ydpi = 72.0;
+ break;
+ }
+
+ return (9 + thumb_data_len);
+}
+
+static size_t
+read_APP0_JFXX (FILE *fp, size_t length)
+{
+ get_unsigned_byte(fp);
+ /* Extension Code:
+ *
+ * 0x10: Thumbnail coded using JPEG
+ * 0x11: Thumbnail stored using 1 byte/pixel
+ * 0x13: Thumbnail stored using 3 bytes/pixel
+ */
+ seek_relative(fp, length - 1); /* Thunbnail image */
+
+ /* Ignore */
+
+ return length;
+}
+
+static size_t
+read_APP1_XMP (struct JPEG_info *j_info, FILE *fp, size_t length)
+{
+ struct JPEG_APPn_XMP *app_data;
+
+ app_data = NEW(1, struct JPEG_APPn_XMP);
+ app_data->length = length;
+ app_data->packet = NEW(app_data->length, unsigned char);
+ fread(app_data->packet, 1, app_data->length, fp);
+
+ add_APPn_marker(j_info, JM_APP1, JS_APPn_XMP, app_data);
+
+ return length;
+}
+
+static size_t
+read_APP2_ICC (struct JPEG_info *j_info, FILE *fp, size_t length)
+{
+ struct JPEG_APPn_ICC *app_data;
+
+ app_data = NEW(1, struct JPEG_APPn_ICC);
+ app_data->seq_id = get_unsigned_byte(fp); /* Starting at 1 */
+ app_data->num_chunks = get_unsigned_byte(fp);
+ app_data->length = length - 2;
+ app_data->chunk = NEW(app_data->length, unsigned char);
+ fread(app_data->chunk, 1, app_data->length, fp);
+
+ add_APPn_marker(j_info, JM_APP2, JS_APPn_ICC, app_data);
+
+ return length;
+}
+
+static int
+JPEG_copy_stream (struct JPEG_info *j_info, pdf_obj *stream, FILE *fp)
+{
+ JPEG_marker marker;
+ int length;
+ int found_SOFn, count;
+
+#define SKIP_CHUNK(j,c) ((j)->skipbits[(c) / 8] & (1 << (7 - (c) % 8)))
+#define COPY_CHUNK(f,s,l) while ((l) > 0) { \
+ int nb_read = fread(work_buffer, sizeof(char), MIN((l), WORK_BUFFER_SIZE), (f)); \
+ if (nb_read > 0) \
+ pdf_add_stream((s), work_buffer, nb_read); \
+ (l) -= nb_read; \
+}
+ rewind(fp);
+ count = 0;
+ found_SOFn = 0;
+ while (!found_SOFn && count < MAX_COUNT &&
+ (marker = JPEG_get_marker(fp)) != (JPEG_marker) - 1) {
+ if ( marker == JM_SOI ||
+ (marker >= JM_RST0 && marker <= JM_RST7)) {
+ work_buffer[0] = (char) 0xff;
+ work_buffer[1] = (char) marker;
+ pdf_add_stream(stream, work_buffer, 2);
+ } else {
+ length = get_unsigned_pair(fp) - 2;
+ switch (marker) {
+ case JM_SOF0: case JM_SOF1: case JM_SOF2: case JM_SOF3:
+ case JM_SOF5: case JM_SOF6: case JM_SOF7: case JM_SOF9:
+ case JM_SOF10: case JM_SOF11: case JM_SOF13: case JM_SOF14:
+ case JM_SOF15:
+ work_buffer[0] = (char) 0xff;
+ work_buffer[1] = (char) marker;
+ work_buffer[2] = ((length + 2) >> 8) & 0xff;
+ work_buffer[3] = (length + 2) & 0xff;
+ pdf_add_stream(stream, work_buffer, 4);
+ COPY_CHUNK(fp, stream, length);
+ found_SOFn = 1;
+ break;
+ default:
+ if (SKIP_CHUNK(j_info, count)) {
+ seek_relative(fp, length);
+ } else {
+ work_buffer[0] = (char) 0xff;
+ work_buffer[1] = (char) marker;
+ work_buffer[2] = ((length + 2) >> 8) & 0xff;
+ work_buffer[3] = (length + 2) & 0xff;
+ pdf_add_stream(stream, work_buffer, 4);
+ COPY_CHUNK(fp, stream, length);
+ }
+ }
+ }
+ count++;
+ }
+ while ((length = fread(work_buffer,
+ sizeof(char), WORK_BUFFER_SIZE, fp)) > 0) {
+ pdf_add_stream(stream, work_buffer, length);
+ }
+
+ return (found_SOFn ? 0 : -1);
+}
+
+/* Adobe Technical Note #5116 "Supporting the DCT Filters in PostScript Level 2"
+ * 6. "DCTDecode Filter Summary"
+ * ... APPn (application-specific) markers are skipped over harmlessly except
+ * for the Adobe reserved marker described later.
+ *
+ */
+#define SET_SKIP(j,c) if ((c) < MAX_COUNT) { \
+ (j)->skipbits[(c) / 8] |= (1 << (7 - ((c) % 8))); \
+}
+static int
+JPEG_scan_file (struct JPEG_info *j_info, FILE *fp)
+{
+ JPEG_marker marker;
+ int found_SOFn, count;
+ char app_sig[128];
+
+ rewind(fp);
+ count = 0;
+ found_SOFn = 0;
+ while (!found_SOFn &&
+ (marker = JPEG_get_marker(fp)) != (JPEG_marker) -1) {
+ if ( marker != JM_SOI &&
+ (marker < JM_RST0 || marker > JM_RST7)) {
+ int length = get_unsigned_pair(fp) - 2;
+ switch (marker) {
+ case JM_SOF0: case JM_SOF1: case JM_SOF2: case JM_SOF3:
+ case JM_SOF5: case JM_SOF6: case JM_SOF7: case JM_SOF9:
+ case JM_SOF10: case JM_SOF11: case JM_SOF13: case JM_SOF14:
+ case JM_SOF15:
+ j_info->bits_per_component = get_unsigned_byte(fp);
+ j_info->height = get_unsigned_pair(fp);
+ j_info->width = get_unsigned_pair(fp);
+ j_info->num_components = get_unsigned_byte(fp);
+ found_SOFn = 1;
+ break;
+ case JM_APP0:
+ if (length > 5) {
+ if (fread(app_sig, sizeof(char), 5, fp) != 5)
+ return -1;
+ length -= 5;
+ if (!memcmp(app_sig, "JFIF\000", 5)) {
+ /* APP0 JFIF marker preserved */
+ j_info->flags |= HAVE_APPn_JFIF;
+ length -= read_APP0_JFIF(j_info, fp);
+ } else if (!memcmp(app_sig, "JFXX", 5)) {
+ length -= read_APP0_JFXX(fp, length);
+ SET_SKIP(j_info, count);
+ } else {
+ SET_SKIP(j_info, count);
+ }
+ } else {
+ SET_SKIP(j_info, count);
+ }
+ seek_relative(fp, length);
+ break;
+ case JM_APP1:
+ if (length > 5) {
+ if (fread(app_sig, sizeof(char), 5, fp) != 5)
+ return -1;
+ length -= 5;
+ if (!memcmp(app_sig, "Exif\000", 5)) {
+ /* APP1 Exif marker preserved */
+ j_info->flags |= HAVE_APPn_Exif;
+ length -= read_APP1_Exif(j_info, fp, length);
+ } else if (!memcmp(app_sig, "http:", 5) && length > 24) {
+ if (fread(app_sig, sizeof(char), 24, fp) != 24)
+ return -1;
+ length -= 24;
+ if (!memcmp(app_sig, "//ns.adobe.com/xap/1.0/\000", 24)) {
+ j_info->flags |= HAVE_APPn_XMP;
+ length -= read_APP1_XMP(j_info, fp, length);
+ }
+ SET_SKIP(j_info, count);
+ }
+ } else {
+ SET_SKIP(j_info, count);
+ }
+ seek_relative(fp, length);
+ break;
+ case JM_APP2:
+ if (length >= 14) {
+ if (fread(app_sig, sizeof(char), 12, fp) != 12)
+ return -1;
+ length -= 12;
+ if (!memcmp(app_sig, "ICC_PROFILE\000", 12)) {
+ j_info->flags |= HAVE_APPn_ICC;
+ length -= read_APP2_ICC(j_info, fp, length);
+ }
+ }
+ seek_relative(fp, length);
+ SET_SKIP(j_info, count);
+ break;
+ case JM_APP14:
+ if (length > 5) {
+ if (fread(app_sig, sizeof(char), 5, fp) != 5)
+ return -1;
+ length -= 5;
+ if (!memcmp(app_sig, "Adobe", 5)) {
+ /* APP14 Adobe marker preserved */
+ j_info->flags |= HAVE_APPn_ADOBE;
+ length -= read_APP14_Adobe(j_info, fp);
+ } else {
+ SET_SKIP(j_info, count);
+ }
+ } else {
+ SET_SKIP(j_info, count);
+ }
+ seek_relative(fp, length);
+ break;
+ default:
+ seek_relative(fp, length);
+ if (marker >= JM_APP0 && marker <= JM_APP15) {
+ SET_SKIP(j_info, count);
+ }
+ break;
+ }
+ }
+ count++;
+ }
+
+ return (found_SOFn ? 0 : -1);
+}
+
+int
+jpeg_get_bbox (FILE *fp, int *width, int *height, double *xdensity, double *ydensity)
+{
+ struct JPEG_info j_info;
+
+ JPEG_info_init(&j_info);
+
+ if (JPEG_scan_file(&j_info, fp) < 0) {
+ WARN("%s: Not a JPEG file?", JPEG_DEBUG_STR);
+ JPEG_info_clear(&j_info);
+ return -1;
+ }
+
+ *width = j_info.width;
+ *height = j_info.height;
+
+ jpeg_get_density(&j_info, xdensity, ydensity);
+
+ JPEG_info_clear(&j_info);
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/jpegimage.h b/Build/source/texk/dvipdfm-x/jpegimage.h
new file mode 100644
index 00000000000..7a2b63a754a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/jpegimage.h
@@ -0,0 +1,36 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _JPEGIMAGE_H_
+#define _JPEGIMAGE_H_
+
+#include "mfileio.h"
+#include "pdfximage.h"
+
+extern int check_for_jpeg (FILE *fp);
+extern int jpeg_include_image (pdf_ximage *ximage, FILE *fp);
+extern int jpeg_get_bbox (FILE *fp, int *width, int *height,
+ double *xdensity, double *ydensity);
+
+#endif /* _JPEGIMAGE_H_ */
+
+
diff --git a/Build/source/texk/dvipdfm-x/man/dvipdfmx.1 b/Build/source/texk/dvipdfm-x/man/dvipdfmx.1
new file mode 100644
index 00000000000..c8a6ad6c3c8
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/man/dvipdfmx.1
@@ -0,0 +1,354 @@
+.de EX
+.sp
+.in +5
+.nf
+.ft CW
+..
+.de EE
+.in -5
+.ft R
+.sp
+.fi
+..
+.TH "DVIPDFMX" "1" "5 October 2020"
+.SH NAME
+dvipdfmx, xdvipdfmx, dvipdfm \- produce PDF files directly from DVI files
+.SH SYNOPSIS
+.B dvipdfmx
+or
+.B dvipdfm
+.RI [ options ]
+.I file\c
+.RB [ .dvi ]
+.SH DESCRIPTION
+The program
+.B dvipdfmx
+generates a PDF file from a DVI file. DVI files are the output produced
+by TeX.
+.B groff
+can also generate DVI files using
+.BR grodvi (-Tdvi).
+
+In TeX Live,
+.B dvipdfm
+is another incarnation of
+.B dvipdfmx
+rather than a separate program. Compatibility is attempted as best as
+possible.
+
+In addition,
+.B xdvipdfmx
+is another incarnation. It is used as the back end for
+.BR xetex (1)
+and is not intended to be invoked directly.
+
+.B dvipdfmx
+recognizes several commonly used
+.BR \especial
+commands, which are extensions to the DVI format. Specifically, it
+understands color specials, papersize specials, tpic specials (which
+allow it to be used with
+.BR pic ),
+hypertex specials, and some PostScript specials. These extensions allow
+documents to contain color, figures, and hyperlinks. The program tries
+to mimic the behavior of
+.B dvips
+where possible, so that many macro packages produced for use with
+.B dvips
+will also work with
+.BR dvipdfmx .
+In addition,
+.B dvipdfmx
+understands its own specific
+.B \especial
+commands to allow access to PDF features such as annotations and
+bookmarks.
+
+As of December 2018, one such special specific to
+.B dvipdfmx
+is
+.IR pdf:trailerid ,
+which specifies the /ID in the PDF trailer.
+It is used like this (from the TeX level):
+.br
+\especial{pdf:trailerid [ (0123456789abcdef) (01234567890abcdef) ]}
+.br
+That is, the special takes an array (the square brackets) of two 16-byte
+PDF strings (the parentheses). This is the same syntax as LuaTeX's
+.IR "\epdfvariable trailerid" ,
+while different from pdfTeX's
+.IR \epdftrailerid .
+It must appear on the first output page, otherwise it is ignored.
+
+Unrecognized specials will generate warning messages. Packages that may need a
+.B dvipdfm
+or
+.B dvipdfmx
+driver option include
+.IR geometry ,
+.IR hyperref ,
+.IR bookmark ,
+.IR graphicx ,
+and
+.IR xcolor .
+
+For issues related to bounding boxes (and hence image sizes), see
+.BR extractbb (1).
+.SH OPTIONS
+Unlike with many other programs, argument values must be separated from
+option names by a space, not an = sign; option names cannot be
+abbreviated; and \- and \-\- cannot be used interchangeably.
+.TP 5
+.B \-\^c
+Ignore (or accept) color
+.BR \especials .
+By default, color
+.BR \especial "s"
+are interpreted normally (changeable in the configuration file). The
+.B \-\^c
+option may be used to produce a black and white document
+from a document containing color TeX
+.B \especial
+commands.
+.TP 5
+.B \-\-\^dvipdfm
+Enable
+.B dvipdfm
+emulation mode. This is the default if the executable name is `dvipdfm'.
+.TP 5
+.B \-\^d number
+Specify the number of decimal digits in the PDF output; must be between
+0 and 5, default is 2.
+.TP 5
+.B \-\^e
+Ignored, for (semi-)compatibility with
+.BR dvipdfm .
+.TP 5
+.B \-\^f map_file
+Read the font map file given by
+.IR map_file .
+The default map file in TeX Live is
+.IR pdftex.map ,
+as defined in the configuration file.
+.TP 5
+.B \-\-\^help
+Show a help message and exit successfully.
+.TP 5
+.B \-\^l
+Select landscape mode. In other words, exchange the
+.I x
+and
+.I y
+dimensions of the paper.
+.TP 5
+.B \-\^m " mag"
+Magnify the input document by
+.IR mag .
+.TP 5
+.B \-\^o " filename"
+Set the PDF output file name; use `-' for stdout.
+By default, the name of the output
+file is derived from the input, that is,
+.IR file .pdf.
+.TP 5
+.B \-\^p " paper"
+Select the papersize by name (e.g.,
+.BR letter ", " legal ", " ledger ", " tabloid ", " a3 ", " a4 ", or " a5
+)
+.TP 5
+.B \-\^q
+Quiet mode.
+.TP 5
+.B \-\^r " size"
+Set resolution of bitmapped fonts to
+.B size
+dots per inch. Bitmapped fonts are generated
+by the Kpathsea library, which uses Metafont. Bitmapped
+fonts are included as Type 3 fonts in the PDF output file. Default is 600.
+.TP 5
+.B \-\^s " page_specifications"
+Select the pages of the DVI file to be processed; default is `-',
+meaning all pages. The
+.I page_specifications
+consists of a comma separated list of
+.IR page_ranges :
+.EX
+.IR "page_specifications := page_specification" "[," page_specifications "]"
+.EE
+where
+.EX
+.IR "page_specification := single_page" | page_range
+.IR "page_range := " [ first_page ]\^\-\^[ last_page ]
+.EE
+An empty
+.I first_page
+is treated as the first page of the DVI file, and
+an empty
+.I last_page
+is treated as the last page of the DVI file.
+
+Examples:
+.RS
+.TP 5
+.B "\-\^s 1,3,5"
+includes pages 1, 3, and 5;
+.TP 5
+.B "\-\^s \-"
+includes all pages;
+.TP 5
+.B "\-\^s \-,\-"
+includes two copies of all pages in the DVI file;
+and
+.TP 5
+.B "\-\^s 1\-10"
+includes the first ten pages of the DVI
+file.
+.RE
+.TP 5
+.B \-\^t
+Search for thumbnail images of each page
+in the directory named by the
+.B TMPDIR
+environment variable. The thumbnail images must be named in a specific
+format: the same base name as the DVI file and the page number as the
+extension to the file name.
+.B dvipdfmx
+does not generate such thumbnails itself, but it is distributed with a
+wrapper program named
+.B dvipdft
+that does so.
+.TP 5
+.B \-\-\^version
+Show a help message and exit successfully.
+.TP 5
+.B \-\^v
+Increase verbosity.
+Results of the
+.B \-\^v
+option are cumulative (e.g.,
+.B \-\^vv
+increases the verbosity by two increments). Maximum verbosity is four.
+.TP 5
+.B \-\-\^kpathsea-debug number
+Have Kpathsea output debugging information; `-1' for everything (voluminous).
+.TP 5
+.B \-\^x x_offset
+Set the left margin to
+.IR x_offset .
+The default left margin is
+.BR 1.0in .
+The dimension may be specified in any units understood by TeX (e.g.,
+.BR bp ", " pt ", " in ", " cm ).
+.TP 5
+.B \-\^y y_offset
+Set the top margin to
+.IR y_offset .
+The default top margin is
+.BR 1.0in .
+The dimension may be specified in any units understood by TeX (e.g.,
+.BR bpt ", " pt ", " in ", " cm ).
+.TP 5
+.B \-\^z number
+Set the compression level to
+.IR compression_level .
+Compression levels range from 0 (no compression) to
+9 (maximum compression) and correspond to the values understood by zlib;
+default is 9.
+.TP 5
+.B \-\^C number
+Miscellaneous option flags; see the --help output for details.
+.TP 5
+.B \-\^D template
+PostScript to PDF conversion command line template; the default is taken
+from the configuration file, which also gives all the details and
+mentions several possibilities.
+.TP 5
+.B \-\^E
+Always try to embed fonts, ignoring licensing flags, etc.
+.TP 5
+.B \-\^I number
+Image cache life in hours; default is -2, meaning to not cache images at
+all. A value of -1 means to erase all old images and also new images; 0
+means to erase all old images but leave new images.
+.TP 5
+.B \-\^K number
+Encryption key length; default 40.
+.TP 5
+.B \-\^M
+Process MetaPost PostScript output.
+.TP 5
+.B \-\^O number
+Set maximum depth of open bookmark items; default 0.
+.TP 5
+.B \-\^P number
+Set permission flags for PDF encryption; default 0x003C.
+.TP 5
+.B \-\^S
+Enable PDF encryption.
+.TP 5
+.B \-\^V number
+Set PDF minor version; default 5 (from the configuration file).
+.SH "IMAGE BOUNDING BOXES"
+When including images with
+.BR dvipdfmx ,
+their bounding boxes should be generated by running
+.BR extractbb .
+The result will be in an
+.B .xbb
+file; the xbb information is the same as for the PDF format.
+.SH ENVIRONMENT
+.B dvipdfmx
+uses the
+.B kpathsea
+library for locating the files that it opens. Hence, the environment
+variables documented in the
+.I Kpathsea library
+documentation influence
+.BR dvipdfmx .
+It also uses the value of the environment variable TMPDIR as the
+directory to search for thumbnail images of each page.
+.SH FILES
+The precise location of the following files is determined by the
+.I Kpathsea library
+configuration. The location may be determined by using kpsewhich, e.g.,
+.nf
+.B kpsewhich \-progname=dvipdfmx \-format='other text files' dvipdfmx.cfg
+.fi
+.TP 5
+.I dvipdfmx.cfg
+Default configuration file
+.TP 5
+.I pdftex.map
+The default font map file (this may be changed in the config file).
+.TP 5
+.I *.tfm
+TeX font metrics
+.TP 5
+.I *.vf
+TeX virtual font files
+.TP 5
+.I *.pfb
+PostScript Type 1 font files
+.TP 5
+.I
+texmf.cnf
+The Kpathsea library configuration file.
+The location of this file may be found by typing
+.nf
+.B kpsewhich texmf.cnf
+.fi
+.SH "SEE ALSO"
+dvipdft(1), extractbb(1),
+.br
+tex(1), luatex(1), xetex(1), dvips(1),
+.br
+groff(1), grodvi(1), pic(1),
+the Kpathsea library Info documentation (http://tug.org/kpathsea),
+and the Dvipdfmx User's Manual (in the distribution).
+.SH AUTHOR
+Primarily Mark A. Wicks; dvipdfmx extensions primarily by Jin-Hwan Cho,
+Shunsaku Hirata, and Matthias Franz. For the version in TeX Live, all
+bugs and other reports should go to the
+.B dvipdfmx
+maintainers at tex-k (at) tug.org. This man page edited for TeX Live
+by Bob Tennent and others. This man page is public domain.
diff --git a/Build/source/texk/dvipdfm-x/man/dvipdft.1 b/Build/source/texk/dvipdfm-x/man/dvipdft.1
new file mode 100644
index 00000000000..50646022ef0
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/man/dvipdft.1
@@ -0,0 +1,40 @@
+.TH "dvipdft" "1" "May 2004" "teTeX" "teTeX"
+.PP
+.SH "NAME"
+dvipdft \- create thumbnail images for use with dvipdfm
+.PP
+.SH "SYNOPSIS"
+.PP
+.B dvipdft
+.RI [ DVIPDFM-OPTIONS \&.\&.\&.]
+.I filename\c
+.RB [ .dvi ]
+.PP
+.SH "DESCRIPTION"
+.PP
+.B dvipdft
+creates thumbnail pictures of the pages in your file
+and subsequently runs dvipdfm to create a PDF file with these
+thumbnails.
+.PP
+.SH "OPTIONS"
+.HP
+All options are simply handed on to dvipdfm
+.HP
+.SH "SEE ALSO"
+.IP
+\fBdvipdfm\fP(1)
+.PP
+.SH "BUGS"
+.PP
+None known\&.
+.PP
+.SH "AUTHOR"
+.PP
+\fBdvipdft\fP was written by Mark A. Wicks and Thomas Esser.
+.PP
+This manual page was written by Frank K\[:u]ster <frank@kuesterei\&.ch>,
+for the Debian GNU/Linux system\&. It may be used by others without
+contacting the author\&. Any mistakes or omissions in the manual page
+are my fault; inquiries about or corrections to this manual page
+should be directed to me (and not to the primary author)\&.
diff --git a/Build/source/texk/dvipdfm-x/man/extractbb.1 b/Build/source/texk/dvipdfm-x/man/extractbb.1
new file mode 100644
index 00000000000..34b6d348580
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/man/extractbb.1
@@ -0,0 +1,99 @@
+.TH "EXTRACTBB" "1" "20 April 2012" "20120420" "DVIPDFMx"
+.PP
+.SH "NAME"
+extractbb, ebb \- extract bounding box information from graphics files
+.PP
+.SH "SYNOPSIS"
+.PP
+.B extractbb
+.RB [ \-v | \-q ]
+.RB [ \-O ]
+.RB [ \-m | \-x ]
+.IR file \&.\&.\&.
+.PP
+.SH "DESCRIPTION"
+.PP
+For each
+.SM JPEG\c
+,
+.SM PNG\c
+, or
+.SM PDF
+file given on the command line,
+.B extractbb
+extracts the bounding box information and writes it into a file with extension
+.BR .xbb ,
+together with some header information. These files can then be used by
+.B dvipdfmx
+or other programs. For
+.SM PDF
+files, the number of pages and the
+.SM PDF
+version number are reported as well.
+The input filename extension may be in upper or lower case.
+.PP
+If called as
+.BR ebb ,
+the output is written in the ``bb'' format (and with extension
+.BR .bb )
+as used by
+.BR dvipdfm .
+.B Xbb
+may be defined as a synomym for
+.B extractbb
+on your system.
+.PP
+.SH "OPTIONS"
+.PD 0
+.TP 10
+.B -v
+Be verbose.
+.TP
+.B -q
+Be quiet.
+.TP
+.B -O
+Write output to standard output.
+.TP
+.B -m
+Write output in dvipdfm's ``bb'' format.
+.TP
+.B -x
+Write output in dvipdfmx's ``xbb'' format (default), which is the same
+as that used by pdfTeX.
+.PD
+.PP
+.SH "OUTPUT FORMATS"
+.PP
+Here are more details about the bb and xbb formats:
+.PP
+The original ebb (from dvipdfm) ignored density information in bitmap
+images, and generated bounding boxes with 100px = 72bp = 1in.
+Unfortunately, screenshots (especially) tend to look bad with this
+approach.
+.PP
+So, extractbb (from dvipdfmx) uses density information if present.
+Otherwise, it generates bounding box with 100px = 100bp. This is what
+pdfTeX does.
+.SH "BUGS"
+.PP
+There is currently no way to specify which bounding box is taken
+for
+.SM PDF
+files. It will always be the first one from the following
+list: ArtBox, TrimBox, BleedBox, MediaBox. (Often only MediaBox
+is defined.) Moreover, the reported bounding box always refers
+to the first page in a
+.SM PDF
+file.
+.PP
+.SH "AUTHOR"
+.PP
+\fBextractbb\fP was written by the DVIPDFMx project team
+<dvipdfmx@ktug.or.kr>, based on the program \fBebb\fP by Mark A. Wicks.
+.PP
+This manual page was also written by the DVIPDFMx project team,
+based on a manual page Frank K\[:u]ster <frank@kuesterei\&.ch>
+wrote for the Debian GNU/Linux system\&.
+It may be used, modified, and/or redistributed by others without
+contacting the authors\&.
diff --git a/Build/source/texk/dvipdfm-x/mem.c b/Build/source/texk/dvipdfm-x/mem.c
new file mode 100644
index 00000000000..947fca73088
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/mem.c
@@ -0,0 +1,57 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+void *new (uint32_t size)
+{
+ void *result = malloc ((size_t)size);
+ if (!result) {
+ ERROR("Out of memory - asked for %u bytes\n", size);
+ }
+
+ return result;
+}
+
+void *renew (void *mem, uint32_t size)
+{
+ if (size) {
+ void *result = realloc (mem, (size_t)size);
+ if (!result) {
+ ERROR("Out of memory - asked for %u bytes\n", size);
+ }
+ return result;
+ } else {
+ /* realloc may not return NULL if size == 0 */
+ free(mem);
+ return NULL;
+ }
+}
diff --git a/Build/source/texk/dvipdfm-x/mem.h b/Build/source/texk/dvipdfm-x/mem.h
new file mode 100644
index 00000000000..4fda508fe50
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/mem.h
@@ -0,0 +1,50 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _MEM_H_
+#define _MEM_H_
+
+#include <stdlib.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+extern void *new (uint32_t size);
+extern void *renew (void *p, uint32_t size);
+
+#define NEW(n,type) (type *) new(((uint32_t)(n))*sizeof(type))
+#define RENEW(p,n,type) (type *) renew(p,((uint32_t)(n))*sizeof(type))
+#define RELEASE(p) free(p)
+
+/*
+ * mem.h is not suitable for the following, but it is the only common
+ * header file for dpxcrypt.c, pdfencrypt.c, and pdffont.c, which use
+ * the function rand().
+ */
+extern void init_genrand(unsigned long long s);
+extern long genrand_int31(void);
+#define srand(x) init_genrand((x))
+#define rand() genrand_int31()
+#endif /* _MEM_H_ */
diff --git a/Build/source/texk/dvipdfm-x/mfileio.c b/Build/source/texk/dvipdfm-x/mfileio.c
new file mode 100644
index 00000000000..80f5d3f1067
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/mfileio.c
@@ -0,0 +1,171 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "system.h"
+#include "mfileio.h"
+#include "error.h"
+
+#ifdef IODEBUG
+static FILE *iodebug_file = NULL;
+static int event = 0;
+static void io_debug_init(void)
+{
+ if (!iodebug_file) {
+ iodebug_file = fopen ("fopen.log", "wb");
+ fprintf (stderr, "\n*** File IO debugging started ***\n");
+ }
+ if (!iodebug_file) {
+ fprintf (stderr, "\nError opening io log\n");
+ }
+}
+#endif
+
+#ifdef IODEBUG
+FILE *mfopen(const char *name, const char *mode, const char *function, int line)
+{
+ FILE *tmp;
+ io_debug_init();
+#if defined(WIN32)
+ tmp = fsyscp_fopen (name, mode);
+#else
+ tmp = fopen (name, mode);
+#endif
+ event += 1;
+ fprintf(iodebug_file, "%p %07d [fopen] %s:%d\n", tmp, event,
+ function, line);
+ return tmp;
+}
+int mfclose(FILE *file, const char *function, int line)
+{
+ io_debug_init();
+ event += 1;
+ fprintf(iodebug_file, "%p %07d [fclose] %s:%d\n", file, event,
+ function, line);
+ return fclose(file);
+}
+#endif
+
+static void os_error(void)
+{
+ ERROR ("io: An OS command failed that should not have.\n");
+}
+
+void seek_absolute (FILE *file, int32_t pos)
+{
+ if (fseek(file, (long)pos, SEEK_SET)) {
+ os_error();
+ }
+}
+
+void seek_relative (FILE *file, int32_t pos)
+{
+ if (fseek(file, (long)pos, SEEK_CUR)) {
+ os_error();
+ }
+}
+
+
+void seek_end (FILE *file)
+{
+ if (fseek(file, 0L, SEEK_END)) {
+ os_error();
+ }
+}
+
+int32_t tell_position (FILE *file)
+{
+ long size = ftell (file);
+ if (size < 0)
+ os_error();
+#if LONG_MAX > 0x7fffffff
+ if (size > 0x7fffffff)
+ ERROR ("ftell: file size %ld exceeds 0x7fffffff.\n", size);
+#endif
+ return size;
+}
+
+int32_t file_size (FILE *file)
+{
+ int32_t size;
+ /* Seek to end */
+ seek_end (file);
+ size = tell_position (file);
+ rewind (file);
+ return size;
+}
+
+off_t xfile_size (FILE *file, const char *name)
+{
+ off_t size;
+ xseek_end (file, name);
+ size = xtell_position (file, name);
+ rewind (file);
+ return size;
+}
+
+/* Unlike fgets, mfgets works with \r, \n, or \r\n end of lines. */
+char *mfgets (char *buffer, int length, FILE *file)
+{
+ int ch = 0, i = 0;
+ while (i < length-1 && (ch = fgetc (file)) >= 0 && ch != '\n' && ch != '\r')
+ buffer[i++] = ch;
+ buffer[i] = 0;
+ if (ch < 0 && i == 0)
+ return NULL;
+ if (ch == '\r' && (ch = fgetc (file)) >= 0 && (ch != '\n'))
+ ungetc (ch, file);
+ return buffer;
+}
+
+/* As each lines may contain null-characters, so outptr here is NOT
+ * null-terminated string.
+ * Returns -1 for when EOF is already reached, and -2 if buffer has no
+ * enough space.
+ */
+int
+mfreadln (char *buf, int size, FILE *fp)
+{
+ int c;
+ int len = 0;
+
+ while ((c = fgetc(fp)) != EOF && c != '\n' && c != '\r') {
+ if (len >= size) {
+ return -2;
+ }
+ buf[len++] = (char) c;
+ }
+ if (c == EOF && len == 0) {
+ return -1;
+ }
+ if (c == '\r' && (c = fgetc(fp)) >= 0 && (c != '\n'))
+ ungetc(c, fp);
+
+ return len;
+}
+
+char work_buffer[WORK_BUFFER_SIZE];
diff --git a/Build/source/texk/dvipdfm-x/mfileio.h b/Build/source/texk/dvipdfm-x/mfileio.h
new file mode 100644
index 00000000000..97429a99036
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/mfileio.h
@@ -0,0 +1,70 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _MFILEIO_H_
+#define _MFILEIO_H_
+
+#include <stdio.h>
+#include "numbers.h"
+
+#ifdef IODEBUG
+FILE *mfopen (const char *name, const char *mode,
+ const char *function, int line);
+int mfclose (FILE *file, const char *function, int line);
+#define MFOPEN(name,mode) \
+ mfopen((name),(mode),__FUNCTION__,__LINE__)
+#define MFCLOSE(file) \
+ mfclose((file),__FUNCTION__,__LINE__)
+#else
+#if defined(WIN32)
+extern FILE *generic_fsyscp_fopen(const char *fname, const char *mode);
+#define MFOPEN(name,mode) generic_fsyscp_fopen((name),(mode))
+#else
+#define MFOPEN(name,mode) fopen((name),(mode))
+#endif
+#define MFCLOSE(file) fclose(file)
+#endif
+
+extern void seek_absolute (FILE *file, int32_t pos);
+extern void seek_relative (FILE *file, int32_t pos);
+
+extern void seek_end (FILE *file);
+
+extern int32_t tell_position (FILE *file);
+
+extern int32_t file_size (FILE *file);
+
+#define xseek_absolute(file, pos, name) xfseeko (file, (off_t)(pos), SEEK_SET, name)
+#define xseek_relative(file, pos, name) xfseeko (file, (off_t)(pos), SEEK_CUR, name)
+#define xseek_end(file, name) xfseeko (file, (off_t)0, SEEK_END, name)
+#define xtell_position(file, name) xftello (file, name)
+
+extern off_t xfile_size (FILE *file, const char *name);
+
+extern char *mfgets (char *buffer, int length, FILE *file);
+extern int mfreadln (char *buffer, int length, FILE *file);
+
+extern char work_buffer[];
+
+#define WORK_BUFFER_SIZE 1024
+
+#endif /* _MFILEIO_H_ */
diff --git a/Build/source/texk/dvipdfm-x/mpost.c b/Build/source/texk/dvipdfm-x/mpost.c
new file mode 100644
index 00000000000..d2496176646
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/mpost.c
@@ -0,0 +1,1679 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+#include "numbers.h"
+#include "dpxconf.h"
+
+#include "tfm.h"
+
+#include "pdfobj.h"
+#include "pdfparse.h"
+#include "pdfdev.h"
+#include "pdfdoc.h"
+
+#include "pdfcolor.h"
+#include "pdfdraw.h"
+
+#include "fontmap.h"
+#include "subfont.h"
+
+#include "pdfximage.h"
+
+#include "mpost.h"
+#include "dvipdfmx.h"
+
+/*
+ * Define the origin as (llx, lly) in order to
+ * match the new xetex.def and dvipdfmx.def
+ */
+
+static double Xorigin, Yorigin;
+static int translate_origin = 0;
+
+void
+mps_set_translate_origin (int v) {
+ translate_origin = v;
+}
+
+/*
+ * In PDF, current path is not a part of graphics state parameter.
+ * Hence, current path is not saved by the "q" operator and is not
+ * recovered by the "Q" operator. This means that the following PS
+ * code
+ *
+ * <path construction> gsave <path painting> grestore ...
+ *
+ * can't be translated to PDF code
+ *
+ * <path construction> q <path painting> Q ...
+ *
+ * . Only clipping path (which is graphics state parameter in PDF
+ * too) is treated in the same way. So, we write clipping path
+ * immediately and forget about it but remember current path.
+ */
+
+static int mp_parse_body (const char **start, const char *end, double x_user, double y_user);
+
+static struct mp_font
+{
+ char *font_name;
+ int font_id;
+ int tfm_id; /* Used for text width calculation */
+ int subfont_id;
+ double pt_size;
+} font_stack[PDF_GSAVE_MAX] = {
+ {NULL, -1, -1, -1, 0}
+};
+static int currentfont = 0;
+
+#define CURRENT_FONT() ((currentfont < 0) ? NULL : &font_stack[currentfont])
+#define FONT_DEFINED(f) ((f) && (f)->font_name && ((f)->font_id >= 0))
+
+static void
+clear_mp_font_struct (struct mp_font *font)
+{
+ ASSERT(font);
+
+ if (font->font_name)
+ RELEASE(font->font_name);
+ font->font_name = NULL;
+ font->font_id = -1;
+ font->tfm_id = -1;
+ font->subfont_id = -1;
+ font->pt_size = 0.0;
+}
+
+/* Compatibility */
+#define MP_CMODE_MPOST 0
+#define MP_CMODE_DVIPSK 1
+#define MP_CMODE_PTEXVERT 2
+static int mp_cmode = MP_CMODE_MPOST;
+
+static int
+mp_setfont (const char *font_name, double pt_size)
+{
+ const char *name = font_name;
+ struct mp_font *font;
+ int subfont_id = -1;
+ fontmap_rec *mrec;
+
+ font = CURRENT_FONT();
+
+ mrec = pdf_lookup_fontmap_record(font_name);
+ if (mrec && mrec->charmap.sfd_name && mrec->charmap.subfont_id) {
+ subfont_id = sfd_load_record(mrec->charmap.sfd_name, mrec->charmap.subfont_id);
+ }
+
+ /* See comments in dvi_locate_font() in dvi.c. */
+ if (mrec && mrec->map_name) {
+ name = mrec->map_name;
+ } else {
+ name = font_name;
+ }
+
+ if (font->font_name)
+ RELEASE(font->font_name);
+ font->font_name = NEW(strlen(font_name) + 1, char);
+ strcpy(font->font_name, font_name);
+ font->subfont_id = subfont_id;
+ font->pt_size = pt_size;
+ font->tfm_id = tfm_open(font_name, 0); /* Need not exist in MP mode */
+ font->font_id = pdf_dev_locate_font(name,
+ (spt_t) (pt_size * dev_unit_dviunit()));
+
+ if (font->font_id < 0) {
+ ERROR("MPOST: No physical font assigned for \"%s\".", font_name);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+save_font (void)
+{
+ struct mp_font *current, *next;
+
+ current = &font_stack[currentfont++];
+ next = &font_stack[currentfont ];
+ if (FONT_DEFINED(current)) {
+ next->font_name = NEW(strlen(current->font_name)+1, char);
+ strcpy(next->font_name, current->font_name);
+ next->font_id = current->font_id;
+ next->pt_size = current->pt_size;
+ next->subfont_id = current->subfont_id;
+ next->tfm_id = current->tfm_id;
+ } else {
+ next->font_name = NULL;
+ next->font_id = -1;
+ next->pt_size = 0.0;
+ next->subfont_id = -1;
+ next->tfm_id = -1;
+ }
+}
+
+static void
+restore_font (void)
+{
+ struct mp_font *current;
+
+ current = CURRENT_FONT();
+ if (current) {
+ clear_mp_font_struct(current);
+ }
+
+ currentfont--;
+}
+
+static void
+clear_fonts (void)
+{
+ while (currentfont > 0) {
+ clear_mp_font_struct(&font_stack[currentfont]);
+ currentfont--;
+ }
+}
+
+static int
+is_fontname (const char *token)
+{
+ fontmap_rec *mrec;
+
+ mrec = pdf_lookup_fontmap_record(token);
+ if (mrec)
+ return 1;
+
+ return tfm_exists(token);
+}
+
+int
+mps_scan_bbox (const char **pp, const char *endptr, pdf_rect *bbox)
+{
+ char *number;
+ double values[4];
+ int i;
+
+ /* skip_white() skips lines starting '%'... */
+ while (*pp < endptr && isspace((unsigned char)**pp))
+ (*pp)++;
+
+ /* Scan for bounding box record */
+ while (*pp < endptr && **pp == '%') {
+ if (*pp + 14 < endptr &&
+ !strncmp(*pp, "%%BoundingBox:", 14)) {
+
+ *pp += 14;
+
+ for (i = 0; i < 4; i++) {
+ skip_white(pp, endptr);
+ number = parse_number(pp, endptr);
+ if (!number) {
+ break;
+ }
+ values[i] = atof(number);
+ RELEASE(number);
+ }
+ if (i < 4) {
+ return -1;
+ } else {
+ /* The new xetex.def and dvipdfmx.def require bbox->llx = bbox->lly = 0. */
+ if (translate_origin) {
+ bbox->llx = 0;
+ bbox->lly = 0;
+ bbox->urx = values[2] - values[0];
+ bbox->ury = values[3] - values[1];
+
+ Xorigin = (double)values[0];
+ Yorigin = (double)values[1];
+ } else {
+ bbox->llx = values[0];
+ bbox->lly = values[1];
+ bbox->urx = values[2];
+ bbox->ury = values[3];
+
+ Xorigin = 0.0;
+ Yorigin = 0.0;
+ }
+ return 0;
+ }
+ }
+ pdfparse_skip_line (pp, endptr);
+ while (*pp < endptr && isspace((unsigned char)**pp))
+ (*pp)++;
+ }
+
+ return -1;
+}
+
+static void
+skip_prolog (const char **start, const char *end)
+{
+ int found_prolog = 0;
+ const char *save;
+
+ save = *start;
+ while (*start < end) {
+ if (**start != '%')
+ skip_white(start, end);
+ if (*start >= end)
+ break;
+ if (!strncmp(*start, "%%EndProlog", 11)) {
+ found_prolog = 1;
+ pdfparse_skip_line(start, end);
+ break;
+ } else if (!strncmp(*start, "%%Page:", 7)) {
+ pdfparse_skip_line(start, end);
+ break;
+ }
+ pdfparse_skip_line(start, end);
+ }
+ if (!found_prolog) {
+ *start = save;
+ }
+
+ return;
+}
+
+/* PostScript Operators */
+
+/* Acoid conflict with SET... from <wingdi.h>. */
+#undef SETLINECAP
+#undef SETLINEJOIN
+#undef SETMITERLIMIT
+
+#define ADD 1
+#define SUB 2
+#define MUL 3
+#define DIV 4
+#define NEG 5
+#define TRUNCATE 6
+
+#define CLEAR 10
+#define EXCH 11
+#define POP 12
+
+#define NEWPATH 31
+#define CLOSEPATH 32
+#define MOVETO 33
+#define RMOVETO 34
+#define CURVETO 35
+#define RCURVETO 36
+#define LINETO 37
+#define RLINETO 38
+#define ARC 39
+#define ARCN 40
+
+#define FILL 41
+#define STROKE 42
+#define SHOW 43
+
+#define CLIP 44
+#define EOCLIP 45
+
+#define SHOWPAGE 49
+
+#define GSAVE 50
+#define GRESTORE 51
+
+#define CONCAT 52
+#define SCALE 53
+#define TRANSLATE 54
+#define ROTATE 55
+
+#define SETLINEWIDTH 60
+#define SETDASH 61
+#define SETLINECAP 62
+#define SETLINEJOIN 63
+#define SETMITERLIMIT 64
+
+#define SETGRAY 70
+#define SETRGBCOLOR 71
+#define SETCMYKCOLOR 72
+
+#define CURRENTPOINT 80
+#define IDTRANSFORM 81
+#define DTRANSFORM 82
+
+#define FINDFONT 201
+#define SCALEFONT 202
+#define SETFONT 203
+#define CURRENTFONT 204
+
+#define STRINGWIDTH 210
+
+#define DEF 999
+
+#define FSHOW 1001
+#define STEXFIG 1002
+#define ETEXFIG 1003
+#define HLW 1004
+#define VLW 1005
+#define RD 1006
+#define B 1007
+
+static struct operators
+{
+ const char *token;
+ int opcode;
+} ps_operators[] = {
+ {"add", ADD},
+ {"mul", MUL},
+ {"div", DIV},
+ {"neg", NEG},
+ {"sub", SUB},
+ {"truncate", TRUNCATE},
+
+ {"clear", CLEAR},
+ {"exch", EXCH},
+ {"pop", POP},
+
+ {"clip", CLIP},
+ {"eoclip", EOCLIP},
+ {"closepath", CLOSEPATH},
+ {"concat", CONCAT},
+
+ {"newpath", NEWPATH},
+ {"moveto", MOVETO},
+ {"rmoveto", RMOVETO},
+ {"lineto", LINETO},
+ {"rlineto", RLINETO},
+ {"curveto", CURVETO},
+ {"rcurveto", RCURVETO},
+ {"arc", ARC},
+ {"arcn", ARCN},
+
+ {"stroke", STROKE},
+ {"fill", FILL},
+ {"show", SHOW},
+ {"showpage", SHOWPAGE},
+
+ {"gsave", GSAVE},
+ {"grestore", GRESTORE},
+ {"translate", TRANSLATE},
+ {"rotate", ROTATE},
+ {"scale", SCALE},
+
+ {"setlinecap", SETLINECAP},
+ {"setlinejoin", SETLINEJOIN},
+ {"setlinewidth", SETLINEWIDTH},
+ {"setmiterlimit", SETMITERLIMIT},
+ {"setdash", SETDASH},
+
+ {"setgray", SETGRAY},
+ {"setrgbcolor", SETRGBCOLOR},
+ {"setcmykcolor", SETCMYKCOLOR},
+
+ {"currentpoint", CURRENTPOINT}, /* This is here for rotate support
+ in graphics package-not MP support */
+ {"dtransform", DTRANSFORM},
+ {"idtransform", IDTRANSFORM},
+
+ {"findfont", FINDFONT},
+ {"scalefont", SCALEFONT},
+ {"setfont", SETFONT},
+ {"currentfont", CURRENTFONT},
+
+ {"stringwidth", STRINGWIDTH},
+
+ {"def", DEF} /* not implemented yet; just work with mptopdf */
+};
+
+static struct operators mps_operators[] = {
+ {"fshow", FSHOW}, /* exch findfont exch scalefont setfont show */
+ {"startTexFig", STEXFIG},
+ {"endTexFig", ETEXFIG},
+ {"hlw", HLW}, /* 0 dtransform exch truncate exch idtransform pop setlinewidth */
+ {"vlw", VLW}, /* 0 exch dtransform truncate idtransform pop setlinewidth pop */
+ {"l", LINETO},
+ {"r", RLINETO},
+ {"c", CURVETO},
+ {"m", MOVETO},
+ {"p", CLOSEPATH},
+ {"n", NEWPATH},
+ {"C", SETCMYKCOLOR},
+ {"G", SETGRAY},
+ {"R", SETRGBCOLOR},
+ {"lj", SETLINEJOIN},
+ {"ml", SETMITERLIMIT},
+ {"lc", SETLINECAP},
+ {"S", STROKE},
+ {"F", FILL},
+ {"q", GSAVE},
+ {"Q", GRESTORE},
+ {"s", SCALE},
+ {"t", CONCAT},
+ {"sd", SETDASH},
+ {"rd", RD}, /* [] 0 setdash */
+ {"P", SHOWPAGE},
+ {"B", B}, /* gsave fill grestore */
+ {"W", CLIP}
+};
+
+#define NUM_PS_OPERATORS (sizeof(ps_operators)/sizeof(ps_operators[0]))
+#define NUM_MPS_OPERATORS (sizeof(mps_operators)/sizeof(mps_operators[0]))
+static int
+get_opcode (const char *token)
+{
+ int i;
+
+ for (i = 0; i < NUM_PS_OPERATORS; i++) {
+ if (!strcmp(token, ps_operators[i].token)) {
+ return ps_operators[i].opcode;
+ }
+ }
+
+ for (i = 0; i < NUM_MPS_OPERATORS; i++) {
+ if (!strcmp(token, mps_operators[i].token)) {
+ return mps_operators[i].opcode;
+ }
+ }
+
+ return -1;
+}
+
+#define PS_STACK_SIZE 1024
+
+static pdf_obj *stack[PS_STACK_SIZE];
+static unsigned top_stack = 0;
+
+#define POP_STACK() ((top_stack > 0) ? stack[--top_stack] : NULL)
+#define PUSH_STACK(o,e) { \
+ if (top_stack < PS_STACK_SIZE) { \
+ stack[top_stack++] = (o); \
+ } else { \
+ WARN("PS stack overflow including MetaPost file or inline PS code"); \
+ *(e) = 1; \
+ } \
+}
+
+static int
+do_exch (void)
+{
+ pdf_obj *tmp;
+
+ if (top_stack < 2)
+ return -1;
+
+ tmp = stack[top_stack-1];
+ stack[top_stack-1] = stack[top_stack-2];
+ stack[top_stack-2] = tmp;
+
+ return 0;
+}
+
+static int
+do_clear (void)
+{
+ pdf_obj *tmp;
+
+ while (top_stack > 0) {
+ tmp = POP_STACK();
+ if (tmp)
+ pdf_release_obj(tmp);
+ }
+
+ return 0;
+}
+
+/* This should be set_bottom and clear (or
+ * have independent stack) to ensure stack
+ * depth do not go below real stack bottom.
+ */
+static void
+mps_stack_clear_to (int depth)
+{
+ pdf_obj *tmp;
+
+ while (top_stack > depth) {
+ tmp = POP_STACK();
+ if (tmp)
+ pdf_release_obj(tmp);
+ }
+
+ return;
+}
+
+static int
+pop_get_numbers (double *values, int count)
+{
+ pdf_obj *tmp;
+
+ while (count-- > 0) {
+ tmp = POP_STACK();
+ if (!tmp) {
+ WARN("mpost: Stack underflow.");
+ break;
+ } else if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ WARN("mpost: Not a number!");
+ pdf_release_obj(tmp);
+ break;
+ }
+ values[count] = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ }
+
+ return (count + 1);
+}
+
+static int
+cvr_array (pdf_obj *array, double *values, int count)
+{
+ if (!PDF_OBJ_ARRAYTYPE(array)) {
+ WARN("mpost: Not an array!");
+ } else {
+ pdf_obj *tmp;
+
+ while (count-- > 0) {
+ tmp = pdf_get_array(array, count);
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ WARN("mpost: Not a number!");
+ break;
+ }
+ values[count] = pdf_number_value(tmp);
+ }
+ }
+ if (array)
+ pdf_release_obj(array);
+
+ return (count + 1);
+}
+
+static int
+is_fontdict (pdf_obj *dict)
+{
+ pdf_obj *tmp;
+
+ if (!PDF_OBJ_DICTTYPE(dict))
+ return 0;
+
+ tmp = pdf_lookup_dict(dict, "Type");
+ if (!tmp || !PDF_OBJ_NAMETYPE(tmp) ||
+ strcmp(pdf_name_value(tmp), "Font")) {
+ return 0;
+ }
+
+ tmp = pdf_lookup_dict(dict, "FontName");
+ if (!tmp || !PDF_OBJ_NAMETYPE(tmp)) {
+ return 0;
+ }
+
+ tmp = pdf_lookup_dict(dict, "FontScale");
+ if (!tmp || !PDF_OBJ_NUMBERTYPE(tmp)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+do_findfont (void)
+{
+ int error = 0;
+ pdf_obj *font_dict, *font_name;
+
+ font_name = POP_STACK();
+ if (!font_name)
+ return 1;
+ else if (PDF_OBJ_STRINGTYPE(font_name) ||
+ PDF_OBJ_NAMETYPE(font_name)) {
+ /* Do not check the existence...
+ * The reason for this is that we cannot locate PK font without
+ * font scale.
+ */
+ font_dict = pdf_new_dict();
+ pdf_add_dict(font_dict,
+ pdf_new_name("Type"), pdf_new_name("Font"));
+ if (PDF_OBJ_STRINGTYPE(font_name)) {
+ pdf_add_dict(font_dict,
+ pdf_new_name("FontName"),
+ pdf_new_name(pdf_string_value(font_name)));
+ pdf_release_obj(font_name);
+ } else {
+ pdf_add_dict(font_dict,
+ pdf_new_name("FontName"), font_name);
+ }
+ pdf_add_dict(font_dict,
+ pdf_new_name("FontScale"), pdf_new_number(1.0));
+
+ if (top_stack < PS_STACK_SIZE) {
+ stack[top_stack++] = font_dict;
+ } else {
+ WARN("PS stack overflow including MetaPost file or inline PS code");
+ pdf_release_obj(font_dict);
+ error = 1;
+ }
+ } else {
+ error = 1;
+ }
+
+ return error;
+}
+
+static int
+do_scalefont (void)
+{
+ int error = 0;
+ pdf_obj *font_dict;
+ pdf_obj *font_scale;
+ double scale;
+
+ error = pop_get_numbers(&scale, 1);
+ if (error)
+ return error;
+
+ font_dict = POP_STACK();
+ if (!font_dict)
+ error = 1;
+ else if (is_fontdict(font_dict)) {
+ font_scale = pdf_lookup_dict(font_dict, "FontScale");
+ pdf_set_number(font_scale, pdf_number_value(font_scale)*scale);
+ if (top_stack < PS_STACK_SIZE) {
+ stack[top_stack++] = font_dict;
+ } else {
+ WARN("PS stack overflow including MetaPost file or inline PS code");
+ pdf_release_obj(font_dict);
+ error = 1;
+ }
+ } else {
+ error = 1;
+ }
+
+ return error;
+}
+
+static int
+do_setfont (void)
+{
+ int error = 0;
+ char *font_name;
+ double font_scale;
+ pdf_obj *font_dict;
+
+ font_dict = POP_STACK();
+ if (!is_fontdict(font_dict))
+ error = 1;
+ else {
+ /* Subfont support prevent us from managing
+ * font in a single place...
+ */
+ font_name = pdf_name_value (pdf_lookup_dict(font_dict, "FontName"));
+ font_scale = pdf_number_value(pdf_lookup_dict(font_dict, "FontScale"));
+
+ error = mp_setfont(font_name, font_scale);
+ }
+ pdf_release_obj(font_dict);
+
+ return error;
+}
+
+/* Push dummy font dict onto PS stack */
+static int
+do_currentfont (void)
+{
+ int error = 0;
+ struct mp_font *font;
+ pdf_obj *font_dict;
+
+ font = CURRENT_FONT();
+ if (!FONT_DEFINED(font)) {
+ WARN("Currentfont undefined...");
+ return 1;
+ } else {
+ font_dict = pdf_new_dict();
+ pdf_add_dict(font_dict,
+ pdf_new_name("Type"),
+ pdf_new_name("Font"));
+ pdf_add_dict(font_dict,
+ pdf_new_name("FontName"),
+ pdf_new_name(font->font_name));
+ pdf_add_dict(font_dict,
+ pdf_new_name("FontScale"),
+ pdf_new_number(font->pt_size));
+ if (top_stack < PS_STACK_SIZE) {
+ stack[top_stack++] = font_dict;
+ } else {
+ WARN("PS stack overflow...");
+ pdf_release_obj(font_dict);
+ error = 1;
+ }
+ }
+
+ return error;
+}
+
+static int
+do_show (void)
+{
+ struct mp_font *font;
+ pdf_coord cp;
+ pdf_obj *text_str;
+ int length;
+ unsigned char *strptr;
+ double text_width;
+
+ font = CURRENT_FONT();
+ if (!FONT_DEFINED(font)) {
+ WARN("Currentfont not set."); /* Should not be error... */
+ return 1;
+ }
+
+ pdf_dev_currentpoint(&cp);
+
+ text_str = POP_STACK();
+ if (!PDF_OBJ_STRINGTYPE(text_str)) {
+ if (text_str)
+ pdf_release_obj(text_str);
+ return 1;
+ }
+ if (font->font_id < 0) {
+ WARN("mpost: not set."); /* Should not be error... */
+ pdf_release_obj(text_str);
+ return 1;
+ }
+
+ strptr = pdf_string_value (text_str);
+ length = pdf_string_length(text_str);
+
+ if (font->tfm_id < 0) {
+ WARN("mpost: TFM not found for \"%s\".", font->font_name);
+ WARN("mpost: Text width not calculated...");
+ }
+
+ text_width = 0.0;
+ if (font->subfont_id >= 0) {
+ unsigned short uch;
+ unsigned char *ustr;
+ int i;
+
+ ustr = NEW(length * 2, unsigned char);
+ for (i = 0; i < length; i++) {
+ uch = lookup_sfd_record(font->subfont_id, strptr[i]);
+ ustr[2*i ] = uch >> 8;
+ ustr[2*i+1] = uch & 0xff;
+ if (font->tfm_id >= 0) {
+ text_width += tfm_get_width(font->tfm_id, strptr[i]);
+ }
+ }
+ text_width *= font->pt_size;
+
+ pdf_dev_set_string((spt_t)(cp.x * dev_unit_dviunit()),
+ (spt_t)(cp.y * dev_unit_dviunit()),
+ ustr, length * 2,
+ (spt_t)(text_width*dev_unit_dviunit()),
+ font->font_id);
+ RELEASE(ustr);
+ } else {
+#define FWBASE ((double) (1<<20))
+ if (font->tfm_id >= 0) {
+ text_width = (double) tfm_string_width(font->tfm_id, strptr, length)/FWBASE;
+ text_width *= font->pt_size;
+ }
+ pdf_dev_set_string((spt_t)(cp.x * dev_unit_dviunit()),
+ (spt_t)(cp.y * dev_unit_dviunit()),
+ strptr, length,
+ (spt_t)(text_width*dev_unit_dviunit()),
+ font->font_id);
+ }
+
+ if (pdf_dev_get_font_wmode(font->font_id)) {
+ pdf_dev_rmoveto(0.0, -text_width);
+ } else {
+ pdf_dev_rmoveto(text_width, 0.0);
+ }
+
+ graphics_mode();
+ pdf_release_obj(text_str);
+
+ return 0;
+}
+
+static int
+do_mpost_bind_def (const char *ps_code, double x_user, double y_user)
+{
+ int error = 0;
+ const char *start, *end;
+
+ start = ps_code;
+ end = start + strlen(start);
+
+ error = mp_parse_body(&start, end, x_user, y_user);
+
+ return error;
+}
+
+static int
+do_texfig_operator (int opcode, double x_user, double y_user)
+{
+ static transform_info fig_p;
+ static int in_tfig = 0;
+ static int xobj_id = -1;
+ static int count = 0;
+ double values[6];
+ int error = 0;
+
+ switch (opcode) {
+ case STEXFIG:
+ error = pop_get_numbers(values, 6);
+ if (!error) {
+ double dvi2pts;
+ char resname[256];
+
+ transform_info_clear(&fig_p);
+ dvi2pts = 1.0/dev_unit_dviunit();
+
+ fig_p.width = values[0] * dvi2pts;
+ fig_p.height = values[1] * dvi2pts;
+ fig_p.bbox.llx = values[2] * dvi2pts;
+ fig_p.bbox.lly = -values[3] * dvi2pts;
+ fig_p.bbox.urx = values[4] * dvi2pts;
+ fig_p.bbox.ury = -values[5] * dvi2pts;
+ fig_p.flags |= INFO_HAS_USER_BBOX;
+
+ sprintf(resname, "__tf%d__", count);
+ xobj_id = pdf_doc_begin_grabbing(resname, fig_p.bbox.llx, fig_p.bbox.ury, &fig_p.bbox);
+
+ in_tfig = 1;
+ count++;
+ }
+ break;
+ case ETEXFIG:
+ if (!in_tfig)
+ ERROR("endTexFig without valid startTexFig!.");
+
+ pdf_doc_end_grabbing(NULL);
+ pdf_dev_put_image(xobj_id, &fig_p, x_user, y_user, NULL); /* FIXME */
+ in_tfig = 0;
+ break;
+ default:
+ error = 1;
+ }
+
+ return error;
+}
+
+/*
+ * buggy...
+ */
+
+/*
+ * CTM(Current Transformation Matrix) means the transformation of User Space
+ * to Device Space coordinates. Because DVIPDFMx does not know the resolution
+ * of Device Space, we assume that the resolution is 1/1000.
+ */
+#define DEVICE_RESOLUTION 1000
+static int
+ps_dev_CTM (pdf_tmatrix *M)
+{
+ pdf_dev_currentmatrix(M);
+ M->a *= DEVICE_RESOLUTION; M->b *= DEVICE_RESOLUTION;
+ M->c *= DEVICE_RESOLUTION; M->d *= DEVICE_RESOLUTION;
+ M->e *= DEVICE_RESOLUTION; M->f *= DEVICE_RESOLUTION;
+
+ return 0;
+}
+
+/*
+ * Again, the only piece that needs x_user and y_user is
+ * that piece dealing with texfig.
+ */
+static int
+do_operator (const char *token, double x_user, double y_user)
+{
+ int error = 0;
+ int opcode = 0;
+ double values[12];
+ pdf_obj *tmp = NULL;
+ pdf_tmatrix matrix;
+ pdf_coord cp;
+ pdf_color color;
+
+#define PUSH(o) { \
+ if (top_stack < PS_STACK_SIZE) { \
+ stack[top_stack++] = (o); \
+ } else { \
+ WARN("PS stack overflow including MetaPost file or inline PS code"); \
+ error=1; \
+ break;\
+ } \
+}
+
+ opcode = get_opcode(token);
+
+ switch (opcode) {
+
+ /*
+ * Arithmetic operators
+ */
+ case ADD:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ PUSH(pdf_new_number(values[0] + values[1]));
+ break;
+ case MUL:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ PUSH(pdf_new_number(values[0]*values[1]));
+ break;
+ case NEG:
+ error = pop_get_numbers(values, 1);
+ if (!error)
+ PUSH(pdf_new_number(-values[0]));
+ break;
+ case SUB:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ PUSH(pdf_new_number(values[0] - values[1]));
+ break;
+ case DIV:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ PUSH(pdf_new_number(values[0]/values[1]));
+ break;
+ case TRUNCATE: /* Round toward zero. */
+ error = pop_get_numbers(values, 1);
+ if (!error)
+ PUSH(pdf_new_number(((values[0] > 0) ? floor(values[0]) : ceil(values[0]))));
+ break;
+
+ /* Stack operation */
+ case CLEAR:
+ error = do_clear();
+ break;
+ case POP:
+ tmp = POP_STACK();
+ if (tmp)
+ pdf_release_obj(tmp);
+ break;
+ case EXCH:
+ error = do_exch();
+ break;
+
+ /* Path construction */
+ case MOVETO:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ error = pdf_dev_moveto(values[0], values[1]);
+ break;
+ case RMOVETO:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ error = pdf_dev_rmoveto(values[0], values[1]);
+ break;
+ case LINETO:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ error = pdf_dev_lineto(values[0], values[1]);
+ break;
+ case RLINETO:
+ error = pop_get_numbers(values, 2);
+ if (!error)
+ error = pdf_dev_rlineto(values[0], values[1]);
+ break;
+ case CURVETO:
+ error = pop_get_numbers(values, 6);
+ if (!error)
+ error = pdf_dev_curveto(values[0], values[1],
+ values[2], values[3],
+ values[4], values[5]);
+ break;
+ case RCURVETO:
+ error = pop_get_numbers(values, 6);
+ if (!error)
+ error = pdf_dev_rcurveto(values[0], values[1],
+ values[2], values[3],
+ values[4], values[5]);
+ break;
+ case CLOSEPATH:
+ error = pdf_dev_closepath();
+ break;
+ case ARC:
+ error = pop_get_numbers(values, 5);
+ if (!error)
+ error = pdf_dev_arc(values[0], values[1],
+ values[2], /* rad */
+ values[3], values[4]);
+ break;
+ case ARCN:
+ error = pop_get_numbers(values, 5);
+ if (!error)
+ error = pdf_dev_arcn(values[0], values[1],
+ values[2], /* rad */
+ values[3], values[4]);
+ break;
+
+ case NEWPATH:
+ pdf_dev_newpath();
+ break;
+ case STROKE:
+ /* fill rule not supported yet */
+ pdf_dev_flushpath('S', PDF_FILL_RULE_NONZERO);
+ break;
+ case FILL:
+ pdf_dev_flushpath('f', PDF_FILL_RULE_NONZERO);
+ break;
+
+ case CLIP:
+ error = pdf_dev_clip();
+ break;
+ case EOCLIP:
+ error = pdf_dev_eoclip();
+ break;
+
+ /* Graphics state operators: */
+ case GSAVE:
+ error = pdf_dev_gsave();
+ save_font();
+ break;
+ case GRESTORE:
+ error = pdf_dev_grestore();
+ restore_font();
+ break;
+
+ case CONCAT:
+ tmp = POP_STACK();
+ error = cvr_array(tmp, values, 6); /* This does pdf_release_obj() */
+ tmp = NULL;
+ if (error)
+ WARN("Missing array before \"concat\".");
+ else {
+ pdf_setmatrix(&matrix,
+ values[0], values[1],
+ values[2], values[3],
+ values[4], values[5]);
+ error = pdf_dev_concat(&matrix);
+ }
+ break;
+ case SCALE:
+ error = pop_get_numbers(values, 2);
+ if (!error) {
+ switch (mp_cmode) {
+#ifndef WITHOUT_ASCII_PTEX
+ case MP_CMODE_PTEXVERT:
+ pdf_setmatrix(&matrix,
+ values[1], 0.0,
+ 0.0 , values[0],
+ 0.0 , 0.0);
+ break;
+#endif /* !WITHOUT_ASCII_PTEX */
+ default:
+ pdf_setmatrix(&matrix,
+ values[0], 0.0,
+ 0.0 , values[1],
+ 0.0 , 0.0);
+ break;
+ }
+
+ error = pdf_dev_concat(&matrix);
+ }
+ break;
+ /* Positive angle means clock-wise direction in graphicx-dvips??? */
+ case ROTATE:
+ error = pop_get_numbers(values, 1);
+ if (!error) {
+ values[0] = values[0] * M_PI / 180;
+
+ switch (mp_cmode) {
+ case MP_CMODE_DVIPSK:
+ case MP_CMODE_MPOST: /* Really? */
+#ifndef WITHOUT_ASCII_PTEX
+ case MP_CMODE_PTEXVERT:
+#endif /* !WITHOUT_ASCII_PTEX */
+ pdf_setmatrix(&matrix,
+ cos(values[0]), -sin(values[0]),
+ sin(values[0]), cos(values[0]),
+ 0.0, 0.0);
+ break;
+ default:
+ pdf_setmatrix(&matrix,
+ cos(values[0]) , sin(values[0]),
+ -sin(values[0]), cos(values[0]),
+ 0.0, 0.0);
+ break;
+ }
+ error = pdf_dev_concat(&matrix);
+ }
+ break;
+ case TRANSLATE:
+ error = pop_get_numbers(values, 2);
+ if (!error) {
+ pdf_setmatrix(&matrix,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ values[0], values[1]);
+ error = pdf_dev_concat(&matrix);
+ }
+ break;
+
+ case SETDASH:
+ error = pop_get_numbers(values, 1);
+ if (!error) {
+ pdf_obj *pattern, *dash;
+ int i, num_dashes;
+ double dash_values[PDF_DASH_SIZE_MAX];
+ double offset;
+
+ offset = values[0];
+ pattern = POP_STACK();
+ if (!PDF_OBJ_ARRAYTYPE(pattern)) {
+ if (pattern)
+ pdf_release_obj(pattern);
+ error = 1;
+ break;
+ }
+ num_dashes = pdf_array_length(pattern);
+ if (num_dashes > PDF_DASH_SIZE_MAX) {
+ WARN("Too many dashes...");
+ pdf_release_obj(pattern);
+ error = 1;
+ break;
+ }
+ for (i = 0;
+ i < num_dashes && !error ; i++) {
+ dash = pdf_get_array(pattern, i);
+ if (!PDF_OBJ_NUMBERTYPE(dash))
+ error = 1;
+ else {
+ dash_values[i] = pdf_number_value(dash);
+ }
+ }
+ pdf_release_obj(pattern);
+ if (!error) {
+ error = pdf_dev_setdash(num_dashes, dash_values, offset);
+ }
+ }
+ break;
+ case SETLINECAP:
+ error = pop_get_numbers(values, 1);
+ if (!error)
+ error = pdf_dev_setlinecap((int)values[0]);
+ break;
+ case SETLINEJOIN:
+ error = pop_get_numbers(values, 1);
+ if (!error)
+ error = pdf_dev_setlinejoin((int)values[0]);
+ break;
+ case SETLINEWIDTH:
+ error = pop_get_numbers(values, 1);
+ if (!error)
+ error = pdf_dev_setlinewidth(values[0]);
+ break;
+ case SETMITERLIMIT:
+ error = pop_get_numbers(values, 1);
+ if (!error)
+ error = pdf_dev_setmiterlimit(values[0]);
+ break;
+
+ case SETCMYKCOLOR:
+ error = pop_get_numbers(values, 4);
+ /* Not handled properly */
+ if (!error) {
+ pdf_color_cmykcolor(&color,
+ values[0], values[1],
+ values[2], values[3]);
+ pdf_dev_set_strokingcolor(&color);
+ pdf_dev_set_nonstrokingcolor(&color);
+ }
+ break;
+ case SETGRAY:
+ /* Not handled properly */
+ error = pop_get_numbers(values, 1);
+ if (!error) {
+ pdf_color_graycolor(&color, values[0]);
+ pdf_dev_set_strokingcolor(&color);
+ pdf_dev_set_nonstrokingcolor(&color);
+ }
+ break;
+ case SETRGBCOLOR:
+ error = pop_get_numbers(values, 3);
+ if (!error) {
+ pdf_color_rgbcolor(&color,
+ values[0], values[1], values[2]);
+ pdf_dev_set_strokingcolor(&color);
+ pdf_dev_set_nonstrokingcolor(&color);
+ }
+ break;
+
+ case SHOWPAGE: /* Let's ignore this for now */
+ break;
+
+ case CURRENTPOINT:
+ error = pdf_dev_currentpoint(&cp);
+ if (!error) {
+ PUSH(pdf_new_number(cp.x));
+ PUSH(pdf_new_number(cp.y));
+ }
+ break;
+
+ case DTRANSFORM:
+ {
+ int has_matrix = 0;
+
+ tmp = POP_STACK();
+ if (PDF_OBJ_ARRAYTYPE(tmp)) {
+ error = cvr_array(tmp, values, 6); /* This does pdf_release_obj() */
+ tmp = NULL;
+ if (error)
+ break;
+ pdf_setmatrix(&matrix,
+ values[0], values[1],
+ values[2], values[3],
+ values[4], values[5]);
+ tmp = POP_STACK();
+ has_matrix = 1;
+ }
+
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ error = 1;
+ break;
+ }
+ cp.y = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+
+ tmp = POP_STACK();
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ error = 1;
+ break;
+ }
+ cp.x = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+
+ if (!has_matrix) {
+ ps_dev_CTM(&matrix); /* Here, we need real PostScript CTM */
+ }
+ pdf_dev_dtransform(&cp, &matrix);
+ PUSH(pdf_new_number(cp.x));
+ PUSH(pdf_new_number(cp.y));
+ }
+ break;
+
+ case IDTRANSFORM:
+ {
+ int has_matrix = 0;
+
+ tmp = POP_STACK();
+ if (PDF_OBJ_ARRAYTYPE(tmp)) {
+ error = cvr_array(tmp, values, 6); /* This does pdf_release_obj() */
+ tmp = NULL;
+ if (error)
+ break;
+ pdf_setmatrix(&matrix,
+ values[0], values[1],
+ values[2], values[3],
+ values[4], values[5]);
+ tmp = POP_STACK();
+ has_matrix = 1;
+ }
+
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ error = 1;
+ break;
+ }
+ cp.y = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+
+ tmp = POP_STACK();
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ error = 1;
+ break;
+ }
+ cp.x = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+
+ if (!has_matrix) {
+ ps_dev_CTM(&matrix); /* Here, we need real PostScript CTM */
+ }
+ pdf_dev_idtransform(&cp, &matrix);
+ PUSH(pdf_new_number(cp.x));
+ PUSH(pdf_new_number(cp.y));
+ break;
+ }
+
+ case FINDFONT:
+ error = do_findfont();
+ break;
+ case SCALEFONT:
+ error = do_scalefont();
+ break;
+ case SETFONT:
+ error = do_setfont();
+ break;
+ case CURRENTFONT:
+ error = do_currentfont();
+ break;
+
+ case SHOW:
+ error = do_show();
+ break;
+
+ case STRINGWIDTH:
+ error = 1;
+ break;
+
+ /* Extensions */
+ case FSHOW:
+ error = do_mpost_bind_def("exch findfont exch scalefont setfont show", x_user, y_user);
+ break;
+ case STEXFIG:
+ case ETEXFIG:
+ error = do_texfig_operator(opcode, x_user, y_user);
+ break;
+ case HLW:
+ error = do_mpost_bind_def("0 dtransform exch truncate exch idtransform pop setlinewidth", x_user, y_user);
+ break;
+ case VLW:
+ error = do_mpost_bind_def("0 exch dtransform truncate idtransform setlinewidth pop", x_user, y_user);
+ break;
+ case RD:
+ error = do_mpost_bind_def("[] 0 setdash", x_user, y_user);
+ break;
+ case B:
+ error = do_mpost_bind_def("gsave fill grestore", x_user, y_user);
+ break;
+
+ case DEF:
+ tmp = POP_STACK();
+ tmp = POP_STACK();
+ /* do nothing; not implemented yet */
+ break;
+
+ default:
+ if (is_fontname(token)) {
+ PUSH(pdf_new_name(token));
+ } else {
+ WARN("Unknown token \"%s\"", token);
+ error = 1;
+ }
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * The only sections that need to know x_user and y _user are those
+ * dealing with texfig.
+ */
+static int
+mp_parse_body (const char **start, const char *end, double x_user, double y_user)
+{
+ char *token;
+ pdf_obj *obj;
+ int error = 0;
+
+ skip_white(start, end);
+ while (*start < end && !error) {
+ if (isdigit((unsigned char)**start) ||
+ (*start < end - 1 &&
+ (**start == '+' || **start == '-' || **start == '.' ))) {
+ double value;
+ char *next;
+
+ value = strtod(*start, &next);
+ if (next < end && !strchr("<([{/%", *next) && !isspace((unsigned char)*next)) {
+ WARN("Unkown PostScript operator.");
+ dump(*start, next);
+ error = 1;
+ } else {
+ PUSH(pdf_new_number(value));
+ *start = next;
+ }
+ /*
+ * PDF parser can't handle PS operator inside arrays.
+ * This shouldn't use parse_pdf_array().
+ */
+ } else if (**start == '[' &&
+ (obj = parse_pdf_array(start, end, NULL))) {
+ PUSH(obj);
+ /* This cannot handle ASCII85 string. */
+ } else if (*start < end - 1 &&
+ (**start == '<' && *(*start+1) == '<') &&
+ (obj = parse_pdf_dict(start, end, NULL))) {
+ PUSH(obj);
+ } else if ((**start == '(' || **start == '<') &&
+ (obj = parse_pdf_string (start, end))) {
+ PUSH(obj);
+ } else if (**start == '/' &&
+ (obj = parse_pdf_name(start, end))) {
+ PUSH(obj);
+ } else {
+ token = parse_ident(start, end);
+ if (!token)
+ error = 1;
+ else {
+ error = do_operator(token, x_user, y_user);
+ RELEASE(token);
+ }
+ }
+ skip_white(start, end);
+ }
+
+ return error;
+}
+
+void
+mps_eop_cleanup (void)
+{
+ clear_fonts();
+ do_clear();
+}
+
+int
+mps_stack_depth (void)
+{
+ return top_stack;
+}
+
+int
+mps_exec_inline (const char **p, const char *endptr,
+ double x_user, double y_user)
+{
+ int error;
+ int dirmode, autorotate;
+
+ /* Compatibility for dvipsk. */
+ dirmode = pdf_dev_get_dirmode();
+ if (dirmode) {
+ mp_cmode = MP_CMODE_PTEXVERT;
+ } else {
+ mp_cmode = MP_CMODE_DVIPSK;
+ }
+
+ autorotate = pdf_dev_get_param(PDF_DEV_PARAM_AUTOROTATE);
+ pdf_dev_set_param(PDF_DEV_PARAM_AUTOROTATE, 0);
+ //pdf_color_push(); /* ... */
+
+ /* Comment in dvipdfm:
+ * Remember that x_user and y_user are off by 0.02 %
+ */
+ pdf_dev_moveto(x_user, y_user);
+ error = mp_parse_body(p, endptr, x_user, y_user);
+
+ //pdf_color_pop(); /* ... */
+ pdf_dev_set_param(PDF_DEV_PARAM_AUTOROTATE, autorotate);
+ pdf_dev_set_dirmode(dirmode);
+
+ return error;
+}
+
+/* mp inclusion is a bit of a hack. The routine
+ * starts a form at the lower left corner of
+ * the page and then calls begin_form_xobj telling
+ * it to record the image drawn there and bundle it
+ * up in an xojbect. This allows us to use the coordinates
+ * in the MP file directly. This appears to be the
+ * easiest way to be able to use the pdf_dev_set_string()
+ * command (with its scaled and extended fonts) without
+ * getting all confused about the coordinate system.
+ * After the xobject is created, the whole thing can
+ * be scaled any way the user wants
+ */
+
+/* Should implement save and restore. */
+int
+mps_include_page (const char *ident, FILE *fp)
+{
+ int form_id;
+ xform_info info;
+ int st_depth, gs_depth;
+ char *buffer;
+ const char *p, *endptr;
+ int length, nb_read;
+ int dirmode, autorotate, error;
+
+ rewind(fp);
+
+ length = file_size(fp);
+ if (length < 1) {
+ WARN("Can't read any byte in the MPS file.");
+ return -1;
+ }
+
+ buffer = NEW(length + 1, char);
+ buffer[length] = '\0';
+ p = buffer;
+ endptr = p + length;
+
+ while (length > 0) {
+ nb_read = fread(buffer, sizeof(char), length, fp);
+ if (nb_read < 0) {
+ RELEASE(buffer);
+ WARN("Reading file failed...");
+ return -1;
+ }
+ length -= nb_read;
+ }
+
+ error = mps_scan_bbox(&p, endptr, &(info.bbox));
+ if (error) {
+ WARN("Error occured while scanning MetaPost file headers: Could not find BoundingBox.");
+ RELEASE(buffer);
+ return -1;
+ }
+ skip_prolog(&p, endptr);
+
+ dirmode = pdf_dev_get_dirmode();
+ autorotate = pdf_dev_get_param(PDF_DEV_PARAM_AUTOROTATE);
+ pdf_dev_set_param(PDF_DEV_PARAM_AUTOROTATE, 0);
+ //pdf_color_push();
+
+ form_id = pdf_doc_begin_grabbing(ident, Xorigin, Yorigin, &(info.bbox));
+
+ mp_cmode = MP_CMODE_MPOST;
+ gs_depth = pdf_dev_current_depth();
+ st_depth = mps_stack_depth();
+ /* At this point the gstate must be initialized, since it starts a new
+ * XObject. Note that it increase gs_depth by 1. */
+ pdf_dev_push_gstate();
+
+ error = mp_parse_body(&p, endptr, 0.0, 0.0);
+ RELEASE(buffer);
+
+ if (error) {
+ WARN("Errors occured while interpreting MPS file.");
+ /* WARN("Leaving garbage in output PDF file."); */
+ form_id = -1;
+ }
+
+ /* It's time to pop the new gstate above. */
+ pdf_dev_pop_gstate();
+ mps_stack_clear_to (st_depth);
+ pdf_dev_grestore_to(gs_depth);
+
+ pdf_doc_end_grabbing(NULL);
+
+ //pdf_color_pop();
+ pdf_dev_set_param(PDF_DEV_PARAM_AUTOROTATE, autorotate);
+ pdf_dev_set_dirmode(dirmode);
+
+ return form_id;
+}
+
+int
+mps_do_page (FILE *image_file)
+{
+ int error = 0;
+ pdf_rect bbox;
+ char *buffer;
+ const char *start, *end;
+ int size;
+ int dir_mode;
+
+ rewind(image_file);
+ if ((size = file_size(image_file)) == 0) {
+ WARN("Can't read any byte in the MPS file.");
+ return -1;
+ }
+
+ buffer = NEW(size+1, char);
+ fread(buffer, sizeof(char), size, image_file);
+ buffer[size] = 0;
+ start = buffer;
+ end = buffer + size;
+
+ error = mps_scan_bbox(&start, end, &bbox);
+ if (error) {
+ WARN("Error occured while scanning MetaPost file headers: Could not find BoundingBox.");
+ RELEASE(buffer);
+ return -1;
+ }
+
+ mp_cmode = MP_CMODE_MPOST;
+
+ pdf_doc_begin_page (1.0, -Xorigin, -Yorigin); /* scale, xorig, yorig */
+ pdf_doc_set_mediabox(pdf_doc_current_page_number(), &bbox);
+
+ dir_mode = pdf_dev_get_dirmode();
+ pdf_dev_set_autorotate(0);
+
+ skip_prolog(&start, end);
+
+ error = mp_parse_body(&start, end, 0.0, 0.0);
+
+ if (error) {
+ WARN("Errors occured while interpreting MetaPost file.");
+ }
+
+ pdf_dev_set_autorotate(1);
+ pdf_dev_set_dirmode(dir_mode);
+
+ pdf_doc_end_page();
+
+ RELEASE(buffer);
+
+ /*
+ * The reason why we don't return XObject itself is
+ * PDF inclusion may not be made so.
+ */
+ return (error ? -1 : 0);
+}
diff --git a/Build/source/texk/dvipdfm-x/mpost.h b/Build/source/texk/dvipdfm-x/mpost.h
new file mode 100644
index 00000000000..602e8ebdc2d
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/mpost.h
@@ -0,0 +1,45 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _MPOST_H_
+#define _MPOST_H_
+
+#include "mfileio.h"
+#include "pdfximage.h"
+#include "pdfdev.h"
+
+extern void mps_set_translate_origin (int boolean_value);
+
+extern int mps_scan_bbox (const char **pp, const char *endptr, pdf_rect *bbox);
+
+/* returns xobj_id */
+extern int mps_include_page (const char *ident, FILE *fp);
+
+extern int mps_exec_inline (const char **buffer, const char *endptr,
+ double x_user, double y_user);
+extern int mps_stack_depth (void);
+
+extern void mps_eop_cleanup (void);
+
+extern int mps_do_page (FILE *fp);
+
+#endif /* _MPOST_H_ */
diff --git a/Build/source/texk/dvipdfm-x/mt19937ar.c b/Build/source/texk/dvipdfm-x/mt19937ar.c
new file mode 100644
index 00000000000..fab87b924a5
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/mt19937ar.c
@@ -0,0 +1,192 @@
+/*
+ A C-program for MT19937, with initialization improved 2002/1/26.
+ Coded by Takuji Nishimura and Makoto Matsumoto.
+
+ Before using, initialize the state by using init_genrand(seed)
+ or init_by_array(init_key, key_length).
+
+ Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ Any feedback is very welcome.
+ http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+ email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+*/
+
+#include <stdio.h>
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+
+static unsigned long mt[N]; /* the array for the state vector */
+static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
+
+/* initializes mt[N] with a seed */
+/* void init_genrand(unsigned long s) */
+void init_genrand(unsigned long long s)
+{
+ mt[0]= s & 0xffffffffUL;
+ for (mti=1; mti<N; mti++) {
+ mt[mti] =
+ (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array mt[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ mt[mti] &= 0xffffffffUL;
+ /* for >32 bit machines */
+ }
+}
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+/* slight change for C++, 2004/2/26 */
+void init_by_array(unsigned long init_key[], int key_length)
+{
+ int i, j, k;
+ init_genrand(19650218UL);
+ i=1; j=0;
+ k = (N>key_length ? N : key_length);
+ for (; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
+ + init_key[j] + j; /* non linear */
+ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+ i++; j++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ if (j>=key_length) j=0;
+ }
+ for (k=N-1; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
+ - i; /* non linear */
+ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+ i++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ }
+
+ mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
+}
+
+/* generates a random number on [0,0xffffffff]-interval */
+unsigned long genrand_int32(void)
+{
+ unsigned long y;
+ static unsigned long mag01[2]={0x0UL, MATRIX_A};
+ /* mag01[x] = x * MATRIX_A for x=0,1 */
+
+ if (mti >= N) { /* generate N words at one time */
+ int kk;
+
+ if (mti == N+1) /* if init_genrand() has not been called, */
+ init_genrand(5489UL); /* a default initial seed is used */
+
+ for (kk=0;kk<N-M;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ for (;kk<N-1;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+ mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+ mti = 0;
+ }
+
+ y = mt[mti++];
+
+ /* Tempering */
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680UL;
+ y ^= (y << 15) & 0xefc60000UL;
+ y ^= (y >> 18);
+
+ return y;
+}
+
+/* generates a random number on [0,0x7fffffff]-interval */
+long genrand_int31(void)
+{
+ return (long)(genrand_int32()>>1);
+}
+
+/* generates a random number on [0,1]-real-interval */
+double genrand_real1(void)
+{
+ return genrand_int32()*(1.0/4294967295.0);
+ /* divided by 2^32-1 */
+}
+
+/* generates a random number on [0,1)-real-interval */
+double genrand_real2(void)
+{
+ return genrand_int32()*(1.0/4294967296.0);
+ /* divided by 2^32 */
+}
+
+/* generates a random number on (0,1)-real-interval */
+double genrand_real3(void)
+{
+ return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
+ /* divided by 2^32 */
+}
+
+/* generates a random number on [0,1) with 53-bit resolution*/
+double genrand_res53(void)
+{
+ unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
+ return(a*67108864.0+b)*(1.0/9007199254740992.0);
+}
+/* These real versions are due to Isaku Wada, 2002/01/09 added */
+#ifdef TEST
+int main(void)
+{
+ int i;
+ unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
+ init_by_array(init, length);
+ printf("1000 outputs of genrand_int32()\n");
+ for (i=0; i<1000; i++) {
+ printf("%10lu ", genrand_int32());
+ if (i%5==4) printf("\n");
+ }
+ printf("\n1000 outputs of genrand_real2()\n");
+ for (i=0; i<1000; i++) {
+ printf("%10.8f ", genrand_real2());
+ if (i%5==4) printf("\n");
+ }
+ return 0;
+}
+#endif
diff --git a/Build/source/texk/dvipdfm-x/numbers.c b/Build/source/texk/dvipdfm-x/numbers.c
new file mode 100644
index 00000000000..382612b2f80
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/numbers.c
@@ -0,0 +1,171 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "error.h"
+#include "mfileio.h"
+#include "numbers.h"
+
+unsigned char get_unsigned_byte (FILE *file)
+{
+ int ch;
+ if ((ch = fgetc (file)) < 0)
+ ERROR ("File ended prematurely\n");
+ return (unsigned char) ch;
+}
+
+void skip_bytes (unsigned int n, FILE *file)
+{
+ while (n-- > 0)
+ get_unsigned_byte(file);
+}
+
+signed char get_signed_byte (FILE *file)
+{
+ int byte;
+ byte = get_unsigned_byte(file);
+ if (byte >= 0x80)
+ byte -= 0x100;
+ return (signed char) byte;
+}
+
+unsigned short get_unsigned_pair (FILE *file)
+{
+ unsigned short pair = get_unsigned_byte(file);
+ pair = (pair << 8) | get_unsigned_byte(file);
+ return pair;
+}
+
+unsigned short sget_unsigned_pair (unsigned char *s)
+{
+ unsigned short pair = *(s++);
+ pair = (pair << 8) | *(s++);
+ return pair;
+}
+
+signed short get_signed_pair (FILE *file)
+{
+ signed short pair = get_signed_byte(file);
+ pair = (pair << 8) | get_unsigned_byte(file);
+ return pair;
+}
+
+
+unsigned int get_unsigned_triple(FILE *file)
+{
+ int i;
+ unsigned int triple = 0;
+ for (i=0; i<3; i++) {
+ triple = (triple << 8) | get_unsigned_byte(file);
+ }
+ return triple;
+}
+
+signed int get_signed_triple(FILE *file)
+{
+ int i;
+ signed int triple = get_signed_byte(file);
+ for (i=0; i<2; i++) {
+ triple = (triple << 8) | get_unsigned_byte(file);
+ }
+ return triple;
+}
+
+int32_t get_signed_quad(FILE *file)
+{
+ int i;
+ int32_t quad = get_signed_byte(file);
+ for (i=0; i<3; i++) {
+ quad = (quad << 8) | get_unsigned_byte(file);
+ }
+ return quad;
+}
+
+uint32_t get_unsigned_quad(FILE *file)
+{
+ int i;
+ uint32_t quad = 0;
+ for (i=0; i<4; i++) {
+ quad = (quad << 8) | get_unsigned_byte(file);
+ }
+ return quad;
+}
+
+int32_t get_unsigned_num (FILE *file, unsigned char num)
+{
+ int32_t val = get_unsigned_byte (file);
+ switch (num) {
+ case 3: if (val > 0x7f)
+ val -= 0x100;
+ val = (val << 8) | get_unsigned_byte (file);
+ case 2: val = (val << 8) | get_unsigned_byte (file);
+ case 1: val = (val << 8) | get_unsigned_byte (file);
+ default: break;
+ }
+ return val;
+}
+
+/* Compute a signed quad that must be positive */
+uint32_t get_positive_quad (FILE *file, const char *type, const char *name)
+{
+ int32_t val = get_signed_quad (file);
+ if (val < 0)
+ ERROR ("Bad %s: negative %s: %d", type, name, val);
+ return (uint32_t)val;
+}
+
+int32_t sqxfw (int32_t sq, fixword fw)
+{
+ int sign = 1;
+ uint32_t a, b, c, d, ad, bd, bc, ac;
+ uint32_t e, f, g, h, i, j, k;
+ int32_t result;
+ /* Make positive. */
+ if (sq < 0) {
+ sign = -sign;
+ sq = -sq;
+ }
+ if (fw < 0) {
+ sign = -sign;
+ fw = -fw;
+ }
+ a = ((uint32_t) sq) >> 16;
+ b = ((uint32_t) sq) & 0xffffu;
+ c = ((uint32_t) fw) >> 16;
+ d = ((uint32_t) fw) & 0xffffu;
+ ad = a*d; bd = b*d; bc = b*c; ac = a*c;
+ e = bd >> 16;
+ f = ad >> 16;
+ g = ad & 0xffffu;
+ h = bc >> 16;
+ i = bc & 0xffffu;
+ j = ac >> 16;
+ k = ac & 0xffffu;
+ result = (e+g+i + (1<<3)) >> 4; /* 1<<3 is for rounding */
+ result += (f+h+k) << 12;
+ result += j << 28;
+ return (sign > 0) ? result : -result;
+}
diff --git a/Build/source/texk/dvipdfm-x/numbers.h b/Build/source/texk/dvipdfm-x/numbers.h
new file mode 100644
index 00000000000..fd4470279e1
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/numbers.h
@@ -0,0 +1,101 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _NUMBERS_H_
+#define _NUMBERS_H_
+
+#include <stdio.h>
+#include <math.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifndef PRId64
+# ifdef _WIN32
+# define PRId64 "I64d"
+# elif SIZEOF_LONG == 8
+# define PRId64 "ld"
+# else
+# define PRId64 "lld"
+# endif
+#endif
+
+/* When reading numbers from binary files 1, 2, or 3 bytes are
+ interpreted as either signed or unsigned.
+
+ Four bytes from DVI, PK, TFM, or VF files always yield a signed
+ 32-bit integer (int32_t), but some of them must not be negative.
+
+ Four byte numbers from JPEG2000, OpenType, or TrueType files are
+ mostly unsigned (uint32_t) and occasionally signed (int32_t).
+*/
+
+extern unsigned char get_unsigned_byte (FILE *);
+extern void skip_bytes (unsigned int, FILE *);
+extern signed char get_signed_byte (FILE *);
+extern unsigned short get_unsigned_pair (FILE *);
+extern unsigned short sget_unsigned_pair (unsigned char *);
+extern signed short get_signed_pair (FILE *);
+extern unsigned int get_unsigned_triple (FILE *);
+extern signed int get_signed_triple (FILE *);
+extern int32_t get_signed_quad (FILE *);
+extern uint32_t get_unsigned_quad (FILE *);
+extern int32_t get_unsigned_num (FILE *, unsigned char);
+extern uint32_t get_positive_quad (FILE *, const char *, const char *);
+
+typedef int32_t fixword;
+
+extern int32_t sqxfw (int32_t sq, fixword fw);
+
+#ifndef MAX
+# define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+#ifndef MIN
+# define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#define ISODD(n) (((n)/2)*2!=(n))
+#define ISEVEN(n) (((n)/2)*2==(n))
+
+#ifndef M_PI
+# define M_PI (4.0*atan(1.0))
+#endif
+
+#define ROUND(n,acc) (floor(((double)n)/(acc)+0.5)*(acc))
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+# define __C99__
+#endif
+
+#ifndef __C99__
+# ifndef round
+# define round(v) (floor((v) + 0.5))
+# endif
+# ifndef trunc
+# define trunc(v) ((v) > 0.0 ? floor((v)) : ceil((v)))
+# endif
+#endif
+#define round_at(v,acc) (round(((double)(v))/(acc))*(acc))
+
+#endif /* _NUMBERS_H_ */
diff --git a/Build/source/texk/dvipdfm-x/otl_opt.c b/Build/source/texk/dvipdfm-x/otl_opt.c
new file mode 100644
index 00000000000..b0e2796536e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/otl_opt.c
@@ -0,0 +1,340 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+#include "mfileio.h"
+
+#include "otl_opt.h"
+
+struct bt_node {
+ int flag;
+
+ struct bt_node *left;
+ struct bt_node *right;
+
+ char data[4];
+};
+
+#define FLAG_NOT (1 << 0)
+#define FLAG_AND (1 << 1)
+
+static int match_expr (struct bt_node *expr, const char *key);
+static int
+match_expr (struct bt_node *expr, const char *key)
+{
+ int retval = 1;
+ int i;
+
+ if (expr) {
+ if (!expr->left && !expr->right) {
+ for (i = 0; i < 4; i++) {
+ if (expr->data[i] != '?' &&
+ expr->data[i] != key[i]) {
+ retval = 0;
+ break;
+ }
+ }
+ } else {
+ if (expr->left) {
+ retval = match_expr(expr->left, key);
+ }
+ if (expr->right) {
+ if (retval && (expr->flag & FLAG_AND)) /* and */
+ retval &= match_expr(expr->right, key);
+ else if (!retval && !(expr->flag & FLAG_AND)) /* or */
+ retval = match_expr(expr->right, key);
+ }
+ }
+ if (expr->flag & FLAG_NOT) /* not */
+ retval = retval ? 0 : 1;
+
+ }
+
+ return retval;
+}
+
+static struct bt_node *
+bt_new_tree (void)
+{
+ struct bt_node *expr;
+
+ expr = NEW(1, struct bt_node);
+ expr->flag = 0;
+ expr->left = NULL;
+ expr->right = NULL;
+ memset(expr->data, 0, 4);
+
+ return expr;
+}
+
+static void bt_release_tree (struct bt_node *tree);
+
+static void
+bt_release_tree (struct bt_node *tree)
+{
+ if (tree) {
+ if (tree->left)
+ bt_release_tree(tree->left);
+ if (tree->right)
+ bt_release_tree(tree->right);
+ RELEASE(tree);
+ }
+}
+
+static struct bt_node *
+parse_expr (const char **pp, const char *endptr)
+{
+ struct bt_node *root, *curr;
+
+ if (*pp >= endptr)
+ return NULL;
+
+ root = curr = bt_new_tree();
+ while (*pp < endptr) {
+ switch (**pp) {
+ case '!':
+ if (curr->flag & 2)
+ curr->flag &= ~FLAG_NOT;
+ else
+ curr->flag |= FLAG_NOT;
+ (*pp)++;
+ break;
+ case '(':
+ (*pp)++;
+ if (*pp < endptr) {
+ struct bt_node *expr;
+
+ expr = parse_expr(pp, endptr);
+ if (!expr) {
+ WARN("Syntax error: %s\n", *pp);
+ return NULL;
+ }
+ if (**pp != ')') {
+ WARN("Syntax error: Unbalanced ()\n");
+ return NULL;
+ }
+ curr->left = expr->left;
+ curr->right = expr->right;
+ memcpy(curr->data, expr->data, 4);
+
+ RELEASE(expr);
+ } else {
+ WARN("Syntax error: Unbalanced ()\n");
+ bt_release_tree(root);
+ return NULL;
+ }
+ (*pp)++;
+ break;
+ case ')':
+ return root;
+ case '|': case '&':
+ if (*pp >= endptr) {
+ WARN("Syntax error: %s\n", *pp);
+ bt_release_tree(root);
+ return NULL;
+ } else {
+ struct bt_node *tmp;
+
+ tmp = bt_new_tree();
+ tmp->left = root;
+ tmp->right = curr = bt_new_tree();
+ if (**pp == '&')
+ tmp->flag = 1;
+ else
+ tmp->flag = 0;
+ root = tmp;
+ }
+ (*pp)++;
+ break;
+ case '*':
+ memset(curr->data, '?', 4);
+ (*pp)++;
+ break;
+ default:
+ if (*pp + 4 <= endptr) {
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (**pp == ' ' || **pp == '?' ||
+ isalpha((unsigned char)**pp) || isdigit((unsigned char)**pp))
+ curr->data[i] = **pp;
+ else if (**pp == '_')
+ curr->data[i] = ' ';
+ else {
+ WARN("Invalid char in tag: %c\n", **pp);
+ bt_release_tree(root);
+ return NULL;
+ }
+ (*pp)++;
+ }
+ } else {
+ WARN("Syntax error: %s\n", *pp);
+ bt_release_tree(root);
+ return NULL;
+ }
+ break;
+ }
+ }
+
+ return root;
+}
+
+
+struct otl_opt
+{
+ struct bt_node *rule;
+};
+
+otl_opt *
+otl_new_opt (void)
+{
+ struct otl_opt *opt;
+
+ opt = NEW(1, struct otl_opt);
+ opt->rule = NULL;
+
+ return (otl_opt *) opt;
+}
+
+
+void
+otl_release_opt (otl_opt *opt)
+{
+ if (opt->rule) {
+ bt_release_tree(opt->rule);
+ }
+ opt->rule = NULL;
+ RELEASE(opt);
+}
+
+#if 0
+struct lv_range
+{
+ int start, end;
+};
+
+struct uc_coverage
+{
+ int count;
+ struct lv_range *ranges;
+};
+
+static inline int
+range_cmp (const void *v1, const void *v2)
+{
+ struct lv_range *sv1, *sv2;
+
+ sv1 = (struct lv_range *) v1;
+ sv2 = (struct lv_range *) v2;
+
+ if (sv1->start < sv2->start)
+ return -1;
+ else
+ return 1;
+
+ return 0;
+}
+
+static inline int
+range_overlap (const void *v1, const void *v2)
+{
+ struct lv_range *sv1, *sv2;
+
+ sv1 = (struct lv_range *) v1;
+ sv2 = (struct lv_range *) v2;
+
+ /* Must be first sort in increasing start order */
+ if (sv1->end >= sv2->start)
+ return 0;
+ else if (sv1->end < sv2->start)
+ return -1;
+
+ return 1;
+}
+
+static void
+check_uc_coverage (struct uc_coverage *coverage)
+{
+ struct lv_range *r1, *r2;
+ int i;
+
+ for (i = 0; i < coverage->count; i++) {
+ r1 = &coverage->ranges[i];
+ r2 = bsearch(r1, coverage->ranges,
+ coverage->count, sizeof(struct lv_range),
+ range_overlap);
+ if (r2 && r1 != r2) {
+ WARN("Overlapping Unicode range found:");
+ WARN("[%x-%x], [%x-%x] ==> [%x-%x]",
+ r1->start, r1->end, r2->start, r2->end,
+ MIN(r1->start, r2->start), MAX(r1->end, r2->end));
+ r2->start = MIN(r1->start, r2->start);
+ r2->end = MAX(r1->end , r2->end );
+ if (i < coverage->count - 1) {
+ memmove(&coverage->ranges[i], &coverage->ranges[i+1],
+ (coverage->count - i - 1) * sizeof(struct lv_range));
+ coverage->count -= 1;
+ }
+ }
+ }
+ /* ... */
+ if (coverage->count == 0) {
+ RELEASE(coverage->ranges);
+ coverage->ranges = NULL;
+ }
+}
+#endif
+
+int
+otl_parse_optstring (otl_opt *opt, const char *optstr)
+{
+ const char *p, *endptr;
+
+ ASSERT(opt);
+
+ if (optstr) {
+ p = optstr;
+ endptr = p + strlen(optstr);
+ opt->rule = parse_expr(&p, endptr);
+ }
+
+ return 0;
+}
+
+int
+otl_match_optrule (otl_opt *opt, const char *tag)
+{
+ ASSERT(tag);
+
+ if (!opt || !opt->rule)
+ return 1;
+
+ return match_expr(opt->rule, tag);
+}
diff --git a/Build/source/texk/dvipdfm-x/otl_opt.h b/Build/source/texk/dvipdfm-x/otl_opt.h
new file mode 100644
index 00000000000..8db14af5e04
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/otl_opt.h
@@ -0,0 +1,35 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _OTL_OPT_H_
+#define _OTL_OPT_H_
+
+
+typedef struct otl_opt otl_opt;
+
+#define OTL_OPTSTR_SEP '+'
+
+extern otl_opt *otl_new_opt (void);
+extern void otl_release_opt (otl_opt *opt);
+
+extern int otl_parse_optstring (otl_opt *opt, const char *optstr);
+extern int otl_match_optrule (otl_opt *opt, const char *tag);
+
+#endif /* _OTL_OPT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfcolor.c b/Build/source/texk/dvipdfm-x/pdfcolor.c
new file mode 100644
index 00000000000..a0f49834bdf
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfcolor.c
@@ -0,0 +1,1560 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/* No page independence here...
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxconf.h"
+#include "dpxfile.h"
+
+#include "pdfdoc.h"
+#include "pdfdev.h"
+#include "pdfresource.h"
+
+#include "pdfcolor.h"
+
+int
+pdf_color_type (const pdf_color *color)
+{
+ ASSERT(color);
+
+ return color->type;
+}
+
+int
+pdf_color_rgbcolor (pdf_color *color, double r, double g, double b)
+{
+ ASSERT(color);
+
+ if (r < 0.0 || r > 1.0) {
+ WARN("Invalid color value specified: red=%g", r);
+ return -1;
+ }
+ if (g < 0.0 || g > 1.0) {
+ WARN("Invalid color value specified: green=%g", g);
+ return -1;
+ }
+ if (b < 0.0 || b > 1.0) {
+ WARN("Invalid color value specified: blue=%g", b);
+ return -1;
+ }
+ color->values[0] = r;
+ color->values[1] = g;
+ color->values[2] = b;
+
+ color->res_id = -1;
+ color->type = PDF_COLORSPACE_TYPE_RGB;
+ color->num_components = 3;
+
+ color->spot_color_name = NULL;
+
+ return 0;
+}
+
+int
+pdf_color_cmykcolor (pdf_color *color,
+ double c, double m, double y, double k)
+{
+ ASSERT(color);
+
+ if (c < 0.0 || c > 1.0) {
+ WARN("Invalid color value specified: cyan=%g", c);
+ return -1;
+ }
+ if (m < 0.0 || m > 1.0) {
+ WARN("Invalid color value specified: magenta=%g", m);
+ return -1;
+ }
+ if (y < 0.0 || y > 1.0) {
+ WARN("Invalid color value specified: yellow=%g", y);
+ return -1;
+ }
+ if (k < 0.0 || k > 1.0) {
+ WARN("Invalid color value specified: black=%g", k);
+ return -1;
+ }
+
+ color->values[0] = c;
+ color->values[1] = m;
+ color->values[2] = y;
+ color->values[3] = k;
+
+ color->res_id = -1;
+ color->type = PDF_COLORSPACE_TYPE_CMYK;
+ color->num_components = 4;
+
+ color->spot_color_name = NULL;
+
+ return 0;
+}
+
+int
+pdf_color_graycolor (pdf_color *color, double g)
+{
+ ASSERT(color);
+
+ if (g < 0.0 || g > 1.0) {
+ WARN("Invalid color value specified: gray=%g", g);
+ return -1;
+ }
+
+ color->values[0] = g;
+
+ color->res_id = -1;
+ color->type = PDF_COLORSPACE_TYPE_GRAY;
+ color->num_components = 1;
+
+ color->spot_color_name = NULL;
+
+ return 0;
+}
+
+int
+pdf_color_spotcolor (pdf_color *color, char* name, double c)
+{
+ ASSERT(color);
+
+ if (c < 0.0 || c > 1.0) {
+ WARN("Invalid color value specified: grade=%g", c);
+ return -1;
+ }
+
+ color->values[0] = c;
+ color->values[1] = 0.0; /* Dummy */
+
+ color->res_id = -1; /* ??? */
+ color->type = PDF_COLORSPACE_TYPE_SPOT;
+ color->num_components = 2;
+
+ color->spot_color_name = name;
+
+ return 0;
+}
+
+
+void
+pdf_color_copycolor (pdf_color *color1, const pdf_color *color2)
+{
+ ASSERT(color1 && color2);
+
+ memcpy(color1, color2, sizeof(pdf_color));
+}
+
+/* Brighten up a color. f == 0 means no change, f == 1 means white. */
+void
+pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f)
+{
+ ASSERT(dst && src);
+
+ if (src->type != PDF_COLORSPACE_TYPE_RGB &&
+ src->type != PDF_COLORSPACE_TYPE_CMYK &&
+ src->type != PDF_COLORSPACE_TYPE_GRAY) {
+ pdf_color_copycolor(dst, src);
+ return;
+ }
+
+ if (f == 1.0) {
+ pdf_color_white(dst);
+ } else {
+ double f0, f1;
+ int n;
+
+ pdf_color_copycolor(dst, src);
+ n = src->num_components;
+ f1 = n == 4 ? 0.0 : f; /* n == 4 is CMYK, others are RGB and Gray */
+ f0 = 1.0-f;
+
+ while (n--)
+ dst->values[n] = f0 * src->values[n] + f1;
+ }
+}
+
+/* TODO: remove "is_white"...
+ * pdfdoc.c only use this but not necessary if we have a flag have_bgcolor
+ * to indicate if bg color was set.
+ */
+int
+pdf_color_is_white (const pdf_color *color)
+{
+ int n;
+ double f;
+
+ ASSERT(color);
+
+ switch (color->type) {
+ case PDF_COLORSPACE_TYPE_GRAY:
+ case PDF_COLORSPACE_TYPE_RGB:
+ f = 1.0;
+ break;
+ case PDF_COLORSPACE_TYPE_CMYK:
+ f = 0.0;
+ break;
+ default:
+ return 0;
+ }
+
+ n = color->num_components;
+ while (n--)
+ if (color->values[n] != f)
+ return 0;
+
+ return 1;
+}
+
+/* TODO: make_resource_name() in pdfresource.c with configurable prefix. */
+int
+pdf_color_set_color (const pdf_color *color, char *buffer, size_t buffer_len, char mask)
+{
+ int len = 0;
+ int i;
+
+ {
+ size_t estimate = 0;
+ if (color->num_components > 0) {
+ estimate += 5 * (color->num_components + 1) + 4; /* Assuming color values [0, 1]... */
+ }
+ estimate += strlen(" /DeiceGray CS");
+ if (estimate + 1 > buffer_len) {
+ WARN("Not enough buffer space allocated for writing set_color op...");
+ return 0;
+ }
+ }
+
+ switch (pdf_color_type(color)) {
+ case PDF_COLORSPACE_TYPE_DEVICEGRAY:
+ {
+ len += sprintf(buffer+len, " /DeviceGray %c%c", 'C' | mask, 'S' | mask);
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c%c", 'S' | mask, 'C' | mask);
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_DEVICERGB:
+ {
+ len += sprintf(buffer+len, " /DeviceRGB %c%c", 'C' | mask, 'S' | mask);
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c%c", 'S' | mask, 'C' | mask);
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_DEVICECMYK:
+ {
+ len += sprintf(buffer+len, " /DeviceCMYK %c%c", 'C' | mask, 'S' | mask);
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c%c", 'S' | mask, 'C' | mask);
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_GRAY:
+ {
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c", 'G' | mask);
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_RGB:
+ {
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c%c", 'R' | mask, 'G' | mask);
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_CMYK:
+ {
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c", 'K' | mask);
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_SPOT:
+ {
+ len = sprintf(buffer+len,
+ " /%s %c%c %g %c%c",
+ color->spot_color_name,
+ 'C' | mask, 'S' | mask,
+ ROUND(color->values[0], 0.001),
+ 'S' | mask, 'C' | mask);
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_CALGRAY:
+ case PDF_COLORSPACE_TYPE_CALRGB:
+ case PDF_COLORSPACE_TYPE_LAB:
+ case PDF_COLORSPACE_TYPE_INDEXED:
+ {
+ char res_name[16];
+
+ snprintf(res_name, 16, "XC%d", color->res_id & 0xffff); /* TODO: Upper 16bits for category ID. See, pdfresource.c */
+ res_name[15] = 0;
+ len += sprintf(buffer+len, " /%s %c%c", res_name, 'C' | mask, 'S' | mask);
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c%c", 'S' | mask, 'C' | mask);
+ pdf_doc_add_page_resource("ColorSpace", res_name, pdf_get_resource_reference(color->res_id));
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_PATTERN:
+ {
+ char res_name[16];
+
+ if (color->res_id < 0) {
+ len += sprintf(buffer+len, " /Pattern %c%c", 'C' | mask, 'S' | mask);
+ /* no color value but just a name */
+ } else {
+ snprintf(res_name, 16, "XC%d", color->res_id & 0xffff); /* TODO: Upper 16bits for category ID. See, pdfresource.c */
+ res_name[15] = 0;
+ len += sprintf(buffer+len, " /%s %c%c", res_name, 'C' | mask, 'S' | mask);
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ pdf_doc_add_page_resource("ColorSpace", res_name, pdf_get_resource_reference(color->res_id));
+ }
+ snprintf(res_name, 16, "XP%d", color->pattern_id & 0xffff); /* TODO: see below */
+ res_name[15] = 0;
+ len += sprintf(buffer+len, " /%s %c%c%c", res_name, 'S' | mask, 'C' | mask, 'N' | mask);
+
+ pdf_doc_add_page_resource("Pattern", res_name, pdf_get_resource_reference(color->pattern_id));
+ }
+ break;
+ default:
+ {
+ char res_name[16];
+
+ snprintf(res_name, 8, "XC%d", color->res_id & 0xffff); /* TODO: Upper 16bits for category ID. See, pdfresource.c */
+ res_name[8] = 0;
+ len += sprintf(buffer+len, " /%s %c%c", res_name, 'C' | mask, 'S' | mask);
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ len += sprintf(buffer+len, " %c%c%c", 'S' | mask, 'C' | mask, 'N' | mask);
+ pdf_doc_add_page_resource("ColorSpace", res_name, pdf_get_resource_reference(color->res_id));
+ }
+ }
+
+ return len;
+}
+
+pdf_color current_fill = {
+ -1,
+ PDF_COLORSPACE_TYPE_GRAY,
+ 1,
+ NULL,
+ {0.0},
+ -1
+};
+
+pdf_color current_stroke = {
+ -1,
+ PDF_COLORSPACE_TYPE_GRAY,
+ 1,
+ NULL,
+ {0.0},
+ -1
+};
+
+/*
+ * This routine is not a real color matching.
+ * TODO: This can be removed too?
+ * Maybe we are currently always forcing installing color.
+ */
+int
+pdf_color_compare (const pdf_color *color1, const pdf_color *color2)
+{
+ int n;
+
+ if (color1->type != PDF_COLORSPACE_TYPE_GRAY ||
+ color1->type != PDF_COLORSPACE_TYPE_RGB ||
+ color1->type != PDF_COLORSPACE_TYPE_CMYK ||
+ color1->type != PDF_COLORSPACE_TYPE_SPOT ||
+ color2->type != PDF_COLORSPACE_TYPE_GRAY ||
+ color2->type != PDF_COLORSPACE_TYPE_RGB ||
+ color2->type != PDF_COLORSPACE_TYPE_CMYK ||
+ color2->type != PDF_COLORSPACE_TYPE_SPOT ||
+ color1->type != color2->type) {
+ return -1;
+ }
+
+ n = color1->num_components;
+ while (--n >= 0) {
+ if (color1->values[n] != color2->values[n])
+ return -1;
+ }
+ if (color1->spot_color_name && color2->spot_color_name)
+ return strcmp(color1->spot_color_name, color2->spot_color_name);
+
+ return 0;
+}
+
+/* Dvipdfm special */
+pdf_color default_color = {
+ -1,
+ PDF_COLORSPACE_TYPE_GRAY,
+ 1,
+ NULL,
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ -1
+};
+
+#define DEV_COLOR_STACK_MAX 128
+
+static struct {
+ int current;
+ pdf_color stroke[DEV_COLOR_STACK_MAX];
+ pdf_color fill[DEV_COLOR_STACK_MAX];
+} color_stack = {
+ 0,
+};
+
+void
+pdf_color_clear_stack (void)
+{
+ if (color_stack.current > 0) {
+ WARN("You've mistakenly made a global color change within nested colors.");
+ }
+ while (color_stack.current--) {
+ if (color_stack.stroke[color_stack.current].spot_color_name)
+ RELEASE(color_stack.stroke[color_stack.current].spot_color_name);
+ if (color_stack.fill[color_stack.current].spot_color_name)
+ RELEASE(color_stack.fill[color_stack.current].spot_color_name);
+ }
+ color_stack.current = 0;
+ pdf_color_black(color_stack.stroke);
+ pdf_color_black(color_stack.fill);
+ return;
+}
+
+void
+pdf_color_set (pdf_color *sc, pdf_color *fc)
+{
+ pdf_color_copycolor(&color_stack.stroke[color_stack.current], sc);
+ pdf_color_copycolor(&color_stack.fill[color_stack.current], fc);
+ pdf_dev_reset_color(1);
+}
+
+void
+pdf_color_push (pdf_color *sc, pdf_color *fc)
+{
+ if (color_stack.current >= DEV_COLOR_STACK_MAX-1) {
+ WARN("Color stack overflow. Just ignore.");
+ } else {
+ color_stack.current++;
+ pdf_color_set(sc, fc);
+ }
+ return;
+}
+
+void
+pdf_color_pop (void)
+{
+ if (color_stack.current <= 0) {
+ WARN("Color stack underflow. Just ignore.");
+ } else {
+ color_stack.current--;
+ pdf_dev_reset_color(1);
+ }
+ return;
+}
+
+void
+pdf_color_get_current (pdf_color **sc, pdf_color **fc)
+{
+ *sc = &color_stack.stroke[color_stack.current];
+ *fc = &color_stack.fill[color_stack.current];
+ return;
+}
+
+#if 0
+/* BUG (20060330): color change does not effect on the next page.
+ * The problem is due to the part of grestore because it restores
+ * the color values in the state of gsave which are not correct
+ * if the color values are changed inside of a page.
+ */
+void
+pdf_dev_preserve_color (void)
+{
+ if (color_stack.current > 0) {
+ current_stroke = color_stack.stroke[color_stack.current];
+ current_fill = color_stack.fill[color_stack.current];
+ }
+}
+#endif
+
+/***************************** COLOR SPACE *****************************/
+/* Currently only for ICCBased color loaded while reading images */
+static int pdf_colorspace_defineresource (const char *ident, int subtype, void *cdata, pdf_obj *resource);
+static int pdf_colorspace_findresource (const char *ident, int subtype, const void *cdata);
+
+static unsigned char nullbytes16[16] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static struct
+{
+ int major;
+ int minor;
+} icc_versions[] = {
+ {0, 0}, /* PDF-1.0, we don't support them */
+ {0, 0}, /* PDF-1.1, we don't support them */
+ {0, 0}, /* PDF-1.2, we don't support them */
+ {0x02, 0x10}, /* PDF-1.3 */
+ {0x02, 0x20}, /* PDF-1.4 */
+ {0x04, 0x00}, /* PDF-1.5 */
+ {0x04, 0x00}, /* PDF-1.6 */
+ {0x04, 0x20}, /* PDF-1.7 */
+ {0x04, 0x20}, /* Dummy(1.8)*/
+ {0x04, 0x20}, /* Dummy(1.9) */
+ {0x04, 0x20} /* PDF-2.0 */
+};
+
+static int
+iccp_version_supported (int major, int minor)
+{
+ int idx;
+
+ idx = pdf_get_version() - 10;
+ if (idx < 11) {
+ if (icc_versions[idx].major < major)
+ return 0;
+ else if (icc_versions[idx].major == major &&
+ icc_versions[idx].minor < minor)
+ return 0;
+ else {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+typedef uint32_t iccSig;
+static iccSig
+str2iccSig (const void *s)
+{
+ const char *p;
+
+ p = (const char *) s;
+
+ return (iccSig) ((p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]);
+}
+
+typedef struct
+{
+ int32_t X, Y, Z; /* s15Fixed16Number */
+} iccXYZNumber;
+
+typedef struct
+{
+ int size;
+ iccSig CMMType;
+ int32_t version;
+ iccSig devClass;
+ iccSig colorSpace;
+ iccSig PCS; /* Profile Connection Space */
+ char creationDate[12];
+ iccSig acsp;
+ iccSig platform;
+ char flags[4];
+ iccSig devMnfct;
+ iccSig devModel;
+ char devAttr[8];
+ int32_t intent;
+ iccXYZNumber illuminant;
+ iccSig creator;
+ unsigned char ID[16]; /* MD5 checksum with Rendering intent,
+ * Header attrs, Profile ID fields are
+ * set to zeros.
+ */
+ /* 28 bytes reserved - must be set to zeros */
+} iccHeader;
+
+#define iccNullSig 0
+static void
+iccp_init_iccHeader (iccHeader *icch)
+{
+ ASSERT(icch);
+
+ icch->size = 0;
+ icch->CMMType = iccNullSig;
+ icch->version = 0xFFFFFF;
+ icch->devClass = iccNullSig;
+ icch->colorSpace = iccNullSig;
+ icch->PCS = iccNullSig;
+ memset(icch->creationDate, 0, 12);
+ icch->acsp = str2iccSig("ascp");
+ icch->platform = iccNullSig;
+ memset(icch->flags, 0, 4);
+ icch->devMnfct = iccNullSig;
+ icch->devModel = iccNullSig;
+ memset(icch->devAttr, 0, 8);
+ icch->intent = 0;
+ icch->illuminant.X = 0;
+ icch->illuminant.Y = 0;
+ icch->illuminant.Z = 0;
+ icch->creator = iccNullSig;
+ memset(icch->ID, 0, 16);
+}
+
+#define ICC_INTENT_TYPE(n) ((int) (((n) >> 16) & 0xff))
+#define ICC_INTENT_PERCEPTUAL 0
+#define ICC_INTENT_RELATIVE 1
+#define ICC_INTENT_SATURATION 2
+#define ICC_INTENT_ABSOLUTE 3
+
+/*
+ * In ICC profile stream dicrionary, there is /Range whose values must
+ * "match the information in the profile". But where is those values in?
+ *
+ * How should I treat rendering intent?
+ */
+struct iccbased_cdata
+{
+ int32_t sig; /* 'i' 'c' 'c' 'b' */
+
+ unsigned char checksum[16]; /* 16 bytes MD5 Checksum */
+ int colorspace; /* input colorspace:
+ * RGB, Gray, CMYK, (Lab?)
+ */
+ int alternate; /* alternate colorspace (id), unused */
+};
+
+#define check_sig(d,p,q,r,s) ((d) && (d)->sig == ((p)<<24|(q)<<16|(r)<<8|(s)))
+
+static void
+init_iccbased_cdata (struct iccbased_cdata *cdata)
+{
+ ASSERT(cdata);
+
+ cdata->sig = ('i' << 24|'c' << 16|'c' << 8|'b');
+ memset(cdata->checksum, 0, 16);
+ cdata->colorspace = PDF_COLORSPACE_TYPE_INVALID;
+ cdata->alternate = -1;
+
+ return;
+}
+
+static void
+release_iccbased_cdata (struct iccbased_cdata *cdata)
+{
+ ASSERT(check_sig(cdata, 'i', 'c', 'c', 'b'));
+
+ RELEASE(cdata);
+}
+
+static int
+get_num_components_iccbased (const struct iccbased_cdata *cdata)
+{
+ int num_components = 0;
+
+ ASSERT(check_sig(cdata, 'i', 'c', 'c', 'b'));
+
+ switch (cdata->colorspace) {
+ case PDF_COLORSPACE_TYPE_RGB:
+ num_components = 3;
+ break;
+ case PDF_COLORSPACE_TYPE_CMYK:
+ num_components = 4;
+ break;
+ case PDF_COLORSPACE_TYPE_GRAY:
+ num_components = 1;
+ break;
+ case PDF_COLORSPACE_TYPE_LAB:
+ num_components = 3;
+ break;
+ }
+
+ return num_components;
+}
+
+static int
+compare_iccbased (const char *ident1, const struct iccbased_cdata *cdata1,
+ const char *ident2, const struct iccbased_cdata *cdata2)
+{
+ if (cdata1 && cdata2) {
+
+ ASSERT(check_sig(cdata1, 'i', 'c', 'c', 'b'));
+ ASSERT(check_sig(cdata2, 'i', 'c', 'c', 'b'));
+
+ if (memcmp(cdata1->checksum, nullbytes16, 16) &&
+ memcmp(cdata2->checksum, nullbytes16, 16)) {
+ return memcmp(cdata1->checksum, cdata2->checksum, 16);
+ }
+ if (cdata1->colorspace != cdata2->colorspace) {
+ return (cdata1->colorspace - cdata2->colorspace);
+ }
+
+ /* Continue if checksum unknown and colorspace is same. */
+ }
+
+ if (ident1 && ident2)
+ return strcmp(ident1, ident2);
+
+ /* No way to compare */
+ return -1;
+}
+
+int
+iccp_check_colorspace (int colortype, const void *profile, int proflen)
+{
+ iccSig colorspace;
+ const unsigned char *p;
+
+ if (!profile || proflen < 128)
+ return -1;
+
+ p = (const unsigned char *) profile;
+
+ colorspace = str2iccSig(p + 16);
+
+ switch (colortype) {
+ case PDF_COLORSPACE_TYPE_CALRGB:
+ case PDF_COLORSPACE_TYPE_RGB:
+ if (colorspace != str2iccSig("RGB ")) {
+ return -1;
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_CALGRAY:
+ case PDF_COLORSPACE_TYPE_GRAY:
+ if (colorspace != str2iccSig("GRAY")) {
+ return -1;
+ }
+ break;
+ case PDF_COLORSPACE_TYPE_CMYK:
+ if (colorspace != str2iccSig("CMYK")) {
+ return -1;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+pdf_obj *
+iccp_get_rendering_intent (const void *profile, int proflen)
+{
+ pdf_obj *ri = NULL;
+ const unsigned char *p;
+ int32_t intent;
+
+ if (!profile || proflen < 128)
+ return NULL;
+
+ p = (const unsigned char *) profile;
+
+ intent = (p[64] << 24)|(p[65] << 16)|(p[66] << 8)|p[67];
+ switch (ICC_INTENT_TYPE(intent)) {
+ case ICC_INTENT_SATURATION:
+ ri = pdf_new_name("Saturation");
+ break;
+ case ICC_INTENT_PERCEPTUAL:
+ ri = pdf_new_name("Perceptual");
+ break;
+ case ICC_INTENT_ABSOLUTE:
+ ri = pdf_new_name("AbsoluteColorimetric");
+ break;
+ case ICC_INTENT_RELATIVE:
+ ri = pdf_new_name("RelativeColorimetric");
+ break;
+ default:
+ WARN("Invalid rendering intent type: %d", ICC_INTENT_TYPE(intent));
+ ri = NULL;
+ }
+
+ return ri;
+}
+
+#define sget_signed_long(p) ((int32_t) ((p)[0] << 24|(p)[1] << 16|(p)[2] << 8|(p)[3]))
+#define sget_signed_short(p) ((short) ((p)[0] << 8|(p)[1]))
+#define get_iccSig(p) ((iccSig) ((p)[0] << 24|(p)[1] << 16|(p)[2] << 8|(p)[3]))
+
+static int
+iccp_unpack_header (iccHeader *icch,
+ const void *profile, int proflen, int check_size)
+{
+ const unsigned char *p, *endptr;
+
+ if (check_size) {
+ if (!profile || proflen < 128 ||
+ proflen % 4 != 0) {
+ WARN("Profile size: %ld", proflen);
+ return -1;
+ }
+ }
+
+ p = (const unsigned char *) profile;
+ endptr = p + 128;
+
+ icch->size = sget_signed_long(p);
+ if (check_size) {
+ if (icch->size != proflen) {
+ WARN("ICC Profile size: %ld(header) != %ld", icch->size, proflen);
+ return -1;
+ }
+ }
+ p += 4;
+
+ icch->CMMType = str2iccSig(p);
+ p += 4;
+ icch->version = sget_signed_long(p);
+ p += 4;
+ icch->devClass = str2iccSig(p);
+ p += 4;
+ icch->colorSpace = str2iccSig(p);
+ p += 4;
+ icch->PCS = str2iccSig(p);
+ p += 4;
+ memcpy(icch->creationDate, p, 12);
+ p += 12;
+ icch->acsp = str2iccSig(p); /* acsp */
+ if (icch->acsp != str2iccSig("acsp")) {
+ WARN("Invalid ICC profile: not \"acsp\" - %c%c%c%c ",
+ p[0], p[1], p[2], p[3]);
+ return -1;
+ }
+ p += 4;
+ icch->platform = str2iccSig(p);
+ p += 4;
+ memcpy(icch->flags, p, 4);
+ p += 4;
+ icch->devMnfct = str2iccSig(p);
+ p += 4;
+ icch->devModel = str2iccSig(p);
+ p += 4;
+ memcpy(icch->devAttr, p, 8);
+ p += 8;
+ icch->intent = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
+ p += 4;
+ icch->illuminant.X = sget_signed_long(p);
+ p += 4;
+ icch->illuminant.Y = sget_signed_long(p);
+ p += 4;
+ icch->illuminant.Z = sget_signed_long(p);
+ p += 4;
+ icch->creator = str2iccSig(p);
+ p += 4;
+ memcpy(icch->ID, p, 16);
+ p += 16;
+
+ /* 28 bytes reserved - must be set to zeros */
+ for (; p < endptr; p++) {
+ if (*p != '\0') {
+ WARN("Reserved pad not zero: %02x (at offset %d in ICC profile header.)",
+ *p, 128 - ((int) (endptr - p)));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* MD5 checksum with Rendering intent,
+ * Header attrs, Profile ID fields are
+ * set to zeros.
+ */
+#define ICC_HEAD_SECT1_START 0
+#define ICC_HEAD_SECT1_LENGTH 56
+/* 8 bytes devAttr, 4 bytes intent */
+#define ICC_HEAD_SECT2_START 68
+#define ICC_HEAD_SECT2_LENGTH 16
+/* 16 bytes ID (checksum) */
+#define ICC_HEAD_SECT3_START 100
+#define ICC_HEAD_SECT3_LENGTH 28
+
+#include "dpxcrypt.h"
+static void
+iccp_get_checksum (unsigned char *checksum, const void *profile, int proflen)
+{
+ const unsigned char *p;
+ MD5_CONTEXT md5;
+
+ p = (const unsigned char *) profile;
+
+ MD5_init (&md5);
+ MD5_write(&md5, p + ICC_HEAD_SECT1_START, ICC_HEAD_SECT1_LENGTH);
+ MD5_write(&md5, nullbytes16, 12);
+ MD5_write(&md5, p + ICC_HEAD_SECT2_START, ICC_HEAD_SECT2_LENGTH);
+ MD5_write(&md5, nullbytes16, 16);
+ MD5_write(&md5, p + ICC_HEAD_SECT3_START, ICC_HEAD_SECT3_LENGTH);
+
+ /* body */
+ MD5_write(&md5, p + 128, proflen - 128);
+
+ MD5_final(checksum, &md5);
+}
+
+static void
+print_iccp_header (iccHeader *icch, unsigned char *checksum)
+{
+ int i;
+
+ ASSERT(icch);
+
+#define print_iccSig(s,t) if ((s) == 0) {\
+ MESG("pdf_color>> %s:\t(null)\n", (t)); \
+ } else if (!isprint(((s) >> 24) & 0xff) || \
+ !isprint(((s) >> 16) & 0xff) || \
+ !isprint(((s) >> 8) & 0xff) || \
+ !isprint((s) & 0xff)) { \
+ MESG("pdf_color>> %s:\t(invalid)\n", (t)); \
+ } else { \
+ MESG("pdf_color>> %s:\t%c%c%c%c\n", (t), \
+ ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, \
+ ((s) >> 8) & 0xff, (s) & 0xff); \
+}
+
+ MESG("\n");
+ MESG("pdf_color>> ICC Profile Info\n");
+ MESG("pdf_color>> Profile Size:\t%ld bytes\n", icch->size);
+ print_iccSig(icch->CMMType, "CMM Type");
+ MESG("pdf_color>> Profile Version:\t%d.%01d.%01d\n",
+ (icch->version >> 24) & 0xff,
+ (icch->version >> 20) & 0x0f,
+ (icch->version >> 16) & 0x0f);
+ print_iccSig(icch->devClass, "Device Class");
+ print_iccSig(icch->colorSpace, "Color Space");
+ print_iccSig(icch->PCS, "Connection Space");
+ MESG("pdf_color>> Creation Date:\t");
+ for (i = 0; i < 12; i += 2) {
+ if (i == 0)
+ MESG("%04u",
+ sget_unsigned_pair((unsigned char *) icch->creationDate));
+ else {
+ MESG(":%02u",
+ sget_unsigned_pair((unsigned char *) (&icch->creationDate[i])));
+ }
+ }
+ MESG("\n");
+ print_iccSig(icch->platform, "Primary Platform");
+ MESG("pdf_color>> Profile Flags:\t%02x:%02x:%02x:%02x\n",
+ icch->flags[0], icch->flags[1], icch->flags[2], icch->flags[3]);
+ print_iccSig(icch->devMnfct, "Device Mnfct");
+ print_iccSig(icch->devModel, "Device Model");
+ MESG("pdf_color>> Device Attr:\t");
+ for (i = 0; i < 8; i++) {
+ if (i == 0)
+ MESG("%02x", icch->devAttr[i]);
+ else
+ MESG(":%02x", icch->devAttr[i]);
+ }
+ MESG("\n");
+ MESG("pdf_color>> Rendering Intent:\t");
+ switch (ICC_INTENT_TYPE(icch->intent)) {
+ case ICC_INTENT_SATURATION:
+ MESG("Saturation");
+ break;
+ case ICC_INTENT_PERCEPTUAL:
+ MESG("Perceptual");
+ break;
+ case ICC_INTENT_ABSOLUTE:
+ MESG("Absolute Colorimetric");
+ break;
+ case ICC_INTENT_RELATIVE:
+ MESG("Relative Colorimetric");
+ break;
+ default:
+ MESG("(invalid)");
+ break;
+ }
+ MESG("\n");
+ print_iccSig(icch->creator, "Creator");
+ MESG("pdf_color>> Illuminant (XYZ):\t");
+ MESG("%.3f %.3f %.3f\n",
+ (double) icch->illuminant.X / 0x10000,
+ (double) icch->illuminant.Y / 0x10000,
+ (double) icch->illuminant.Z / 0x10000);
+ MESG("pdf_color>> Checksum:\t");
+ if (!memcmp(icch->ID, nullbytes16, 16)) {
+ MESG("(null)");
+ } else {
+ for (i = 0; i < 16; i++) {
+ if (i == 0)
+ MESG("%02x", icch->ID[i]);
+ else
+ MESG(":%02x", icch->ID[i]);
+ }
+ }
+ MESG("\n");
+ if (checksum) {
+ MESG("pdf_color>> Calculated:\t");
+ for (i = 0; i < 16; i++) {
+ if (i == 0)
+ MESG("%02x", checksum[i]);
+ else
+ MESG(":%02x", checksum[i]);
+ }
+ MESG("\n");
+ }
+
+ return;
+}
+
+
+static int
+iccp_devClass_allowed (int dev_class)
+{
+ int colormode;
+
+ colormode = pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE);
+
+ switch (colormode) {
+#if 0
+ case PDF_DEV_COLORMODE_PDFX1:
+ break;
+ case PDF_DEV_COLORMODE_PDFX3:
+ if (dev_class != str2iccSig("prtr")) {
+ return 0;
+ }
+ break;
+#endif
+ default:
+ if (dev_class != str2iccSig("scnr") &&
+ dev_class != str2iccSig("mntr") &&
+ dev_class != str2iccSig("prtr") &&
+ dev_class != str2iccSig("spac")) {
+ return 0;
+ }
+ break;
+ }
+
+
+ return 1;
+}
+
+int
+iccp_load_profile (const char *ident,
+ const void *profile, int proflen)
+{
+ int cspc_id;
+ pdf_obj *resource;
+ pdf_obj *stream;
+ pdf_obj *stream_dict;
+ iccHeader icch;
+ int colorspace;
+ unsigned char checksum[16];
+ struct iccbased_cdata *cdata;
+
+ iccp_init_iccHeader(&icch);
+ if (iccp_unpack_header(&icch, profile, proflen, 1) < 0) { /* check size */
+ WARN("Invalid ICC profile header in \"%s\"", ident);
+ print_iccp_header(&icch, NULL);
+ return -1;
+ }
+
+ if (!iccp_version_supported((icch.version >> 24) & 0xff,
+ (icch.version >> 16) & 0xff)) {
+ WARN("ICC profile format spec. version %d.%01d.%01d"
+ " not supported in current PDF version setting.",
+ (icch.version >> 24) & 0xff,
+ (icch.version >> 20) & 0x0f,
+ (icch.version >> 16) & 0x0f);
+ WARN("ICC profile not embedded.");
+ print_iccp_header(&icch, NULL);
+ return -1;
+ }
+
+ if (!iccp_devClass_allowed(icch.devClass)) {
+ WARN("Unsupported ICC Profile Device Class:");
+ print_iccp_header(&icch, NULL);
+ return -1;
+ }
+
+ if (icch.colorSpace == str2iccSig("RGB ")) {
+ colorspace = PDF_COLORSPACE_TYPE_RGB;
+ } else if (icch.colorSpace == str2iccSig("GRAY")) {
+ colorspace = PDF_COLORSPACE_TYPE_GRAY;
+ } else if (icch.colorSpace == str2iccSig("CMYK")) {
+ colorspace = PDF_COLORSPACE_TYPE_CMYK;
+ } else {
+ WARN("Unsupported input color space.");
+ print_iccp_header(&icch, NULL);
+ return -1;
+ }
+
+ iccp_get_checksum(checksum, profile, proflen);
+ if (memcmp(icch.ID, nullbytes16, 16) &&
+ memcmp(icch.ID, checksum, 16)) {
+ WARN("Invalid ICC profile: Inconsistent checksum.");
+ print_iccp_header(&icch, checksum);
+ return -1;
+ }
+
+ cdata = NEW(1, struct iccbased_cdata);
+ init_iccbased_cdata(cdata);
+ cdata->colorspace = colorspace;
+ memcpy(cdata->checksum, checksum, 16);
+
+ cspc_id = pdf_colorspace_findresource(ident,
+ PDF_COLORSPACE_TYPE_ICCBASED, cdata);
+ if (cspc_id >= 0) {
+ if (dpx_conf.verbose_level > 0)
+ MESG("(ICCP:[id=%d])", cspc_id);
+ release_iccbased_cdata(cdata);
+ return cspc_id;
+ }
+ if (dpx_conf.verbose_level > 1) {
+ print_iccp_header(&icch, checksum);
+ }
+
+ resource = pdf_new_array();
+
+ stream = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_array(resource, pdf_new_name("ICCBased"));
+ pdf_add_array(resource, pdf_ref_obj (stream));
+
+ stream_dict = pdf_stream_dict(stream);
+ pdf_add_dict(stream_dict, pdf_new_name("N"),
+ pdf_new_number(get_num_components_iccbased(cdata)));
+
+ pdf_add_stream (stream, profile, proflen);
+ pdf_release_obj(stream);
+
+ cspc_id = pdf_colorspace_defineresource(ident,
+ PDF_COLORSPACE_TYPE_ICCBASED,
+ cdata, resource);
+
+ return cspc_id;
+}
+
+#if 0
+#define WBUF_SIZE 4096
+static unsigned char wbuf[WBUF_SIZE];
+
+static pdf_obj *
+iccp_load_file_stream (unsigned char *checksum, int length, FILE *fp)
+{
+ pdf_obj *stream;
+ MD5_CONTEXT md5;
+ int nb_read;
+
+ rewind(fp);
+
+ if (fread(wbuf, 1, 128, fp) != 128) {
+ return NULL;
+ }
+ length -= 128;
+
+ stream = pdf_new_stream(STREAM_COMPRESS);
+
+ MD5_init (&md5);
+ MD5_write(&md5, wbuf + ICC_HEAD_SECT1_START, ICC_HEAD_SECT1_LENGTH);
+ MD5_write(&md5, nullbytes16, 12);
+ MD5_write(&md5, wbuf + ICC_HEAD_SECT2_START, ICC_HEAD_SECT2_LENGTH);
+ MD5_write(&md5, nullbytes16, 16);
+ MD5_write(&md5, wbuf + ICC_HEAD_SECT3_START, ICC_HEAD_SECT3_LENGTH);
+
+ pdf_add_stream(stream, wbuf, 128);
+
+ /* body */
+ while (length > 0) {
+ nb_read = fread(wbuf, 1, MIN(length, WBUF_SIZE), fp);
+ MD5_write(&md5, wbuf, nb_read);
+ pdf_add_stream(stream, wbuf, nb_read);
+ length -= nb_read;
+ }
+
+ MD5_final(checksum, &md5);
+
+
+ return stream;
+}
+
+int
+pdf_colorspace_load_ICCBased (const char *ident, const char *filename)
+{
+ int cspc_id;
+ FILE *fp;
+ pdf_obj *resource;
+ pdf_obj *stream;
+ pdf_obj *stream_dict;
+ iccHeader icch;
+ int colorspace;
+ int size;
+ unsigned char checksum[16];
+ struct iccbased_cdata *cdata;
+
+
+ fp = DPXFOPEN(filename, DPX_RES_TYPE_ICCPROFILE);
+ if (!fp)
+ return -1;
+
+ size = file_size(fp);
+ if (size < 128) {
+ MFCLOSE(fp);
+ return -1;
+ }
+ if (fread(wbuf, 1, 128, fp) != 128) {
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ iccp_init_iccHeader(&icch);
+ if (iccp_unpack_header(&icch, wbuf, 128, 0) < 0) {
+ WARN("Invalid ICC profile header in \"%s\"", ident);
+ print_iccp_header(&icch, NULL);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ if (icch.size > size) {
+ WARN("File size smaller than recorded in header: %ld %ld",
+ icch.size, size);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (!iccp_version_supported((icch.version >> 24) & 0xff,
+ (icch.version >> 16) & 0xff)) {
+ WARN("ICC profile format spec. version %d.%01d.%01d"
+ " not supported in current PDF version setting.",
+ (icch.version >> 24) & 0xff,
+ (icch.version >> 20) & 0x0f,
+ (icch.version >> 16) & 0x0f);
+ WARN("ICC profile not embedded.");
+ print_iccp_header(&icch, NULL);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (!iccp_devClass_allowed(icch.devClass)) {
+ WARN("Unsupported ICC Profile Device Class:");
+ print_iccp_header(&icch, NULL);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (icch.colorSpace == str2iccSig("RGB ")) {
+ colorspace = PDF_COLORSPACE_TYPE_RGB;
+ } else if (icch.colorSpace == str2iccSig("GRAY")) {
+ colorspace = PDF_COLORSPACE_TYPE_GRAY;
+ } else if (icch.colorSpace == str2iccSig("CMYK")) {
+ colorspace = PDF_COLORSPACE_TYPE_CMYK;
+ } else {
+ WARN("Unsupported input color space.");
+ print_iccp_header(&icch, NULL);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ stream = iccp_load_file_stream(checksum, icch.size, fp);
+ DPXFCLOSE(fp);
+
+ if (!stream) {
+ WARN("Loading ICC Profile failed...: %s", filename);
+ return -1;
+ }
+
+ if (memcmp(icch.ID, nullbytes16, 16) &&
+ memcmp(icch.ID, checksum, 16)) {
+ WARN("Invalid ICC profile: Inconsistent checksum.");
+ print_iccp_header(&icch, NULL);
+ pdf_release_obj(stream);
+ return -1;
+ }
+
+ cdata = NEW(1, struct iccbased_cdata);
+ init_iccbased_cdata(cdata);
+ cdata->colorspace = colorspace;
+ memcpy(cdata->checksum, checksum, 16);
+
+ cspc_id = pdf_colorspace_findresource(ident,
+ PDF_COLORSPACE_TYPE_ICCBASED, cdata);
+ if (cspc_id >= 0) {
+ if (dpx_conf.verbose_level > 0)
+ MESG("(ICCP:[id=%d])", cspc_id);
+ release_iccbased_cdata(cdata);
+ pdf_release_obj(stream);
+ return cspc_id;
+ }
+ if (dpx_conf.verbose_level > 1) {
+ print_iccp_header(&icch, checksum);
+ }
+
+ resource = pdf_new_array();
+
+ pdf_add_array(resource, pdf_new_name("ICCBased"));
+ pdf_add_array(resource, pdf_ref_obj (stream));
+
+ stream_dict = pdf_stream_dict(stream);
+ pdf_add_dict(stream_dict, pdf_new_name("N"),
+ pdf_new_number(get_num_components_iccbased(cdata)));
+ pdf_release_obj(stream);
+
+ cspc_id = pdf_colorspace_defineresource(ident,
+ PDF_COLORSPACE_TYPE_ICCBASED,
+ cdata, resource);
+
+ return cspc_id;
+}
+#endif
+
+typedef struct {
+ char *ident;
+ int subtype;
+
+ pdf_obj *resource;
+ pdf_obj *reference;
+
+ void *cdata;
+} pdf_colorspace;
+
+static struct {
+ int count;
+ int capacity;
+ pdf_colorspace *colorspaces;
+} cspc_cache = {
+ 0, 0, NULL
+};
+
+int
+pdf_colorspace_findresource (const char *ident,
+ int type, const void *cdata)
+{
+ pdf_colorspace *colorspace;
+ int cspc_id, cmp = -1;
+
+ for (cspc_id = 0;
+ cmp && cspc_id < cspc_cache.count; cspc_id++) {
+ colorspace = &cspc_cache.colorspaces[cspc_id];
+ if (colorspace->subtype != type)
+ continue;
+
+ switch (colorspace->subtype) {
+ case PDF_COLORSPACE_TYPE_ICCBASED:
+ cmp = compare_iccbased(ident, cdata,
+ colorspace->ident, colorspace->cdata);
+ break;
+ }
+ if (!cmp)
+ return cspc_id;
+ }
+
+ return -1; /* not found */
+}
+
+static void
+pdf_init_colorspace_struct (pdf_colorspace *colorspace)
+{
+ ASSERT(colorspace);
+
+ colorspace->ident = NULL;
+ colorspace->subtype = PDF_COLORSPACE_TYPE_INVALID;
+
+ colorspace->resource = NULL;
+ colorspace->reference = NULL;
+ colorspace->cdata = NULL;
+
+ return;
+}
+
+static void
+pdf_clean_colorspace_struct (pdf_colorspace *colorspace)
+{
+ ASSERT(colorspace);
+
+ if (colorspace->ident)
+ RELEASE(colorspace->ident);
+ if (colorspace->resource)
+ pdf_release_obj(colorspace->resource);
+ if (colorspace->reference)
+ pdf_release_obj(colorspace->reference);
+ colorspace->resource = NULL;
+ colorspace->reference = NULL;
+
+ if (colorspace->cdata) {
+ switch (colorspace->subtype) {
+ case PDF_COLORSPACE_TYPE_ICCBASED:
+ release_iccbased_cdata(colorspace->cdata);
+ break;
+ }
+ }
+ colorspace->cdata = NULL;
+ colorspace->subtype = PDF_COLORSPACE_TYPE_INVALID;
+
+ return;
+}
+
+static void
+pdf_flush_colorspace (pdf_colorspace *colorspace)
+{
+ ASSERT(colorspace);
+
+ if (colorspace->resource)
+ pdf_release_obj(colorspace->resource);
+ if (colorspace->reference)
+ pdf_release_obj(colorspace->reference);
+
+ colorspace->resource = NULL;
+ colorspace->reference = NULL;
+}
+
+int
+pdf_colorspace_defineresource (const char *ident,
+ int subtype, void *cdata, pdf_obj *resource)
+{
+ int cspc_id;
+ pdf_colorspace *colorspace;
+
+ if (cspc_cache.count >= cspc_cache.capacity) {
+ cspc_cache.capacity += 16;
+ cspc_cache.colorspaces = RENEW(cspc_cache.colorspaces,
+ cspc_cache.capacity, pdf_colorspace);
+ }
+ cspc_id = cspc_cache.count;
+ colorspace = &cspc_cache.colorspaces[cspc_id];
+
+ pdf_init_colorspace_struct(colorspace);
+ if (ident) {
+ colorspace->ident = NEW(strlen(ident) + 1, char);
+ strcpy(colorspace->ident, ident);
+ }
+ colorspace->subtype = subtype;
+ colorspace->cdata = cdata;
+ colorspace->resource = resource;
+
+ if (dpx_conf.verbose_level > 0) {
+ MESG("(ColorSpace:%s", ident);
+ if (dpx_conf.verbose_level > 1) {
+ switch (subtype) {
+ case PDF_COLORSPACE_TYPE_ICCBASED:
+ MESG("[ICCBased]");
+ break;
+ case PDF_COLORSPACE_TYPE_CALRGB:
+ MESG("[CalRGB]");
+ break;
+ case PDF_COLORSPACE_TYPE_CALGRAY:
+ MESG("[CalGray]");
+ break;
+ }
+ }
+ MESG(")");
+ }
+
+ cspc_cache.count++;
+
+ return cspc_id;
+}
+
+pdf_obj *
+pdf_get_colorspace_reference (int cspc_id)
+{
+ pdf_colorspace *colorspace;
+
+ colorspace = &cspc_cache.colorspaces[cspc_id];
+ if (!colorspace->reference) {
+ colorspace->reference = pdf_ref_obj(colorspace->resource);
+ pdf_release_obj(colorspace->resource); /* .... */
+ colorspace->resource = NULL;
+ }
+
+ return pdf_link_obj(colorspace->reference);
+}
+
+#if 0
+int
+pdf_get_colorspace_num_components (int cspc_id)
+{
+ pdf_colorspace *colorspace;
+ int num_components;
+
+ colorspace = &cspc_cache.colorspaces[cspc_id];
+
+ switch (colorspace->subtype) {
+ case PDF_COLORSPACE_TYPE_ICCBASED:
+ num_components = get_num_components_iccbased(colorspace->cdata);
+ break;
+ case PDF_COLORSPACE_TYPE_DEVICEGRAY:
+ num_components = 1;
+ break;
+ case PDF_COLORSPACE_TYPE_DEVICERGB:
+ num_components = 3;
+ break;
+ case PDF_COLORSPACE_TYPE_DEVICECMYK:
+ num_components = 4;
+ break;
+ case PDF_COLORSPACE_TYPE_CALRGB:
+ num_components = 3;
+ break;
+ case PDF_COLORSPACE_TYPE_CALGRAY:
+ num_components = 1;
+ break;
+ default:
+ num_components = 0;
+ break;
+ }
+
+ return num_components;
+}
+
+int
+pdf_get_colorspace_subtype (int cspc_id)
+{
+ pdf_colorspace *colorspace;
+
+ colorspace = &cspc_cache.colorspaces[cspc_id];
+
+ return colorspace->subtype;
+}
+#endif
+
+void
+pdf_init_colors (void)
+{
+ cspc_cache.count = 0;
+ cspc_cache.capacity = 0;
+ cspc_cache.colorspaces = NULL;
+}
+
+void
+pdf_close_colors (void)
+{
+ int i;
+
+ for (i = 0; i < cspc_cache.count; i++) {
+ pdf_colorspace *colorspace;
+
+ colorspace = &cspc_cache.colorspaces[i];
+ pdf_flush_colorspace(colorspace);
+ pdf_clean_colorspace_struct(colorspace);
+ }
+ RELEASE(cspc_cache.colorspaces);
+ cspc_cache.colorspaces = NULL;
+ cspc_cache.count = cspc_cache.capacity = 0;
+
+}
+
+#define PDF_COLORSPACE_FAMILY_DEVICE 0
+#define PDF_COLORSPACE_FAMILY_CIEBASED 1
+#define PDF_COLORSPACE_FAMILY_SPECIAL 2
diff --git a/Build/source/texk/dvipdfm-x/pdfcolor.h b/Build/source/texk/dvipdfm-x/pdfcolor.h
new file mode 100644
index 00000000000..cc23396ebc5
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfcolor.h
@@ -0,0 +1,117 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDF_COLOR_H_
+#define _PDF_COLOR_H_
+
+#include "pdfobj.h"
+
+#define PDF_COLORSPACE_TYPE_CMYK -4
+#define PDF_COLORSPACE_TYPE_RGB -3
+#define PDF_COLORSPACE_TYPE_SPOT -2
+#define PDF_COLORSPACE_TYPE_GRAY -1
+#define PDF_COLORSPACE_TYPE_INVALID 0
+#define PDF_COLORSPACE_TYPE_DEVICEGRAY 1
+#define PDF_COLORSPACE_TYPE_DEVICERGB 2
+#define PDF_COLORSPACE_TYPE_DEVICECMYK 3
+#define PDF_COLORSPACE_TYPE_CALGRAY 4
+#define PDF_COLORSPACE_TYPE_CALRGB 5
+#define PDF_COLORSPACE_TYPE_LAB 6
+#define PDF_COLORSPACE_TYPE_ICCBASED 7
+#define PDF_COLORSPACE_TYPE_SEPARATION 8
+#define PDF_COLORSPACE_TYPE_DEVICEN 9
+#define PDF_COLORSPACE_TYPE_INDEXED 10
+#define PDF_COLORSPACE_TYPE_PATTERN 11
+
+#define PDF_COLOR_COMPONENT_MAX 32
+
+typedef struct
+{
+ int res_id;
+ int type;
+ int num_components;
+ char *spot_color_name;
+ double values[PDF_COLOR_COMPONENT_MAX];
+ int pattern_id;
+} pdf_color;
+
+extern int pdf_color_rgbcolor (pdf_color *color,
+ double r, double g, double b);
+extern int pdf_color_cmykcolor (pdf_color *color,
+ double c, double m, double y, double k);
+extern int pdf_color_graycolor (pdf_color *color, double g);
+
+extern int pdf_color_spotcolor (pdf_color *color, char* color_name, double c);
+
+extern void pdf_color_copycolor (pdf_color *color1, const pdf_color *color2);
+
+#define pdf_color_black(c) pdf_color_graycolor(c, 0.0);
+#define pdf_color_white(c) pdf_color_graycolor(c, 1.0);
+
+extern void pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f);
+
+extern int pdf_color_type (const pdf_color *color);
+extern int pdf_color_compare (const pdf_color *color1, const pdf_color *color2);
+extern int pdf_color_set_color (const pdf_color *color, char *buff, size_t buff_len, char mask);
+
+extern int pdf_color_is_white (const pdf_color *color);
+
+/* Not check size */
+extern pdf_obj *iccp_get_rendering_intent (const void *profile, int proflen);
+extern int iccp_check_colorspace (int colortype,
+ const void *profile, int proflen);
+
+/* returns colorspace ID */
+extern int iccp_load_profile (const char *ident,
+ const void *profile, int proflen);
+
+extern void pdf_init_colors (void);
+extern void pdf_close_colors (void);
+
+extern pdf_obj *pdf_get_colorspace_reference (int cspc_id);
+#if 0
+extern int pdf_get_colorspace_num_components (int cspc_id);
+extern int pdf_get_colorspace_subtype (int cspc_id);
+
+/* Not working */
+extern int pdf_colorspace_load_ICCBased (const char *ident,
+ const char *profile_filename);
+#endif
+
+/* Color special
+ * See remark in spc_color.c.
+ */
+extern void pdf_color_set (pdf_color *sc, pdf_color *fc);
+extern void pdf_color_push (pdf_color *sc, pdf_color *fc);
+extern void pdf_color_pop (void);
+
+/* Color stack
+ */
+extern void pdf_color_clear_stack (void);
+extern void pdf_color_get_current (pdf_color **sc, pdf_color **fc);
+
+#if 0
+/* Reinstall color */
+extern void pdf_dev_preserve_color(void);
+#endif
+
+#endif /* _PDF_COLOR_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfdev.c b/Build/source/texk/dvipdfm-x/pdfdev.c
new file mode 100644
index 00000000000..29980b5ade8
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfdev.c
@@ -0,0 +1,1849 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+
+#include "mfileio.h"
+#include "numbers.h"
+
+#include "pdfdoc.h"
+#include "pdfobj.h"
+
+#include "pdffont.h"
+#include "fontmap.h"
+#include "cmap.h"
+#include "pdfximage.h"
+
+#include "pdfdraw.h"
+#include "pdfcolor.h"
+
+#include "pdflimits.h"
+
+#include "pdfdev.h"
+
+struct dev_param
+{
+ /* Text composition (direction) mode is ignored (always same
+ * as font's writing mode) if autorotate is unset (value zero).
+ */
+ int autorotate;
+
+ /*
+ * Ignore color migrated to here. This is device's capacity.
+ * colormode 0 for ignore colors
+ */
+ int colormode;
+
+};
+
+/*
+ * Text handling routines.
+ */
+
+/* Motion state:
+ * GRAPHICS_MODE Initial state (not within BT/ET block nor in string)
+ * TEXT_MODE Text section is started via BT operator but not
+ * in string.
+ * STRING_MODE In string. A string or array of strings are currently
+ * in process. May started '[', '<' or '('.
+ */
+#define GRAPHICS_MODE 1
+#define TEXT_MODE 2
+#define STRING_MODE 3
+
+/*
+ * In PDF, vertical text positioning is always applied when current font
+ * is vertical font. While ASCII pTeX manages current writing direction
+ * and font's WMode separately.
+ *
+ * 000/101 WMODE_HH/VV h(v) font, h(v) direction.
+ * 001 WMODE_HV -90 deg. rotated
+ * 100 WMODE_VH +90 deg. rotated
+ * 011 WMODE_HD +90 deg. rotated
+ * 111 WMODE_VD 180 deg. rotated
+
+ * In MetaPost PostScript file processing (mp_mode = 1), only HH/VV mode
+ * is applied.
+ */
+#define TEXT_WMODE_HH 0
+#define TEXT_WMODE_HV 1
+#define TEXT_WMODE_VH 4
+#define TEXT_WMODE_VV 5
+#define TEXT_WMODE_HD 3
+#define TEXT_WMODE_VD 7
+
+#define ANGLE_CHANGES(m1,m2) ((abs((m1)-(m2)) % 5) == 0 ? 0 : 1)
+#define ROTATE_TEXT(m) ((m) != TEXT_WMODE_HH && (m) != TEXT_WMODE_VV)
+
+struct text_state {
+
+ /* Current font.
+ * This is index within dev_fonts.
+ */
+ int font_id;
+
+ /* Dvipdfmx does compression of text by doing text positioning
+ * in relative motion and uses string array [(foo) -250 (bar)]
+ * with kerning (negative kern is used for white space as suited
+ * for TeX). This is offset within current string.
+ */
+ spt_t offset;
+
+ /* This is reference point of strings.
+ * It may include error correction induced by rounding.
+ */
+ spt_t ref_x;
+ spt_t ref_y;
+
+ /* Using text raise and leading is highly recommended for
+ * text extraction to work properly. But not implemented yet.
+ * We can't do consice output for \TeX without this.
+ */
+ spt_t raise; /* unused */
+ spt_t leading; /* unused */
+
+ /* This is not always text matrix but rather font matrix.
+ * We do not use horizontal scaling in PDF text state parameter
+ * since they always apply scaling in fixed direction regardless
+ * of writing mode.
+ */
+ struct {
+ double slant;
+ double extend;
+ int rotate; /* TEXT_WMODE_XX */
+ } matrix;
+
+ /* Fake bold parameter:
+ * If bold_param is positive, use text rendering mode
+ * fill-then-stroke with stroking line width specified
+ * by bold_param.
+ */
+ double bold_param;
+
+ /* Text composition (direction) mode. */
+ int dir_mode;
+
+ /* internal */
+
+ /* Flag indicating text matrix to be forcibly reset.
+ * Enabled if synthetic font features (slant, extend, etc)
+ * are used for current font or when text rotation mode
+ * changes.
+ */
+ int force_reset;
+
+ /* This information is duplicated from dev[font_id].format.
+ * Set to 1 if font is composite (Type0) font.
+ */
+ int is_mb;
+};
+
+#define PDF_FONTTYPE_SIMPLE 1
+#define PDF_FONTTYPE_BITMAP 2
+#define PDF_FONTTYPE_COMPOSITE 3
+
+struct dev_font {
+ /* Needs to be big enough to hold name "Fxxx"
+ * where xxx is number of largest font
+ */
+ char short_name[16]; /* Resource name */
+ int used_on_this_page;
+
+ char *tex_name; /* String identifier of this font */
+ spt_t sptsize; /* Point size */
+
+ /* Returned values from font/encoding layer:
+ *
+ * The font_id and enc_id is font and encoding (CMap) identifier
+ * used in pdf_font or encoding/cmap layer.
+ * The PDF object "resource" is an indirect reference object
+ * pointing font resource of this font. The used_chars is somewhat
+ * misleading, this is actually used_glyphs in CIDFont for Type0
+ * and is 65536/8 bytes binary data with each bits representing
+ * whether the glyph is in-use or not. It is 256 char array for
+ * simple font.
+ */
+ int font_id;
+ int enc_id;
+
+ pdf_obj *resource;
+ char *used_chars;
+
+ /* Font format:
+ * simple, composite or bitmap.
+ */
+ int format;
+
+ /* Writing mode:
+ * Non-zero for vertical. Duplicated from CMap.
+ */
+ int wmode;
+
+ /* Syntetic Font:
+ *
+ * We use text matrix for creating extended or slanted font,
+ * but not with font's FontMatrix since TrueType and Type0
+ * font don't support them.
+ */
+ double extend;
+ double slant;
+ double bold; /* Boldness prameter */
+};
+
+/*
+ * Unit conversion, formatting and others.
+ */
+
+#define TEX_ONE_HUNDRED_BP 6578176
+struct dev_unit {
+ double dvi2pts; /* multiplier for DVI unit to bpt conversion */
+ int min_bp_val; /* Shortest resolvable distance in the output PDF. */
+ int precision; /* Number of decimal digits (in fractional part) kept. */
+};
+
+#define FORMAT_BUF_SIZE 4096
+struct pdf_dev {
+ int motion_state;
+ struct dev_param param;
+ struct dev_unit unit;
+ struct text_state text_state;
+ struct dev_font *fonts;
+ int num_dev_fonts;
+ int max_dev_fonts;
+ char format_buffer[FORMAT_BUF_SIZE+1];
+};
+
+/*
+ * For a moment declare as static variable here
+ * 2020/07/23 Most of the static variables put into single struct pdev
+ */
+static pdf_dev pdev;
+
+static pdf_dev *
+current_device (void)
+{
+ return &pdev;
+}
+
+static void
+dev_out (pdf_dev *p, const char *str, size_t len)
+{
+ pdf_doc_add_page_content(str, len);
+}
+
+static double
+pdf_dev_unit_dviunit (pdf_dev *p)
+{
+ ASSERT(p);
+
+ return (1.0 / p->unit.dvi2pts);
+}
+
+#define DEV_PRECISION_MAX 8
+static uint32_t ten_pow[10] = {
+ 1u, 10u, 100u, 1000u, 10000u, 100000u, 1000000u, 10000000u, 100000000u, 1000000000u
+};
+
+static double ten_pow_inv[10] = {
+ 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001
+};
+
+#define bpt2spt(p, b) ( (spt_t) round( (b) / (p)->unit.dvi2pts ) )
+#define spt2bpt(p, s) ( (s) * (p)->unit.dvi2pts )
+#define dround_at(v,p) (ROUND( (v), ten_pow_inv[(p)] ))
+
+static int
+p_itoa (int value, char *buf)
+{
+ int sign, ndigits;
+ char *p = buf;
+
+ if (value < 0) {
+ *p++ = '-';
+ value = -value;
+ sign = 1;
+ } else {
+ sign = 0;
+ }
+
+ ndigits = 0;
+ /* Generate at least one digit in reverse order */
+ do {
+ p[ndigits++] = (value % 10) + '0';
+ value /= 10;
+ } while (value != 0);
+
+ /* Reverse the digits */
+ {
+ int i;
+
+ for (i = 0; i < ndigits / 2 ; i++) {
+ char tmp = p[i];
+ p[i] = p[ndigits-i-1];
+ p[ndigits-i-1] = tmp;
+ }
+ }
+ p[ndigits] = '\0';
+
+ return (sign ? ndigits + 1 : ndigits);
+}
+
+/* NOTE: Acrobat 5 and prior uses 16.16 fixed point representation for
+ * real numbers.
+ */
+static int
+p_dtoa (double value, int prec, char *buf)
+{
+ const int32_t p[10] = { 1, 10, 100, 1000, 10000,
+ 100000, 1000000, 10000000,
+ 100000000, 1000000000 };
+ double i, f;
+ int32_t g;
+ char *c = buf;
+ int n;
+
+ if (value < 0) {
+ value = -value;
+ *c++ = '-';
+ n = 1;
+ } else {
+ n = 0;
+ }
+
+ f = modf(value, &i);
+ g = (int32_t) (f * p[prec] + 0.5);
+
+ if (g == p[prec]) {
+ g = 0;
+ i += 1;
+ }
+
+ if (i) {
+ int m = sprintf(c, "%.0f", i);
+ c += m;
+ n += m;
+ } else if (g == 0) {
+ *(c = buf) = '0';
+ n = 1;
+ }
+
+ if (g) {
+ int j = prec;
+
+ *c++ = '.';
+
+ while (j--) {
+ c[j] = (g % 10) + '0';
+ g /= 10;
+ }
+ c += prec - 1;
+ n += 1 + prec;
+
+ while (*c == '0') {
+ c--;
+ n--;
+ }
+ }
+
+ *(++c) = 0;
+
+ return n;
+}
+
+static int
+dev_sprint_bp (pdf_dev *p, char *buf, spt_t value, spt_t *error)
+{
+ double value_in_bp;
+ double error_in_bp;
+ int prec;
+
+ ASSERT(p);
+
+ prec = p->unit.precision;
+
+ value_in_bp = spt2bpt(p, value);
+ if (error) {
+ error_in_bp = value_in_bp - dround_at(value_in_bp, prec);
+ *error = bpt2spt(p, error_in_bp);
+ }
+
+ return p_dtoa(value_in_bp, prec, buf);
+}
+
+/* They are affected by precision (set at device initialization). */
+static size_t
+pdf_dev_sprint_matrix (pdf_dev *p, char *buf, const pdf_tmatrix *M)
+{
+ size_t len;
+ int prec0, prec2;
+
+ ASSERT(p);
+
+ prec2 = MIN(p->unit.precision + 2, DEV_PRECISION_MAX);
+ prec0 = MAX(p->unit.precision, 2);
+
+ len = p_dtoa(M->a, prec2, buf);
+ buf[len++] = ' ';
+ len += p_dtoa(M->b, prec2, buf+len);
+ buf[len++] = ' ';
+ len += p_dtoa(M->c, prec2, buf+len);
+ buf[len++] = ' ';
+ len += p_dtoa(M->d, prec2, buf+len);
+ buf[len++] = ' ';
+ len += p_dtoa(M->e, prec0, buf+len);
+ buf[len++] = ' ';
+ len += p_dtoa(M->f, prec0, buf+len);
+ buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
+
+ return len;
+}
+
+static size_t
+pdf_dev_sprint_rect (pdf_dev *p, char *buf, const pdf_rect *rect)
+{
+ size_t len;
+
+ ASSERT(p);
+
+ len = p_dtoa(rect->llx, p->unit.precision, buf);
+ buf[len++] = ' ';
+ len += p_dtoa(rect->lly, p->unit.precision, buf+len);
+ buf[len++] = ' ';
+ len += p_dtoa(rect->urx, p->unit.precision, buf+len);
+ buf[len++] = ' ';
+ len += p_dtoa(rect->ury, p->unit.precision, buf+len);
+ buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
+
+ return len;
+}
+
+static size_t
+pdf_dev_sprint_coord (pdf_dev *p, char *buf, const pdf_coord *c)
+{
+ size_t len;
+
+ ASSERT(p);
+
+ len = p_dtoa(c->x, p->unit.precision, buf);
+ buf[len++] = ' ';
+ len += p_dtoa(c->y, p->unit.precision, buf+len);
+ buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
+
+ return len;
+}
+
+static size_t
+pdf_dev_sprint_length (pdf_dev *p, char *buf, double value)
+{
+ size_t len;
+
+ ASSERT(p);
+
+ len = p_dtoa(value, p->unit.precision, buf);
+ buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
+
+ return len;
+}
+
+static size_t
+pdf_dev_sprint_number (pdf_dev *p, char *buf, double value)
+{
+ size_t len;
+
+ ASSERT(p);
+
+ len = p_dtoa(value, DEV_PRECISION_MAX, buf);
+ buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
+
+ return len;
+}
+
+/* Text handling */
+#define CURRENTFONT(p) (((p)->text_state.font_id < 0) ? \
+ NULL : &((p)->fonts[(p)->text_state.font_id]))
+#define GET_FONT(p, n) (&((p)->fonts[(n)]))
+
+static void
+dev_set_text_matrix (pdf_dev *p,
+ spt_t xpos, spt_t ypos,
+ double slant, double extend, int rotate)
+{
+ pdf_tmatrix tm;
+ int len = 0;
+
+ ASSERT(p);
+
+ /* slant is negated for vertical font so that right-side
+ * is always lower. */
+ switch (rotate) {
+ case TEXT_WMODE_VH:
+ /* Vertical font */
+ tm.a = slant ; tm.b = 1.0;
+ tm.c = -extend; tm.d = 0.0 ;
+ break;
+ case TEXT_WMODE_HV:
+ /* Horizontal font */
+ tm.a = 0.0; tm.b = -extend;
+ tm.c = 1.0; tm.d = -slant ;
+ break;
+ case TEXT_WMODE_HH:
+ /* Horizontal font */
+ tm.a = extend; tm.b = 0.0;
+ tm.c = slant ; tm.d = 1.0;
+ break;
+ case TEXT_WMODE_VV:
+ /* Vertical font */
+ tm.a = 1.0; tm.b = -slant;
+ tm.c = 0.0; tm.d = extend;
+ break;
+ case TEXT_WMODE_HD:
+ /* Horizontal font */
+ tm.a = 0.0; tm.b = extend;
+ tm.c = -1.0; tm.d = slant ;
+ break;
+ case TEXT_WMODE_VD:
+ /* Vertical font */
+ tm.a = -1.0; tm.b = slant;
+ tm.c = 0.0; tm.d = -extend;
+ break;
+ }
+ tm.e = xpos * p->unit.dvi2pts;
+ tm.f = ypos * p->unit.dvi2pts;
+
+ p->format_buffer[len++] = ' ';
+ len += pdf_dev_sprint_matrix(p, p->format_buffer+len, &tm);
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'T';
+ p->format_buffer[len++] = 'm';
+
+ dev_out(p, p->format_buffer, len); /* op: Tm */
+
+ p->text_state.ref_x = xpos;
+ p->text_state.ref_y = ypos;
+ p->text_state.matrix.slant = slant;
+ p->text_state.matrix.extend = extend;
+ p->text_state.matrix.rotate = rotate;
+}
+
+/*
+ * reset_text_state() outputs a BT and does any necessary coordinate
+ * transformations to get ready to ship out text.
+ */
+
+static void
+reset_text_state (pdf_dev *p)
+{
+ ASSERT(p);
+
+ /*
+ * We need to reset the line matrix to handle slanted fonts.
+ */
+ dev_out(p, " BT", 3); /* op: BT */
+ /*
+ * text_state.matrix is identity at top of page.
+ * This sometimes write unnecessary "Tm"s when transition from
+ * GRAPHICS_MODE to TEXT_MODE occurs.
+ */
+ if (p->text_state.force_reset ||
+ p->text_state.matrix.slant != 0.0 ||
+ p->text_state.matrix.extend != 1.0 ||
+ ROTATE_TEXT(p->text_state.matrix.rotate)) {
+ dev_set_text_matrix(p, 0, 0,
+ p->text_state.matrix.slant,
+ p->text_state.matrix.extend,
+ p->text_state.matrix.rotate);
+ }
+ p->text_state.ref_x = 0;
+ p->text_state.ref_y = 0;
+ p->text_state.offset = 0;
+ p->text_state.force_reset = 0;
+}
+
+static void
+pdf_dev_text_mode (pdf_dev *p)
+{
+ ASSERT(p);
+
+ switch (p->motion_state) {
+ case TEXT_MODE:
+ break;
+ case STRING_MODE:
+ dev_out(p, p->text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */
+ break;
+ case GRAPHICS_MODE:
+ reset_text_state(p);
+ break;
+ }
+ p->motion_state = TEXT_MODE;
+ p->text_state.offset = 0;
+}
+
+static void
+pdf_dev_graphics_mode (pdf_dev *p)
+{
+ switch (p->motion_state) {
+ case GRAPHICS_MODE:
+ break;
+ case STRING_MODE:
+ dev_out(p, p->text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */
+ /* continue */
+ case TEXT_MODE:
+ if (p->text_state.bold_param != 0.0) {
+ /* fake-bold "2 Tr" is still active */
+ dev_out(p, " 0 Tr", 5); /* op: Tr */
+ p->text_state.bold_param = 0.0;
+ }
+ dev_out(p, " ET", 3); /* op: ET */
+ p->text_state.force_reset = 0;
+ p->text_state.font_id = -1;
+ break;
+ }
+ p->motion_state = GRAPHICS_MODE;
+}
+
+static void
+start_string (pdf_dev *p,
+ spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
+{
+ spt_t delx, dely, error_delx, error_dely;
+ spt_t desired_delx, desired_dely;
+ int len = 0;
+
+ ASSERT(p);
+
+ delx = xpos - p->text_state.ref_x;
+ dely = ypos - p->text_state.ref_y;
+ /*
+ * Precompensating for line transformation matrix.
+ *
+ * Line transformation matrix L for horizontal font in horizontal
+ * mode and it's inverse I is
+ *
+ * | e 0| | 1/e 0|
+ * L_hh = | | , I_hh = | |
+ * | s 1| |-s/e 1|
+ *
+ * For vertical font in vertical mode,
+ *
+ * | 1 -s| | 1 s/e|
+ * L_vv = | | , I_vv = | |
+ * | 0 e| | 0 1/e|
+ *
+ * For vertical font in horizontal mode,
+ *
+ * | s 1| | 0 1|
+ * L_vh = | | = L_vv x | |
+ * |-e 0| |-1 0|
+ *
+ * | 0 -1|
+ * I_vh = | | x I_vv
+ * | 1 0|
+ *
+ * For horizontal font in vertical mode,
+ *
+ * | 0 -e| | 0 -1|
+ * L_hv = | | = L_hh x | |
+ * | 1 -s| | 1 0|
+ *
+ * | 0 1|
+ * I_hv = | | x I_hh
+ * |-1 0|
+ *
+ */
+ switch (rotate) {
+ case TEXT_WMODE_VH:
+ /* Vertical font in horizontal mode: rot = +90
+ * | 0 -1/e|
+ * d_user = d x I_vh = d x | |
+ * | 1 s/e|
+ */
+ desired_delx = dely;
+ desired_dely = (spt_t) (-(delx - dely*slant)/extend);
+
+ /* error_del is in device space
+ *
+ * | 0 1|
+ * e = e_user x | | = (-e_user_y, e_user_x)
+ * |-1 0|
+ *
+ * We must care about rotation here but not extend/slant...
+ * The extend and slant actually is font matrix.
+ */
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_delx);
+ error_delx = -error_delx;
+ break;
+ case TEXT_WMODE_HV:
+ /* Horizontal font in vertical mode: rot = -90
+ *
+ * |-s/e 1|
+ * d_user = d x I_hv = d x | |
+ * |-1/e 0|
+ */
+ desired_delx = (spt_t)(-(dely + delx*slant)/extend);
+ desired_dely = delx;
+
+ /*
+ * e = (e_user_y, -e_user_x)
+ */
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_delx);
+ error_dely = -error_dely;
+ break;
+ case TEXT_WMODE_HH:
+ /* Horizontal font in horizontal mode:
+ * | 1/e 0|
+ * d_user = d x I_hh = d x | |
+ * |-s/e 1|
+ */
+ desired_delx = (spt_t)((delx - dely*slant)/extend);
+ desired_dely = dely;
+
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_dely);
+ break;
+ case TEXT_WMODE_VV:
+ /* Vertical font in vertical mode:
+ * | 1 s/e|
+ * d_user = d x I_vv = d x | |
+ * | 0 1/e|
+ */
+ desired_delx = delx;
+ desired_dely = (spt_t)((dely + delx*slant)/extend);
+
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_dely);
+ break;
+ case TEXT_WMODE_HD:
+ /* Horizontal font in down-to-up mode: rot = +90
+ *
+ * | s/e -1|
+ * d_user = d x -I_hv = d x | |
+ * | 1/e 0|
+ */
+ desired_delx = -(spt_t)(-(dely + delx*slant)/extend);
+ desired_dely = -delx;
+
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_delx);
+ error_delx = -error_delx;
+ error_dely = -error_dely;
+ break;
+ case TEXT_WMODE_VD:
+ /* Vertical font in down-to-up mode: rot = 180
+ * |-1 -s/e|
+ * d_user = d x -I_vv = d x | |
+ * | 0 -1/e|
+ */
+ desired_delx = -delx;
+ desired_dely = -(spt_t)((dely + delx*slant)/extend);
+
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_dely);
+ error_delx = -error_delx;
+ error_dely = -error_dely;
+ break;
+ }
+ dev_out(p, p->format_buffer, len); /* op: */
+ /*
+ * dvipdfm wrongly using "TD" in place of "Td".
+ * The TD operator set leading, but we are not using T* etc.
+ */
+ dev_out(p, p->text_state.is_mb ? " Td[<" : " Td[(", 5); /* op: Td */
+
+ /* Error correction */
+ p->text_state.ref_x = xpos - error_delx;
+ p->text_state.ref_y = ypos - error_dely;
+
+ p->text_state.offset = 0;
+}
+
+static void
+pdf_dev_string_mode (pdf_dev *p, spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
+{
+ ASSERT(p);
+
+ switch (p->motion_state) {
+ case STRING_MODE:
+ break;
+ case GRAPHICS_MODE:
+ reset_text_state(p);
+ /* continue */
+ case TEXT_MODE:
+ if (p->text_state.force_reset) {
+ dev_set_text_matrix(p, xpos, ypos, slant, extend, rotate);
+ dev_out(p, p->text_state.is_mb ? "[<" : "[(", 2); /* op: */
+ p->text_state.force_reset = 0;
+ } else {
+ start_string(p, xpos, ypos, slant, extend, rotate);
+ }
+ break;
+ }
+ p->motion_state = STRING_MODE;
+}
+
+/*
+ * The purpose of the following routine is to force a Tf only
+ * when it's actually necessary. This became a problem when the
+ * VF code was added. The VF spec says to instantiate the
+ * first font contained in the VF file before drawing a virtual
+ * character. However, that font may not be used for
+ * many characters (e.g. small caps fonts). For this reason,
+ * dev_select_font() should not force a "physical" font selection.
+ * This routine prevents a PDF Tf font selection until there's
+ * really a character in that font.
+ */
+
+static int
+pdf_dev_set_font (pdf_dev *p, int font_id)
+{
+ struct dev_font *font;
+ int text_rotate;
+ double font_scale;
+ int len;
+ int vert_dir, vert_font;
+
+ ASSERT(p);
+
+ /* text_mode() must come before text_state.is_mb is changed. */
+ pdf_dev_text_mode(p);
+
+ font = GET_FONT(p, font_id);
+ ASSERT(font); /* Caller should check font_id. */
+
+ p->text_state.is_mb = (font->format == PDF_FONTTYPE_COMPOSITE) ? 1 : 0;
+
+ vert_font = font->wmode ? 1 : 0;
+ if (p->param.autorotate) {
+ vert_dir = p->text_state.dir_mode;
+ } else {
+ vert_dir = vert_font;
+ }
+ text_rotate = (vert_font << 2)|vert_dir;
+
+ if (font->slant != p->text_state.matrix.slant ||
+ font->extend != p->text_state.matrix.extend ||
+ ANGLE_CHANGES(text_rotate, p->text_state.matrix.rotate)) {
+ p->text_state.force_reset = 1;
+ }
+ p->text_state.matrix.slant = font->slant;
+ p->text_state.matrix.extend = font->extend;
+ p->text_state.matrix.rotate = text_rotate;
+
+ if (!font->resource) {
+ font->resource = pdf_get_font_reference(font->font_id);
+ font->used_chars = pdf_get_font_usedchars(font->font_id);
+ }
+
+ if (!font->used_on_this_page) {
+ pdf_doc_add_page_resource("Font",
+ font->short_name,
+ pdf_link_obj(font->resource));
+ font->used_on_this_page = 1;
+ }
+
+ font_scale = (double) font->sptsize * p->unit.dvi2pts;
+ len = sprintf(p->format_buffer, " /%s", font->short_name); /* space not necessary. */
+ p->format_buffer[len++] = ' ';
+ len += p_dtoa(font_scale, MIN(p->unit.precision+1, DEV_PRECISION_MAX),
+ p->format_buffer+len);
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'T';
+ p->format_buffer[len++] = 'f';
+ dev_out(p, p->format_buffer, len); /* op: Tf */
+
+ if (font->bold > 0.0 || font->bold != p->text_state.bold_param) {
+ if (font->bold <= 0.0)
+ len = sprintf(p->format_buffer, " 0 Tr");
+ else
+ len = sprintf(p->format_buffer, " 2 Tr %.6f w", font->bold); /* _FIXME_ */
+ dev_out(p, p->format_buffer, len); /* op: Tr w */
+ }
+ p->text_state.bold_param = font->bold;
+
+ p->text_state.font_id = font_id;
+
+ return 0;
+}
+
+/* These tmp buffers can't be removed since the pointer to this can be
+ * used as the return value of handle_multibyte_string(): str_ptr can point these.
+ */
+static unsigned char sbuf0[FORMAT_BUF_SIZE];
+
+static int
+handle_multibyte_string (struct dev_font *font, const unsigned char **str_ptr, int *str_len)
+{
+ const unsigned char *p;
+ int length;
+
+ p = *str_ptr;
+ length = *str_len;
+
+ /*
+ * Font is double-byte font. Output is assumed to be 16-bit fixed length
+ * encoding.
+ * TODO: A character decomposed to multiple characters.
+ */
+ if (font->enc_id >= 0) {
+ const unsigned char *inbuf;
+ unsigned char *outbuf;
+ int inbytesleft, outbytesleft;
+ CMap *cmap;
+
+ cmap = CMap_cache_get(font->enc_id);
+ inbuf = p;
+ outbuf = sbuf0;
+ inbytesleft = length;
+ outbytesleft = FORMAT_BUF_SIZE;
+
+ CMap_decode(cmap, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+ if (inbytesleft != 0) {
+ WARN("CMap conversion failed. (%d bytes remains)", inbytesleft);
+ return -1;
+ }
+ length = FORMAT_BUF_SIZE - outbytesleft;
+ p = sbuf0;
+ }
+
+ *str_ptr = p;
+ *str_len = length;
+ return 0;
+}
+
+void
+pdf_dev_set_string (spt_t xpos, spt_t ypos,
+ const void *instr_ptr, int instr_len, spt_t width, int font_id)
+{
+ pdf_dev *p = current_device();
+ struct dev_font *font;
+ const unsigned char *str_ptr; /* Pointer to the reencoded string. */
+ int length, i, len = 0;
+ spt_t kern, delh, delv;
+ spt_t text_xorigin;
+ spt_t text_yorigin;
+
+ if (font_id < 0 || font_id >= p->num_dev_fonts) {
+ ERROR("Invalid font: %d (%d)", font_id, p->num_dev_fonts);
+ return;
+ }
+ if (font_id != p->text_state.font_id) {
+ pdf_dev_set_font(p, font_id);
+ }
+
+ font = CURRENTFONT(p);
+ if (!font) {
+ ERROR("Currentfont not set.");
+ return;
+ }
+
+ text_xorigin = p->text_state.ref_x;
+ text_yorigin = p->text_state.ref_y;
+
+ str_ptr = instr_ptr;
+ length = instr_len;
+
+ if (font->format == PDF_FONTTYPE_COMPOSITE) {
+ if (handle_multibyte_string(font, &str_ptr, &length) < 0) {
+ ERROR("Error in converting input string...");
+ return;
+ }
+ if (font->used_chars != NULL) {
+ for (i = 0; i < length; i += 2) {
+ unsigned short cid = (str_ptr[i] << 8) | str_ptr[i + 1];
+ add_to_used_chars2(font->used_chars, cid);
+ }
+ }
+ } else {
+ if (font->used_chars != NULL) {
+ for (i = 0; i < length; i++)
+ font->used_chars[str_ptr[i]] = 1;
+ }
+ }
+
+ /*
+ * Kern is in units of character units, i.e., 1000 = 1 em.
+ *
+ * Positive kern means kerning (reduce excess white space).
+ *
+ * The following formula is of the form a*x/b where a, x, and b are signed long
+ * integers. Since in integer arithmetic (a*x) could overflow and a*(x/b) would
+ * not be accurate, we use floating point arithmetic rather than trying to do
+ * this all with integer arithmetic.
+ *
+ * 1000.0 / (font->extend * font->sptsize) is caluculated each times...
+ * Is accuracy really a matter? Character widths are always rounded to integer
+ * (in 1000 units per em) but dvipdfmx does not take into account of this...
+ */
+
+ if (p->text_state.dir_mode==0) {
+ /* Left-to-right */
+ delh = text_xorigin + p->text_state.offset - xpos;
+ delv = ypos - text_yorigin;
+ } else if (p->text_state.dir_mode==1) {
+ /* Top-to-bottom */
+ delh = ypos - text_yorigin + p->text_state.offset;
+ delv = xpos - text_xorigin;
+ } else {
+ /* Bottom-to-top */
+ delh = ypos + text_yorigin + p->text_state.offset;
+ delv = xpos + text_xorigin;
+ }
+
+ /* White-space more than 3em is not considered as a part of single text.
+ * So we will break string mode in that case.
+ * Dvipdfmx spend most of time processing strings with kern = 0 (but far
+ * more times in font handling).
+ * You may want to use pre-calculated value for WORD_SPACE_MAX.
+ * More text compression may be possible by replacing kern with space char
+ * when -kern is equal to space char width.
+ */
+#define WORD_SPACE_MAX(f) (spt_t) (3.0 * (f)->extend * (f)->sptsize)
+
+ if (p->text_state.force_reset ||
+ labs(delv) > p->unit.min_bp_val ||
+ labs(delh) > WORD_SPACE_MAX(font)) {
+ pdf_dev_text_mode(p);
+ kern = 0;
+ } else {
+ kern = (spt_t) (1000.0 / font->extend * delh / font->sptsize);
+ }
+
+ /* Inaccucary introduced by rounding of character width appears within
+ * single text block. There are point_size/1000 rounding error per character.
+ * If you really care about accuracy, you should compensate this here too.
+ */
+ if (p->motion_state != STRING_MODE)
+ pdf_dev_string_mode(p, xpos, ypos,
+ font->slant, font->extend, p->text_state.matrix.rotate);
+ else if (kern != 0) {
+ /*
+ * Same issues as earlier. Use floating point for simplicity.
+ * This routine needs to be fast, so we don't call sprintf() or strcpy().
+ */
+ p->text_state.offset -=
+ (spt_t) (kern * font->extend * (font->sptsize / 1000.0));
+ p->format_buffer[len++] = p->text_state.is_mb ? '>' : ')';
+ if (font->wmode)
+ len += p_itoa(-kern, p->format_buffer + len);
+ else {
+ len += p_itoa( kern, p->format_buffer + len);
+ }
+ p->format_buffer[len++] = p->text_state.is_mb ? '<' : '(';
+ dev_out(p, p->format_buffer, len); /* op: */
+ len = 0;
+ }
+
+ if (p->text_state.is_mb) {
+ if (FORMAT_BUF_SIZE - len < 2 * length)
+ ERROR("Buffer overflow...");
+ for (i = 0; i < length; i++) {
+ int first, second;
+
+ first = (str_ptr[i] >> 4) & 0x0f;
+ second = str_ptr[i] & 0x0f;
+ p->format_buffer[len++] = ((first >= 10) ? first + 'W' : first + '0');
+ p->format_buffer[len++] = ((second >= 10) ? second + 'W' : second + '0');
+ }
+ } else {
+ len += pdfobj_escape_str(p->format_buffer + len,
+ FORMAT_BUF_SIZE - len, str_ptr, length);
+ }
+ /* I think if you really care about speed, you should avoid memcopy here. */
+ dev_out(p, p->format_buffer, len); /* op: */
+
+ p->text_state.offset += width;
+}
+
+void
+pdf_init_device (double dvi2pts, int precision, int black_and_white)
+{
+ pdf_dev *p = current_device();
+
+ p->motion_state = GRAPHICS_MODE;
+ p->unit.dvi2pts = 0.0;
+ p->unit.min_bp_val = 658;
+ p->unit.precision = 2;
+ p->param.autorotate = 1;
+ p->param.colormode = 1;
+ p->text_state.font_id = -1;
+ p->text_state.offset = 0;
+ p->text_state.matrix.slant = 0;
+ p->text_state.matrix.extend = 0;
+ p->text_state.matrix.rotate = 0;
+ p->text_state.bold_param = 0;
+ p->text_state.dir_mode = 0;
+ p->text_state.force_reset = 0;
+ p->text_state.is_mb = 0;
+
+ if (precision < 0 ||
+ precision > DEV_PRECISION_MAX)
+ WARN("Number of decimal digits out of range [0-%d].",
+ DEV_PRECISION_MAX);
+
+ if (precision < 0) {
+ p->unit.precision = 0;
+ } else if (precision > DEV_PRECISION_MAX) {
+ p->unit.precision = DEV_PRECISION_MAX;
+ } else {
+ p->unit.precision = precision;
+ }
+ p->unit.dvi2pts = dvi2pts;
+ p->unit.min_bp_val = (int) ROUND(1.0/(ten_pow[p->unit.precision]*dvi2pts), 1);
+ if (p->unit.min_bp_val < 0)
+ p->unit.min_bp_val = -p->unit.min_bp_val;
+
+ p->param.colormode = (black_and_white ? 0 : 1);
+
+ pdf_dev_graphics_mode(p);
+ pdf_color_clear_stack();
+ pdf_dev_init_gstates();
+
+ p->num_dev_fonts = p->max_dev_fonts = 0;
+ p->fonts = NULL;
+
+ return;
+}
+
+void
+pdf_close_device (void)
+{
+ pdf_dev *p = current_device();
+
+ if (p->fonts) {
+ int i;
+
+ for (i = 0; i < p->num_dev_fonts; i++) {
+ if (p->fonts[i].tex_name)
+ RELEASE(p->fonts[i].tex_name);
+ if (p->fonts[i].resource)
+ pdf_release_obj(p->fonts[i].resource);
+ p->fonts[i].tex_name = NULL;
+ p->fonts[i].resource = NULL;
+ }
+ RELEASE(p->fonts);
+ p->fonts = NULL;
+ }
+ pdf_dev_clear_gstates();
+}
+
+/*
+ * BOP, EOP, and FONT section.
+ * BOP and EOP manipulate some of the same data structures
+ * as the font stuff.
+ */
+void
+pdf_dev_reset_fonts (int newpage)
+{
+ pdf_dev *p = current_device();
+ int i;
+
+ for (i = 0; i < p->num_dev_fonts; i++) {
+ p->fonts[i].used_on_this_page = 0;
+ }
+
+ p->text_state.font_id = -1;
+
+ p->text_state.matrix.slant = 0.0;
+ p->text_state.matrix.extend = 1.0;
+ p->text_state.matrix.rotate = TEXT_WMODE_HH;
+
+ if (newpage)
+ p->text_state.bold_param = 0.0;
+
+ p->text_state.is_mb = 0;
+}
+
+void
+pdf_dev_reset_color (int force)
+{
+ pdf_color *sc, *fc;
+
+ pdf_color_get_current(&sc, &fc);
+ pdf_dev_set_color(sc, 0, force);
+ pdf_dev_set_color(fc, 0x20, force);
+}
+
+void
+pdf_dev_bop (const pdf_tmatrix *M)
+{
+ pdf_dev *p = current_device();
+
+ pdf_dev_graphics_mode(p);
+
+ p->text_state.force_reset = 0;
+
+ pdf_dev_gsave();
+ pdf_dev_concat(M);
+
+ pdf_dev_reset_fonts(1);
+ pdf_dev_reset_color(0);
+ pdf_dev_reset_xgstate(0);
+}
+
+void
+pdf_dev_eop (void)
+{
+ pdf_dev *p = current_device();
+ int depth;
+
+ pdf_dev_graphics_mode(p);
+
+ depth = pdf_dev_current_depth();
+ if (depth != 1) {
+ WARN("Unbalenced q/Q nesting...: %d", depth);
+ pdf_dev_grestore_to(0);
+ } else {
+ pdf_dev_grestore();
+ }
+}
+
+static void
+print_fontmap (const char *font_name, fontmap_rec *mrec)
+{
+ if (!mrec)
+ return;
+
+ MESG("\n");
+
+ MESG("fontmap: %s -> %s", font_name, mrec->font_name);
+ if (mrec->enc_name)
+ MESG("(%s)", mrec->enc_name);
+ if (mrec->opt.extend != 1.0)
+ MESG("[extend:%g]", mrec->opt.extend);
+ if (mrec->opt.slant != 0.0)
+ MESG("[slant:%g]", mrec->opt.slant);
+ if (mrec->opt.bold != 0.0)
+ MESG("[bold:%g]", mrec->opt.bold);
+ if (mrec->opt.flags & FONTMAP_OPT_NOEMBED)
+ MESG("[noemb]");
+ if (mrec->opt.mapc >= 0)
+ MESG("[map:<%02x>]", mrec->opt.mapc);
+ if (mrec->opt.charcoll)
+ MESG("[csi:%s]", mrec->opt.charcoll);
+ if (mrec->opt.index)
+ MESG("[index:%d]", mrec->opt.index);
+
+ switch (mrec->opt.style) {
+ case FONTMAP_STYLE_BOLD:
+ MESG("[style:bold]");
+ break;
+ case FONTMAP_STYLE_ITALIC:
+ MESG("[style:italic]");
+ break;
+ case FONTMAP_STYLE_BOLDITALIC:
+ MESG("[style:bolditalic]");
+ break;
+ }
+ MESG("\n");
+
+}
+
+/* _FIXME_
+ * Font is identified with font_name and point_size as in DVI here.
+ * However, except for PDF_FONTTYPE_BITMAP, we can share the
+ * short_name, resource and used_chars between multiple instances
+ * of the same font at different sizes.
+ */
+int
+pdf_dev_locate_font (const char *font_name, spt_t ptsize)
+{
+ pdf_dev *p = current_device();
+ int i;
+ fontmap_rec *mrec;
+ struct dev_font *font;
+
+ if (!font_name)
+ return -1;
+
+ if (ptsize == 0) {
+ ERROR("pdf_dev_locate_font() called with the zero ptsize.");
+ return -1;
+ }
+
+ for (i = 0; i < p->num_dev_fonts; i++) {
+ if (!strcmp(font_name, p->fonts[i].tex_name) &&
+ ptsize == p->fonts[i].sptsize) {
+ return i; /* found a dev_font that matches the request */
+ }
+ }
+
+ /*
+ * Make sure we have room for a new one, even though we may not
+ * actually create one.
+ */
+ if (p->num_dev_fonts >= p->max_dev_fonts) {
+ p->max_dev_fonts += 16;
+ p->fonts = RENEW(p->fonts, p->max_dev_fonts, struct dev_font);
+ }
+
+ font = &p->fonts[p->num_dev_fonts];
+
+ /* New font */
+ mrec = pdf_lookup_fontmap_record(font_name);
+
+ if (dpx_conf.verbose_level > 1)
+ print_fontmap(font_name, mrec);
+
+ font->font_id = pdf_font_findresource(font_name, ptsize * p->unit.dvi2pts);
+ if (font->font_id < 0) {
+ font->font_id = pdf_font_load_font(font_name, ptsize * p->unit.dvi2pts, mrec);
+ if (font->font_id < 0)
+ return -1;
+ }
+
+ pdf_font_resource_name(font->font_id, font->short_name);
+
+ font->used_on_this_page = 0;
+
+ font->tex_name = NEW(strlen(font_name) + 1, char);
+ strcpy(font->tex_name, font_name);
+ font->sptsize = ptsize;
+
+ switch (pdf_get_font_subtype(font->font_id)) {
+ case PDF_FONT_FONTTYPE_TYPE3:
+ font->format = PDF_FONTTYPE_BITMAP;
+ break;
+ case PDF_FONT_FONTTYPE_TYPE0:
+ font->format = PDF_FONTTYPE_COMPOSITE;
+ break;
+ default:
+ font->format = PDF_FONTTYPE_SIMPLE;
+ break;
+ }
+
+ font->wmode = pdf_get_font_wmode (font->font_id);
+ font->enc_id = pdf_get_font_encoding(font->font_id);
+
+ font->resource = NULL; /* Don't ref obj until font is actually used. */
+ font->used_chars = NULL;
+
+ font->extend = 1.0;
+ font->slant = 0.0;
+ font->bold = 0.0;
+ if (mrec) {
+ font->extend = mrec->opt.extend;
+ font->slant = mrec->opt.slant;
+ font->bold = mrec->opt.bold;
+ }
+
+ return p->num_dev_fonts++;
+}
+
+
+/* This does not remember current stroking width. */
+static int
+dev_sprint_line (pdf_dev *p, char *buf, spt_t width,
+ spt_t p0_x, spt_t p0_y, spt_t p1_x, spt_t p1_y)
+{
+ int len = 0;
+ double w;
+
+ w = width * p->unit.dvi2pts;
+
+ len += p_dtoa(w, MIN(p->unit.precision+1, DEV_PRECISION_MAX), buf+len);
+ buf[len++] = ' ';
+ buf[len++] = 'w';
+ buf[len++] = ' ';
+ len += dev_sprint_bp(p, buf+len, p0_x, NULL);
+ buf[len++] = ' ';
+ len += dev_sprint_bp(p, buf+len, p0_y, NULL);
+ buf[len++] = ' ';
+ buf[len++] = 'm';
+ buf[len++] = ' ';
+ len += dev_sprint_bp(p, buf+len, p1_x, NULL);
+ buf[len++] = ' ';
+ len += dev_sprint_bp(p, buf+len, p1_y, NULL);
+ buf[len++] = ' ';
+ buf[len++] = 'l';
+ buf[len++] = ' ';
+ buf[len++] = 'S';
+
+ return len;
+}
+
+/* Not optimized. */
+#define PDF_LINE_THICKNESS_MAX 5.0
+void
+pdf_dev_set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
+{
+ pdf_dev *p = current_device();
+ int len = 0;
+ double width_in_bp;
+
+ pdf_dev_graphics_mode(p);
+
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'q';
+ p->format_buffer[len++] = ' ';
+ /* Don't use too thick line. */
+ width_in_bp = ((width < height) ? width : height) * p->unit.dvi2pts;
+ if (width_in_bp < 0.0 || /* Shouldn't happen */
+ width_in_bp > PDF_LINE_THICKNESS_MAX) {
+ pdf_rect rect;
+
+ rect.llx = p->unit.dvi2pts * xpos;
+ rect.lly = p->unit.dvi2pts * ypos;
+ rect.urx = p->unit.dvi2pts * width;
+ rect.ury = p->unit.dvi2pts * height;
+ len += pdf_dev_sprint_rect(p, p->format_buffer+len, &rect);
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'r';
+ p->format_buffer[len++] = 'e';
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'f';
+ } else {
+ if (width > height) {
+ /* NOTE:
+ * A line width of 0 denotes the thinnest line that can be rendered at
+ * device resolution. See, PDF Reference Manual 4th ed., sec. 4.3.2,
+ * "Details of Graphics State Parameters", p. 185.
+ */
+ if (height < p->unit.min_bp_val) {
+ WARN("Too thin line: height=%ld (%g bp)", height, width_in_bp);
+ WARN("Please consider using \"-d\" option.");
+ }
+ len += dev_sprint_line(p, p->format_buffer+len,
+ height,
+ xpos,
+ ypos + height/2,
+ xpos + width,
+ ypos + height/2);
+ } else {
+ if (width < p->unit.min_bp_val) {
+ WARN("Too thin line: width=%ld (%g bp)", width, width_in_bp);
+ WARN("Please consider using \"-d\" option.");
+ }
+ len += dev_sprint_line(p, p->format_buffer+len,
+ width,
+ xpos + width/2,
+ ypos,
+ xpos + width/2,
+ ypos + height);
+ }
+ }
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'Q';
+ dev_out(p, p->format_buffer, len); /* op: q re f Q */
+}
+
+/* Rectangle in device space coordinate. */
+void
+pdf_dev_set_rect (pdf_rect *rect,
+ spt_t x_user, spt_t y_user,
+ spt_t width, spt_t height, spt_t depth)
+{
+ pdf_dev *p = current_device();
+ double dev_x, dev_y;
+ pdf_coord p0, p1, p2, p3;
+ double min_x, min_y, max_x, max_y;
+
+ dev_x = x_user * p->unit.dvi2pts;
+ dev_y = y_user * p->unit.dvi2pts;
+ if (p->text_state.dir_mode) {
+ p0.x = dev_x - p->unit.dvi2pts * depth;
+ p0.y = dev_y - p->unit.dvi2pts * width;
+ p1.x = dev_x + p->unit.dvi2pts * height;
+ p1.y = p0.y;
+ p2.x = p1.x;
+ p2.y = dev_y;
+ p3.x = p0.x;
+ p3.y = p2.y;
+ } else {
+ p0.x = dev_x;
+ p0.y = dev_y - p->unit.dvi2pts * depth;
+ p1.x = dev_x + p->unit.dvi2pts * width;
+ p1.y = p0.y;
+ p2.x = p1.x;
+ p2.y = dev_y + p->unit.dvi2pts * height;
+ p3.x = p0.x;
+ p3.y = p2.y;
+ }
+
+ pdf_dev_transform(&p0, NULL); /* currentmatrix */
+ pdf_dev_transform(&p1, NULL);
+ pdf_dev_transform(&p2, NULL);
+ pdf_dev_transform(&p3, NULL);
+
+ min_x = MIN(p0.x , p1.x);
+ min_x = MIN(min_x, p2.x);
+ min_x = MIN(min_x, p3.x);
+
+ max_x = MAX(p0.x , p1.x);
+ max_x = MAX(max_x, p2.x);
+ max_x = MAX(max_x, p3.x);
+
+ min_y = MIN(p0.y , p1.y);
+ min_y = MIN(min_y, p2.y);
+ min_y = MIN(min_y, p3.y);
+
+ max_y = MAX(p0.y , p1.y);
+ max_y = MAX(max_y, p2.y);
+ max_y = MAX(max_y, p3.y);
+
+ rect->llx = min_x;
+ rect->lly = min_y;
+ rect->urx = max_x;
+ rect->ury = max_y;
+
+ return;
+}
+
+int
+pdf_dev_get_dirmode (void)
+{
+ pdf_dev *p = current_device();
+ return p->text_state.dir_mode;
+}
+
+void
+pdf_dev_set_dirmode (int text_dir)
+{
+ pdf_dev *p = current_device();
+ struct dev_font *font;
+ int text_rotate;
+ int vert_dir, vert_font;
+
+ font = CURRENTFONT(p);
+
+ vert_font = (font && font->wmode) ? 1 : 0;
+ if (p->param.autorotate) {
+ vert_dir = text_dir;
+ } else {
+ vert_dir = vert_font;
+ }
+ text_rotate = (vert_font << 2)|vert_dir;
+
+ if (font &&
+ ANGLE_CHANGES(text_rotate, p->text_state.matrix.rotate)) {
+ p->text_state.force_reset = 1;
+ }
+
+ p->text_state.matrix.rotate = text_rotate;
+ p->text_state.dir_mode = text_dir;
+}
+
+static void
+dev_set_param_autorotate (pdf_dev *p, int auto_rotate)
+{
+ struct dev_font *font;
+ int text_rotate, vert_font, vert_dir;
+
+ ASSERT(p);
+
+ font = CURRENTFONT(p);
+
+ vert_font = (font && font->wmode) ? 1 : 0;
+ if (auto_rotate) {
+ vert_dir = p->text_state.dir_mode;
+ } else {
+ vert_dir = vert_font;
+ }
+ text_rotate = (vert_font << 2)|vert_dir;
+
+ if (ANGLE_CHANGES(text_rotate, p->text_state.matrix.rotate)) {
+ p->text_state.force_reset = 1;
+ }
+ p->text_state.matrix.rotate = text_rotate;
+ p->param.autorotate = auto_rotate;
+}
+
+int
+pdf_dev_get_param (int param_type)
+{
+ pdf_dev *p = current_device();
+ int value = 0;
+
+ switch (param_type) {
+ case PDF_DEV_PARAM_AUTOROTATE:
+ value = p->param.autorotate;
+ break;
+ case PDF_DEV_PARAM_COLORMODE:
+ value = p->param.colormode;
+ break;
+ default:
+ ERROR("Unknown device parameter: %d", param_type);
+ }
+
+ return value;
+}
+
+void
+pdf_dev_set_param (int param_type, int value)
+{
+ pdf_dev *p = current_device();
+
+ switch (param_type) {
+ case PDF_DEV_PARAM_AUTOROTATE:
+ dev_set_param_autorotate(p, value);
+ break;
+ case PDF_DEV_PARAM_COLORMODE:
+ p->param.colormode = value; /* 0 for B&W */
+ break;
+ default:
+ ERROR("Unknown device parameter: %d", param_type);
+ }
+
+ return;
+}
+
+
+/* rect returned */
+int
+pdf_dev_put_image (int id, transform_info *ti, double ref_x, double ref_y, pdf_rect *rect)
+{
+ pdf_dev *p = current_device();
+ char *res_name;
+ pdf_tmatrix M, M1;
+ pdf_rect r;
+ int len = 0;
+
+ pdf_copymatrix(&M, &(ti->matrix));
+ M.e += ref_x; M.f += ref_y;
+ /* Just rotate by -90, but not tested yet. Any problem if M has scaling? */
+ if (p->param.autorotate &&
+ p->text_state.dir_mode) {
+ double tmp;
+ tmp = -M.a; M.a = M.b; M.b = tmp;
+ tmp = -M.c; M.c = M.d; M.d = tmp;
+ }
+
+ pdf_dev_graphics_mode(p);
+ pdf_dev_gsave();
+
+ pdf_ximage_scale_image(id, &M1, &r, ti);
+ pdf_concatmatrix(&M, &M1);
+ pdf_dev_concat(&M);
+
+ /* Clip */
+ if (ti->flags & INFO_DO_CLIP) {
+ pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly);
+ }
+
+ res_name = pdf_ximage_get_resname(id);
+ {
+ char *buf;
+
+ buf = NEW(strlen(res_name)+6, char);
+ len = sprintf(buf, " /%s Do", res_name);
+ dev_out(p, buf, len); /* op: Do */
+ RELEASE(buf);
+ }
+ if (rect) {
+ pdf_rect r1;
+
+ /* Sorry for ugly code. */
+ pdf_dev_set_rect(&r1,
+ bpt2spt(p, r.llx), bpt2spt(p, r.lly),
+ bpt2spt(p, r.urx - r.llx), bpt2spt(p, r.ury - r.lly), 0);
+ rect->llx = r1.llx; rect->lly = r1.lly;
+ rect->urx = r1.urx; rect->ury = r1.ury;
+ }
+
+ pdf_dev_grestore();
+
+ pdf_doc_add_page_resource("XObject",
+ res_name,
+ pdf_ximage_get_reference(id));
+
+ return 0;
+}
+
+void
+transform_info_clear (transform_info *info)
+{
+ /* Physical dimensions */
+ info->width = 0.0;
+ info->height = 0.0;
+ info->depth = 0.0;
+
+ info->bbox.llx = 0.0;
+ info->bbox.lly = 0.0;
+ info->bbox.urx = 0.0;
+ info->bbox.ury = 0.0;
+
+ /* Transformation matrix */
+ pdf_setmatrix(&(info->matrix), 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+
+ info->flags = 0;
+}
+
+void
+pdf_dev_begin_actualtext (uint16_t *unicodes, int count)
+{
+ pdf_dev *p = current_device();
+ int len, i, pdf_doc_enc = 1;
+
+ /* check whether we can use PDFDocEncoding for this string
+ (we punt on the 0x80..0xA0 range that does not directly correspond to unicode) */
+ for (i = 0; i < count; i++) {
+ if (unicodes[i] > 0xff || (unicodes[i] > 0x7f && unicodes[i] < 0xa1)) {
+ pdf_doc_enc = 0;
+ break;
+ }
+ }
+
+ pdf_dev_graphics_mode(p);
+
+ dev_out(p, "\n/Span << /ActualText (", 23);
+ if (!pdf_doc_enc)
+ dev_out(p, "\xFE\xFF", 2);
+
+ while (count-- > 0) {
+ unsigned char s[2] = { *unicodes >> 8, *unicodes & 0xff };
+ char buf[32];
+ i = pdf_doc_enc; /* if using PDFDocEncoding, we only care about the low 8 bits,
+ so start with the second byte of our pair */
+ len = 0;
+ for (; i < 2; i++) {
+ unsigned char c = s[i];
+ if (c == '(' || c == ')' || c == '\\') {
+ len += sprintf(buf + len, "\\%c", c);
+ } else if (c < ' ') {
+ len += sprintf(buf + len, "\\%03o", c);
+ } else {
+ len += sprintf(buf + len, "%c", c);
+ }
+ }
+ dev_out(p, buf, len);
+ ++unicodes;
+ }
+
+ dev_out(p, ") >> BDC", 8);
+}
+
+void
+pdf_dev_end_actualtext (void)
+{
+ pdf_dev *p = current_device();
+
+ pdf_dev_graphics_mode(p);
+
+ dev_out(p, " EMC", 4);
+}
+
+/* Compatibility functions.... For other files still using old interface */
+void
+graphics_mode (void)
+{
+ pdf_dev *p = current_device();
+
+ pdf_dev_graphics_mode(p);
+}
+
+double
+dev_unit_dviunit (void)
+{
+ pdf_dev *p = current_device();
+ return pdf_dev_unit_dviunit(p);
+}
+
+int
+pdf_sprint_matrix (char *buf, const pdf_tmatrix *M)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_matrix(p, buf, M);
+}
+
+int
+pdf_sprint_rect (char *buf, const pdf_rect *rect)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_rect(p, buf, rect);
+}
+
+int
+pdf_sprint_coord (char *buf, const pdf_coord *c)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_coord(p, buf, c);
+}
+
+int
+pdf_sprint_length (char *buf, double value)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_length(p, buf, value);
+}
+
+int
+pdf_sprint_number (char *buf, double value)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_number(p, buf, value);
+}
+
+/* Access text state parameters. */
+int
+pdf_dev_get_font_wmode (int font_id)
+{
+ pdf_dev *p = current_device();
+ struct dev_font *font;
+
+ font = GET_FONT(p, font_id);
+ if (font) {
+ return font->wmode;
+ }
+
+ return 0;
+}
+
+int
+pdf_dev_font_minbytes (int font_id)
+{
+ pdf_dev *p = current_device();
+ struct dev_font *font;
+ int minbytes = 1;
+
+ font = GET_FONT(p, font_id);
+ if (font && font->format == PDF_FONTTYPE_COMPOSITE) {
+ CMap *cmap;
+
+ cmap = CMap_cache_get(font->enc_id);
+ minbytes = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN);
+ }
+
+ return minbytes;
+}
diff --git a/Build/source/texk/dvipdfm-x/pdfdev.h b/Build/source/texk/dvipdfm-x/pdfdev.h
new file mode 100644
index 00000000000..7750e432b29
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfdev.h
@@ -0,0 +1,178 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFDEV_H_
+#define _PDFDEV_H_
+
+#include "numbers.h"
+#include "pdfobj.h"
+#include "pdfcolor.h"
+
+typedef struct pdf_dev pdf_dev;
+
+typedef int spt_t;
+
+typedef struct pdf_tmatrix
+{
+ double a, b, c, d, e, f;
+} pdf_tmatrix;
+
+typedef struct pdf_rect
+{
+ double llx, lly, urx, ury;
+} pdf_rect;
+
+typedef struct pdf_coord
+{
+ double x, y;
+} pdf_coord;
+
+/* The name transform_info is misleading.
+ * I'll put this here for a moment...
+ */
+typedef struct
+{
+ /* Physical dimensions
+ *
+ * If those values are given, images will be scaled
+ * and/or shifted to fit within a box described by
+ * those values.
+ */
+ double width;
+ double height;
+ double depth;
+
+ pdf_tmatrix matrix; /* transform matrix */
+ pdf_rect bbox; /* user_bbox */
+
+ int flags;
+} transform_info;
+#define INFO_HAS_USER_BBOX (1 << 0)
+#define INFO_HAS_WIDTH (1 << 1)
+#define INFO_HAS_HEIGHT (1 << 2)
+#define INFO_DO_CLIP (1 << 3)
+#define INFO_DO_HIDE (1 << 4)
+extern void transform_info_clear (transform_info *info);
+
+/* Not in spt_t. */
+extern int pdf_sprint_matrix (char *buf, const pdf_tmatrix *p);
+extern int pdf_sprint_rect (char *buf, const pdf_rect *p);
+extern int pdf_sprint_coord (char *buf, const pdf_coord *p);
+extern int pdf_sprint_length (char *buf, double value);
+extern int pdf_sprint_number (char *buf, double value);
+
+/* unit_conv: multiplier for input unit (spt_t) to bp conversion.
+ * precision: How many fractional digits preserved in output (not real
+ * accuracy control).
+ * is_bw: Ignore color related special instructions.
+ */
+extern void pdf_init_device (double unit_conv, int precision, int is_bw);
+extern void pdf_close_device (void);
+
+/* returns 1.0/unit_conv */
+extern double dev_unit_dviunit (void);
+
+/* Draw texts and rules:
+ *
+ * xpos, ypos, width, and height are all fixed-point numbers
+ * converted to big-points by multiplying unit_conv (dvi2pts).
+ * They must be position in the user space.
+ *
+ * ctype:
+ * 0 - input string is in multi-byte encoding.
+ * 1 - input string is in 8-bit encoding.
+ * 2 - input string is in 16-bit encoding.
+ */
+extern void pdf_dev_set_string (spt_t xpos, spt_t ypos,
+ const void *instr_ptr, int instr_len,
+ spt_t text_width, int font_id);
+extern void pdf_dev_set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height);
+
+/* Place XObject: rect returned */
+extern int pdf_dev_put_image (int xobj_id, transform_info *p, double ref_x, double ref_y, pdf_rect *rect);
+
+/* The design_size and ptsize required by PK font support...
+ */
+extern int pdf_dev_locate_font (const char *font_name, spt_t ptsize);
+
+/* The following two routines are NOT WORKING.
+ * Dvipdfmx doesn't manage gstate well..
+ */
+#define pdf_dev_scale() (1.0)
+
+/* Access text state parameters. */
+extern int pdf_dev_get_font_wmode (int font_id); /* ps: special support want this (pTeX). */
+
+/* Text composition (direction) mode
+ * This affects only when auto_rotate is enabled.
+ */
+extern int pdf_dev_get_dirmode (void);
+extern void pdf_dev_set_dirmode (int dir_mode);
+
+/* Set rect to rectangle in device space.
+ * Unit conversion spt_t to bp and transformation applied within it.
+ */
+extern void pdf_dev_set_rect (pdf_rect *rect,
+ spt_t x_pos, spt_t y_pos,
+ spt_t width, spt_t height, spt_t depth);
+
+/* Accessor to various device parameters.
+ */
+#define PDF_DEV_PARAM_AUTOROTATE 1
+#define PDF_DEV_PARAM_COLORMODE 2
+
+extern int pdf_dev_get_param (int param_type);
+extern void pdf_dev_set_param (int param_type, int value);
+
+/* Text composition mode is ignored (always same as font's
+ * writing mode) and glyph rotation is not enabled if
+ * auto_rotate is unset.
+ */
+#define pdf_dev_set_autorotate(v) pdf_dev_set_param(PDF_DEV_PARAM_AUTOROTATE, (v))
+
+/*
+ * For pdf_doc, pdf_draw and others.
+ */
+
+/* Force reselecting font and color:
+ * XFrom (content grabbing) and Metapost support want them.
+ */
+extern void pdf_dev_reset_fonts (int newpage);
+extern void pdf_dev_reset_color (int force);
+
+/* Initialization of transformation matrix with M and others.
+ * They are called within pdf_doc_begin_page() and pdf_doc_end_page().
+ */
+extern void pdf_dev_bop (const pdf_tmatrix *M);
+extern void pdf_dev_eop (void);
+
+/* Text is normal and line art is not normal in dvipdfmx. So we don't have
+ * begin_text (BT in PDF) and end_text (ET), but instead we have graphics_mode()
+ * to terminate text section. pdf_dev_flushpath() and others call this.
+ */
+extern void graphics_mode (void);
+
+extern void pdf_dev_begin_actualtext (uint16_t *unicodes, int len);
+extern void pdf_dev_end_actualtext (void);
+
+extern int pdf_dev_font_minbytes (int font_id);
+#endif /* _PDFDEV_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfdoc.c b/Build/source/texk/dvipdfm-x/pdfdoc.c
new file mode 100644
index 00000000000..75ed8179dde
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfdoc.c
@@ -0,0 +1,2878 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * TODO: Many things...
+ * {begin,end}_{bead,article}, box stack, name tree (not limited to dests)...
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+#include "dpxconf.h"
+
+#include "numbers.h"
+
+#include "pdfobj.h"
+#include "pdfparse.h"
+#include "pdfnames.h"
+
+#include "pdfencrypt.h"
+
+#include "dvipdfmx.h"
+
+#include "pdfdev.h"
+#include "pdfdraw.h"
+#include "pdfcolor.h"
+
+#include "pdfresource.h"
+#include "pdffont.h"
+#include "pdfximage.h"
+
+#include "pdflimits.h"
+
+#if HAVE_LIBPNG
+#include "pngimage.h"
+#endif
+#include "jpegimage.h"
+
+#include "pdfdoc.h"
+
+#define PDFDOC_PAGES_ALLOC_SIZE 128u
+#define PDFDOC_ARTICLE_ALLOC_SIZE 16
+#define PDFDOC_BEAD_ALLOC_SIZE 16
+
+static pdf_obj *
+read_thumbnail (const char *thumb_filename)
+{
+ pdf_obj *image_ref;
+ int xobj_id;
+ FILE *fp;
+ load_options options = {1, 0, NULL};
+
+ fp = MFOPEN(thumb_filename, FOPEN_RBIN_MODE);
+ if (!fp) {
+ WARN("Could not open thumbnail file \"%s\"", thumb_filename);
+ return NULL;
+ }
+ if (!check_for_png(fp) && !check_for_jpeg(fp)) {
+ WARN("Thumbnail \"%s\" not a png/jpeg file!", thumb_filename);
+ MFCLOSE(fp);
+ return NULL;
+ }
+ MFCLOSE(fp);
+
+ xobj_id = pdf_ximage_load_image(thumb_filename, thumb_filename, options);
+ if (xobj_id < 0) {
+ WARN("Could not read thumbnail file \"%s\".", thumb_filename);
+ image_ref = NULL;
+ } else {
+ image_ref = pdf_ximage_get_reference(xobj_id);
+ }
+
+ return image_ref;
+}
+
+/* Sorry no appropriate place to put this... */
+struct ht_table *global_names = NULL;
+
+typedef struct pdf_form
+{
+ char *ident;
+
+ pdf_tmatrix matrix;
+ pdf_rect cropbox;
+
+ pdf_obj *resources;
+ pdf_obj *contents;
+} pdf_form;
+
+struct form_list_node
+{
+ int q_depth;
+ pdf_form form;
+
+ struct form_list_node *prev;
+};
+
+#define USE_MY_MEDIABOX (1 << 0)
+typedef struct pdf_page
+{
+ pdf_obj *page_obj;
+ pdf_obj *page_ref;
+
+ int flags;
+
+ double ref_x, ref_y;
+ pdf_rect cropbox;
+
+ pdf_obj *resources;
+
+ /* Contents */
+ pdf_obj *background;
+ pdf_obj *contents;
+
+ /* global bop, background, contents, global eop */
+ pdf_obj *content_refs[4];
+
+ pdf_obj *annots;
+ pdf_obj *beads;
+} pdf_page;
+
+typedef struct pdf_olitem
+{
+ pdf_obj *dict;
+
+ int is_open;
+
+ struct pdf_olitem *first;
+ struct pdf_olitem *parent;
+
+ struct pdf_olitem *next;
+} pdf_olitem;
+
+typedef struct pdf_bead
+{
+ char *id;
+ int page_no;
+ pdf_rect rect;
+} pdf_bead;
+
+typedef struct pdf_article
+{
+ char *id;
+ pdf_obj *info;
+ int num_beads;
+ int max_beads;
+ pdf_bead *beads;
+} pdf_article;
+
+struct name_dict
+{
+ const char *category;
+ struct ht_table *data;
+};
+
+
+typedef struct pdf_doc
+{
+ struct {
+ pdf_obj *dict;
+
+ pdf_obj *viewerpref;
+ pdf_obj *pagelabels;
+ pdf_obj *pages;
+ pdf_obj *names;
+ pdf_obj *threads;
+ } root;
+
+ pdf_obj *info;
+
+ struct {
+ pdf_rect mediabox;
+ pdf_obj *bop, *eop;
+
+ int num_entries; /* This is not actually total number of pages. */
+ int max_entries;
+ pdf_page *entries;
+ } pages;
+
+ struct {
+ pdf_olitem *first;
+ pdf_olitem *current;
+ int current_depth;
+ } outlines;
+
+ struct {
+ int num_entries;
+ int max_entries;
+ pdf_article *entries;
+ } articles;
+
+ struct name_dict *names;
+
+ int check_gotos;
+ struct ht_table gotos;
+
+ struct {
+ int outline_open_depth;
+ struct {
+ double x, y;
+ } annot_grow;
+ int enable_manual_thumb;
+ } options;
+
+ struct form_list_node *pending_forms;
+
+ char *thumb_basename;
+} pdf_doc;
+static pdf_doc pdoc;
+
+static void
+pdf_doc_init_catalog (pdf_doc *p)
+{
+ p->root.viewerpref = NULL;
+ p->root.pagelabels = NULL;
+ p->root.pages = NULL;
+ p->root.names = NULL;
+ p->root.threads = NULL;
+
+ p->root.dict = pdf_new_dict();
+ pdf_set_root(p->root.dict);
+
+ return;
+}
+
+static void
+pdf_doc_close_catalog (pdf_doc *p)
+{
+ pdf_obj *tmp;
+
+ if (p->root.viewerpref) {
+ tmp = pdf_lookup_dict(p->root.dict, "ViewerPreferences");
+ if (!tmp) {
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("ViewerPreferences"),
+ pdf_ref_obj (p->root.viewerpref));
+ } else if (PDF_OBJ_DICTTYPE(tmp)) {
+ pdf_merge_dict(p->root.viewerpref, tmp);
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("ViewerPreferences"),
+ pdf_ref_obj (p->root.viewerpref));
+ } else { /* Maybe reference */
+ /* What should I do? */
+ WARN("Could not modify ViewerPreferences.");
+ }
+ pdf_release_obj(p->root.viewerpref);
+ p->root.viewerpref = NULL;
+ }
+
+ if (p->root.pagelabels) {
+ tmp = pdf_lookup_dict(p->root.dict, "PageLabels");
+ if (!tmp) {
+ tmp = pdf_new_dict();
+ pdf_add_dict(tmp, pdf_new_name("Nums"), pdf_link_obj(p->root.pagelabels));
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("PageLabels"), pdf_ref_obj(tmp));
+ pdf_release_obj(tmp);
+ } else { /* Maybe reference */
+ /* What should I do? */
+ WARN("Could not modify PageLabels.");
+ }
+ pdf_release_obj(p->root.pagelabels);
+ p->root.pagelabels = NULL;
+ }
+
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("Type"), pdf_new_name("Catalog"));
+ pdf_release_obj(p->root.dict);
+ p->root.dict = NULL;
+
+ return;
+}
+
+/*
+ * Pages are starting at 1.
+ * The page count does not increase until the page is finished.
+ */
+#define LASTPAGE(p) (&(p->pages.entries[p->pages.num_entries]))
+#define FIRSTPAGE(p) (&(p->pages.entries[0]))
+#define PAGECOUNT(p) (p->pages.num_entries)
+#define MAXPAGES(p) (p->pages.max_entries)
+
+static void
+doc_resize_page_entries (pdf_doc *p, int size)
+{
+ if (size > MAXPAGES(p)) {
+ int i;
+
+ p->pages.entries = RENEW(p->pages.entries, size, struct pdf_page);
+ for (i = p->pages.max_entries; i < size; i++) {
+ p->pages.entries[i].page_obj = NULL;
+ p->pages.entries[i].page_ref = NULL;
+ p->pages.entries[i].flags = 0;
+ p->pages.entries[i].resources = NULL;
+ p->pages.entries[i].background = NULL;
+ p->pages.entries[i].contents = NULL;
+ p->pages.entries[i].content_refs[0] = NULL; /* global bop */
+ p->pages.entries[i].content_refs[1] = NULL; /* background */
+ p->pages.entries[i].content_refs[2] = NULL; /* page body */
+ p->pages.entries[i].content_refs[3] = NULL; /* global eop */
+ p->pages.entries[i].annots = NULL;
+ p->pages.entries[i].beads = NULL;
+ }
+ p->pages.max_entries = size;
+ }
+
+ return;
+}
+
+static pdf_page *
+doc_get_page_entry (pdf_doc *p, unsigned int page_no)
+{
+ pdf_page *page;
+
+ if (page_no > 65535ul) {
+ ERROR("Page number %ul too large!", page_no);
+ } else if (page_no == 0) {
+ ERROR("Invalid Page number %ul.", page_no);
+ }
+
+ if (page_no > MAXPAGES(p)) {
+ doc_resize_page_entries(p, page_no + PDFDOC_PAGES_ALLOC_SIZE);
+ }
+
+ page = &(p->pages.entries[page_no - 1]);
+
+ return page;
+}
+
+static void pdf_doc_init_page_tree (pdf_doc *p, double media_width, double media_height);
+static void pdf_doc_close_page_tree (pdf_doc *p);
+
+static void pdf_doc_init_names (pdf_doc *p, int check_gotos);
+static void pdf_doc_close_names (pdf_doc *p);
+
+static void pdf_doc_add_goto (pdf_obj *annot_dict);
+
+static void pdf_doc_init_docinfo (pdf_doc *p);
+static void pdf_doc_close_docinfo (pdf_doc *p);
+
+static void pdf_doc_init_articles (pdf_doc *p);
+static void pdf_doc_close_articles (pdf_doc *p);
+static void pdf_doc_init_bookmarks (pdf_doc *p, int bm_open_depth);
+static void pdf_doc_close_bookmarks (pdf_doc *p);
+
+void
+pdf_doc_set_bop_content (const char *content, unsigned length)
+{
+ pdf_doc *p = &pdoc;
+
+ ASSERT(p);
+
+ if (p->pages.bop) {
+ pdf_release_obj(p->pages.bop);
+ p->pages.bop = NULL;
+ }
+
+ if (length > 0) {
+ p->pages.bop = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_stream(p->pages.bop, content, length);
+ } else {
+ p->pages.bop = NULL;
+ }
+
+ return;
+}
+
+void
+pdf_doc_set_eop_content (const char *content, unsigned length)
+{
+ pdf_doc *p = &pdoc;
+
+ if (p->pages.eop) {
+ pdf_release_obj(p->pages.eop);
+ p->pages.eop = NULL;
+ }
+
+ if (length > 0) {
+ p->pages.eop = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_stream(p->pages.eop, content, length);
+ } else {
+ p->pages.eop = NULL;
+ }
+
+ return;
+}
+
+static void
+pdf_doc_init_docinfo (pdf_doc *p)
+{
+ p->info = pdf_new_dict();
+ pdf_set_info(p->info);
+
+ return;
+}
+
+static void
+pdf_doc_close_docinfo (pdf_doc *p)
+{
+ pdf_obj *docinfo = p->info;
+
+ /*
+ * Excerpt from PDF Reference 4th ed., sec. 10.2.1.
+ *
+ * Any entry whose value is not known should be omitted from the dictionary,
+ * rather than included with an empty string as its value.
+ *
+ * ....
+ *
+ * Note: Although viewer applications can store custom metadata in the document
+ * information dictionary, it is inappropriate to store private content or
+ * structural information there; such information should be stored in the
+ * document catalog instead (see Section 3.6.1, Document Catalog ).
+ */
+ const char *keys[] = {
+ "Title", "Author", "Subject", "Keywords", "Creator", "Producer",
+ "CreationDate", "ModDate", /* Date */
+ NULL
+ };
+ pdf_obj *value;
+ int i;
+
+ for (i = 0; keys[i] != NULL; i++) {
+ value = pdf_lookup_dict(docinfo, keys[i]);
+ if (value) {
+ if (!PDF_OBJ_STRINGTYPE(value)) {
+ WARN("\"%s\" in DocInfo dictionary not string type.", keys[i]);
+ pdf_remove_dict(docinfo, keys[i]);
+ WARN("\"%s\" removed from DocInfo.", keys[i]);
+ } else if (pdf_string_length(value) == 0) {
+ /* The hyperref package often uses emtpy strings. */
+ pdf_remove_dict(docinfo, keys[i]);
+ }
+ }
+ }
+
+ if (!pdf_lookup_dict(docinfo, "Producer")) {
+ char *banner;
+
+ banner = NEW(strlen(my_name)+strlen(VERSION)+4, char);
+ sprintf(banner, "%s (%s)", my_name, VERSION);
+ pdf_add_dict(docinfo,
+ pdf_new_name("Producer"),
+ pdf_new_string(banner, strlen(banner)));
+ RELEASE(banner);
+ }
+
+ if (!pdf_lookup_dict(docinfo, "CreationDate")) {
+ char now[32];
+
+ dpx_util_format_asn_date(now, 1);
+ pdf_add_dict(docinfo,
+ pdf_new_name ("CreationDate"),
+ pdf_new_string(now, strlen(now)));
+ }
+
+ pdf_release_obj(docinfo);
+ p->info = NULL;
+
+ return;
+}
+
+static pdf_obj *
+pdf_doc_get_page_resources (pdf_doc *p, const char *category)
+{
+ pdf_obj *resources;
+ pdf_page *currentpage;
+ pdf_obj *res_dict;
+
+ if (!p || !category) {
+ return NULL;
+ }
+
+ if (p->pending_forms) {
+ if (p->pending_forms->form.resources) {
+ res_dict = p->pending_forms->form.resources;
+ } else {
+ res_dict = p->pending_forms->form.resources = pdf_new_dict();
+ }
+ } else {
+ currentpage = LASTPAGE(p);
+ if (currentpage->resources) {
+ res_dict = currentpage->resources;
+ } else {
+ res_dict = currentpage->resources = pdf_new_dict();
+ }
+ }
+ resources = pdf_lookup_dict(res_dict, category);
+ if (!resources) {
+ resources = pdf_new_dict();
+ pdf_add_dict(res_dict, pdf_new_name(category), resources);
+ } else if (pdf_obj_typeof(resources) == PDF_INDIRECT) {
+ resources = pdf_deref_obj(resources); /* FIXME: deref_obj increment link count */
+ if (!resources) {
+ WARN("Resource %s already released?", category);
+ } else {
+ pdf_release_obj(resources); /* FIXME: just to decrement link count */
+ }
+ }
+
+ return resources;
+}
+
+void
+pdf_doc_add_page_resource (const char *category,
+ const char *resource_name, pdf_obj *resource_ref)
+{
+ pdf_doc *p = &pdoc;
+ pdf_obj *resources;
+ pdf_obj *duplicate;
+
+ resources = pdf_doc_get_page_resources(p, category);
+ if (!resources) {
+ WARN("Can't add object to resource %s", category);
+ return;
+ }
+ duplicate = pdf_lookup_dict(resources, resource_name);
+ if (duplicate) {
+ if (pdf_compare_reference(duplicate, resource_ref)) {
+ WARN("Possibly two different resource using the same name... (page: %d, category: %s, name: %s).",
+ pdf_doc_current_page_number(), category, resource_name);
+ WARN("Ignoring...");
+ }
+ pdf_release_obj(resource_ref); /* Discard */
+ } else {
+ pdf_add_dict(resources, pdf_new_name(resource_name), resource_ref);
+ }
+
+ return;
+}
+
+static void
+doc_flush_page (pdf_doc *p, pdf_page *page, pdf_obj *parent_ref)
+{
+ pdf_obj *contents_array;
+ int count;
+
+ pdf_add_dict(page->page_obj,
+ pdf_new_name("Type"), pdf_new_name("Page"));
+ pdf_add_dict(page->page_obj,
+ pdf_new_name("Parent"), parent_ref);
+
+ /*
+ * Clipping area specified by CropBox is affected by MediaBox which
+ * might be inherit from parent node. If MediaBox of the root node
+ * does not have enough size to cover all page's imaging area, using
+ * CropBox here gives incorrect result.
+ */
+ if (page->flags & USE_MY_MEDIABOX) {
+ pdf_obj *mediabox;
+
+ mediabox = pdf_new_array();
+ pdf_add_array(mediabox,
+ pdf_new_number(ROUND(page->cropbox.llx, 0.01)));
+ pdf_add_array(mediabox,
+ pdf_new_number(ROUND(page->cropbox.lly, 0.01)));
+ pdf_add_array(mediabox,
+ pdf_new_number(ROUND(page->cropbox.urx, 0.01)));
+ pdf_add_array(mediabox,
+ pdf_new_number(ROUND(page->cropbox.ury, 0.01)));
+ pdf_add_dict(page->page_obj, pdf_new_name("MediaBox"), mediabox);
+ }
+
+ count = 0;
+ contents_array = pdf_new_array();
+ if (page->content_refs[0]) { /* global bop */
+ pdf_add_array(contents_array, page->content_refs[0]);
+ count++;
+ } else if (p->pages.bop &&
+ pdf_stream_length(p->pages.bop) > 0) {
+ pdf_add_array(contents_array, pdf_ref_obj(p->pages.bop));
+ count++;
+ }
+ if (page->content_refs[1]) { /* background */
+ pdf_add_array(contents_array, page->content_refs[1]);
+ count++;
+ }
+ if (page->content_refs[2]) { /* page body */
+ pdf_add_array(contents_array, page->content_refs[2]);
+ count++;
+ }
+ if (page->content_refs[3]) { /* global eop */
+ pdf_add_array(contents_array, page->content_refs[3]);
+ count++;
+ } else if (p->pages.eop &&
+ pdf_stream_length(p->pages.eop) > 0) {
+ pdf_add_array(contents_array, pdf_ref_obj(p->pages.eop));
+ count++;
+ }
+
+ if (count == 0) {
+ WARN("Page with empty content found!!!");
+ }
+ page->content_refs[0] = NULL;
+ page->content_refs[1] = NULL;
+ page->content_refs[2] = NULL;
+ page->content_refs[3] = NULL;
+
+ pdf_add_dict(page->page_obj,
+ pdf_new_name("Contents"), contents_array);
+
+
+ if (page->annots) {
+ pdf_add_dict(page->page_obj,
+ pdf_new_name("Annots"), pdf_ref_obj(page->annots));
+ pdf_release_obj(page->annots);
+ }
+ if (page->beads) {
+ pdf_add_dict(page->page_obj,
+ pdf_new_name("B"), pdf_ref_obj(page->beads));
+ pdf_release_obj(page->beads);
+ }
+ pdf_release_obj(page->page_obj);
+ pdf_release_obj(page->page_ref);
+
+ page->page_obj = NULL;
+ page->page_ref = NULL;
+ page->annots = NULL;
+ page->beads = NULL;
+
+ return;
+}
+
+/* B-tree? */
+#define PAGE_CLUSTER 4
+static pdf_obj *
+build_page_tree (pdf_doc *p,
+ pdf_page *firstpage, int num_pages,
+ pdf_obj *parent_ref)
+{
+ pdf_obj *self, *self_ref, *kids;
+ int i;
+
+ self = pdf_new_dict();
+ /*
+ * This is a slight kludge which allow the subtree dictionary
+ * generated by this routine to be merged with the real
+ * page_tree dictionary, while keeping the indirect object
+ * references right.
+ */
+ self_ref = parent_ref ? pdf_ref_obj(self) : pdf_ref_obj(p->root.pages);
+
+ pdf_add_dict(self, pdf_new_name("Type"), pdf_new_name("Pages"));
+ pdf_add_dict(self, pdf_new_name("Count"), pdf_new_number((double) num_pages));
+
+ if (parent_ref != NULL)
+ pdf_add_dict(self, pdf_new_name("Parent"), parent_ref);
+
+ kids = pdf_new_array();
+ if (num_pages > 0 && num_pages <= PAGE_CLUSTER) {
+ for (i = 0; i < num_pages; i++) {
+ pdf_page *page;
+
+ page = firstpage + i;
+ if (!page->page_ref)
+ page->page_ref = pdf_ref_obj(page->page_obj);
+ pdf_add_array (kids, pdf_link_obj(page->page_ref));
+ doc_flush_page(p, page, pdf_link_obj(self_ref));
+ }
+ } else if (num_pages > 0) {
+ for (i = 0; i < PAGE_CLUSTER; i++) {
+ int start, end;
+
+ start = (i*num_pages)/PAGE_CLUSTER;
+ end = ((i+1)*num_pages)/PAGE_CLUSTER;
+ if (end - start > 1) {
+ pdf_obj *subtree;
+
+ subtree = build_page_tree(p, firstpage + start, end - start,
+ pdf_link_obj(self_ref));
+ pdf_add_array(kids, pdf_ref_obj(subtree));
+ pdf_release_obj(subtree);
+ } else {
+ pdf_page *page;
+
+ page = firstpage + start;
+ if (!page->page_ref)
+ page->page_ref = pdf_ref_obj(page->page_obj);
+ pdf_add_array (kids, pdf_link_obj(page->page_ref));
+ doc_flush_page(p, page, pdf_link_obj(self_ref));
+ }
+ }
+ }
+ pdf_add_dict(self, pdf_new_name("Kids"), kids);
+ pdf_release_obj(self_ref);
+
+ return self;
+}
+
+static void
+pdf_doc_init_page_tree (pdf_doc *p, double media_width, double media_height)
+{
+ /*
+ * Create empty page tree.
+ * The docroot.pages is kept open until the document is closed.
+ * This allows the user to write to pages if he so choses.
+ */
+ p->root.pages = pdf_new_dict();
+
+ p->pages.num_entries = 0;
+ p->pages.max_entries = 0;
+ p->pages.entries = NULL;
+
+ p->pages.bop = NULL;
+ p->pages.eop = NULL;
+
+ p->pages.mediabox.llx = 0.0;
+ p->pages.mediabox.lly = 0.0;
+ p->pages.mediabox.urx = media_width;
+ p->pages.mediabox.ury = media_height;
+
+ return;
+}
+
+static void
+pdf_doc_close_page_tree (pdf_doc *p)
+{
+ pdf_obj *page_tree_root;
+ pdf_obj *mediabox;
+ int page_no;
+
+ /*
+ * Do consistency check on forward references to pages.
+ */
+ for (page_no = PAGECOUNT(p) + 1; page_no <= MAXPAGES(p); page_no++) {
+ pdf_page *page;
+
+ page = doc_get_page_entry(p, page_no);
+ if (page->page_obj) {
+ WARN("Nonexistent page #%ld refered.", page_no);
+ pdf_release_obj(page->page_ref);
+ page->page_ref = NULL;
+ }
+ if (page->page_obj) {
+ WARN("Entry for a nonexistent page #%ld created.", page_no);
+ pdf_release_obj(page->page_obj);
+ page->page_obj = NULL;
+ }
+ if (page->annots) {
+ WARN("Annotation attached to a nonexistent page #%ld.", page_no);
+ pdf_release_obj(page->annots);
+ page->annots = NULL;
+ }
+ if (page->beads) {
+ WARN("Article beads attached to a nonexistent page #%ld.", page_no);
+ pdf_release_obj(page->beads);
+ page->beads = NULL;
+ }
+ if (page->resources) {
+ pdf_release_obj(page->resources);
+ page->resources = NULL;
+ }
+ }
+
+ /*
+ * Connect page tree to root node.
+ */
+ page_tree_root = build_page_tree(p, FIRSTPAGE(p), PAGECOUNT(p), NULL);
+ pdf_merge_dict (p->root.pages, page_tree_root);
+ pdf_release_obj(page_tree_root);
+
+ /* They must be after build_page_tree() */
+ if (p->pages.bop) {
+ pdf_add_stream (p->pages.bop, "\n", 1);
+ pdf_release_obj(p->pages.bop);
+ p->pages.bop = NULL;
+ }
+ if (p->pages.eop) {
+ pdf_add_stream (p->pages.eop, "\n", 1);
+ pdf_release_obj(p->pages.eop);
+ p->pages.eop = NULL;
+ }
+
+ /* Create media box at root node and let the other pages inherit it. */
+ mediabox = pdf_new_array();
+ pdf_add_array(mediabox, pdf_new_number(ROUND(p->pages.mediabox.llx, 0.01)));
+ pdf_add_array(mediabox, pdf_new_number(ROUND(p->pages.mediabox.lly, 0.01)));
+ pdf_add_array(mediabox, pdf_new_number(ROUND(p->pages.mediabox.urx, 0.01)));
+ pdf_add_array(mediabox, pdf_new_number(ROUND(p->pages.mediabox.ury, 0.01)));
+ pdf_add_dict(p->root.pages, pdf_new_name("MediaBox"), mediabox);
+
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("Pages"),
+ pdf_ref_obj (p->root.pages));
+ pdf_release_obj(p->root.pages);
+ p->root.pages = NULL;
+
+ RELEASE(p->pages.entries);
+ p->pages.entries = NULL;
+ p->pages.num_entries = 0;
+ p->pages.max_entries = 0;
+
+ return;
+}
+
+int
+pdf_doc_get_page_count (pdf_file *pf)
+{
+ int count = 0;
+ pdf_obj *page_tree = NULL;
+ pdf_obj *catalog;
+
+ catalog = pdf_file_get_catalog(pf);
+
+ page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages"));
+
+ if (!PDF_OBJ_DICTTYPE(page_tree)) {
+ return 0;
+ }
+
+ {
+ pdf_obj *tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count"));
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ if (tmp)
+ pdf_release_obj(tmp);
+ return 0;
+ }
+ count = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ }
+
+ return count;
+}
+
+static int
+set_bounding_box (pdf_rect *bbox, enum pdf_page_boundary opt_bbox,
+ pdf_obj *media_box, pdf_obj *crop_box,
+ pdf_obj *art_box, pdf_obj *trim_box, pdf_obj *bleed_box)
+{
+ pdf_obj *box = NULL;
+
+ if (!media_box) {
+ WARN("MediaBox not found in included PDF...");
+ return -1;
+ }
+#define VALIDATE_BOX(o) if ((o)) {\
+ if (!PDF_OBJ_ARRAYTYPE((o)) || pdf_array_length((o)) != 4) \
+ return -1;\
+}
+ VALIDATE_BOX(media_box);
+ VALIDATE_BOX(crop_box);
+ VALIDATE_BOX(art_box);
+ VALIDATE_BOX(trim_box);
+ VALIDATE_BOX(bleed_box);
+
+ if (opt_bbox == pdf_page_boundary__auto) {
+ if (crop_box)
+ box = pdf_link_obj(crop_box);
+ else if (art_box)
+ box = pdf_link_obj(art_box);
+ else if (trim_box)
+ box = pdf_link_obj(trim_box);
+ else if (bleed_box)
+ box = pdf_link_obj(bleed_box);
+ else {
+ box = pdf_link_obj(media_box);
+ }
+ } else {
+ if (!crop_box) {
+ crop_box = pdf_link_obj(media_box);
+ }
+ if (!art_box) {
+ art_box = pdf_link_obj(crop_box);
+ }
+ if (!trim_box) {
+ trim_box = pdf_link_obj(crop_box);
+ }
+ if (!bleed_box) {
+ bleed_box = pdf_link_obj(crop_box);
+ }
+ /* At this point all boxes must be defined. */
+ switch (opt_bbox) {
+ case pdf_page_boundary_cropbox:
+ box = pdf_link_obj(crop_box);
+ break;
+ case pdf_page_boundary_mediabox:
+ box = pdf_link_obj(media_box);
+ break;
+ case pdf_page_boundary_artbox:
+ box = pdf_link_obj(art_box);
+ break;
+ case pdf_page_boundary_trimbox:
+ box = pdf_link_obj(trim_box);
+ break;
+ case pdf_page_boundary_bleedbox:
+ box = pdf_link_obj(bleed_box);
+ break;
+ default:
+ box = pdf_link_obj(crop_box);
+ break;
+ }
+ }
+
+ if (!box) {
+ /* Impossible */
+ WARN("No appropriate page boudary box found???");
+ return -1;
+ } else {
+ int i;
+
+ for (i = 4; i--; ) {
+ double x;
+ pdf_obj *tmp = pdf_deref_obj(pdf_get_array(box, i));
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ pdf_release_obj(tmp);
+ pdf_release_obj(box);
+ return -1;
+ }
+ x = pdf_number_value(tmp);
+ switch (i) {
+ case 0: bbox->llx = x; break;
+ case 1: bbox->lly = x; break;
+ case 2: bbox->urx = x; break;
+ case 3: bbox->ury = x; break;
+ }
+ pdf_release_obj(tmp);
+ }
+
+ /* New scheme only for XDV files */
+ if (dpx_conf.compat_mode == dpx_mode_xdv_mode ||
+ opt_bbox != pdf_page_boundary__auto) {
+ for (i = 4; i--; ) {
+ double x;
+ pdf_obj *tmp = pdf_deref_obj(pdf_get_array(media_box, i));
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ pdf_release_obj(tmp);
+ pdf_release_obj(box);
+ return -1;
+ }
+ x = pdf_number_value(tmp);
+ switch (i) {
+ case 0: if (bbox->llx < x) bbox->llx = x; break;
+ case 1: if (bbox->lly < x) bbox->lly = x; break;
+ case 2: if (bbox->urx > x) bbox->urx = x; break;
+ case 3: if (bbox->ury > x) bbox->ury = x; break;
+ }
+ pdf_release_obj(tmp);
+ }
+ }
+ }
+ pdf_release_obj(box);
+
+ return 0;
+}
+
+static int
+set_transform_matrix (pdf_tmatrix *matrix, pdf_rect *bbox, pdf_obj *rotate)
+{
+ double deg;
+ int rot;
+
+ matrix->a = matrix->d = 1.0;
+ matrix->b = matrix->c = 0.0;
+ matrix->e = matrix->f = 0.0;
+ /* Handle Rotate */
+ if (rotate) {
+ if (!PDF_OBJ_NUMBERTYPE(rotate)) {
+ return -1;
+ } else {
+ deg = pdf_number_value(rotate);
+ if (deg - (int)deg != 0.0) {
+ WARN("Invalid value specified for /Rotate: %f", deg);
+ return -1;
+ } else if (deg != 0.0) {
+ rot = (int) deg;
+ if (rot % 90 != 0.0) {
+ WARN("Invalid value specified for /Rotate: %f", deg);
+ } else {
+ rot = rot % 360;
+ if (rot < 0) rot += 360;
+ switch (rot) {
+ case 90:
+ matrix->a = matrix->d = 0;
+ matrix->b = -1;
+ matrix->c = 1;
+ matrix->e = bbox->llx - bbox->lly;
+ matrix->f = bbox->lly + bbox->urx;
+ break;
+ case 180:
+ matrix->a = matrix->d = -1;
+ matrix->b = matrix->c = 0;
+ matrix->e = bbox->llx + bbox->urx;
+ matrix->f = bbox->lly + bbox->ury;
+ break;
+ case 270:
+ matrix->a = matrix->d = 0;
+ matrix->b = 1;
+ matrix->c = -1;
+ matrix->e = bbox->llx + bbox->ury;
+ matrix->f = bbox->lly - bbox->llx;
+ break;
+ default:
+ WARN("Invalid value specified for /Rotate: %f", deg);
+ break;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * From PDFReference15_v6.pdf (p.119 and p.834)
+ *
+ * MediaBox rectangle (Required; inheritable)
+ *
+ * The media box defines the boundaries of the physical medium on which the
+ * page is to be printed. It may include any extended area surrounding the
+ * finished page for bleed, printing marks, or other such purposes. It may
+ * also include areas close to the edges of the medium that cannot be marked
+ * because of physical limitations of the output device. Content falling
+ * outside this boundary can safely be discarded without affecting the
+ * meaning of the PDF file.
+ *
+ * CropBox rectangle (Optional; inheritable)
+ *
+ * The crop box defines the region to which the contents of the page are to be
+ * clipped (cropped) when displayed or printed. Unlike the other boxes, the
+ * crop box has no defined meaning in terms of physical page geometry or
+ * intended use; it merely imposes clipping on the page contents. However,
+ * in the absence of additional information (such as imposition instructions
+ * specified in a JDF or PJTF job ticket), the crop box will determine how
+ * the page's contents are to be positioned on the output medium. The default
+ * value is the page's media box.
+ *
+ * BleedBox rectangle (Optional; PDF 1.3)
+ *
+ * The bleed box (PDF 1.3) defines the region to which the contents of the
+ * page should be clipped when output in a production environment. This may
+ * include any extra "bleed area" needed to accommodate the physical
+ * limitations of cutting, folding, and trimming equipment. The actual printed
+ * page may include printing marks that fall outside the bleed box.
+ * The default value is the page's crop box.
+ *
+ * TrimBox rectangle (Optional; PDF 1.3)
+ *
+ * The trim box (PDF 1.3) defines the intended dimensions of the finished page
+ * after trimming. It may be smaller than the media box, to allow for
+ * production-related content such as printing instructions, cut marks, or
+ * color bars. The default value is the page's crop box.
+ *
+ * ArtBox rectangle (Optional; PDF 1.3)
+ *
+ * The art box (PDF 1.3) defines the extent of the page's meaningful content
+ * (including potential white space) as intended by the page's creator.
+ * The default value is the page's crop box.
+ *
+ * Rotate integer (Optional; inheritable)
+ *
+ * The number of degrees by which the page should be rotated clockwise when
+ * displayed or printed. The value must be a multiple of 90. Default value: 0.
+ */
+
+/* count_p removed: Please use different interface if you want to get total page
+ * number. pdf_doc_get_page() is obviously not an interface to do such.
+ */
+pdf_obj *
+pdf_doc_get_page (pdf_file *pf,
+ int page_no, enum pdf_page_boundary opt_bbox, /* load options */
+ pdf_rect *bbox, pdf_tmatrix *matrix, /* returned value */
+ pdf_obj **resources_p /* returned values */
+ ) {
+ pdf_obj *catalog = NULL, *page_tree = NULL;
+ pdf_obj *resources = NULL, *rotate = NULL;
+ pdf_obj *art_box = NULL, *trim_box = NULL, *bleed_box = NULL;
+ pdf_obj *media_box = NULL, *crop_box = NULL;
+ int error = 0;
+
+ catalog = pdf_file_get_catalog(pf);
+
+ page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages"));
+
+ if (!PDF_OBJ_DICTTYPE(page_tree))
+ goto error_exit;
+
+ {
+ int count;
+ pdf_obj *tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count"));
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ if (tmp)
+ pdf_release_obj(tmp);
+ goto error_exit;
+ }
+ count = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ if (page_no <= 0 || page_no > count) {
+ WARN("Page %ld does not exist.", page_no);
+ goto error_silent;
+ }
+ }
+
+ /*
+ * Seek correct page. Get MediaBox, CropBox and Resources.
+ * (Note that these entries can be inherited.)
+ */
+ {
+ pdf_obj *kids, *tmp;
+ int depth = PDF_OBJ_MAX_DEPTH;
+ int page_idx = page_no - 1, kids_length = 1, i = 0;
+
+ while (--depth && i != kids_length) {
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "MediaBox")))) {
+ if (media_box)
+ pdf_release_obj(media_box);
+ media_box = tmp;
+ }
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "CropBox")))) {
+ if (crop_box)
+ pdf_release_obj(crop_box);
+ crop_box = tmp;
+ }
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "ArtBox")))) {
+ if (art_box)
+ pdf_release_obj(art_box);
+ art_box = tmp;
+ }
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "TrimBox")))) {
+ if (trim_box)
+ pdf_release_obj(trim_box);
+ trim_box = tmp;
+ }
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "BleedBox")))) {
+ if (bleed_box)
+ pdf_release_obj(bleed_box);
+ bleed_box = tmp;
+ }
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Rotate")))) {
+ if (rotate)
+ pdf_release_obj(rotate);
+ rotate = tmp;
+ }
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Resources")))) {
+ if (resources)
+ pdf_release_obj(resources);
+ resources = tmp;
+ }
+
+ kids = pdf_deref_obj(pdf_lookup_dict(page_tree, "Kids"));
+ if (!kids)
+ break;
+ else if (!PDF_OBJ_ARRAYTYPE(kids)) {
+ pdf_release_obj(kids);
+ goto error_exit;
+ }
+ kids_length = pdf_array_length(kids);
+
+ for (i = 0; i < kids_length; i++) {
+ int count;
+
+ pdf_release_obj(page_tree);
+ page_tree = pdf_deref_obj(pdf_get_array(kids, i));
+ if (!PDF_OBJ_DICTTYPE(page_tree))
+ goto error_exit;
+
+ tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count"));
+ if (PDF_OBJ_NUMBERTYPE(tmp)) {
+ /* Pages object */
+ count = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ } else if (!tmp)
+ /* Page object */
+ count = 1;
+ else {
+ pdf_release_obj(tmp);
+ goto error_exit;
+ }
+ if (page_idx < count)
+ break;
+ page_idx -= count;
+ }
+ pdf_release_obj(kids);
+ }
+ if (!depth || kids_length == i)
+ goto error_exit;
+ }
+
+ if (!PDF_OBJ_DICTTYPE(resources))
+ goto error_exit;
+ if (resources_p)
+ *resources_p = pdf_link_obj(resources);
+
+ /* Select page boundary box */
+ error = set_bounding_box(bbox, opt_bbox, media_box, crop_box, art_box, trim_box, bleed_box);
+ if (error)
+ goto error_exit;
+ /* Set transformation matrix */
+ error = set_transform_matrix(matrix, bbox, rotate);
+ if (error)
+ goto error_exit;
+
+goto clean_exit; /* Success */
+
+ error_exit:
+ WARN("Error found in including PDF image.");
+ error_silent:
+ if (page_tree)
+ pdf_release_obj(page_tree);
+ page_tree = NULL;
+
+clean_exit:
+ if (crop_box)
+ pdf_release_obj(crop_box);
+ if (bleed_box)
+ pdf_release_obj(bleed_box);
+ if (trim_box)
+ pdf_release_obj(trim_box);
+ if (art_box)
+ pdf_release_obj(art_box);
+ if (media_box)
+ pdf_release_obj(media_box);
+ if (rotate)
+ pdf_release_obj(rotate);
+ if (resources)
+ pdf_release_obj(resources);
+
+ return page_tree;
+}
+
+#ifndef BOOKMARKS_OPEN_DEFAULT
+#define BOOKMARKS_OPEN_DEFAULT 0
+#endif
+
+static int clean_bookmarks (pdf_olitem *item);
+static int flush_bookmarks (pdf_olitem *item,
+ pdf_obj *parent_ref,
+ pdf_obj *parent_dict);
+
+static void
+pdf_doc_init_bookmarks (pdf_doc *p, int bm_open_depth)
+{
+ pdf_olitem *item;
+
+#define MAX_OUTLINE_DEPTH 256u
+ p->options.outline_open_depth =
+ ((bm_open_depth >= 0) ?
+ bm_open_depth : MAX_OUTLINE_DEPTH - bm_open_depth);
+
+ p->outlines.current_depth = 1;
+
+ item = NEW(1, pdf_olitem);
+ item->dict = NULL;
+ item->next = NULL;
+ item->first = NULL;
+ item->parent = NULL;
+ item->is_open = 1;
+
+ p->outlines.current = item;
+ p->outlines.first = item;
+
+ return;
+}
+
+static int
+clean_bookmarks (pdf_olitem *item)
+{
+ pdf_olitem *next;
+
+ while (item) {
+ next = item->next;
+ if (item->dict)
+ pdf_release_obj(item->dict);
+ if (item->first)
+ clean_bookmarks(item->first);
+ RELEASE(item);
+
+ item = next;
+ }
+
+ return 0;
+}
+
+static int
+flush_bookmarks (pdf_olitem *node,
+ pdf_obj *parent_ref, pdf_obj *parent_dict)
+{
+ int retval;
+ int count;
+ pdf_olitem *item;
+ pdf_obj *this_ref, *prev_ref, *next_ref;
+
+ ASSERT(node->dict);
+
+ this_ref = pdf_ref_obj(node->dict);
+ pdf_add_dict(parent_dict,
+ pdf_new_name("First"), pdf_link_obj(this_ref));
+
+ retval = 0;
+ for (item = node, prev_ref = NULL;
+ item && item->dict; item = item->next) {
+ if (item->first && item->first->dict) {
+ count = flush_bookmarks(item->first, this_ref, item->dict);
+ if (item->is_open) {
+ pdf_add_dict(item->dict,
+ pdf_new_name("Count"),
+ pdf_new_number(count));
+ retval += count;
+ } else {
+ pdf_add_dict(item->dict,
+ pdf_new_name("Count"),
+ pdf_new_number(-count));
+ }
+ }
+ pdf_add_dict(item->dict,
+ pdf_new_name("Parent"),
+ pdf_link_obj(parent_ref));
+ if (prev_ref) {
+ pdf_add_dict(item->dict,
+ pdf_new_name("Prev"),
+ prev_ref);
+ }
+ if (item->next && item->next->dict) {
+ next_ref = pdf_ref_obj(item->next->dict);
+ pdf_add_dict(item->dict,
+ pdf_new_name("Next"),
+ pdf_link_obj(next_ref));
+ } else {
+ next_ref = NULL;
+ }
+
+ pdf_release_obj(item->dict);
+ item->dict = NULL;
+
+ prev_ref = this_ref;
+ this_ref = next_ref;
+ retval++;
+ }
+
+ pdf_add_dict(parent_dict,
+ pdf_new_name("Last"),
+ pdf_link_obj(prev_ref));
+
+ pdf_release_obj(prev_ref);
+ pdf_release_obj(node->dict);
+ node->dict = NULL;
+
+ return retval;
+}
+
+int
+pdf_doc_bookmarks_up (void)
+{
+ pdf_doc *p = &pdoc;
+ pdf_olitem *parent, *item;
+
+ item = p->outlines.current;
+ if (!item || !item->parent) {
+ WARN("Can't go up above the bookmark root node!");
+ return -1;
+ }
+ parent = item->parent;
+ item = parent->next;
+ if (!parent->next) {
+ parent->next = item = NEW(1, pdf_olitem);
+ item->dict = NULL;
+ item->first = NULL;
+ item->next = NULL;
+ item->is_open = 0;
+ item->parent = parent->parent;
+ }
+ p->outlines.current = item;
+ p->outlines.current_depth--;
+
+ return 0;
+}
+
+int
+pdf_doc_bookmarks_down (void)
+{
+ pdf_doc *p = &pdoc;
+ pdf_olitem *item, *first;
+
+ item = p->outlines.current;
+ if (!item->dict) {
+ pdf_obj *tcolor, *action;
+
+ WARN("Empty bookmark node!");
+ WARN("You have tried to jump more than 1 level.");
+
+ item->dict = pdf_new_dict();
+
+#define TITLE_STRING "<No Title>"
+ pdf_add_dict(item->dict,
+ pdf_new_name("Title"),
+ pdf_new_string(TITLE_STRING, strlen(TITLE_STRING)));
+
+ tcolor = pdf_new_array();
+ pdf_add_array(tcolor, pdf_new_number(1.0));
+ pdf_add_array(tcolor, pdf_new_number(0.0));
+ pdf_add_array(tcolor, pdf_new_number(0.0));
+ pdf_add_dict (item->dict,
+ pdf_new_name("C"), pdf_link_obj(tcolor));
+ pdf_release_obj(tcolor);
+
+ pdf_add_dict (item->dict,
+ pdf_new_name("F"), pdf_new_number(1.0));
+
+#define JS_CODE "app.alert(\"The author of this document made this bookmark item empty!\", 3, 0)"
+ action = pdf_new_dict();
+ pdf_add_dict(action,
+ pdf_new_name("S"), pdf_new_name("JavaScript"));
+ pdf_add_dict(action,
+ pdf_new_name("JS"), pdf_new_string(JS_CODE, strlen(JS_CODE)));
+ pdf_add_dict(item->dict,
+ pdf_new_name("A"), pdf_link_obj(action));
+ pdf_release_obj(action);
+ }
+
+ item->first = first = NEW(1, pdf_olitem);
+ first->dict = NULL;
+ first->is_open = 0;
+ first->parent = item;
+ first->next = NULL;
+ first->first = NULL;
+
+ p->outlines.current = first;
+ p->outlines.current_depth++;
+
+ return 0;
+}
+
+int
+pdf_doc_bookmarks_depth (void)
+{
+ pdf_doc *p = &pdoc;
+
+ return p->outlines.current_depth;
+}
+
+void
+pdf_doc_bookmarks_add (pdf_obj *dict, int is_open)
+{
+ pdf_doc *p = &pdoc;
+ pdf_olitem *item, *next;
+
+ ASSERT(p && dict);
+
+ item = p->outlines.current;
+
+ if (!item) {
+ item = NEW(1, pdf_olitem);
+ item->parent = NULL;
+ p->outlines.first = item;
+ } else if (item->dict) { /* go to next item */
+ item = item->next;
+ }
+
+#define BMOPEN(b,p) (((b) < 0) ? (((p)->outlines.current_depth > (p)->options.outline_open_depth) ? 0 : 1) : (b))
+
+#if 0
+ item->dict = pdf_link_obj(dict);
+#endif
+ item->dict = dict;
+ item->first = NULL;
+ item->is_open = BMOPEN(is_open, p);
+
+ item->next = next = NEW(1, pdf_olitem);
+ next->dict = NULL;
+ next->parent = item->parent;
+ next->first = NULL;
+ next->is_open = -1;
+ next->next = NULL;
+
+ p->outlines.current = item;
+
+ pdf_doc_add_goto(dict);
+
+ return;
+}
+
+static void
+pdf_doc_close_bookmarks (pdf_doc *p)
+{
+ pdf_obj *catalog = p->root.dict;
+ pdf_olitem *item;
+ int count;
+ pdf_obj *bm_root, *bm_root_ref;
+
+ item = p->outlines.first;
+ if (item->dict) {
+ bm_root = pdf_new_dict();
+ bm_root_ref = pdf_ref_obj(bm_root);
+ count = flush_bookmarks(item, bm_root_ref, bm_root);
+ pdf_add_dict(bm_root,
+ pdf_new_name("Count"),
+ pdf_new_number(count));
+ pdf_add_dict(catalog,
+ pdf_new_name("Outlines"),
+ bm_root_ref);
+ pdf_release_obj(bm_root);
+ }
+ clean_bookmarks(item);
+
+ p->outlines.first = NULL;
+ p->outlines.current = NULL;
+ p->outlines.current_depth = 0;
+
+ return;
+}
+
+
+static const char *name_dict_categories[] = {
+ "Dests", "AP", "JavaScript", "Pages",
+ "Templates", "IDS", "URLS", "EmbeddedFiles",
+ "AlternatePresentations", "Renditions"
+};
+#define NUM_NAME_CATEGORY (sizeof(name_dict_categories)/sizeof(name_dict_categories[0]))
+
+static void
+pdf_doc_init_names (pdf_doc *p, int check_gotos)
+{
+ int i;
+
+ p->root.names = NULL;
+
+ p->names = NEW(NUM_NAME_CATEGORY + 1, struct name_dict);
+ for (i = 0; i < NUM_NAME_CATEGORY; i++) {
+ p->names[i].category = name_dict_categories[i];
+ p->names[i].data = strcmp(name_dict_categories[i], "Dests") ?
+ NULL : pdf_new_name_tree();
+ /*
+ * We need a non-null entry for PDF destinations in order to find
+ * broken links even if no destination is defined in the DVI file.
+ */
+ }
+ p->names[NUM_NAME_CATEGORY].category = NULL;
+ p->names[NUM_NAME_CATEGORY].data = NULL;
+
+ p->check_gotos = check_gotos;
+ ht_init_table(&p->gotos, (void (*) (void *)) pdf_release_obj);
+
+ return;
+}
+
+int
+pdf_doc_add_names (const char *category,
+ const void *key, int keylen, pdf_obj *value)
+{
+ pdf_doc *p = &pdoc;
+ int i;
+
+ for (i = 0; p->names[i].category != NULL; i++) {
+ if (!strcmp(p->names[i].category, category)) {
+ break;
+ }
+ }
+ if (p->names[i].category == NULL) {
+ WARN("Unknown name dictionary category \"%s\".", category);
+ return -1;
+ }
+ if (!p->names[i].data) {
+ p->names[i].data = pdf_new_name_tree();
+ }
+
+ return pdf_names_add_object(p->names[i].data, key, keylen, value);
+}
+
+static void
+pdf_doc_add_goto (pdf_obj *annot_dict)
+{
+ pdf_obj *subtype = NULL, *A = NULL, *S = NULL, *D = NULL, *D_new, *dict;
+ const char *dest, *key;
+ int destlen = 0;
+
+ if (!pdoc.check_gotos)
+ return;
+
+ /*
+ * An annotation dictionary coming from an annotation special
+ * must have a "Subtype". An annotation dictionary coming from
+ * an outline special has none.
+ */
+ subtype = pdf_deref_obj(pdf_lookup_dict(annot_dict, "Subtype"));
+ if (subtype) {
+ if (PDF_OBJ_UNDEFINED(subtype))
+ goto undefined;
+ else if (!PDF_OBJ_NAMETYPE(subtype))
+ goto error;
+ else if (strcmp(pdf_name_value(subtype), "Link"))
+ goto cleanup;
+ }
+
+ dict = annot_dict;
+ key = "Dest";
+ D = pdf_deref_obj(pdf_lookup_dict(annot_dict, key));
+ if (PDF_OBJ_UNDEFINED(D))
+ goto undefined;
+
+ A = pdf_deref_obj(pdf_lookup_dict(annot_dict, "A"));
+ if (A) {
+ if (PDF_OBJ_UNDEFINED(A))
+ goto undefined;
+ else if (D || !PDF_OBJ_DICTTYPE(A))
+ goto error;
+ else {
+ S = pdf_deref_obj(pdf_lookup_dict(A, "S"));
+ if (PDF_OBJ_UNDEFINED(S))
+ goto undefined;
+ else if (!PDF_OBJ_NAMETYPE(S))
+ goto error;
+ else if (strcmp(pdf_name_value(S), "GoTo"))
+ goto cleanup;
+
+ dict = A;
+ key = "D";
+ D = pdf_deref_obj(pdf_lookup_dict(A, key));
+ }
+ }
+
+ if (PDF_OBJ_STRINGTYPE(D)) {
+ dest = (char *) pdf_string_value(D);
+ destlen = pdf_string_length(D);
+ }
+#if 0
+ /* Names as destinations are not supported by dvipdfmx */
+ else if (PDF_OBJ_NAMETYPE(D))
+ dest = pdf_name_value(D);
+#endif
+ else if (PDF_OBJ_ARRAYTYPE(D))
+ goto cleanup;
+ else if (PDF_OBJ_UNDEFINED(D))
+ goto undefined;
+ else
+ goto error;
+
+ D_new = ht_lookup_table(&pdoc.gotos, dest, destlen);
+ if (!D_new) {
+ char buf[10];
+
+ /* We use hexadecimal notation for our numeric destinations.
+ * Other bases (e.g., 10+26 or 10+2*26) would be more efficient.
+ */
+ sprintf(buf, "%x", ht_table_size(&pdoc.gotos));
+ D_new = pdf_new_string(buf, strlen(buf));
+ ht_append_table(&pdoc.gotos, dest, destlen, D_new);
+ }
+
+ {
+ pdf_obj *key_obj = pdf_new_name(key);
+ if (!pdf_add_dict(dict, key_obj, pdf_link_obj(D_new)))
+ pdf_release_obj(key_obj);
+ }
+
+ cleanup:
+ if (subtype)
+ pdf_release_obj(subtype);
+ if (A)
+ pdf_release_obj(A);
+ if (S)
+ pdf_release_obj(S);
+ if (D)
+ pdf_release_obj(D);
+
+ return;
+
+ error:
+ WARN("Unknown PDF annotation format. Output file may be broken.");
+ goto cleanup;
+
+ undefined:
+ WARN("Cannot optimize PDF annotations. Output file may be broken."
+ " Please restart with option \"-C 0x10\"\n");
+ goto cleanup;
+}
+
+static void
+warn_undef_dests (struct ht_table *dests, struct ht_table *gotos)
+{
+ struct ht_iter iter;
+
+ if (ht_set_iter(gotos, &iter) < 0)
+ return;
+
+ do {
+ int keylen;
+ char *key = ht_iter_getkey(&iter, &keylen);
+ if (!ht_lookup_table(dests, key, keylen)) {
+ char *dest = NEW(keylen+1, char);
+ memcpy(dest, key, keylen);
+ dest[keylen] = 0;
+ WARN("PDF destination \"%s\" not defined.", dest);
+ RELEASE(dest);
+ }
+ } while (ht_iter_next(&iter) >= 0);
+
+ ht_clear_iter(&iter);
+}
+
+static void
+pdf_doc_close_names (pdf_doc *p)
+{
+ pdf_obj *tmp;
+ int i;
+
+ for (i = 0; p->names[i].category != NULL; i++) {
+ if (p->names[i].data) {
+ struct ht_table *data = p->names[i].data;
+ pdf_obj *name_tree;
+ int count;
+
+ if (!pdoc.check_gotos || strcmp(p->names[i].category, "Dests"))
+ name_tree = pdf_names_create_tree(data, &count, NULL);
+ else {
+ name_tree = pdf_names_create_tree(data, &count, &pdoc.gotos);
+
+ if (dpx_conf.verbose_level > 0 && count < data->count)
+ MESG("\nRemoved %ld unused PDF destinations\n", data->count-count);
+
+ if (count < pdoc.gotos.count)
+ warn_undef_dests(data, &pdoc.gotos);
+ }
+
+ if (name_tree) {
+ if (!p->root.names)
+ p->root.names = pdf_new_dict();
+ pdf_add_dict(p->root.names,
+ pdf_new_name(p->names[i].category),
+ pdf_ref_obj(name_tree));
+ pdf_release_obj(name_tree);
+ }
+ pdf_delete_name_tree(&p->names[i].data);
+ }
+ }
+
+ if (p->root.names) {
+ tmp = pdf_lookup_dict(p->root.dict, "Names");
+ if (!tmp) {
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("Names"),
+ pdf_ref_obj (p->root.names));
+ } else if (PDF_OBJ_DICTTYPE(tmp)) {
+ pdf_merge_dict(p->root.names, tmp);
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("Names"),
+ pdf_ref_obj (p->root.names));
+ } else { /* Maybe reference */
+ /* What should I do? */
+ WARN("Could not modify Names dictionary.");
+ }
+ pdf_release_obj(p->root.names);
+ p->root.names = NULL;
+ }
+
+ RELEASE(p->names);
+ p->names = NULL;
+
+ ht_clear_table(&p->gotos);
+
+ return;
+}
+
+static void pdf_doc_get_mediabox (unsigned page_no, pdf_rect *mediabox);
+
+void
+pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect,
+ pdf_obj *annot_dict, int new_annot)
+{
+ pdf_doc *p = &pdoc;
+ pdf_page *page;
+ pdf_obj *rect_array;
+
+ page = doc_get_page_entry(p, page_no);
+ if (!page->annots)
+ page->annots = pdf_new_array();
+
+ {
+ pdf_rect mediabox;
+
+ pdf_doc_get_mediabox(page_no, &mediabox);
+ if (rect->llx < mediabox.llx || rect->urx > mediabox.urx ||
+ rect->lly < mediabox.lly || rect->ury > mediabox.ury) {
+ WARN("Annotation out of page boundary.");
+ WARN("Current page's MediaBox: [%g %g %g %g]",
+ mediabox.llx, mediabox.lly, mediabox.urx, mediabox.ury);
+ WARN("Annotation: [%g %g %g %g]",
+ rect->llx, rect->lly, rect->urx, rect->ury);
+ WARN("Maybe incorrect paper size specified.");
+ }
+ if (rect->llx > rect->urx || rect->lly > rect->ury) {
+ WARN("Rectangle with negative width/height: [%g %g %g %g]",
+ rect->llx, rect->lly, rect->urx, rect->ury);
+ }
+ }
+
+ rect_array = pdf_new_array();
+ pdf_add_array(rect_array, pdf_new_number(ROUND(rect->llx, 0.001)));
+ pdf_add_array(rect_array, pdf_new_number(ROUND(rect->lly, 0.001)));
+ pdf_add_array(rect_array, pdf_new_number(ROUND(rect->urx, 0.001)));
+ pdf_add_array(rect_array, pdf_new_number(ROUND(rect->ury, 0.001)));
+ pdf_add_dict (annot_dict, pdf_new_name("Rect"), rect_array);
+
+ pdf_add_array(page->annots, pdf_ref_obj(annot_dict));
+
+ if (new_annot)
+ pdf_doc_add_goto(annot_dict);
+
+ return;
+}
+
+
+/*
+ * PDF Article Thread
+ */
+static void
+pdf_doc_init_articles (pdf_doc *p)
+{
+ p->root.threads = NULL;
+
+ p->articles.num_entries = 0;
+ p->articles.max_entries = 0;
+ p->articles.entries = NULL;
+
+ return;
+}
+
+void
+pdf_doc_begin_article (const char *article_id, pdf_obj *article_info)
+{
+ pdf_doc *p = &pdoc;
+ pdf_article *article;
+
+ if (article_id == NULL || strlen(article_id) == 0)
+ ERROR("Article thread without internal identifier.");
+
+ if (p->articles.num_entries >= p->articles.max_entries) {
+ p->articles.max_entries += PDFDOC_ARTICLE_ALLOC_SIZE;
+ p->articles.entries = RENEW(p->articles.entries,
+ p->articles.max_entries, struct pdf_article);
+ }
+ article = &(p->articles.entries[p->articles.num_entries]);
+
+ article->id = NEW(strlen(article_id)+1, char);
+ strcpy(article->id, article_id);
+ article->info = article_info;
+ article->num_beads = 0;
+ article->max_beads = 0;
+ article->beads = NULL;
+
+ p->articles.num_entries++;
+
+ return;
+}
+
+static pdf_bead *
+find_bead (pdf_article *article, const char *bead_id)
+{
+ pdf_bead *bead;
+ int i;
+
+ bead = NULL;
+ for (i = 0; i < article->num_beads; i++) {
+ if (!strcmp(article->beads[i].id, bead_id)) {
+ bead = &(article->beads[i]);
+ break;
+ }
+ }
+
+ return bead;
+}
+
+void
+pdf_doc_add_bead (const char *article_id,
+ const char *bead_id, int page_no, const pdf_rect *rect)
+{
+ pdf_doc *p = &pdoc;
+ pdf_article *article;
+ pdf_bead *bead;
+ int i;
+
+ if (!article_id) {
+ ERROR("No article identifier specified.");
+ }
+
+ article = NULL;
+ for (i = 0; i < p->articles.num_entries; i++) {
+ if (!strcmp(p->articles.entries[i].id, article_id)) {
+ article = &(p->articles.entries[i]);
+ break;
+ }
+ }
+ if (!article) {
+ ERROR("Specified article thread that doesn't exist.");
+ return;
+ }
+
+ bead = bead_id ? find_bead(article, bead_id) : NULL;
+ if (!bead) {
+ if (article->num_beads >= article->max_beads) {
+ article->max_beads += PDFDOC_BEAD_ALLOC_SIZE;
+ article->beads = RENEW(article->beads,
+ article->max_beads, struct pdf_bead);
+ for (i = article->num_beads; i < article->max_beads; i++) {
+ article->beads[i].id = NULL;
+ article->beads[i].page_no = -1;
+ }
+ }
+ bead = &(article->beads[article->num_beads]);
+ if (bead_id) {
+ bead->id = NEW(strlen(bead_id)+1, char);
+ strcpy(bead->id, bead_id);
+ } else {
+ bead->id = NULL;
+ }
+ article->num_beads++;
+ }
+ bead->rect.llx = rect->llx;
+ bead->rect.lly = rect->lly;
+ bead->rect.urx = rect->urx;
+ bead->rect.ury = rect->ury;
+ bead->page_no = page_no;
+
+ return;
+}
+
+static pdf_obj *
+make_article (pdf_doc *p,
+ pdf_article *article,
+ const char **bead_ids, int num_beads,
+ pdf_obj *article_info)
+{
+ pdf_obj *art_dict;
+ pdf_obj *first, *prev, *last;
+ int i, n;
+
+ if (!article)
+ return NULL;
+
+ art_dict = pdf_new_dict();
+ first = prev = last = NULL;
+ /*
+ * The bead_ids represents logical order of beads in an article thread.
+ * If bead_ids is not given, we create an article thread in the order of
+ * beads appeared.
+ */
+ n = bead_ids ? num_beads : article->num_beads;
+ for (i = 0; i < n; i++) {
+ pdf_bead *bead;
+
+ bead = bead_ids ? find_bead(article, bead_ids[i]) : &(article->beads[i]);
+ if (!bead || bead->page_no < 0) {
+ continue;
+ }
+ last = pdf_new_dict();
+ if (prev == NULL) {
+ first = last;
+ pdf_add_dict(first,
+ pdf_new_name("T"), pdf_ref_obj(art_dict));
+ } else {
+ pdf_add_dict(prev,
+ pdf_new_name("N"), pdf_ref_obj(last));
+ pdf_add_dict(last,
+ pdf_new_name("V"), pdf_ref_obj(prev));
+ /* We must link first to last. */
+ if (prev != first)
+ pdf_release_obj(prev);
+ }
+
+ /* Realize bead now. */
+ {
+ pdf_page *page;
+ pdf_obj *rect;
+
+ page = doc_get_page_entry(p, bead->page_no);
+ if (!page->beads) {
+ page->beads = pdf_new_array();
+ }
+ pdf_add_dict(last, pdf_new_name("P"), pdf_link_obj(page->page_ref));
+ rect = pdf_new_array();
+ pdf_add_array(rect, pdf_new_number(ROUND(bead->rect.llx, 0.01)));
+ pdf_add_array(rect, pdf_new_number(ROUND(bead->rect.lly, 0.01)));
+ pdf_add_array(rect, pdf_new_number(ROUND(bead->rect.urx, 0.01)));
+ pdf_add_array(rect, pdf_new_number(ROUND(bead->rect.ury, 0.01)));
+ pdf_add_dict (last, pdf_new_name("R"), rect);
+ pdf_add_array(page->beads, pdf_ref_obj(last));
+ }
+
+ prev = last;
+ }
+
+ if (first && last) {
+ pdf_add_dict(last,
+ pdf_new_name("N"), pdf_ref_obj(first));
+ pdf_add_dict(first,
+ pdf_new_name("V"), pdf_ref_obj(last));
+ if (first != last) {
+ pdf_release_obj(last);
+ }
+ pdf_add_dict(art_dict,
+ pdf_new_name("F"), pdf_ref_obj(first));
+ /* If article_info is supplied, we override article->info. */
+ if (article_info) {
+ pdf_add_dict(art_dict,
+ pdf_new_name("I"), article_info);
+ } else if (article->info) {
+ pdf_add_dict(art_dict,
+ pdf_new_name("I"), pdf_ref_obj(article->info));
+ pdf_release_obj(article->info);
+ article->info = NULL; /* We do not write as object reference. */
+ }
+ pdf_release_obj(first);
+ } else {
+ pdf_release_obj(art_dict);
+ art_dict = NULL;
+ }
+
+ return art_dict;
+}
+
+static void
+clean_article (pdf_article *article)
+{
+ if (!article)
+ return;
+
+ if (article->beads) {
+ int i;
+
+ for (i = 0; i < article->num_beads; i++) {
+ if (article->beads[i].id)
+ RELEASE(article->beads[i].id);
+ }
+ RELEASE(article->beads);
+ article->beads = NULL;
+ }
+
+ if (article->id)
+ RELEASE(article->id);
+ article->id = NULL;
+ article->num_beads = 0;
+ article->max_beads = 0;
+
+ return;
+}
+
+static void
+pdf_doc_close_articles (pdf_doc *p)
+{
+ int i;
+
+ for (i = 0; i < p->articles.num_entries; i++) {
+ pdf_article *article;
+
+ article = &(p->articles.entries[i]);
+ if (article->beads) {
+ pdf_obj *art_dict;
+
+ art_dict = make_article(p, article, NULL, 0, NULL);
+ if (!p->root.threads) {
+ p->root.threads = pdf_new_array();
+ }
+ pdf_add_array(p->root.threads, pdf_ref_obj(art_dict));
+ pdf_release_obj(art_dict);
+ }
+ clean_article(article);
+ }
+ RELEASE(p->articles.entries);
+ p->articles.entries = NULL;
+ p->articles.num_entries = 0;
+ p->articles.max_entries = 0;
+
+ if (p->root.threads) {
+ pdf_add_dict(p->root.dict,
+ pdf_new_name("Threads"),
+ pdf_ref_obj (p->root.threads));
+ pdf_release_obj(p->root.threads);
+ p->root.threads = NULL;
+ }
+
+ return;
+}
+
+/* page_no = 0 for root page tree node. */
+void
+pdf_doc_set_mediabox (unsigned page_no, const pdf_rect *mediabox)
+{
+ pdf_doc *p = &pdoc;
+ pdf_page *page;
+
+ if (page_no == 0) {
+ p->pages.mediabox.llx = mediabox->llx;
+ p->pages.mediabox.lly = mediabox->lly;
+ p->pages.mediabox.urx = mediabox->urx;
+ p->pages.mediabox.ury = mediabox->ury;
+ } else {
+ page = doc_get_page_entry(p, page_no);
+ page->cropbox.llx = mediabox->llx;
+ page->cropbox.lly = mediabox->lly;
+ page->cropbox.urx = mediabox->urx;
+ page->cropbox.ury = mediabox->ury;
+ page->flags |= USE_MY_MEDIABOX;
+ }
+
+ return;
+}
+
+static void
+pdf_doc_get_mediabox (unsigned page_no, pdf_rect *mediabox)
+{
+ pdf_doc *p = &pdoc;
+ pdf_page *page;
+
+ if (page_no == 0) {
+ mediabox->llx = p->pages.mediabox.llx;
+ mediabox->lly = p->pages.mediabox.lly;
+ mediabox->urx = p->pages.mediabox.urx;
+ mediabox->ury = p->pages.mediabox.ury;
+ } else {
+ page = doc_get_page_entry(p, page_no);
+ if (page->flags & USE_MY_MEDIABOX) {
+ mediabox->llx = page->cropbox.llx;
+ mediabox->lly = page->cropbox.lly;
+ mediabox->urx = page->cropbox.urx;
+ mediabox->ury = page->cropbox.ury;
+ } else {
+ mediabox->llx = p->pages.mediabox.llx;
+ mediabox->lly = p->pages.mediabox.lly;
+ mediabox->urx = p->pages.mediabox.urx;
+ mediabox->ury = p->pages.mediabox.ury;
+ }
+ }
+
+ return;
+}
+
+pdf_obj *
+pdf_doc_current_page_resources (void)
+{
+ pdf_obj *resources;
+ pdf_doc *p = &pdoc;
+ pdf_page *currentpage;
+
+ if (p->pending_forms) {
+ if (p->pending_forms->form.resources) {
+ resources = p->pending_forms->form.resources;
+ } else {
+ resources = p->pending_forms->form.resources = pdf_new_dict();
+ }
+ } else {
+ currentpage = LASTPAGE(p);
+ if (currentpage->resources) {
+ resources = currentpage->resources;
+ } else {
+ resources = currentpage->resources = pdf_new_dict();
+ }
+ }
+
+ return resources;
+}
+
+pdf_obj *
+pdf_doc_get_dictionary (const char *category)
+{
+ pdf_doc *p = &pdoc;
+ pdf_obj *dict = NULL;
+
+ ASSERT(category);
+
+ if (!strcmp(category, "Names")) {
+ if (!p->root.names)
+ p->root.names = pdf_new_dict();
+ dict = p->root.names;
+ } else if (!strcmp(category, "Pages")) {
+ if (!p->root.pages)
+ p->root.pages = pdf_new_dict();
+ dict = p->root.pages;
+ } else if (!strcmp(category, "Catalog")) {
+ if (!p->root.dict)
+ p->root.dict = pdf_new_dict();
+ dict = p->root.dict;
+ } else if (!strcmp(category, "Info")) {
+ if (!p->info)
+ p->info = pdf_new_dict();
+ dict = p->info;
+ } else if (!strcmp(category, "@THISPAGE")) {
+ /* Sorry for this... */
+ pdf_page *currentpage;
+
+ currentpage = LASTPAGE(p);
+ dict = currentpage->page_obj;
+ }
+
+ if (!dict) {
+ ERROR("Document dict. \"%s\" not exist. ", category);
+ }
+
+ return dict;
+}
+
+int
+pdf_doc_current_page_number (void)
+{
+ pdf_doc *p = &pdoc;
+
+ return (int) (PAGECOUNT(p) + 1);
+}
+
+pdf_obj *
+pdf_doc_ref_page (unsigned page_no)
+{
+ pdf_doc *p = &pdoc;
+ pdf_page *page;
+
+ page = doc_get_page_entry(p, page_no);
+ if (!page->page_obj) {
+ page->page_obj = pdf_new_dict();
+ page->page_ref = pdf_ref_obj(page->page_obj);
+ }
+
+ return pdf_link_obj(page->page_ref);
+}
+
+pdf_obj *
+pdf_doc_get_reference (const char *category)
+{
+ pdf_obj *ref = NULL;
+ int page_no;
+
+ ASSERT(category);
+
+ page_no = pdf_doc_current_page_number();
+ if (!strcmp(category, "@THISPAGE")) {
+ ref = pdf_doc_ref_page(page_no);
+ } else if (!strcmp(category, "@PREVPAGE")) {
+ if (page_no <= 1) {
+ ERROR("Reference to previous page, but no pages have been completed yet.");
+ }
+ ref = pdf_doc_ref_page(page_no - 1);
+ } else if (!strcmp(category, "@NEXTPAGE")) {
+ ref = pdf_doc_ref_page(page_no + 1);
+ }
+
+ if (!ref) {
+ ERROR("Reference to \"%s\" not exist. ", category);
+ }
+
+ return ref;
+}
+
+static void
+pdf_doc_new_page (pdf_doc *p)
+{
+ pdf_page *currentpage;
+
+ if (PAGECOUNT(p) >= MAXPAGES(p)) {
+ doc_resize_page_entries(p, MAXPAGES(p) + PDFDOC_PAGES_ALLOC_SIZE);
+ }
+
+ /*
+ * This is confusing. pdf_doc_finish_page() have increased page count!
+ */
+ currentpage = LASTPAGE(p);
+ /* Was this page already instantiated by a forward reference to it? */
+ if (!currentpage->page_ref) {
+ currentpage->page_obj = pdf_new_dict();
+ currentpage->page_ref = pdf_ref_obj(currentpage->page_obj);
+ }
+
+ currentpage->background = NULL;
+ currentpage->contents = pdf_new_stream(STREAM_COMPRESS);
+ currentpage->resources = pdf_new_dict();
+
+ currentpage->annots = NULL;
+ currentpage->beads = NULL;
+
+ return;
+}
+
+/* This only closes contents and resources. */
+static void
+pdf_doc_finish_page (pdf_doc *p)
+{
+ pdf_page *currentpage;
+
+ if (p->pending_forms) {
+ ERROR("A pending form XObject at the end of page.");
+ }
+
+ currentpage = LASTPAGE(p);
+ if (!currentpage->page_obj)
+ currentpage->page_obj = pdf_new_dict();
+
+ /*
+ * Make Contents array.
+ */
+
+ /*
+ * Global BOP content stream.
+ * pdf_ref_obj() returns reference itself when the object is
+ * indirect reference, not reference to the indirect reference.
+ * We keep bop itself but not reference to it since it is
+ * expected to be small.
+ */
+ if (p->pages.bop &&
+ pdf_stream_length(p->pages.bop) > 0) {
+ currentpage->content_refs[0] = pdf_ref_obj(p->pages.bop);
+ } else {
+ currentpage->content_refs[0] = NULL;
+ }
+ /*
+ * Current page background content stream.
+ */
+ if (currentpage->background) {
+ if (pdf_stream_length(currentpage->background) > 0) {
+ currentpage->content_refs[1] = pdf_ref_obj(currentpage->background);
+ pdf_add_stream (currentpage->background, "\n", 1);
+ }
+ pdf_release_obj(currentpage->background);
+ currentpage->background = NULL;
+ } else {
+ currentpage->content_refs[1] = NULL;
+ }
+
+ /* Content body of current page */
+ currentpage->content_refs[2] = pdf_ref_obj(currentpage->contents);
+ pdf_add_stream (currentpage->contents, "\n", 1);
+ pdf_release_obj(currentpage->contents);
+ currentpage->contents = NULL;
+
+ /*
+ * Global EOP content stream.
+ */
+ if (p->pages.eop &&
+ pdf_stream_length(p->pages.eop) > 0) {
+ currentpage->content_refs[3] = pdf_ref_obj(p->pages.eop);
+ } else {
+ currentpage->content_refs[3] = NULL;
+ }
+
+ /*
+ * Page resources.
+ */
+ if (currentpage->resources) {
+ pdf_obj *procset;
+ /*
+ * ProcSet is obsolete in PDF-1.4 but recommended for compatibility.
+ */
+
+ procset = pdf_new_array ();
+ pdf_add_array(procset, pdf_new_name("PDF"));
+ pdf_add_array(procset, pdf_new_name("Text"));
+ pdf_add_array(procset, pdf_new_name("ImageC"));
+ pdf_add_array(procset, pdf_new_name("ImageB"));
+ pdf_add_array(procset, pdf_new_name("ImageI"));
+ pdf_add_dict(currentpage->resources, pdf_new_name("ProcSet"), procset);
+
+ pdf_add_dict(currentpage->page_obj,
+ pdf_new_name("Resources"),
+ pdf_ref_obj(currentpage->resources));
+ pdf_release_obj(currentpage->resources);
+ currentpage->resources = NULL;
+ }
+
+ if (p->options.enable_manual_thumb) {
+ char *thumb_filename;
+ pdf_obj *thumb_ref;
+
+ thumb_filename = NEW(strlen(p->thumb_basename)+7, char);
+ sprintf(thumb_filename, "%s.%ld",
+ p->thumb_basename, (p->pages.num_entries % 99999) + 1L);
+ thumb_ref = read_thumbnail(thumb_filename);
+ RELEASE(thumb_filename);
+ if (thumb_ref)
+ pdf_add_dict(currentpage->page_obj, pdf_new_name("Thumb"), thumb_ref);
+ }
+
+ p->pages.num_entries++;
+
+ return;
+}
+
+static pdf_color bgcolor = { -1, PDF_COLORSPACE_TYPE_GRAY, 1, NULL, { 1.0 }, -1};
+
+void
+pdf_doc_set_bgcolor (const pdf_color *color)
+{
+ if (color) {
+ pdf_color_copycolor(&bgcolor, color);
+ } else { /* as clear... */
+ pdf_color_white(&bgcolor);
+ }
+}
+
+static void
+doc_fill_page_background (pdf_doc *p)
+{
+ pdf_page *currentpage;
+ pdf_rect r;
+ int cm;
+ pdf_obj *saved_content;
+
+ cm = pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE);
+ if (!cm || pdf_color_is_white(&bgcolor)) {
+ return;
+ }
+
+ pdf_doc_get_mediabox(pdf_doc_current_page_number(), &r);
+
+ currentpage = LASTPAGE(p);
+ ASSERT(currentpage);
+
+ if (!currentpage->background)
+ currentpage->background = pdf_new_stream(STREAM_COMPRESS);
+
+ saved_content = currentpage->contents;
+ currentpage->contents = currentpage->background;
+
+ pdf_dev_gsave();
+ pdf_dev_set_nonstrokingcolor(&bgcolor);
+ pdf_dev_rectfill(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly);
+ pdf_dev_grestore();
+
+ currentpage->contents = saved_content;
+
+ return;
+}
+
+void
+pdf_doc_begin_page (double scale, double x_origin, double y_origin)
+{
+ pdf_doc *p = &pdoc;
+ pdf_tmatrix M;
+
+ M.a = scale; M.b = 0.0;
+ M.c = 0.0 ; M.d = scale;
+ M.e = x_origin;
+ M.f = y_origin;
+
+ /* pdf_doc_new_page() allocates page content stream. */
+ pdf_doc_new_page(p);
+ pdf_dev_bop(&M);
+
+ return;
+}
+
+void
+pdf_doc_end_page (void)
+{
+ pdf_doc *p = &pdoc;
+
+ pdf_dev_eop();
+ doc_fill_page_background(p);
+
+ pdf_doc_finish_page(p);
+
+ return;
+}
+
+void
+pdf_doc_add_page_content (const char *buffer, unsigned length)
+{
+ pdf_doc *p = &pdoc;
+ pdf_page *currentpage;
+
+ if (p->pending_forms) {
+ pdf_add_stream(p->pending_forms->form.contents, buffer, length);
+ } else {
+ currentpage = LASTPAGE(p);
+ pdf_add_stream(currentpage->contents, buffer, length);
+ }
+
+ return;
+}
+
+void
+pdf_open_document (const char *filename,
+ const char *creator,
+ const unsigned char *id1, const unsigned char *id2,
+ struct pdf_setting settings)
+{
+ pdf_doc *p = &pdoc;
+
+ pdf_out_init(filename, id1, id2,
+ settings.ver_major, settings.ver_minor, settings.object.compression_level,
+ settings.enable_encrypt,
+ settings.object.enable_objstm, settings.object.enable_predictor);
+ pdf_files_init();
+
+ pdf_doc_init_catalog(p);
+
+ /* After Catalog is created... */
+ if (settings.enable_encrypt) {
+ pdf_out_set_encrypt(settings.encrypt.key_size, settings.encrypt.permission,
+ settings.encrypt.oplain, settings.encrypt.uplain,
+ 1, 1);
+ }
+
+ p->options.annot_grow.x = settings.annot_grow_amount.x;
+ p->options.annot_grow.y = settings.annot_grow_amount.y;
+ p->options.outline_open_depth = settings.outline_open_depth;
+
+ pdf_init_resources();
+ pdf_init_colors();
+ pdf_init_fonts();
+ /* Thumbnail want this to be initialized... */
+ pdf_init_images();
+
+ pdf_doc_init_docinfo(p);
+ if (creator) {
+ pdf_add_dict(p->info,
+ pdf_new_name("Creator"),
+ pdf_new_string(creator, strlen(creator)));
+ }
+
+ pdf_doc_init_bookmarks(p, settings.outline_open_depth);
+ pdf_doc_init_articles (p);
+ pdf_doc_init_names (p, settings.check_gotos);
+ pdf_doc_init_page_tree(p, settings.media_width, settings.media_height);
+
+ pdf_doc_set_bgcolor(NULL);
+
+ p->options.enable_manual_thumb = settings.enable_manual_thumb;
+ /* Create a default name for thumbnail image files */
+ if (p->options.enable_manual_thumb) {
+ if (strlen(filename) > 4 &&
+ !strncmp(".pdf", filename + strlen(filename) - 4, 4)) {
+ size_t len = strlen(filename) - strlen(".pdf");
+ p->thumb_basename = NEW(len+1, char);
+ strncpy(p->thumb_basename, filename, len);
+ p->thumb_basename[len] = 0;
+ } else {
+ p->thumb_basename = NEW(strlen(filename)+1, char);
+ strcpy(p->thumb_basename, filename);
+ }
+ }
+
+ p->pending_forms = NULL;
+
+ pdf_init_device(settings.device.dvi2pts, settings.device.precision,
+ settings.device.ignore_colors);
+
+
+ global_names = pdf_new_name_tree();
+
+ return;
+}
+
+void
+pdf_close_document (void)
+{
+ pdf_doc *p = &pdoc;
+
+ pdf_delete_name_tree(&global_names);
+
+ pdf_close_device();
+
+ /*
+ * Following things were kept around so user can add dictionary items.
+ */
+ pdf_doc_close_articles (p);
+ pdf_doc_close_names (p);
+ pdf_doc_close_bookmarks(p);
+ pdf_doc_close_page_tree(p);
+ pdf_doc_close_docinfo (p);
+
+ pdf_doc_close_catalog (p);
+
+ pdf_close_images();
+ pdf_close_fonts ();
+ pdf_close_colors();
+
+ pdf_close_resources(); /* Should be at last. */
+
+ pdf_files_close();
+ pdf_out_flush();
+
+ if (p->thumb_basename)
+ RELEASE(p->thumb_basename);
+
+ return;
+}
+
+/*
+ * All this routine does is give the form a name and add a unity scaling matrix.
+ * It fills in required fields. The caller must initialize the stream.
+ */
+static void
+pdf_doc_make_xform (pdf_obj *xform,
+ pdf_rect *bbox,
+ pdf_tmatrix *matrix,
+ pdf_obj *resources,
+ pdf_obj *attrib)
+{
+ pdf_obj *xform_dict;
+ pdf_obj *tmp;
+
+ xform_dict = pdf_stream_dict(xform);
+ pdf_add_dict(xform_dict,
+ pdf_new_name("Type"), pdf_new_name("XObject"));
+ pdf_add_dict(xform_dict,
+ pdf_new_name("Subtype"), pdf_new_name("Form"));
+ pdf_add_dict(xform_dict,
+ pdf_new_name("FormType"), pdf_new_number(1.0));
+
+ if (!bbox)
+ ERROR("No BoundingBox supplied.");
+
+ tmp = pdf_new_array();
+ pdf_add_array(tmp, pdf_new_number(ROUND(bbox->llx, .001)));
+ pdf_add_array(tmp, pdf_new_number(ROUND(bbox->lly, .001)));
+ pdf_add_array(tmp, pdf_new_number(ROUND(bbox->urx, .001)));
+ pdf_add_array(tmp, pdf_new_number(ROUND(bbox->ury, .001)));
+ pdf_add_dict(xform_dict, pdf_new_name("BBox"), tmp);
+
+ if (matrix) {
+ tmp = pdf_new_array();
+ pdf_add_array(tmp, pdf_new_number(ROUND(matrix->a, .00001)));
+ pdf_add_array(tmp, pdf_new_number(ROUND(matrix->b, .00001)));
+ pdf_add_array(tmp, pdf_new_number(ROUND(matrix->c, .00001)));
+ pdf_add_array(tmp, pdf_new_number(ROUND(matrix->d, .00001)));
+ pdf_add_array(tmp, pdf_new_number(ROUND(matrix->e, .001 )));
+ pdf_add_array(tmp, pdf_new_number(ROUND(matrix->f, .001 )));
+ pdf_add_dict(xform_dict, pdf_new_name("Matrix"), tmp);
+ }
+
+ if (attrib) {
+ pdf_merge_dict(xform_dict, attrib);
+ }
+
+ pdf_add_dict(xform_dict, pdf_new_name("Resources"), resources);
+
+ return;
+}
+
+/*
+ * begin_form_xobj creates an xobject with its "origin" at
+ * xpos and ypos that is clipped to the specified bbox. Note
+ * that the origin is not the lower left corner of the bbox.
+ */
+int
+pdf_doc_begin_grabbing (const char *ident,
+ double ref_x, double ref_y, const pdf_rect *cropbox)
+{
+ int xobj_id = -1;
+ pdf_doc *p = &pdoc;
+ pdf_form *form;
+ struct form_list_node *fnode;
+ xform_info info;
+
+ pdf_dev_push_gstate();
+
+ fnode = NEW(1, struct form_list_node);
+
+ fnode->prev = p->pending_forms;
+ fnode->q_depth = pdf_dev_current_depth();
+ form = &fnode->form;
+
+ /*
+ * The reference point of an Xobject is at the lower left corner
+ * of the bounding box. Since we would like to have an arbitrary
+ * reference point, we use a transformation matrix, translating
+ * the reference point to (0,0).
+ */
+
+ form->matrix.a = 1.0; form->matrix.b = 0.0;
+ form->matrix.c = 0.0; form->matrix.d = 1.0;
+ form->matrix.e = -ref_x;
+ form->matrix.f = -ref_y;
+
+ form->cropbox.llx = ref_x + cropbox->llx;
+ form->cropbox.lly = ref_y + cropbox->lly;
+ form->cropbox.urx = ref_x + cropbox->urx;
+ form->cropbox.ury = ref_y + cropbox->ury;
+
+ form->contents = pdf_new_stream(STREAM_COMPRESS);
+ form->resources = pdf_new_dict();
+
+ pdf_ximage_init_form_info(&info);
+
+ info.matrix.a = 1.0; info.matrix.b = 0.0;
+ info.matrix.c = 0.0; info.matrix.d = 1.0;
+ info.matrix.e = -ref_x;
+ info.matrix.f = -ref_y;
+
+ info.bbox.llx = cropbox->llx;
+ info.bbox.lly = cropbox->lly;
+ info.bbox.urx = cropbox->urx;
+ info.bbox.ury = cropbox->ury;
+
+ /* Use reference since content itself isn't available yet.
+ * - 2020/07/21 Changed... "forward reference" support requires object itself.
+ */
+ xobj_id = pdf_ximage_defineresource(ident,
+ PDF_XOBJECT_TYPE_FORM,
+ &info, pdf_link_obj(form->contents));
+
+ p->pending_forms = fnode;
+
+ /*
+ * Make sure the object is self-contained by adding the
+ * current font and color to the object stream.
+ */
+ pdf_dev_reset_fonts(1);
+ pdf_dev_reset_color(1); /* force color operators to be added to stream */
+ pdf_dev_reset_xgstate(1);
+
+ return xobj_id;
+}
+
+void
+pdf_doc_end_grabbing (pdf_obj *attrib)
+{
+ pdf_form *form;
+ pdf_obj *procset;
+ pdf_doc *p = &pdoc;
+ struct form_list_node *fnode;
+
+ if (!p->pending_forms) {
+ WARN("Tried to close a nonexistent form XOject.");
+ return;
+ }
+
+ fnode = p->pending_forms;
+ form = &fnode->form;
+
+ pdf_dev_grestore_to(fnode->q_depth);
+
+ /*
+ * ProcSet is obsolete in PDF-1.4 but recommended for compatibility.
+ */
+ procset = pdf_new_array();
+ pdf_add_array(procset, pdf_new_name("PDF"));
+ pdf_add_array(procset, pdf_new_name("Text"));
+ pdf_add_array(procset, pdf_new_name("ImageC"));
+ pdf_add_array(procset, pdf_new_name("ImageB"));
+ pdf_add_array(procset, pdf_new_name("ImageI"));
+ pdf_add_dict (form->resources, pdf_new_name("ProcSet"), procset);
+
+ pdf_doc_make_xform(form->contents,
+ &form->cropbox, &form->matrix,
+ pdf_ref_obj(form->resources), attrib);
+ pdf_release_obj(form->resources);
+ pdf_release_obj(form->contents);
+ if (attrib) pdf_release_obj(attrib);
+
+ p->pending_forms = fnode->prev;
+
+ pdf_dev_pop_gstate();
+
+ pdf_dev_reset_fonts(1);
+ pdf_dev_reset_color(0);
+ pdf_dev_reset_xgstate(0);
+
+ RELEASE(fnode);
+
+ return;
+}
+
+static struct
+{
+ int dirty;
+ int broken;
+ pdf_obj *annot_dict;
+ pdf_rect rect;
+} breaking_state = {0, 0, NULL, {0.0, 0.0, 0.0, 0.0}};
+
+static void
+reset_box (void)
+{
+ breaking_state.rect.llx = breaking_state.rect.lly = HUGE_VAL;
+ breaking_state.rect.urx = breaking_state.rect.ury = -HUGE_VAL;
+ breaking_state.dirty = 0;
+}
+
+void
+pdf_doc_begin_annot (pdf_obj *dict)
+{
+ breaking_state.annot_dict = dict;
+ breaking_state.broken = 0;
+ reset_box();
+}
+
+void
+pdf_doc_end_annot (void)
+{
+ pdf_doc_break_annot();
+ if (breaking_state.annot_dict)
+ pdf_release_obj(breaking_state.annot_dict);
+ breaking_state.annot_dict = NULL;
+}
+
+void
+pdf_doc_break_annot (void)
+{
+ pdf_doc *p = &pdoc;
+ double g_x = p->options.annot_grow.x;
+ double g_y = p->options.annot_grow.y;
+
+ if (breaking_state.dirty) {
+ pdf_obj *annot_dict, *annot_copy;
+ pdf_rect rect;
+
+ /* Copy dict */
+ annot_dict = breaking_state.annot_dict;
+ annot_copy = pdf_new_dict();
+ pdf_merge_dict(annot_copy, breaking_state.annot_dict);
+ breaking_state.annot_dict = annot_copy;
+ rect = breaking_state.rect;
+ rect.llx -= g_x;
+ rect.lly -= g_y;
+ rect.urx += g_x;
+ rect.ury += g_y;
+ pdf_doc_add_annot(pdf_doc_current_page_number(), &rect,
+ annot_dict, !breaking_state.broken);
+ pdf_release_obj(annot_dict);
+
+ breaking_state.broken = 1;
+ }
+ reset_box();
+}
+
+void
+pdf_doc_expand_box (const pdf_rect *rect)
+{
+ breaking_state.rect.llx = MIN(breaking_state.rect.llx, rect->llx);
+ breaking_state.rect.lly = MIN(breaking_state.rect.lly, rect->lly);
+ breaking_state.rect.urx = MAX(breaking_state.rect.urx, rect->urx);
+ breaking_state.rect.ury = MAX(breaking_state.rect.ury, rect->ury);
+ breaking_state.dirty = 1;
+}
+
+#if 0
+/* This should be number tree */
+void
+pdf_doc_set_pagelabel (int pg_start,
+ const char *type,
+ const void *prefix, int prfx_len, int start)
+{
+ pdf_doc *p = &pdoc;
+ pdf_obj *label_dict;
+
+ if (!p->root.pagelabels)
+ p->root.pagelabels = pdf_new_array();
+
+ label_dict = pdf_new_dict();
+ if (!type || type[0] == '\0') /* Set back to default. */
+ pdf_add_dict(label_dict, pdf_new_name("S"), pdf_new_name("D"));
+ else {
+ if (type)
+ pdf_add_dict(label_dict, pdf_new_name("S"), pdf_new_name(type));
+ if (prefix && prfx_len > 0)
+ pdf_add_dict(label_dict,
+ pdf_new_name("P"),
+ pdf_new_string(prefix, prfx_len));
+ if (start != 1)
+ pdf_add_dict(label_dict,
+ pdf_new_name("St"), pdf_new_number(start));
+ }
+
+ pdf_add_array(p->root.pagelabels, pdf_new_number(pg_start));
+ pdf_add_array(p->root.pagelabels, label_dict);
+
+ return;
+}
+#endif
diff --git a/Build/source/texk/dvipdfm-x/pdfdoc.h b/Build/source/texk/dvipdfm-x/pdfdoc.h
new file mode 100644
index 00000000000..bd8bf3bedaa
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfdoc.h
@@ -0,0 +1,176 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFDOC_H_
+#define _PDFDOC_H_
+
+#include "pdfobj.h"
+#include "pdfdev.h"
+
+enum pdf_page_boundary
+{
+ pdf_page_boundary__auto = 0,
+ pdf_page_boundary_mediabox,
+ pdf_page_boundary_cropbox,
+ pdf_page_boundary_artbox,
+ pdf_page_boundary_trimbox,
+ pdf_page_boundary_bleedbox
+};
+
+#define PDF_DOC_GRABBING_NEST_MAX 4
+
+struct pdf_dev_setting {
+ double dvi2pts; /* conversion unit */
+ int precision; /* number of decimal digits kept */
+ int ignore_colors; /* 1 for black or white */
+};
+
+struct pdf_enc_setting {
+ int key_size;
+ uint32_t permission;
+ const char *uplain, *oplain; /* password */
+ int use_aes;
+ int encrypt_metadata;
+};
+
+struct pdf_obj_setting {
+ int enable_objstm;
+ int enable_predictor;
+ int compression_level;
+};
+
+struct pdf_setting
+{
+ int ver_major, ver_minor;
+ double media_width, media_height;
+ struct {
+ double x, y;
+ } annot_grow_amount;
+ int outline_open_depth;
+ int check_gotos;
+ int enable_manual_thumb;
+ int enable_encrypt;
+ struct pdf_enc_setting encrypt;
+ struct pdf_dev_setting device;
+ struct pdf_obj_setting object;
+};
+
+extern void pdf_open_document (const char *filename,
+ const char *creator,
+ const unsigned char *id1,
+ const unsigned char *id2,
+ struct pdf_setting settings);
+extern void pdf_close_document(void);
+
+/* They just return PDF dictionary object.
+ * Callers are completely responsible for doing right thing...
+ */
+extern pdf_obj *pdf_doc_get_dictionary(const char *category);
+extern pdf_obj *pdf_doc_get_reference(const char *category);
+
+#define pdf_doc_page_tree() pdf_doc_get_dictionary("Pages")
+#define pdf_doc_catalog() pdf_doc_get_dictionary("Catalog")
+#define pdf_doc_docinfo() pdf_doc_get_dictionary("Info")
+#define pdf_doc_names() pdf_doc_get_dictionary("Names")
+#define pdf_doc_this_page() pdf_doc_get_dictionary("@THISPAGE")
+
+extern int pdf_doc_get_page_count(pdf_file *pf);
+extern pdf_obj *pdf_doc_get_page(pdf_file *pf, int page_no, enum pdf_page_boundary opt_bbox,
+ pdf_rect *bbox, pdf_tmatrix *matrix, pdf_obj **resources_p);
+
+extern int pdf_doc_current_page_number(void);
+extern pdf_obj *pdf_doc_current_page_resources(void);
+
+extern pdf_obj *pdf_doc_ref_page(unsigned page_no);
+#define pdf_doc_this_page_ref() pdf_doc_get_reference("@THISPAGE")
+#define pdf_doc_next_page_ref() pdf_doc_get_reference("@NEXTPAGE")
+#define pdf_doc_prev_page_ref() pdf_doc_get_reference("@PREVPAGE")
+
+/* Not really managing tree...
+ * There should be something for number tree.
+ */
+extern int pdf_doc_add_names(const char *category,
+ const void *key, int keylen, pdf_obj *value);
+
+extern void pdf_doc_set_bop_content(const char *str, unsigned length);
+extern void pdf_doc_set_eop_content(const char *str, unsigned length);
+
+/* Page */
+extern void pdf_doc_begin_page(double scale, double x_origin, double y_origin);
+extern void pdf_doc_end_page(void);
+
+extern void pdf_doc_set_mediabox(unsigned page_no, const pdf_rect *mediabox);
+
+extern void pdf_doc_add_page_content(const char *buffer, unsigned length);
+extern void pdf_doc_add_page_resource(const char *category,
+ const char *resource_name, pdf_obj *resources);
+
+/* Article thread */
+extern void pdf_doc_begin_article(const char *article_id, pdf_obj *info);
+extern void pdf_doc_add_bead(const char *article_id,
+ const char *bead_id,
+ int page_no, const pdf_rect *rect);
+
+/* Bookmarks */
+extern int pdf_doc_bookmarks_up(void);
+extern int pdf_doc_bookmarks_down(void);
+extern void pdf_doc_bookmarks_add(pdf_obj *dict, int is_open);
+extern int pdf_doc_bookmarks_depth(void);
+
+/* Returns xobj_id of started xform. */
+extern int pdf_doc_begin_grabbing(const char *ident,
+ double ref_x, double ref_y,
+ const pdf_rect *cropbox);
+extern void pdf_doc_end_grabbing(pdf_obj *attrib);
+
+/* Annotation */
+extern void pdf_doc_add_annot(unsigned page_no,
+ const pdf_rect *rect,
+ pdf_obj *annot_dict,
+ int new_annot);
+
+/* Annotation with auto- clip and line (or page) break */
+extern void pdf_doc_begin_annot(pdf_obj *dict);
+extern void pdf_doc_end_annot(void);
+
+extern void pdf_doc_break_annot(void);
+extern void pdf_doc_expand_box(const pdf_rect *rect);
+
+/* Manual thumbnail */
+extern void pdf_doc_enable_manual_thumbnails(void);
+
+#if 0
+/* PageLabels - */
+extern void pdf_doc_set_pagelabel (int page_start,
+ const char *type,
+ const void *prefix, int pfrx_len,
+ int counter_start);
+#endif
+
+/* Similar to bop_content */
+#include "pdfcolor.h"
+extern void pdf_doc_set_bgcolor(const pdf_color *color);
+
+/* Sorry no appropriate place to put this... */
+extern struct ht_table *global_names;
+
+#endif /* _PDFDOC_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfdraw.c b/Build/source/texk/dvipdfm-x/pdfdraw.c
new file mode 100644
index 00000000000..66549e193b1
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfdraw.c
@@ -0,0 +1,1888 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+#include "mfileio.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+#include "numbers.h"
+
+#include "pdfdoc.h"
+#include "pdfdev.h"
+#include "pdfcolor.h"
+#include "pdfparse.h"
+#include "pdfobj.h"
+
+#include "pdfdraw.h"
+
+#define OUR_EPSILON 2.5e-16
+
+/*
+ * Numbers are rounding to 0-5 fractional digits
+ * in output routine.
+ */
+#define detM(M) ((M).a * (M).d - (M).b * (M).c)
+#define detP(M) ((M)->a * (M)->d - (M)->b * (M)->c)
+
+
+static /* __inline__ */ int
+inversematrix (pdf_tmatrix *W, const pdf_tmatrix *M)
+{
+ double det;
+
+ det = detP(M);
+ if (fabs(det) < OUR_EPSILON) {
+ WARN("Inverting matrix with zero determinant...");
+ return -1; /* result is undefined. */
+ }
+
+ W->a = (M->d) / det; W->b = -(M->b) / det;
+ W->c = -(M->c) / det; W->d = (M->a) / det;
+ W->e = (M->c) * (M->f) - (M->d) * (M->e);
+ W->f = (M->b) * (M->e) - (M->a) * (M->f);
+ W->e /= det;
+ W->f /= det;
+
+ return 0;
+}
+
+/* pdf_coord as vector */
+#define vecprd(v,w) ((v).x * (w).x + (v).y * (w).y)
+#define vecrot(v,w) ((v).x * (w).y - (v).y * (w).x)
+#define dsign(v) (((v) >= 0.0) ? 1.0 : -1.0)
+/* acos => [0, pi] */
+#define vecang(v,w) ( \
+ dsign(vecrot((v),(w))) * \
+ acos(vecprd((v),(w)) / sqrt(vecprd((v),(v)) * vecprd((w),(w)))) \
+)
+
+static /* __inline__ */ int
+pdf_coord__equal (const pdf_coord *p1, const pdf_coord *p2)
+{
+ if (fabs(p1->x - p2->x) < 1.e-7 &&
+ fabs(p1->y - p2->y) < 1.e-7)
+ return 1;
+ return 0;
+}
+#define COORD_EQUAL(p,q) pdf_coord__equal((p),(q))
+
+#if 0
+static int
+pdf_coord__sort_compar_X (const void *pp1, const void *pp2)
+{
+ pdf_coord *p1 = (pdf_coord *)pp1;
+ pdf_coord *p2 = (pdf_coord *)pp2;
+
+ if (pdf_coord__equal(p1, p2))
+ return 0;
+ else
+ return (int) dsign(p1->x - p2->x);
+
+ return 1;
+}
+
+static int
+pdf_coord__sort_compar_Y (const void *pp1, const void *pp2)
+{
+ pdf_coord *p1 = (pdf_coord *)pp1;
+ pdf_coord *p2 = (pdf_coord *)pp2;
+
+ if (pdf_coord__equal(p1, p2))
+ return 0;
+ else
+ return (int) dsign(p1->y - p2->y);
+
+ return 1;
+}
+#endif
+
+
+static /* __inline__ */ int
+pdf_coord__transform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ double x, y;
+
+ x = p->x; y = p->y;
+ p->x = x * M->a + y * M->c + M->e;
+ p->y = x * M->b + y * M->d + M->f;
+
+ return 0;
+}
+
+static /* __inline__ */ int
+pdf_coord__itransform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ pdf_tmatrix W;
+ double x, y;
+ int error;
+
+ error = inversematrix(&W, M);
+ if (error)
+ return error;
+
+ x = p->x; y = p->y;
+ p->x = x * W.a + y * W.c + W.e;
+ p->y = x * W.b + y * W.d + W.f;
+
+ return 0;
+}
+
+static /* __inline__ */ int
+pdf_coord__dtransform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ double x, y;
+
+ x = p->x; y = p->y;
+ p->x = x * M->a + y * M->c;
+ p->y = x * M->b + y * M->d;
+
+ return 0;
+}
+
+static /* __inline__ */ int
+pdf_coord__idtransform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ pdf_tmatrix W;
+ double x, y;
+ int error;
+
+ error = inversematrix(&W, M);
+ if (error)
+ return error;
+
+ x = p->x; y = p->y;
+ p->x = x * W.a + y * W.c;
+ p->y = x * W.b + y * W.d;
+
+ return 0;
+}
+
+
+/* Modify M itself */
+void
+pdf_invertmatrix (pdf_tmatrix *M)
+{
+ pdf_tmatrix W;
+ double det;
+
+ ASSERT(M);
+
+ det = detP(M);
+ if (fabs(det) < OUR_EPSILON) {
+ WARN("Inverting matrix with zero determinant...");
+ W.a = 1.0; W.c = 0.0;
+ W.b = 0.0; W.d = 1.0;
+ W.e = 0.0; W.f = 0.0;
+ } else {
+ W.a = (M->d) / det; W.b = -(M->b) / det;
+ W.c = -(M->c) / det; W.d = (M->a) / det;
+ W.e = (M->c) * (M->f) - (M->d) * (M->e);
+ W.f = (M->b) * (M->e) - (M->a) * (M->f);
+ W.e /= det; W.f /= det;
+ }
+
+ pdf_copymatrix(M, &W);
+
+ return;
+}
+
+
+typedef struct pa_elem_
+{
+ int type;
+ pdf_coord p[3];
+} pa_elem;
+
+/* each subpath delimitted by moveto */
+struct pdf_path_
+{
+ int num_paths;
+ int max_paths;
+ pa_elem *path;
+};
+
+static const struct {
+ char opchr; /* PDF operator char */
+ int n_pts; /* number of *points* */
+ const char *strkey;
+} petypes[] = {
+#define PE_TYPE__INVALID -1
+#define PE_TYPE__MOVETO 0
+ {'m', 1, "moveto" },
+#define PE_TYPE__LINETO 1
+ {'l', 1, "lineto" },
+#define PE_TYPE__CURVETO 2
+ {'c', 3, "curveto" },
+ /* no PS correspondence for v and y */
+#define PE_TYPE__CURVETO_V 3
+ {'v', 2, "vcurveto"}, /* current point replicated */
+#define PE_TYPE__CURVETO_Y 4
+ {'y', 2, "ycurveto"}, /* last point replicated */
+#define PE_TYPE__CLOSEPATH 5
+ {'h', 0, "closepath"},
+#define PE_TYPE__TERMINATE 6
+ {' ', 0, NULL}
+};
+
+#define PE_VALID(p) ((p) && \
+ (p)->type > PE_TYPE__INVALID && (p)->type < PE_TYPE__TERMINATE)
+#define PE_N_PTS(p) (PE_VALID((p)) ? petypes[(p)->type].n_pts : 0)
+#define PE_OPCHR(p) (PE_VALID((p)) ? petypes[(p)->type].opchr : ' ')
+
+#define PA_LENGTH(pa) ((pa)->num_paths)
+
+#define GS_FLAG_CURRENTPOINT_SET (1 << 0)
+
+
+#define FORMAT_BUFF_LEN 1024
+static char fmt_buf[FORMAT_BUFF_LEN];
+
+static void
+init_a_path (pdf_path *p)
+{
+ ASSERT(p);
+
+ p->num_paths = 0;
+ p->max_paths = 0;
+ p->path = NULL;
+
+ return;
+}
+
+static void
+pdf_path__clearpath (pdf_path *p)
+{
+ ASSERT(p);
+
+ p->num_paths = 0;
+
+ return;
+}
+
+static int
+pdf_path__growpath (pdf_path *p, int max_pe)
+{
+ if (max_pe < p->max_paths)
+ return 0;
+
+ p->max_paths = MAX(p->max_paths + 8, max_pe);
+ p->path = RENEW(p->path, p->max_paths, pa_elem);
+
+ return 0;
+}
+
+static void
+clear_a_path (pdf_path *p)
+{
+ ASSERT(p);
+
+ if (p->path)
+ RELEASE(p->path);
+ p->path = NULL;
+ p->num_paths = 0;
+ p->max_paths = 0;
+
+ return;
+}
+
+static int
+pdf_path__copypath (pdf_path *p1, const pdf_path *p0)
+{
+ pa_elem *pe0, *pe1;
+ int i;
+
+ pdf_path__growpath(p1, PA_LENGTH(p0));
+ for (i = 0; i < PA_LENGTH(p0); i++) {
+ pe1 = &(p1->path[i]);
+ pe0 = &(p0->path[i]);
+ /* FIXME */
+ pe1->type = pe0->type;
+ pe1->p[0].x = pe0->p[0].x;
+ pe1->p[0].y = pe0->p[0].y;
+ pe1->p[1].x = pe0->p[1].x;
+ pe1->p[1].y = pe0->p[1].y;
+ pe1->p[2].x = pe0->p[2].x;
+ pe1->p[2].y = pe0->p[2].y;
+ }
+ p1->num_paths = PA_LENGTH(p0);
+
+ return 0;
+}
+
+
+/* start new subpath */
+static int
+pdf_path__moveto (pdf_path *pa,
+ pdf_coord *cp,
+ const pdf_coord *p0)
+{
+ pa_elem *pe;
+
+ pdf_path__growpath(pa, PA_LENGTH(pa) + 1);
+ if (PA_LENGTH(pa) > 0) {
+ pe = &pa->path[pa->num_paths-1];
+ if (pe->type == PE_TYPE__MOVETO) {
+ pe->p[0].x = cp->x = p0->x;
+ pe->p[0].y = cp->y = p0->y;
+ return 0;
+ }
+ }
+ pe = &pa->path[pa->num_paths++];
+ pe->type = PE_TYPE__MOVETO;
+ pe->p[0].x = cp->x = p0->x;
+ pe->p[0].y = cp->y = p0->y;
+
+ return 0;
+}
+
+/* Do 'compression' of path while adding new path elements.
+ * Sequantial moveto command will be replaced with a
+ * single moveto. If cp is not equal to the last point in pa,
+ * then moveto is inserted (starting new subpath).
+ * FIXME:
+ * 'moveto' must be used to enforce starting new path.
+ * This affects how 'closepath' is treated.
+ */
+static pa_elem *
+pdf_path__next_pe (pdf_path *pa, const pdf_coord *cp)
+{
+ pa_elem *pe;
+
+ pdf_path__growpath(pa, PA_LENGTH(pa) + 2);
+ if (PA_LENGTH(pa) == 0) {
+ pe = &pa->path[pa->num_paths++];
+ pe->type = PE_TYPE__MOVETO;
+ pe->p[0].x = cp->x;
+ pe->p[0].y = cp->y;
+
+ return &pa->path[pa->num_paths++];
+ }
+
+ pe = &pa->path[pa->num_paths-1];
+ switch (pe->type) {
+ case PE_TYPE__MOVETO:
+ pe->p[0].x = cp->x;
+ pe->p[0].y = cp->y;
+ break;
+ case PE_TYPE__LINETO:
+ if (!COORD_EQUAL(&pe->p[0], cp)) {
+ pe = &pa->path[pa->num_paths++];
+ pe->type = PE_TYPE__MOVETO;
+ pe->p[0].x = cp->x;
+ pe->p[0].y = cp->y;
+ }
+ break;
+ case PE_TYPE__CURVETO:
+ if (!COORD_EQUAL(&pe->p[2], cp)) {
+ pe = &pa->path[pa->num_paths++];
+ pe->type = PE_TYPE__MOVETO;
+ pe->p[0].x = cp->x;
+ pe->p[0].y = cp->y;
+ }
+ break;
+ case PE_TYPE__CURVETO_Y:
+ case PE_TYPE__CURVETO_V:
+ if (!COORD_EQUAL(&pe->p[1], cp)) {
+ pe = &pa->path[pa->num_paths++];
+ pe->type = PE_TYPE__MOVETO;
+ pe->p[0].x = cp->x;
+ pe->p[0].y = cp->y;
+ }
+ break;
+ case PE_TYPE__CLOSEPATH:
+ pe = &pa->path[pa->num_paths++];
+ pe->type = PE_TYPE__MOVETO;
+ pe->p[0].x = cp->x;
+ pe->p[0].y = cp->y;
+ break;
+ }
+
+ return &pa->path[pa->num_paths++];
+}
+
+static int
+pdf_path__transform (pdf_path *pa, const pdf_tmatrix *M)
+{
+ pa_elem *pe;
+ int n = 0, i;
+
+ ASSERT(pa && M);
+
+ for (i = 0; i < PA_LENGTH(pa); i++) {
+ pe = &(pa->path[i]);
+ n = PE_N_PTS(pe);
+ while (n-- > 0)
+ pdf_coord__transform(&(pe->p[n]), M);
+ }
+
+ return 0;
+}
+
+
+/* Path Construction */
+static int
+pdf_path__lineto (pdf_path *pa,
+ pdf_coord *cp,
+ const pdf_coord *p0)
+{
+ pa_elem *pe;
+
+ pe = pdf_path__next_pe(pa, cp);
+ pe->type = PE_TYPE__LINETO;
+ pe->p[0].x = cp->x = p0->x;
+ pe->p[0].y = cp->y = p0->y;
+
+ return 0;
+}
+
+static int
+pdf_path__curveto (pdf_path *pa,
+ pdf_coord *cp,
+ const pdf_coord *p0,
+ const pdf_coord *p1,
+ const pdf_coord *p2
+ )
+{
+ pa_elem *pe;
+
+ pe = pdf_path__next_pe(pa, cp);
+ if (COORD_EQUAL(cp, p0)) {
+ pe->type = PE_TYPE__CURVETO_V;
+ pe->p[0].x = p1->x;
+ pe->p[0].y = p1->y;
+ pe->p[1].x = cp->x = p2->x;
+ pe->p[1].y = cp->y = p2->y;
+ } else if (COORD_EQUAL(p1, p2)) {
+ pe->type = PE_TYPE__CURVETO_Y;
+ pe->p[0].x = p0->x;
+ pe->p[0].y = p0->y;
+ pe->p[1].x = cp->x = p1->x;
+ pe->p[1].y = cp->y = p1->y;
+ } else {
+ pe->type = PE_TYPE__CURVETO;
+ pe->p[0].x = p0->x;
+ pe->p[0].y = p0->y;
+ pe->p[1].x = p1->x;
+ pe->p[1].y = p1->y;
+ pe->p[2].x = cp->x = p2->x;
+ pe->p[2].y = cp->y = p2->y;
+ }
+
+ return 0;
+}
+
+#if 0
+#define QB_TWO_THIRD (2.0/3.0)
+#define QB_ONE_THIRD (1.0/3.0)
+
+static int
+pdf_path__curveto_QB (pdf_path *pa,
+ pdf_coord *cp,
+ const pdf_coord *p0,
+ const pdf_coord *p1
+ )
+{
+ pdf_coord q0, q1;
+
+ q0.x = cp->x + QB_TWO_THIRD * (p0->x - cp->x);
+ q0.y = cp->y + QB_TWO_THIRD * (p0->y - cp->y);
+ q1.x = p0->x + QB_ONE_THIRD * (p1->x - p0->x);
+ q1.y = p0->y + QB_ONE_THIRD * (p1->y - p0->y);
+ /* q2 == p1 */
+
+ return pdf_path__curveto(pa, cp, &q0, &q1, p1);
+}
+#endif
+
+
+/* This isn't specified as cp to somewhere. */
+static int
+pdf_path__elliptarc (pdf_path *pa,
+ pdf_coord *cp,
+ const pdf_coord *ca, /* ellipsis center */
+ double r_x, /* x radius */
+ double r_y, /* y radius */
+ double xar, /* x-axis-rotation (deg!) */
+ double a_0, /* start angle */
+ double a_1, /* stop angle */
+ int a_d /* arc orientation */
+ )
+{
+ double b, b_x, b_y;
+ double d_a, q;
+ pdf_coord p0, p1, p2, p3;
+ pdf_coord e0, e1;
+ pdf_tmatrix T;
+ int n_c; /* number of segments */
+ int i, error = 0;
+
+ if (fabs(r_x) < OUR_EPSILON ||
+ fabs(r_y) < OUR_EPSILON)
+ return -1;
+
+ if (a_d < 0) {
+ for ( ; a_1 > a_0; a_1 -= 360.0);
+ } else {
+ for ( ; a_1 < a_0; a_0 -= 360.0);
+ }
+
+ d_a = a_1 - a_0;
+ for (n_c = 1; fabs(d_a) > 90.0 * n_c; n_c++);
+ d_a /= n_c;
+ if (fabs(d_a) < OUR_EPSILON)
+ return -1;
+
+ a_0 *= M_PI / 180.0;
+ a_1 *= M_PI / 180.0;
+ d_a *= M_PI / 180.0;
+ xar *= M_PI / 180.0;
+ T.a = cos(xar); T.c = -sin(xar);
+ T.b = -T.c ; T.d = T.a;
+ T.e = 0.0 ; T.f = 0.0;
+
+ /* A parameter that controls cb-curve (off-curve) points */
+ b = 4.0 * (1.0 - cos(.5 * d_a)) / (3.0 * sin(.5 * d_a));
+ b_x = r_x * b;
+ b_y = r_y * b;
+
+ p0.x = r_x * cos(a_0);
+ p0.y = r_y * sin(a_0);
+ pdf_coord__transform(&p0, &T);
+ p0.x += ca->x; p0.y += ca->y;
+ if (PA_LENGTH(pa) == 0) {
+ pdf_path__moveto(pa, cp, &p0);
+ } else if (!COORD_EQUAL(cp, &p0)) {
+ pdf_path__lineto(pa, cp, &p0); /* add line seg */
+ }
+ for (i = 0; !error && i < n_c; i++) {
+ q = a_0 + i * d_a;
+ e0.x = cos(q); e0.y = sin(q);
+ e1.x = cos(q + d_a); e1.y = sin(q + d_a);
+
+ /* Condition for tangent vector requirs
+ * d1 = p1 - p0 = f ( sin a, -cos a)
+ * d2 = p2 - p3 = g ( sin b, -cos b)
+ * and from symmetry
+ * g^2 = f^2
+ */
+ p0.x = r_x * e0.x; /* s.p. */
+ p0.y = r_y * e0.y;
+ p3.x = r_x * e1.x; /* e.p. */
+ p3.y = r_y * e1.y;
+
+ p1.x = -b_x * e0.y;
+ p1.y = b_y * e0.x;
+ p2.x = b_x * e1.y;
+ p2.y = -b_y * e1.x;
+
+ pdf_coord__transform(&p0, &T);
+ pdf_coord__transform(&p1, &T);
+ pdf_coord__transform(&p2, &T);
+ pdf_coord__transform(&p3, &T);
+ p0.x += ca->x; p0.y += ca->y;
+ p3.x += ca->x; p3.y += ca->y;
+ p1.x += p0.x ; p1.y += p0.y ;
+ p2.x += p3.x ; p2.y += p3.y ;
+
+ error = pdf_path__curveto(pa, &p0, &p1, &p2, &p3);
+ cp->x = p3.x; cp->y = p3.y;
+ }
+
+ return error;
+}
+
+static int
+pdf_path__closepath (pdf_path *pa, pdf_coord *cp /* no arg */)
+{
+ pa_elem *pe = NULL;
+ int i;
+
+ /* search for start point of the last subpath */
+ for (i = PA_LENGTH(pa) - 1; i >= 0; i--) {
+ pe = &pa->path[i];
+ if (pe->type == PE_TYPE__MOVETO)
+ break;
+ }
+
+ if (!pe || i < 0)
+ return -1; /* No path or no start point(!) */
+
+ cp->x = pe->p[0].x;
+ cp->y = pe->p[0].y;
+
+ pdf_path__growpath(pa, PA_LENGTH(pa) + 1);
+
+ /* NOTE:
+ * Manually closed path without closepath is not
+ * affected by linejoin. A path with coincidental
+ * starting and ending point is not the same as
+ * 'closed' path.
+ */
+ pe = &pa->path[pa->num_paths++];
+ pe->type = PE_TYPE__CLOSEPATH;
+
+ return 0;
+}
+
+/*
+ * x y width height re
+ *
+ * is equivalent to
+ *
+ * x y m
+ * (x + width) y l
+ * (x + width) (y + height) l
+ * x (y + height) l
+ * h
+ */
+/* Just for quick test */
+static /* __inline__ */ int
+pdf_path__isarect (pdf_path *pa,
+ int f_ir /* fill-rule is ignorable */
+ )
+{
+ pa_elem *pe0, *pe1, *pe2, *pe3, *pe4;
+
+ if (PA_LENGTH(pa) == 5) {
+ pe0 = &(pa->path[0]);
+ pe1 = &(pa->path[1]);
+ pe2 = &(pa->path[2]);
+ pe3 = &(pa->path[3]);
+ pe4 = &(pa->path[4]);
+ if (pe0->type == PE_TYPE__MOVETO &&
+ pe1->type == PE_TYPE__LINETO &&
+ pe2->type == PE_TYPE__LINETO &&
+ pe3->type == PE_TYPE__LINETO &&
+ pe4->type == PE_TYPE__CLOSEPATH) {
+ if (pe1->p[0].y - pe0->p[0].y == 0 &&
+ pe2->p[0].x - pe1->p[0].x == 0 &&
+ pe3->p[0].y - pe2->p[0].y == 0) {
+ if (pe1->p[0].x - pe0->p[0].x
+ == pe2->p[0].x - pe3->p[0].x) {
+ return 1;
+ }
+ /* Winding number is different but ignore it here. */
+ } else if (f_ir &&
+ pe1->p[0].x - pe0->p[0].x == 0 &&
+ pe2->p[0].y - pe1->p[0].y == 0 &&
+ pe3->p[0].x - pe2->p[0].x == 0) {
+ if (pe1->p[0].y - pe0->p[0].y
+ == pe2->p[0].y - pe3->p[0].y) {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Path Painting */
+/* F is obsoleted */
+#define PT_OP_VALID(c) ( \
+ (c) == 'f' || (c) == 'F' || \
+ (c) == 's' || (c) == 'S' || \
+ (c) == 'b' || (c) == 'B' || \
+ (c) == 'W' \
+)
+
+static /* __inline__ */ int
+INVERTIBLE_MATRIX (const pdf_tmatrix *M)
+{
+ if (fabs(detP(M)) < OUR_EPSILON) {
+ WARN("Transformation matrix not invertible.");
+ WARN("--- M = [%g %g %g %g %g %g]",
+ M->a, M->b, M->c, M->d, M->e, M->f);
+ return -1;
+ }
+ return 0;
+}
+
+/* rectfill, rectstroke, rectclip, recteoclip
+ *
+ * Draw isolated rectangle without actually doing gsave/grestore operation.
+ *
+ * TODO:
+ * linestyle, fill-opacity, stroke-opacity,....
+ * As this routine draw a single graphics object
+ * each time, there should be options for specifying
+ * various drawing styles, which might inherite
+ * current graphcs state parameter.
+ */
+static int
+pdf_dev__rectshape (const pdf_rect *r,
+ const pdf_tmatrix *M,
+ char opchr
+ )
+{
+ char *buf = fmt_buf;
+ int len = 0;
+ int isclip = 0;
+ pdf_coord p;
+ double wd, ht;
+
+ ASSERT(r && PT_OP_VALID(opchr));
+
+ isclip = (opchr == 'W') ? 1 : 0;
+
+ /* disallow matrix for clipping.
+ * q ... clip Q does nothing and
+ * n M cm ... clip n alter CTM.
+ */
+ if (M && (isclip ||
+ !INVERTIBLE_MATRIX(M)))
+ return -1;
+
+ graphics_mode();
+
+ if (!isclip) {
+ pdf_dev_gsave();
+ }
+ pdf_dev_newpath();
+ if (!isclip && M) {
+ pdf_dev_concat(M);
+ }
+
+ p.x = r->llx; p.y = r->lly;
+ wd = r->urx - r->llx;
+ ht = r->ury - r->lly;
+ buf[len++] = ' ';
+ len += pdf_sprint_coord (buf + len, &p);
+ buf[len++] = ' ';
+ len += pdf_sprint_length(buf + len, wd);
+ buf[len++] = ' ';
+ len += pdf_sprint_length(buf + len, ht);
+ buf[len++] = ' ';
+ buf[len++] = 'r'; buf[len++] = 'e';
+
+ buf[len++] = ' ';
+ buf[len++] = opchr;
+
+ pdf_doc_add_page_content(buf, len);
+
+ if (isclip) {
+ pdf_dev_newpath();
+ } else {
+ pdf_dev_grestore();
+ }
+
+ return 0;
+}
+
+/* FIXME */
+static int
+pdf_dev__flushpath (pdf_path *pa,
+ char opchr,
+ int rule,
+ int ignore_rule)
+{
+ pa_elem *pe, *pe1;
+ char *b = fmt_buf;
+ int b_len = FORMAT_BUFF_LEN;
+ pdf_rect r; /* FIXME */
+ pdf_coord *pt;
+ int n_pts, n_seg;
+ int len = 0;
+ int isrect, i, j;
+
+ ASSERT(pa && PT_OP_VALID(opchr));
+
+ if (PA_LENGTH(pa) <= 0)
+ return 0;
+
+ graphics_mode();
+ isrect = pdf_path__isarect(pa, ignore_rule);
+ if (isrect) {
+ pe = &(pa->path[0]);
+ pe1 = &(pa->path[2]);
+
+ r.llx = pe->p[0].x;
+ r.lly = pe->p[0].y;
+ r.urx = pe1->p[0].x - pe->p[0].x; /* width... */
+ r.ury = pe1->p[0].y - pe->p[0].y; /* height... */
+
+ b[len++] = ' ';
+ len += pdf_sprint_rect(b + len, &r);
+ b[len++] = ' ';
+ b[len++] = 'r';
+ b[len++] = 'e';
+ pdf_doc_add_page_content(b, len); /* op: re */
+ len = 0;
+ } else {
+ n_seg = PA_LENGTH(pa);
+ for (i = 0, len = 0, pe = &pa->path[0];
+ i < n_seg; pe++, i++) {
+ n_pts = PE_N_PTS(pe);
+ for (j = 0, pt = &pe->p[0];
+ j < n_pts; j++, pt++) {
+ b[len++] = ' ';
+ len += pdf_sprint_coord(b + len, pt);
+ }
+ b[len++] = ' ';
+ b[len++] = PE_OPCHR(pe);
+ if (len + 128 > b_len) {
+ pdf_doc_add_page_content(b, len); /* op: m l c v y h */
+ len = 0;
+ }
+ }
+ if (len > 0) {
+ pdf_doc_add_page_content(b, len); /* op: m l c v y h */
+ len = 0;
+ }
+ }
+
+ b[len++] = ' ';
+ b[len++] = opchr;
+ if (rule == PDF_FILL_RULE_EVENODD)
+ b[len++] = '*';
+
+ pdf_doc_add_page_content(b, len); /* op: f F s S b B W f* F* s* S* b* B* W* */
+
+ return 0;
+}
+
+/* ExtGState stack */
+static dpx_stack xgs_stack;
+static int xgs_count = 0;
+
+struct xgs_res {
+ pdf_obj *object;
+ pdf_obj *accumlated;
+};
+
+static const char default_xgs[] = "\
+<< /Type /ExtGState\
+ /LW 1 /LC 0 /LJ 0 /ML 10 /D [[] 0]\
+ /RI /RelativeColorimetric /SA false /BM /Normal /SMask /None\
+ /AIS false /TK false /CA 1 /ca 1\
+ /OP false /op false /OPM 0 /FL 1\
+>>";
+
+static void
+init_xgstate (void)
+{
+ dpx_stack_init(&xgs_stack);
+ xgs_count = 0;
+
+ return;
+}
+
+static void
+clear_xgstate (void)
+{
+ struct xgs_res *xgs;
+
+ while ((xgs = dpx_stack_pop(&xgs_stack)) != NULL) {
+ pdf_release_obj(xgs->object);
+ pdf_release_obj(xgs->accumlated);
+ RELEASE(xgs);
+ }
+
+ return;
+}
+
+/* Graphics State */
+typedef struct pdf_gstate_
+{
+ pdf_coord cp;
+
+ pdf_tmatrix matrix; /* cm, - */
+
+ pdf_color strokecolor;
+ pdf_color fillcolor;
+ /* colorspace here */
+
+ struct {
+ int num_dash;
+ double pattern[PDF_DASH_SIZE_MAX];
+ double offset;
+ } linedash; /* d, D */
+
+ double linewidth; /* w, LW */
+
+ int linecap; /* J, LC */
+ int linejoin; /* j, LJ */
+ double miterlimit; /* M, ML */
+
+ int flatness; /* i, FL, 0 to 100 (0 for use device-default) */
+
+ /* internal */
+ pdf_path path;
+ int flags;
+
+ pdf_obj *extgstate;
+} pdf_gstate;
+
+static dpx_stack gs_stack;
+
+static void
+init_a_gstate (pdf_gstate *gs)
+{
+ gs->cp.x = 0.0;
+ gs->cp.y = 0.0;
+
+ pdf_setmatrix(&gs->matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+
+ pdf_color_black(&gs->strokecolor);
+ pdf_color_black(&gs->fillcolor);
+
+ gs->linedash.num_dash = 0;
+ gs->linedash.offset = 0;
+ gs->linecap = 0;
+ gs->linejoin = 0;
+ gs->linewidth = 1.0;
+ gs->miterlimit = 10.0;
+
+ gs->flatness = 1; /* default to 1 in PDF */
+
+ /* Internal variables */
+ gs->flags = 0;
+ init_a_path(&gs->path);
+
+ gs->extgstate = NULL;
+
+ return;
+}
+
+static void
+clear_a_gstate (pdf_gstate *gs)
+{
+ clear_a_path(&gs->path);
+ if (gs->extgstate)
+ pdf_release_obj(gs->extgstate);
+ memset(gs, 0, sizeof(pdf_gstate));
+
+ return;
+}
+
+static void
+copy_a_gstate (pdf_gstate *gs1, pdf_gstate *gs2)
+{
+ int i;
+
+ ASSERT(gs1 && gs2);
+
+ gs1->cp.x = gs2->cp.x;
+ gs1->cp.y = gs2->cp.y;
+
+ pdf_copymatrix(&gs1->matrix, &gs2->matrix);
+
+ /* TODO:
+ * Path should be linked list and gsave only
+ * record starting point within path rather than
+ * copying whole path.
+ */
+ pdf_path__copypath(&gs1->path, &gs2->path);
+
+ gs1->linedash.num_dash = gs2->linedash.num_dash;
+ for (i = 0; i < gs2->linedash.num_dash; i++) {
+ gs1->linedash.pattern[i] = gs2->linedash.pattern[i];
+ }
+ gs1->linedash.offset = gs2->linedash.offset;
+
+ gs1->linecap = gs2->linecap;
+ gs1->linejoin = gs2->linejoin;
+ gs1->linewidth = gs2->linewidth;
+ gs1->miterlimit = gs2->miterlimit;
+ gs1->flatness = gs2->flatness;
+
+ pdf_color_copycolor(&gs1->fillcolor , &gs2->fillcolor);
+ pdf_color_copycolor(&gs1->strokecolor, &gs2->strokecolor);
+
+ gs1->extgstate = gs2->extgstate ? pdf_link_obj(gs2->extgstate) : NULL;
+
+ return;
+}
+
+static int
+pdf_dev_set_xgstate (pdf_obj *diff, pdf_obj *accumlated)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ char buf[64], res_name[16];
+ int len = 0, id;
+
+ id = xgs_count;
+ snprintf(res_name, 16, "DPX_GS%d", id);
+ res_name[15] = '\0';
+ len += snprintf(buf, 64, " /%s gs", res_name);
+ pdf_doc_add_page_content(buf, len);
+ pdf_doc_add_page_resource("ExtGState", res_name, pdf_link_obj(diff));
+ if (gs->extgstate)
+ pdf_release_obj(gs->extgstate);
+ gs->extgstate = pdf_link_obj(accumlated);
+ xgs_count++;
+
+ return 0;
+}
+
+int
+pdf_dev_reset_xgstate (int force)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs;
+ pdf_obj *current, *target, *keys, *diff;
+ struct xgs_res *xgs;
+ int i, need_reset = 0;
+
+ gs = dpx_stack_top(gss);
+ xgs = dpx_stack_top(&xgs_stack);
+ if (xgs) {
+ target = pdf_link_obj(xgs->accumlated);
+ } else {
+ const char *ptr, *endptr;
+
+ if (!gs->extgstate && !force)
+ return 0;
+ ptr = default_xgs;
+ endptr = ptr + strlen(ptr);
+ target = parse_pdf_dict(&ptr, endptr, NULL);
+ }
+ if (gs->extgstate) {
+ current = pdf_link_obj(gs->extgstate);
+ } else {
+ const char *ptr, *endptr;
+ ptr = default_xgs;
+ endptr = ptr + strlen(ptr);
+ current = parse_pdf_dict(&ptr, endptr, NULL);
+ }
+
+ diff = pdf_new_dict();
+ keys = pdf_dict_keys(target);
+ for (i = 0; i < pdf_array_length(keys); i++) {
+ pdf_obj *key, *value1, *value2;
+ int is_diff = 0;
+
+ key = pdf_get_array(keys, i);
+ value1 = pdf_lookup_dict(target, pdf_name_value(key));
+ value2 = pdf_lookup_dict(current, pdf_name_value(key));
+ is_diff = pdf_compare_object(value1, value2);
+ if (is_diff) {
+ pdf_add_dict(diff, pdf_link_obj(key), pdf_link_obj(value1));
+ need_reset = 1;
+ }
+ }
+ pdf_release_obj(keys);
+ if (need_reset)
+ pdf_dev_set_xgstate(diff, target);
+ pdf_release_obj(diff);
+ pdf_release_obj(current);
+ pdf_release_obj(target);
+
+ return 0;
+}
+
+void
+pdf_dev_xgstate_push (pdf_obj *object)
+{
+ struct xgs_res *target, *current;
+ pdf_obj *accumlated;
+
+ target = NEW(1, struct xgs_res);
+ target->object = object;
+ current = dpx_stack_top(&xgs_stack);
+ if (!current) {
+ const char *ptr, *endptr;
+ ptr = default_xgs;
+ endptr = ptr + strlen(default_xgs);
+ accumlated = parse_pdf_dict(&ptr, endptr, NULL);
+ } else {
+ accumlated = pdf_new_dict();
+ pdf_merge_dict(accumlated, current->accumlated);
+ }
+ pdf_merge_dict(accumlated, object);
+ target->accumlated = accumlated;
+ dpx_stack_push(&xgs_stack, target);
+
+ pdf_dev_set_xgstate(target->object, target->accumlated);
+
+ return;
+}
+
+void
+pdf_dev_xgstate_pop (void)
+{
+ struct xgs_res *current, *target;
+ pdf_obj *accumlated, *revert, *keys;
+ int i;
+
+ current = dpx_stack_pop(&xgs_stack);
+ target = dpx_stack_top(&xgs_stack);
+ if (!current) {
+ WARN("Too many pop operation for ExtGState!");
+ return;
+ }
+ if (!target) {
+ const char *ptr, *endptr;
+ ptr = default_xgs;
+ endptr = ptr + strlen(default_xgs);
+ accumlated = parse_pdf_dict(&ptr, endptr, NULL);
+ } else {
+ accumlated = pdf_link_obj(target->accumlated);
+ }
+ keys = pdf_dict_keys(current->object);
+ revert = pdf_new_dict();
+ for (i = 0; i < pdf_array_length(keys); i++) {
+ pdf_obj *key, *value;
+ key = pdf_get_array(keys, i);
+ value = pdf_lookup_dict(accumlated, pdf_name_value(key));
+ if (!value) {
+ WARN("No previous ExtGState entry known for \"%s\", ignoring...", pdf_name_value(key));
+ } else {
+ pdf_add_dict(revert, pdf_link_obj(key), pdf_link_obj(value));
+ }
+ }
+ pdf_dev_set_xgstate(revert, accumlated);
+ pdf_release_obj(revert);
+ pdf_release_obj(keys);
+ pdf_release_obj(accumlated);
+
+ pdf_release_obj(current->object);
+ pdf_release_obj(current->accumlated);
+ RELEASE(current);
+
+ return;
+}
+
+void
+pdf_dev_init_gstates (void)
+{
+ pdf_gstate *gs;
+
+ dpx_stack_init(&gs_stack);
+
+ gs = NEW(1, pdf_gstate);
+ init_a_gstate(gs);
+
+ dpx_stack_push(&gs_stack, gs); /* Initial state */
+ init_xgstate();
+
+ return;
+}
+
+void
+pdf_dev_clear_gstates (void)
+{
+ pdf_gstate *gs;
+
+ if (dpx_stack_depth(&gs_stack) > 1) /* at least 1 elem. */
+ WARN("GS stack depth is not zero at the end of the document.");
+
+ while ((gs = dpx_stack_pop(&gs_stack)) != NULL) {
+ clear_a_gstate(gs);
+ RELEASE(gs);
+ }
+
+ clear_xgstate();
+
+ return;
+}
+
+int
+pdf_dev_gsave (void)
+{
+ pdf_gstate *gs0, *gs1;
+
+ gs0 = dpx_stack_top(&gs_stack);
+ gs1 = NEW(1, pdf_gstate);
+ init_a_gstate(gs1);
+ copy_a_gstate(gs1, gs0);
+ dpx_stack_push(&gs_stack, gs1);
+
+ pdf_doc_add_page_content(" q", 2); /* op: q */
+
+ return 0;
+}
+
+int
+pdf_dev_grestore (void)
+{
+ pdf_gstate *gs;
+
+ if (dpx_stack_depth(&gs_stack) <= 1) { /* Initial state at bottom */
+ WARN("Too many grestores.");
+ return -1;
+ }
+
+ gs = dpx_stack_pop(&gs_stack);
+ clear_a_gstate(gs);
+ RELEASE(gs);
+
+ pdf_doc_add_page_content(" Q", 2); /* op: Q */
+
+ pdf_dev_reset_fonts(0);
+
+ return 0;
+}
+
+
+int
+pdf_dev_push_gstate (void)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs0;
+
+ gs0 = NEW(1, pdf_gstate);
+
+ init_a_gstate(gs0);
+
+ dpx_stack_push(gss, gs0);
+
+ return 0;
+}
+
+
+int
+pdf_dev_pop_gstate (void)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs;
+
+ if (dpx_stack_depth(gss) <= 1) { /* Initial state at bottom */
+ WARN("Too many grestores.");
+ return -1;
+ }
+
+ gs = dpx_stack_pop(gss);
+ clear_a_gstate(gs);
+ RELEASE(gs);
+
+ return 0;
+}
+
+
+int
+pdf_dev_current_depth (void)
+{
+ return (dpx_stack_depth(&gs_stack) - 1); /* 0 means initial state */
+}
+
+void
+pdf_dev_grestore_to (int depth)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs;
+
+ ASSERT(depth >= 0);
+
+ if (dpx_stack_depth(gss) > depth + 1) {
+ WARN("Closing pending transformations at end of page/XObject.");
+ }
+
+ while (dpx_stack_depth(gss) > depth + 1) {
+ pdf_doc_add_page_content(" Q", 2); /* op: Q */
+ gs = dpx_stack_pop(gss);
+ clear_a_gstate(gs);
+ RELEASE(gs);
+ }
+ pdf_dev_reset_fonts(0);
+
+ return;
+}
+
+int
+pdf_dev_currentpoint (pdf_coord *p)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_coord *cpt = &gs->cp;
+
+ ASSERT(p);
+
+ p->x = cpt->x; p->y = cpt->y;
+
+ return 0;
+}
+
+int
+pdf_dev_currentmatrix (pdf_tmatrix *M)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_tmatrix *CTM = &gs->matrix;
+
+ ASSERT(M);
+
+ pdf_copymatrix(M, CTM);
+
+ return 0;
+}
+
+#if 0
+int
+pdf_dev_currentcolor (pdf_color *color, int is_fill)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_color *fcl = &gs->fillcolor;
+ pdf_color *scl = &gs->strokecolor;
+
+ ASSERT(color);
+
+ pdf_color_copycolor(color, is_fill ? fcl : scl);
+
+ return 0;
+}
+#endif /* 0 */
+
+/*
+ * FIXME: Please use a macro instead of using 0x20!
+ * mask == 0 means stroking color, mask == 0x20 nonstroking color
+ *
+ * force == 1 means that operators will be generated even if
+ * the color is the same as the current graphics state color
+ */
+void
+pdf_dev_set_color (const pdf_color *color, char mask, int force)
+{
+ int len;
+
+ pdf_gstate *gs = dpx_stack_top(&gs_stack);
+ pdf_color *current = mask ? &gs->fillcolor : &gs->strokecolor;
+
+ if (!(pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE) &&
+ (force || pdf_color_compare(color, current))))
+ /* If "color" is already the current color, then do nothing
+ * unless a color operator is forced
+ */
+ return;
+
+ graphics_mode();
+ len = pdf_color_set_color(color, fmt_buf, FORMAT_BUFF_LEN, mask);
+ pdf_doc_add_page_content(fmt_buf, len); /* op: RG K G rg k g etc. */
+ pdf_color_copycolor(current, color);
+}
+
+int
+pdf_dev_concat (const pdf_tmatrix *M)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_tmatrix *CTM = &gs->matrix;
+ pdf_tmatrix W = {0, 0, 0, 0, 0, 0}; /* Init to avoid compiler warning */
+ char *buf = fmt_buf;
+ int len = 0;
+
+ ASSERT(M);
+
+ /* Adobe Reader erases page content if there are
+ * non invertible transformation.
+ */
+ if (fabs(detP(M)) < OUR_EPSILON) {
+ WARN("Transformation matrix not invertible.");
+ WARN("--- M = [%g %g %g %g %g %g]",
+ M->a, M->b, M->c, M->d, M->e, M->f);
+ return -1;
+ }
+
+ if (fabs(M->a - 1.0) > OUR_EPSILON || fabs(M->b) > OUR_EPSILON
+ || fabs(M->c) > OUR_EPSILON || fabs(M->d - 1.0) > OUR_EPSILON
+ || fabs(M->e) > OUR_EPSILON || fabs(M->f) > OUR_EPSILON) {
+ buf[len++] = ' ';
+ len += pdf_sprint_matrix(buf + len, M);
+ buf[len++] = ' ';
+ buf[len++] = 'c';
+ buf[len++] = 'm';
+ pdf_doc_add_page_content(buf, len); /* op: cm */
+
+ pdf_concatmatrix(CTM, M);
+ }
+ inversematrix(&W, M);
+
+ pdf_path__transform (cpa, &W);
+ pdf_coord__transform(cpt, &W);
+
+ return 0;
+}
+
+/*
+ * num w LW linewidth (g.t. 0)
+ * int J LC linecap
+ * int j LJ linejoin
+ * num M ML miter limit (g.t. 0)
+ * array num d D line dash
+ * int ri RI renderint intnet
+ * int i FL flatness tolerance (0-100)
+ * name gs -- name: res. name of ExtGState dict.
+ */
+int
+pdf_dev_setmiterlimit (double mlimit)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ int len = 0;
+ char *buf = fmt_buf;
+
+ if (gs->miterlimit != mlimit) {
+ buf[len++] = ' ';
+ len += pdf_sprint_length(buf + len, mlimit);
+ buf[len++] = ' ';
+ buf[len++] = 'M';
+ pdf_doc_add_page_content(buf, len); /* op: M */
+ gs->miterlimit = mlimit;
+ }
+
+ return 0;
+}
+
+int
+pdf_dev_setlinecap (int capstyle)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ int len = 0;
+ char *buf = fmt_buf;
+
+ if (gs->linecap != capstyle) {
+ len = sprintf(buf, " %d J", capstyle);
+ pdf_doc_add_page_content(buf, len); /* op: J */
+ gs->linecap = capstyle;
+ }
+
+ return 0;
+}
+
+int
+pdf_dev_setlinejoin (int joinstyle)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ int len = 0;
+ char *buf = fmt_buf;
+
+ if (gs->linejoin != joinstyle) {
+ len = sprintf(buf, " %d j", joinstyle);
+ pdf_doc_add_page_content(buf, len); /* op: j */
+ gs->linejoin = joinstyle;
+ }
+
+ return 0;
+}
+
+int
+pdf_dev_setlinewidth (double width)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ int len = 0;
+ char *buf = fmt_buf;
+
+ if (gs->linewidth != width) {
+ buf[len++] = ' ';
+ len += pdf_sprint_length(buf + len, width);
+ buf[len++] = ' ';
+ buf[len++] = 'w';
+ pdf_doc_add_page_content(buf, len); /* op: w */
+ gs->linewidth = width;
+ }
+
+ return 0;
+}
+
+int
+pdf_dev_setdash (int count, double *pattern, double offset)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ int len = 0;
+ char *buf = fmt_buf;
+ int i;
+
+ gs->linedash.num_dash = count;
+ gs->linedash.offset = offset;
+ pdf_doc_add_page_content(" [", 2); /* op: */
+ for (i = 0; i < count; i++) {
+ buf[0] = ' ';
+ len = pdf_sprint_length (buf + 1, pattern[i]);
+ pdf_doc_add_page_content(buf, len + 1); /* op: */
+ gs->linedash.pattern[i] = pattern[i];
+ }
+ pdf_doc_add_page_content("] ", 2); /* op: */
+ len = pdf_sprint_length (buf, offset);
+ pdf_doc_add_page_content(buf, len); /* op: */
+ pdf_doc_add_page_content(" d", 2); /* op: d */
+
+ return 0;
+}
+
+#if 0
+int
+pdf_dev_setflat (int flatness)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ int len = 0;
+ char *buf = fmt_buf;
+
+ if (flatness < 0 || flatness > 100)
+ return -1;
+
+ if (gs->flatness != flatness) {
+ gs->flatness = flatness;
+ len = sprintf(buf, " %d i", flatness);
+ pdf_doc_add_page_content(buf, len); /* op: i */
+ }
+
+ return 0;
+}
+#endif
+
+/* ZSYUEDVEDEOF */
+int
+pdf_dev_clip (void)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+
+ return pdf_dev__flushpath(cpa, 'W', PDF_FILL_RULE_NONZERO, 0);
+}
+
+int
+pdf_dev_eoclip (void)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+
+ return pdf_dev__flushpath(cpa, 'W', PDF_FILL_RULE_EVENODD, 0);
+}
+
+int
+pdf_dev_flushpath (char p_op, int fill_rule)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ int error = 0;
+
+ /* last arg 'ignore_rule' is only for single object
+ * that can be converted to a rect where fill rule
+ * is inessential.
+ */
+ error = pdf_dev__flushpath(cpa, p_op, fill_rule, 1);
+ pdf_path__clearpath(cpa);
+
+ gs->flags &= ~GS_FLAG_CURRENTPOINT_SET;
+
+ return error;
+}
+
+int
+pdf_dev_newpath (void)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *p = &gs->path;
+
+ if (PA_LENGTH(p) > 0) {
+ pdf_path__clearpath (p);
+ }
+ /* The following is required for "newpath" operator in mpost.c. */
+ pdf_doc_add_page_content(" n", 2); /* op: n */
+
+ return 0;
+}
+
+int
+pdf_dev_moveto (double x, double y)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord p;
+
+ p.x = x; p.y = y;
+ return pdf_path__moveto(cpa, cpt, &p); /* cpt updated */
+}
+
+int
+pdf_dev_rmoveto (double x, double y)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord p;
+
+ p.x = cpt->x + x;
+ p.y = cpt->y + y;
+ return pdf_path__moveto(cpa, cpt, &p); /* cpt updated */
+}
+
+int
+pdf_dev_lineto (double x, double y)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord p0;
+
+ p0.x = x; p0.y = y;
+
+ return pdf_path__lineto(cpa, cpt, &p0);
+}
+
+int
+pdf_dev_rlineto (double x, double y)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord p0;
+
+ p0.x = x + cpt->x; p0.y = y + cpt->y;
+
+ return pdf_path__lineto(cpa, cpt, &p0);
+}
+
+int
+pdf_dev_curveto (double x0, double y0,
+ double x1, double y1,
+ double x2, double y2)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord p0, p1, p2;
+
+ p0.x = x0; p0.y = y0;
+ p1.x = x1; p1.y = y1;
+ p2.x = x2; p2.y = y2;
+
+ return pdf_path__curveto(cpa, cpt, &p0, &p1, &p2);
+}
+
+int
+pdf_dev_rcurveto (double x0, double y0,
+ double x1, double y1,
+ double x2, double y2)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord p0, p1, p2;
+
+ p0.x = x0 + cpt->x; p0.y = y0 + cpt->y;
+ p1.x = x1 + cpt->x; p1.y = y1 + cpt->y;
+ p2.x = x2 + cpt->x; p2.y = y2 + cpt->y;
+
+ return pdf_path__curveto(cpa, cpt, &p0, &p1, &p2);
+}
+
+
+int
+pdf_dev_closepath (void)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_coord *cpt = &gs->cp;
+ pdf_path *cpa = &gs->path;
+
+ return pdf_path__closepath(cpa, cpt);
+}
+
+
+void
+pdf_dev_dtransform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_tmatrix *CTM = &gs->matrix;
+
+ ASSERT(p);
+
+ pdf_coord__dtransform(p, (M ? M : CTM));
+
+ return;
+}
+
+void
+pdf_dev_idtransform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_tmatrix *CTM = &gs->matrix;
+
+ ASSERT(p);
+
+ pdf_coord__idtransform(p, (M ? M : CTM));
+
+ return;
+}
+
+void
+pdf_dev_transform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_tmatrix *CTM = &gs->matrix;
+
+ ASSERT(p);
+
+ pdf_coord__transform(p, (M ? M : CTM));
+
+ return;
+}
+
+void
+pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_tmatrix *CTM = &gs->matrix;
+
+ ASSERT(p);
+
+ pdf_coord__itransform(p, (M ? M : CTM));
+
+ return;
+}
+
+int
+pdf_dev_arc (double c_x , double c_y, double r,
+ double a_0 , double a_1)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord c;
+
+ c.x = c_x; c.y = c_y;
+
+ return pdf_path__elliptarc(cpa, cpt, &c, r, r, 0.0, a_0, a_1, +1);
+}
+
+/* *negative* arc */
+int
+pdf_dev_arcn (double c_x , double c_y, double r,
+ double a_0 , double a_1)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord c;
+
+ c.x = c_x; c.y = c_y;
+
+ return pdf_path__elliptarc(cpa, cpt, &c, r, r, 0.0, a_0, a_1, -1);
+}
+
+int
+pdf_dev_arcx (double c_x , double c_y,
+ double r_x , double r_y,
+ double a_0 , double a_1,
+ int a_d ,
+ double xar)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord c;
+
+ c.x = c_x; c.y = c_y;
+
+ return pdf_path__elliptarc(cpa, cpt, &c, r_x, r_y, xar, a_0, a_1, a_d);
+}
+
+/* Required by Tpic */
+int
+pdf_dev_bspline (double x0, double y0,
+ double x1, double y1, double x2, double y2)
+{
+ dpx_stack *gss = &gs_stack;
+ pdf_gstate *gs = dpx_stack_top(gss);
+ pdf_path *cpa = &gs->path;
+ pdf_coord *cpt = &gs->cp;
+ pdf_coord p1, p2, p3;
+
+ p1.x = x0 + 2.0 * (x1 - x0) / 3.0;
+ p1.y = y0 + 2.0 * (y1 - y0) / 3.0;
+ p2.x = x1 + (x2 - x1) / 3.0;
+ p2.y = y1 + (y2 - y1) / 3.0;
+ p3.x = x2;
+ p3.y = y2;
+
+ return pdf_path__curveto(cpa, cpt, &p1, &p2, &p3);
+}
+
+int
+pdf_dev_rectstroke (double x, double y,
+ double w, double h,
+ const pdf_tmatrix *M /* optional */
+ )
+{
+ pdf_rect r;
+
+ r.llx = x;
+ r.lly = y;
+ r.urx = x + w;
+ r.ury = y + h;
+
+ return pdf_dev__rectshape(&r, M, 'S');
+}
+
+int
+pdf_dev_rectfill (double x, double y,
+ double w, double h)
+{
+ pdf_rect r;
+
+ r.llx = x;
+ r.lly = y;
+ r.urx = x + w;
+ r.ury = y + h;
+
+ return pdf_dev__rectshape(&r, NULL, 'f');
+}
+
+int
+pdf_dev_rectclip (double x, double y,
+ double w, double h)
+{
+ pdf_rect r;
+
+ r.llx = x;
+ r.lly = y;
+ r.urx = x + w;
+ r.ury = y + h;
+
+ return pdf_dev__rectshape(&r, NULL, 'W');
+}
diff --git a/Build/source/texk/dvipdfm-x/pdfdraw.h b/Build/source/texk/dvipdfm-x/pdfdraw.h
new file mode 100644
index 00000000000..cf4588cdbd9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfdraw.h
@@ -0,0 +1,165 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDF_DRAW_H_
+#define _PDF_DRAW_H_
+
+#include "pdfcolor.h"
+#include "pdfdev.h"
+
+#define PDF_DASH_SIZE_MAX 16
+#define PDF_GSAVE_MAX 256
+
+extern void pdf_dev_init_gstates (void);
+extern void pdf_dev_clear_gstates (void);
+
+#define pdf_copymatrix(m,n) do {\
+ (m)->a = (n)->a; (m)->b = (n)->b;\
+ (m)->c = (n)->c; (m)->d = (n)->d;\
+ (m)->e = (n)->e; (m)->f = (n)->f;\
+} while (0)
+
+#define pdf_setmatrix(m,p,q,r,s,t,u) do {\
+ (m)->a = (p); (m)->b = (q);\
+ (m)->c = (r); (m)->d = (s);\
+ (m)->e = (t); (m)->f = (u);\
+} while (0)
+
+/* m -> n x m */
+#define pdf_concatmatrix(m,n) do {\
+ double _tmp_a, _tmp_b, _tmp_c, _tmp_d; \
+ _tmp_a = (m)->a; _tmp_b = (m)->b; \
+ _tmp_c = (m)->c; _tmp_d = (m)->d; \
+ (m)->a = ((n)->a) * _tmp_a + ((n)->b) * _tmp_c; \
+ (m)->b = ((n)->a) * _tmp_b + ((n)->b) * _tmp_d; \
+ (m)->c = ((n)->c) * _tmp_a + ((n)->d) * _tmp_c; \
+ (m)->d = ((n)->c) * _tmp_b + ((n)->d) * _tmp_d; \
+ (m)->e += ((n)->e) * _tmp_a + ((n)->f) * _tmp_c; \
+ (m)->f += ((n)->e) * _tmp_b + ((n)->f) * _tmp_d; \
+} while (0)
+
+typedef struct pdf_path_ pdf_path;
+
+extern int pdf_dev_currentmatrix (pdf_tmatrix *M);
+extern int pdf_dev_currentpoint (pdf_coord *cp);
+
+extern int pdf_dev_setlinewidth (double width);
+extern int pdf_dev_setmiterlimit (double mlimit);
+extern int pdf_dev_setlinecap (int style);
+extern int pdf_dev_setlinejoin (int style);
+extern int pdf_dev_setdash (int count,
+ double *pattern,
+ double offset);
+#if 0
+extern int pdf_dev_setflat (int flatness);
+#endif
+
+/* Path Construction */
+extern int pdf_dev_moveto (double x , double y);
+extern int pdf_dev_rmoveto (double x , double y);
+extern int pdf_dev_closepath (void);
+
+extern int pdf_dev_lineto (double x0 , double y0);
+extern int pdf_dev_rlineto (double x0 , double y0);
+extern int pdf_dev_curveto (double x0 , double y0,
+ double x1 , double y1,
+ double x2 , double y2);
+extern int pdf_dev_rcurveto (double x0 , double y0,
+ double x1 , double y1,
+ double x2 , double y2);
+extern int pdf_dev_arc (double c_x, double c_y, double r,
+ double a_0, double a_1);
+extern int pdf_dev_arcn (double c_x, double c_y, double r,
+ double a_0, double a_1);
+
+#define PDF_FILL_RULE_NONZERO 0
+#define PDF_FILL_RULE_EVENODD 1
+
+extern int pdf_dev_newpath (void);
+
+/* Path Painting */
+extern int pdf_dev_clip (void);
+extern int pdf_dev_eoclip (void);
+
+
+extern int pdf_dev_rectstroke (double x, double y,
+ double w, double h,
+ const pdf_tmatrix *M /* optional */
+ );
+extern int pdf_dev_rectfill (double x, double y, double w, double h);
+extern int pdf_dev_rectclip (double x, double y, double w, double h);
+
+extern int pdf_dev_flushpath (char p_op, int fill_rule);
+
+extern int pdf_dev_concat (const pdf_tmatrix *M);
+/* NULL pointer of M mean apply current transformation */
+extern void pdf_dev_dtransform (pdf_coord *p, const pdf_tmatrix *M);
+extern void pdf_dev_idtransform (pdf_coord *p, const pdf_tmatrix *M);
+extern void pdf_dev_transform (pdf_coord *p, const pdf_tmatrix *M);
+extern void pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M);
+
+extern int pdf_dev_gsave (void);
+extern int pdf_dev_grestore (void);
+
+/* Requires from mpost.c because new MetaPost graphics must initialize
+ * the current gstate. */
+extern int pdf_dev_push_gstate (void);
+extern int pdf_dev_pop_gstate (void);
+
+
+/* extension */
+extern int pdf_dev_arcx (double c_x, double c_y,
+ double r_x, double r_y,
+ double a_0, double a_1,
+ int a_d, /* arc direction */
+ double xar /* x-axis-rotation */
+ );
+extern int pdf_dev_bspline (double x0, double y0,
+ double x1, double y1,
+ double x2, double y2);
+
+
+extern void pdf_invertmatrix (pdf_tmatrix *M);
+
+/* The depth here is the depth of q/Q nesting.
+ * We must remember current depth of nesting when starting a page or xform,
+ * and must recover until that depth at the end of page/xform.
+ */
+extern int pdf_dev_current_depth (void);
+extern void pdf_dev_grestore_to (int depth);
+
+#if 0
+extern int pdf_dev_currentcolor (pdf_color *color, int is_fill);
+#endif
+
+extern void pdf_dev_set_fixed_point (double x, double y);
+extern void pdf_dev_get_fixed_point (pdf_coord *p);
+
+extern void pdf_dev_set_color (const pdf_color *color, char mask, int force);
+#define pdf_dev_set_strokingcolor(c) pdf_dev_set_color(c, 0, 0);
+#define pdf_dev_set_nonstrokingcolor(c) pdf_dev_set_color(c, 0x20, 0);
+
+extern void pdf_dev_xgstate_push (pdf_obj *object);
+extern void pdf_dev_xgstate_pop (void);
+extern int pdf_dev_reset_xgstate (int force);
+
+#endif /* _PDF_DRAW_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfencoding.c b/Build/source/texk/dvipdfm-x/pdfencoding.c
new file mode 100644
index 00000000000..777dbcd2d50
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfencoding.c
@@ -0,0 +1,1079 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "pdfparse.h"
+#include "pdfobj.h"
+
+#include "dpxfile.h"
+
+#include "pdfencoding.h"
+
+static int is_similar_charset (char **encoding, const char **encoding2);
+static pdf_obj *make_encoding_differences (char **encoding, char **baseenc,
+ const char *is_used);
+
+static const char *MacRomanEncoding[256];
+static const char *MacExpertEncoding[256];
+static const char *WinAnsiEncoding[256];
+#if 0
+static const char *StandardEncoding[256];
+static const char *ISOLatin1Encoding[256];
+#endif
+
+/*
+ * ident: File name, e.g., 8a.enc.
+ * name: Name of encoding, StandardEncoding, TeXBase1Encoding, ...
+ * glyphs: List of encoded glyphs (name).
+ * flags:
+ * IS_PREDEFINED:
+ * Encoding is one of the MacRomanEncoding, MacExpertEncoding, and
+ * WinAnsiEncoding.
+ * FLAG_USED_BY_TYPE3:
+ * Encoding is used by a Type 3 font.
+ */
+#define FLAG_IS_PREDEFINED (1 << 0)
+#define FLAG_USED_BY_TYPE3 (1 << 1)
+
+typedef struct pdf_encoding
+{
+ char *ident;
+
+ char *enc_name;
+ int flags;
+ char *glyphs[256]; /* ".notdef" must be represented as NULL */
+ char is_used[256];
+
+ struct pdf_encoding *baseenc;
+ pdf_obj *tounicode;
+
+ pdf_obj *resource;
+} pdf_encoding;
+
+static int pdf_encoding_new_encoding (const char *enc_name,
+ const char *ident,
+ const char **encoding_vec,
+ const char *baseenc_name,
+ int flags);
+
+static void
+pdf_init_encoding_struct (pdf_encoding *encoding)
+{
+ ASSERT(encoding);
+
+ encoding->ident = NULL;
+
+ encoding->enc_name = NULL;
+
+ memset(encoding->glyphs, 0, 256*sizeof(char *));
+ memset(encoding->is_used, 0, 256);
+
+ encoding->tounicode = NULL;
+
+ encoding->baseenc = NULL;
+ encoding->resource = NULL;
+
+ encoding->flags = 0;
+
+ return;
+}
+
+/* Creates the PDF Encoding entry for the encoding.
+ * If baseenc is non-null, it is used as BaseEncoding entry.
+ */
+static pdf_obj *
+create_encoding_resource (pdf_encoding *encoding, pdf_encoding *baseenc)
+{
+ pdf_obj *differences;
+ ASSERT(encoding);
+ ASSERT(!encoding->resource);
+
+ differences = make_encoding_differences(encoding->glyphs,
+ baseenc ? baseenc->glyphs : NULL,
+ encoding->is_used);
+
+ if (differences) {
+ pdf_obj *resource = pdf_new_dict();
+ if (baseenc)
+ pdf_add_dict(resource, pdf_new_name("BaseEncoding"),
+ pdf_link_obj(baseenc->resource));
+ pdf_add_dict(resource, pdf_new_name("Differences"), differences);
+ return resource;
+ } else {
+ /* Fix a bug with the MinionPro package using MnSymbol fonts
+ * in its virtual fonts:
+ *
+ * Some font may have font_id even if no character is used.
+ * For example, suppose that a virtual file A.vf uses two
+ * other fonts, B and C. Even if only characters of B are used
+ * in a DVI document, C will have font_id too.
+ * In this case, both baseenc and differences can be NULL.
+ *
+ * Actually these fonts will be ignored in pdffont.c.
+ */
+ return baseenc ? pdf_link_obj(baseenc->resource) : NULL;
+ }
+}
+
+static void
+pdf_flush_encoding (pdf_encoding *encoding)
+{
+ ASSERT(encoding);
+
+ if (encoding->resource) {
+ pdf_release_obj(encoding->resource);
+ encoding->resource = NULL;
+ }
+ if (encoding->tounicode) {
+ pdf_release_obj(encoding->tounicode);
+ encoding->tounicode = NULL;
+ }
+
+ return;
+}
+
+static void
+pdf_clean_encoding_struct (pdf_encoding *encoding)
+{
+ int code;
+
+ ASSERT(encoding);
+
+ if (encoding->resource)
+ ERROR("Object not flushed.");
+
+ if (encoding->tounicode)
+ pdf_release_obj(encoding->tounicode);
+ if (encoding->ident)
+ RELEASE(encoding->ident);
+ if (encoding->enc_name)
+ RELEASE(encoding->enc_name);
+
+ encoding->ident = NULL;
+ encoding->enc_name = NULL;
+
+ for (code = 0; code < 256; code++) {
+ if (encoding->glyphs[code])
+ RELEASE(encoding->glyphs[code]);
+ encoding->glyphs[code] = NULL;
+ }
+ encoding->ident = NULL;
+ encoding->enc_name = NULL;
+
+ return;
+}
+
+#if 0
+static inline int
+glycmp (const void *pv1, const void *pv2)
+{
+ char *v1, *v2;
+
+ v1 = (char *) pv1;
+ v2 = *((char **) pv2);
+
+ return strcmp(v1, v2);
+}
+#endif
+
+static int
+is_similar_charset (char **enc_vec, const char **enc_vec2)
+{
+ int code, same = 0;
+
+ for (code = 0; code < 256; code++)
+ if (!(enc_vec[code] && strcmp(enc_vec[code], enc_vec2[code]))
+ && ++same >= 64)
+ /* is 64 a good level? */
+ return 1;
+
+ return 0;
+}
+
+/* Creates a PDF Differences array for the encoding, based on the
+ * base encoding baseenc (if not NULL). Only character codes which
+ * are actually used in the document are considered.
+ */
+static pdf_obj *
+make_encoding_differences (char **enc_vec, char **baseenc, const char *is_used)
+{
+ pdf_obj *differences = NULL;
+ int code, count = 0;
+ int skipping = 1;
+
+ ASSERT(enc_vec);
+
+ /*
+ * Write all entries (except .notdef) if baseenc is unknown.
+ * If is_used is given, write only used entries.
+ */
+ differences = pdf_new_array();
+ for (code = 0; code < 256; code++) {
+ /* We skip NULL (= ".notdef"). Any character code mapped to ".notdef"
+ * glyph should not be used in the document.
+ */
+ if ((is_used && !is_used[code]) || !enc_vec[code])
+ skipping = 1;
+ else if (!baseenc || !baseenc[code] ||
+ strcmp(baseenc[code], enc_vec[code]) != 0) {
+ /*
+ * Difference found.
+ */
+ if (skipping)
+ pdf_add_array(differences, pdf_new_number(code));
+ pdf_add_array(differences, pdf_new_name(enc_vec[code]));
+ skipping = 0;
+ count++;
+ } else
+ skipping = 1;
+ }
+
+ /*
+ * No difference found. Some PDF viewers can't handle differences without
+ * any differences. We return NULL.
+ */
+ if (count == 0) {
+ pdf_release_obj(differences);
+ differences = NULL;
+ }
+
+ return differences;
+}
+
+static int
+load_encoding_file (const char *filename)
+{
+ FILE *fp;
+ pdf_obj *enc_name = NULL;
+ pdf_obj *encoding_array = NULL;
+ char *wbuf;
+ const char *p, *endptr;
+ const char *enc_vec[256];
+ int code, fsize, enc_id;
+
+ if (!filename)
+ return -1;
+
+ if (dpx_conf.verbose_level > 0) {
+ MESG("(Encoding:%s", filename);
+ }
+
+ fp = DPXFOPEN(filename, DPX_RES_TYPE_ENC);
+ if (!fp)
+ return -1;
+ /*
+ * file_size do seek_end witout saving current position and
+ * do rewind.
+ */
+ fsize = file_size(fp);
+
+ wbuf = NEW(fsize + 1, char);
+ wbuf[fsize] = '\0';
+ fread(wbuf, sizeof(char), fsize, fp);
+ DPXFCLOSE(fp);
+
+ p = wbuf;
+ endptr = wbuf + fsize;
+
+ skip_white(&p, endptr);
+
+ /*
+ * Skip comment lines.
+ */
+ while (p < endptr && p[0] == '%') {
+ pdfparse_skip_line (&p, endptr);
+ skip_white(&p, endptr);
+ }
+ if (p[0] == '/')
+ enc_name = parse_pdf_name(&p, endptr);
+
+ skip_white(&p, endptr);
+ encoding_array = parse_pdf_array(&p, endptr, NULL);
+ RELEASE(wbuf);
+ if (!encoding_array) {
+ if (enc_name)
+ pdf_release_obj(enc_name);
+ return -1;
+ }
+
+ for (code = 0; code < 256; code++) {
+ enc_vec[code] = pdf_name_value(pdf_get_array(encoding_array, code));
+ }
+ enc_id = pdf_encoding_new_encoding(enc_name ? pdf_name_value(enc_name) : NULL,
+ filename, enc_vec, NULL, 0);
+
+ if (enc_name) {
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%s]", pdf_name_value(enc_name));
+ pdf_release_obj(enc_name);
+ }
+ pdf_release_obj(encoding_array);
+
+ if (dpx_conf.verbose_level > 0) MESG(")");
+
+ return enc_id;
+}
+
+#define CHECK_ID(n) do { \
+ if ((n) < 0 || (n) >= enc_cache.count) { \
+ ERROR("Invalid encoding id: %d", (n)); \
+ } \
+} while (0)
+
+#define CACHE_ALLOC_SIZE 16u
+
+struct {
+ int count;
+ int capacity;
+ pdf_encoding *encodings;
+} enc_cache = {
+ 0, 0, NULL
+};
+
+void
+pdf_init_encodings (void)
+{
+ enc_cache.count = 0;
+ enc_cache.capacity = 3;
+ enc_cache.encodings = NEW(enc_cache.capacity, pdf_encoding);
+
+ /*
+ * PDF Predefined Encodings
+ */
+ pdf_encoding_new_encoding("WinAnsiEncoding", "WinAnsiEncoding",
+ WinAnsiEncoding, NULL, FLAG_IS_PREDEFINED);
+ pdf_encoding_new_encoding("MacRomanEncoding", "MacRomanEncoding",
+ MacRomanEncoding, NULL, FLAG_IS_PREDEFINED);
+ pdf_encoding_new_encoding("MacExpertEncoding", "MacExpertEncoding",
+ MacExpertEncoding, NULL, FLAG_IS_PREDEFINED);
+
+ return;
+}
+
+/*
+ * The original dvipdfm describes as:
+ *
+ * Some software doesn't like BaseEncoding key (e.g., FastLane)
+ * so this code is commented out for the moment. It may reemerge in the
+ * future
+ *
+ * and the line for BaseEncoding is commented out.
+ *
+ * I'm not sure why this happens. But maybe BaseEncoding key causes problems
+ * when the font is Symbol font or TrueType font.
+ */
+
+static int
+pdf_encoding_new_encoding (const char *enc_name, const char *ident,
+ const char **encoding_vec,
+ const char *baseenc_name, int flags)
+{
+ int enc_id, code;
+
+ pdf_encoding *encoding;
+
+ enc_id = enc_cache.count;
+ if (enc_cache.count++ >= enc_cache.capacity) {
+ enc_cache.capacity += 16;
+ enc_cache.encodings = RENEW(enc_cache.encodings,
+ enc_cache.capacity, pdf_encoding);
+ }
+ encoding = &enc_cache.encodings[enc_id];
+
+ pdf_init_encoding_struct(encoding);
+
+ encoding->ident = NEW(strlen(ident)+1, char);
+ strcpy(encoding->ident, ident);
+ encoding->enc_name = NEW(strlen(enc_name)+1, char);
+ strcpy(encoding->enc_name, enc_name);
+
+ encoding->flags = flags;
+
+ for (code = 0; code < 256; code++)
+ if (encoding_vec[code] && strcmp(encoding_vec[code], ".notdef")) {
+ encoding->glyphs[code] = NEW(strlen(encoding_vec[code])+1, char);
+ strcpy(encoding->glyphs[code], encoding_vec[code]);
+ }
+
+ if (!baseenc_name && !(flags & FLAG_IS_PREDEFINED)
+ && is_similar_charset(encoding->glyphs, WinAnsiEncoding)) {
+ /* Dvipdfmx default setting. */
+ baseenc_name = "WinAnsiEncoding";
+ }
+
+ /* TODO: make base encoding configurable */
+ if (baseenc_name) {
+ int baseenc_id = pdf_encoding_findresource(baseenc_name);
+ if (baseenc_id < 0 || !pdf_encoding_is_predefined(baseenc_id))
+ ERROR("Illegal base encoding %s for encoding %s\n",
+ baseenc_name, encoding->enc_name);
+ encoding->baseenc = &enc_cache.encodings[baseenc_id];
+ }
+
+ if (flags & FLAG_IS_PREDEFINED)
+ encoding->resource = pdf_new_name(encoding->enc_name);
+
+ return enc_id;
+}
+
+/* Creates Encoding resource and ToUnicode CMap
+ * for all non-predefined encodings.
+ */
+void pdf_encoding_complete (void)
+{
+ int enc_id;
+
+ for (enc_id = 0; enc_id < enc_cache.count; enc_id++) {
+ if (!pdf_encoding_is_predefined(enc_id)) {
+ pdf_encoding *encoding = &enc_cache.encodings[enc_id];
+ /* Section 5.5.4 of the PDF 1.5 reference says that the encoding
+ * of a Type 3 font must be completely described by a Differences
+ * array, but implementation note 56 explains that this is rather
+ * an incorrect implementation in Acrobat 4 and earlier. Hence,
+ * we do use a base encodings for PDF versions >= 1.3.
+ */
+ int with_base = !(encoding->flags & FLAG_USED_BY_TYPE3)
+ || pdf_check_version(1, 4) >= 0;
+ ASSERT(!encoding->resource);
+ encoding->resource = create_encoding_resource(encoding,
+ with_base ? encoding->baseenc : NULL);
+ ASSERT(!encoding->tounicode);
+ encoding->tounicode = pdf_create_ToUnicode_CMap(encoding->enc_name,
+ encoding->glyphs,
+ encoding->is_used);
+ }
+ }
+}
+
+void
+pdf_close_encodings (void)
+{
+ int enc_id;
+
+ if (enc_cache.encodings) {
+ for (enc_id = 0; enc_id < enc_cache.count; enc_id++) {
+ pdf_encoding *encoding;
+
+ encoding = &enc_cache.encodings[enc_id];
+ if (encoding) {
+ pdf_flush_encoding(encoding);
+ pdf_clean_encoding_struct(encoding);
+ }
+ }
+ RELEASE(enc_cache.encodings);
+ }
+ enc_cache.encodings = NULL;
+ enc_cache.count = 0;
+ enc_cache.capacity = 0;
+}
+
+int
+pdf_encoding_findresource (const char *enc_name)
+{
+ int enc_id;
+ pdf_encoding *encoding;
+
+ ASSERT(enc_name);
+ for (enc_id = 0; enc_id < enc_cache.count; enc_id++) {
+ encoding = &enc_cache.encodings[enc_id];
+ if (encoding->ident &&
+ !strcmp(enc_name, encoding->ident))
+ return enc_id;
+ else if (encoding->enc_name &&
+ !strcmp(enc_name, encoding->enc_name))
+ return enc_id;
+ }
+
+ return load_encoding_file(enc_name);
+}
+
+
+/*
+ * Pointer will change if other encoding is loaded...
+ */
+
+char **
+pdf_encoding_get_encoding (int enc_id)
+{
+ pdf_encoding *encoding;
+
+ CHECK_ID(enc_id);
+
+ encoding = &enc_cache.encodings[enc_id];
+
+ return encoding->glyphs;
+}
+
+pdf_obj *
+pdf_get_encoding_obj (int enc_id)
+{
+ pdf_encoding *encoding;
+
+ CHECK_ID(enc_id);
+
+ encoding = &enc_cache.encodings[enc_id];
+
+ return encoding->resource;
+}
+
+int
+pdf_encoding_is_predefined (int enc_id)
+{
+ pdf_encoding *encoding;
+
+ CHECK_ID(enc_id);
+
+ encoding = &enc_cache.encodings[enc_id];
+
+ return (encoding->flags & FLAG_IS_PREDEFINED) ? 1 : 0;
+}
+
+void
+pdf_encoding_used_by_type3 (int enc_id)
+{
+ pdf_encoding *encoding;
+
+ CHECK_ID(enc_id);
+
+ encoding = &enc_cache.encodings[enc_id];
+
+ encoding->flags |= FLAG_USED_BY_TYPE3;
+}
+
+
+char *
+pdf_encoding_get_name (int enc_id)
+{
+ pdf_encoding *encoding;
+
+ CHECK_ID(enc_id);
+
+ encoding = &enc_cache.encodings[enc_id];
+
+ return encoding->enc_name;
+}
+
+/* CSI_UNICODE */
+#include "cid.h"
+
+#include "cmap.h"
+#include "cmap_read.h"
+#include "cmap_write.h"
+
+#include "agl.h"
+
+#define WBUF_SIZE 1024
+static unsigned char wbuf[WBUF_SIZE];
+static unsigned char range_min[1] = {0x00u};
+static unsigned char range_max[1] = {0xFFu};
+
+void
+pdf_encoding_add_usedchars (int encoding_id, const char *is_used)
+{
+ pdf_encoding *encoding;
+ int code;
+
+ CHECK_ID(encoding_id);
+
+ if (!is_used || pdf_encoding_is_predefined(encoding_id))
+ return;
+
+ encoding = &enc_cache.encodings[encoding_id];
+
+ for (code = 0; code <= 0xff; code++)
+ encoding->is_used[code] |= is_used[code];
+}
+
+pdf_obj *
+pdf_encoding_get_tounicode (int encoding_id)
+{
+ CHECK_ID(encoding_id);
+
+ return enc_cache.encodings[encoding_id].tounicode;
+}
+
+
+/* Creates a ToUnicode CMap. An empty CMap is replaced by NULL.
+ *
+ * For PDF <= 1.4 a complete CMap is created unless all character codes
+ * are predefined in PDF. For PDF >= 1.5 only those character codes which
+ * are not predefined appear in the CMap.
+ *
+ * Note: The PDF 1.4 reference is not consistent: Section 5.9 describes
+ * the Unicode mapping of PDF 1.3 and Section 9.7.2 (in the context of
+ * Tagged PDF) the one of PDF 1.5.
+ *
+ * CHANGED: 20180906
+ * Always create ToUnicode CMap unless there is missing mapping.
+ * Change made on rev.7557 broke ToUnicode CMap support. Now reverted.
+ */
+pdf_obj *
+pdf_create_ToUnicode_CMap (const char *enc_name,
+ char **enc_vec, const char *is_used)
+{
+ pdf_obj *stream;
+ CMap *cmap;
+ int code, count, total_fail;
+ char *cmap_name;
+ unsigned char *p, *endptr;
+
+ ASSERT(enc_name && enc_vec);
+
+ if (!is_used)
+ return NULL;
+
+ cmap_name = NEW(strlen(enc_name)+strlen("-UTF16")+1, char);
+ sprintf(cmap_name, "%s-UTF16", enc_name);
+
+ cmap = CMap_new();
+ CMap_set_name (cmap, cmap_name);
+ CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE);
+ CMap_set_wmode(cmap, 0);
+
+ CMap_set_CIDSysInfo(cmap, &CSI_UNICODE);
+
+ CMap_add_codespacerange(cmap, range_min, range_max, 1);
+
+ count = 0;
+ total_fail = 0;
+ for (code = 0; code <= 0xff; code++) {
+ if (is_used && !is_used[code])
+ continue;
+
+ if (enc_vec[code]) {
+ size_t len;
+ int fail_count = 0;
+ wbuf[0] = (code & 0xff);
+ p = wbuf + 1;
+ endptr = wbuf + WBUF_SIZE;
+ len = agl_sput_UTF16BE(enc_vec[code], &p, endptr, &fail_count);
+ if (len < 1 && fail_count > 0) {
+ total_fail++;
+ } else {
+ CMap_add_bfchar(cmap, wbuf, 1, wbuf + 1, len);
+ count++;
+ }
+ }
+ }
+
+ if (total_fail > 0) {
+ if (dpx_conf.verbose_level > 0)
+ WARN("Glyphs with no Unicode mapping found. Removing ToUnicode CMap.");
+ }
+ stream = (count == 0 || total_fail > 0) ? NULL : CMap_create_stream(cmap);
+
+ CMap_release(cmap);
+ RELEASE(cmap_name);
+
+ return stream;
+}
+
+
+pdf_obj *
+pdf_load_ToUnicode_stream (const char *ident)
+{
+ pdf_obj *stream = NULL;
+ CMap *cmap;
+ FILE *fp;
+
+ if (!ident)
+ return NULL;
+
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_CMAP);
+ if (!fp)
+ return NULL;
+ else if (CMap_parse_check_sig(fp) < 0) {
+ DPXFCLOSE(fp);
+ return NULL;
+ }
+
+ cmap = CMap_new();
+ if (CMap_parse(cmap, fp) < 0) {
+ WARN("Reading CMap file \"%s\" failed.", ident);
+ } else {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("(CMap:%s)", ident);
+ }
+ stream = CMap_create_stream(cmap);
+ if (!stream) {
+ WARN("Failed to creat ToUnicode CMap stream for \"%s\".", ident);
+ }
+ }
+ CMap_release(cmap);
+ DPXFCLOSE(fp);
+
+ return stream;
+}
+
+
+static const char *
+MacRomanEncoding[256] = {
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quotesingle",
+ "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash",
+ "zero", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "colon", "semicolon",
+ "less", "equal", "greater", "question",
+ "at", "A", "B", "C",
+ "D", "E", "F", "G", "H",
+ "I", "J", "K", "L",
+ "M", "N", "O", "P",
+ "Q", "R", "S", "T",
+ "U", "V", "W", "X",
+ "Y", "Z", "bracketleft", "backslash",
+ "bracketright", "asciicircum", "underscore",
+ "grave", "a", "b", "c",
+ "d", "e", "f", "g",
+ "h", "i", "j", "k",
+ "l", "m", "n", "o",
+ "p", "q", "r", "s",
+ "t", "u", "v", "w",
+ "x", "y", "z", "braceleft",
+ "bar", "braceright", "asciitilde", ".notdef",
+ "Adieresis", "Aring", "Ccedilla", "Eacute",
+ "Ntilde", "Odieresis", "Udieresis", "aacute",
+ "agrave", "acircumflex", "adieresis", "atilde",
+ "aring", "ccedilla", "eacute", "egrave",
+ "ecircumflex", "edieresis", "iacute", "igrave",
+ "icircumflex", "idieresis", "ntilde", "oacute",
+ "ograve", "ocircumflex", "odieresis", "otilde",
+ "uacute", "ugrave", "ucircumflex", "udieresis",
+ "dagger", "degree", "cent", "sterling",
+ "section", "bullet", "paragraph", "germandbls",
+ "registered", "copyright", "trademark", "acute",
+ "dieresis", "notequal", "AE", "Oslash",
+ "infinity", "plusminus", "lessequal", "greaterequal",
+ "yen", "mu", "partialdiff", "summation",
+ "product", "pi", "integral", "ordfeminine",
+ "ordmasculine", "Omega", "ae", "oslash",
+ "questiondown", "exclamdown", "logicalnot", "radical",
+ "florin", "approxequal", "Delta", "guillemotleft",
+ "guillemotright", "ellipsis", "space", "Agrave",
+ "Atilde", "Otilde", "OE", "oe",
+ "endash", "emdash", "quotedblleft", "quotedblright",
+ "quoteleft", "quoteright", "divide", "lozenge",
+ "ydieresis", "Ydieresis", "fraction", "currency",
+ "guilsinglleft", "guilsinglright", "fi", "fl",
+ "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase",
+ "perthousand", "Acircumflex", "Ecircumflex", "Aacute",
+ "Edieresis", "Egrave", "Iacute", "Icircumflex",
+ "Idieresis", "Igrave", "Oacute", "Ocircumflex",
+ "apple", "Ograve", "Uacute", "Ucircumflex",
+ "Ugrave", "dotlessi", "circumflex", "tilde",
+ "macron", "breve", "dotaccent", "ring",
+ "cedilla", "hungarumlaut", "ogonek", "caron"
+};
+
+static const char *
+MacExpertEncoding[256] = {
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "space", "exclamsmall", "Hungarumlautsmall", "centoldstyle",
+ "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall",
+ "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader",
+ "comma", "hyphen", "period", "fraction",
+ "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle",
+ "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle",
+ "eightoldstyle", "nineoldstyle", "colon", "semicolon",
+ ".notdef", "threequartersemdash", ".notdef", "questionsmall",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "Ethsmall", ".notdef", ".notdef", "onequarter",
+ "onehalf", "threequarters", "oneeighth", "threeeighths",
+ "fiveeighths", "seveneighths", "onethird", "twothirds",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", "ff", "fi",
+ "fl", "ffi", "ffl", "parenleftinferior",
+ ".notdef", "parenrightinferior", "Circumflexsmall", "hypheninferior",
+ "Gravesmall", "Asmall", "Bsmall", "Csmall",
+ "Dsmall", "Esmall", "Fsmall", "Gsmall",
+ "Hsmall", "Ismall", "Jsmall", "Ksmall",
+ "Lsmall", "Msmall", "Nsmall", "Osmall",
+ "Psmall", "Qsmall", "Rsmall", "Ssmall",
+ "Tsmall", "Usmall", "Vsmall", "Wsmall",
+ "Xsmall", "Ysmall", "Zsmall", "colonmonetary",
+ "onefitted", "rupiah", "Tildesmall", ".notdef",
+ ".notdef", "asuperior", "centsuperior", ".notdef",
+ ".notdef", ".notdef", ".notdef", "Aacutesmall",
+ "Agravesmall", "Acircumflexsmall", "Adieresissmall", "Atildesmall",
+ "Aringsmall", "Ccedillasmall", "Eacutesmall", "Egravesmall",
+ "Ecircumflexsmall", "Edieresissmall", "Iacutesmall", "Igravesmall",
+ "Icircumflexsmall", "Idieresissmall", "Ntildesmall", "Oacutesmall",
+ "Ogravesmall", "Ocircumflexsmall", "Odieresissmall", "Otildesmall",
+ "Uacutesmall", "Ugravesmall", "Ucircumflexsmall", "Udieresissmall",
+ ".notdef", "eightsuperior", "fourinferior", "threeinferior",
+ "sixinferior", "eightinferior", "seveninferior", "Scaronsmall",
+ ".notdef", "centinferior", "twoinferior", ".notdef",
+ "Dieresissmall", ".notdef", "Caronsmall", "osuperior",
+ "fiveinferior", ".notdef", "commainferior", "periodinferior",
+ "Yacutesmall", ".notdef", "dollarinferior", ".notdef",
+ ".notdef", "Thornsmall", ".notdef", "nineinferior",
+ "zeroinferior", "Zcaronsmall", "AEsmall", "Oslashsmall",
+ "questiondownsmall", "oneinferior", "Lslashsmall", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", "Cedillasmall", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", "OEsmall",
+ "figuredash", "hyphensuperior", ".notdef", ".notdef",
+ ".notdef", ".notdef", "exclamdownsmall", ".notdef",
+ "Ydieresissmall", ".notdef", "onesuperior", "twosuperior",
+ "threesuperior", "foursuperior", "fivesuperior", "sixsuperior",
+ "sevensuperior", "ninesuperior", "zerosuperior", ".notdef",
+ "esuperior", "rsuperior", "tsuperior", ".notdef",
+ ".notdef", "isuperior", "ssuperior", "dsuperior",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", "lsuperior", "Ogoneksmall", "Brevesmall",
+ "Macronsmall", "bsuperior", "nsuperior", "msuperior",
+ "commasuperior", "periodsuperior", "Dotaccentsmall", "Ringsmall",
+ ".notdef", ".notdef", ".notdef", ".notdef"
+};
+
+static const char *
+WinAnsiEncoding[256] = {
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quotesingle",
+ "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash",
+ "zero", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "colon", "semicolon",
+ "less", "equal", "greater", "question",
+ "at", "A", "B", "C",
+ "D", "E", "F", "G",
+ "H", "I", "J", "K",
+ "L", "M", "N", "O",
+ "P", "Q", "R", "S",
+ "T", "U", "V", "W",
+ "X", "Y", "Z", "bracketleft",
+ "backslash", "bracketright", "asciicircum", "underscore",
+ "grave", "a", "b", "c",
+ "d", "e", "f", "g",
+ "h", "i", "j", "k",
+ "l", "m", "n", "o",
+ "p", "q", "r", "s",
+ "t", "u", "v", "w",
+ "x", "y", "z", "braceleft",
+ "bar", "braceright", "asciitilde", "bullet",
+ "Euro", "bullet", "quotesinglbase", "florin",
+ "quotedblbase", "ellipsis", "dagger", "daggerdbl",
+ "circumflex", "perthousand", "Scaron", "guilsinglleft",
+ "OE", "bullet", "Zcaron", "bullet",
+ "bullet", "quoteleft", "quoteright", "quotedblleft",
+ "quotedblright", "bullet", "endash", "emdash",
+ "tilde", "trademark", "scaron", "guilsinglright",
+ "oe", "bullet", "zcaron", "Ydieresis",
+ "space", "exclamdown", "cent", "sterling",
+ "currency", "yen", "brokenbar", "section",
+ "dieresis", "copyright", "ordfeminine", "guillemotleft",
+ "logicalnot", "hyphen", "registered", "macron",
+ "degree", "plusminus", "twosuperior", "threesuperior",
+ "acute", "mu", "paragraph", "periodcentered",
+ "cedilla", "onesuperior", "ordmasculine", "guillemotright",
+ "onequarter", "onehalf", "threequarters", "questiondown",
+ "Agrave", "Aacute", "Acircumflex", "Atilde",
+ "Adieresis", "Aring", "AE", "Ccedilla",
+ "Egrave", "Eacute", "Ecircumflex", "Edieresis",
+ "Igrave", "Iacute", "Icircumflex", "Idieresis",
+ "Eth", "Ntilde", "Ograve", "Oacute",
+ "Ocircumflex", "Otilde", "Odieresis", "multiply",
+ "Oslash", "Ugrave", "Uacute", "Ucircumflex",
+ "Udieresis", "Yacute", "Thorn", "germandbls",
+ "agrave", "aacute", "acircumflex", "atilde",
+ "adieresis", "aring", "ae", "ccedilla",
+ "egrave", "eacute", "ecircumflex", "edieresis",
+ "igrave", "iacute", "icircumflex", "idieresis",
+ "eth", "ntilde", "ograve", "oacute",
+ "ocircumflex", "otilde", "odieresis", "divide",
+ "oslash", "ugrave", "uacute", "ucircumflex",
+ "udieresis", "yacute", "thorn", "ydieresis"
+};
+
+#if 0
+static const char *
+StandardEncoding[256] = {
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quoteright",
+ "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash",
+ "zero", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "colon", "semicolon",
+ "less", "equal", "greater", "question",
+ "at", "A", "B", "C",
+ "D", "E", "F", "G",
+ "H", "I", "J", "K",
+ "L", "M", "N", "O",
+ "P", "Q", "R", "S",
+ "T", "U", "V", "W",
+ "X", "Y", "Z", "bracketleft",
+ "backslash", "bracketright", "asciicircum", "underscore",
+ "quoteleft", "a", "b", "c",
+ "d", "e", "f", "g",
+ "h", "i", "j", "k",
+ "l", "m", "n", "o",
+ "p", "q", "r", "s",
+ "t", "u", "v", "w",
+ "x", "y", "z", "braceleft",
+ "bar", "braceright", "asciitilde", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", "exclamdown", "cent", "sterling",
+ "fraction", "yen", "florin", "section",
+ "currency", "quotesingle", "quotedblleft", "guillemotleft",
+ "guilsinglleft", "guilsinglright", "fi", "fl",
+ ".notdef", "endash", "dagger", "daggerdbl",
+ "periodcentered", ".notdef", "paragraph", "bullet",
+ "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
+ "ellipsis", "perthousand", ".notdef", "questiondown",
+ ".notdef", "grave", "acute", "circumflex",
+ "tilde", "macron", "breve", "dotaccent",
+ "dieresis", ".notdef", "ring", "cedilla",
+ ".notdef", "hungarumlaut", "ogonek", "caron",
+ "emdash", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", "AE", ".notdef", "ordfeminine",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "Lslash", "Oslash", "OE", "ordmasculine",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", "ae", ".notdef", ".notdef",
+ ".notdef", "dotlessi", ".notdef", ".notdef",
+ "lslash", "oslash", "oe", "germandbls",
+ ".notdef", ".notdef", ".notdef", ".notdef"
+};
+
+static const char *
+ISOLatin1Encoding[256] = {
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quotesingle",
+ "parenleft", "parenright", "asterisk", "plus",
+ "comma", "hyphen", "period", "slash",
+ "zero", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "colon", "semicolon",
+ "less", "equal", "greater", "question",
+ "at", "A", "B", "C",
+ "D", "E", "F", "G",
+ "H", "I", "J", "K",
+ "L", "M", "N", "O",
+ "P", "Q", "R", "S",
+ "T", "U", "V", "W",
+ "X", "Y", "Z", "bracketleft",
+ "backslash", "bracketright", "asciicircum", "underscore",
+ "grave", "a", "b", "c",
+ "d", "e", "f", "g",
+ "h", "i", "j", "k",
+ "l", "m", "n", "o",
+ "p", "q", "r", "s",
+ "t", "u", "v", "w",
+ "x", "y", "z", "braceleft",
+ "bar", "braceright", "asciitilde", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef",
+ "dotlessi", "quoteleft", "quoteright", "circumflex",
+ "tilde", "macron", "breve", "dotaccent",
+ "dieresis", ".notdef", "ring", "cedilla",
+ ".notdef", "hungarumlaut", "ogonek", "caron",
+ "space", "exclamdown", "cent", "sterling",
+ "currency", "yen", "brokenbar", "section",
+ "dieresis", "copyright", "ordfeminine", "guillemotleft",
+ "logicalnot", "hyphen", "registered", "macron",
+ "degree", "plusminus", "twosuperior", "threesuperior",
+ "acute", "mu", "paragraph", "periodcentered",
+ "cedilla", "onesuperior", "ordmasculine", "guillemotright",
+ "onequarter", "onehalf", "threequarters", "questiondown",
+ "Agrave", "Aacute", "Acircumflex", "Atilde",
+ "Adieresis", "Aring", "AE", "Ccedilla",
+ "Egrave", "Eacute", "Ecircumflex", "Edieresis",
+ "Igrave", "Iacute", "Icircumflex", "Idieresis",
+ "Eth", "Ntilde", "Ograve", "Oacute",
+ "Ocircumflex", "Otilde", "Odieresis", "multiply",
+ "Oslash", "Ugrave", "Uacute", "Ucircumflex",
+ "Udieresis", "Yacute", "Thorn", "germandbls",
+ "agrave", "aacute", "acircumflex", "atilde",
+ "adieresis", "aring", "ae", "ccedilla",
+ "egrave", "eacute", "ecircumflex", "edieresis",
+ "igrave", "iacute", "icircumflex", "idieresis",
+ "eth", "ntilde", "ograve", "oacute",
+ "ocircumflex", "otilde", "odieresis", "divide",
+ "oslash", "ugrave", "uacute", "ucircumflex",
+ "udieresis", "yacute", "thorn", "ydieresis"
+};
+#endif
diff --git a/Build/source/texk/dvipdfm-x/pdfencoding.h b/Build/source/texk/dvipdfm-x/pdfencoding.h
new file mode 100644
index 00000000000..1c7c8e23bbb
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfencoding.h
@@ -0,0 +1,76 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFENCODING_H_
+#define _PDFENCODING_H_
+
+#include "pdfobj.h"
+
+extern void pdf_init_encodings (void);
+extern void pdf_close_encodings (void);
+
+/* Creates Encoding resource and ToUnicode CMap
+ * for all non-predefined encodings.
+ */
+extern void pdf_encoding_complete (void);
+
+/* enc_name here is .enc file name or the name of predefined
+ * encodings.
+ */
+extern int pdf_encoding_findresource (const char *enc_name);
+
+/* Returns the Encoding resource object.
+ */
+extern pdf_obj *pdf_get_encoding_obj (int enc_id);
+
+extern int pdf_encoding_is_predefined (int enc_id);
+extern void pdf_encoding_used_by_type3 (int enc_id);
+
+/* WARNING:
+ * Pointer(s) may change after another encoding is loaded.
+ */
+extern char *pdf_encoding_get_name (int enc_id);
+extern char **pdf_encoding_get_encoding (int enc_id);
+
+/*
+ * pdf_create_ToUnicode_CMap() returns stream object but not
+ * reference. This need to be renamed to other name like
+ * pdf_create_ToUnicode_stream().
+ */
+extern pdf_obj *pdf_create_ToUnicode_CMap (const char *enc_name,
+ char **enc_vec,
+ const char *is_used);
+
+/* pdf_encoding_copy_usedchars adds the given vector of used characters
+ * to the corresponding vector of the encoding.
+ */
+extern void pdf_encoding_add_usedchars (int encoding_id,
+ const char *is_used);
+
+extern pdf_obj * pdf_encoding_get_tounicode (int encoding_id);
+
+/* Just load CMap identified with 'ident'. (parsed)
+ * PDF stream object (not reference) returned.
+ */
+extern pdf_obj *pdf_load_ToUnicode_stream (const char *ident);
+
+#endif /* _PDFENCODINGS_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfencrypt.c b/Build/source/texk/dvipdfm-x/pdfencrypt.c
new file mode 100644
index 00000000000..524181b084f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfencrypt.c
@@ -0,0 +1,764 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "system.h"
+#include "mem.h"
+#include "numbers.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+#include "unicode.h"
+#include "dpxcrypt.h"
+
+/* Encryption support
+ *
+ * Supported: 40-128 bit RC4, 128 bit AES, 256 bit AES
+ *
+ * TODO: Convert password to PDFDocEncoding. SASLPrep stringpref for AESV3.
+ */
+
+
+#define USE_ADOBE_EXTENSION 1
+
+#include "dvipdfmx.h"
+#include "pdfencrypt.h"
+
+struct pdf_sec {
+ unsigned char key[32];
+ int key_size;
+
+ unsigned char ID[16];
+ unsigned char O[48], U[48];
+ unsigned char OE[32], UE[32];
+ int V, R;
+ int32_t P;
+
+ struct {
+ int use_aes;
+ int encrypt_metadata;
+ int need_adobe_extension;
+ } setting;
+
+ struct {
+ uint64_t objnum;
+ uint16_t gennum;
+ } label;
+};
+
+static void pdf_enc_set_password (pdf_sec *p_sec, unsigned int bits, unsigned int perm,
+ const char *oplain, const char *uplain);
+
+static const unsigned char padding_bytes[32] = {
+ 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
+ 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
+ 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
+ 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
+};
+
+pdf_sec *
+pdf_enc_init (const unsigned char *id,
+ int keybits, uint32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata)
+{
+ time_t current_time;
+ pdf_sec *p_sec;
+
+ p_sec = NEW(1, pdf_sec);
+ memset(p_sec, 0, sizeof(pdf_sec));
+ current_time = dpx_util_get_unique_time_if_given();
+ if (current_time == INVALID_EPOCH_VALUE)
+ current_time = time(NULL);
+ srand(current_time); /* For AES IV */
+ p_sec->setting.use_aes = use_aes;
+ p_sec->setting.encrypt_metadata = encrypt_metadata;
+ p_sec->setting.need_adobe_extension = 0;
+
+ memcpy(p_sec->ID, id, 16);
+ pdf_enc_set_password(p_sec, keybits, permission, opasswd, upasswd);
+
+ return p_sec;
+}
+
+void
+pdf_enc_close (pdf_sec **p_sec)
+{
+ if (p_sec && *p_sec) {
+ RELEASE(*p_sec);
+ *p_sec = NULL;
+ }
+}
+
+static void
+passwd_padding (const char *src, unsigned char *dst)
+{
+ int len;
+
+ len = MIN(32, strlen(src));
+
+ memcpy(dst, src, len);
+ memcpy(dst + len, padding_bytes, 32 - len);
+}
+
+static void
+compute_owner_password (pdf_sec *p_sec,
+ const char *opasswd, const char *upasswd)
+{
+ int i, j;
+ unsigned char padded[32];
+ MD5_CONTEXT md5;
+ ARC4_CONTEXT arc4;
+ unsigned char hash[16];
+
+ passwd_padding((strlen(opasswd) > 0 ? opasswd : upasswd), padded);
+
+ MD5_init (&md5);
+ MD5_write(&md5, padded, 32);
+ MD5_final(hash, &md5);
+ if (p_sec->R >= 3) {
+ for (i = 0; i < 50; i++) {
+ /*
+ * NOTE: We truncate each MD5 hash as in the following step.
+ * Otherwise Adobe Reader won't decrypt the PDF file.
+ */
+ MD5_init (&md5);
+ MD5_write(&md5, hash, p_sec->key_size);
+ MD5_final(hash, &md5);
+ }
+ }
+ ARC4_set_key(&arc4, p_sec->key_size, hash);
+ passwd_padding(upasswd, padded);
+ {
+ unsigned char tmp1[32], tmp2[32];
+ unsigned char key[16];
+
+ ARC4(&arc4, 32, padded, tmp1);
+ if (p_sec->R >= 3) {
+ for (i = 1; i <= 19; i++) {
+ memcpy(tmp2, tmp1, 32);
+ for (j = 0; j < p_sec->key_size; j++)
+ key[j] = hash[j] ^ i;
+ ARC4_set_key(&arc4, p_sec->key_size, key);
+ ARC4(&arc4, 32, tmp2, tmp1);
+ }
+ }
+ memcpy(p_sec->O, tmp1, 32);
+ }
+}
+
+static void
+compute_encryption_key (pdf_sec *p_sec, const char *passwd)
+{
+ int i;
+ unsigned char hash[32], padded[32];
+ MD5_CONTEXT md5;
+
+ passwd_padding(passwd, padded);
+ MD5_init (&md5);
+ MD5_write(&md5, padded, 32);
+ MD5_write(&md5, p_sec->O, 32);
+ {
+ unsigned char tmp[4];
+
+ tmp[0] = (unsigned char)(p_sec->P) & 0xFF;
+ tmp[1] = (unsigned char)(p_sec->P >> 8) & 0xFF;
+ tmp[2] = (unsigned char)(p_sec->P >> 16) & 0xFF;
+ tmp[3] = (unsigned char)(p_sec->P >> 24) & 0xFF;
+ MD5_write(&md5, tmp, 4);
+ }
+ MD5_write(&md5, p_sec->ID, 16);
+#if 0
+ /* Not Supported Yet */
+ if (!p_sec->setting.encrypt_metadata) {
+ unsigned char tmp[4] = {0xff, 0xff, 0xff, 0xff};
+ MD5_write(&md5, tmp, 4);
+ }
+#endif
+ MD5_final(hash, &md5);
+
+ if (p_sec->R >= 3) {
+ for (i = 0; i < 50; i++) {
+ /*
+ * NOTE: We truncate each MD5 hash as in the following step.
+ * Otherwise Adobe Reader won't decrypt the PDF file.
+ */
+ MD5_init (&md5);
+ MD5_write(&md5, hash, p_sec->key_size);
+ MD5_final(hash, &md5);
+ }
+ }
+ memcpy(p_sec->key, hash, p_sec->key_size);
+}
+
+static void
+compute_user_password (pdf_sec *p_sec, const char *uplain)
+{
+ int i, j;
+ ARC4_CONTEXT arc4;
+ MD5_CONTEXT md5;
+ unsigned char upasswd[32];
+
+ compute_encryption_key(p_sec, uplain);
+
+ switch (p_sec->R) {
+ case 2:
+ ARC4_set_key(&arc4, p_sec->key_size, p_sec->key);
+ ARC4(&arc4, 32, padding_bytes, upasswd);
+ break;
+ case 3: case 4:
+ {
+ unsigned char hash[32];
+ unsigned char tmp1[32], tmp2[32];
+
+ MD5_init (&md5);
+ MD5_write(&md5, padding_bytes, 32);
+
+ MD5_write(&md5, p_sec->ID, 16);
+ MD5_final(hash, &md5);
+
+ ARC4_set_key(&arc4, p_sec->key_size, p_sec->key);
+ ARC4(&arc4, 16, hash, tmp1);
+
+ for (i = 1; i <= 19; i++) {
+ unsigned char key[16];
+
+ memcpy(tmp2, tmp1, 16);
+ for (j = 0; j < p_sec->key_size; j++)
+ key[j] = p_sec->key[j] ^ i;
+ ARC4_set_key(&arc4, p_sec->key_size, key);
+ ARC4(&arc4, 16, tmp2, tmp1);
+ }
+ memcpy(upasswd, tmp1, 32);
+ }
+ break;
+ default:
+ ERROR("Invalid revision number.");
+ }
+
+ memcpy(p_sec->U, upasswd, 32);
+}
+
+/* Algorithm 2.B from ISO 32000-1 chapter 7 */
+static void
+compute_hash_V5 (unsigned char *hash,
+ const char *passwd,
+ const unsigned char *salt,
+ const unsigned char *user_key, int R /* revision */)
+{
+ unsigned char K[64];
+ size_t K_len;
+ int nround;
+
+ {
+ SHA256_CONTEXT sha;
+
+ SHA256_init (&sha);
+ SHA256_write(&sha, (const unsigned char *)passwd, strlen(passwd));
+ SHA256_write(&sha, salt, 8);
+ if (user_key)
+ SHA256_write(&sha, user_key, 48);
+ SHA256_final(hash, &sha);
+ }
+
+ ASSERT( R ==5 || R == 6 );
+
+ if (R == 5)
+ return;
+
+ memcpy(K, hash, 32); K_len = 32;
+ for (nround = 1; ; nround++) { /* Initial K count as nround 0. */
+ unsigned char K1[256], *Kr, *E;
+ size_t K1_len, E_len;
+ int i, c, E_mod3 = 0;
+
+ K1_len = strlen(passwd) + K_len + (user_key ? 48 : 0);
+ ASSERT(K1_len < 240);
+ memcpy(K1, passwd, strlen(passwd));
+ memcpy(K1 + strlen(passwd), K, K_len);
+ if (user_key)
+ memcpy(K1 + strlen(passwd) + K_len, user_key, 48);
+
+ Kr = NEW(K1_len * 64, unsigned char);
+ for (i = 0; i < 64; i++)
+ memcpy(Kr + i * K1_len, K1, K1_len);
+ AES_cbc_encrypt(K, 16, K + 16, 0, Kr, K1_len * 64, &E, &E_len);
+ RELEASE(Kr);
+
+ for (i = 0; i < 16; i++)
+ E_mod3 += E[i];
+ E_mod3 %= 3;
+
+ switch (E_mod3) {
+ case 0:
+ {
+ SHA256_CONTEXT sha;
+
+ SHA256_init (&sha);
+ SHA256_write(&sha, E, E_len);
+ SHA256_final(K, &sha);
+ K_len = 32;
+ }
+ break;
+ case 1:
+ {
+ SHA512_CONTEXT sha;
+
+ SHA384_init (&sha);
+ SHA384_write(&sha, E, E_len);
+ SHA384_final(K, &sha);
+ K_len = 48;
+ }
+ break;
+ case 2:
+ {
+ SHA512_CONTEXT sha;
+
+ SHA512_init (&sha);
+ SHA512_write(&sha, E, E_len);
+ SHA512_final(K, &sha);
+ K_len = 64;
+ }
+ break;
+ }
+ c = (uint8_t) E[E_len - 1];
+ RELEASE(E);
+ if (nround >= 64 && c <= nround - 32)
+ break;
+ }
+ memcpy(hash, K, 32);
+}
+
+static void
+compute_owner_password_V5 (pdf_sec *p_sec, const char *oplain)
+{
+ unsigned char vsalt[8], ksalt[8], hash[32];
+ unsigned char *OE, iv[AES_BLOCKSIZE];
+ size_t OE_len;
+ int i;
+
+ for (i = 0; i < 8 ; i++) {
+ vsalt[i] = rand() % 256;
+ ksalt[i] = rand() % 256;
+ }
+
+ compute_hash_V5(hash, oplain, vsalt, p_sec->U, p_sec->R);
+ memcpy(p_sec->O, hash, 32);
+ memcpy(p_sec->O + 32, vsalt, 8);
+ memcpy(p_sec->O + 40, ksalt, 8);
+
+ compute_hash_V5(hash, oplain, ksalt, p_sec->U, p_sec->R);
+ memset(iv, 0, AES_BLOCKSIZE);
+ AES_cbc_encrypt(hash, 32, iv, 0, p_sec->key, p_sec->key_size, &OE, &OE_len);
+ memcpy(p_sec->OE, OE, 32);
+ RELEASE(OE);
+}
+
+static void
+compute_user_password_V5 (pdf_sec *p_sec, const char *uplain)
+{
+ unsigned char vsalt[8], ksalt[8], hash[32];
+ unsigned char *UE, iv[AES_BLOCKSIZE];
+ size_t UE_len;
+ int i;
+
+ for (i = 0; i < 8 ; i++) {
+ vsalt[i] = rand() % 256;
+ ksalt[i] = rand() % 256;
+ }
+
+ compute_hash_V5(hash, uplain, vsalt, NULL, p_sec->R);
+ memcpy(p_sec->U, hash, 32);
+ memcpy(p_sec->U + 32, vsalt, 8);
+ memcpy(p_sec->U + 40, ksalt, 8);
+
+ compute_hash_V5(hash, uplain, ksalt, NULL, p_sec->R);
+ memset(iv, 0, AES_BLOCKSIZE);
+ AES_cbc_encrypt(hash, 32, iv, 0, p_sec->key, p_sec->key_size, &UE, &UE_len);
+ memcpy(p_sec->UE, UE, 32);
+ RELEASE(UE);
+}
+
+static void
+check_version (pdf_sec *p_sec, int version)
+{
+ if (p_sec->V > 2 && version < 14) {
+ WARN("Current encryption setting requires PDF version >= 1.4.");
+ p_sec->V = 1;
+ p_sec->key_size = 5;
+ } else if (p_sec->V == 4 && version < 15) {
+ WARN("Current encryption setting requires PDF version >= 1.5.");
+ p_sec->V = 2;
+ } else if (p_sec->V ==5 && version < 17) {
+ WARN("Current encryption setting requires PDF version >= 1.7" \
+ " (plus Adobe Extension Level 3).");
+ p_sec->V = 4;
+ p_sec->key_size = 16;
+ }
+ if (p_sec->V == 5 && version < 20) {
+ p_sec->setting.need_adobe_extension = 1;
+ }
+}
+
+/* Dummy routine for stringprep - NOT IMPLEMENTED YET
+ *
+ * Preprocessing of a user-provided password consists first of
+ * normalizing its representation by applying the "SASLPrep" profile (RFC 4013)
+ * of the "stringprep" algorithm (RFC 3454) to the supplied password using the
+ * Normalize and BiDi options.
+ */
+typedef int Stringprep_profile_flags;
+#define STRINGPREP_OK 0
+#define STRINGPREP_ERROR -1
+static int
+stringprep_profile(const char *input, char **output, const char *profile,
+ Stringprep_profile_flags flags)
+{
+ const char *p, *endptr;
+
+ p = input; endptr = p + strlen(p);
+ while (p < endptr) {
+ int32_t ucv = UC_UTF8_decode_char((const unsigned char **)&p,
+ (const unsigned char *)endptr);
+ if (!UC_is_valid(ucv))
+ return STRINGPREP_ERROR;
+ }
+
+ *output = NEW(strlen(input) + 1, char);
+ strcpy(*output, input);
+
+ (void) profile;
+ (void) flags;
+
+ return STRINGPREP_OK;
+}
+
+static int
+preproc_password (const char *passwd, char *outbuf, int V)
+{
+ char *saslpwd = NULL;
+ int error = 0;
+
+ memset(outbuf, 0, 128);
+ switch (V) {
+ case 1: case 2: case 3: case 4:
+ {
+ int i;
+ /* Need to be converted to PDFDocEncoding - UNIMPLEMENTED */
+ for (i = 0; i < strlen(passwd); i++) {
+ if (passwd[i] < 0x20 || passwd[i] > 0x7e)
+ WARN("Non-ASCII-printable character found in password.");
+ }
+ memcpy(outbuf, passwd, MIN(127, strlen(passwd)));
+ }
+ break;
+ case 5:
+ /* This is a dummy routine - not actually stringprep password... */
+ if (stringprep_profile(passwd, &saslpwd,
+ "SASLprep", 0) != STRINGPREP_OK)
+ return -1;
+ else if (saslpwd) {
+ memcpy(outbuf, saslpwd, MIN(127, strlen(saslpwd)));
+ RELEASE(saslpwd);
+ }
+ break;
+ default:
+ error = -1;
+ break;
+ }
+
+ return error;
+}
+
+static void
+pdf_enc_set_password (pdf_sec *p_sec, unsigned int bits, unsigned int perm,
+ const char *oplain, const char *uplain)
+{
+ char opasswd[128], upasswd[128];
+ int version;
+ char empty_passwd[1] = "\0";
+
+ version = pdf_get_version();
+
+ p_sec->key_size = (int) (bits / 8);
+ if (p_sec->key_size == 5) { /* 40bit */
+ p_sec->V = 1;
+ } else if (p_sec->key_size < 16) {
+ p_sec->V = 2;
+ } else if (p_sec->key_size == 16) {
+ p_sec->V = p_sec->setting.use_aes ? 4 : 2;
+ } else if (p_sec->key_size == 32) {
+ p_sec->V = 5;
+ } else {
+ WARN("Key length %d unsupported.", bits);
+ p_sec->key_size = 5;
+ p_sec->V = 2;
+ }
+ check_version(p_sec, version);
+
+ p_sec->P = (int32_t) (perm | 0xC0U);
+ /* Bit position 10 shall be always set to 1 for PDF >= 2.0. */
+ if (version >= 20)
+ p_sec->P |= (1 << 9);
+ switch (p_sec->V) {
+ case 1:
+ p_sec->R = (p_sec->P < 0x100L) ? 2 : 3;
+ break;
+ case 2: case 3:
+ p_sec->R = 3;
+ break;
+ case 4:
+ p_sec->R = 4;
+ break;
+ case 5:
+#if USE_ADOBE_EXTENSION
+ p_sec->R = 6;
+#else
+ WARN("Encryption V 5 unsupported.");
+ p_sec->R = 4; p_sec->V = 4;
+#endif
+ break;
+ default:
+ p_sec->R = 3;
+ break;
+ }
+
+ memset(opasswd, 0, 128);
+ memset(upasswd, 0, 128);
+ /* Password must be preprocessed. */
+ if (oplain) {
+ if (preproc_password(oplain, opasswd, p_sec->V) < 0)
+ WARN("Invaid UTF-8 string for password.");
+ } else {
+ preproc_password(empty_passwd, opasswd, p_sec->V);
+ }
+ if (uplain) {
+ if (preproc_password(uplain, upasswd, p_sec->V) < 0)
+ WARN("Invalid UTF-8 string for passowrd.");
+ } else {
+ preproc_password(empty_passwd, upasswd, p_sec->V);
+ }
+
+ if (p_sec->R >= 3)
+ p_sec->P |= 0xFFFFF000U;
+
+ if (p_sec->V < 5) {
+ compute_owner_password(p_sec, opasswd, upasswd);
+ compute_user_password (p_sec, upasswd);
+ } else if (p_sec->V == 5) {
+ int i;
+
+ for (i = 0; i < 32; i++)
+ p_sec->key[i] = rand() % 256;
+ p_sec->key_size = 32;
+ /* Order is important here */
+ compute_user_password_V5 (p_sec, upasswd);
+ compute_owner_password_V5(p_sec, opasswd); /* uses p_sec->U */
+ }
+}
+
+static void
+calculate_key (pdf_sec *p_sec, unsigned char *key)
+{
+ int len = p_sec->key_size + 5;
+ unsigned char tmp[25];
+ MD5_CONTEXT md5;
+
+ memcpy(tmp, p_sec->key, p_sec->key_size);
+ tmp[p_sec->key_size ] = (unsigned char) p_sec->label.objnum & 0xFF;
+ tmp[p_sec->key_size+1] = (unsigned char)(p_sec->label.objnum >> 8) & 0xFF;
+ tmp[p_sec->key_size+2] = (unsigned char)(p_sec->label.objnum >> 16) & 0xFF;
+ tmp[p_sec->key_size+3] = (unsigned char)(p_sec->label.gennum) & 0xFF;
+ tmp[p_sec->key_size+4] = (unsigned char)(p_sec->label.gennum >> 8) & 0xFF;
+ if (p_sec->V >= 4) {
+ tmp[p_sec->key_size + 5] = 0x73;
+ tmp[p_sec->key_size + 6] = 0x41;
+ tmp[p_sec->key_size + 7] = 0x6c;
+ tmp[p_sec->key_size + 8] = 0x54;
+ len += 4;
+ }
+ MD5_init (&md5);
+ MD5_write(&md5, tmp, len);
+ MD5_final(key, &md5);
+}
+
+void
+pdf_encrypt_data (pdf_sec *p_sec,
+ const unsigned char *plain, size_t plain_len,
+ unsigned char **cipher, size_t *cipher_len)
+{
+ unsigned char key[32];
+
+ ASSERT(p_sec);
+
+ switch (p_sec->V) {
+ case 1: case 2:
+ calculate_key(p_sec, key);
+ {
+ ARC4_CONTEXT arc4;
+
+ *cipher_len = plain_len;
+ *cipher = NEW(*cipher_len, unsigned char);
+ ARC4_set_key(&arc4, MIN(16, p_sec->key_size + 5), key);
+ ARC4(&arc4, plain_len, plain, *cipher);
+ }
+ break;
+ case 4:
+ calculate_key(p_sec, key);
+ AES_cbc_encrypt(key, MIN(16, p_sec->key_size + 5), NULL, 1,
+ plain, plain_len, cipher, cipher_len);
+ break;
+ case 5:
+ AES_cbc_encrypt(p_sec->key, p_sec->key_size, NULL, 1,
+ plain, plain_len, cipher, cipher_len);
+ break;
+ default:
+ ERROR("pdfencrypt: Unexpected V value: %d", p_sec->V);
+ break;
+ }
+}
+
+pdf_obj *
+pdf_enc_get_encrypt_dict (pdf_sec *p_sec)
+{
+ pdf_obj *doc_encrypt;
+
+ ASSERT(p_sec);
+
+ doc_encrypt = pdf_new_dict();
+
+ pdf_add_dict(doc_encrypt, pdf_new_name("Filter"), pdf_new_name("Standard"));
+ pdf_add_dict(doc_encrypt, pdf_new_name("V"), pdf_new_number(p_sec->V));
+#if 0
+ /* PDF reference describes it as:
+ *
+ * (Optional; PDF 1.4; only if V is 2 or 3)
+ *
+ * but Acrobat *requires* this even for V 5!
+ */
+ if (p_sec->V > 1 && p_sec->V < 4)
+#endif
+ pdf_add_dict(doc_encrypt,
+ pdf_new_name("Length"), pdf_new_number(p_sec->key_size * 8));
+ if (p_sec->V >= 4) {
+ pdf_obj *CF, *StdCF;
+ CF = pdf_new_dict();
+ StdCF = pdf_new_dict();
+ pdf_add_dict(StdCF, pdf_new_name("CFM"),
+ pdf_new_name( (p_sec->V == 4) ? "AESV2" : "AESV3" ));
+ pdf_add_dict(StdCF, pdf_new_name("AuthEvent"), pdf_new_name("DocOpen"));
+ pdf_add_dict(StdCF, pdf_new_name("Length"), pdf_new_number(p_sec->key_size));
+ pdf_add_dict(CF, pdf_new_name("StdCF"), StdCF);
+ pdf_add_dict(doc_encrypt, pdf_new_name("CF"), CF);
+ pdf_add_dict(doc_encrypt, pdf_new_name("StmF"), pdf_new_name("StdCF"));
+ pdf_add_dict(doc_encrypt, pdf_new_name("StrF"), pdf_new_name("StdCF"));
+#if 0
+ /* NOT SUPPORTED YET */
+ if (!p_sec->setting.encrypt_metadata)
+ pdf_add_dict(doc_encrypt,
+ pdf_new_name("EncryptMetadata"), pdf_new_boolean(false));
+#endif
+ }
+ pdf_add_dict(doc_encrypt, pdf_new_name("R"), pdf_new_number(p_sec->R));
+ if (p_sec->V < 5) {
+ pdf_add_dict(doc_encrypt, pdf_new_name("O"), pdf_new_string(p_sec->O, 32));
+ pdf_add_dict(doc_encrypt, pdf_new_name("U"), pdf_new_string(p_sec->U, 32));
+ } else if (p_sec->V == 5) {
+ pdf_add_dict(doc_encrypt, pdf_new_name("O"), pdf_new_string(p_sec->O, 48));
+ pdf_add_dict(doc_encrypt, pdf_new_name("U"), pdf_new_string(p_sec->U, 48));
+ }
+ pdf_add_dict(doc_encrypt, pdf_new_name("P"), pdf_new_number(p_sec->P));
+
+ if (p_sec->V == 5) {
+ unsigned char perms[16], *cipher = NULL;
+ size_t cipher_len = 0;
+
+ pdf_add_dict(doc_encrypt, pdf_new_name("OE"), pdf_new_string(p_sec->OE, 32));
+ pdf_add_dict(doc_encrypt, pdf_new_name("UE"), pdf_new_string(p_sec->UE, 32));
+ perms[0] = p_sec->P & 0xff;
+ perms[1] = (p_sec->P >> 8) & 0xff;
+ perms[2] = (p_sec->P >> 16) & 0xff;
+ perms[3] = (p_sec->P >> 24) & 0xff;
+ perms[4] = 0xff;
+ perms[5] = 0xff;
+ perms[6] = 0xff;
+ perms[7] = 0xff;
+ perms[8] = p_sec->setting.encrypt_metadata ? 'T' : 'F';
+ perms[9] = 'a';
+ perms[10] = 'd';
+ perms[11] = 'b';
+ perms[12] = 0;
+ perms[13] = 0;
+ perms[14] = 0;
+ perms[15] = 0;
+ AES_ecb_encrypt(p_sec->key, p_sec->key_size, perms, 16, &cipher, &cipher_len);
+ pdf_add_dict(doc_encrypt,
+ pdf_new_name("Perms"), pdf_new_string(cipher, cipher_len));
+ RELEASE(cipher);
+ }
+
+ return doc_encrypt;
+}
+
+pdf_obj *
+pdf_enc_get_extension_dict (pdf_sec *p_sec)
+{
+ pdf_obj *ext = NULL, *adbe;
+
+ ASSERT(p_sec);
+
+#ifdef USE_ADOBE_EXTENSION
+ if (p_sec->setting.need_adobe_extension) {
+ ext = pdf_new_dict();
+ adbe = pdf_new_dict();
+
+ pdf_add_dict(adbe, pdf_new_name("BaseVersion"), pdf_new_name("1.7"));
+ pdf_add_dict(adbe, pdf_new_name("ExtensionLevel"),
+ pdf_new_number(p_sec->R == 5 ? 3 : 8));
+ pdf_add_dict(ext, pdf_new_name("ADBE"), adbe);
+ }
+#endif
+
+ return ext;
+}
+
+void pdf_enc_set_label (pdf_sec *p_sec, unsigned label)
+{
+ ASSERT(p_sec);
+
+ p_sec->label.objnum = label;
+}
+
+void pdf_enc_set_generation (pdf_sec *p_sec, unsigned generation)
+{
+ ASSERT(p_sec);
+
+ p_sec->label.gennum = generation;
+}
diff --git a/Build/source/texk/dvipdfm-x/pdfencrypt.h b/Build/source/texk/dvipdfm-x/pdfencrypt.h
new file mode 100644
index 00000000000..885cdc6d0b6
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfencrypt.h
@@ -0,0 +1,45 @@
+/*
+
+ This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFENCRYPT_H_
+#define _PDFENCRYPT_H_
+
+#include "pdfobj.h"
+#include "pdfdoc.h"
+
+#define MAX_PWD_LEN 127
+
+typedef struct pdf_sec pdf_sec;
+extern pdf_sec *pdf_enc_init (const unsigned char *id,
+ int keybits, uint32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata);
+extern void pdf_enc_close (pdf_sec **p_sec);
+
+extern void pdf_enc_set_label (pdf_sec *p_sec, unsigned label);
+extern void pdf_enc_set_generation (pdf_sec *p_sec, unsigned generation);
+extern void pdf_encrypt_data (pdf_sec *p_sec, const unsigned char *plain, size_t plain_len,
+ unsigned char **cipher, size_t *cipher_len);
+extern pdf_obj *pdf_enc_get_encrypt_dict (pdf_sec *p_sec);
+extern pdf_obj *pdf_enc_get_extension_dict (pdf_sec *p_sec);
+
+#endif /* _PDFENCRYPT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdffont.c b/Build/source/texk/dvipdfm-x/pdffont.c
new file mode 100644
index 00000000000..b95d150ba21
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdffont.c
@@ -0,0 +1,1091 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+#include "dpxfile.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+
+#include "agl.h"
+#include "pdfencoding.h"
+#include "cmap.h"
+#include "unicode.h"
+
+#include "type1.h"
+#include "type1c.h"
+#include "truetype.h"
+
+#include "pkfont.h"
+
+#include "cidtype0.h"
+#include "type0.h"
+#include "tt_cmap.h"
+
+#include "pdffont.h"
+
+#define MREC_HAS_TOUNICODE(m) ((m) && (m)->opt.tounicode)
+
+void
+pdf_font_set_dpi (int font_dpi)
+{
+ PKFont_set_dpi(font_dpi);
+}
+
+void
+pdf_font_make_uniqueTag (char *tag)
+{
+ int i;
+ char ch;
+
+ for (i = 0; i < 6; i++) {
+ ch = rand() % 26;
+ tag[i] = ch + 'A';
+ }
+ tag[6] = '\0';
+}
+
+static void
+init_CIDSysInfo (CIDSysInfo *csi) {
+ csi->registry = NULL;
+ csi->ordering = NULL;
+ csi->supplement = 0;
+}
+
+static void
+pdf_init_font_struct (pdf_font *font)
+{
+ ASSERT(font);
+
+ font->ident = NULL;
+ font->filename = NULL;
+ font->subtype = -1;
+ font->font_id = -1;
+ font->fontname = NULL;
+ memset(font->uniqueID, 0, 7);
+ font->index = 0;
+
+ font->encoding_id = -1;
+
+ font->reference = NULL;
+ font->resource = NULL;
+ font->descriptor = NULL;
+
+ font->point_size = 0;
+ font->design_size = 0;
+
+ font->usedchars = NULL;
+ font->flags = 0;
+
+ font->type0.descendant = -1;
+ font->type0.wmode = 0;
+
+ init_CIDSysInfo(&font->cid.csi);
+ font->cid.need_vmetrics = 0;
+ font->cid.usedchars_v = NULL;
+ font->cid.options.embed = 0;
+ font->cid.options.style = FONT_STYLE_NONE;
+ font->cid.options.stemv = 0;
+ init_CIDSysInfo(&font->cid.options.csi);
+
+ return;
+}
+
+static void
+pdf_flush_font (pdf_font *font)
+{
+ char *fontname, *uniqueTag;
+
+ if (!font)
+ return;
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) || (font->flags & PDF_FONT_FLAG_IS_REENCODE)) {
+ return;
+ }
+
+ if (font->resource && font->reference) {
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_TYPE3:
+ case PDF_FONT_FONTTYPE_TYPE0:
+ break;
+ case PDF_FONT_FONTTYPE_CIDTYPE0:
+ case PDF_FONT_FONTTYPE_CIDTYPE2:
+ break;
+ default:
+ if (font->flags & PDF_FONT_FLAG_NOEMBED) {
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
+ if (font->descriptor) {
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(font->fontname));
+ }
+ } else {
+ ASSERT(font->fontname);
+ fontname = NEW(7+strlen(font->fontname)+1, char);
+ uniqueTag = pdf_font_get_uniqueTag(font);
+ sprintf(fontname, "%6s+%s", uniqueTag, font->fontname);
+ pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(fontname));
+ if (font->descriptor) {
+ pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(fontname));
+ }
+ RELEASE(fontname);
+ }
+ if (font->descriptor) {
+ pdf_add_dict(font->resource, pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor));
+ }
+ }
+ }
+
+ if (font->resource)
+ pdf_release_obj(font->resource);
+ if (font->descriptor)
+ pdf_release_obj(font->descriptor);
+ if (font->reference)
+ pdf_release_obj(font->reference);
+
+ font->reference = NULL;
+ font->resource = NULL;
+ font->descriptor = NULL;
+
+ return;
+}
+
+static void
+pdf_clean_font_struct (pdf_font *font)
+{
+ if (!font)
+ return;
+
+ if (font->resource)
+ WARN("font \"%s\" not properly released?", font->ident);
+
+ if (font->ident)
+ RELEASE(font->ident);
+ if (font->filename)
+ RELEASE(font->filename);
+ if (font->fontname)
+ RELEASE(font->fontname);
+ if (font->usedchars) {
+ if (!(font->flags & PDF_FONT_FLAG_USEDCHAR_SHARED))
+ RELEASE(font->usedchars);
+ }
+ if (font->cid.csi.registry)
+ RELEASE(font->cid.csi.registry);
+ if (font->cid.csi.ordering)
+ RELEASE(font->cid.csi.ordering);
+ if (font->cid.options.csi.registry)
+ RELEASE(font->cid.options.csi.registry);
+ if (font->cid.options.csi.ordering)
+ RELEASE(font->cid.options.csi.ordering);
+ if (font->cid.usedchars_v)
+ RELEASE(font->cid.usedchars_v);
+
+ font->ident = NULL;
+ font->filename = NULL;
+ font->fontname = NULL;
+ font->usedchars = NULL;
+ font->cid.csi.registry = NULL;
+ font->cid.csi.ordering = NULL;
+ font->cid.options.csi.registry = NULL;
+ font->cid.options.csi.ordering = NULL;
+ font->cid.usedchars_v = NULL;
+
+ return;
+}
+
+#define CACHE_ALLOC_SIZE 16u
+
+static struct {
+ int count;
+ int capacity;
+ pdf_font *fonts;
+} font_cache = {
+ 0, 0, NULL
+};
+
+void
+pdf_init_fonts (void)
+{
+ ASSERT(font_cache.fonts == NULL);
+
+ agl_init_map();
+
+ CMap_cache_init();
+ pdf_init_encodings();
+
+ font_cache.count = 0;
+ font_cache.capacity = CACHE_ALLOC_SIZE;
+ font_cache.fonts = NEW(font_cache.capacity, pdf_font);
+
+ {
+ time_t current_time;
+
+ current_time = dpx_util_get_unique_time_if_given();
+ if (current_time == INVALID_EPOCH_VALUE)
+ current_time = time(NULL);
+ srand(current_time);
+ }
+}
+
+#define CHECK_ID(n) do {\
+ if ((n) < 0 || (n) >= font_cache.count) {\
+ ERROR("Invalid font ID: %d", (n));\
+ }\
+} while (0)
+
+static pdf_font *
+GET_FONT (int font_id)
+{
+ pdf_font *font = NULL;
+
+ if (font_id >= 0 && font_id < font_cache.count) {
+ font = &font_cache.fonts[font_id];
+ if (font->flags & PDF_FONT_FLAG_IS_ALIAS) {
+ font = &font_cache.fonts[font->font_id];
+ }
+ }
+
+ return font;
+}
+
+pdf_font *
+pdf_get_font_data (int font_id)
+{
+ CHECK_ID(font_id);
+
+ return &font_cache.fonts[font_id];
+}
+
+char *
+pdf_get_font_ident (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = &font_cache.fonts[font_id];
+
+ return font->ident;
+}
+
+pdf_obj *
+pdf_get_font_reference (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+ if (!font->reference) {
+ font->reference = pdf_ref_obj(pdf_font_get_resource(font));
+ }
+ if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
+ if (!pdf_lookup_dict(font->resource, "DescendantFonts")) {
+ pdf_obj *array;
+
+ array = pdf_new_array();
+ pdf_add_array(array, pdf_get_font_reference(font->type0.descendant));
+ pdf_add_dict(font->resource, pdf_new_name("DescendantFonts"), array);
+ }
+ }
+
+ return pdf_link_obj(font->reference);
+}
+
+pdf_obj *
+pdf_get_font_resource (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+ if (!font->resource)
+ font->resource = pdf_new_dict();
+
+ return font->resource; /* FIXME */
+}
+
+char *
+pdf_get_font_usedchars (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
+ if (!font->usedchars) {
+ font->usedchars = NEW(256, char);
+ memset(font->usedchars, 0, 256 * sizeof(char));
+ }
+ }
+
+ return font->usedchars;
+}
+
+int
+pdf_get_font_wmode (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+ if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
+ return font->type0.wmode;
+ } else {
+ return 0;
+ }
+}
+
+int
+pdf_get_font_subtype (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font = GET_FONT(font->font_id);
+ }
+
+ return font->subtype;
+}
+
+int
+pdf_get_font_encoding (int font_id)
+{
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = GET_FONT(font_id);
+
+ return font->encoding_id;
+}
+
+int
+pdf_font_resource_name (int font_id, char *buff)
+{
+ int len;
+ pdf_font *font;
+
+ CHECK_ID(font_id);
+
+ font = &font_cache.fonts[font_id];
+ if (font->flags & PDF_FONT_FLAG_IS_ALIAS) {
+ font_id = font->font_id;
+ }
+ font = GET_FONT(font_id);
+ if (font->flags & PDF_FONT_FLAG_IS_REENCODE) {
+ font_id = font->font_id;
+ }
+ len = sprintf(buff, "F%d", font_id);
+
+ return len;
+}
+
+/* The rule for ToUnicode creation is:
+ *
+ * If "tounicode" option is specified in fontmap, use that.
+ * If there is ToUnicode CMap with same name as TFM, use that.
+ * If no "tounicode" option is used and no ToUnicode CMap with
+ * same name as TFM is found, create ToUnicode CMap from glyph
+ * names and AGL file.
+ */
+static int
+try_load_ToUnicode_CMap (pdf_font *font)
+{
+ pdf_obj *tounicode;
+ const char *cmap_name = NULL;
+ fontmap_rec *mrec = NULL; /* Be sure fontmap is still alive here */
+
+ ASSERT(font);
+
+ /* We are using different encoding for Type0 font.
+ * This feature is unavailable for them.
+ */
+ if (font->subtype == PDF_FONT_FONTTYPE_TYPE0)
+ return 0;
+
+ ASSERT(font->ident);
+
+ mrec = pdf_lookup_fontmap_record(font->ident);
+ if (MREC_HAS_TOUNICODE(mrec)) {
+ cmap_name = mrec->opt.tounicode;
+ } else {
+ cmap_name = font->ident;
+ }
+ tounicode = pdf_load_ToUnicode_stream(cmap_name);
+
+ if (!tounicode) {
+ if (MREC_HAS_TOUNICODE(mrec)) {
+ WARN("Failed to read ToUnicode mapping \"%s\"...", mrec->opt.tounicode);
+ }
+ } else {
+ if (pdf_obj_typeof(tounicode) != PDF_STREAM) {
+ ERROR("Object returned by pdf_load_ToUnicode_stream() not stream object! (This must be bug)");
+ } else if (pdf_stream_length(tounicode) > 0) {
+ pdf_obj *fontdict = pdf_font_get_resource(font);
+
+ pdf_add_dict(fontdict,
+ pdf_new_name("ToUnicode"),
+ pdf_ref_obj (tounicode)); /* _FIXME_ */
+ if (dpx_conf.verbose_level > 0)
+ MESG("pdf_font>> ToUnicode CMap \"%s\" attached to font id=\"%s\".\n",
+ cmap_name, font->ident);
+ }
+ pdf_release_obj(tounicode);
+ }
+
+ return 0;
+}
+
+void
+pdf_close_fonts (void)
+{
+ int font_id;
+
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ pdf_font *font;
+
+ font = &font_cache.fonts[font_id];
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) ||
+ (font->flags & PDF_FONT_FLAG_IS_REENCODE) ||
+ !font->reference) {
+ continue;
+ }
+ if (font->subtype == PDF_FONT_FONTTYPE_CIDTYPE0 ||
+ font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2) {
+ continue;
+ }
+
+ if (dpx_conf.verbose_level > 0) {
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
+ MESG("(%s", font->filename);
+ if (dpx_conf.verbose_level > 2 &&
+ !(font->flags & PDF_FONT_FLAG_NOEMBED)) {
+ MESG("[%s+%s]", pdf_font_get_uniqueTag(font), font->fontname);
+ } else if (dpx_conf.verbose_level > 1) {
+ MESG("[%s]", font->fontname);
+ }
+ if (dpx_conf.verbose_level > 1) {
+ if (font->encoding_id >= 0) {
+ MESG("[%s]", pdf_encoding_get_name(font->encoding_id));
+ } else {
+ MESG("[built-in]");
+ }
+ }
+ }
+ }
+
+ /* Must come before load_xxx */
+ try_load_ToUnicode_CMap(font);
+
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_TYPE1:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[Type1]");
+ if (!(font->flags & PDF_FONT_FLAG_BASEFONT))
+ pdf_font_load_type1(font);
+ break;
+ case PDF_FONT_FONTTYPE_TYPE1C:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[Type1C]");
+ pdf_font_load_type1c(font);
+ break;
+ case PDF_FONT_FONTTYPE_TRUETYPE:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[TrueType]");
+ pdf_font_load_truetype(font);
+ break;
+ case PDF_FONT_FONTTYPE_TYPE3:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[Type3/PK]");
+ pdf_font_load_pkfont (font);
+ break;
+ case PDF_FONT_FONTTYPE_TYPE0:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[Type0]");
+ pdf_font_load_type0(font);
+ break;
+ }
+
+ if (font->encoding_id >= 0) {
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
+ pdf_encoding_add_usedchars(font->encoding_id, font->usedchars);
+ }
+ }
+
+ if (dpx_conf.verbose_level > 0) {
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
+ MESG(")");
+ }
+ }
+ }
+
+ pdf_encoding_complete();
+ /* Order is important... */
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ pdf_font *font = &font_cache.fonts[font_id];
+
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) ||
+ (font->flags & PDF_FONT_FLAG_IS_REENCODE) ||
+ !font->reference) {
+ continue;
+ }
+
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_CIDTYPE0:
+ case PDF_FONT_FONTTYPE_CIDTYPE2:
+ pdf_font_load_cidfont(font);
+ break;
+ }
+ }
+
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ pdf_font *font;
+
+ font = &font_cache.fonts[font_id];
+
+ if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) ||
+ (font->flags & PDF_FONT_FLAG_IS_REENCODE) ||
+ !font->reference) {
+ pdf_clean_font_struct(font);
+ continue;
+ }
+
+ if (font->encoding_id >= 0 &&
+ font->subtype != PDF_FONT_FONTTYPE_TYPE0 &&
+ font->subtype != PDF_FONT_FONTTYPE_CIDTYPE0 &&
+ font->subtype != PDF_FONT_FONTTYPE_CIDTYPE2) {
+ pdf_obj *enc_obj = pdf_get_encoding_obj(font->encoding_id);
+ pdf_obj *tounicode;
+
+ /* Predefined encodings (and those simplified to them) are embedded
+ * as direct objects, but this is purely a matter of taste.
+ */
+ if (enc_obj) {
+ if (font->subtype == PDF_FONT_FONTTYPE_TRUETYPE) {
+ if (pdf_encoding_is_predefined(font->encoding_id) && PDF_OBJ_NAMETYPE(enc_obj)) {
+ pdf_add_dict(font->resource,
+ pdf_new_name("Encoding"), pdf_link_obj(enc_obj));
+ }
+ } else {
+ pdf_add_dict(font->resource,
+ pdf_new_name("Encoding"),
+ PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj));
+ }
+ }
+ /* For built-in encoding, each font loader create ToUnicode CMap. */
+ if (!pdf_lookup_dict(font->resource, "ToUnicode")) {
+ tounicode = pdf_encoding_get_tounicode(font->encoding_id);
+ if (tounicode) {
+ pdf_add_dict(font->resource,
+ pdf_new_name("ToUnicode"), pdf_ref_obj(tounicode));
+ }
+ }
+ } else if (font->subtype == PDF_FONT_FONTTYPE_TRUETYPE) {
+ /* encoding_id < 0 means MacRoman here (but not really)
+ * We use MacRoman as "default" encoding. */
+ pdf_add_dict(font->resource,
+ pdf_new_name("Encoding"),
+ pdf_new_name("MacRomanEncoding"));
+ }
+ pdf_flush_font(font);
+ pdf_clean_font_struct(font);
+ }
+
+ RELEASE(font_cache.fonts);
+ font_cache.fonts = NULL;
+ font_cache.count = 0;
+ font_cache.capacity = 0;
+
+ CMap_cache_close();
+ pdf_close_encodings();
+
+ agl_close_map (); /* After encoding */
+
+ return;
+}
+
+int
+pdf_font_findresource (const char *ident, double scale)
+{
+ int font_id, found = 0;
+
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ pdf_font *font;
+
+ font = &font_cache.fonts[font_id];
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_TYPE1:
+ case PDF_FONT_FONTTYPE_TYPE1C:
+ case PDF_FONT_FONTTYPE_TRUETYPE:
+ case PDF_FONT_FONTTYPE_TYPE0:
+ if (!strcmp(ident, font->ident)) {
+ found = 1;
+ }
+ break;
+ case PDF_FONT_FONTTYPE_TYPE3:
+ /* There shouldn't be any encoding specified for PK font.
+ * It must be always font's build-in encoding.
+ *
+ * TODO: a PK font with two encodings makes no sense. Change?
+ */
+ if (!strcmp(ident, font->ident) && scale == font->point_size) {
+ found = 1;
+ }
+ break;
+ }
+
+ if (found) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Font \"%s\" (enc_id=%d) found at id=%d.\n", font->ident, font->encoding_id, font_id);
+ }
+ break;
+ }
+ }
+
+ return found ? font_id : -1;
+}
+
+static int
+create_font_alias (const char *ident, int font_id)
+{
+ int this_id;
+ pdf_font *font, *src;
+
+ if (font_id < 0 || font_id >= font_cache.count)
+ return -1;
+
+ src = &font_cache.fonts[font_id];
+
+ this_id = font_cache.count;
+ if (font_cache.count >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
+ font = &font_cache.fonts[this_id];
+ pdf_init_font_struct(font);
+
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->font_id = font_id;
+ font->subtype = src->subtype;
+ font->encoding_id = src->encoding_id;
+
+ font->flags |= PDF_FONT_FLAG_IS_ALIAS;
+
+ font_cache.count++;
+
+ return this_id;
+}
+
+static int
+create_font_reencoded (const char *ident, int font_id, int cmap_id)
+{
+ int this_id;
+ pdf_font *font;
+
+ if (font_cache.count + 1 >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
+
+ this_id = font_cache.count;
+ font = &font_cache.fonts[this_id];
+ pdf_init_font_struct(font);
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->font_id = font_id;
+ font->subtype = PDF_FONT_FONTTYPE_TYPE0;
+ font->encoding_id = cmap_id;
+ font->flags |= PDF_FONT_FLAG_IS_REENCODE;
+ font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED;
+ font_cache.count++;
+
+ return this_id;
+}
+
+int
+pdf_font_load_font (const char *ident, double font_scale, const fontmap_rec *mrec)
+{
+ int font_id = -1;
+ pdf_font *font;
+ int encoding_id = -1, cmap_id = -1;
+ const char *fontname;
+
+ /*
+ * Get appropriate info from map file. (PK fonts at two different
+ * point sizes would be looked up twice unecessarily.)
+ */
+ fontname = mrec ? mrec->font_name : ident;
+ /* XeTeX specific...
+ * First try loading GID-to-CID mapping from CFF CID-keyed OpenType font.
+ * There was a serious bug in xdv support... It was implemented with the wrong
+ * assumption that CID always equals to GID.
+ * TODO: There is a possibility that GID-to-CID mapping is not one-to-one.
+ * Use internal glyph ordering rather than map GID to CIDs.
+ */
+ if (mrec && mrec->opt.use_glyph_encoding) {
+ int wmode = 0;
+ /* Should be always Identity-H or Identity-V for XeTeX output. */
+ if (mrec->enc_name) {
+ if (!strcmp(mrec->enc_name, "Identity-V"))
+ wmode = 1;
+ else if (!strcmp(mrec->enc_name, "Identity-H"))
+ wmode = 0;
+ else {
+ WARN("Unexpected encoding specified for xdv: %s", mrec->enc_name);
+ }
+ /* cmap_id < 0 is returned if ...
+ * Font is not a CFF font
+ * GID to CID mapping is identity mapping
+ *
+ * TODO: fontmap record still has Identity CMap assigned but actually different CMap
+ * can be attached to the font here. Should we fix mrec->enc_name here?
+ */
+ cmap_id = otf_try_load_GID_to_CID_map(mrec->font_name, mrec->opt.index, wmode);
+ }
+ }
+
+ if (cmap_id < 0 && mrec && mrec->enc_name) {
+ if (!strcmp(mrec->enc_name, "unicode")) {
+ cmap_id = otf_load_Unicode_CMap(mrec->font_name,
+ mrec->opt.index, mrec->opt.otl_tags,
+ ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
+ if (cmap_id < 0) {
+ cmap_id = t1_load_UnicodeCMap(mrec->font_name, mrec->opt.otl_tags,
+ ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
+ }
+ } else if (!strstr(mrec->enc_name, ".enc") || strstr(mrec->enc_name, ".cmap")) {
+ cmap_id = CMap_cache_find(mrec->enc_name);
+ }
+ if (cmap_id < 0) {
+ encoding_id = pdf_encoding_findresource(mrec->enc_name);
+ }
+ }
+
+ if (mrec && mrec->enc_name) {
+ if (cmap_id < 0 && encoding_id < 0) {
+ WARN("Could not read encoding file: %s", mrec->enc_name);
+ return -1;
+ }
+ }
+
+ if (mrec && cmap_id >= 0) {
+ /* Composite font */
+ CMap *cmap;
+ CIDSysInfo *csi;
+ int wmode, cid_id;
+
+ cmap = CMap_cache_get(cmap_id);
+ csi = CMap_is_Identity(cmap) ? NULL : CMap_get_CIDSysInfo(cmap);
+ wmode = CMap_get_wmode(cmap);
+
+ cid_id = pdf_font_cidfont_lookup_cache(font_cache.fonts, font_cache.count, mrec->font_name, csi, &mrec->opt);
+ if (cid_id >= 0) {
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ font = &font_cache.fonts[font_id];
+ if (font->subtype != PDF_FONT_FONTTYPE_TYPE0)
+ continue;
+ if (font->type0.wmode == wmode && font->type0.descendant == cid_id) {
+ break;
+ }
+ }
+ if (font_id >= 0 && font_id < font_cache.count) {
+ font = &font_cache.fonts[font_id];
+ if (font->encoding_id == cmap_id) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Type0 font \"%s\" cmap_id=<%s,%d> found at font_id=<%s,%d>.\n",
+ mrec->font_name, mrec->enc_name, cmap_id, pdf_get_font_ident(font_id), font_id);
+ }
+ if (!strcmp(ident, font->ident)) {
+ return font_id;
+ } else {
+ return create_font_alias(ident, font_id);
+ }
+ } else {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Type0 font \"%s\" cmap_id=<%s,%d> found at font_id=<%s,%d>. (re-encoded)\n",
+ mrec->font_name, mrec->enc_name, cmap_id, pdf_get_font_ident(font_id), font_id);
+ }
+ return create_font_reencoded(ident, font_id, cmap_id);
+ }
+ }
+ }
+
+ /* plus one for CIDFont */
+ if (font_cache.count + 1 >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
+
+ if (cid_id < 0) {
+ pdf_font *cidfont;
+
+ cid_id = font_cache.count;
+ cidfont = &font_cache.fonts[cid_id];
+ pdf_init_font_struct(cidfont);
+ if (pdf_font_open_cidfont(cidfont, fontname, csi, &mrec->opt) < 0) {
+ pdf_clean_font_struct(cidfont);
+ return -1;
+ }
+ font_cache.count++;
+ }
+ font_id = font_cache.count;
+ font = &font_cache.fonts[font_id];
+ pdf_init_font_struct(font);
+ if (pdf_font_open_type0(font, cid_id, wmode) < 0) {
+ pdf_clean_font_struct(font);
+ return -1;
+ }
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->subtype = PDF_FONT_FONTTYPE_TYPE0;
+ font->encoding_id = cmap_id;
+
+ font_cache.count++;
+
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\n");
+ MESG("pdf_font>> Type0 font \"%s\" ", fontname);
+ MESG("cmap_id=<%s,%d> ", mrec->enc_name, font->encoding_id);
+ MESG("font_id=<%s,%d>.", ident, font_id);
+ MESG("\n");
+ }
+ } else {
+ /* Simple Font - always embed. */
+ for (font_id = 0; font_id < font_cache.count; font_id++) {
+ font = &font_cache.fonts[font_id];
+ if (font->flags & PDF_FONT_FLAG_IS_ALIAS)
+ continue;
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_TYPE1:
+ case PDF_FONT_FONTTYPE_TYPE1C:
+ case PDF_FONT_FONTTYPE_TRUETYPE:
+ /* fontname here is font file name.
+ * We must compare both font file name and encoding
+ *
+ * TODO: Embed a font only once if it is used
+ * with two different encodings
+ */
+ if (!strcmp(fontname, font->filename) && encoding_id == font->encoding_id &&
+ (!mrec || mrec->opt.index == font->index)) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", fontname, encoding_id, font_id);
+ }
+ if (!strcmp(ident, font->ident)) {
+ return font_id;
+ } else {
+ return create_font_alias(ident, font_id);
+ }
+ }
+ break;
+ case PDF_FONT_FONTTYPE_TYPE3:
+ /* There shouldn't be any encoding specified for PK font.
+ * It must be always font's build-in encoding.
+ *
+ * TODO: a PK font with two encodings makes no sense. Change?
+ */
+ if (!strcmp(fontname, font->filename) && font_scale == font->point_size) {
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", fontname, encoding_id, font_id);
+ }
+ if (!strcmp(ident, font->ident)) {
+ return font_id;
+ } else {
+ return create_font_alias(ident, font_id);
+ }
+ }
+ break;
+ }
+ }
+
+ font_id = font_cache.count;
+ if (font_cache.count >= font_cache.capacity) {
+ font_cache.capacity += CACHE_ALLOC_SIZE;
+ font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
+ }
+
+ font = &font_cache.fonts[font_id];
+ pdf_init_font_struct(font);
+
+ font->ident = NEW(strlen(ident) + 1, char);
+ strcpy(font->ident, ident);
+ font->encoding_id = encoding_id;
+ font->filename = NEW(strlen(fontname) + 1, char);
+ font->point_size = font_scale;
+ strcpy(font->filename, fontname);
+ font->index = (mrec && mrec->opt.index) ? mrec->opt.index : 0;
+ font->flags |= (mrec && (mrec->opt.flags & FONTMAP_OPT_NOEMBED)) ? PDF_FONT_FLAG_NOEMBED : 0;
+ if (pdf_font_open_type1(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TYPE1;
+ } else if (pdf_font_open_type1c(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TYPE1C;
+ } else if (pdf_font_open_truetype(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TRUETYPE;
+ } else if (pdf_font_open_pkfont(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1, font->point_size) >= 0) {
+ font->subtype = PDF_FONT_FONTTYPE_TYPE3;
+ } else {
+ pdf_clean_font_struct(font);
+ return -1;
+ }
+
+ font_cache.count++;
+
+ if (dpx_conf.verbose_level > 0) {
+ MESG("\n");
+ MESG("pdf_font>> Simple font \"%s\" ", fontname);
+ MESG("enc_id=<%s,%d> ", (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id);
+ MESG("font_id=<%s,%d>.", ident, font_id);
+ MESG("\n");
+ }
+ }
+
+ return font_id;
+}
+
+pdf_obj *
+pdf_font_get_resource (pdf_font *font)
+{
+ ASSERT(font);
+
+ if (!font->resource) {
+ font->resource = pdf_new_dict();
+ pdf_add_dict(font->resource, pdf_new_name("Type"), pdf_new_name("Font"));
+ switch (font->subtype) {
+ case PDF_FONT_FONTTYPE_TYPE1:
+ case PDF_FONT_FONTTYPE_TYPE1C:
+ pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("Type1"));
+ break;
+ case PDF_FONT_FONTTYPE_TYPE3:
+ pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("Type3"));
+ break;
+ case PDF_FONT_FONTTYPE_TRUETYPE:
+ pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("TrueType"));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return font->resource;
+}
+
+pdf_obj *
+pdf_font_get_descriptor (pdf_font *font)
+{
+ ASSERT(font);
+
+ if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
+ return NULL;
+ } else if (!font->descriptor) {
+ font->descriptor = pdf_new_dict();
+ pdf_add_dict(font->descriptor, pdf_new_name("Type"), pdf_new_name("FontDescriptor"));
+ }
+
+ return font->descriptor;
+}
+
+char *
+pdf_font_get_uniqueTag (pdf_font *font)
+{
+ ASSERT(font);
+
+ if (font->uniqueID[0] == '\0') {
+ pdf_font_make_uniqueTag(font->uniqueID);
+ }
+
+ return font->uniqueID;
+}
+
+/*
+ * Please don’t use TFM widths for the /Widths
+ * entry of the font dictionary.
+ *
+ * PDF 32000-1:2008 (p.255)
+ *
+ * These widths shall be consistent with the
+ * actual widths given in the font program.
+ */
+
+#include "tfm.h"
+
+int
+pdf_check_tfm_widths (const char *ident, double *widths, int firstchar, int lastchar, const char *usedchars)
+{
+ int error = 0;
+ int tfm_id, code, count = 0;
+ double sum = 0.0;
+ double tolerance = 1.0;
+ int override = 0; /* Don't set to 1! */
+
+ tfm_id = tfm_open(ident, 0);
+ if (tfm_id < 0)
+ return 0;
+ for (code = firstchar; code <= lastchar; code++) {
+ if (usedchars[code]) {
+ double width, diff;
+
+ width = 1000. * tfm_get_width(tfm_id, code);
+ diff = widths[code] - width;
+ diff = diff < 0 ? -diff : diff;
+ if (override) {
+ widths[code] = width;
+ } else if (diff > tolerance) {
+ if (dpx_conf.verbose_level > 0) {
+ WARN("Intolerable difference in glyph width: font=%s, char=%d", ident, code);
+ WARN("font: %g vs. tfm: %g", widths[code], width);
+ }
+ sum += diff;
+ }
+ count++;
+ }
+ }
+
+ error = sum > 0.5 * count * tolerance ? -1 : 0;
+
+ return override ? 0 : error;
+}
diff --git a/Build/source/texk/dvipdfm-x/pdffont.h b/Build/source/texk/dvipdfm-x/pdffont.h
new file mode 100644
index 00000000000..7794b860111
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdffont.h
@@ -0,0 +1,165 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFFONT_H_
+#define _PDFFONT_H_
+
+#include "pdfobj.h"
+#include "fontmap.h"
+#include "pdflimits.h"
+
+#define PDF_FONT_FONTTYPE_TYPE1 0
+#define PDF_FONT_FONTTYPE_TYPE1C 1
+#define PDF_FONT_FONTTYPE_TYPE3 2
+#define PDF_FONT_FONTTYPE_TRUETYPE 3
+
+#define PDF_FONT_FONTTYPE_TYPE0 4
+#define PDF_FONT_FONTTYPE_CIDTYPE0 5
+#define PDF_FONT_FONTTYPE_CIDTYPE2 6
+
+extern void pdf_font_set_dpi (int font_dpi);
+
+#define PDF_FONT_FLAG_NOEMBED (1 << 0)
+#define PDF_FONT_FLAG_COMPOSITE (1 << 1)
+#define PDF_FONT_FLAG_BASEFONT (1 << 2)
+#define PDF_FONT_FLAG_USEDCHAR_SHARED (1 << 3)
+#define PDF_FONT_FLAG_IS_ALIAS (1 << 4)
+#define PDF_FONT_FLAG_IS_REENCODE (1 << 5)
+#define PDF_FONT_FLAG_ACCFONT (1 << 6)
+#define PDF_FONT_FLAG_UCSFONT (1 << 7)
+
+/* FIXME */
+/* Converted from Type 1 */
+#define CIDFONT_FLAG_TYPE1 (1 << 8)
+#define CIDFONT_FLAG_TYPE1C (1 << 9)
+#define CIDFONT_FLAG_TRUETYPE (1 << 10)
+
+#define PDF_FONT_PARAM_DESIGN_SIZE 1
+#define PDF_FONT_PARAM_POINT_SIZE 2
+
+#include "fontmap.h"
+#define FONT_STYLE_NONE FONTMAP_STYLE_NONE
+#define FONT_STYLE_BOLD FONTMAP_STYLE_BOLD
+#define FONT_STYLE_ITALIC FONTMAP_STYLE_ITALIC
+#define FONT_STYLE_BOLDITALIC FONTMAP_STYLE_BOLDITALIC
+
+typedef struct {
+ char *registry;
+ char *ordering;
+ int supplement;
+} CIDSysInfo;
+
+typedef struct
+{
+ CIDSysInfo csi;
+ int style;
+ int embed;
+ int stemv;
+} cid_opt;
+
+struct pdf_font
+{
+ char *ident; /* map name */
+ int font_id; /* ID of this font */
+ int subtype;
+
+ char *filename;
+
+ int encoding_id; /* encoding or CMap */
+
+ uint32_t index;
+ char *fontname;
+ char uniqueID[7];
+
+ /*
+ * PDF font resource objects
+ */
+ pdf_obj *reference;
+ pdf_obj *resource;
+ pdf_obj *descriptor;
+
+ /*
+ * Font format specific data
+ */
+ char *usedchars;
+ int flags;
+
+ /* PK font */
+ double point_size;
+ double design_size;
+
+ /* Type0 font */
+ struct {
+ int descendant; /* Only single descendant is allowed. */
+ int wmode;
+ } type0;
+
+ /* CIDFont */
+ struct {
+ CIDSysInfo csi; /* Character collection */
+ cid_opt options; /* Options from map record */
+ int need_vmetrics;
+ char *usedchars_v;
+ } cid;
+};
+
+typedef struct pdf_font pdf_font;
+
+/* pdf_open_document() call them. */
+extern void pdf_init_fonts (void);
+extern void pdf_close_fonts (void);
+
+/* tex_name is used when mrec is NULL.
+ * font_scale (point size) used by PK font.
+ * It might be necessary if dvipdfmx supports font format with
+ * various optical sizes supported in the future.
+ */
+extern int pdf_font_findresource (const char *tex_name, double font_scale);
+extern int pdf_font_load_font (const char *tex_name, double font_scale, const fontmap_rec *mrec);
+
+extern pdf_font *pdf_get_font_data (int font_id);
+
+extern char *pdf_get_font_ident (int font_id);
+extern int pdf_get_font_subtype (int font_id);
+extern pdf_obj *pdf_get_font_reference (int font_id);
+extern pdf_obj *pdf_get_font_resource (int font_id);
+extern char *pdf_get_font_usedchars (int font_id);
+
+extern int pdf_get_font_encoding (int font_id);
+extern int pdf_get_font_wmode (int font_id);
+
+extern int pdf_font_resource_name (int font_id, char *buf);
+
+
+extern char *pdf_font_get_uniqueTag (pdf_font *font);
+
+extern pdf_obj *pdf_font_get_resource (pdf_font *font);
+extern pdf_obj *pdf_font_get_descriptor (pdf_font *font);
+
+extern void pdf_font_make_uniqueTag (char *tag);
+
+#define add_to_used_chars2(b,c) {(b)[(c)/8] |= (1 << (7-((c)%8)));}
+#define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8))))
+
+extern int pdf_check_tfm_widths (const char *ident, double *widths, int firstchar, int lastchar, const char *usedchars);
+
+#endif /* _PDFFONT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdflimits.h b/Build/source/texk/dvipdfm-x/pdflimits.h
new file mode 100644
index 00000000000..087e7df12e4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdflimits.h
@@ -0,0 +1,42 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFLIMITS_H_
+#define _PDFLIMITS_H_
+
+/*
+ * The minimal and maximal PDF version supported by DVIPDFMx.
+ * NOTE: Don't forget to update CIDFont_stdcc_def[] in cid.c
+ * if you increase PDF_VERSION_MAX!
+ */
+#define PDF_VERSION_MIN 13
+#define PDF_VERSION_MAX 20
+#define PDF_VERSION_DEFAULT 15
+
+/*
+ * PDF_NAME_LEN_MAX: see, Appendix C of PDF Ref. v1.3, 2nd. ed.
+ * This is Acrobat implementation limit.
+ */
+#define PDF_NAME_LEN_MAX 127
+#define PDF_NUM_INDIRECT_MAX 8388607ul
+
+#endif /* _PDFLIMITS_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfnames.c b/Build/source/texk/dvipdfm-x/pdfnames.c
new file mode 100644
index 00000000000..103faaf6c63
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfnames.c
@@ -0,0 +1,469 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "numbers.h"
+
+/* Hash */
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+
+#include "pdfnames.h"
+
+#include "dvipdfmx.h"
+
+struct obj_data
+{
+ pdf_obj *reference;
+ pdf_obj *object;
+ int closed; /* 1 if object is closed */
+};
+
+static char *
+printable_key (const char *key, int keylen)
+{
+#define MAX_KEY 32
+ static char pkey[MAX_KEY+4];
+ int i, len;
+ unsigned char hi, lo;
+
+ for (i = 0, len = 0;
+ i < keylen && len < MAX_KEY; i++) {
+ if (isprint((unsigned char)key[i])) {
+ pkey[len++] = key[i];
+ } else {
+ hi = (key[i] >> 4) & 0xff;
+ lo = key[i] & 0xff;
+ pkey[len++] = '#';
+ pkey[len++] = (hi < 10) ? hi + '0' : (hi - 10) + 'A';
+ pkey[len++] = (lo < 10) ? lo + '0' : (lo - 10) + 'A';
+ }
+ }
+ pkey[len] = '\0';
+
+ return (char *) pkey;
+}
+
+static inline void
+hval_free (void *hval)
+{
+ struct obj_data *value;
+
+ value = (struct obj_data *) hval;
+
+ if (value->reference) {
+ pdf_release_obj(value->reference);
+ value->reference = NULL;
+ }
+ if (value->object) {
+ pdf_release_obj(value->object);
+ value->object = NULL;
+ }
+
+ RELEASE(value);
+
+ return;
+}
+
+struct ht_table *
+pdf_new_name_tree (void)
+{
+ struct ht_table *names;
+
+ names = NEW(1, struct ht_table);
+ ht_init_table(names, hval_free);
+
+ return names;
+}
+
+static void
+check_objects_defined (struct ht_table *ht_tab)
+{
+ struct ht_iter iter;
+
+ if (ht_set_iter(ht_tab, &iter) >= 0) {
+ do {
+ char *key;
+ int keylen;
+ struct obj_data *value;
+
+ key = ht_iter_getkey(&iter, &keylen);
+ value = ht_iter_getval(&iter);
+ if (PDF_OBJ_UNDEFINED(value->object)) {
+ pdf_names_add_object(ht_tab, key, keylen, pdf_new_null());
+ WARN("Object @%s used, but not defined. Replaced by null.",
+ printable_key(key, keylen));
+ }
+ } while (ht_iter_next(&iter) >= 0);
+ ht_clear_iter(&iter);
+ }
+}
+
+void
+pdf_delete_name_tree (struct ht_table **names)
+{
+ ASSERT(names && *names);
+
+ check_objects_defined (*names);
+
+ ht_clear_table(*names);
+ RELEASE(*names);
+ *names = NULL;
+}
+
+int
+pdf_names_add_object (struct ht_table *names, const void *key, int keylen, pdf_obj *object)
+{
+ struct obj_data *value;
+
+ ASSERT(names && object);
+
+ if (!key || keylen < 1) {
+ WARN("Null string used for name tree key.");
+ return -1;
+ }
+
+ value = ht_lookup_table(names, key, keylen);
+ if (!value) {
+ value = NEW(1, struct obj_data);
+ value->object = object;
+ value->reference = NULL;
+ value->closed = 0;
+ ht_append_table(names, key, keylen, value);
+ } else {
+ if (value->object && PDF_OBJ_UNDEFINED(value->object)) {
+ pdf_transfer_label(object, value->object);
+ pdf_release_obj(value->object);
+ value->object = object;
+ } else {
+ WARN("Object @%s already defined.", printable_key(key, keylen));
+ pdf_release_obj(object);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+pdf_obj *
+pdf_names_reserve (struct ht_table *names, const void *key, int keylen)
+{
+ pdf_obj *obj_ref = NULL;
+ struct obj_data *value;
+
+ ASSERT(names);
+
+ if (!key || keylen < 1) {
+ WARN("Null string used for name tree key.");
+ return NULL;
+ }
+
+ value = ht_lookup_table(names, key, keylen);
+ if (!value) {
+ value = NEW(1, struct obj_data);
+ value->object = pdf_new_undefined();
+ value->reference = NULL;
+ value->closed = 0;
+ ht_append_table(names, key, keylen, value);
+ obj_ref = pdf_ref_obj(value->object);
+ } else {
+ if (value->object && PDF_OBJ_UNDEFINED(value->object)) {
+ if (!value->reference)
+ value->reference = pdf_ref_obj(value->object);
+ obj_ref = pdf_link_obj(value->reference);
+ } else {
+ WARN("Object @%s already defined.", printable_key(key, keylen));
+ obj_ref = NULL;
+ }
+ }
+
+ return obj_ref;
+}
+
+/*
+ * The following routine returns copies, not the original object.
+ */
+pdf_obj *
+pdf_names_lookup_reference (struct ht_table *names, const void *key, int keylen)
+{
+ struct obj_data *value;
+ pdf_obj *obj_ref;
+
+ ASSERT(names);
+
+ value = ht_lookup_table(names, key, keylen);
+
+ if (value) {
+ if (!value->reference) {
+ if (value->object) {
+ value->reference = pdf_ref_obj(value->object);
+ } else {
+ WARN("Can't create object ref for already released object: %s", printable_key(key, keylen));
+ }
+ }
+ obj_ref = pdf_link_obj(value->reference);
+ } else {
+ /* A null object as dummy would create problems because as value
+ * of a dictionary entry, a null object is be equivalent to no entry
+ * at all. This matters for optimization of PDF destinations.
+ */
+ obj_ref = pdf_names_reserve(names, key, keylen);
+ }
+
+ return obj_ref;
+}
+
+pdf_obj *
+pdf_names_lookup_object (struct ht_table *names, const void *key, int keylen)
+{
+ struct obj_data *value;
+
+ ASSERT(names);
+
+ value = ht_lookup_table(names, key, keylen);
+ if (!value || PDF_OBJ_UNDEFINED(value->object))
+ return NULL;
+ if (value->closed)
+ WARN("Object \"%s\" already closed.", printable_key(key, keylen));
+
+ return value->object;
+}
+
+int
+pdf_names_close_object (struct ht_table *names, const void *key, int keylen)
+{
+ struct obj_data *value;
+
+ ASSERT(names);
+
+ value = ht_lookup_table(names, key, keylen);
+ if (!value ||PDF_OBJ_UNDEFINED(value->object) ) {
+ WARN("Cannot close undefined object @%s.", printable_key(key, keylen));
+ return -1;
+ }
+ ASSERT(value->object);
+
+ if (value->closed) {
+ WARN("Object @%s already closed.", printable_key(key, keylen));
+ return -1;
+ }
+
+ if (value->reference) {
+ pdf_release_obj(value->object);
+ value->object = NULL;
+ }
+ value->closed = 1;
+
+ return 0;
+}
+
+struct named_object
+{
+ char *key;
+ int keylen;
+ pdf_obj *value;
+};
+
+static inline int
+cmp_key (const void *d1, const void *d2)
+{
+ const struct named_object *sd1, *sd2;
+ int keylen, cmp;
+
+ sd1 = (const struct named_object *) d1;
+ sd2 = (const struct named_object *) d2;
+
+ if (!sd1->key)
+ cmp = -1;
+ else if (!sd2->key)
+ cmp = 1;
+ else {
+ keylen = MIN(sd1->keylen, sd2->keylen);
+ cmp = memcmp(sd1->key, sd2->key, keylen);
+ if (!cmp) {
+ cmp = sd1->keylen - sd2->keylen;
+ }
+ }
+
+ return cmp;
+}
+
+#define NAME_CLUSTER 4
+static pdf_obj *
+build_name_tree (struct named_object *first, int num_leaves, int is_root)
+{
+ pdf_obj *result;
+ int i;
+
+ result = pdf_new_dict();
+ /*
+ * According to PDF Refrence, Third Edition (p.101-102), a name tree
+ * always has exactly one root node, which contains a SINGLE entry:
+ * either Kids or Names but not both. If the root node has a Names
+ * entry, it is the only node in the tree. If it has a Kids entry,
+ * then each of the remaining nodes is either an intermediate node,
+ * containing a Limits entry and a Kids entry, or a leaf node,
+ * containing a Limits entry and a Names entry.
+ */
+ if (!is_root) {
+ struct named_object *last;
+ pdf_obj *limits;
+
+ limits = pdf_new_array();
+ last = &first[num_leaves - 1];
+ pdf_add_array(limits, pdf_new_string(first->key, first->keylen));
+ pdf_add_array(limits, pdf_new_string(last->key , last->keylen ));
+ pdf_add_dict (result, pdf_new_name("Limits"), limits);
+ }
+
+ if (num_leaves > 0 &&
+ num_leaves <= 2 * NAME_CLUSTER) {
+ pdf_obj *names;
+
+ /* Create leaf nodes. */
+ names = pdf_new_array();
+ for (i = 0; i < num_leaves; i++) {
+ struct named_object *cur;
+
+ cur = &first[i];
+ pdf_add_array(names, pdf_new_string(cur->key, cur->keylen));
+ switch (PDF_OBJ_TYPEOF(cur->value)) {
+ case PDF_ARRAY:
+ case PDF_DICT:
+ case PDF_STREAM:
+ case PDF_STRING:
+ pdf_add_array(names, pdf_ref_obj(cur->value));
+ break;
+ case PDF_OBJ_INVALID:
+ ERROR("Invalid object...: %s", printable_key(cur->key, cur->keylen));
+ default:
+ pdf_add_array(names, pdf_link_obj(cur->value));
+ break;
+ }
+ pdf_release_obj(cur->value);
+ cur->value = NULL;
+ }
+ pdf_add_dict(result, pdf_new_name("Names"), names);
+ } else if (num_leaves > 0) {
+ pdf_obj *kids;
+
+ /* Intermediate node */
+ kids = pdf_new_array();
+ for (i = 0; i < NAME_CLUSTER; i++) {
+ pdf_obj *subtree;
+ int start, end;
+
+ start = (i*num_leaves) / NAME_CLUSTER;
+ end = ((i+1)*num_leaves) / NAME_CLUSTER;
+ subtree = build_name_tree(&first[start], (end - start), 0);
+ pdf_add_array (kids, pdf_ref_obj(subtree));
+ pdf_release_obj(subtree);
+ }
+ pdf_add_dict(result, pdf_new_name("Kids"), kids);
+ }
+
+ return result;
+}
+
+static struct named_object *
+flat_table (struct ht_table *ht_tab, int *num_entries,
+ struct ht_table *filter)
+{
+ struct named_object *objects;
+ struct ht_iter iter;
+ int count;
+
+ ASSERT(ht_tab);
+
+ objects = NEW(ht_tab->count, struct named_object);
+ count = 0;
+ if (ht_set_iter(ht_tab, &iter) >= 0) {
+ do {
+ char *key;
+ int keylen;
+ struct obj_data *value;
+
+ key = ht_iter_getkey(&iter, &keylen);
+
+ if (filter) {
+ pdf_obj *new_obj = ht_lookup_table(filter, key, keylen);
+
+ if (!new_obj)
+ continue;
+
+ key = pdf_string_value(new_obj);
+ keylen = pdf_string_length(new_obj);
+ }
+
+ value = ht_iter_getval(&iter);
+ ASSERT(value->object);
+ if (PDF_OBJ_UNDEFINED(value->object)) {
+ WARN("Object @%s\" not defined. Replaced by null.",
+ printable_key(key, keylen));
+ objects[count].key = (char *) key;
+ objects[count].keylen = keylen;
+ objects[count].value = pdf_new_null();
+ } else if (value->object) {
+ objects[count].key = (char *) key;
+ objects[count].keylen = keylen;
+ objects[count].value = pdf_link_obj(value->object);
+ }
+ count++;
+ } while (ht_iter_next(&iter) >= 0);
+ ht_clear_iter(&iter);
+ }
+
+ *num_entries = count;
+ objects = RENEW(objects, count, struct named_object);
+
+ return objects;
+}
+
+pdf_obj *
+pdf_names_create_tree (struct ht_table *names, int *count,
+ struct ht_table *filter)
+{
+ pdf_obj *name_tree;
+ struct named_object *flat;
+
+ flat = flat_table(names, count, filter);
+ if (!flat)
+ name_tree = NULL;
+ else {
+ qsort(flat, *count, sizeof(struct named_object), cmp_key);
+ name_tree = build_name_tree(flat, *count, 1);
+ RELEASE(flat);
+ }
+
+ return name_tree;
+}
diff --git a/Build/source/texk/dvipdfm-x/pdfnames.h b/Build/source/texk/dvipdfm-x/pdfnames.h
new file mode 100644
index 00000000000..5b4e3599864
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfnames.h
@@ -0,0 +1,49 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDF_NAMES_H_
+#define _PDF_NAMES_H_
+
+/* Hash */
+#include "dpxutil.h"
+#include "pdfobj.h"
+
+/* Not actually tree... */
+extern struct ht_table *pdf_new_name_tree (void);
+extern void pdf_delete_name_tree (struct ht_table **names);
+
+extern int pdf_names_add_object (struct ht_table *names,
+ const void *key, int keylen, pdf_obj *object);
+extern pdf_obj *pdf_names_lookup_reference (struct ht_table *names,
+ const void *key, int keylen);
+extern pdf_obj *pdf_names_lookup_object (struct ht_table *names,
+ const void *key, int keylen);
+extern int pdf_names_close_object (struct ht_table *names,
+ const void *key, int keylen);
+extern pdf_obj *pdf_names_reserve (struct ht_table *names,
+ const void *key, int keylen);
+/* Really create name tree... */
+extern pdf_obj *pdf_names_create_tree (struct ht_table *names,
+ int *count,
+ struct ht_table *filter);
+
+#endif /* _PDF_NAMES_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfobj.c b/Build/source/texk/dvipdfm-x/pdfobj.c
new file mode 100644
index 00000000000..804466378bc
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfobj.c
@@ -0,0 +1,4624 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+/* floor and abs */
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "pdflimits.h"
+#include "pdfencrypt.h"
+#include "pdfparse.h"
+
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif /* HAVE_ZLIB */
+
+#include "pdfobj.h"
+#include "pdfdev.h"
+
+#define STREAM_ALLOC_SIZE 4096u
+#define ARRAY_ALLOC_SIZE 256
+#define IND_OBJECTS_ALLOC_SIZE 512
+
+#define OBJ_NO_OBJSTM (1 << 0)
+/* Objects with this flag will not be put into an object stream.
+ For instance, all stream objects have this flag set. */
+#define OBJ_NO_ENCRYPT (1 << 1)
+/* Objects with this flag will not be encrypted.
+ This implies OBJ_NO_OBJSTM if encryption is turned on. */
+
+/* Any of these types can be represented as follows */
+struct pdf_obj
+{
+ int type;
+
+ uint32_t label; /* Only used for indirect objects all other "label" to zero */
+ uint16_t generation; /* Only used if "label" is used */
+ int refcount; /* Number of links to this object */
+ int32_t flags;
+ void *data;
+
+#if defined(PDFOBJ_DEBUG)
+ int obj_id;
+#endif
+};
+
+#if defined(PDFOBJ_DEBUG)
+static pdf_obj *bucket[65535];
+static int cur_obj_id = 0;
+#endif
+
+struct pdf_boolean
+{
+ char value;
+};
+
+struct pdf_number
+{
+ double value;
+};
+
+struct pdf_string
+{
+ unsigned char *string;
+ size_t length;
+};
+
+struct pdf_name
+{
+ char *name;
+};
+
+struct pdf_array
+{
+ size_t max;
+ size_t size;
+ struct pdf_obj **values;
+};
+
+struct pdf_dict
+{
+ struct pdf_obj *key;
+ struct pdf_obj *value;
+ struct pdf_dict *next;
+};
+
+/* DecodeParms for FlateDecode */
+ struct decode_parms {
+ int predictor;
+ int colors;
+ int bits_per_component;
+ int32_t columns;
+ };
+
+/* 2015/12/27 Added support for predictor functions
+ *
+ * There are yet no way to specify the use of predictor functions.
+ * Using TIFF2 or PNG predictor usually gives better compression for images
+ * but there is a case that compression speed becomes significantly slower.
+ * Please use -C 0x20 option to disable the use of predictor functions.
+ *
+ * See, e.g., for a heuristic approach for selecting filters
+ * http://www.w3.org/TR/PNG-Encoders.html#E.Filter-selection
+ */
+
+struct pdf_stream
+{
+ struct pdf_obj *dict;
+ unsigned char *stream;
+ int *objstm_data; /* used for object streams */
+ size_t stream_length;
+ size_t max_length;
+ int32_t _flags;
+ struct decode_parms decodeparms;
+};
+
+struct pdf_indirect
+{
+ pdf_file *pf;
+ pdf_obj *obj; /* used when PF == NULL */
+ uint32_t label;
+ uint16_t generation;
+};
+
+typedef void pdf_null;
+typedef struct pdf_boolean pdf_boolean;
+typedef struct pdf_number pdf_number;
+typedef struct pdf_string pdf_string;
+typedef struct pdf_name pdf_name;
+typedef struct pdf_array pdf_array;
+typedef struct pdf_dict pdf_dict;
+typedef struct pdf_stream pdf_stream;
+typedef struct pdf_indirect pdf_indirect;
+
+typedef struct xref_entry
+{
+ uint8_t type; /* object storage type */
+ uint32_t field2; /* offset in file or object stream */
+ uint16_t field3; /* generation or index */
+ pdf_obj *direct; /* used for imported objects */
+ pdf_obj *indirect; /* used for imported objects */
+} xref_entry;
+
+struct pdf_file
+{
+ FILE *file;
+ pdf_obj *trailer;
+ xref_entry *xref_table;
+ pdf_obj *catalog;
+ int num_obj;
+ int file_size;
+ int version;
+};
+
+static int error_out = 0;
+
+#define OBJSTM_MAX_OBJS 200
+/* the limit is only 100 for linearized PDF */
+
+struct pdf_out {
+ struct {
+ int enc_mode; /* boolean */
+ } state;
+
+ unsigned char id1[16];
+ unsigned char id2[16];
+
+ struct {
+ int major;
+ int minor;
+ } version;
+
+ struct {
+ struct {
+ int level;
+ int use_predictor;
+ } compression;
+
+ int enable_encrypt;
+ int use_objstm;
+ } options;
+
+ struct {
+ FILE *file;
+ size_t file_position;
+ int line_position;
+ size_t compression_saved;
+ } output;
+
+ struct {
+ uint32_t next_label;
+ uint32_t max_ind_objects;
+ } obj;
+
+ pdf_sec *sec_data;
+
+ pdf_obj *trailer;
+ uint32_t startxref;
+ xref_entry * xref_table;
+
+ pdf_obj *xref_stream;
+ pdf_obj *output_stream;
+ pdf_obj *current_objstm;
+ /* The following flag bits are (8,338,607+1)/8 bytes data
+ * each bit represenging if the object is freed.
+ * Where the value 8,338,607 is taken from PDF ref. manual, v.1.7,
+ * Appendix C, "Implementation Limits".
+ */
+ char *free_list;
+};
+
+#if defined(LIBDPX)
+size_t output_file_size;
+#endif /* LIBDPX */
+
+/* Underway to reform PDF related code... For a moment place pdf_out
+ * object as a static variable. */
+static pdf_out pout;
+
+static pdf_out *
+current_output (void)
+{
+ return &pout;
+}
+
+static void
+init_pdf_out_struct (pdf_out *p)
+{
+ ASSERT(p);
+
+ p->state.enc_mode = 0;
+
+ memset(p->id1, 0, 16);
+ memset(p->id2, 0, 16);
+
+ p->version.major = 1;
+ p->version.minor = PDF_VERSION_DEFAULT;
+
+ p->options.compression.level = 9;
+ p->options.compression.use_predictor = 1;
+ p->options.enable_encrypt = 0;
+ p->options.use_objstm = 1;
+
+ p->output.file = NULL;
+ p->output.file_position = 0;
+ p->output.line_position = 0;
+ p->output.compression_saved = 0;
+#if defined(LIBDPX)
+ output_file_size = 0;
+#endif /* LIBDPX */
+
+ p->obj.next_label = 1;
+ p->obj.max_ind_objects = 0;
+
+ p->sec_data = NULL;
+ p->trailer = NULL;
+ p->startxref = 0;
+ p->xref_table = NULL;
+
+ p->xref_stream = NULL;
+ p->output_stream = NULL;
+ p->current_objstm = NULL;
+
+ p->free_list = NEW((PDF_NUM_INDIRECT_MAX+1)/8, char);
+ memset(p->free_list, 0, (PDF_NUM_INDIRECT_MAX+1)/8);
+}
+
+static void
+clean_pdf_out_struct (pdf_out *p)
+{
+ if (p->free_list)
+ RELEASE(p->free_list);
+ memset(p, 0, sizeof(pdf_out));
+}
+
+/* Internal static routines */
+
+static int check_for_pdf_version (FILE *file);
+
+static void pdf_flush_obj (pdf_out *p, pdf_obj *object);
+static void pdf_label_obj (pdf_out *p, pdf_obj *object);
+static void pdf_write_obj (pdf_out *p, pdf_obj *object);
+
+static void set_objstm_data (pdf_obj *objstm, int *data);
+static int *get_objstm_data (pdf_obj *objstm);
+static void release_objstm (pdf_obj *objstm);
+
+static void pdf_out_char (pdf_out *p, char c);
+static void pdf_out_str (pdf_out *p, const void *buffer, size_t length);
+
+static pdf_obj *pdf_new_ref (pdf_out *p, pdf_obj *object);
+static void release_indirect (pdf_indirect *data);
+static void write_indirect (pdf_out *p, pdf_indirect *indirect);
+
+static void release_boolean (pdf_obj *data);
+static void write_boolean (pdf_out *p, pdf_boolean *data);
+
+static void write_null (pdf_out *p);
+
+static void release_number (pdf_number *number);
+static void write_number (pdf_out *p, pdf_number *number);
+
+static void write_string (pdf_out *p, pdf_string *str);
+static void release_string (pdf_string *str);
+
+static void write_name (pdf_out *p, pdf_name *name);
+static void release_name (pdf_name *name);
+
+static void write_array (pdf_out *p, pdf_array *array);
+static void release_array (pdf_array *array);
+
+static void write_dict (pdf_out *p, pdf_dict *dict);
+static void release_dict (pdf_dict *dict);
+
+static void write_stream (pdf_out *p, pdf_stream *stream);
+static void release_stream (pdf_stream *stream);
+
+static void
+pdf_out_set_compression (pdf_out *p, int level)
+{
+ ASSERT(p);
+
+#ifndef HAVE_ZLIB
+ ERROR("You don't have compression compiled in. Possibly libz wasn't found by configure.");
+#else
+#ifndef HAVE_ZLIB_COMPRESS2
+ if (level != 0)
+ WARN("Unable to set compression level -- your zlib doesn't have compress2().");
+#endif
+ if (level >= 0 && level <= 9)
+ p->options.compression.level = level;
+ else {
+ ERROR("set_compression: invalid compression level: %d", level);
+ }
+#endif /* !HAVE_ZLIB */
+
+ return;
+}
+
+FILE *
+pdf_get_output_file (void)
+{
+ pdf_out *p = current_output();
+ return p->output.file;
+}
+
+static void
+pdf_out_set_version (pdf_out *p, int ver_major, int ver_minor)
+{
+ int version;
+
+ ASSERT(p);
+
+ version = ver_major * 10 + ver_minor;
+ /* Don't forget to update CIDFont_stdcc_def[] in cid.c too! */
+ if (version >= PDF_VERSION_MIN && version <= PDF_VERSION_MAX) {
+ p->version.major = ver_major;
+ p->version.minor = ver_minor;
+ } else {
+ WARN("Unsupported PDF version %d.%d ... Ignoring.", ver_major, ver_minor);
+ }
+}
+
+int
+pdf_get_version (void)
+{
+ pdf_out *p = current_output();
+ return (p->version.major * 10 + p->version.minor);
+}
+
+int
+pdf_get_version_major (void)
+{
+ pdf_out *p = current_output();
+ return p->version.major;
+}
+
+int
+pdf_get_version_minor (void)
+{
+ pdf_out *p = current_output();
+ return p->version.minor;
+}
+
+int
+pdf_check_version (int major, int minor)
+{
+ pdf_out *p = current_output();
+ if (p->version.major > major)
+ return 0;
+ else if (p->version.major < major)
+ return -1;
+ else {
+ return (p->version.minor >= minor) ? 0 : -1;
+ }
+
+ return -1;
+}
+
+static void
+add_xref_entry (pdf_out *p,
+ uint32_t label, uint8_t type, uint32_t field2, uint16_t field3)
+{
+ ASSERT(p);
+
+ if (label >= p->obj.max_ind_objects) {
+ p->obj.max_ind_objects = (label/IND_OBJECTS_ALLOC_SIZE+1)*IND_OBJECTS_ALLOC_SIZE;
+ p->xref_table = RENEW(p->xref_table, p->obj.max_ind_objects, xref_entry);
+ }
+
+ p->xref_table[label].type = type;
+ p->xref_table[label].field2 = field2;
+ p->xref_table[label].field3 = field3;
+ p->xref_table[label].direct = NULL;
+ p->xref_table[label].indirect = NULL;
+}
+
+#define BINARY_MARKER "%\344\360\355\370\n"
+pdf_out *
+pdf_out_init (const char *filename,
+ const unsigned char *id1,
+ const unsigned char *id2,
+ int ver_major, int ver_minor, int compression_level,
+ int enable_encrypt,
+ int enable_objstm,
+ int enable_predictor)
+{
+ pdf_out *p = current_output();
+ char v;
+
+ init_pdf_out_struct(p);
+
+ pdf_out_set_version(p, ver_major, ver_minor);
+ pdf_out_set_compression(p, compression_level);
+
+ add_xref_entry(p, 0, 0, 0, 0xffff);
+
+ /* This must be set before pdf_set_root() is called */
+ p->options.enable_encrypt = enable_encrypt;
+ if (pdf_check_version(1, 5) == 0) {
+ if (enable_objstm) {
+ p->xref_stream = pdf_new_stream(STREAM_COMPRESS);
+ p->xref_stream->flags |= OBJ_NO_ENCRYPT;
+ p->trailer = pdf_stream_dict(p->xref_stream);
+ pdf_add_dict(p->trailer, pdf_new_name("Type"), pdf_new_name("XRef"));
+ p->options.use_objstm = 1;
+ } else {
+ p->xref_stream = NULL;
+ p->trailer = pdf_new_dict();
+ p->options.use_objstm = 0;
+ }
+ } else {
+ p->xref_stream = NULL;
+ p->trailer = pdf_new_dict();
+ p->options.use_objstm = 0;
+ }
+
+ p->output_stream = NULL;
+
+ if (filename == NULL) { /* no filename: writing to stdout */
+#ifdef WIN32
+ setmode(fileno(stdout), _O_BINARY);
+#endif
+ p->output.file = stdout;
+ } else {
+ p->output.file = MFOPEN(filename, FOPEN_WBIN_MODE);
+ if (!p->output.file) {
+ if (strlen(filename) < 128)
+ ERROR("Unable to open \"%s\".", filename);
+ else
+ ERROR("Unable to open file.");
+ }
+ }
+ pdf_out_str(p, "%PDF-", strlen("%PDF-"));
+ v = '0' + p->version.major;
+ pdf_out_str(p, &v, 1);
+ pdf_out_str(p, ".", 1);
+ v = '0' + p->version.minor;
+ pdf_out_str(p, &v, 1);
+ pdf_out_str(p, "\n", 1);
+ pdf_out_str(p, BINARY_MARKER, strlen(BINARY_MARKER));
+
+ /* Set trailer ID and setup security handler */
+ {
+ pdf_obj *id_array;
+
+ memcpy(p->id1, id1, 16);
+ memcpy(p->id2, id2, 16);
+ id_array = pdf_new_array();
+ pdf_add_array(id_array, pdf_new_string(p->id1, 16));
+ pdf_add_array(id_array, pdf_new_string(p->id2, 16));
+ pdf_add_dict(p->trailer, pdf_new_name("ID"), id_array);
+ }
+ p->state.enc_mode = 0;
+ p->options.compression.use_predictor = enable_predictor;
+
+ return p;
+}
+
+void
+pdf_out_set_encrypt (int keybits, int32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata)
+{
+ pdf_out *p = current_output();
+
+ pdf_obj *encrypt, *extension, *catalog;
+
+ p->sec_data = pdf_enc_init(p->id1, keybits, permission,
+ opasswd, upasswd, use_aes, encrypt_metadata);
+ if (!p->sec_data) {
+ p->options.enable_encrypt = 0;
+ return;
+ }
+
+ encrypt = pdf_enc_get_encrypt_dict(p->sec_data);
+ pdf_add_dict(p->trailer,
+ pdf_new_name("Encrypt"), pdf_ref_obj(encrypt));
+ encrypt->flags |= OBJ_NO_ENCRYPT;
+ encrypt->flags |= OBJ_NO_OBJSTM;
+ pdf_release_obj(encrypt);
+
+ extension = pdf_enc_get_extension_dict(p->sec_data);
+ if (extension) {
+ catalog = pdf_doc_catalog();
+ pdf_add_dict(catalog, pdf_new_name("Extensions"), extension);
+ }
+}
+
+static void
+dump_xref_table (pdf_out *p)
+{
+ int i, length;
+ char buf[32];
+
+ ASSERT(p);
+
+ pdf_out_str(p, "xref\n", 5);
+
+ length = sprintf(buf, "%d %u\n", 0, p->obj.next_label);
+ pdf_out_str(p, buf, length);
+
+ /*
+ * Every space counts. The space after the 'f' and 'n' is * *essential*.
+ * The PDF spec says the lines must be 20 characters long including the
+ * end of line character.
+ */
+ for (i = 0; i < p->obj.next_label; i++) {
+ uint8_t type = p->xref_table[i].type;
+ if (type > 1)
+ ERROR("object type %hu not allowed in xref table", type);
+ length = sprintf(buf, "%010u %05hu %c \n",
+ p->xref_table[i].field2, p->xref_table[i].field3,
+ type ? 'n' : 'f');
+ pdf_out_str(p, buf, length);
+ }
+}
+
+static void
+dump_trailer (pdf_out *p)
+{
+ ASSERT(p);
+
+ pdf_out_str(p, "trailer\n", 8);
+ p->state.enc_mode = 0;
+ write_dict(p, p->trailer->data);
+ pdf_release_obj(p->trailer);
+ p->trailer = NULL;
+ pdf_out_char(p, '\n');
+}
+
+/*
+ * output a PDF 1.5 cross-reference stream;
+ * contributed by Matthias Franz (March 21, 2007)
+ */
+static void
+dump_xref_stream (pdf_out *p)
+{
+ uint32_t pos, i;
+ uint32_t poslen;
+ unsigned char buf[7] = {0, 0, 0, 0, 0};
+ pdf_obj *w;
+
+ ASSERT(p);
+
+ /* determine the necessary size of the offset field */
+ pos = p->startxref; /* maximal offset value */
+ poslen = 1;
+ while (pos >>= 8)
+ poslen++;
+
+ w = pdf_new_array();
+ pdf_add_array(w, pdf_new_number(1)); /* type */
+ pdf_add_array(w, pdf_new_number(poslen)); /* offset (big-endian) */
+ pdf_add_array(w, pdf_new_number(2)); /* generation */
+ pdf_add_dict(p->trailer, pdf_new_name("W"), w);
+
+ /* We need the xref entry for the xref stream right now */
+ add_xref_entry(p, p->obj.next_label - 1, 1, p->startxref, 0);
+
+ for (i = 0; i < p->obj.next_label; i++) {
+ size_t j;
+ uint16_t f3;
+ buf[0] = p->xref_table[i].type;
+ pos = p->xref_table[i].field2;
+ for (j = poslen; j--; ) {
+ buf[1+j] = (unsigned char) pos;
+ pos >>= 8;
+ }
+ f3 = p->xref_table[i].field3;
+ buf[poslen+1] = (unsigned char) (f3 >> 8);
+ buf[poslen+2] = (unsigned char) (f3);
+ pdf_add_stream(p->xref_stream, &buf, poslen+3);
+ }
+
+ pdf_release_obj(p->xref_stream);
+ p->xref_stream = NULL;
+}
+
+#if defined(LIBDPX)
+long
+pdf_output_stats (void)
+{
+ return (long) output_file_size;
+}
+#endif /* LIBDPX */
+
+void
+pdf_out_flush (void)
+{
+ pdf_out *p = current_output();
+ char buf[16];
+
+ if (p->output.file) {
+ int length;
+
+ /* Flush current object stream */
+ if (p->current_objstm) {
+ release_objstm(p->current_objstm);
+ p->current_objstm =NULL;
+ }
+
+ /*
+ * Label xref stream - we need the number of correct objects
+ * for the xref stream dictionary (= trailer).
+ * Labelling it in pdf_out_init (with 1) does not work (why?).
+ */
+ if (p->xref_stream)
+ pdf_label_obj(p, p->xref_stream);
+
+ /* Record where this xref is for trailer */
+ p->startxref = p->output.file_position;
+
+ pdf_add_dict(p->trailer,
+ pdf_new_name("Size"), pdf_new_number(p->obj.next_label));
+
+ if (p->xref_stream)
+ dump_xref_stream(p);
+ else {
+ dump_xref_table(p);
+ dump_trailer(p);
+ }
+
+ /* Done with xref table */
+ RELEASE(p->xref_table);
+ p->xref_table = NULL;
+
+ pdf_out_str(p, "startxref\n", 10);
+ length = sprintf(buf, "%u\n", p->startxref);
+ pdf_out_str(p, buf, length);
+ pdf_out_str(p, "%%EOF\n", 6);
+
+#if !defined(LIBDPX)
+ MESG("\n");
+#endif /* !LIBDPX */
+ if (dpx_conf.verbose_level > 0) {
+ if (p->options.compression.level > 0) {
+ MESG("Compression saved %ld bytes\n", p->output.compression_saved);
+ }
+ }
+#if !defined(LIBDPX)
+ MESG("%ld bytes written", p->output.file_position);
+#else
+ output_file_size = p->output.file_position;
+#endif /* !LIBDPX */
+
+ MFCLOSE(p->output.file);
+ p->output.file = NULL;
+ p->output.file_position = 0;
+ p->output.line_position = 0;
+ }
+ if (p->sec_data)
+ pdf_enc_close(&p->sec_data);
+#if defined(PDFOBJ_DEBUG)
+ {
+ int i;
+ error_out = 1;
+ MESG("\ndebug>> %d PDF objects created.", cur_obj_id);
+ for (i = 0; i < cur_obj_id; i++) {
+ pdf_obj *obj = bucket[i];
+ if (obj) {
+ if (obj->label > 0) {
+ WARN("Object obj_id=<%lu, %u> unreleased...", obj->label, obj->generation);
+ WARN("Reference count=%d", obj->refcount);
+ pdf_write_obj(p, obj);
+ MESG("\n");
+ } else {
+ WARN("Unreleased object found: (unlabeled) id=%d", i);
+ pdf_write_obj(p, obj);
+ MESG("\n");
+ }
+ }
+ }
+ }
+#endif
+ clean_pdf_out_struct(p);
+}
+
+void
+pdf_error_cleanup (void)
+{
+ pdf_out *p = current_output();
+ /*
+ * This routine is the cleanup required for an abnormal exit.
+ * For now, simply close the file.
+ */
+ if (p->output.file)
+ MFCLOSE(p->output.file);
+ p->output.file = NULL;
+}
+
+
+void
+pdf_set_root (pdf_obj *object)
+{
+ pdf_out *p = current_output();
+
+ if (pdf_lookup_dict(p->trailer, "Root"))
+ ERROR("Root object already set!");
+ pdf_add_dict(p->trailer, pdf_new_name("Root"), pdf_ref_obj(object));
+ /* Adobe Readers don't like a document catalog inside an encrypted
+ * object stream, although the PDF v1.5 spec seems to allow this.
+ * Note that we don't set OBJ_NO_ENCRYPT since the name dictionary in
+ * a document catalog may contain strings, which should be encrypted.
+ */
+ if (p->options.enable_encrypt)
+ object->flags |= OBJ_NO_OBJSTM;
+}
+
+void
+pdf_set_info (pdf_obj *object)
+{
+ pdf_out *p = current_output();
+
+ if (pdf_lookup_dict(p->trailer, "Info"))
+ ERROR ("Info object already set!");
+ pdf_add_dict(p->trailer, pdf_new_name("Info"), pdf_ref_obj(object));
+}
+
+
+
+static void
+pdf_out_char (pdf_out *p, char c)
+{
+ ASSERT(p);
+
+ if (error_out) {
+ fputc(c, stderr);
+ } else {
+ if (p->output_stream)
+ pdf_add_stream(p->output_stream, &c, 1);
+ else {
+ fputc(c, p->output.file);
+ p->output.file_position += 1;
+ if (c == '\n')
+ p->output.line_position = 0;
+ else
+ p->output.line_position += 1;
+ }
+ }
+}
+
+static char xchar[] = "0123456789abcdef";
+
+static void
+pdf_out_xchar (pdf_out *p, char c)
+{
+ ASSERT(p);
+
+ pdf_out_char(p, xchar[(c >> 4) & 0x0f]);
+ pdf_out_char(p, xchar[c & 0x0f]);
+}
+
+static void
+pdf_out_str (pdf_out *p, const void *buffer, size_t length)
+{
+ ASSERT(p);
+
+ if (error_out)
+ fwrite(buffer, 1, length, stderr);
+ else {
+ if (p->output_stream)
+ pdf_add_stream(p->output_stream, buffer, length);
+ else {
+ fwrite(buffer, 1, length, p->output.file);
+ p->output.file_position += length;
+ p->output.line_position += length;
+ /* "foo\nbar\n "... */
+ if (length > 0 &&
+ ((const char *)buffer)[length-1] == '\n')
+ p->output.line_position = 0;
+ }
+ }
+}
+
+/* returns 1 if a white-space character is necessary to separate
+ an object of type1 followed by an object of type2 */
+static
+int pdf_need_white (int type1, int type2)
+{
+ return !(type1 == PDF_STRING || type1 == PDF_ARRAY || type1 == PDF_DICT ||
+ type2 == PDF_STRING || type2 == PDF_NAME ||
+ type2 == PDF_ARRAY || type2 == PDF_DICT);
+}
+
+static
+void pdf_out_white (pdf_out *p)
+{
+ ASSERT(p);
+
+ if (p->output.line_position >= 80) {
+ pdf_out_char(p, '\n');
+ } else {
+ pdf_out_char(p, ' ');
+ }
+}
+
+#define TYPECHECK(o,t) if (!(o) || (o)->type != (t)) {\
+ ERROR("typecheck: Invalid object type: %d %d (line %d)", (o) ? (o)->type : -1, (t), __LINE__);\
+}
+
+#define INVALIDOBJ(o) ((o) == NULL || (o)->type <= 0 || (o)->type > PDF_UNDEFINED)
+
+static pdf_obj *
+pdf_new_obj(int type)
+{
+ pdf_obj *result;
+
+ if (type > PDF_UNDEFINED || type < 0)
+ ERROR("Invalid object type: %d", type);
+
+ result = NEW(1, pdf_obj);
+ result->type = type;
+ result->data = NULL;
+ result->label = 0;
+ result->generation = 0;
+ result->refcount = 1;
+ result->flags = 0;
+
+#if defined(PDFOBJ_DEBUG)
+ result->obj_id = cur_obj_id;
+ bucket[cur_obj_id] = result;
+ cur_obj_id++;
+#endif
+
+ return result;
+}
+
+int
+pdf_obj_typeof (pdf_obj *object)
+{
+ if (INVALIDOBJ(object))
+ return PDF_OBJ_INVALID;
+
+ return object->type;
+}
+
+static void
+pdf_label_obj (pdf_out *p, pdf_obj *object)
+{
+ ASSERT(p);
+
+ if (INVALIDOBJ(object))
+ ERROR("pdf_label_obj(): passed invalid object.");
+
+ /*
+ * Don't change label on an already labeled object. Ignore such calls.
+ */
+ if (object->label == 0) {
+ if (p->obj.next_label == PDF_NUM_INDIRECT_MAX) {
+ ERROR("Number of indirect object has reached its maximum value!");
+ }
+ object->label = p->obj.next_label++;
+ object->generation = 0;
+ }
+}
+
+/*
+ * Transfer the label assigned to the object src to the object dst.
+ * The object dst must not yet have been labeled.
+ */
+void
+pdf_transfer_label (pdf_obj *dst, pdf_obj *src)
+{
+ ASSERT(dst && !dst->label && src);
+
+ dst->label = src->label;
+ dst->generation = src->generation;
+ src->label = 0;
+ src->generation = 0;
+}
+
+/*
+ * This doesn't really copy the object, but allows it to be used without
+ * fear that somebody else will free it.
+ */
+pdf_obj *
+pdf_link_obj (pdf_obj *object)
+{
+ if (INVALIDOBJ(object))
+ ERROR("pdf_link_obj(): passed invalid object.");
+
+ object->refcount += 1;
+
+ return object;
+}
+
+
+pdf_obj *
+pdf_ref_obj (pdf_obj *object)
+{
+ pdf_out *p = current_output();
+
+ if (INVALIDOBJ(object))
+ ERROR("pdf_ref_obj(): passed invalid object.");
+
+ if (object->refcount == 0) {
+ MESG("\nTrying to refer already released object!!!\n");
+ error_out = 1;
+ pdf_write_obj(p, object);
+ ERROR("Cannot continue...");
+ error_out = 0;
+ }
+
+ if (PDF_OBJ_INDIRECTTYPE(object)) {
+ return pdf_link_obj(object);
+ } else {
+ return pdf_new_ref(p, object);
+ }
+}
+
+static void
+release_indirect (pdf_indirect *data)
+{
+ RELEASE(data);
+}
+
+static void
+write_indirect (pdf_out *p, pdf_indirect *indirect)
+{
+ int length;
+ char buf[64];
+
+ ASSERT(p);
+ ASSERT(!indirect->pf);
+
+ length = sprintf(buf, "%u %hu R",
+ indirect->label, indirect->generation);
+ pdf_out_str(p, buf, length);
+}
+
+/* The undefined object is used as a placeholder in pdfnames.c
+ * for objects which are referenced before they are defined.
+ */
+pdf_obj *
+pdf_new_undefined (void)
+{
+ pdf_obj *result;
+
+ result = pdf_new_obj(PDF_UNDEFINED);
+ result->data = NULL;
+
+ return result;
+}
+
+pdf_obj *
+pdf_new_null (void)
+{
+ pdf_obj *result;
+
+ result = pdf_new_obj(PDF_NULL);
+ result->data = NULL;
+
+ return result;
+}
+
+static void
+write_null (pdf_out *p)
+{
+ pdf_out_str(p, "null", 4);
+}
+
+pdf_obj *
+pdf_new_boolean (char value)
+{
+ pdf_obj *result;
+ pdf_boolean *data;
+
+ result = pdf_new_obj(PDF_BOOLEAN);
+ data = NEW(1, pdf_boolean);
+ data->value = value;
+ result->data = data;
+
+ return result;
+}
+
+static void
+release_boolean (pdf_obj *data)
+{
+ RELEASE (data);
+}
+
+static void
+write_boolean (pdf_out *p, pdf_boolean *data)
+{
+ if (data->value) {
+ pdf_out_str(p, "true", 4);
+ } else {
+ pdf_out_str(p, "false", 5);
+ }
+}
+
+char
+pdf_boolean_value (pdf_obj *object)
+{
+ pdf_boolean *data;
+
+ TYPECHECK(object, PDF_BOOLEAN);
+
+ data = object->data;
+
+ return data->value;
+}
+
+pdf_obj *
+pdf_new_number (double value)
+{
+ pdf_obj *result;
+ pdf_number *data;
+
+ result = pdf_new_obj(PDF_NUMBER);
+ data = NEW(1, pdf_number);
+ data->value = value;
+ result->data = data;
+
+ return result;
+}
+
+static void
+release_number (pdf_number *data)
+{
+ RELEASE (data);
+}
+
+static void
+write_number (pdf_out *p, pdf_number *number)
+{
+ int count;
+ char buf[512];
+
+ count = pdf_sprint_number(buf, number->value);
+
+ pdf_out_str(p, buf, count);
+}
+
+
+void
+pdf_set_number (pdf_obj *object, double value)
+{
+ pdf_number *data;
+
+ TYPECHECK(object, PDF_NUMBER);
+
+ data = object->data;
+ data->value = value;
+}
+
+double
+pdf_number_value (pdf_obj *object)
+{
+ pdf_number *data;
+
+ TYPECHECK(object, PDF_NUMBER);
+
+ data = object->data;
+
+ return data->value;
+}
+
+pdf_obj *
+pdf_new_string (const void *str, unsigned length)
+{
+ pdf_obj *result;
+ pdf_string *data;
+
+ ASSERT(str);
+
+ result = pdf_new_obj(PDF_STRING);
+ data = NEW(1, pdf_string);
+ result->data = data;
+ data->length = length;
+
+ if (length) {
+ data->string = NEW(length+1, unsigned char);
+ memcpy(data->string, str, length);
+ /* Shouldn't assume NULL terminated. */
+ data->string[length] = '\0';
+ } else
+ data->string = NULL;
+
+ return result;
+}
+
+void *
+pdf_string_value (pdf_obj *object)
+{
+ pdf_string *data;
+
+ TYPECHECK(object, PDF_STRING);
+
+ data = object->data;
+
+ return data->string;
+}
+
+unsigned
+pdf_string_length (pdf_obj *object)
+{
+ pdf_string *data;
+
+ TYPECHECK(object, PDF_STRING);
+
+ data = object->data;
+
+ return (unsigned) data->length;
+}
+
+/*
+ * This routine escapes non printable characters and control
+ * characters in an output string.
+ */
+int
+pdfobj_escape_str (char *buffer, int bufsize, const unsigned char *s, int len)
+{
+ size_t result = 0;
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ unsigned char ch;
+
+ ch = s[i];
+ if (result > bufsize - 4)
+ ERROR("pdfobj_escape_str: Buffer overflow");
+
+ /*
+ * We always write three octal digits. Optimization only gives few Kb
+ * smaller size for most documents when zlib compressed.
+ */
+ if (ch < 32 || ch > 126) {
+ buffer[result++] = '\\';
+#if 0
+ if (i < len - 1 && !isdigit(s[i+1]))
+ result += sprintf(buffer+result, "%o", ch);
+ else
+ result += sprintf(buffer+result, "%03o", ch);
+#endif
+ result += sprintf(buffer+result, "%03o", ch);
+ } else {
+ switch (ch) {
+ case '(':
+ buffer[result++] = '\\';
+ buffer[result++] = '(';
+ break;
+ case ')':
+ buffer[result++] = '\\';
+ buffer[result++] = ')';
+ break;
+ case '\\':
+ buffer[result++] = '\\';
+ buffer[result++] = '\\';
+ break;
+ default:
+ buffer[result++] = ch;
+ break;
+ }
+ }
+ }
+
+ return (int) result;
+}
+
+static void
+write_string (pdf_out *p, pdf_string *str)
+{
+ unsigned char *s = NULL;
+ size_t i, nescc = 0;
+ size_t len = 0;
+
+ ASSERT(p);
+
+ if (p->state.enc_mode) {
+ pdf_encrypt_data(p->sec_data, str->string, str->length, &s, &len);
+ } else {
+ s = str->string;
+ len = str->length;
+ }
+
+ /*
+ * Count all ASCII non-printable characters.
+ */
+ for (i = 0; i < len; i++) {
+ if (!isprint(s[i]))
+ nescc++;
+ }
+ /*
+ * If the string contains much escaped chars, then we write it as
+ * ASCII hex string.
+ */
+ if (nescc > len / 3) {
+ pdf_out_char(p, '<');
+ for (i = 0; i < len; i++) {
+ pdf_out_xchar(p, s[i]);
+ }
+ pdf_out_char(p, '>');
+ } else {
+ char *buf;
+ size_t size, count;
+
+ /* At most len/3 is to be escaped here. (see above)
+ * Thus 4*len/3 + 2*len/3 + 2 is enough for buffer size.
+ */
+ size = len * 2 + 3;
+ buf = NEW(size, char);
+
+ pdf_out_char(p, '(');
+ /*
+ * This section of code probably isn't speed critical. Escaping the
+ * characters in the string one at a time may seem slow, but it's
+ * safe if the formatted string length exceeds FORMAT_BUF_SIZE.
+ * Occasionally you see some long strings in PDF. pdfobj_escape_str
+ * is also used for strings of text with no kerning. These must be
+ * handled as quickly as possible since there are so many of them.
+ */
+ for (i = 0; i < len; i++) {
+ count = pdfobj_escape_str(buf, size, &(s[i]), 1);
+ pdf_out_str(p, buf, count);
+ }
+ pdf_out_char(p, ')');
+ RELEASE(buf);
+ }
+
+ if (p->state.enc_mode && s)
+ RELEASE(s);
+}
+
+static void
+release_string (pdf_string *data)
+{
+ if (data->string != NULL) {
+ RELEASE(data->string);
+ data->string = NULL;
+ }
+ RELEASE(data);
+}
+
+void
+pdf_set_string (pdf_obj *object, unsigned char *str, unsigned length)
+{
+ pdf_string *data;
+
+ TYPECHECK(object, PDF_STRING);
+
+ data = object->data;
+ if (data->string != 0) {
+ RELEASE(data->string);
+ }
+ if (length != 0) {
+ data->length = length;
+ data->string = NEW(length + 1, unsigned char);
+ memcpy(data->string, str, length);
+ data->string[length] = '\0';
+ } else {
+ data->length = 0;
+ data->string = NULL;
+ }
+}
+
+/* Name does *not* include the /. */
+pdf_obj *
+pdf_new_name (const char *name)
+{
+ pdf_obj *result;
+ size_t length;
+ pdf_name *data;
+
+ result = pdf_new_obj(PDF_NAME);
+ data = NEW (1, pdf_name);
+ result->data = data;
+ length = strlen(name);
+ if (length != 0) {
+ data->name = NEW(length+1, char);
+ memcpy(data->name, name, length);
+ data->name[length] = '\0';
+ } else {
+ data->name = NULL;
+ }
+
+ return result;
+}
+
+static void
+write_name (pdf_out *p, pdf_name *name)
+{
+ char *s;
+ size_t i, length;
+
+ ASSERT(p);
+
+ s = name->name;
+ length = name->name ? strlen(name->name) : 0;
+ /*
+ * From PDF Reference, 3rd ed., p.33:
+ *
+ * Beginning with PDF 1.2, any character except null (character code 0)
+ * may be included in a name by writing its 2-digit hexadecimal code,
+ * preceded bythe number sign character (#); see implementation notes 3
+ * and 4 in Appendix H. This syntax is required in order to represent
+ * any of the delimiter or white-space characters or the number sign
+ * character itself; it is recommended but not required for characters
+ * whose codes are outside the range 33 (!) to 126 (~).
+ */
+#ifndef is_delim
+ /* Avoid '{' and '}' for PostScript compatibility? */
+#define is_delim(c) ((c) == '(' || (c) == ')' || \
+ (c) == '/' || \
+ (c) == '<' || (c) == '>' || \
+ (c) == '[' || (c) == ']' || \
+ (c) == '{' || (c) == '}' || \
+ (c) == '%')
+#endif
+ pdf_out_char(p, '/');
+ for (i = 0; i < length; i++) {
+ if (s[i] < '!' || s[i] > '~' || s[i] == '#' || is_delim(s[i])) {
+ /* ^ "space" is here. */
+ pdf_out_char (p, '#');
+ pdf_out_xchar(p, s[i]);
+ } else {
+ pdf_out_char (p, s[i]);
+ }
+ }
+}
+
+static void
+release_name (pdf_name *data)
+{
+ if (data->name != NULL) {
+ RELEASE(data->name);
+ data->name = NULL;
+ }
+ RELEASE(data);
+}
+
+char *
+pdf_name_value (pdf_obj *object)
+{
+ pdf_name *data;
+
+ TYPECHECK(object, PDF_NAME);
+
+ data = object->data;
+
+ return data->name;
+}
+
+/*
+ * We do not have pdf_name_length() since '\0' is not allowed
+ * in PDF name object.
+ */
+
+pdf_obj *
+pdf_new_array (void)
+{
+ pdf_obj *result;
+ pdf_array *data;
+
+ result = pdf_new_obj(PDF_ARRAY);
+ data = NEW(1, pdf_array);
+ data->values = NULL;
+ data->max = 0;
+ data->size = 0;
+ result->data = data;
+
+ return result;
+}
+
+static void
+write_array (pdf_out *p, pdf_array *array)
+{
+ ASSERT(p);
+
+ pdf_out_char(p, '[');
+ if (array->size > 0) {
+ size_t i;
+ int type1 = PDF_UNDEFINED, type2;
+
+ for (i = 0; i < array->size; i++) {
+ if (array->values[i]) {
+ type2 = array->values[i]->type;
+ if (type1 != PDF_UNDEFINED && pdf_need_white(type1, type2))
+ pdf_out_white(p);
+ type1 = type2;
+ pdf_write_obj(p, array->values[i]);
+ } else
+ WARN("PDF array element %ld undefined.", i);
+ }
+ }
+ pdf_out_char(p, ']');
+}
+
+pdf_obj *
+pdf_get_array (pdf_obj *array, int idx)
+{
+ pdf_obj *result = NULL;
+ pdf_array *data;
+
+ TYPECHECK(array, PDF_ARRAY);
+
+ data = array->data;
+ if (idx < 0)
+ result = data->values[idx + data->size];
+ else if (idx < data->size) {
+ result = data->values[idx];
+ }
+
+ return result;
+}
+
+unsigned
+pdf_array_length (pdf_obj *array)
+{
+ pdf_array *data;
+
+ TYPECHECK(array, PDF_ARRAY);
+
+ data = (pdf_array *) array->data;
+
+ return (unsigned) data->size;
+}
+
+static void
+release_array (pdf_array *data)
+{
+ size_t i;
+
+ if (data->values) {
+ for (i = 0; i < data->size; i++) {
+ pdf_release_obj(data->values[i]);
+ data->values[i] = NULL;
+ }
+ RELEASE(data->values);
+ data->values = NULL;
+ }
+ RELEASE(data);
+}
+
+/*
+ * The name pdf_add_array is misleading. It behaves differently than
+ * pdf_add_dict(). This should be pdf_push_array().
+ */
+void
+pdf_add_array (pdf_obj *array, pdf_obj *object)
+{
+ pdf_array *data;
+
+ TYPECHECK(array, PDF_ARRAY);
+
+ data = array->data;
+ if (data->size >= data->max) {
+ data->max += ARRAY_ALLOC_SIZE;
+ data->values = RENEW(data->values, data->max, pdf_obj *);
+ }
+ data->values[data->size] = object;
+ data->size++;
+
+ return;
+}
+
+#if 0
+void
+pdf_put_array (pdf_obj *array, int idx, pdf_obj *object)
+{
+ pdf_array *data;
+ int i;
+
+ TYPECHECK(array, PDF_ARRAY);
+
+ data = array->data;
+ if (idx + 1 > data->max) {
+ data->max += ARRAY_ALLOC_SIZE;
+ data->values = RENEW(data->values, data->max, pdf_obj *);
+ }
+ /*
+ * Rangecheck error in PostScript interpreters if
+ * idx > data->size - 1. But pdf_new_array() doesn't set
+ * array size, pdf_add_array() dynamically increases size
+ * of array. This might confusing...
+ */
+ if (idx + 1 > data->size) {
+ for (i = data->size; i < idx; i++)
+ data->values[i] = pdf_new_null(); /* release_array() won't work without this */
+ data->values[idx] = object;
+ data->size = idx + 1;
+ } else {
+ if (data->values[idx])
+ pdf_release_obj(data->values[idx]);
+ data->values[idx] = object;
+ }
+}
+
+/* Easily leaks memory... */
+pdf_obj *
+pdf_shift_array (pdf_obj *array)
+{
+ pdf_obj *result = NULL;
+ pdf_array *data;
+
+ TYPECHECK(array, PDF_ARRAY);
+
+ data = array->data;
+ if (data->size > 0) {
+ size_t i;
+
+ result = data->values[0];
+ for (i = 1; i < data->size; i++)
+ data->values[i-1] = data->values[i];
+ data->size--;
+ }
+
+ return result;
+}
+#endif
+
+/* Prepend an object to an array */
+static void
+pdf_unshift_array (pdf_obj *array, pdf_obj *object)
+{
+ pdf_array *data;
+
+ TYPECHECK(array, PDF_ARRAY);
+
+ data = array->data;
+ if (data->size >= data->max) {
+ data->max += ARRAY_ALLOC_SIZE;
+ data->values = RENEW(data->values, data->max, pdf_obj *);
+ }
+ memmove(&data->values[1], data->values, data->size * sizeof(pdf_obj *));
+ data->values[0] = object;
+ data->size++;
+}
+
+#if 0
+pdf_obj *
+pdf_pop_array (pdf_obj *array)
+{
+ pdf_obj *result;
+ pdf_array *data;
+
+ TYPECHECK(array, PDF_ARRAY);
+
+ data = array->data;
+ if (data->size > 0) {
+ result = data->values[data->size - 1];
+ data->size--;
+ } else {
+ result = NULL;
+ }
+
+ return result;
+}
+#endif
+
+static void
+write_dict (pdf_out *p, pdf_dict *dict)
+{
+#if 0
+ pdf_out_str (p, "<<\n", 3); /* dropping \n saves few kb. */
+#else
+ pdf_out_str(p, "<<", 2);
+#endif
+ while (dict->key != NULL) {
+ pdf_write_obj(p, dict->key);
+ if (pdf_need_white(PDF_NAME, (dict->value)->type)) {
+ pdf_out_white(p);
+ }
+ pdf_write_obj(p, dict->value);
+#if 0
+ pdf_out_char (file, '\n'); /* removing this saves few kb. */
+#endif
+ dict = dict->next;
+ }
+ pdf_out_str(p, ">>", 2);
+}
+
+pdf_obj *
+pdf_new_dict (void)
+{
+ pdf_obj *result;
+ pdf_dict *data;
+
+ result = pdf_new_obj(PDF_DICT);
+ data = NEW(1, pdf_dict);
+ data->key = NULL;
+ data->value = NULL;
+ data->next = NULL;
+ result->data = data;
+
+ return result;
+}
+
+static void
+release_dict (pdf_dict *data)
+{
+ pdf_dict *next;
+
+ while (data != NULL && data->key != NULL) {
+ pdf_release_obj(data->key);
+ pdf_release_obj(data->value);
+ data->key = NULL;
+ data->value = NULL;
+ next = data->next;
+ RELEASE(data);
+ data = next;
+ }
+ RELEASE(data);
+}
+
+/* Array is ended by a node with NULL this pointer */
+/* pdf_add_dict returns 0 if the key is new and non-zero otherwise */
+int
+pdf_add_dict (pdf_obj *dict, pdf_obj *key, pdf_obj *value)
+{
+ pdf_dict *data, *new_node;
+
+ TYPECHECK(dict, PDF_DICT);
+ TYPECHECK(key, PDF_NAME);
+
+ /* It seems that NULL is sometimes used for null object... */
+ if (value != NULL && INVALIDOBJ(value))
+ ERROR("pdf_add_dict(): Passed invalid value");
+
+ /* If this key already exists, simply replace the value */
+ for (data = dict->data; data->key != NULL; data = data->next) {
+ if (!strcmp(pdf_name_value(key), pdf_name_value(data->key))) {
+ /* Release the old value */
+ pdf_release_obj(data->value);
+ /* Release the new key (we don't need it) */
+ pdf_release_obj(key);
+ data->value = value;
+ return 1;
+ }
+ }
+ /*
+ * We didn't find the key. We build a new "end" node and add
+ * the new key just before the end
+ */
+ new_node = NEW (1, pdf_dict);
+ new_node->key = NULL;
+ new_node->value = NULL;
+ new_node->next = NULL;
+ data->next = new_node;
+ data->key = key;
+ data->value = value;
+ return 0;
+}
+
+#if 0
+void
+pdf_put_dict (pdf_obj *dict, const char *key, pdf_obj *value)
+{
+ pdf_dict *data;
+
+ TYPECHECK(dict, PDF_DICT);
+
+ if (!key) {
+ ERROR("pdf_put_dict(): Passed invalid key.");
+ }
+ /* It seems that NULL is sometimes used for null object... */
+ if (value != NULL && INVALIDOBJ(value)) {
+ ERROR("pdf_add_dict(): Passed invalid value.");
+ }
+
+ data = dict->data;
+
+ while (data->key != NULL) {
+ if (!strcmp(key, pdf_name_value(data->key))) {
+ pdf_release_obj(data->value);
+ data->value = value;
+ break;
+ }
+ data = data->next;
+ }
+
+ /*
+ * If we didn't find the key, build a new "end" node and add
+ * the new key just before the end
+ */
+ if (data->key == NULL) {
+ pdf_dict *new_node;
+
+ new_node = NEW (1, pdf_dict);
+ new_node->key = NULL;
+ new_node->value = NULL;
+ new_node->next = NULL;
+ data->next = new_node;
+ data->key = pdf_new_name(key);
+ data->value = value;
+ }
+}
+#endif
+
+/* pdf_merge_dict makes a link for each item in dict2 before stealing it */
+void
+pdf_merge_dict (pdf_obj *dict1, pdf_obj *dict2)
+{
+ pdf_dict *data;
+
+ TYPECHECK(dict1, PDF_DICT);
+ TYPECHECK(dict2, PDF_DICT);
+
+ data = dict2->data;
+ while (data->key != NULL) {
+ pdf_add_dict(dict1, pdf_link_obj(data->key), pdf_link_obj(data->value));
+ data = data->next;
+ }
+}
+
+int
+pdf_foreach_dict (pdf_obj *dict,
+ int (*proc) (pdf_obj *, pdf_obj *, void *), void *pdata)
+{
+ int error = 0;
+ pdf_dict *data;
+
+ ASSERT(proc);
+
+ TYPECHECK(dict, PDF_DICT);
+
+ data = dict->data;
+ while (!error &&
+ data->key != NULL) {
+ error = proc(data->key, data->value, pdata);
+ data = data->next;
+ }
+
+ return error;
+}
+
+#define pdf_match_name(o,s) ((o) && (s) && !strcmp(((pdf_name *)(o)->data)->name, (s)))
+pdf_obj *
+pdf_lookup_dict (pdf_obj *dict, const char *name)
+{
+ pdf_dict *data;
+
+ ASSERT(name);
+
+ TYPECHECK(dict, PDF_DICT);
+
+ data = dict->data;
+ while (data->key != NULL) {
+ if (!strcmp(name, pdf_name_value(data->key))) {
+ return data->value;
+ }
+ data = data->next;
+ }
+
+ return NULL;
+}
+
+/* Returns array of dictionary keys */
+pdf_obj *
+pdf_dict_keys (pdf_obj *dict)
+{
+ pdf_obj *keys;
+ pdf_dict *data;
+
+ TYPECHECK(dict, PDF_DICT);
+
+ keys = pdf_new_array();
+ for (data = dict->data; (data &&
+ data->key != NULL); data = data->next) {
+ /* We duplicate name object rather than linking keys.
+ * If we forget to free keys, broken PDF is generated.
+ */
+ pdf_add_array(keys, pdf_new_name(pdf_name_value(data->key)));
+ }
+
+ return keys;
+}
+
+void
+pdf_remove_dict (pdf_obj *dict, const char *name)
+{
+ pdf_dict *data, **data_p;
+
+ TYPECHECK(dict, PDF_DICT);
+
+ data = dict->data;
+ data_p = (pdf_dict **) (void *) &(dict->data);
+ while (data->key != NULL) {
+ if (pdf_match_name(data->key, name)) {
+ pdf_release_obj(data->key);
+ pdf_release_obj(data->value);
+ *data_p = data->next;
+ RELEASE(data);
+ break;
+ }
+ data_p = &(data->next);
+ data = data->next;
+ }
+}
+
+pdf_obj *
+pdf_new_stream (int flags)
+{
+ pdf_obj *result;
+ pdf_stream *data;
+
+ result = pdf_new_obj(PDF_STREAM);
+ data = NEW(1, pdf_stream);
+ /*
+ * Although we are using an arbitrary pdf_object here, it must have
+ * type=PDF_DICT and cannot be an indirect reference. This will be
+ * checked by the output routine.
+ */
+ data->dict = pdf_new_dict();
+ data->_flags = flags;
+ data->stream = NULL;
+ data->stream_length = 0;
+ data->max_length = 0;
+ data->objstm_data = NULL;
+
+ data->decodeparms.predictor = 2;
+ data->decodeparms.columns = 0;
+ data->decodeparms.bits_per_component = 0;
+ data->decodeparms.colors = 0;
+
+ result->data = data;
+ result->flags |= OBJ_NO_OBJSTM;
+
+ return result;
+}
+
+void
+pdf_stream_set_predictor (pdf_obj *stream,
+ int predictor, int32_t columns, int bpc, int colors)
+{
+ struct pdf_stream *data;
+
+ if (pdf_obj_typeof(stream) != PDF_STREAM)
+ return;
+ else if (columns < 0 || bpc < 0 || colors < 0)
+ return;
+
+ data = (struct pdf_stream *) stream->data;
+ data->decodeparms.predictor = predictor;
+ data->decodeparms.columns = columns;
+ data->decodeparms.bits_per_component = bpc;
+ data->decodeparms.colors = colors;
+ data->_flags |= STREAM_USE_PREDICTOR;
+}
+
+/* Adaptive PNG filter
+ * We use the "minimum sum of absolute differences" heuristic approach
+ * for finding the most optimal filter to be used.
+ *
+ * From http://www.libpng.org/pub/png/book/chapter09.html
+ *
+ * For grayscale and truecolor images of 8 or more bits per sample, with or
+ * without alpha channels, dynamic filtering is almost always beneficial. The
+ * approach that has by now become standard is known as the minimum sum of
+ * absolute differences heuristic and was first proposed by Lee Daniel
+ * Crocker in February 1995.
+ */
+static unsigned char *
+filter_PNG15_apply_filter (unsigned char *raster,
+ int32_t columns, int32_t rows,
+ int8_t bpc, int8_t colors, int32_t *length)
+{
+ unsigned char *dst;
+ int bits_per_pixel = colors * bpc;
+ int bytes_per_pixel = (bits_per_pixel + 7) / 8;
+ int32_t rowbytes = columns * bytes_per_pixel;
+ int32_t i, j;
+
+ ASSERT(raster && length);
+
+ /* Result */
+ dst = NEW((rowbytes+1)*rows, unsigned char);
+ *length = (rowbytes + 1) * rows;
+
+ for (j = 0; j < rows; j++) {
+ int type = 0;
+ unsigned char *pp = dst + j * (rowbytes + 1);
+ unsigned char *p = raster + j * rowbytes;
+ uint32_t sum[5] = {0, 0, 0, 0, 0};
+ /* First calculated sum of values to make a heuristic guess
+ * of optimal predictor function.
+ */
+ for (i = 0; i < rowbytes; i++) {
+ int left = (i - bytes_per_pixel >= 0) ? p[i - bytes_per_pixel] : 0;
+ int up = (j > 0) ? *(p+i-rowbytes) : 0;
+ int uplft = (j > 0) ?
+ ((i - bytes_per_pixel >= 0) ?
+ *(p+i-rowbytes-bytes_per_pixel) : 0) : 0;
+ /* Type 0 -- None */
+ sum[0] += p[i];
+ /* Type 1 -- Sub */
+ sum[1] += abs((int) p[i] - left);
+ /* Type 2 -- Up */
+ sum[2] += abs((int) p[i] - up);
+ /* Type 3 -- Average */
+ {
+ int tmp = floor((up + left) / 2);
+ sum[3] += abs((int) p[i] - tmp);
+ }
+ /* Type 4 -- Peath */
+ {
+ int q = left + up - uplft;
+ int qa = abs(q - left), qb = abs(q - up), qc = abs(q - uplft);
+ if (qa <= qb && qa <= qc)
+ sum[4] += abs((int) p[i] - left);
+ else if (qb <= qc)
+ sum[4] += abs((int) p[i] - up);
+ else
+ sum[4] += abs((int) p[i] - uplft);
+ }
+ }
+ {
+ int min = sum[0], min_idx = 0;
+ for (i = 0; i < 5; i++) {
+ if (sum[i] < min) {
+ min = sum[i]; min_idx = i;
+ }
+ }
+ type = min_idx;
+ }
+ /* Now we actually apply filter. */
+ pp[0] = type;
+ switch (type) {
+ case 0:
+ memcpy(pp+1, p, rowbytes);
+ break;
+ case 1:
+ for (i = 0; i < rowbytes; i++) {
+ int left = (i - bytes_per_pixel >= 0) ? p[i - bytes_per_pixel] : 0;
+ pp[i+1] = p[i] - left;
+ }
+ break;
+ case 2:
+ for (i = 0; i < rowbytes; i++) {
+ int up = (j > 0) ? *(p+i - rowbytes) : 0;
+ pp[i+1] = p[i] - up;
+ }
+ break;
+ case 3:
+ {
+ for (i = 0; i < rowbytes; i++) {
+ int up = (j > 0) ? *(p+i-rowbytes) : 0;
+ int left = (i - bytes_per_pixel >= 0) ? p[i - bytes_per_pixel] : 0;
+ int tmp = floor((up + left) / 2);
+ pp[i+1] = p[i] - tmp;
+ }
+ }
+ break;
+ case 4: /* Peath */
+ {
+ for (i = 0; i < rowbytes; i++) {
+ int up = (j > 0) ? *(p+i-rowbytes) : 0;
+ int left = (i - bytes_per_pixel >= 0) ? p[i - bytes_per_pixel] : 0;
+ int uplft = (j > 0) ?
+ ((i - bytes_per_pixel >= 0) ?
+ *(p+i-rowbytes-bytes_per_pixel) : 0) : 0;
+ int q = left + up - uplft;
+ int qa = abs(q - left), qb = abs(q - up), qc = abs(q - uplft);
+ if (qa <= qb && qa <= qc)
+ pp[i+1] = p[i] - left;
+ else if (qb <= qc)
+ pp[i+1] = p[i] - up;
+ else
+ pp[i+1] = p[i] - uplft;
+ }
+ }
+ break;
+ }
+ }
+
+ return dst;
+}
+
+/* TIFF predictor filter support
+ * This modifies "raster" itself!
+ */
+static void
+apply_filter_TIFF2_1_2_4 (unsigned char *raster,
+ int32_t width, int32_t height,
+ int8_t bpc, int8_t num_comp)
+{
+ int32_t rowbytes = (bpc * num_comp * width + 7) / 8;
+ uint8_t mask = (1 << bpc) - 1;
+ uint16_t *prev;
+ int32_t i, j;
+
+ ASSERT(raster);
+ ASSERT( bpc > 0 && bpc <= 8 );
+
+ prev = NEW(num_comp, uint16_t);
+
+ /* Generic routine for 1 to 16 bit.
+ * It supports, e.g., 7 bpc images too.
+ * Actually, it is not necessary to have 16 bit inbuf and outbuf
+ * since we only need 1, 2, and 4 bit support here. 8 bit is enough.
+ */
+ for (j = 0; j < height; j++) {
+ int32_t k, l, inbits, outbits;
+ uint16_t inbuf, outbuf;
+ int c;
+
+ memset(prev, 0, sizeof(uint16_t)*num_comp);
+ inbuf = outbuf = 0; inbits = outbits = 0;
+ l = k = j * rowbytes;
+ for (i = 0; i < width; i++) {
+ for (c = 0; c < num_comp; c++) {
+ uint8_t cur;
+ int8_t sub;
+ if (inbits < bpc) { /* need more byte */
+ inbuf = (inbuf << 8) | raster[l]; l++;
+ inbits += 8;
+ }
+ cur = (inbuf >> (inbits - bpc)) & mask;
+ inbits -= bpc; /* consumed bpc bits */
+ sub = cur - prev[c];
+ prev[c] = cur;
+ if (sub < 0)
+ sub += (1 << bpc);
+ /* Append newly filtered component value */
+ outbuf = (outbuf << bpc) | sub;
+ outbits += bpc;
+ /* flush */
+ if (outbits >= 8) {
+ raster[k] = (outbuf >> (outbits - 8)); k++;
+ outbits -= 8;
+ }
+ }
+ }
+ if (outbits > 0) {
+ raster[k] = (outbuf << (8 - outbits));
+ k++;
+ }
+ }
+ RELEASE(prev);
+}
+
+static unsigned char *
+filter_TIFF2_apply_filter (unsigned char *raster,
+ int32_t columns, int32_t rows,
+ int8_t bpc, int8_t colors, int32_t *length)
+{
+ unsigned char *dst;
+ uint16_t *prev;
+ int32_t rowbytes = (bpc * colors * columns + 7) / 8;
+ int32_t i, j;
+
+ ASSERT(raster && length);
+
+ dst = NEW(rowbytes*rows, unsigned char);
+ memcpy(dst, raster, rowbytes*rows);
+ *length = rowbytes * rows;
+
+ switch (bpc) {
+ case 1: case 2: case 4:
+ apply_filter_TIFF2_1_2_4(dst, columns, rows, bpc, colors);
+ break;
+
+ case 8:
+ prev = NEW(colors, uint16_t);
+ for (j = 0; j < rows; j++) {
+ memset(prev, 0, sizeof(uint16_t)*colors);
+ for (i = 0; i < columns; i++) {
+ int c;
+ int32_t pos = colors * (columns * j + i);
+ for (c = 0; c < colors; c++) {
+ uint8_t cur = raster[pos+c];
+ int32_t sub = cur - prev[c];
+ prev[c] = cur;
+ dst[pos+c] = sub;
+ }
+ }
+ }
+ RELEASE(prev);
+ break;
+
+ case 16:
+ prev = NEW(colors, uint16_t);
+ for (j = 0; j < rows; j++) {
+ memset(prev, 0, sizeof(uint16_t)*colors);
+ for (i = 0; i < columns; i++) {
+ int c;
+ int32_t pos = 2 * colors * (columns * j + i);
+ for (c = 0; c < colors; c++) {
+ uint16_t cur = ((uint8_t)raster[pos+2*c])*256 +
+ (uint8_t)raster[pos+2*c+1];
+ uint16_t sub = cur - prev[c];
+ prev[c] = cur;
+ dst[pos+2*c ] = (sub >> 8) & 0xff;
+ dst[pos+2*c+1] = sub & 0xff;
+ }
+ }
+ }
+ RELEASE(prev);
+ break;
+
+ }
+
+ return dst;
+}
+
+static pdf_obj *
+filter_create_predictor_dict (int predictor, int32_t columns,
+ int bpc, int colors)
+{
+ pdf_obj *parms;
+
+ parms = pdf_new_dict();
+ pdf_add_dict(parms, pdf_new_name("BitsPerComponent"), pdf_new_number(bpc));
+ pdf_add_dict(parms, pdf_new_name("Colors"), pdf_new_number(colors));
+ pdf_add_dict(parms, pdf_new_name("Columns"), pdf_new_number(columns));
+ pdf_add_dict(parms, pdf_new_name("Predictor"), pdf_new_number(predictor));
+
+ return parms;
+}
+
+static void
+write_stream (pdf_out *p, pdf_stream *stream)
+{
+ unsigned char *filtered;
+ size_t filtered_length;
+#ifdef HAVE_ZLIB
+ uLong buffer_length;
+#else
+ size_t buffer_length;
+#endif
+ unsigned char *buffer;
+
+ ASSERT(p);
+
+ /*
+ * Always work from a copy of the stream. All filters read from
+ * "filtered" and leave their result in "filtered".
+ */
+#if 0
+ filtered = NEW(stream->stream_length + 1, unsigned char);
+#endif
+ filtered = NEW(stream->stream_length, unsigned char);
+ memcpy(filtered, stream->stream, stream->stream_length);
+ filtered_length = stream->stream_length;
+
+ /* PDF/A requires Metadata to be not filtered. */
+ {
+ pdf_obj *type;
+ type = pdf_lookup_dict(stream->dict, "Type");
+ if (type && !strcmp("Metadata", pdf_name_value(type))) {
+ stream->_flags &= ~STREAM_COMPRESS;
+ }
+ }
+
+#ifdef HAVE_ZLIB
+ /* Apply compression filter if requested */
+ if (stream->stream_length > 0 &&
+ (stream->_flags & STREAM_COMPRESS) &&
+ p->options.compression.level > 0) {
+ pdf_obj *filters;
+
+ /* First apply predictor filter if requested. */
+ if ( p->options.compression.use_predictor &&
+ (stream->_flags & STREAM_USE_PREDICTOR) &&
+ !pdf_lookup_dict(stream->dict, "DecodeParms")) {
+ int bits_per_pixel = stream->decodeparms.colors *
+ stream->decodeparms.bits_per_component;
+ int32_t len = (stream->decodeparms.columns * bits_per_pixel + 7) / 8;
+ int32_t rows = stream->stream_length / len;
+ unsigned char *filtered2 = NULL;
+ int32_t length2 = stream->stream_length;
+ pdf_obj *parms;
+
+ parms = filter_create_predictor_dict(stream->decodeparms.predictor,
+ stream->decodeparms.columns,
+ stream->decodeparms.bits_per_component,
+ stream->decodeparms.colors);
+
+ switch (stream->decodeparms.predictor) {
+ case 2: /* TIFF2 */
+ filtered2 = filter_TIFF2_apply_filter(filtered,
+ stream->decodeparms.columns,
+ rows,
+ stream->decodeparms.bits_per_component,
+ stream->decodeparms.colors, &length2);
+ break;
+ case 15: /* PNG optimun */
+ filtered2 = filter_PNG15_apply_filter(filtered,
+ stream->decodeparms.columns,
+ rows,
+ stream->decodeparms.bits_per_component,
+ stream->decodeparms.colors, &length2);
+ break;
+ default:
+ WARN("Unknown/unsupported Predictor function %d.",
+ stream->decodeparms.predictor);
+ break;
+ }
+ if (parms && filtered2) {
+ RELEASE(filtered);
+ filtered = filtered2;
+ filtered_length = length2;
+ pdf_add_dict(stream->dict, pdf_new_name("DecodeParms"), parms);
+ }
+ }
+
+ filters = pdf_lookup_dict(stream->dict, "Filter");
+
+ buffer_length = filtered_length + filtered_length/1000 + 14;
+ buffer = NEW(buffer_length, unsigned char);
+ {
+ pdf_obj *filter_name = pdf_new_name("FlateDecode");
+
+ if (filters)
+ /*
+ * FlateDecode is the first filter to be applied to the stream.
+ */
+ pdf_unshift_array(filters, filter_name);
+ else
+ /*
+ * Adding the filter as a name instead of a one-element array
+ * is crucial because otherwise Adobe Reader cannot read the
+ * cross-reference stream any more, cf. the PDF v1.5 Errata.
+ */
+ pdf_add_dict(stream->dict, pdf_new_name("Filter"), filter_name);
+ }
+#ifdef HAVE_ZLIB_COMPRESS2
+ if (compress2(buffer, &buffer_length, filtered,
+ filtered_length, p->options.compression.level)) {
+ ERROR("Zlib error");
+ }
+#else
+ if (compress(buffer, &buffer_length, filtered,
+ filtered_length)) {
+ ERROR ("Zlib error");
+ }
+#endif /* HAVE_ZLIB_COMPRESS2 */
+ RELEASE(filtered);
+ p->output.compression_saved +=
+ filtered_length - buffer_length
+ - (filters ? strlen("/FlateDecode "): strlen("/Filter/FlateDecode\n"));
+
+ filtered = buffer;
+ filtered_length = buffer_length;
+ }
+#endif /* HAVE_ZLIB */
+
+ /* AES will change the size of data! */
+ if (p->state.enc_mode) {
+ unsigned char *cipher = NULL;
+ size_t cipher_len = 0;
+ pdf_encrypt_data(p->sec_data, filtered, filtered_length, &cipher, &cipher_len);
+ RELEASE(filtered);
+ filtered = cipher;
+ filtered_length = cipher_len;
+ }
+
+ #if 0
+ /*
+ * An optional end-of-line marker preceding the "endstream" is
+ * not part of stream data. See, PDF Reference 4th ed., p. 38.
+ */
+ /* Add a '\n' if the last character wasn't one */
+ if (filtered_length > 0 &&
+ filtered[filtered_length-1] != '\n') {
+ filtered[filtered_length] = '\n';
+ filtered_length++;
+ }
+#endif
+
+ pdf_add_dict(stream->dict,
+ pdf_new_name("Length"), pdf_new_number(filtered_length));
+
+ pdf_write_obj(p, stream->dict);
+
+ pdf_out_str(p, "\nstream\n", 8);
+
+ if (filtered_length > 0)
+ pdf_out_str(p, filtered, filtered_length);
+ RELEASE(filtered);
+
+ /*
+ * This stream length "object" gets reset every time write_stream is
+ * called for the stream object.
+ * If this stream gets written more than once with different
+ * filters, this could be a problem.
+ */
+
+ pdf_out_str(p, "\n", 1);
+ pdf_out_str(p, "endstream", 9);
+}
+
+static void
+release_stream (pdf_stream *stream)
+{
+ pdf_release_obj(stream->dict);
+ stream->dict = NULL;
+
+ if (stream->stream) {
+ RELEASE(stream->stream);
+ stream->stream = NULL;
+ }
+
+ if (stream->objstm_data) {
+ RELEASE(stream->objstm_data);
+ stream->objstm_data = NULL;
+ }
+
+ RELEASE(stream);
+}
+
+pdf_obj *
+pdf_stream_dict (pdf_obj *stream)
+{
+ pdf_stream *data;
+
+ TYPECHECK(stream, PDF_STREAM);
+
+ data = stream->data;
+
+ return data->dict;
+}
+
+const void *
+pdf_stream_dataptr (pdf_obj *stream)
+{
+ pdf_stream *data;
+
+ TYPECHECK(stream, PDF_STREAM);
+
+ data = stream->data;
+
+ return (const void *) data->stream;
+}
+
+int
+pdf_stream_length (pdf_obj *stream)
+{
+ pdf_stream *data;
+
+ TYPECHECK(stream, PDF_STREAM);
+
+ data = stream->data;
+
+ return (int) data->stream_length;
+}
+
+static void
+set_objstm_data (pdf_obj *objstm, int *data) {
+ TYPECHECK(objstm, PDF_STREAM);
+
+ ((pdf_stream *) objstm->data)->objstm_data = data;
+}
+
+static int *
+get_objstm_data (pdf_obj *objstm) {
+ TYPECHECK(objstm, PDF_STREAM);
+
+ return ((pdf_stream *) objstm->data)->objstm_data;
+}
+
+void
+pdf_add_stream (pdf_obj *stream, const void *stream_data, int length)
+{
+ pdf_stream *data;
+
+ TYPECHECK(stream, PDF_STREAM);
+
+ if (length < 1)
+ return;
+ data = stream->data;
+ if (data->stream_length + length > data->max_length) {
+ data->max_length += length + STREAM_ALLOC_SIZE;
+ data->stream = RENEW(data->stream, data->max_length, unsigned char);
+ }
+ memcpy(data->stream + data->stream_length, stream_data, length);
+ data->stream_length += length;
+}
+
+#if HAVE_ZLIB
+#define WBUF_SIZE 4096
+
+static int
+filter_get_DecodeParms_FlateDecode (struct decode_parms *parms, pdf_obj *dict)
+{
+ pdf_obj *tmp;
+
+ ASSERT(dict && parms);
+ ASSERT(PDF_OBJ_DICTTYPE(dict));
+
+ /* Fill with default values */
+ parms->predictor = 1;
+ parms->colors = 1;
+ parms->bits_per_component = 8;
+ parms->columns = 1;
+
+ tmp = pdf_deref_obj(pdf_lookup_dict(dict, "Predictor"));
+ if (tmp) {
+ parms->predictor = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ }
+ tmp = pdf_deref_obj(pdf_lookup_dict(dict, "Colors"));
+ if (tmp) {
+ parms->colors = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ }
+ tmp = pdf_deref_obj(pdf_lookup_dict(dict, "BitsPerComponent"));
+ if (tmp) {
+ parms->bits_per_component = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ }
+ tmp = pdf_deref_obj(pdf_lookup_dict(dict, "Columns"));
+ if (tmp) {
+ parms->columns = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ }
+ if (parms->bits_per_component != 1 &&
+ parms->bits_per_component != 2 &&
+ parms->bits_per_component != 4 &&
+ parms->bits_per_component != 8 &&
+ parms->bits_per_component != 16) {
+ WARN("Invalid BPC value in DecodeParms: %d", parms->bits_per_component);
+ return -1;
+ } else if (parms->predictor <= 0 || parms->colors <= 0 ||
+ parms->columns <= 0)
+ return -1;
+ return 0;
+}
+
+/* From Xpdf version 3.04
+ * I'm not sure if I properly ported... Untested.
+ */
+static int
+filter_row_TIFF2 (unsigned char *dst, const unsigned char *src,
+ struct decode_parms *parms)
+{
+ const unsigned char *p = src;
+ unsigned char *col;
+ /* bits_per_component < 8 here */
+ int mask = (1 << parms->bits_per_component) - 1;
+ int inbuf, outbuf; /* 2 bytes buffer */
+ int i, ci, j, k, inbits, outbits;
+
+ col = NEW(parms->colors, unsigned char);
+ memset(col, 0, parms->colors);
+ inbuf = outbuf = 0; inbits = outbits = 0;
+ j = k = 0;
+ for (i = 0; i < parms->columns; i++) {
+ /* expanding each color component into an 8-bits bytes array */
+ for (ci = 0; ci < parms->colors; ci++) {
+ if (inbits < parms->bits_per_component) {
+ /* need more byte */
+ inbuf = (inbuf << 8) | p[j++];
+ inbits += 8;
+ }
+ /* predict current color component */
+ col[ci] = (unsigned char) ((col[ci] +
+ (inbuf >> (inbits - parms->bits_per_component))) & mask);
+ inbits -= parms->bits_per_component; /* consumed bpc bits */
+ /* append newly predicted color component value */
+ outbuf = (outbuf << parms->bits_per_component) | col[ci];
+ outbits += parms->bits_per_component;
+ if (outbits >= 8) { /* flush */
+ dst[k++] = (unsigned char) (outbuf >> (outbits - 8));
+ outbits -= 8;
+ }
+ }
+ }
+ if (outbits > 0) {
+ dst[k] = (unsigned char) (outbuf << (8 - outbits));
+ }
+ RELEASE(col);
+
+ return 0;
+}
+
+/* This routine is inefficient. Length is typically 4 for Xref streams.
+ * Especially, calling pdf_add_stream() for each 4 bytes append is highly
+ * inefficient.
+ */
+static pdf_obj *
+filter_stream_decode_Predictor (const void *src, size_t srclen, struct decode_parms *parms)
+{
+ pdf_obj *dst;
+ const unsigned char *p = (const unsigned char *) src;
+ const unsigned char *endptr = p + srclen;
+ unsigned char *prev, *buf;
+ int bits_per_pixel = parms->colors * parms->bits_per_component;
+ int bytes_per_pixel = (bits_per_pixel + 7) / 8;
+ int length = (parms->columns * bits_per_pixel + 7) / 8;
+ int i, error = 0;
+
+ dst = pdf_new_stream(0);
+
+ prev = NEW(length, unsigned char);
+ buf = NEW(length, unsigned char);
+
+ memset(prev, 0, length);
+ switch (parms->predictor) {
+ case 1 : /* No prediction */
+ pdf_add_stream(dst, src, srclen); /* Just copy */
+ break;
+ case 2: /* TIFF Predictor 2 */
+ {
+ if (parms->bits_per_component == 8) {
+ while (p + length < endptr) {
+ /* Same as PNG Sub */
+ for (i = 0; i < length; i++) {
+ int pv = i - bytes_per_pixel >= 0 ? buf[i - bytes_per_pixel] : 0;
+ buf[i] = (unsigned char)(((int) p[i] + pv) & 0xff);
+ }
+ pdf_add_stream(dst, buf, length);
+ p += length;
+ }
+ } else if (parms->bits_per_component == 16) {
+ while (p + length < endptr) {
+ for (i = 0; i < length; i += 2) {
+ int b = i - bytes_per_pixel;
+ char hi = b >= 0 ? buf[b] : 0;
+ char lo = b >= 0 ? buf[b + 1] : 0;
+ int pv = (hi << 8) | lo;
+ int cv = (p[i] << 8) | p[i + 1];
+ int c = pv + cv;
+ buf[i] = (unsigned char) (c >> 8);
+ buf[i + 1] = (unsigned char) (c & 0xff);
+ }
+ pdf_add_stream(dst, buf, length);
+ p += length;
+ }
+ } else { /* bits per component 1, 2, 4 */
+ while (!error && p + length < endptr) {
+ error = filter_row_TIFF2(buf, p, parms);
+ if (!error) {
+ pdf_add_stream(dst, buf, length);
+ p += length;
+ }
+ }
+ }
+ }
+ break;
+ /* PNG predictors: first byte of each rows is predictor type */
+ case 10: /* PNG None */
+ case 11: /* PNG Sub on all rows */
+ case 12: /* PNG UP on all rows */
+ case 13: /* PNG Average on all rows */
+ case 14: /* PNG Paeth on all rows */
+ case 15: /* PNG optimun: prediction algorithm can change from line to line. */
+ {
+ int type = parms->predictor - 10;
+
+ while (!error && p + length < endptr) {
+ if (parms->predictor == 15)
+ type = *p;
+ else if (*p != type) {
+ WARN("Mismatched Predictor type in data stream.");
+ error = -1;
+ }
+ p++;
+ switch (type) {
+ case 0: /* Do nothing just skip first byte */
+ memcpy(buf, p, length);
+ break;
+ case 1:
+ for (i = 0; i < length; i++) {
+ int pv = i - bytes_per_pixel >= 0 ? buf[i - bytes_per_pixel] : 0;
+ buf[i] = (unsigned char)(((int) p[i] + pv) & 0xff);
+ }
+ break;
+ case 2:
+ for (i = 0; i < length; i++) {
+ buf[i] = (unsigned char)(((int) p[i] + (int) prev[i]) & 0xff);
+ }
+ break;
+ case 3:
+ for (i = 0; i < length; i++) {
+ int up = prev[i];
+ int left = i - bytes_per_pixel >= 0 ? buf[i - bytes_per_pixel] : 0;
+ int tmp = floor((up + left) / 2);
+ buf[i] = (unsigned char)((p[i] + tmp) & 0xff);
+ }
+ break;
+ case 4:
+ for (i = 0; i < length; i++) {
+ int a = i - bytes_per_pixel >= 0 ? buf[i - bytes_per_pixel] : 0; /* left */
+ int b = prev[i]; /* above */
+ int c = i - bytes_per_pixel >= 0 ? prev[i - bytes_per_pixel] : 0; /* upper left */
+ int q = a + b - c;
+ int qa = q - a, qb = q - b, qc = q - c;
+ qa = qa < 0 ? -qa : qa;
+ qb = qb < 0 ? -qb : qb;
+ qc = qc < 0 ? -qc : qc;
+ if (qa <= qb && qa <= qc)
+ buf[i] = (unsigned char) (((int) p[i] + a) & 0xff);
+ else if (qb <= qc)
+ buf[i] = (unsigned char) (((int) p[i] + b) & 0xff);
+ else
+ buf[i] = (unsigned char) (((int) p[i] + c) & 0xff);
+ }
+ break;
+ default:
+ WARN("Unknown PNG predictor type: %d", type);
+ error = -1;
+ }
+ if (!error) {
+ pdf_add_stream(dst, buf, length); /* highly inefficient */
+ memcpy(prev, buf, length);
+ p += length;
+ }
+ }
+ }
+ break;
+ default:
+ WARN("Unknown Predictor type value :%d", parms->predictor);
+ error = -1;
+ }
+
+ RELEASE(prev);
+ RELEASE(buf);
+
+ if (error) {
+ pdf_release_obj(dst);
+ dst = NULL;
+ }
+
+ return dst;
+}
+
+static pdf_obj *
+filter_stream_decode_FlateDecode (const void *data, size_t len, struct decode_parms *parms)
+{
+ pdf_obj *dst;
+ pdf_obj *tmp;
+ z_stream z;
+ Bytef wbuf[WBUF_SIZE];
+
+ z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL;
+
+ z.next_in = (z_const Bytef *) data; z.avail_in = len;
+ z.next_out = (Bytef *) wbuf; z.avail_out = WBUF_SIZE;
+
+ if (inflateInit(&z) != Z_OK) {
+ WARN("inflateInit() failed.");
+ return NULL;
+ }
+
+ tmp = pdf_new_stream(0);
+ for (;;) {
+ int status;
+ status = inflate(&z, Z_NO_FLUSH);
+ if (status == Z_STREAM_END) {
+ break;
+ } else if (status == Z_DATA_ERROR && z.avail_in == 0) {
+ WARN("Ignoring zlib error: status=%d, message=\"%s\"", status, z.msg);
+ break;
+ } else if (status != Z_OK) {
+ WARN("inflate() failed. Broken PDF file?");
+ inflateEnd(&z);
+ pdf_release_obj(tmp);
+ return NULL;
+ }
+
+ if (z.avail_out == 0) {
+ pdf_add_stream(tmp, wbuf, WBUF_SIZE);
+ z.next_out = wbuf;
+ z.avail_out = WBUF_SIZE;
+ }
+ }
+
+ if (WBUF_SIZE - z.avail_out > 0)
+ pdf_add_stream(tmp, wbuf, WBUF_SIZE - z.avail_out);
+
+ if (inflateEnd(&z) == Z_OK) {
+ if (parms) {
+ dst = filter_stream_decode_Predictor(pdf_stream_dataptr(tmp), pdf_stream_length(tmp), parms);
+ } else {
+ dst = pdf_link_obj(tmp);
+ }
+ } else {
+ dst = NULL;
+ }
+ pdf_release_obj(tmp);
+
+ return dst;
+}
+#endif
+
+static pdf_obj *
+filter_stream_decode_ASCIIHexDecode (const void *data, size_t len)
+{
+ pdf_obj *dst;
+ int eod, error;
+ const char *p = (const char *) data;
+ const char *endptr = p + len;
+ unsigned char *buf, ch;
+ size_t pos, n;
+
+ buf = NEW((len+1)/2, unsigned char);
+ skip_white(&p, endptr);
+ ch = 0; n = 0; pos = 0; eod = 0; error = 0;
+ while (p < endptr && !error && !eod) {
+ char c1, val;
+ c1 = p[0];
+ if (c1 >= 'A' && c1 <= 'F') {
+ val = c1 - 'A' + 10;
+ } else if (c1 >= 'a' && c1 <= 'f') {
+ val = c1 - 'a' + 10;
+ } else if (c1 >= '0' && c1 <= '9') {
+ val = c1 - '0';
+ } else if (c1 == '>') {
+ val = 0;
+ eod = 1;
+ if ((pos % 2) == 0)
+ break;
+ } else {
+ error = -1;
+ break;
+ }
+ if (pos % 2) {
+ buf[n] = ch + val;
+ n++;
+ ch = 0;
+ } else {
+ ch = val << 4;
+ }
+ pos++; p++;
+ skip_white(&p, endptr);
+ }
+ if (error || !eod) {
+ WARN("Invalid ASCIIHex data seen: %s", error ? "Invalid character" : "No EOD marker");
+ dst = NULL;
+ } else {
+ dst = pdf_new_stream(0);
+ pdf_add_stream(dst, buf, n);
+ }
+ RELEASE(buf);
+
+ return dst;
+}
+
+/* Percent sign is not start of comment here.
+ * We need this for reading Ascii85 encoded data.
+ */
+#define is_space(c) ((c) == ' ' || (c) == '\t' || (c) == '\f' || \
+ (c) == '\r' || (c) == '\n' || (c) == '\0')
+static void
+skip_white_a85 (const char **p, const char *endptr)
+{
+ while (*p < endptr && (is_space(**p))) {
+ (*p)++;
+ }
+}
+
+static pdf_obj *
+filter_stream_decode_ASCII85Decode (const void *data, size_t len)
+{
+ pdf_obj *dst;
+ int eod, error;
+ const char *p = (const char *) data;
+ const char *endptr = p + len;
+ unsigned char *buf;
+ size_t n;
+
+ buf = NEW(((len+4)/5)*4, unsigned char);
+ skip_white_a85(&p, endptr);
+ n = 0; eod = 0; error = 0;
+ while (p < endptr && !error && !eod) {
+ char q[5] = {'u', 'u', 'u', 'u', 'u'};
+ int m;
+ char ch;
+
+ ch = p[0];
+ p++;
+ skip_white_a85(&p, endptr);
+ if (ch == 'z') {
+ memset(buf+n, 0, 4);
+ n += 4;
+ continue;
+ } else if (ch == '~') {
+ if (p < endptr && p[0] == '>') {
+ eod = 1;
+ p++;
+ } else {
+ error = -1;
+ }
+ break;
+ }
+ q[0] = ch;
+ for (m = 1; m < 5 && p < endptr; m++) {
+ ch = p[0];
+ p++;
+ skip_white_a85(&p, endptr);
+ if (ch == '~') {
+ if (p < endptr && p[0] == '>') {
+ eod = 1;
+ p++;
+ } else {
+ error = -1;
+ }
+ break;
+ } else if (ch < '!' || ch > 'u') {
+ error = -1;
+ break;
+ } else {
+ q[m] = ch;
+ }
+ }
+ if (!error) {
+ uint32_t val = 0;
+ int i;
+ if (m <= 1) {
+ error = -1;
+ break;
+ }
+ val = 85*85*85*(q[0] - '!') + 85*85*(q[1] - '!')
+ + 85*(q[2] - '!') + (q[3] - '!');
+ /* Check overflow */
+ if (val > UINT32_MAX / 85) {
+ error = -1;
+ break;
+ } else {
+ val = 85 * val;
+ if (val > UINT32_MAX - (q[4] - '!')) {
+ error = -1;
+ break;
+ }
+ val += (q[4] - '!');
+ }
+ if (!error) {
+ for (i = 3; i >= 0; i--) {
+ buf[n + i] = val & 0xff;
+ val /= 256;
+ }
+ n += m - 1;
+ }
+ }
+ }
+
+ if (error) {
+ WARN("Error in reading ASCII85 data.");
+ dst = NULL;
+ } else if (!eod) {
+ WARN("Error in reading ASCII85 data: No EOD");
+ dst = NULL;
+ } else {
+ dst = pdf_new_stream(0);
+ pdf_add_stream(dst, buf, n);
+ }
+ RELEASE(buf);
+
+ return dst;
+}
+
+static pdf_obj *
+filter_stream_decode (const char *filter_name, pdf_obj *src, pdf_obj *parm)
+{
+ pdf_obj *dec;
+ const char *stream_data;
+ size_t stream_length;
+
+ if (!filter_name)
+ return pdf_link_obj(src);
+
+ stream_data = pdf_stream_dataptr(src);
+ stream_length = pdf_stream_length(src);
+
+ if (!strcmp(filter_name, "ASCIIHexDecode")) {
+ dec = filter_stream_decode_ASCIIHexDecode(stream_data, stream_length);
+ } else if (!strcmp(filter_name, "ASCII85Decode")) {
+ dec = filter_stream_decode_ASCII85Decode(stream_data, stream_length);
+#if HAVE_ZLIB
+ } else if (!strcmp(filter_name, "FlateDecode")) {
+ struct decode_parms decode_parm;
+ if (parm)
+ filter_get_DecodeParms_FlateDecode(&decode_parm, parm);
+ dec = filter_stream_decode_FlateDecode(stream_data, stream_length, parm ? &decode_parm : NULL);
+#endif /* HAVE_ZLIB */
+ } else {
+ WARN("DecodeFilter \"%s\" not supported.", filter_name);
+ dec = NULL;
+ }
+
+ return dec;
+}
+
+int
+pdf_concat_stream (pdf_obj *dst, pdf_obj *src)
+{
+ pdf_obj *filtered;
+ pdf_obj *stream_dict;
+ pdf_obj *filter, *parms;
+ int error = 0;
+
+ if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src)) {
+ WARN("Passed invalid type in pdf_concat_stream().");
+ return -1;
+ }
+
+ stream_dict = pdf_stream_dict(src);
+
+ filter = pdf_lookup_dict(stream_dict, "Filter");
+ if (!filter) {
+ pdf_add_stream(dst, pdf_stream_dataptr(src), pdf_stream_length(src));
+ return 0;
+ }
+ if (pdf_lookup_dict(stream_dict, "DecodeParms")) {
+ /* Dictionary or array */
+ parms = pdf_deref_obj(pdf_lookup_dict(stream_dict, "DecodeParms"));
+ if (!parms) {
+ WARN("Failed to deref DeocdeParms...");
+ return -1;
+ } else if (!PDF_OBJ_ARRAYTYPE(parms) && !PDF_OBJ_DICTTYPE(parms)) {
+ WARN("PDF dict or array expected for DecodeParms...");
+ pdf_release_obj(parms);
+ return -1;
+ }
+ } else {
+ parms = NULL;
+ }
+ if (PDF_OBJ_ARRAYTYPE(filter)) {
+ int i, num;
+ pdf_obj *prev = NULL;
+
+ num = pdf_array_length(filter);
+ if (parms) {
+ if (!PDF_OBJ_ARRAYTYPE(parms) || pdf_array_length(parms) != num) {
+ WARN("Invalid DecodeParam object found.");
+ pdf_release_obj(parms);
+ return -1;
+ }
+ }
+ if (num == 0) {
+ filtered = pdf_link_obj(src);
+ } else {
+ filtered = NULL;
+ prev = pdf_link_obj(src);
+ for (i = 0; i < num && prev != NULL; i++) {
+ pdf_obj *tmp1, *tmp2;
+
+ tmp1 = pdf_deref_obj(pdf_get_array(filter, i));
+ if (parms) {
+ tmp2 = pdf_deref_obj(pdf_get_array(parms, i));
+ } else {
+ tmp2 = NULL;
+ }
+ if (PDF_OBJ_NAMETYPE(tmp1)) {
+ filtered = filter_stream_decode(pdf_name_value(tmp1), prev, tmp2);
+ } else if (PDF_OBJ_NULLTYPE(tmp1)) {
+ filtered = pdf_link_obj(prev);
+ } else {
+ WARN("Unexpected object found for /Filter...");
+ filtered = NULL;
+ }
+ if (prev)
+ pdf_release_obj(prev);
+ if (tmp1)
+ pdf_release_obj(tmp1);
+ if (tmp2)
+ pdf_release_obj(tmp2);
+ prev = filtered;
+ }
+ }
+ } else if (PDF_OBJ_NAMETYPE(filter)) {
+ filtered = filter_stream_decode(pdf_name_value(filter), src, parms);
+ } else {
+ WARN("Invalid value for /Filter found.");
+ filtered = NULL;
+ }
+ if (parms)
+ pdf_release_obj(parms);
+ if (filtered) {
+ pdf_add_stream(dst, pdf_stream_dataptr(filtered), pdf_stream_length(filtered));
+ pdf_release_obj(filtered);
+ error = 0;
+ } else {
+ error = -1;
+ }
+
+ return error;
+}
+
+static pdf_obj *
+pdf_stream_uncompress (pdf_obj *src) {
+ pdf_obj *dst = pdf_new_stream(0);
+
+ TYPECHECK(src, PDF_STREAM);
+
+ pdf_merge_dict(pdf_stream_dict(dst), pdf_stream_dict(src));
+ pdf_remove_dict(pdf_stream_dict(dst), "Length");
+ pdf_concat_stream(dst, src);
+
+ return dst;
+}
+
+#if 0
+void
+pdf_stream_set_flags (pdf_obj *stream, int flags)
+{
+ pdf_stream *data;
+
+ TYPECHECK(stream, PDF_STREAM);
+
+ data = stream->data;
+ data->_flags = flags;
+}
+
+int
+pdf_stream_get_flags (pdf_obj *stream)
+{
+ pdf_stream *data;
+
+ TYPECHECK(stream, PDF_STREAM);
+
+ data = stream->data;
+
+ return data->_flags;
+}
+#endif
+
+static void
+pdf_write_obj (pdf_out *p, pdf_obj *object)
+{
+ ASSERT(p);
+
+ if (object == NULL) {
+ write_null(p);
+ return;
+ }
+
+ if (INVALIDOBJ(object) || PDF_OBJ_UNDEFINED(object))
+ ERROR("pdf_write_obj: Invalid object, type = %d\n", object->type);
+
+ if (error_out)
+ fprintf(stderr, "{%d}", object->refcount);
+
+ switch (object->type) {
+ case PDF_BOOLEAN:
+ write_boolean(p, object->data);
+ break;
+ case PDF_NUMBER:
+ write_number (p, object->data);
+ break;
+ case PDF_STRING:
+ write_string (p, object->data);
+ break;
+ case PDF_NAME:
+ write_name(p, object->data);
+ break;
+ case PDF_ARRAY:
+ write_array(p, object->data);
+ break;
+ case PDF_DICT:
+ write_dict (p, object->data);
+ break;
+ case PDF_STREAM:
+ write_stream(p, object->data);
+ break;
+ case PDF_NULL:
+ write_null(p);
+ break;
+ case PDF_INDIRECT:
+ write_indirect(p, object->data);
+ break;
+ }
+}
+
+/* Write the object to the file */
+static void
+pdf_flush_obj (pdf_out *p, pdf_obj *object)
+{
+ size_t length;
+ char buf[64];
+
+ /*
+ * Record file position
+ */
+ add_xref_entry(p, object->label, 1,
+ p->output.file_position, object->generation);
+ length = sprintf(buf, "%u %hu obj\n", object->label, object->generation);
+ p->state.enc_mode =
+ (p->options.enable_encrypt && !(object->flags & OBJ_NO_ENCRYPT)) ? 1 : 0;
+ if (p->state.enc_mode) {
+ pdf_enc_set_label(p->sec_data, object->label);
+ pdf_enc_set_generation(p->sec_data, object->generation);
+ }
+ pdf_out_str(p, buf, length);
+ pdf_write_obj(p, object);
+ pdf_out_str(p, "\nendobj\n", 8);
+}
+
+static int
+pdf_add_objstm (pdf_out *p, pdf_obj *objstm, pdf_obj *object)
+{
+ int *data, pos;
+
+ TYPECHECK(objstm, PDF_STREAM);
+ ASSERT(p);
+
+ data = get_objstm_data(objstm);
+ pos = ++data[0];
+
+ data[2*pos] = object->label;
+ data[2*pos+1] = pdf_stream_length(objstm);
+
+ add_xref_entry(p, object->label, 2, objstm->label, pos-1);
+
+ /* redirect output into objstm */
+ p->output_stream = objstm;
+ p->state.enc_mode = 0;
+ pdf_write_obj(p, object);
+ pdf_out_char(p, '\n');
+ p->output_stream = NULL;
+
+ return pos;
+}
+
+static void
+release_objstm (pdf_obj *objstm)
+{
+ int *data = get_objstm_data(objstm);
+ int pos = data[0];
+ pdf_obj *dict;
+ pdf_stream *stream;
+ unsigned char *old_buf;
+ size_t old_length;
+ stream = (pdf_stream *) objstm->data;
+
+ /* Precede stream data by offset table */
+ old_buf = stream->stream;
+ old_length = stream->stream_length;
+ /* Reserve 22 bytes for each entry (two 10 digit numbers plus two spaces) */
+ stream->stream = NEW(old_length + 22*pos, unsigned char);
+ stream->stream_length = 0;
+
+ {
+ int i = 2*pos, *val = data+2;
+ while (i--) {
+ char buf[32];
+ size_t length = sprintf(buf, "%d ", *(val++));
+ pdf_add_stream(objstm, buf, length);
+ }
+ }
+
+ dict = pdf_stream_dict(objstm);
+ pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("ObjStm"));
+ pdf_add_dict(dict, pdf_new_name("N"), pdf_new_number(pos));
+ pdf_add_dict(dict, pdf_new_name("First"), pdf_new_number(stream->stream_length));
+
+ pdf_add_stream(objstm, old_buf, old_length);
+ RELEASE(old_buf);
+ pdf_release_obj(objstm);
+}
+
+#define is_free(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8))))
+
+void
+pdf_release_obj (pdf_obj *object)
+{
+ pdf_out *p = current_output();
+
+ if (object == NULL)
+ return;
+ if (INVALIDOBJ(object) || object->refcount <= 0) {
+ MESG("\npdf_release_obj: object=%p, type=%d, refcount=%d\n",
+ object, object->type, object->refcount);
+ error_out = 1;
+ pdf_write_obj(p, object);
+ ERROR("pdf_release_obj: Called with invalid object.");
+ error_out = 0;
+ }
+ object->refcount -= 1;
+ if (object->refcount == 0) {
+#if defined(PDFOBJ_DEBUG)
+ bucket[object->obj_id] = NULL;
+#endif
+ /*
+ * Nothing is using this object so it's okay to remove it.
+ * Nonzero "label" means object needs to be written before it's destroyed.
+ */
+ if (object->label) {
+ p->free_list[object->label/8] |= (1 << (7-(object->label % 8)));
+ if (p->output.file != NULL) {
+ if (!p->options.use_objstm || object->flags & OBJ_NO_OBJSTM ||
+ (p->options.enable_encrypt && (object->flags & OBJ_NO_ENCRYPT)) ||
+ object->generation) {
+ pdf_flush_obj(p, object);
+ } else {
+ if (!p->current_objstm) {
+ int *data = NEW(2*OBJSTM_MAX_OBJS+2, int);
+ data[0] = data[1] = 0;
+ p->current_objstm = pdf_new_stream(STREAM_COMPRESS);
+ set_objstm_data(p->current_objstm, data);
+ pdf_label_obj(p, p->current_objstm);
+ }
+ if (pdf_add_objstm(p, p->current_objstm, object) == OBJSTM_MAX_OBJS) {
+ release_objstm(p->current_objstm);
+ p->current_objstm = NULL;
+ }
+ }
+ }
+ }
+ switch (object->type) {
+ case PDF_BOOLEAN:
+ release_boolean(object->data);
+ break;
+ case PDF_NULL:
+ break;
+ case PDF_NUMBER:
+ release_number(object->data);
+ break;
+ case PDF_STRING:
+ release_string(object->data);
+ break;
+ case PDF_NAME:
+ release_name(object->data);
+ break;
+ case PDF_ARRAY:
+ release_array(object->data);
+ break;
+ case PDF_DICT:
+ release_dict(object->data);
+ break;
+ case PDF_STREAM:
+ release_stream(object->data);
+ break;
+ case PDF_INDIRECT:
+ release_indirect(object->data);
+ break;
+ }
+ /* This might help detect freeing already freed objects */
+ object->type = -1;
+ object->data = NULL;
+ RELEASE(object);
+ }
+}
+
+/* Reading external PDF files
+ *
+ */
+static int
+backup_line (FILE *pdf_input_file)
+{
+ int ch = -1;
+
+ /*
+ * Note: this code should work even if \r\n is eol. It could fail on a
+ * machine where \n is eol and there is a \r in the stream --- Highly
+ * unlikely in the last few bytes where this is likely to be used.
+ */
+ if (tell_position(pdf_input_file) > 1)
+ do {
+ seek_relative (pdf_input_file, -2);
+ } while (tell_position(pdf_input_file) > 0 &&
+ (ch = fgetc(pdf_input_file)) >= 0 &&
+ (ch != '\n' && ch != '\r' ));
+ if (ch < 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+find_xref (FILE *pdf_input_file)
+{
+ size_t len, xref_pos = 0;
+ int tries = 10;
+
+ do {
+ size_t currentpos;
+
+ if (!backup_line(pdf_input_file)) {
+ tries = 0;
+ break;
+ }
+ currentpos = tell_position(pdf_input_file);
+ fread(work_buffer, sizeof(char), strlen("startxref"), pdf_input_file);
+ seek_absolute(pdf_input_file, currentpos);
+ tries--;
+ } while (tries > 0 &&
+ strncmp(work_buffer, "startxref", strlen("startxref")));
+ if (tries <= 0)
+ return 0;
+
+ /* Skip rest of this line */
+ mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file);
+ /* Next line of input file should contain actual xref location */
+ len = mfreadln(work_buffer, WORK_BUFFER_SIZE, pdf_input_file);
+ if (len <= 0)
+ WARN("Reading xref location data failed... Not a PDF file?");
+ else {
+ const char *start, *end;
+ char *number;
+
+ start = work_buffer;
+ end = start + len;
+ skip_white(&start, end);
+ number = parse_number(&start, end);
+ xref_pos = (int) atof(number);
+ RELEASE(number);
+ }
+
+ return xref_pos;
+}
+
+/*
+ * This routine must be called with the file pointer located
+ * at the start of the trailer.
+ */
+static pdf_obj *
+parse_trailer (pdf_file *pf)
+{
+ pdf_obj *result;
+ /*
+ * Fill work_buffer and hope trailer fits. This should
+ * be made a bit more robust sometime.
+ */
+ if (fread(work_buffer, sizeof(char),
+ WORK_BUFFER_SIZE, pf->file) == 0 ||
+ strncmp(work_buffer, "trailer", strlen("trailer"))) {
+ WARN("No trailer. Are you sure this is a PDF file?");
+ WARN("buffer:\n->%s<-\n", work_buffer);
+ result = NULL;
+ } else {
+ const char *p = work_buffer + strlen("trailer");
+ skip_white(&p, work_buffer + WORK_BUFFER_SIZE);
+ result = parse_pdf_dict(&p, work_buffer + WORK_BUFFER_SIZE, pf);
+ }
+
+ return result;
+}
+
+/*
+ * This routine tries to estimate an upper bound for character position
+ * of the end of the object, so it knows how big the buffer must be.
+ * The parsing routines require that the entire object be read into
+ * memory. It would be a major pain to rewrite them. The worst case
+ * is that an object before an xref table will grab the whole table
+ * :-(
+ */
+static int
+next_object_offset (pdf_file *pf, uint32_t obj_num)
+{
+ uint32_t next = pf->file_size; /* Worst case */
+ size_t i;
+ uint32_t curr;
+
+ curr = pf->xref_table[obj_num].field2;
+ /* Check all other type 1 objects to find next one */
+ for (i = 0; i < pf->num_obj; i++) {
+ if (pf->xref_table[i].type == 1 &&
+ pf->xref_table[i].field2 > curr &&
+ pf->xref_table[i].field2 < next)
+ next = pf->xref_table[i].field2;
+ }
+
+ return next;
+}
+
+#define checklabel(pf, n, g) ((n) > 0 && (n) < (pf)->num_obj && ( \
+ ((pf)->xref_table[(n)].type == 1 && (pf)->xref_table[(n)].field3 == (g)) || \
+ ((pf)->xref_table[(n)].type == 2 && !(g))))
+
+pdf_obj *
+pdf_new_indirect (pdf_file *pf, uint32_t obj_num, uint16_t obj_gen)
+{
+ pdf_obj *result;
+ pdf_indirect *indirect;
+
+ indirect = NEW(1, pdf_indirect);
+ indirect->pf = pf;
+ indirect->obj = NULL;
+ indirect->label = obj_num;
+ indirect->generation = obj_gen;
+
+ result = pdf_new_obj(PDF_INDIRECT);
+ result->data = indirect;
+
+ return result;
+}
+
+static pdf_obj *
+pdf_read_object (uint32_t obj_num, uint16_t obj_gen, pdf_file *pf, size_t offset, size_t limit)
+{
+ pdf_obj *result = NULL;
+ size_t length;
+ char *buffer;
+ const char *p, *endptr;
+
+ length = limit - offset;
+
+ if (length <= 0)
+ return NULL;
+
+ buffer = NEW(length + 1, char);
+
+ seek_absolute(pf->file, offset);
+ fread(buffer, sizeof(char), length, pf->file);
+
+ p = buffer;
+ endptr = p + length;
+
+ /* Check for obj_num and obj_gen */
+ {
+ const char *q = p; /* <== p */
+ char *sp;
+ uint32_t n, g;
+
+ skip_white(&q, endptr);
+ sp = parse_unsigned(&q, endptr);
+ if (!sp) {
+ RELEASE(buffer);
+ return NULL;
+ }
+ n = strtoul(sp, NULL, 10);
+ RELEASE(sp);
+
+ skip_white(&q, endptr);
+ sp = parse_unsigned(&q, endptr);
+ if (!sp) {
+ RELEASE(buffer);
+ return NULL;
+ }
+ g = strtoul(sp, NULL, 10);
+ RELEASE(sp);
+
+ if (obj_num && (n != obj_num || g != obj_gen)) {
+ RELEASE(buffer);
+ return NULL;
+ }
+
+ p = q; /* ==> p */
+ }
+
+
+ skip_white(&p, endptr);
+ if (memcmp(p, "obj", strlen("obj"))) {
+ WARN("Didn't find \"obj\".");
+ RELEASE(buffer);
+ return NULL;
+ }
+ p += strlen("obj");
+
+ result = parse_pdf_object(&p, endptr, pf);
+
+ skip_white(&p, endptr);
+ if (memcmp(p, "endobj", strlen("endobj"))) {
+ WARN("Didn't find \"endobj\".");
+ if (result)
+ pdf_release_obj(result);
+ result = NULL;
+ }
+ RELEASE(buffer);
+
+ return result;
+}
+
+static pdf_obj *
+read_objstm (pdf_file *pf, uint32_t num)
+{
+ size_t offset = pf->xref_table[num].field2;
+ uint16_t gen = pf->xref_table[num].field3;
+ size_t limit = next_object_offset(pf, num);
+ int n, first, *header = NULL;
+ char *data = NULL, *q;
+ const char *p, *endptr;
+ int i;
+ pdf_obj *objstm, *dict, *type, *n_obj, *first_obj;
+
+ objstm = pdf_read_object(num, gen, pf, offset, limit);
+
+ if (!PDF_OBJ_STREAMTYPE(objstm))
+ goto error;
+
+ {
+ pdf_obj *tmp = pdf_stream_uncompress(objstm);
+ if (!tmp)
+ goto error;
+ pdf_release_obj(objstm);
+ objstm = tmp;
+ }
+
+ dict = pdf_stream_dict(objstm);
+
+ type = pdf_lookup_dict(dict, "Type");
+ if (!PDF_OBJ_NAMETYPE(type) ||
+ strcmp(pdf_name_value(type), "ObjStm"))
+ goto error;
+
+ n_obj = pdf_lookup_dict(dict, "N");
+ if (!PDF_OBJ_NUMBERTYPE(n_obj))
+ goto error;
+ n = (int) pdf_number_value(n_obj);
+
+ first_obj = pdf_lookup_dict(dict, "First");
+ if (!PDF_OBJ_NUMBERTYPE(first_obj))
+ goto error;
+ first = (int) pdf_number_value(first_obj);
+ /* reject object streams without object data */
+ if (first >= pdf_stream_length(objstm))
+ goto error;
+
+ header = NEW(2*(n+1), int);
+ set_objstm_data(objstm, header);
+ *(header++) = n;
+ *(header++) = first;
+
+ /* avoid parsing beyond offset table */
+ data = NEW(first + 1, char);
+ memcpy(data, pdf_stream_dataptr(objstm), first);
+ data[first] = 0;
+
+ p = data;
+ endptr = p + first;
+ i = 2*n;
+ while (i--) {
+ *(header++) = strtoul(p, &q, 10);
+ if (q == p)
+ goto error;
+ p = q;
+ }
+
+ /* Any garbage after last entry? */
+ skip_white(&p, endptr);
+ if (p != endptr)
+ goto error;
+ RELEASE(data);
+
+ return pf->xref_table[num].direct = objstm;
+
+ error:
+ WARN("Cannot parse object stream.");
+ if (data)
+ RELEASE(data);
+ if (objstm)
+ pdf_release_obj(objstm);
+ return NULL;
+}
+
+/* Label without corresponding object definition are replaced by the
+ * null object, as required by the PDF spec. This is important to parse
+ * several cross-reference sections.
+ */
+static pdf_obj *
+pdf_get_object (pdf_file *pf, uint32_t obj_num, uint16_t obj_gen)
+{
+ pdf_obj *result;
+
+ if (!checklabel(pf, obj_num, obj_gen)) {
+ WARN("Trying to read nonexistent or deleted object: %lu %u",
+ obj_num, obj_gen);
+ return pdf_new_null();
+ }
+
+ if ((result = pf->xref_table[obj_num].direct)) {
+ return pdf_link_obj(result);
+ }
+
+ if (pf->xref_table[obj_num].type == 1) {
+ /* type == 1 */
+ uint32_t offset;
+ size_t limit;
+ offset = pf->xref_table[obj_num].field2;
+ limit = next_object_offset(pf, obj_num);
+ result = pdf_read_object(obj_num, obj_gen, pf, offset, limit);
+ } else {
+ /* type == 2 */
+ uint32_t objstm_num = pf->xref_table[obj_num].field2;
+ uint16_t index = pf->xref_table[obj_num].field3;
+ pdf_obj *objstm;
+ int *data, n, first, length;
+ const char *p, *q;
+
+ if (objstm_num >= pf->num_obj ||
+ pf->xref_table[objstm_num].type != 1 ||
+ !((objstm = pf->xref_table[objstm_num].direct) ||
+ (objstm = read_objstm(pf, objstm_num))))
+ goto error;
+
+ data = get_objstm_data(objstm);
+ n = *(data++);
+ first = *(data++);
+
+ if (index >= n || data[2*index] != obj_num)
+ goto error;
+
+ length = pdf_stream_length(objstm);
+ p = (const char *) pdf_stream_dataptr(objstm) + first + data[2*index+1];
+ q = p + (index == n-1 ? length : first+data[2*index+3]);
+ result = parse_pdf_object(&p, q, pf);
+ if (!result)
+ goto error;
+ }
+
+ /* Make sure the caller doesn't free this object */
+ pf->xref_table[obj_num].direct = pdf_link_obj(result);
+
+ return result;
+
+ error:
+ WARN("Could not read object from object stream.");
+ return pdf_new_null();
+}
+
+#define OBJ_FILE(o) (((pdf_indirect *)((o)->data))->pf)
+#define OBJ_OBJ(o) (((pdf_indirect *)((o)->data))->obj)
+#define OBJ_NUM(o) (((pdf_indirect *)((o)->data))->label)
+#define OBJ_GEN(o) (((pdf_indirect *)((o)->data))->generation)
+
+static pdf_obj *
+pdf_new_ref (pdf_out *p, pdf_obj *object)
+{
+ pdf_obj *result;
+
+ ASSERT(p);
+
+ if (object->label == 0) {
+ pdf_label_obj(p, object);
+ }
+ result = pdf_new_indirect(NULL, object->label, object->generation);
+ OBJ_OBJ(result) = object;
+ return result;
+}
+
+/* pdf_deref_obj always returns a link instead of the original */
+/* It never return the null object, but the NULL pointer instead */
+pdf_obj *
+pdf_deref_obj (pdf_obj *obj)
+{
+ int count = PDF_OBJ_MAX_DEPTH;
+
+ if (obj)
+ obj = pdf_link_obj(obj);
+
+ while (PDF_OBJ_INDIRECTTYPE(obj) && --count) {
+ pdf_file *pf = OBJ_FILE(obj);
+ if (pf) {
+ uint32_t obj_num = OBJ_NUM(obj);
+ uint16_t obj_gen = OBJ_GEN(obj);
+ pdf_release_obj(obj);
+ obj = pdf_get_object(pf, obj_num, obj_gen);
+ } else {
+ pdf_out *p = current_output();
+ pdf_indirect *data = obj->data;
+
+ if ((p->free_list[data->label/8] & (1 << (7-((data->label) % 8))))) {
+ pdf_release_obj(obj);
+ return NULL;
+ } else {
+ pdf_obj *next_obj = OBJ_OBJ(obj);
+ if (!next_obj) {
+ ERROR("Undefined object reference");
+ }
+ pdf_release_obj(obj);
+ obj = pdf_link_obj(next_obj);
+ }
+ }
+ }
+
+ if (!count)
+ ERROR("Loop in object hierarchy detected. Broken PDF file?");
+
+ if (PDF_OBJ_NULLTYPE(obj)) {
+ pdf_release_obj(obj);
+ return NULL;
+ } else
+ return obj;
+}
+
+static void
+extend_xref (pdf_file *pf, size_t new_size)
+{
+ size_t i;
+
+ pf->xref_table = RENEW(pf->xref_table, new_size, xref_entry);
+ for (i = pf->num_obj; i < new_size; i++) {
+ pf->xref_table[i].direct = NULL;
+ pf->xref_table[i].indirect = NULL;
+ pf->xref_table[i].type = 0;
+ pf->xref_table[i].field3 = 0;
+ pf->xref_table[i].field2 = 0L;
+ }
+ pf->num_obj = new_size;
+}
+
+/* Returns < 0 for error, 1 for success, and 0 when xref stream found. */
+static int
+parse_xref_table (pdf_file *pf, size_t xref_pos)
+{
+ FILE *pdf_input_file = pf->file;
+ const char *p, *endptr;
+ char buf[256]; /* See, PDF ref. v.1.7, p.91 for "255+1" here. */
+ size_t len;
+
+ /*
+ * This routine reads one xref segment. It may be called multiple times
+ * on the same file. xref tables sometimes come in pieces.
+ */
+ seek_absolute(pf->file, xref_pos);
+ len = mfreadln(buf, 255, pdf_input_file);
+ /* We should have already checked that "startxref" section exists.
+ * So, EOF here (len = -1) is impossible. We don't treat too long line
+ * case seriously.
+ */
+ if (len < 0) {
+ WARN("Something went wrong while reading xref table...giving up.");
+ return -1;
+ }
+ p = buf;
+ endptr = buf + len;
+ /* No skip_white() here. There should not be any white-spaces here. */
+ if (memcmp(p, "xref", strlen("xref"))) {
+ /* Might be an xref stream and not an xref table */
+ return 0;
+ }
+ p += strlen("xref");
+ skip_white(&p, endptr);
+ if (p != endptr) {
+ WARN("Garbage after \"xref\" keyword found.");
+ return -1;
+ }
+
+ /* Next line in file has first item and size of table */
+ for (;;) {
+ char flag;
+ size_t current_pos, size, offset;
+ int i;
+ uint32_t first, obj_gen;
+
+ current_pos = tell_position(pdf_input_file);
+ len = mfreadln(buf, 255, pdf_input_file);
+ if (len == 0) /* empty line... just skip. */
+ continue;
+ else if (len < 0) {
+ WARN("Reading a line failed in xref table.");
+ return -1;
+ }
+
+ p = buf;
+ endptr = buf + len;
+ skip_white(&p, endptr);
+ if (p == endptr) { /* Only white-spaces and/or comment found. */
+ continue;
+ } else if (!strncmp(p, "trailer", strlen ("trailer"))) {
+ /*
+ * Backup... This is ugly, but it seems like the safest thing to
+ * do. It is possible the trailer dictionary starts on the same
+ * logical line as the word trailer. In that case, the mfgets
+ * call might have started to read the trailer dictionary and
+ * parse_trailer would fail.
+ */
+ current_pos += p - buf; /* Jump to the beginning of "trailer" keyword. */
+ seek_absolute(pdf_input_file, current_pos);
+ break;
+ }
+ /* Line containing something other than white-space characters found.
+ *
+ * Start reading xref subsection
+ *
+ * This section just reads two nusigned integers, namely, the object number
+ * of first object and the size of the xref subsection. PDF reference says
+ * that only "a space" is allowed between those two numbers but we allow
+ * more white-space characters.
+ */
+ {
+ char *q;
+
+ /* Object number of the first object whithin this xref subsection. */
+ q = parse_unsigned(&p, endptr);
+ if (!q) {
+ WARN("An unsigned integer expected but could not find. (xref)");
+ return -1;
+ }
+ first = atoi(q);
+ RELEASE(q);
+ skip_white(&p, endptr);
+
+ /* Nnumber of objects in this xref subsection. */
+ q = parse_unsigned(&p, endptr);
+ if (!q) {
+ WARN("An unsigned integer expected but could not find. (xref)");
+ return -1;
+ }
+ size = atoi(q);
+ RELEASE(q);
+ skip_white(&p, endptr);
+
+ /* Check for unrecognized tokens */
+ if (p != endptr) {
+ WARN("Unexpected token found in xref table.");
+ return -1;
+ }
+ }
+
+ /* The first line of a xref subsection OK. */
+ if (pf->num_obj < first + size) {
+ extend_xref(pf, first + size);
+ }
+
+ /* Start parsing xref subsection body... */
+ for (i = first; i < first + size; ) {
+ /* PDF spec. requires each xref subsection lines being exactly 20 bytes
+ * long [including end-of-line marker(s)], offset 10 decimal digits,
+ * generation number being 5 decimal digits, and each entries delimitted
+ * by "a single space". However, we don't srtictly follow this rule:
+ * More than one "white-spaces" allowed, can be ended with a comment,
+ * and so on.
+ */
+ len = mfreadln(buf, 255, pdf_input_file);
+ if (len == 0) /* empty line...just skip. */
+ continue;
+ else if (len < 0) {
+ WARN("Something went wrong while reading xref subsection...");
+ return -1;
+ }
+ p = buf;
+ endptr = buf + len;
+ skip_white(&p, endptr);
+ if (p == endptr) /* Only white-spaces and/or comment. */
+ continue;
+
+ /*
+ * Don't overwrite positions that have already been set by a
+ * modified xref table. We are working our way backwards
+ * through the reference table, so we only set "position"
+ * if it hasn't been set yet.
+ */
+ offset = 0UL; obj_gen = 0; flag = 0;
+ {
+ char *q;
+
+ /* Offset value -- 10 digits (0 padded) */
+ q = parse_unsigned(&p, endptr);
+ if (!q) {
+ WARN("An unsigned integer expected but could not find. (xref)");
+ return -1;
+ } else if (strlen(q) != 10) { /* exactly 10 digits */
+ WARN(("Offset must be a 10 digits number. (xref)"));
+ RELEASE(q);
+ return -1;
+ }
+ /* FIXME: Possible overflow here. Consider using strtoll(). */
+ offset = atoi(q);
+ RELEASE(q);
+ skip_white(&p, endptr);
+
+ /* Generation number -- 5 digits (0 padded) */
+ q = parse_unsigned(&p, endptr);
+ if (!q) {
+ WARN("An unsigned integer expected but could not find. (xref)");
+ return -1;
+ } else if (strlen(q) != 5) { /* exactly 5 digits */
+ WARN(("Expecting a 5 digits number. (xref)"));
+ RELEASE(q);
+ return -1;
+ }
+ obj_gen = atoi(q);
+ RELEASE(q);
+ skip_white(&p, endptr);
+ }
+ if (p == endptr) {
+ WARN("Unexpected EOL reached while reading a xref subsection entry.");
+ return -1;
+ }
+
+ /* Flag -- a char */
+ flag = *p; p++;
+ skip_white(&p, endptr);
+ if (p < endptr) {
+ WARN("Garbage in xref subsection entry found...");
+ return -1;
+ } else if (((flag != 'n' && flag != 'f') ||
+ (flag == 'n' &&
+ (offset >= pf->file_size || (offset > 0 && offset < 4))))) {
+ WARN("Invalid xref table entry [%lu]. PDF file is corrupt...", i);
+ return -1;
+ }
+
+ /* Everything seems to be OK. */
+ if (!pf->xref_table[i].field2) {
+ pf->xref_table[i].type = (flag == 'n');
+ pf->xref_table[i].field2 = offset;
+ pf->xref_table[i].field3 = obj_gen;
+ }
+ i++;
+ }
+ }
+
+ return 1;
+}
+
+static uint32_t
+parse_xrefstm_field (const char **p, size_t length, uint32_t def)
+{
+ uint32_t val = 0;
+
+ if (!length)
+ return def;
+
+ while (length--) {
+ val <<= 8;
+ val |= (unsigned char) *((*p)++);
+ }
+
+ return val;
+}
+
+static int
+parse_xrefstm_subsec (pdf_file *pf,
+ const char **p, size_t *length,
+ int *W, int wsum, int first, int size)
+{
+ xref_entry *e;
+
+ if ((*length -= wsum*size) < 0)
+ return -1;
+
+ if (pf->num_obj < first+size)
+ extend_xref(pf, first+size); /* TODO: change! why? */
+
+ e = pf->xref_table + first;
+ while (size--) {
+ uint8_t type;
+ uint32_t field2;
+ uint16_t field3;
+
+ type = (unsigned char) parse_xrefstm_field(p, W[0], 1);
+ if (type > 2)
+ WARN("Unknown cross-reference stream entry type.");
+#if 0
+ /* Not sure */
+ else if (!W[1] || (type != 1 && !W[2]))
+ return -1;
+#endif
+
+ field2 = (uint32_t) parse_xrefstm_field(p, W[1], 0);
+ field3 = (uint16_t) parse_xrefstm_field(p, W[2], 0);
+
+ if (!e->field2) {
+ e->type = type;
+ e->field2 = field2;
+ e->field3 = field3;
+ }
+ e++;
+ }
+
+ return 0;
+}
+
+static int
+parse_xref_stream (pdf_file *pf, size_t xref_pos, pdf_obj **trailer)
+{
+ pdf_obj *xrefstm, *size_obj, *W_obj, *index_obj;
+ uint32_t size;
+ size_t length;
+ int W[3], i, wsum = 0;
+ const char *p;
+
+ xrefstm = pdf_read_object(0, 0, pf, xref_pos, pf->file_size);
+ if (!PDF_OBJ_STREAMTYPE(xrefstm))
+ goto error;
+
+ {
+ pdf_obj *tmp = pdf_stream_uncompress(xrefstm);
+ if (!tmp)
+ goto error;
+ pdf_release_obj(xrefstm);
+ xrefstm = tmp;
+ }
+
+ *trailer = pdf_link_obj(pdf_stream_dict(xrefstm));
+
+ size_obj = pdf_lookup_dict(*trailer, "Size");
+ if (!PDF_OBJ_NUMBERTYPE(size_obj))
+ goto error;
+ size = (uint32_t) pdf_number_value(size_obj);
+
+ length = pdf_stream_length(xrefstm);
+
+ W_obj = pdf_lookup_dict(*trailer, "W");
+ if (!PDF_OBJ_ARRAYTYPE(W_obj) || pdf_array_length(W_obj) != 3)
+ goto error;
+
+ for (i = 0; i < 3; i++) {
+ pdf_obj *tmp = pdf_get_array(W_obj, i);
+ if (!PDF_OBJ_NUMBERTYPE(tmp))
+ goto error;
+ wsum += (W[i] = (int) pdf_number_value(tmp));
+ }
+
+ p = pdf_stream_dataptr(xrefstm);
+
+ index_obj = pdf_lookup_dict(*trailer, "Index");
+ if (index_obj) {
+ size_t index_len;
+ if (!PDF_OBJ_ARRAYTYPE(index_obj) ||
+ ((index_len = pdf_array_length(index_obj)) % 2 ))
+ goto error;
+
+ i = 0;
+ while (i < index_len) {
+ pdf_obj *first = pdf_get_array(index_obj, i++);
+ size_obj = pdf_get_array(index_obj, i++);
+ if (!PDF_OBJ_NUMBERTYPE(first) || !PDF_OBJ_NUMBERTYPE(size_obj) ||
+ parse_xrefstm_subsec(pf, &p, &length, W, wsum,
+ (int) pdf_number_value(first), (int) pdf_number_value(size_obj)))
+ goto error;
+ }
+ } else if (parse_xrefstm_subsec(pf, &p, &length, W, wsum, 0, size))
+ goto error;
+
+ if (length)
+ WARN("Garbage in xref stream.");
+
+ pdf_release_obj(xrefstm);
+
+ return 1;
+
+ error:
+ WARN("Cannot parse cross-reference stream.");
+ if (xrefstm)
+ pdf_release_obj(xrefstm);
+ if (*trailer) {
+ pdf_release_obj(*trailer);
+ *trailer = NULL;
+ }
+ return 0;
+}
+
+/* TODO: parse Version entry */
+static pdf_obj *
+read_xref (pdf_file *pf)
+{
+ pdf_obj *trailer = NULL, *main_trailer = NULL;
+ size_t xref_pos;
+
+ if (!(xref_pos = find_xref(pf->file)))
+ goto error;
+
+ while (xref_pos) {
+ pdf_obj *prev;
+
+ int res = parse_xref_table(pf, xref_pos);
+ if (res > 0) {
+ /* cross-reference table */
+ pdf_obj *xrefstm;
+
+ if (!(trailer = parse_trailer(pf)))
+ goto error;
+
+ if (!main_trailer)
+ main_trailer = pdf_link_obj(trailer);
+
+ if ((xrefstm = pdf_lookup_dict(trailer, "XRefStm"))) {
+ pdf_obj *new_trailer = NULL;
+ if (PDF_OBJ_NUMBERTYPE(xrefstm) &&
+ parse_xref_stream(pf, (int) pdf_number_value(xrefstm),
+ &new_trailer))
+ pdf_release_obj(new_trailer);
+ else
+ WARN("Skipping hybrid reference section.");
+ /* Many PDF 1.5 xref streams use DecodeParms, which we cannot
+ * parse. This way we can use at least xref tables in hybrid
+ * documents. Or should we better stop parsing the file?
+ */
+ }
+
+ } else if (!res && parse_xref_stream(pf, xref_pos, &trailer)) {
+ /* cross-reference stream */
+ if (!main_trailer)
+ main_trailer = pdf_link_obj(trailer);
+ } else
+ goto error;
+
+ if ((prev = pdf_lookup_dict(trailer, "Prev"))) {
+ if (PDF_OBJ_NUMBERTYPE(prev))
+ xref_pos = (size_t) pdf_number_value(prev);
+ else
+ goto error;
+ } else
+ xref_pos = 0;
+
+ pdf_release_obj(trailer);
+ }
+
+#if 0
+ if (!pdf_lookup_dict(main_trailer, "Root")) {
+ WARN("Trailer doesn't have catalog. Is this a correct PDF file?");
+ goto error;
+ }
+#endif
+
+ return main_trailer;
+
+ error:
+ WARN("Error while parsing PDF file.");
+ if (trailer)
+ pdf_release_obj(trailer);
+ if (main_trailer)
+ pdf_release_obj(main_trailer);
+ return NULL;
+}
+
+static struct ht_table *pdf_files = NULL;
+
+static pdf_file *
+pdf_file_new (FILE *file)
+{
+ pdf_file *pf;
+ ASSERT(file);
+ pf = NEW(1, pdf_file);
+ pf->file = file;
+ pf->trailer = NULL;
+ pf->xref_table = NULL;
+ pf->catalog = NULL;
+ pf->num_obj = 0;
+ pf->version = 0;
+
+ seek_end(file);
+ pf->file_size = tell_position(file);
+
+ return pf;
+}
+
+static void
+pdf_file_free (pdf_file *pf)
+{
+ size_t i;
+
+ if (!pf) {
+ return;
+ }
+
+ for (i = 0; i < pf->num_obj; i++) {
+ if (pf->xref_table[i].direct)
+ pdf_release_obj(pf->xref_table[i].direct);
+ if (pf->xref_table[i].indirect)
+ pdf_release_obj(pf->xref_table[i].indirect);
+ }
+
+ RELEASE(pf->xref_table);
+ if (pf->trailer)
+ pdf_release_obj(pf->trailer);
+ if (pf->catalog)
+ pdf_release_obj(pf->catalog);
+
+ RELEASE(pf);
+}
+
+void
+pdf_files_init (void)
+{
+ pdf_files = NEW(1, struct ht_table);
+ ht_init_table(pdf_files, (void (*)(void *)) pdf_file_free);
+}
+
+int
+pdf_file_get_version (pdf_file *pf)
+{
+ ASSERT(pf);
+ return pf->version;
+}
+
+pdf_obj *
+pdf_file_get_trailer (pdf_file *pf)
+{
+ ASSERT(pf);
+ return pdf_link_obj(pf->trailer);
+}
+
+/* FIXME:
+ * pdf_file_get_trailer() does pdf_link_obj() but
+ * pdf_file_get_catalog() does not. Why?
+ */
+pdf_obj *
+pdf_file_get_catalog (pdf_file *pf)
+{
+ ASSERT(pf);
+ return pf->catalog;
+}
+
+pdf_file *
+pdf_open (const char *ident, FILE *file)
+{
+ pdf_out *p = current_output();
+ pdf_file *pf = NULL;
+
+ ASSERT(pdf_files);
+
+ if (ident)
+ pf = (pdf_file *) ht_lookup_table(pdf_files, ident, strlen(ident));
+
+ if (pf) {
+ pf->file = file;
+ } else {
+ pdf_obj *new_version;
+ int version = check_for_pdf_version(file);
+
+ if (!dpx_conf.is_xbb) {
+ int ver_major, ver_minor;
+
+ ver_major = version / 10;
+ ver_minor = version % 10;
+
+ if (version < 10)
+ WARN("Unrecognized PDF version specified for input PDF file: %d.%d",
+ ver_major, ver_minor);
+ else if (pdf_check_version(ver_major, ver_minor) < 0) {
+ WARN("Trying to include PDF file with version (%d.%d), which is " \
+ "newer than current output PDF setting (%d.%d).",
+ ver_major, ver_minor, p->version.major, p->version.minor);
+ }
+ }
+ pf = pdf_file_new(file);
+ pf->version = version;
+
+ if (!(pf->trailer = read_xref(pf)))
+ goto error;
+
+ if (pdf_lookup_dict(pf->trailer, "Encrypt")) {
+ WARN("PDF document is encrypted.");
+ goto error;
+ }
+
+ pf->catalog = pdf_deref_obj(pdf_lookup_dict(pf->trailer, "Root"));
+ if (!PDF_OBJ_DICTTYPE(pf->catalog)) {
+ WARN("Cannot read PDF document catalog. Broken PDF file?");
+ goto error;
+ }
+
+ new_version = pdf_deref_obj(pdf_lookup_dict(pf->catalog, "Version"));
+ if (new_version) {
+ unsigned int major, minor;
+
+ if (!PDF_OBJ_NAMETYPE(new_version) ||
+ sscanf(pdf_name_value(new_version), "%u.%u", &major, &minor) != 2) {
+ pdf_release_obj(new_version);
+ WARN("Illegal Version entry in document catalog. Broken PDF file?");
+ goto error;
+ }
+
+ if (pf->version < major*10+minor)
+ pf->version = major*10+minor;
+
+ pdf_release_obj(new_version);
+ }
+
+ if (ident)
+ ht_append_table(pdf_files, ident, strlen(ident), pf);
+ }
+
+ return pf;
+
+ error:
+ pdf_file_free(pf);
+ return NULL;
+}
+
+void
+pdf_close (pdf_file *pf)
+{
+ if (pf)
+ pf->file = NULL;
+}
+
+void
+pdf_files_close (void)
+{
+ ASSERT(pdf_files);
+ ht_clear_table(pdf_files);
+ RELEASE(pdf_files);
+}
+
+static int
+check_for_pdf_version (FILE *file)
+{
+ unsigned int major, minor;
+
+ rewind(file);
+
+ return (ungetc(fgetc(file), file) == '%' &&
+ fscanf(file, "%%PDF-%u.%u", &major, &minor) == 2) ? (major*10+minor) : -1;
+}
+
+int
+check_for_pdf (FILE *file)
+{
+ int version = check_for_pdf_version(file);
+
+ if (version < 0) /* not a PDF file */
+ return 0;
+
+ if (version <= pdf_get_version())
+ return 1;
+
+ return 1;
+}
+
+static inline int
+import_dict (pdf_obj *key, pdf_obj *value, void *pdata)
+{
+ pdf_obj *copy;
+ pdf_obj *tmp;
+
+ copy = (pdf_obj *) pdata;
+
+ tmp = pdf_import_object(value);
+ if (!tmp) {
+ return -1;
+ }
+ pdf_add_dict(copy, pdf_link_obj(key), tmp);
+
+ return 0;
+}
+
+static pdf_obj *
+pdf_import_indirect (pdf_obj *object)
+{
+ pdf_out *p = current_output();
+ pdf_file *pf = OBJ_FILE(object);
+ uint32_t obj_num = OBJ_NUM(object);
+ uint16_t obj_gen = OBJ_GEN(object);
+ pdf_obj *ref;
+
+ ASSERT(pf);
+
+ if (!checklabel(pf, obj_num, obj_gen)) {
+ WARN("Can't resolve object: %lu %u", obj_num, obj_gen);
+ return pdf_new_null();
+ }
+
+ ref = pf->xref_table[obj_num].indirect;
+ if (!ref) {
+ pdf_obj *obj, *reserved, *imported;
+
+ obj = pdf_get_object(pf, obj_num, obj_gen);
+ if (!obj) {
+ WARN("Could not read object: %lu %u", obj_num, obj_gen);
+ return NULL;
+ }
+
+ /* Fix for circular reference issue
+ *
+ * Older version of dvipdfmx disallowed the following case of
+ * circular reference:
+ * obj #1 --> << /Kids [2 0 R] >>
+ * obj #2 --> << /Parents [1 0 R] >>
+ * The problem is in that dvipdfmx gives new labels to objects after they
+ * are completely read.
+ */
+ reserved = pdf_new_null(); /* for reservation of label */
+ pf->xref_table[obj_num].indirect = ref = pdf_new_ref(p, reserved);
+ imported = pdf_import_object(obj);
+ if (imported) {
+ if (imported->label) {
+ WARN("Imported object already has a label: obj_id=%lu", imported->label);
+ }
+ OBJ_OBJ(ref) = imported;
+ imported->label = reserved->label;
+ imported->generation = reserved->generation;
+ reserved->label = 0;
+ reserved->generation = 0;
+ pdf_release_obj(imported);
+ }
+
+ pdf_release_obj(reserved);
+ pdf_release_obj(obj);
+ }
+
+ return pdf_link_obj(ref);
+}
+
+/*
+ * pdf_import_object recursively copies the object and those
+ * referenced by it and changes the indirect references so that
+ * they refer to the current output file. New indirect references
+ * are remembered, which avoids duplicating objects when they
+ * are imported several times.
+ */
+pdf_obj *
+pdf_import_object (pdf_obj *object)
+{
+ pdf_obj *imported;
+ pdf_obj *tmp;
+ size_t i;
+
+ switch (pdf_obj_typeof(object)) {
+
+ case PDF_INDIRECT:
+ if (OBJ_FILE(object)) {
+ imported = pdf_import_indirect(object);
+ } else {
+ imported = pdf_link_obj(object);
+ }
+ break;
+
+ case PDF_STREAM:
+ {
+ pdf_obj *stream_dict;
+
+ tmp = pdf_import_object(pdf_stream_dict(object));
+ if (!tmp)
+ return NULL;
+
+ imported = pdf_new_stream(0);
+ stream_dict = pdf_stream_dict(imported);
+ pdf_merge_dict(stream_dict, tmp);
+ pdf_release_obj(tmp);
+ pdf_add_stream(imported,
+ pdf_stream_dataptr(object),
+ pdf_stream_length(object));
+ }
+ break;
+
+ case PDF_DICT:
+
+ imported = pdf_new_dict();
+ if (pdf_foreach_dict(object, import_dict, imported) < 0) {
+ pdf_release_obj(imported);
+ return NULL;
+ }
+
+ break;
+
+ case PDF_ARRAY:
+
+ imported = pdf_new_array();
+ for (i = 0; i < pdf_array_length(object); i++) {
+ tmp = pdf_import_object(pdf_get_array(object, i));
+ if (!tmp) {
+ pdf_release_obj(imported);
+ return NULL;
+ }
+ pdf_add_array(imported, tmp);
+ }
+ break;
+
+ default:
+ imported = pdf_link_obj(object);
+ }
+
+ return imported;
+}
+
+
+/* returns 0 if indirect references point to the same object */
+int
+pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2)
+{
+ pdf_indirect *data1, *data2;
+
+ ASSERT(PDF_OBJ_INDIRECTTYPE(ref1) && PDF_OBJ_INDIRECTTYPE(ref2));
+
+ data1 = (pdf_indirect *) ref1->data;
+ data2 = (pdf_indirect *) ref2->data;
+
+ return data1->pf != data2->pf || data1->label != data2->label
+ || data1->generation != data2->generation;
+}
+
+int
+pdf_compare_object (pdf_obj *obj1, pdf_obj *obj2)
+{
+ int r = 0;
+
+ if (!obj1 && !obj2) {
+ return 0;
+ } else if (!obj1 && obj2) {
+ return 1;
+ } else if (obj1 && !obj2) {
+ return 1;
+ } else if (pdf_obj_typeof(obj1) != pdf_obj_typeof(obj2)) {
+ return 1;
+ }
+
+ switch (pdf_obj_typeof(obj1)) {
+ case PDF_BOOLEAN:
+ r = pdf_boolean_value(obj1) - pdf_boolean_value(obj2);
+ break;
+ case PDF_NUMBER:
+ if (pdf_number_value(obj1) < pdf_number_value(obj2)) {
+ r = -1;
+ } else if (pdf_number_value(obj1) > pdf_number_value(obj2)) {
+ r = 1;
+ } else {
+ r = 0;
+ }
+ break;
+ case PDF_STRING:
+ if (pdf_string_length(obj1) < pdf_string_length(obj2)) {
+ r = -1;
+ } else if (pdf_string_length(obj1) > pdf_string_length(obj2)) {
+ r = 1;
+ } else {
+ r = memcmp(pdf_string_value(obj1), pdf_string_value(obj2), pdf_string_length(obj1));
+ }
+ break;
+ case PDF_NAME:
+ r = strcmp(pdf_name_value(obj1), pdf_name_value(obj2));
+ break;
+ case PDF_NULL:
+ /* Always same */
+ r = 0;
+ break;
+ case PDF_INDIRECT:
+ r = pdf_compare_reference(obj1, obj2);
+ break;
+ case PDF_ARRAY:
+ if (pdf_array_length(obj1) < pdf_array_length(obj2)) {
+ r = -1;
+ } else if (pdf_array_length(obj1) > pdf_array_length(obj2)) {
+ r = 1;
+ } else {
+ int i;
+ for (i = 0; r == 0 && i < pdf_array_length(obj1); i++) {
+ pdf_obj *v1, *v2;
+ v1 = pdf_get_array(obj1, i);
+ v2 = pdf_get_array(obj2, i);
+ r = pdf_compare_object(v1, v2);
+ }
+ }
+ break;
+ case PDF_DICT:
+ {
+ pdf_obj *keys1, *keys2;
+ keys1 = pdf_dict_keys(obj1);
+ keys2 = pdf_dict_keys(obj2);
+ r = pdf_compare_object(keys1, keys2);
+ if (r == 0) {
+ int i;
+ for (i = 0; r == 0 && i < pdf_array_length(keys1); i++) {
+ pdf_obj *key, *v1, *v2;
+ key = pdf_get_array(keys1, i);
+ v1 = pdf_lookup_dict(obj1, pdf_name_value(key));
+ v2 = pdf_lookup_dict(obj2, pdf_name_value(key));
+ r = pdf_compare_object(v1, v2);
+ }
+ }
+ pdf_release_obj(keys1);
+ pdf_release_obj(keys2);
+ }
+ break;
+ case PDF_STREAM:
+ /* Not seriously testing... */
+ r = pdf_compare_object(pdf_stream_dict(obj1), pdf_stream_dict(obj2));
+ if (r == 0) {
+ size_t len1, len2;
+ len1 = pdf_stream_length(obj1);
+ len2 = pdf_stream_length(obj2);
+ if (len1 < len2) {
+ r = -1;
+ } else if (len1 > len2) {
+ r = 1;
+ } else {
+ r = 0;
+ }
+ }
+ break;
+ default:
+ r = 1;
+ }
+
+ return r;
+}
diff --git a/Build/source/texk/dvipdfm-x/pdfobj.h b/Build/source/texk/dvipdfm-x/pdfobj.h
new file mode 100644
index 00000000000..7b41bb411b4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfobj.h
@@ -0,0 +1,205 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFOBJ_H_
+#define _PDFOBJ_H_
+
+#include <stdio.h>
+
+typedef struct pdf_out pdf_out;
+
+/* Here is the complete list of PDF object types */
+
+#define PDF_BOOLEAN 1
+#define PDF_NUMBER 2
+#define PDF_STRING 3
+#define PDF_NAME 4
+#define PDF_ARRAY 5
+#define PDF_DICT 6
+#define PDF_STREAM 7
+#define PDF_NULL 8
+#define PDF_INDIRECT 9
+#define PDF_UNDEFINED 10
+
+#define PDF_OBJ_INVALID 0
+
+#define STREAM_COMPRESS (1 << 0)
+#define STREAM_USE_PREDICTOR (1 << 1)
+
+/* A deeper object hierarchy will be considered as (illegal) loop. */
+#define PDF_OBJ_MAX_DEPTH 30
+
+typedef struct pdf_obj pdf_obj;
+typedef struct pdf_file pdf_file;
+
+/* External interface to pdf routines */
+extern void pdf_error_cleanup (void);
+
+extern FILE *pdf_get_output_file (void);
+extern pdf_out *pdf_out_init (const char *filename,
+ const unsigned char *id1, const unsigned char *id2,
+ int ver_major, int ver_minor,
+ int compression_level,
+ int enable_encrypt,
+ int enable_objstm,
+ int enable_predictor);
+extern void pdf_out_set_encrypt (int keybits, int32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata);
+extern void pdf_out_flush (void);
+
+extern int pdf_get_version (void);
+extern int pdf_get_version_major (void);
+extern int pdf_get_version_minor (void);
+
+extern void pdf_release_obj (pdf_obj *object);
+extern int pdf_obj_typeof (pdf_obj *object);
+
+#define PDF_OBJ_NUMBERTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_NUMBER)
+#define PDF_OBJ_BOOLEANTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_BOOLEAN)
+#define PDF_OBJ_STRINGTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_STRING)
+#define PDF_OBJ_NAMETYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_NAME)
+#define PDF_OBJ_ARRAYTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_ARRAY)
+#define PDF_OBJ_NULLTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_NULL)
+#define PDF_OBJ_DICTTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_DICT)
+#define PDF_OBJ_STREAMTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_STREAM)
+#define PDF_OBJ_INDIRECTTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_INDIRECT)
+#define PDF_OBJ_UNDEFINED(o) ((o) && pdf_obj_typeof((o)) == PDF_UNDEFINED)
+
+#define PDF_OBJ_TYPEOF(o) pdf_obj_typeof((o))
+
+extern pdf_obj *pdf_ref_obj (pdf_obj *object);
+extern pdf_obj *pdf_link_obj (pdf_obj *object);
+
+extern void pdf_transfer_label (pdf_obj *dst, pdf_obj *src);
+extern pdf_obj *pdf_new_undefined (void);
+
+extern pdf_obj *pdf_new_null (void);
+
+extern pdf_obj *pdf_new_boolean (char value);
+extern char pdf_boolean_value (pdf_obj *object);
+
+extern pdf_obj *pdf_new_number (double value);
+extern void pdf_set_number (pdf_obj *object, double value);
+extern double pdf_number_value (pdf_obj *number);
+
+extern pdf_obj *pdf_new_string (const void *str, unsigned length);
+extern void pdf_set_string (pdf_obj *object, unsigned char *str, unsigned length);
+extern void *pdf_string_value (pdf_obj *object);
+extern unsigned pdf_string_length (pdf_obj *object);
+
+/* Name does not include the / */
+extern pdf_obj *pdf_new_name (const char *name);
+extern char *pdf_name_value (pdf_obj *object);
+
+extern pdf_obj *pdf_new_array (void);
+/* pdf_add_dict requires key but pdf_add_array does not.
+ * pdf_add_array always append elements to array.
+ * They should be pdf_put_array(array, idx, element) and
+ * pdf_put_dict(dict, key, value)
+ */
+extern void pdf_add_array (pdf_obj *array, pdf_obj *object);
+#if 0
+extern void pdf_put_array (pdf_obj *array, unsigned idx, pdf_obj *object);
+#endif
+extern pdf_obj *pdf_get_array (pdf_obj *array, int idx);
+extern unsigned pdf_array_length (pdf_obj *array);
+
+#if 0
+extern pdf_obj *pdf_shift_array (pdf_obj *array);
+extern pdf_obj *pdf_pop_array (pdf_obj *array);
+#endif
+
+extern pdf_obj *pdf_new_dict (void);
+extern void pdf_remove_dict (pdf_obj *dict, const char *key);
+extern void pdf_merge_dict (pdf_obj *dict1, pdf_obj *dict2);
+extern pdf_obj *pdf_lookup_dict (pdf_obj *dict, const char *key);
+extern pdf_obj *pdf_dict_keys (pdf_obj *dict);
+
+/* pdf_add_dict() want pdf_obj as key, however, key must always be name
+ * object and pdf_lookup_dict() and pdf_remove_dict() uses const char as
+ * key. This strange difference seems come from pdfdoc that first allocate
+ * name objects frequently used (maybe 1000 times) such as /Type and does
+ * pdf_link_obj() it rather than allocate/free-ing them each time. But I
+ * already removed that.
+ */
+extern int pdf_add_dict (pdf_obj *dict, pdf_obj *key, pdf_obj *value);
+#if 0
+extern void pdf_put_dict (pdf_obj *dict, const char *key, pdf_obj *value);
+#endif
+
+/* Apply proc(key, value, pdata) for each key-value pairs in dict, stop if proc()
+ * returned non-zero value (and that value is returned). PDF object is passed for
+ * key to allow modification (fix) of key.
+ */
+extern int pdf_foreach_dict (pdf_obj *dict,
+ int (*proc) (pdf_obj *, pdf_obj *, void *),
+ void *pdata);
+
+extern pdf_obj *pdf_new_stream (int flags);
+extern void pdf_add_stream (pdf_obj *stream,
+ const void *stream_data_ptr,
+ int stream_data_len);
+
+extern int pdf_concat_stream (pdf_obj *dst, pdf_obj *src);
+extern pdf_obj *pdf_stream_dict (pdf_obj *stream);
+extern int pdf_stream_length (pdf_obj *stream);
+#if 0
+extern void pdf_stream_set_flags (pdf_obj *stream, int flags);
+extern int pdf_stream_get_flags (pdf_obj *stream);
+#endif
+extern const void *pdf_stream_dataptr (pdf_obj *stream);
+extern void pdf_stream_set_predictor (pdf_obj *stream,
+ int predictor, int32_t columns,
+ int bpc, int colors);
+
+/* Compare label of two indirect reference object. */
+extern int pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2);
+/* Compare objects. */
+extern int pdf_compare_object (pdf_obj *obj1, pdf_obj *obj2);
+
+
+/* The following routines are not appropriate for pdfobj.
+ */
+
+extern void pdf_set_info (pdf_obj *obj);
+extern void pdf_set_root (pdf_obj *obj);
+
+extern void pdf_files_init (void);
+extern void pdf_files_close (void);
+extern int check_for_pdf (FILE *file);
+extern pdf_file *pdf_open (const char *ident, FILE *file);
+extern void pdf_close (pdf_file *pf);
+extern pdf_obj *pdf_file_get_trailer (pdf_file *pf);
+extern pdf_obj *pdf_file_get_catalog (pdf_file *pf);
+extern int pdf_file_get_version (pdf_file *pf);
+
+extern pdf_obj *pdf_deref_obj (pdf_obj *object);
+extern pdf_obj *pdf_import_object (pdf_obj *object);
+
+extern int pdfobj_escape_str (char *buffer, int size, const unsigned char *s, int len);
+
+extern pdf_obj *pdf_new_indirect (pdf_file *pf, uint32_t label, uint16_t generation);
+
+extern int pdf_check_version (int major, int minor);
+
+#endif /* _PDFOBJ_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfparse.c b/Build/source/texk/dvipdfm-x/pdfparse.c
new file mode 100644
index 00000000000..58ea9a0bc4e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfparse.c
@@ -0,0 +1,1009 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+/* pow() */
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "numbers.h"
+
+#include "mfileio.h"
+
+#include "pdfobj.h"
+#include "pdfdoc.h"
+#include "pdfdev.h"
+
+#include "pdfparse.h"
+
+/* PDF */
+#ifdef is_space
+#undef is_space
+#endif
+#ifdef is_delim
+#undef is_delim
+#endif
+
+#define is_space(c) ((c) == ' ' || (c) == '\t' || (c) == '\f' || \
+ (c) == '\r' || (c) == '\n' || (c) == '\0')
+#define is_delim(c) ((c) == '(' || (c) == ')' || \
+ (c) == '/' || \
+ (c) == '<' || (c) == '>' || \
+ (c) == '[' || (c) == ']' || \
+ (c) == '%')
+#define PDF_TOKEN_END(p,e) ((p) >= (e) || is_space(*(p)) || is_delim(*(p)))
+
+#define istokensep(c) (is_space((c)) || is_delim((c)))
+
+static struct {
+ int tainted;
+} parser_state = {
+ 0
+};
+
+static int xtoi (char ch);
+
+void
+dump (const char *start, const char *end)
+{
+ const char *p = start;
+
+#define DUMP_LIMIT 50
+ MESG("\nCurrent input buffer is -->");
+ while (p < end && p < start + DUMP_LIMIT)
+ MESG("%c", *(p++));
+ if (p == start+DUMP_LIMIT)
+ MESG("...");
+ MESG("<--\n");
+}
+
+void
+pdfparse_skip_line (const char **start, const char *end)
+{
+ while (*start < end && **start != '\n' && **start != '\r')
+ (*start)++;
+ /* The carriage return (CR; \r; 0x0D) and line feed (LF; \n; 0x0A)
+ * characters, also called newline characters, are treated as
+ * end-of-line (EOL) markers. The combination of a carriage return
+ * followed immediately by a line feed is treated as one EOL marker.
+ */
+ if (*start < end && **start == '\r')
+ (*start)++;
+ if (*start < end && **start == '\n')
+ (*start)++;
+}
+
+void
+skip_white (const char **start, const char *end)
+{
+ /*
+ * The null (NUL; 0x00) character is a white-space character in PDF spec
+ * but isspace(0x00) returns FALSE; on the other hand, the vertical tab
+ * (VT; 0x0B) character is not a white-space character in PDF spec but
+ * isspace(0x0B) returns TRUE.
+ */
+ while (*start < end && (is_space(**start) || **start == '%')) {
+ if (**start == '%')
+ pdfparse_skip_line(start, end);
+ else
+ (*start)++;
+ }
+}
+
+
+static char *
+parsed_string (const char *start, const char *end)
+{
+ char *result = NULL;
+ int len;
+
+ len = end - start;
+ if (len > 0) {
+ result = NEW(len + 1, char);
+ memcpy(result, start, len);
+ result[len] = '\0';
+ }
+
+ return result;
+}
+
+char *
+parse_number (const char **start, const char *end)
+{
+ char *number;
+ const char *p;
+
+ skip_white(start, end);
+ p = *start;
+ if (p < end && (*p == '+' || *p == '-'))
+ p++;
+ while (p < end && isdigit((unsigned char)*p))
+ p++;
+ if (p < end && *p == '.') {
+ p++;
+ while (p < end && isdigit((unsigned char)*p))
+ p++;
+ }
+ number = parsed_string(*start, p);
+
+ *start = p;
+ return number;
+}
+
+char *
+parse_unsigned (const char **start, const char *end)
+{
+ char *number;
+ const char *p;
+
+ skip_white(start, end);
+ for (p = *start; p < end; p++) {
+ if (!isdigit((unsigned char)*p))
+ break;
+ }
+ number = parsed_string(*start, p);
+
+ *start = p;
+ return number;
+}
+
+static char *
+parse_gen_ident (const char **start, const char *end, const char *valid_chars)
+{
+ char *ident;
+ const char *p;
+
+ /* No skip_white(start, end)? */
+ for (p = *start; p < end; p++) {
+ if (!strchr(valid_chars, *p))
+ break;
+ }
+ ident = parsed_string(*start, p);
+
+ *start = p;
+ return ident;
+}
+
+char *
+parse_ident (const char **start, const char *end)
+{
+ static const char *valid_chars =
+ "!\"#$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~";
+
+ return parse_gen_ident(start, end, valid_chars);
+}
+
+char *
+parse_val_ident (const char **start, const char *end)
+{
+ static const char *valid_chars =
+ "!\"#$&'*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~";
+
+ return parse_gen_ident(start, end, valid_chars);
+}
+
+char *
+parse_opt_ident (const char **start, const char *end)
+{
+ if (*start < end && **start == '@') {
+ (*start)++;
+ return parse_ident(start, end);
+ }
+
+ return NULL;
+}
+
+pdf_obj *
+parse_pdf_number (const char **pp, const char *endptr)
+{
+ const char *p;
+ double v = 0.0;
+ int nddigits = 0, sign = 1;
+ int has_dot = 0;
+
+ p = *pp;
+ skip_white(&p, endptr);
+ if (p >= endptr ||
+ (!isdigit((unsigned char)p[0]) && p[0] != '.' &&
+ p[0] != '+' && p[0] != '-')) {
+ WARN("Could not find a numeric object.");
+ return NULL;
+ }
+
+ if (p[0] == '-') {
+ if (p + 1 >= endptr) {
+ WARN("Could not find a numeric object.");
+ return NULL;
+ }
+ sign = -1;
+ p++;
+ } else if (p[0] == '+') {
+ if (p + 1 >= endptr) {
+ WARN("Could not find a numeric object.");
+ return NULL;
+ }
+ sign = 1;
+ p++;
+ }
+
+ while (p < endptr && !istokensep(p[0])) {
+ if (p[0] == '.') {
+ if (has_dot) { /* Two dots */
+ WARN("Could not find a numeric object.");
+ return NULL;
+ } else {
+ has_dot = 1;
+ }
+ } else if (isdigit((unsigned char)p[0])) {
+ if (has_dot) {
+ v += (p[0] - '0') / pow(10, nddigits + 1);
+ nddigits++;
+ } else {
+ v = v * 10.0 + p[0] - '0';
+ }
+ } else {
+ WARN("Could not find a numeric object.");
+ return NULL;
+ }
+ p++;
+ }
+
+ *pp = p;
+ return pdf_new_number(sign * v);
+}
+
+/*
+ * PDF Name:
+ *
+ * PDF-1.2+: Two hexadecimal digits preceded by a number sign.
+ */
+static int
+pn_getc (const char **pp, const char *endptr)
+{
+ int ch = 0;
+ const char *p;
+
+ p = *pp;
+ if (p[0] == '#') {
+ if (p + 2 >= endptr) {
+ *pp = endptr;
+ return -1;
+ }
+ if (!isxdigit((unsigned char)p[1]) || !isxdigit((unsigned char)p[2])) {
+ *pp += 3;
+ return -1;
+ }
+ ch = (xtoi(p[1]) << 4);
+ ch += xtoi(p[2]);
+ *pp += 3;
+ } else {
+ ch = p[0];
+ *pp += 1;
+ }
+
+ return ch;
+}
+
+#ifndef PDF_NAME_LEN_MAX
+#define PDF_NAME_LEN_MAX 128
+#endif
+
+#ifndef PDF_STRING_LEN_MAX
+#define PDF_STRING_LEN_MAX 65535
+#endif
+
+#define STRING_BUFFER_SIZE PDF_STRING_LEN_MAX+1
+static char sbuf[PDF_STRING_LEN_MAX+1];
+
+
+pdf_obj *
+parse_pdf_name (const char **pp, const char *endptr)
+{
+ char name[PDF_NAME_LEN_MAX+1];
+ int ch, len = 0;
+
+ skip_white(pp, endptr);
+ if (*pp >= endptr || **pp != '/') {
+ WARN("Could not find a name object.");
+ return NULL;
+ }
+
+ (*pp)++;
+ while (*pp < endptr && !istokensep(**pp)) {
+ ch = pn_getc(pp, endptr);
+ if (ch < 0 || ch > 0xff) {
+ WARN("Invalid char in PDF name object. (ignored)");
+ } else if (ch == 0) {
+ WARN("Null char not allowed in PDF name object. (ignored)");
+ } else if (len < STRING_BUFFER_SIZE) {
+ if (len == PDF_NAME_LEN_MAX) {
+ WARN("PDF name length too long. (>= %d bytes)", PDF_NAME_LEN_MAX);
+ }
+ name[len++] = ch;
+ } else {
+ WARN("PDF name length too long. (>= %d bytes, truncated)",
+ STRING_BUFFER_SIZE);
+ }
+ }
+ if (len < 1) {
+ WARN("No valid name object found.");
+ return NULL;
+ }
+ name[len] = '\0';
+
+ return pdf_new_name(name);
+}
+
+pdf_obj *
+parse_pdf_boolean (const char **pp, const char *endptr)
+{
+ skip_white(pp, endptr);
+ if (*pp + 4 <= endptr &&
+ !strncmp(*pp, "true", 4)) {
+ if (*pp + 4 == endptr ||
+ istokensep(*(*pp + 4))) {
+ *pp += 4;
+ return pdf_new_boolean(1);
+ }
+ } else if (*pp + 5 <= endptr &&
+ !strncmp(*pp, "false", 5)) {
+ if (*pp + 5 == endptr ||
+ istokensep(*(*pp + 5))) {
+ *pp += 5;
+ return pdf_new_boolean(0);
+ }
+ }
+
+ WARN("Not a boolean object.");
+
+ return NULL;
+}
+
+pdf_obj *
+parse_pdf_null (const char **pp, const char *endptr)
+{
+ skip_white(pp, endptr);
+ if (*pp + 4 > endptr) {
+ WARN("Not a null object.");
+ return NULL;
+ } else if (*pp + 4 < endptr &&
+ !istokensep(*(*pp+4))) {
+ WARN("Not a null object.");
+ return NULL;
+ } else if (!strncmp(*pp, "null", 4)) {
+ *pp += 4;
+ return pdf_new_null();
+ }
+
+ WARN("Not a null object.");
+
+ return NULL;
+}
+
+/*
+ * PDF Literal String
+ */
+#ifndef isodigit
+#define isodigit(c) ((c) >= '0' && (c) <= '7')
+#endif
+static int
+ps_getescc (const char **pp, const char *endptr)
+{
+ int ch, i;
+ const char *p;
+
+ p = *pp + 1; /* backslash assumed. */
+ switch (p[0]) {
+ case 'n': ch = '\n'; p++; break;
+ case 'r': ch = '\r'; p++; break;
+ case 't': ch = '\t'; p++; break;
+ case 'b': ch = '\b'; p++; break;
+ case 'f': ch = '\f'; p++; break;
+
+ /*
+ * An end-of-line marker preceded by a backslash must be ignored.
+ */
+ case '\n':
+ ch = -1;
+ p++;
+ break;
+ case '\r':
+ ch = -1;
+ p++;
+ if (p < endptr && p[0] == '\n')
+ p++;
+ break;
+ default:
+ if (p[0] == '\\' ||
+ p[0] == '(' || p[0] == ')') {
+ ch = p[0];
+ p++;
+ } else if (isodigit(p[0])) {
+ ch = 0;
+ /* Don't forget isodigit() is a macro. */
+ for (i = 0; i < 3 &&
+ p < endptr && isodigit(p[0]); i++) {
+ ch = (ch << 3) + (p[0] - '0');
+ p++;
+ }
+ ch = (ch & 0xff); /* Ignore overflow. */
+ } else {
+ ch = ((unsigned char) p[0]); /* Ignore only backslash. */
+ p++;
+ }
+ }
+
+ *pp = p;
+ return ch;
+}
+
+static pdf_obj *
+parse_pdf_literal_string (const char **pp, const char *endptr)
+{
+ int ch, op_count = 0, len = 0;
+ const char *p;
+
+ p = *pp;
+
+ skip_white(&p, endptr);
+
+ if (p >= endptr || p[0] != '(')
+ return NULL;
+
+ p++;
+
+ /* The carriage return (CR, 0x0d) and line feed (LF, 0x0a) characters,
+ * also called newline characters, are treated as end-of-line (EOL)
+ * markers. The combination of a carriage return followed immediately
+ * by a line feed is treated as one EOL marker.
+ * [PDF Reference, 6th ed., version 1.7, p. 50] */
+
+ /* If an end-of-line marker appears within a literal string
+ * without a preceding backslash, the result is equivalent to
+ * \n (regardless of whether the end-of-line marker was
+ * a carriage return, a line feed, or both).
+ * [PDF Reference, 6th ed., version 1.7, p. 55] */
+
+ while (p < endptr) {
+
+ ch = p[0];
+
+ if (ch == ')' && op_count < 1)
+ break;
+
+#ifndef PDF_PARSE_STRICT
+ if (parser_state.tainted) {
+ if (p + 1 < endptr && (ch & 0x80)) {
+ if (len + 2 >= PDF_STRING_LEN_MAX) {
+ WARN("PDF string length too long. (limit: %ld)",
+ PDF_STRING_LEN_MAX);
+ return NULL;
+ }
+ sbuf[len++] = p[0];
+ sbuf[len++] = p[1];
+ p += 2;
+ continue;
+ }
+ }
+#endif /* !PDF_PARSE_STRICT */
+
+ if (len + 1 >= PDF_STRING_LEN_MAX) {
+ WARN("PDF string length too long. (limit: %ld)",
+ PDF_STRING_LEN_MAX);
+ return NULL;
+ }
+
+ switch (ch) {
+ case '\\':
+ ch = ps_getescc(&p, endptr);
+ if (ch >= 0)
+ sbuf[len++] = (ch & 0xff);
+ break;
+ case '\r':
+ p++;
+ if (p < endptr && p[0] == '\n')
+ p++;
+ sbuf[len++] = '\n';
+ break;
+ default:
+ if (ch == '(')
+ op_count++;
+ else if (ch == ')')
+ op_count--;
+ sbuf[len++] = ch;
+ p++;
+ break;
+ }
+ }
+
+ if (op_count > 0 ||
+ p >= endptr || p[0] != ')') {
+ WARN("Unbalanced parens/truncated PDF literal string.");
+ return NULL;
+ }
+
+ *pp = p + 1;
+ return pdf_new_string(sbuf, len);
+}
+
+/*
+ * PDF Hex String
+ */
+static int
+xtoi (char ch)
+{
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ if (ch >= 'A' && ch <= 'F')
+ return (ch - 'A') + 10;
+ if (ch >= 'a' && ch <= 'f')
+ return (ch - 'a') + 10;
+
+ return -1;
+}
+
+static pdf_obj *
+parse_pdf_hex_string (const char **pp, const char *endptr)
+{
+ const char *p;
+ int len;
+
+ p = *pp;
+
+ skip_white(&p, endptr);
+ if (p >= endptr || p[0] != '<')
+ return NULL;
+
+ p++;
+
+ len = 0;
+ /*
+ * PDF Reference does not describe how to treat invalid char.
+ * Zero is appended if final hex digit is missing.
+ */
+ while (p < endptr && p[0] != '>' && len < PDF_STRING_LEN_MAX) {
+ int ch;
+
+ skip_white(&p, endptr);
+ if (p >= endptr || p[0] == '>')
+ break;
+
+ ch = (xtoi(p[0]) << 4);
+ p++;
+
+ skip_white(&p, endptr);
+ if (p < endptr && p[0] != '>') {
+ ch += xtoi(p[0]);
+ p++;
+ }
+ sbuf[len++] = (ch & 0xff);
+ }
+
+ if (p >= endptr) {
+ WARN("Premature end of input hex string.");
+ return NULL;
+ } else if (p[0] != '>') {
+ WARN("PDF string length too long. (limit: %ld)", PDF_STRING_LEN_MAX);
+ return NULL;
+ }
+
+ *pp = p + 1;
+ return pdf_new_string(sbuf, len);
+}
+
+pdf_obj *
+parse_pdf_string (const char **pp, const char *endptr)
+{
+ skip_white(pp, endptr);
+ if (*pp + 2 <= endptr) {
+ if (**pp == '(')
+ return parse_pdf_literal_string(pp, endptr);
+ else if (**pp == '<' &&
+ (*(*pp + 1) == '>' || isxdigit((unsigned char)*(*pp + 1)))) {
+ return parse_pdf_hex_string(pp, endptr);
+ }
+ }
+
+ WARN("Could not find a string object.");
+
+ return NULL;
+}
+
+static pdf_obj *
+parse_pdf_dict_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
+{
+ pdf_obj *result = NULL;
+ const char *p;
+
+ p = *pp;
+
+ skip_white(&p, endptr);
+
+ /* At least four letter <<>>. */
+ if (p + 4 > endptr ||
+ p[0] != '<' || p[1] != '<') {
+ return NULL;
+ }
+ p += 2;
+
+ result = pdf_new_dict();
+
+ skip_white(&p, endptr);
+ while (p < endptr && p[0] != '>') {
+ pdf_obj *key, *value;
+
+ skip_white(&p, endptr);
+ key = parse_pdf_name(&p, endptr);
+ if (!key) {
+ WARN("Could not find a key in dictionary object.");
+ pdf_release_obj(result);
+ return NULL;
+ }
+
+ skip_white(&p, endptr);
+
+ value = parse_pdf_object_extended(&p, endptr, pf, unknown_handler, user_data);
+ if (!value) {
+ pdf_release_obj(key);
+ pdf_release_obj(value);
+ pdf_release_obj(result);
+ WARN("Could not find a value in dictionary object.");
+ return NULL;
+ }
+ pdf_add_dict(result, key, value);
+
+ skip_white(&p, endptr);
+ }
+
+ if (p + 2 > endptr ||
+ p[0] != '>' || p[1] != '>') {
+ WARN("Syntax error: Dictionary object ended prematurely.");
+ pdf_release_obj(result);
+ return NULL;
+ }
+
+ *pp = p + 2; /* skip >> */
+ return result;
+}
+
+static pdf_obj *
+parse_pdf_array_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
+{
+ pdf_obj *result;
+ const char *p;
+
+ p = *pp;
+
+ skip_white(&p, endptr);
+ if (p + 2 > endptr || p[0] != '[') {
+ WARN("Could not find an array object.");
+ return NULL;
+ }
+
+ result = pdf_new_array();
+
+ p++;
+ skip_white(&p, endptr);
+
+ while (p < endptr && p[0] != ']') {
+ pdf_obj *elem;
+
+ elem = parse_pdf_object_extended(&p, endptr, pf, unknown_handler, user_data);
+ if (!elem) {
+ pdf_release_obj(result);
+ WARN("Could not find a valid object in array object.");
+ return NULL;
+ }
+ pdf_add_array(result, elem);
+
+ skip_white(&p, endptr);
+ }
+
+ if (p >= endptr || p[0] != ']') {
+ WARN("Array object ended prematurely.");
+ pdf_release_obj(result);
+ return NULL;
+ }
+
+ *pp = p + 1; /* skip ] */
+ return result;
+}
+
+static pdf_obj *
+parse_pdf_stream (const char **pp, const char *endptr, pdf_obj *dict)
+{
+ pdf_obj *result = NULL;
+ const char *p;
+ pdf_obj *stream_dict;
+ int stream_length;
+
+ p = *pp;
+ skip_white(&p, endptr);
+ if (p + 6 > endptr ||
+ strncmp(p, "stream", 6)) {
+ return NULL;
+ }
+ p += 6;
+
+ /* The keyword stream that follows the stream dictionary
+ * should be followed by an end-of-line marker consisting of
+ * either a carriage return (0x0D;\r) and a line feed (0x0A;\n)
+ * or just a line feed, and not by a carriage return alone.
+ * [PDF Reference, 6th ed., version 1.7, pp. 60-61] */
+
+ /* Notice that TeX translates an end-of-line marker to a single space. */
+ if (p < endptr && p[0] == '\n') {
+ p++;
+ } else if (p + 1 < endptr &&
+ (p[0] == '\r' && p[1] == '\n')) {
+ p += 2;
+ }
+
+ /* Stream length */
+ {
+ pdf_obj *tmp, *tmp2;
+
+ tmp = pdf_lookup_dict(dict, "Length");
+
+ if (tmp != NULL) {
+ tmp2 = pdf_deref_obj(tmp);
+ if (pdf_obj_typeof(tmp2) != PDF_NUMBER)
+ stream_length = -1;
+ else {
+ stream_length = (int) pdf_number_value(tmp2);
+ }
+ pdf_release_obj(tmp2);
+ }
+ else {
+ return NULL;
+ }
+ }
+
+
+ if (stream_length < 0 ||
+ p + stream_length > endptr)
+ return NULL;
+
+ /*
+ * If Filter is not applied, set STREAM_COMPRESS flag.
+ * Should we use filter for ASCIIHexEncode/ASCII85Encode-ed streams?
+ */
+ {
+ pdf_obj *filters;
+
+ filters = pdf_lookup_dict(dict, "Filter");
+ if (!filters && stream_length > 10) {
+ result = pdf_new_stream(STREAM_COMPRESS);
+ } else {
+ result = pdf_new_stream(0);
+ }
+ }
+
+ stream_dict = pdf_stream_dict(result);
+ pdf_merge_dict(stream_dict, dict);
+
+ pdf_add_stream(result, p, stream_length);
+ p += stream_length;
+
+ /* Check "endsteam" */
+ {
+ /* It is recommended that there be an end-of-line marker
+ * after the data and before endstream; this marker is not included
+ * in the stream length.
+ * [PDF Reference, 6th ed., version 1.7, pp. 61] */
+ if (p < endptr && p[0] == '\r')
+ p++;
+ if (p < endptr && p[0] == '\n')
+ p++;
+
+ if (p + 9 > endptr ||
+ memcmp(p, "endstream", 9)) {
+ pdf_release_obj(result);
+ return NULL;
+ }
+ p += 9;
+ }
+
+ *pp = p;
+ return result;
+}
+
+static pdf_obj *
+try_pdf_reference (const char *start, const char *end, const char **endptr, pdf_file *pf)
+{
+ unsigned id = 0;
+ unsigned short gen = 0;
+
+ ASSERT(pf);
+
+ if (endptr)
+ *endptr = start;
+
+ skip_white(&start, end);
+ if (start > end - 5 || !isdigit((unsigned char)*start)) {
+ return NULL;
+ }
+ while (!is_space(*start)) {
+ if (start >= end || !isdigit((unsigned char)*start)) {
+ return NULL;
+ }
+ id = id * 10 + (*start - '0');
+ start++;
+ }
+
+ skip_white(&start, end);
+ if (start >= end || !isdigit((unsigned char)*start))
+ return NULL;
+ while (!is_space(*start)) {
+ if (start >= end || !isdigit((unsigned char)*start))
+ return NULL;
+ gen = gen * 10 + (*start - '0');
+ start++;
+ }
+
+ skip_white(&start, end);
+ if (start >= end || *start != 'R')
+ return NULL;
+ start++;
+ if (!PDF_TOKEN_END(start, end))
+ return NULL;
+
+ if (endptr)
+ *endptr = start;
+
+ return pdf_new_indirect(pf, id, gen);
+}
+
+pdf_obj *
+parse_pdf_object_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
+/* If pf is NULL, then indirect references are not allowed */
+{
+ pdf_obj *result = NULL;
+ const char *nextptr;
+
+ skip_white(pp, endptr);
+ if (*pp >= endptr) {
+ WARN("Could not find any valid object.");
+ return NULL;
+ }
+
+ switch (**pp) {
+
+ case '<':
+
+ if (*(*pp + 1) != '<') {
+ result = parse_pdf_hex_string(pp, endptr);
+ } else {
+ pdf_obj *dict;
+
+ result = parse_pdf_dict_extended(pp, endptr, pf, unknown_handler, user_data);
+ skip_white(pp, endptr);
+ if ( result &&
+ *pp <= endptr - 15 &&
+ !memcmp(*pp, "stream", 6)) {
+ dict = result;
+ result = parse_pdf_stream(pp, endptr, dict);
+ pdf_release_obj(dict);
+ }
+ }
+
+ break;
+ case '(':
+ result = parse_pdf_string(pp, endptr);
+ break;
+ case '[':
+ result = parse_pdf_array_extended(pp, endptr, pf, unknown_handler, user_data);
+ break;
+ case '/':
+ result = parse_pdf_name(pp, endptr);
+ break;
+ case 'n':
+ result = parse_pdf_null(pp, endptr);
+ break;
+ case 't': case 'f':
+ result = parse_pdf_boolean(pp, endptr);
+ break;
+ case '+': case '-': case '.':
+ result = parse_pdf_number(pp, endptr);
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+
+ /*
+ * If pf != NULL, then we are parsing a PDF file,
+ * and indirect references are allowed.
+ */
+ if (pf && (result = try_pdf_reference(*pp, endptr, &nextptr, pf))) {
+ *pp = nextptr;
+ } else {
+ result = parse_pdf_number(pp, endptr);
+ }
+ break;
+
+ default:
+ if (unknown_handler) {
+ result = unknown_handler(pp, endptr, user_data);
+ } else {
+ WARN("Unknown PDF object type.");
+ result = NULL;
+ }
+ break;
+ }
+
+ return result;
+}
+
+pdf_obj *
+parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf)
+{
+ return parse_pdf_dict_extended(pp, endptr, pf, NULL, NULL);
+}
+
+pdf_obj *
+parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf)
+{
+ return parse_pdf_array_extended(pp, endptr, pf, NULL, NULL);
+}
+
+pdf_obj *
+parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf)
+{
+ return parse_pdf_object_extended(pp, endptr, pf, NULL, NULL);
+}
+
+
+pdf_obj *
+parse_pdf_tainted_dict (const char **pp, const char *endptr,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
+{
+ pdf_obj *result;
+
+ parser_state.tainted = 1;
+ result = parse_pdf_dict_extended(pp, endptr, NULL, unknown_handler, user_data);
+ parser_state.tainted = 0;
+
+ return result;
+}
+
diff --git a/Build/source/texk/dvipdfm-x/pdfparse.h b/Build/source/texk/dvipdfm-x/pdfparse.h
new file mode 100644
index 00000000000..52ec95d99fc
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfparse.h
@@ -0,0 +1,62 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFPARSE_H_
+#define _PDFPARSE_H_
+
+#include "numbers.h"
+#include "pdfobj.h"
+
+/* Please remove this */
+extern void dump (const char *start, const char *end);
+
+extern void pdfparse_skip_line (const char **start, const char *end);
+extern void skip_white (const char **start, const char *end);
+
+extern char *parse_number (const char **start, const char *end);
+extern char *parse_unsigned (const char **start, const char *end);
+
+extern char *parse_ident (const char **start, const char *end);
+extern char *parse_val_ident (const char **start, const char *end);
+extern char *parse_opt_ident (const char **start, const char *end);
+
+extern pdf_obj *parse_pdf_name (const char **pp, const char *endptr);
+extern pdf_obj *parse_pdf_boolean (const char **pp, const char *endptr);
+extern pdf_obj *parse_pdf_number (const char **pp, const char *endptr);
+extern pdf_obj *parse_pdf_null (const char **pp, const char *endptr);
+extern pdf_obj *parse_pdf_string (const char **pp, const char *endptr);
+extern pdf_obj *parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf);
+extern pdf_obj *parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf);
+extern pdf_obj *parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf);
+
+extern pdf_obj *parse_pdf_object_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data);
+extern pdf_obj *parse_pdf_tainted_dict (const char **pp, const char *endptr,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data);
+
+#endif /* _PDFPARSE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfresource.c b/Build/source/texk/dvipdfm-x/pdfresource.c
new file mode 100644
index 00000000000..91c353cff7f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfresource.c
@@ -0,0 +1,375 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * Currently, this is nearly useless.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+
+#include "pdfresource.h"
+
+#define PDF_RESOURCE_DEBUG_STR "PDF"
+#define PDF_RESOURCE_DEBUG 3
+
+#define PDF_RESOURCE_FONT 0
+#define PDF_RESOURCE_CIDFONT 1
+#define PDF_RESOURCE_ENCODING 2
+#define PDF_RESOURCE_CMAP 3
+#define PDF_RESOURCE_XOBJECT 4
+#define PDF_RESOURCE_COLORSPACE 5
+#define PDF_RESOURCE_SHADING 6
+#define PDF_RESOURCE_PATTERN 7
+#define PDF_RESOURCE_GSTATE 8
+
+typedef struct pdf_res
+{
+ char *ident;
+
+ int flags;
+
+ int category;
+ void *cdata;
+
+ pdf_obj *object;
+ pdf_obj *reference;
+} pdf_res;
+
+static struct {
+ const char *name;
+ int cat_id;
+} pdf_resource_categories[] = {
+ {"Font", PDF_RESOURCE_FONT},
+ {"CIDFont", PDF_RESOURCE_CIDFONT},
+ {"Encoding", PDF_RESOURCE_ENCODING},
+ {"CMap", PDF_RESOURCE_CMAP},
+ {"XObject", PDF_RESOURCE_XOBJECT},
+ {"ColorSpace", PDF_RESOURCE_COLORSPACE},
+ {"Shading", PDF_RESOURCE_SHADING},
+ {"Pattern", PDF_RESOURCE_PATTERN},
+ {"ExtGState", PDF_RESOURCE_GSTATE},
+};
+
+#define PDF_NUM_RESOURCE_CATEGORIES (sizeof(pdf_resource_categories)/sizeof(pdf_resource_categories[0]))
+
+#define CACHE_ALLOC_SIZE 16u
+struct res_cache
+{
+ int count;
+ int capacity;
+ pdf_res *resources;
+};
+
+static struct res_cache resources[PDF_NUM_RESOURCE_CATEGORIES];
+
+static void
+pdf_init_resource (pdf_res *res)
+{
+ ASSERT(res);
+
+ res->ident = NULL;
+ res->category = -1;
+ res->flags = 0;
+ res->cdata = NULL;
+ res->object = NULL;
+ res->reference = NULL;
+
+ return;
+}
+
+static void
+pdf_flush_resource (pdf_res *res)
+{
+ if (res) {
+ if (res->reference)
+ pdf_release_obj(res->reference);
+ if (res->object)
+ pdf_release_obj(res->object);
+
+ res->reference = NULL;
+ res->object = NULL;
+ }
+}
+
+static void
+pdf_clean_resource (pdf_res *res)
+{
+ if (res) {
+ if (res->reference || res->object)
+ WARN("Trying to release un-flushed object.");
+ if (res->reference)
+ pdf_release_obj(res->reference);
+ if (res->object)
+ pdf_release_obj(res->object);
+ if (res->ident)
+ RELEASE(res->ident);
+ res->ident = NULL;
+ res->category = -1;
+ res->flags = 0;
+ }
+}
+
+void
+pdf_init_resources (void)
+{
+ int i;
+
+ for (i = 0;
+ i < PDF_NUM_RESOURCE_CATEGORIES; i++) {
+ resources[i].count = 0;
+ resources[i].capacity = 0;
+ resources[i].resources = NULL;
+ }
+}
+
+void
+pdf_close_resources (void)
+{
+ int i;
+
+ for (i = 0;
+ i < PDF_NUM_RESOURCE_CATEGORIES; i++) {
+ struct res_cache *rc;
+ int j;
+
+ rc = &resources[i];
+ for (j = 0; j < rc->count; j++) {
+ pdf_flush_resource(&rc->resources[j]);
+ pdf_clean_resource(&rc->resources[j]);
+ }
+ RELEASE(rc->resources);
+
+ rc->count = 0;
+ rc->capacity = 0;
+ rc->resources = NULL;
+ }
+}
+
+static int
+get_category (const char *category)
+{
+ int i;
+
+ for (i = 0;
+ i < PDF_NUM_RESOURCE_CATEGORIES; i++) {
+ if (!strcmp(category, pdf_resource_categories[i].name)) {
+ return pdf_resource_categories[i].cat_id;
+ }
+ }
+
+ return -1;
+}
+
+int
+pdf_defineresource (const char *category,
+ const char *resname, pdf_obj *object, int flags)
+{
+ int res_id;
+ struct res_cache *rc;
+ int cat_id;
+ pdf_res *res = NULL;
+
+ ASSERT(category && object);
+
+ cat_id = get_category(category);
+ if (cat_id < 0) {
+ ERROR("Unknown resource category: %s", category);
+ return -1;
+ }
+
+ rc = &resources[cat_id];
+ if (resname) {
+ for (res_id = 0; res_id < rc->count; res_id++) {
+ res = &rc->resources[res_id];
+ if (!strcmp(resname, res->ident)) {
+ WARN("Resource %s (category: %s) already defined...",
+ resname, category);
+ pdf_flush_resource(res);
+ res->flags = flags;
+ if (flags & PDF_RES_FLUSH_IMMEDIATE) {
+ res->reference = pdf_ref_obj(object);
+ pdf_release_obj(object);
+ } else {
+ res->object = object;
+ }
+ return (cat_id << 16) | res_id;
+ }
+ }
+ } else {
+ res_id = rc->count;
+ }
+
+ if (res_id == rc->count) {
+ if (rc->count >= rc->capacity) {
+ rc->capacity += CACHE_ALLOC_SIZE;
+ rc->resources = RENEW(rc->resources, rc->capacity, pdf_res);
+ }
+ res = &rc->resources[res_id];
+
+ pdf_init_resource(res);
+ if (resname && resname[0] != '\0') {
+ res->ident = NEW(strlen(resname) + 1, char);
+ strcpy(res->ident, resname);
+ }
+ res->category = cat_id;
+ res->flags = flags;
+ if (flags & PDF_RES_FLUSH_IMMEDIATE) {
+ res->reference = pdf_ref_obj(object);
+ pdf_release_obj(object);
+ } else {
+ res->object = object;
+ }
+ rc->count++;
+ }
+
+ return (cat_id << 16) | res_id;
+}
+
+#if 0
+int
+pdf_resource_exist (const char *category, const char *resname)
+{
+ int res_id;
+ struct res_cache *rc;
+ int cat_id;
+
+ ASSERT(resname && category);
+
+ cat_id = get_category(category);
+ if (cat_id < 0)
+ ERROR("Unknown resource category: %s", category);
+
+ rc = &resources[cat_id];
+ for (res_id = 0; res_id < rc->count; res_id++) {
+ pdf_res *res;
+
+ res = &rc->resources[res_id];
+ if (!strcmp(resname, res->ident)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+int
+pdf_findresource (const char *category, const char *resname)
+{
+ pdf_res *res;
+ int res_id, cat_id;
+ struct res_cache *rc;
+
+ ASSERT(resname && category);
+
+ cat_id = get_category(category);
+ if (cat_id < 0) {
+ ERROR("Unknown resource category: %s", category);
+ return -1;
+ }
+
+ rc = &resources[cat_id];
+ for (res_id = 0; res_id < rc->count; res_id++) {
+ res = &rc->resources[res_id];
+ if (!strcmp(resname, res->ident)) {
+ return cat_id << 16 | res_id;
+ }
+ }
+
+ return -1;
+}
+
+pdf_obj *
+pdf_get_resource_reference (int rc_id)
+{
+ int cat_id, res_id;
+ struct res_cache *rc;
+ pdf_res *res;
+
+ cat_id = (rc_id >> 16) & 0xffff;
+ res_id = rc_id & 0xffff;
+
+ if (cat_id < 0 ||
+ cat_id >= PDF_NUM_RESOURCE_CATEGORIES) {
+ ERROR("Invalid category ID: %d", cat_id);
+ return NULL;
+ }
+ rc = &resources[cat_id];
+ if (res_id < 0 || res_id >= rc->count) {
+ ERROR("Invalid resource ID: %d", res_id);
+ return NULL;
+ }
+
+ res = &rc->resources[res_id];
+ if (!res->reference) {
+ if (!res->object) {
+ ERROR("Undefined object...");
+ return NULL;
+ } else {
+ res->reference = pdf_ref_obj(res->object);
+ }
+ }
+
+ return pdf_link_obj(res->reference);
+}
+
+#if 0
+pdf_obj *
+pdf_get_resource (int rc_id)
+{
+ int cat_id, res_id;
+ struct res_cache *rc;
+ pdf_res *res;
+
+ cat_id = (rc_id >> 16) & 0xffff;
+ res_id = rc_id & 0xffff;
+
+ if (cat_id < 0 ||
+ cat_id >= PDF_NUM_RESOURCE_CATEGORIES) {
+ ERROR("Invalid category ID: %d", cat_id);
+ return NULL;
+ }
+ rc = &resources[cat_id];
+ if (res_id < 0 || res_id >= rc->count) {
+ ERROR("Invalid resource ID: %d", res_id);
+ return NULL;
+ }
+
+ res = &rc->resources[res_id];
+ if (!res->object) {
+ ERROR("Object already flushed???");
+ return NULL;
+ }
+
+ return res->object;
+}
+#endif
diff --git a/Build/source/texk/dvipdfm-x/pdfresource.h b/Build/source/texk/dvipdfm-x/pdfresource.h
new file mode 100644
index 00000000000..81c5d7be9fa
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfresource.h
@@ -0,0 +1,45 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDF_RESOURCE_H_
+#define _PDF_RESOURCE_H_
+
+#include "pdfobj.h"
+
+#define PDF_RES_FLUSH_IMMEDIATE 1
+
+extern void pdf_init_resources (void);
+extern void pdf_close_resources (void);
+
+extern int pdf_defineresource (const char *category,
+ const char *resname, pdf_obj *object, int flags);
+extern int pdf_findresource (const char *category, const char *resname);
+#if 0
+extern int pdf_resource_exist (const char *category, const char *resname);
+#endif
+
+extern pdf_obj *pdf_get_resource_reference (int res_id);
+#if 0
+extern pdf_obj *pdf_get_resource (int res_id);
+#endif
+
+#endif /* _PDF_RESOURCE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfximage.c b/Build/source/texk/dvipdfm-x/pdfximage.c
new file mode 100644
index 00000000000..97b424f82df
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfximage.c
@@ -0,0 +1,1225 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+#include "dpxfile.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+
+#include "pdfdoc.h"
+#include "pdfdev.h"
+#include "pdfdraw.h"
+#include "pdfnames.h"
+
+#include "epdf.h"
+#include "mpost.h"
+#include "pngimage.h"
+#include "jpegimage.h"
+#include "jp2image.h"
+#include "bmpimage.h"
+
+#include "pdfximage.h"
+
+static int check_for_ps (FILE *image_file);
+static int check_for_mp (FILE *image_file);
+static int ps_include_page (pdf_ximage *ximage,
+ const char *ident, load_options options);
+
+
+#define IMAGE_TYPE_UNKNOWN -1
+#define IMAGE_TYPE_PDF 0
+#define IMAGE_TYPE_JPEG 1
+#define IMAGE_TYPE_PNG 2
+#define IMAGE_TYPE_MPS 4
+#define IMAGE_TYPE_EPS 5
+#define IMAGE_TYPE_BMP 6
+#define IMAGE_TYPE_JP2 7
+
+#if defined(_WIN32)
+extern int fsyscp_stat(const char *path, struct stat *buffer);
+#endif /* _WIN32 */
+
+struct attr_
+{
+ int width, height;
+ double xdensity, ydensity;
+ pdf_rect bbox;
+
+ /* Not appropriate place but... someone need them. */
+ int page_no;
+ int page_count;
+ int bbox_type; /* Ugh */
+ pdf_obj *dict;
+ char tempfile;
+};
+
+struct pdf_ximage_
+{
+ char *ident;
+ char res_name[16];
+
+ int subtype;
+
+ struct attr_ attr;
+
+ char *filename;
+ char *fullname;
+ pdf_obj *reference;
+ pdf_obj *resource;
+
+ int reserved;
+};
+
+
+/* verbose, verbose, verbose... */
+struct opt_
+{
+ char *cmdtmpl;
+};
+
+static struct opt_ _opts = {
+ NULL
+};
+
+struct ic_
+{
+ int count, capacity;
+ pdf_ximage *ximages;
+};
+
+static struct ic_ _ic = {
+ 0, 0, NULL
+};
+
+static void
+pdf_init_ximage_struct (pdf_ximage *I)
+{
+ I->ident = NULL;
+ I->filename = NULL;
+ I->fullname = NULL;
+
+ I->subtype = -1;
+ memset(I->res_name, 0, 16);
+ I->reference = NULL;
+ I->resource = NULL;
+ I->reserved = 0;
+
+ I->attr.width = I->attr.height = 0;
+ I->attr.xdensity = I->attr.ydensity = 1.0;
+ I->attr.bbox.llx = I->attr.bbox.lly = 0;
+ I->attr.bbox.urx = I->attr.bbox.ury = 0;
+
+ I->attr.page_no = 1;
+ I->attr.page_count = 1;
+ I->attr.bbox_type = 0;
+
+ I->attr.dict = NULL;
+ I->attr.tempfile = 0;
+}
+
+static void
+pdf_set_ximage_tempfile (pdf_ximage *I, const char *fullname)
+{
+ if (I->fullname)
+ RELEASE(I->fullname);
+ I->fullname = NEW(strlen(fullname)+1, char);
+ strcpy(I->fullname, fullname);
+ I->attr.tempfile = 1;
+}
+
+static void
+pdf_clean_ximage_struct (pdf_ximage *I)
+{
+ if (I->ident)
+ RELEASE(I->ident);
+ if (I->filename)
+ RELEASE(I->filename);
+ if (I->fullname)
+ RELEASE(I->fullname);
+ if (I->reference)
+ pdf_release_obj(I->reference);
+ if (I->resource)
+ pdf_release_obj(I->resource);
+ if (I->attr.dict) /* unsafe? */
+ pdf_release_obj(I->attr.dict);
+ pdf_init_ximage_struct(I);
+}
+
+
+void
+pdf_init_images (void)
+{
+ struct ic_ *ic = &_ic;
+ ic->count = 0;
+ ic->capacity = 0;
+ ic->ximages = NULL;
+}
+
+void
+pdf_close_images (void)
+{
+ struct ic_ *ic = &_ic;
+ if (ic->ximages) {
+ int i;
+ for (i = 0; i < ic->count; i++) {
+ pdf_ximage *I = ic->ximages+i;
+ if (I->attr.tempfile) {
+ /*
+ * It is important to remove temporary files at the end because
+ * we cache file names. Since we use mkstemp to create them, we
+ * might get the same file name again if we delete the first file.
+ * (This happens on NetBSD, reported by Jukka Salmi.)
+ * We also use this to convert a PS file only once if multiple
+ * pages are imported from that file.
+ */
+ if (dpx_conf.verbose_level > 1 &&
+ dpx_conf.file.keep_cache != 1)
+ MESG("pdf_image>> deleting temporary file \"%s\"\n", I->filename);
+ dpx_delete_temp_file(I->fullname, false); /* temporary filename freed here */
+ I->fullname = NULL;
+ }
+ pdf_clean_ximage_struct(I);
+ }
+ RELEASE(ic->ximages);
+ ic->ximages = NULL;
+ ic->count = ic->capacity = 0;
+ }
+
+ if (_opts.cmdtmpl)
+ RELEASE(_opts.cmdtmpl);
+ _opts.cmdtmpl = NULL;
+}
+
+static int
+source_image_type (FILE *fp)
+{
+ int format = IMAGE_TYPE_UNKNOWN;
+
+ rewind(fp);
+ /*
+ * Make sure we check for PS *after* checking for MP since
+ * MP is a special case of PS.
+ */
+ if (check_for_jpeg(fp))
+ {
+ format = IMAGE_TYPE_JPEG;
+ }
+ else if (check_for_jp2(fp))
+ {
+ format = IMAGE_TYPE_JP2;
+ }
+#ifdef HAVE_LIBPNG
+ else if (check_for_png(fp))
+ {
+ format = IMAGE_TYPE_PNG;
+ }
+#endif
+ else if (check_for_bmp(fp))
+ {
+ format = IMAGE_TYPE_BMP;
+ } else if (check_for_pdf(fp)) {
+ format = IMAGE_TYPE_PDF;
+ } else if (check_for_mp(fp)) {
+ format = IMAGE_TYPE_MPS;
+ } else if (check_for_ps(fp)) {
+ format = IMAGE_TYPE_EPS;
+ } else {
+ format = IMAGE_TYPE_UNKNOWN;
+ }
+ rewind(fp);
+
+ return format;
+}
+
+static int
+load_image (const char *ident, const char *filename, const char *fullname, int format, FILE *fp,
+ load_options options)
+{
+ struct ic_ *ic = &_ic;
+ int id = -1, reserved = 0;
+ pdf_ximage *I;
+
+ if (ident) {
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident)) {
+ if (I->reserved) {
+ reserved = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (!reserved) {
+ id = ic->count;
+ if (ic->count >= ic->capacity) {
+ ic->capacity += 16;
+ ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
+ }
+ I = &ic->ximages[id];
+ pdf_init_ximage_struct(I);
+ if (ident) {
+ I->ident = NEW(strlen(ident)+1, char);
+ strcpy(I->ident, ident);
+ }
+ ic->count++;
+ }
+ if (filename) {
+ I->filename = NEW(strlen(filename)+1, char);
+ strcpy(I->filename, filename);
+ }
+ if (fullname) {
+ I->fullname = NEW(strlen(fullname)+1, char);
+ strcpy(I->fullname, fullname);
+ }
+
+ I->attr.page_no = options.page_no;
+ I->attr.bbox_type = options.bbox_type;
+ I->attr.dict = options.dict; /* unsafe? */
+
+ switch (format) {
+ case IMAGE_TYPE_JPEG:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[JPEG]");
+ if (jpeg_include_image(I, fp) < 0)
+ goto error;
+ I->subtype = PDF_XOBJECT_TYPE_IMAGE;
+ break;
+ case IMAGE_TYPE_JP2:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[JP2]");
+ if (jp2_include_image(I, fp) < 0)
+ goto error;
+ I->subtype = PDF_XOBJECT_TYPE_IMAGE;
+ break;
+#ifdef HAVE_LIBPNG
+ case IMAGE_TYPE_PNG:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[PNG]");
+ if (png_include_image(I, fp) < 0)
+ goto error;
+ I->subtype = PDF_XOBJECT_TYPE_IMAGE;
+ break;
+#endif
+ case IMAGE_TYPE_BMP:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[BMP]");
+ if (bmp_include_image(I, fp) < 0)
+ goto error;
+ I->subtype = PDF_XOBJECT_TYPE_IMAGE;
+ break;
+ case IMAGE_TYPE_PDF:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[PDF]");
+ {
+ int result = pdf_include_page(I, fp, fullname, options);
+ if (result > 0)
+ /* PDF version too recent */
+ result = ps_include_page(I, fullname, options);
+ if (result < 0)
+ goto error;
+ }
+ if (dpx_conf.verbose_level > 0)
+ MESG(",Page:%ld", I->attr.page_no);
+ I->subtype = PDF_XOBJECT_TYPE_FORM;
+ break;
+/*
+ case IMAGE_TYPE_EPS:
+*/
+ default:
+ if (dpx_conf.verbose_level > 0)
+ MESG(format == IMAGE_TYPE_EPS ? "[PS]" : "[UNKNOWN]");
+ if (ps_include_page(I, fullname, options) < 0)
+ goto error;
+ if (dpx_conf.verbose_level > 0)
+ MESG(",Page:%ld", I->attr.page_no);
+ I->subtype = PDF_XOBJECT_TYPE_FORM;
+ }
+
+ switch (I->subtype) {
+ case PDF_XOBJECT_TYPE_IMAGE:
+ sprintf(I->res_name, "Im%d", id);
+ break;
+ case PDF_XOBJECT_TYPE_FORM:
+ sprintf(I->res_name, "Fm%d", id);
+ break;
+ default:
+ ERROR("Unknown XObject subtype: %d", I->subtype);
+ goto error;
+ }
+
+ return id;
+
+ error:
+ pdf_clean_ximage_struct(I);
+ return -1;
+}
+
+
+#define dpx_find_file(n,d,s) (kpse_find_pict((n)))
+#define dpx_fopen(n,m) (MFOPEN((n),(m)))
+#define dpx_fclose(f) (MFCLOSE((f)))
+
+#if defined(WIN32)
+int utf8name_failed = 0;
+#endif /* WIN32 */
+
+int
+pdf_ximage_load_image (const char *ident, const char *filename, load_options options)
+{
+ struct ic_ *ic = &_ic;
+ int i, id = -1;
+ pdf_ximage *I;
+ char *fullname, *f = NULL;
+ int format;
+ FILE *fp;
+
+ for (i = 0; i < ic->count; i++) {
+ I = &ic->ximages[i];
+ if (I->filename && !strcmp(filename, I->filename)) {
+ id = i;
+ break;
+ }
+ }
+ if (id >= 0) {
+ if (I->attr.page_no == options.page_no &&
+ !pdf_compare_object(I->attr.dict, options.dict) && /* ????? */
+ I->attr.bbox_type == options.bbox_type) {
+ return id;
+ }
+ f = I->fullname;
+ }
+ if (f) {
+ /* we already have converted this file; f is the temporary file name */
+ fullname = NEW(strlen(f)+1, char);
+ strcpy(fullname, f);
+ } else {
+ /* try loading image */
+#if defined(WIN32)
+ utf8name_failed = 0;
+#endif /* WIN32 */
+ fullname = dpx_find_file(filename, "_pic_", "");
+#if defined(WIN32)
+ if (!fullname && file_system_codepage != win32_codepage) {
+ int tmpcp = file_system_codepage;
+ utf8name_failed = 1;
+ file_system_codepage = win32_codepage;
+ fullname = dpx_find_file(filename, "_pic_", "");
+ file_system_codepage = tmpcp;
+ }
+#endif /* WIN32 */
+ if (!fullname) {
+#if defined(WIN32)
+ utf8name_failed = 0;
+#endif /* WIN32 */
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode) {
+ WARN("Image inclusion failed for \"%s\".", filename);
+ } else {
+ ERROR("Image inclusion failed for \"%s\".", filename);
+ }
+ return -1;
+ }
+ }
+
+ fp = dpx_fopen(fullname, FOPEN_RBIN_MODE);
+ if (!fp) {
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode) {
+ WARN("Error opening image file \"%s\"", fullname);
+ RELEASE(fullname);
+ } else {
+ RELEASE(fullname);
+ ERROR("Image inclusion failed for \"%s\".", filename);
+ }
+ return -1;
+ }
+ if (dpx_conf.verbose_level > 0) {
+ MESG("(Image:%s", filename);
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%s]", fullname);
+ }
+
+ format = source_image_type(fp);
+ switch (format) {
+ case IMAGE_TYPE_MPS:
+ if (dpx_conf.verbose_level > 0)
+ MESG("[MPS]");
+ id = mps_include_page(filename, fp);
+ if (id < 0) {
+ WARN("Try again with the distiller.");
+ format = IMAGE_TYPE_EPS;
+ rewind(fp);
+ } else {
+ /* Workaround for the problem reported.
+ * mps_include_page() above doesn't set I->filename...
+ */
+ I = &ic->ximages[id];
+ if (!I->filename) {
+ I->filename = NEW(strlen(filename)+1, char);
+ strcpy(I->filename, filename);
+ }
+ break;
+ }
+ default:
+ id = load_image(ident, filename, fullname, format, fp, options);
+ break;
+ }
+ dpx_fclose(fp);
+
+ RELEASE(fullname);
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(")");
+
+ if (id < 0) {
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode) {
+ WARN("Image inclusion failed for \"%s\".", filename);
+ } else {
+ ERROR("Image inclusion failed for \"%s\".", filename);
+ }
+ }
+
+ return id;
+}
+
+int
+pdf_ximage_findresource (const char *ident)
+{
+ struct ic_ *ic = &_ic;
+ int id = -1;
+ pdf_ximage *I;
+
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident)) {
+ return id;
+ }
+ }
+
+ return -1;
+}
+
+/* Reference: PDF Reference 1.5 v6, pp.321--322
+ *
+ * TABLE 4.42 Additional entries specific to a type 1 form dictionary
+ *
+ * BBox rectangle (Required) An array of four numbers in the form coordinate
+ * system, giving the coordinates of the left, bottom, right,
+ * and top edges, respectively, of the form XObject's bounding
+ * box. These boundaries are used to clip the form XObject and
+ * to determine its size for caching.
+ *
+ * Matrix array (Optional) An array of six numbers specifying the form
+ * matrix, which maps form space into user space.
+ * Default value: the identity matrix [1 0 0 1 0 0].
+ */
+void
+pdf_ximage_init_form_info (xform_info *info)
+{
+ info->flags = 0;
+ info->bbox.llx = 0;
+ info->bbox.lly = 0;
+ info->bbox.urx = 0;
+ info->bbox.ury = 0;
+ info->matrix.a = 1.0;
+ info->matrix.b = 0.0;
+ info->matrix.c = 0.0;
+ info->matrix.d = 1.0;
+ info->matrix.e = 0.0;
+ info->matrix.f = 0.0;
+}
+
+/* Reference: PDF Reference 1.5 v6, pp.303--306
+ *
+ * TABLE 4.42 Additional entries specific to an image dictionary
+ *
+ * Width integer (Required) The width of the image, in samples.
+ *
+ * Height integer (Required) The height of the image, in samples.
+ *
+ * ColorSpace name or array
+ * (Required for images, except those that use the JPXDecode
+ * filter; not allowed for image masks) The color space in
+ * which image samples are specified. This may be any type
+ * of color space except Patter.
+ *
+ * If the image uses the JPXDecode filter, this entry is
+ * optional.
+ *
+ * BitsPerComponent integer
+ * (Required except for image masks and images that use the
+ * JPXDecode filter) The number of bits used to represent
+ * each color component. Only a single value may be specified;
+ * the number of bits is the same for all color components.
+ * Valid values are 1,2,4,8, and (in PDF1.5) 16. If ImageMask
+ * is true, this entry is optional, and if speficified, its
+ * value must be 1.
+ *
+ * If the image stream uses the JPXDecode filter, this entry
+ * is optional and ignored if present. The bit depth is
+ * determined in the process of decoding the JPEG2000 image.
+ */
+void
+pdf_ximage_init_image_info (ximage_info *info)
+{
+ info->flags = 0;
+ info->width = 0;
+ info->height = 0;
+ info->bits_per_component = 0;
+ info->num_components = 0;
+ info->min_dpi = 0;
+ info->xdensity = info->ydensity = 1.0;
+}
+
+void
+pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
+{
+ pdf_obj *dict;
+ ximage_info *info = image_info;
+
+ if (!PDF_OBJ_STREAMTYPE(resource))
+ ERROR("Image XObject must be of stream type.");
+
+ I->subtype = PDF_XOBJECT_TYPE_IMAGE;
+
+ I->attr.width = info->width; /* The width of the image, in samples */
+ I->attr.height = info->height; /* The height of the image, in samples */
+ I->attr.xdensity = info->xdensity;
+ I->attr.ydensity = info->ydensity;
+
+ dict = pdf_stream_dict(resource);
+ pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("XObject"));
+ pdf_add_dict(dict, pdf_new_name("Subtype"), pdf_new_name("Image"));
+ pdf_add_dict(dict, pdf_new_name("Width"), pdf_new_number(info->width));
+ pdf_add_dict(dict, pdf_new_name("Height"), pdf_new_number(info->height));
+ if (info->bits_per_component > 0) /* Ignored for JPXDecode filter. FIXME */
+ pdf_add_dict(dict, pdf_new_name("BitsPerComponent"),
+ pdf_new_number(info->bits_per_component));
+ if (I->attr.dict)
+ pdf_merge_dict(dict, I->attr.dict);
+
+ if (I->ident) {
+ int error;
+
+ error = pdf_names_add_object(global_names, I->ident, strlen(I->ident), pdf_link_obj(resource));
+ if (I->reference)
+ pdf_release_obj(I->reference);
+ if (error) {
+ I->reference = pdf_ref_obj(resource);
+ } else {
+ /* Need to create object reference before closing it */
+ I->reference = pdf_names_lookup_reference(global_names, I->ident, strlen(I->ident));
+ pdf_names_close_object(global_names, I->ident, strlen(I->ident));
+ }
+ I->reserved = 0;
+ } else {
+ I->reference = pdf_ref_obj(resource);
+ }
+ pdf_release_obj(resource); /* Caller don't know we are using reference. */
+ I->resource = NULL;
+}
+
+void
+pdf_ximage_set_form (pdf_ximage *I, void *form_info, pdf_obj *resource)
+{
+ xform_info *info = form_info;
+ pdf_coord p1, p2, p3, p4;
+
+ I->subtype = PDF_XOBJECT_TYPE_FORM;
+
+ /* Image's attribute "bbox" here is affected by /Rotate entry of included
+ * PDF page.
+ */
+ p1.x = info->bbox.llx; p1.y = info->bbox.lly;
+ pdf_dev_transform(&p1, &info->matrix);
+ p2.x = info->bbox.urx; p1.y = info->bbox.lly;
+ pdf_dev_transform(&p2, &info->matrix);
+ p3.x = info->bbox.urx; p3.y = info->bbox.ury;
+ pdf_dev_transform(&p3, &info->matrix);
+ p4.x = info->bbox.llx; p4.y = info->bbox.ury;
+ pdf_dev_transform(&p4, &info->matrix);
+
+ I->attr.bbox.llx = min4(p1.x, p2.x, p3.x, p4.x);
+ I->attr.bbox.lly = min4(p1.y, p2.y, p3.y, p4.y);
+ I->attr.bbox.urx = max4(p1.x, p2.x, p3.x, p4.x);
+ I->attr.bbox.ury = max4(p1.y, p2.y, p3.y, p4.y);
+
+ if (I->ident) {
+ int error;
+
+ error = pdf_names_add_object(global_names, I->ident, strlen(I->ident), pdf_link_obj(resource));
+ if (I->reference)
+ pdf_release_obj(I->reference);
+ if (error) {
+ I->reference = pdf_ref_obj(resource);
+ } else {
+ /* Need to create object reference before closing it */
+ I->reference = pdf_names_lookup_reference(global_names, I->ident, strlen(I->ident));
+ pdf_names_close_object(global_names, I->ident, strlen(I->ident));
+ }
+ I->reserved = 0;
+ } else {
+ I->reference = pdf_ref_obj(resource);
+ }
+ pdf_release_obj(resource); /* Caller don't know we are using reference. */
+ I->resource = NULL;
+}
+
+int
+pdf_ximage_get_page (pdf_ximage *I)
+{
+ return I->attr.page_no;
+}
+
+#define CHECK_ID(c,n) do {\
+ if ((n) < 0 || (n) >= (c)->count) {\
+ ERROR("Invalid XObject ID: %d", (n));\
+ }\
+} while (0)
+#define GET_IMAGE(c,n) (&((c)->ximages[(n)]))
+
+pdf_obj *
+pdf_ximage_get_reference (int id)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+ if (!I->reference && I->resource)
+ I->reference = pdf_ref_obj(I->resource);
+
+ return pdf_link_obj(I->reference);
+}
+
+/* called from pdfdoc.c only for late binding */
+int
+pdf_ximage_defineresource (const char *ident,
+ int subtype, void *info, pdf_obj *resource)
+{
+ struct ic_ *ic = &_ic;
+ int id, reserved = 0;
+ pdf_ximage *I;
+
+ if (ident) {
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident) && I->reserved) {
+ reserved = 1;
+ break;
+ }
+ }
+ }
+
+ if (!reserved) {
+ id = ic->count;
+ if (ic->count >= ic->capacity) {
+ ic->capacity += 16;
+ ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
+ }
+ I = &ic->ximages[id];
+ pdf_init_ximage_struct(I);
+
+ if (ident) {
+ I->ident = NEW(strlen(ident)+1, char);
+ strcpy(I->ident, ident);
+ }
+ ic->count++;
+ }
+
+ switch (subtype) {
+ case PDF_XOBJECT_TYPE_IMAGE:
+ pdf_ximage_set_image(I, info, resource);
+ sprintf(I->res_name, "Im%d", id);
+ break;
+ case PDF_XOBJECT_TYPE_FORM:
+ pdf_ximage_set_form (I, info, resource);
+ sprintf(I->res_name, "Fm%d", id);
+ break;
+ default:
+ ERROR("Unknown XObject subtype: %d", subtype);
+ }
+
+ return id;
+}
+
+int
+pdf_ximage_reserve (const char *ident)
+{
+ struct ic_ *ic = &_ic;
+ int id;
+ pdf_ximage *I;
+
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident)) {
+ WARN("XObject ID \"%s\" already used!", ident);
+ return -1;
+ }
+ }
+
+ id = ic->count;
+ if (ic->count >= ic->capacity) {
+ ic->capacity += 16;
+ ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
+ }
+
+ I = &ic->ximages[id];
+
+ pdf_init_ximage_struct(I);
+
+ if (ident) {
+ I->ident = NEW(strlen(ident)+1, char);
+ strcpy(I->ident, ident);
+ }
+ I->reference = pdf_names_reserve(global_names, ident, strlen(ident));
+ sprintf(I->res_name, "Fm%d", id);
+ I->reserved = 1;
+ ic->count++;
+
+ return id;
+}
+
+char *
+pdf_ximage_get_resname (int id)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+
+ return I->res_name;
+}
+
+int
+pdf_ximage_get_subtype (int id)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+
+ return I->subtype;
+}
+
+void
+pdf_ximage_set_attr (int id, int width, int height, double xdensity, double ydensity, double llx, double lly, double urx, double ury)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+ I->attr.width = width;
+ I->attr.height = height;
+ I->attr.xdensity = xdensity;
+ I->attr.ydensity = ydensity;
+ I->attr.bbox.llx = llx;
+ I->attr.bbox.lly = lly;
+ I->attr.bbox.urx = urx;
+ I->attr.bbox.ury = ury;
+}
+
+/* depth...
+ * Dvipdfm treat "depth" as "yoffset" for pdf:image and pdf:uxobj
+ * not as vertical dimension of scaled image. (And there are bugs.)
+ * This part contains incompatibile behaviour than dvipdfm!
+ */
+#define EBB_DPI 72
+
+static void
+scale_to_fit_I (pdf_tmatrix *T,
+ transform_info *p,
+ pdf_ximage *I)
+{
+ double s_x, s_y, d_x, d_y;
+ double wd0, ht0, dp, xscale, yscale;
+
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ wd0 = p->bbox.urx - p->bbox.llx;
+ ht0 = p->bbox.ury - p->bbox.lly;
+ xscale = I->attr.width * I->attr.xdensity / wd0;
+ yscale = I->attr.height * I->attr.ydensity / ht0;
+ d_x = -p->bbox.llx / wd0;
+ d_y = -p->bbox.lly / ht0;
+ } else {
+ wd0 = I->attr.width * I->attr.xdensity;
+ ht0 = I->attr.height * I->attr.ydensity;
+ xscale = yscale = 1.0;
+ d_x = 0.0;
+ d_y = 0.0;
+ }
+
+ if (wd0 == 0.0) {
+ WARN("Image width=0.0!");
+ wd0 = 1.0;
+ }
+ if (ht0 == 0.0) {
+ WARN("Image height=0.0!");
+ ht0 = 1.0;
+ }
+
+ if ( (p->flags & INFO_HAS_WIDTH ) &&
+ (p->flags & INFO_HAS_HEIGHT) ) {
+ s_x = p->width * xscale;
+ s_y = (p->height + p->depth) * yscale;
+ dp = p->depth * yscale;
+ } else if ( p->flags & INFO_HAS_WIDTH ) {
+ s_x = p->width * xscale;
+ s_y = s_x * ((double)I->attr.height / I->attr.width);
+ dp = 0.0;
+ } else if ( p->flags & INFO_HAS_HEIGHT) {
+ s_y = (p->height + p->depth) * yscale;
+ s_x = s_y * ((double)I->attr.width / I->attr.height);
+ dp = p->depth * yscale;
+ } else {
+ s_x = wd0;
+ s_y = ht0;
+ dp = 0.0;
+ }
+ T->a = s_x; T->c = 0.0;
+ T->b = 0.0; T->d = s_y;
+ T->e = d_x * s_x / xscale; T->f = d_y * s_y / yscale - dp;
+
+ return;
+}
+
+
+static void
+scale_to_fit_F (pdf_tmatrix *T,
+ transform_info *p,
+ pdf_ximage *I)
+{
+ double s_x, s_y, d_x, d_y;
+ double wd0, ht0, dp;
+
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ wd0 = p->bbox.urx - p->bbox.llx;
+ ht0 = p->bbox.ury - p->bbox.lly;
+ d_x = -p->bbox.llx;
+ d_y = -p->bbox.lly;
+ } else {
+ wd0 = I->attr.bbox.urx - I->attr.bbox.llx;
+ ht0 = I->attr.bbox.ury - I->attr.bbox.lly;
+ d_x = 0.0;
+ d_y = 0.0;
+ }
+
+ if (wd0 == 0.0) {
+ WARN("Image width=0.0!");
+ wd0 = 1.0;
+ }
+ if (ht0 == 0.0) {
+ WARN("Image height=0.0!");
+ ht0 = 1.0;
+ }
+
+ if ( (p->flags & INFO_HAS_WIDTH ) &&
+ (p->flags & INFO_HAS_HEIGHT) ) {
+ s_x = p->width / wd0;
+ s_y = (p->height + p->depth) / ht0;
+ dp = p->depth;
+ } else if ( p->flags & INFO_HAS_WIDTH ) {
+ s_x = p->width / wd0;
+ s_y = s_x;
+ dp = 0.0;
+ } else if ( p->flags & INFO_HAS_HEIGHT) {
+ s_y = (p->height + p->depth) / ht0;
+ s_x = s_y;
+ dp = p->depth;
+ } else {
+ s_x = s_y = 1.0;
+ dp = 0.0;
+ }
+
+ T->a = s_x; T->c = 0.0;
+ T->b = 0.0; T->d = s_y;
+ T->e = s_x * d_x; T->f = s_y * d_y - dp;
+
+ return;
+}
+
+
+/* called from pdfdev.c and spc_html.c */
+int
+pdf_ximage_scale_image (int id,
+ pdf_tmatrix *M, /* return value for trans matrix */
+ pdf_rect *r, /* return value for clipping */
+ transform_info *p /* argument from specials */
+ )
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+
+ pdf_setmatrix(M, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+
+ switch (I->subtype) {
+ /* Reference: PDF Reference 1.5 v6, p.302
+ *
+ * An image can be placed on the output page in any desired position,
+ * orientation, and size by using the cm operator to modify the current
+ * transformation matrix (CTM) so as to map the unit square of user space
+ * to the rectangle or parallelogram in which the image is to be painted.
+ *
+ * There is neither BBox nor Matrix key in the image XObject.
+ * Everything must be controlled by the cm operator.
+ *
+ * The argument [p] contains the user-defined bounding box, the scailing
+ * factor of which is bp as EPS and PDF. On the other hand, I->attr
+ * contains the (sampling) width and the (sampling) height of the image.
+ *
+ * There is no problem if a bitmap image has density information.
+ * Otherwise, DVIPDFM's ebb generates bounding box as 100px = 72bp = 1in.
+ * In this case, screen captured images look bad. Moreover, DVIPDFM's ebb
+ * ignores all density information and use just 100px = 72bp = 1in.
+ *
+ * On the other hand, pdfTeX uses 100px = 100bp to get a better quality
+ * for screen captured images.
+ *
+ * DVIPDFMx's xbb generates bounding box as 100px = 100bp in the same
+ * way as pdfTeX. Furthermore, it takes care of density information too.
+ */
+ case PDF_XOBJECT_TYPE_IMAGE:
+ scale_to_fit_I(M, p, I);
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ r->llx = p->bbox.llx / (I->attr.width * I->attr.xdensity);
+ r->lly = p->bbox.lly / (I->attr.height * I->attr.ydensity);
+ r->urx = p->bbox.urx / (I->attr.width * I->attr.xdensity);
+ r->ury = p->bbox.ury / (I->attr.height * I->attr.ydensity);
+ } else {
+ r->llx = 0.0;
+ r->lly = 0.0;
+ r->urx = 1.0;
+ r->ury = 1.0;
+ }
+ break;
+ /* User-defined transformation and clipping are controlled by
+ * the cm operator and W operator, explicitly */
+ case PDF_XOBJECT_TYPE_FORM:
+ scale_to_fit_F(M, p, I);
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ r->llx = p->bbox.llx;
+ r->lly = p->bbox.lly;
+ r->urx = p->bbox.urx;
+ r->ury = p->bbox.ury;
+ } else { /* I->attr.bbox from the image bounding box */
+ r->llx = I->attr.bbox.llx;
+ r->lly = I->attr.bbox.lly;
+ r->urx = I->attr.bbox.urx;
+ r->ury = I->attr.bbox.ury;
+ }
+ break;
+ default: /* maybe reserved */
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ r->llx = p->bbox.llx;
+ r->lly = p->bbox.lly;
+ r->urx = p->bbox.urx;
+ r->ury = p->bbox.ury;
+ } else { /* I->attr.bbox from the image bounding box */
+ r->llx = 0.0;
+ r->lly = 0.0;
+ r->urx = 1.0;
+ r->ury = 1.0;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Migrated from psimage.c */
+
+void set_distiller_template (char *s)
+{
+ if (_opts.cmdtmpl)
+ RELEASE(_opts.cmdtmpl);
+ if (!s || *s == '\0')
+ _opts.cmdtmpl = NULL;
+ else {
+ _opts.cmdtmpl = NEW(strlen(s) + 1, char);
+ strcpy(_opts.cmdtmpl, s);
+ }
+ return;
+}
+
+char *get_distiller_template (void)
+{
+ return _opts.cmdtmpl;
+}
+
+static int
+ps_include_page (pdf_ximage *ximage, const char *filename, load_options options)
+{
+ char *distiller_template = _opts.cmdtmpl;
+ char *temp;
+ FILE *fp;
+ int error = 0;
+ struct stat stat_o, stat_t;
+
+ if (!distiller_template) {
+ WARN("No image converter available for converting file \"%s\" to PDF format.", filename);
+ WARN(">> Please check if you have 'D' option in config file.");
+ return -1;
+ }
+
+ temp = dpx_create_fix_temp_file(filename);
+ if (!temp) {
+ WARN("Failed to create temporary file for image conversion: %s", filename);
+ return -1;
+ }
+
+#ifdef MIKTEX
+ {
+ char *p;
+ for (p = (char *)filename; *p; p++) {
+ if (*p == '\\') *p = '/';
+ }
+ for (p = (char *)temp; *p; p++) {
+ if (*p == '\\') *p = '/';
+ }
+ }
+#endif
+
+#if defined(_WIN32)
+/* temp is always ASCII only. So fsyscp_stat() is not necessary for
+ * temp. However, filename can be non-ASCII UTF-8.
+ */
+ if (dpx_conf.file.keep_cache != -1 &&
+ stat(temp, &stat_t)==0 &&
+ (fsyscp_stat(filename, &stat_o)==0 ||
+ stat(filename, &stat_o)==0) &&
+ stat_t.st_mtime > stat_o.st_mtime) {
+#else
+ if (dpx_conf.file.keep_cache != -1 &&
+ stat(temp, &stat_t)==0 && stat(filename, &stat_o)==0 &&
+ stat_t.st_mtime > stat_o.st_mtime) {
+#endif /* _WIN32 */
+ /* cache exist */
+ /*printf("\nLast file modification: %s", ctime(&stat_o.st_mtime));
+ printf("Last file modification: %s", ctime(&stat_t.st_mtime));*/
+ ;
+ } else {
+ if (dpx_conf.verbose_level > 1) {
+ MESG("\n");
+ MESG("pdf_image>> Converting file \"%s\" --> \"%s\" via:\n", filename, temp);
+ MESG("pdf_image>> %s\n", distiller_template);
+ MESG("pdf_image>> ...");
+ }
+ error = dpx_file_apply_filter(distiller_template, filename, temp,
+ pdf_get_version());
+ if (error) {
+ WARN("Image format conversion for \"%s\" failed...", filename);
+ dpx_delete_temp_file(temp, true);
+ return error;
+ }
+ }
+
+ fp = MFOPEN(temp, FOPEN_RBIN_MODE);
+ if (!fp) {
+ WARN("Could not open conversion result \"%s\" for image \"%s\". Why?", temp, filename);
+ dpx_delete_temp_file(temp, true);
+ return -1;
+ }
+ pdf_set_ximage_tempfile(ximage, temp);
+ error = pdf_include_page(ximage, fp, temp, options);
+ MFCLOSE(fp);
+
+ /* See pdf_close_images for why we cannot delete temporary files here. */
+
+ RELEASE(temp);
+
+ if (error) {
+ WARN("Failed to include image file \"%s\"", filename);
+ WARN(">> Please check if");
+ WARN(">> %s", distiller_template);
+ WARN(">> %%o = output filename, %%i = input filename, %%b = input filename without suffix");
+ WARN(">> can really convert \"%s\" to PDF format image.", filename);
+ }
+
+ return error;
+}
+
+static int check_for_ps (FILE *image_file)
+{
+ rewind (image_file);
+ mfgets (work_buffer, WORK_BUFFER_SIZE, image_file);
+ if (!strncmp (work_buffer, "%!", 2))
+ return 1;
+ return 0;
+}
+
+static int check_for_mp (FILE *image_file)
+{
+ int try_count = 10;
+
+ rewind (image_file);
+ mfgets(work_buffer, WORK_BUFFER_SIZE, image_file);
+ if (strncmp(work_buffer, "%!PS", 4))
+ return 0;
+
+ while (try_count > 0) {
+ mfgets(work_buffer, WORK_BUFFER_SIZE, image_file);
+ if (!strncmp(work_buffer, "%%Creator:", 10)) {
+ if (strlen(work_buffer+10) >= 8 &&
+ strstr(work_buffer+10, "MetaPost"))
+ break;
+ }
+ try_count--;
+ }
+
+ return ((try_count > 0) ? 1 : 0);
+}
+
+/* ERROR() can't be used here otherwise the cleanup routine is recursively called. */
+#undef ERROR
+void
+pdf_error_cleanup_cache (void)
+{
+ struct ic_ *ic = &_ic;
+ int i;
+ pdf_ximage *I;
+
+ for (i = 0; i < ic->count; i++) {
+ I = &ic->ximages[i];
+ if (I->attr.tempfile) {
+ dpx_delete_temp_file(I->fullname, false); /* temporary filename freed here */
+ }
+ }
+}
diff --git a/Build/source/texk/dvipdfm-x/pdfximage.h b/Build/source/texk/dvipdfm-x/pdfximage.h
new file mode 100644
index 00000000000..6cd99055dc6
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pdfximage.h
@@ -0,0 +1,103 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PDFXIMAGE_H_
+#define _PDFXIMAGE_H_
+
+#include "pdfdev.h"
+#include "pdfdoc.h"
+
+#define PDF_XOBJECT_TYPE_FORM 0
+#define PDF_XOBJECT_TYPE_IMAGE 1
+
+typedef struct {
+ int flags;
+
+ int width;
+ int height;
+
+ int bits_per_component;
+ int num_components;
+
+ int min_dpi; /* NOT USED YET */
+
+ double xdensity, ydensity; /* scale factor for bp */
+} ximage_info;
+
+typedef struct {
+ int flags;
+
+ pdf_rect bbox;
+ pdf_tmatrix matrix;
+} xform_info;
+
+typedef struct {
+ int page_no;
+ enum pdf_page_boundary bbox_type;
+ pdf_obj *dict;
+} load_options;
+
+typedef struct pdf_ximage_ pdf_ximage;
+
+extern void pdf_init_images (void);
+extern void pdf_close_images (void);
+
+extern char *pdf_ximage_get_resname (int xobj_id);
+extern pdf_obj *pdf_ximage_get_reference (int xobj_id);
+
+extern int pdf_ximage_findresource (const char *ident);
+extern int pdf_ximage_load_image (const char *ident, const char *filename, load_options options);
+extern int pdf_ximage_defineresource (const char *ident, int subtype, void *cdata, pdf_obj *resource);
+extern int pdf_ximage_reserve (const char *ident);
+
+/* Called by pngimage, jpegimage, epdf, mpost, etc. */
+extern void pdf_ximage_init_image_info (ximage_info *info);
+extern void pdf_ximage_init_form_info (xform_info *info);
+extern void pdf_ximage_set_image (pdf_ximage *ximage,
+ void *info, pdf_obj *resource);
+extern void pdf_ximage_set_form (pdf_ximage *ximage,
+ void *info, pdf_obj *resource);
+extern int pdf_ximage_get_page (pdf_ximage *I);
+
+/* from pdfximage.c */
+extern void set_distiller_template (char *s);
+extern char *get_distiller_template (void);
+
+extern int
+pdf_ximage_scale_image (int id,
+ pdf_tmatrix *M, /* ret */
+ pdf_rect *r, /* ret */
+ transform_info *p /* arg */
+ );
+
+/* from spc_pdfm.c */
+extern int pdf_ximage_get_subtype (int xobj_id);
+extern void
+pdf_ximage_set_attr (int xobj_id,
+ int width, int height, double xdensity, double ydensity,
+ double llx, double lly, double urx, double ury);
+
+/* Migrated from pdfobj.h. Those are not PDF object related... */
+
+extern void pdf_error_cleanup_cache (void);
+
+#endif /* _PDFXIMAGE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pkfont.c b/Build/source/texk/dvipdfm-x/pkfont.c
new file mode 100644
index 00000000000..79d2d28d575
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pkfont.c
@@ -0,0 +1,753 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxfile.h"
+
+#include "numbers.h"
+#include "pdfobj.h"
+#include "pdfdev.h" /* pdf_rect */
+
+#include "pdfencoding.h"
+#include "pdffont.h"
+
+#include "pkfont.h"
+
+#define ENABLE_GLYPHENC 1
+
+#ifndef PKFONT_DPI_DEFAULT
+#define PKFONT_DPI_DEFAULT 600u
+#endif
+
+static unsigned base_dpi = PKFONT_DPI_DEFAULT;
+
+void
+PKFont_set_dpi (int dpi)
+{
+ if (dpi <= 0)
+ ERROR("Invalid DPI: %d\n", dpi);
+ base_dpi = dpi;
+}
+
+
+/* (Only) This requires TFM to get design size... */
+#include "tfm.h"
+
+static unsigned
+truedpi (const char *ident, double point_size, unsigned bdpi)
+{
+ unsigned dpi = bdpi;
+ double design_size;
+ int tfm_id;
+
+ tfm_id = tfm_open(ident, 0);
+ if (tfm_id < 0)
+ return dpi;
+
+ design_size = tfm_get_design_size(tfm_id);
+ if (design_size <= 0.0)
+ WARN("DESGIN_SIZE <= 0.0? (TFM=\"%s\")", ident);
+ else {
+ dpi = (unsigned) ROUND(base_dpi * point_size / design_size, 1.0);
+ }
+
+ return dpi;
+}
+
+static FILE *
+dpx_open_pk_font_at (const char *ident, unsigned dpi, char **pkname)
+{
+ FILE *fp;
+ char *fqpn;
+ kpse_glyph_file_type kpse_file_info;
+/*
+ * ident can be such as "cmr10.pfb":
+ * https://tug.org/pipermail/dvipdfmx/2020-December/000142.html.
+ * As a workaround, we drop a suffix if it exists.
+ *
+ */
+ char *ident_nosuffix;
+ ident_nosuffix = xstrdup(ident);
+ fqpn = strrchr(ident_nosuffix, '.');
+ if (fqpn) {
+ *fqpn = '\0';
+ }
+ fqpn = kpse_find_glyph(ident_nosuffix, dpi, kpse_pk_format, &kpse_file_info);
+
+ if (!fqpn)
+ return NULL;
+ fp = MFOPEN(fqpn, FOPEN_RBIN_MODE);
+ RELEASE(fqpn);
+ *pkname = NEW(strlen(ident_nosuffix)+12, char);
+ (void)snprintf(*pkname, strlen(ident_nosuffix)+12, "%s.%dpk", ident_nosuffix, dpi);
+ RELEASE(ident_nosuffix);
+
+ return fp;
+}
+
+
+int
+pdf_font_open_pkfont (pdf_font *font, const char *ident, int index, int encoding_id, int embedding, double point_size)
+{
+ unsigned dpi;
+ FILE *fp;
+ char *pkname;
+
+ if (!ident || point_size <= 0.0)
+ return -1;
+ if (!embedding) {
+ WARN("Ignoring no-embed option for PK font: %s", ident);
+ }
+ if (index != 0) {
+ WARN("Ignoring font index option for PK font: %s", ident);
+ }
+
+ dpi = truedpi(ident, point_size, base_dpi);
+ fp = dpx_open_pk_font_at(ident, dpi, &pkname);
+ if (!fp)
+ return -1;
+ MFCLOSE(fp);
+
+ /* Type 3 fonts doesn't have FontName.
+ * FontFamily is recommended for PDF 1.5.
+ */
+ font->fontname = pkname;
+
+ if (encoding_id >= 0) {
+ pdf_encoding_used_by_type3(encoding_id);
+ WARN("PK font is found for font \"%s\" but non built-in encoding \"%s\" is specified.",
+ ident, pdf_encoding_get_name(encoding_id));
+#if ENABLE_GLYPHENC
+ WARN(">> Assuming this is for glyph name assignment.");
+#else
+ WARN(">> I can't reencode PK font. (not enough information available)");
+ WARN(">> Maybe you need to install pfb/opentype/truetype font.");
+#endif
+ }
+
+ return 0;
+}
+
+
+/* We are using Mask Image. Fill black is bit clear.
+ * Optimizing those codes doesn't improve things.
+ */
+static uint32_t
+fill_black_run (unsigned char *dp, uint32_t left, uint32_t run_count)
+{
+ const static unsigned char mask[8] = {
+ 127u, 191u, 223u, 239u, 247u, 251u, 253u, 254u
+ };
+ uint32_t right = left + run_count - 1;
+ for ( ; left <= right; left++) {
+ dp[left / 8] &= mask[left % 8];
+ }
+ return run_count;
+}
+
+/* Just skip bits. See decode_packed() */
+static uint32_t
+fill_white_run (uint32_t run_count)
+{
+ return run_count;
+}
+
+static uint32_t
+pk_packed_num (uint32_t *np, int dyn_f, unsigned char *dp, uint32_t pl)
+{
+ uint32_t nmbr = 0, i = *np;
+ int nyb, j;
+#define get_nyb() ((i % 2) ? dp[i/2] & 0x0f : (dp[i/2] >> 4) & 0x0f)
+
+ if (i / 2 == pl) {
+ WARN("EOD reached while unpacking pk_packed_num.");
+ return 0;
+ }
+ nyb = get_nyb(); i++;
+ if (nyb == 0) {
+ j = 0;
+ do {
+ if (i / 2 == pl) {
+ WARN("EOD reached while unpacking pk_packed_num.");
+ break;
+ }
+ nyb = get_nyb(); i++;
+ j++;
+ } while (nyb == 0);
+ nmbr = nyb;
+ while (j-- > 0) {
+ if (i / 2 == pl) {
+ WARN("EOD reached while unpacking pk_packed_num.");
+ break;
+ }
+ nyb = get_nyb(); i++;
+ nmbr = nmbr * 16 + nyb;
+ }
+ nmbr += (13 - dyn_f) * 16 + dyn_f - 15;
+ } else if (nyb <= dyn_f) {
+ nmbr = nyb;
+ } else if (nyb < 14) {
+ if (i / 2 == pl) {
+ WARN("EOD reached while unpacking pk_packed_num.");
+ return 0;
+ }
+ nmbr = (nyb - dyn_f - 1) * 16 + get_nyb() + dyn_f + 1;
+ i++;
+ }
+
+ *np = i;
+ return nmbr;
+}
+
+
+static void
+send_out (unsigned char *rowptr, uint32_t rowbytes, pdf_obj *stream)
+{
+ pdf_add_stream(stream, (void *)rowptr, rowbytes);
+}
+
+static int
+pk_decode_packed (pdf_obj *stream, uint32_t wd, uint32_t ht,
+ int dyn_f, int run_color, unsigned char *dp, uint32_t pl)
+{
+ unsigned char *rowptr;
+ uint32_t rowbytes;
+ uint32_t i, np = 0;
+ uint32_t run_count = 0, repeat_count = 0;
+
+ rowbytes = (wd + 7) / 8;
+ rowptr = NEW(rowbytes, unsigned char);
+ /* repeat count is applied to the *current* row.
+ * "run" can span across rows.
+ * If there are non-zero repeat count and if run
+ * spans across row, first repeat and then continue.
+ */
+ for (np = 0, i = 0; i < ht; i++) {
+ uint32_t rowbits_left, nbits;
+
+ repeat_count = 0;
+ memset(rowptr, 0xff, rowbytes); /* 1 is white */
+ rowbits_left = wd;
+ /* Fill run left over from previous row */
+ if (run_count > 0) {
+ nbits = MIN(rowbits_left, run_count);
+ switch (run_color) {
+ case 0:
+ rowbits_left -= fill_black_run(rowptr, 0, nbits);
+ break;
+ case 1:
+ rowbits_left -= fill_white_run(nbits);
+ break;
+ }
+ run_count -= nbits;
+ }
+
+ /* Read nybbles until we have a full row */
+ while (np / 2 < pl && rowbits_left > 0) {
+ int nyb;
+
+ nyb = (np % 2) ? dp[np/2] & 0x0f : (dp[np/2] >> 4) & 0x0f;
+ if (nyb == 14) { /* packed number "repeat_count" follows */
+ if (repeat_count != 0)
+ WARN("Second repeat count for this row!");
+ np++; /* Consume this nybble */
+ repeat_count = pk_packed_num(&np, dyn_f, dp, pl);
+ } else if (nyb == 15) {
+ if (repeat_count != 0)
+ WARN("Second repeat count for this row!");
+ np++; /* Consume this nybble */
+ repeat_count = 1;
+ } else { /* run_count */
+ /* Interprete current nybble as packed number */
+ run_count = pk_packed_num(&np, dyn_f, dp, pl);
+ nbits = MIN(rowbits_left, run_count);
+ run_color = !run_color;
+ run_count -= nbits;
+ switch (run_color) {
+ case 0:
+ rowbits_left -= fill_black_run(rowptr, wd - rowbits_left, nbits);
+ break;
+ case 1:
+ rowbits_left -= fill_white_run(nbits);
+ break;
+ }
+ }
+ }
+ /* We got bitmap row data. */
+ send_out(rowptr, rowbytes, stream);
+ for ( ; i < ht && repeat_count > 0; repeat_count--, i++)
+ send_out(rowptr, rowbytes, stream);
+ }
+ RELEASE(rowptr);
+
+ return 0;
+}
+
+static int
+pk_decode_bitmap (pdf_obj *stream, uint32_t wd, uint32_t ht,
+ int dyn_f, int run_color, unsigned char *dp, uint32_t pl)
+{
+ unsigned char *rowptr, c;
+ uint32_t i, j, rowbytes;
+ const static unsigned char mask[8] = {
+ 0x80u, 0x40u, 0x20u, 0x10u, 0x08u, 0x04u, 0x02u, 0x01u
+ };
+
+ ASSERT( dyn_f == 14 );
+ if (run_color != 0) {
+ WARN("run_color != 0 for bitmap pk data?");
+ } else if (pl < (wd * ht + 7) / 8) {
+ WARN("Insufficient bitmap pk data. %ldbytes expected but only %ldbytes read.",
+ (wd * ht + 7) / 8, pl);
+ return -1;
+ }
+
+ rowbytes = (wd + 7) / 8;
+ rowptr = NEW(rowbytes, unsigned char);
+ memset(rowptr, 0, rowbytes);
+ /* Flip. PK bitmap is not byte aligned for each rows. */
+ for (i = 0, j = 0; i < ht * wd; i++) {
+ c = dp[i / 8] & mask[i % 8];
+ if (c == 0)
+ rowptr[j / 8] |= mask[i % 8]; /* flip bit */
+ j++;
+ if (j == wd) {
+ send_out(rowptr, rowbytes, stream);
+ memset(rowptr, 0, rowbytes);
+ j = 0;
+ }
+ }
+
+ return 0;
+}
+
+
+static void
+do_preamble (FILE *fp)
+{
+ /* Check for id byte */
+ if (fgetc(fp) == 89) {
+ /* Skip comment */
+ skip_bytes(get_unsigned_byte(fp), fp);
+ /* Skip other header info. It's normally used for verifying this
+ is the file wethink it is */
+ skip_bytes(16, fp);
+ } else {
+ ERROR("embed_pk_font: PK ID byte is incorrect. Are you sure this is a PK file?");
+ }
+ return;
+}
+
+struct pk_header_
+{
+ uint32_t pkt_len;
+ int32_t chrcode;
+ int32_t wd, dx, dy;
+ uint32_t bm_wd, bm_ht;
+ int32_t bm_hoff, bm_voff;
+ int dyn_f, run_color;
+};
+
+static int
+read_pk_char_header (struct pk_header_ *h, unsigned char opcode, FILE *fp)
+{
+ ASSERT(h);
+
+ if ((opcode & 4) == 0) { /* short */
+ h->pkt_len = (opcode & 3) << 8 | get_unsigned_byte(fp);
+ h->chrcode = get_unsigned_byte(fp);
+ h->wd = get_unsigned_triple(fp); /* TFM width */
+ h->dx = get_unsigned_byte(fp) << 16; /* horizontal escapement */
+ h->dy = 0;
+ h->bm_wd = get_unsigned_byte(fp);
+ h->bm_ht = get_unsigned_byte(fp);
+ h->bm_hoff = get_signed_byte(fp);
+ h->bm_voff = get_signed_byte(fp);
+ h->pkt_len -= 8;
+ } else if ((opcode & 7) == 7) { /* long */
+ h->pkt_len = get_positive_quad(fp, "PK", "pkt_len");
+ h->chrcode = get_signed_quad(fp);
+ h->wd = get_signed_quad(fp);
+ h->dx = get_signed_quad(fp); /* 16.16 fixed point number in pixels */
+ h->dy = get_signed_quad(fp);
+ h->bm_wd = get_positive_quad(fp, "PK", "bm_wd");
+ h->bm_ht = get_positive_quad(fp, "PK", "bm_ht");
+ h->bm_hoff = get_signed_quad(fp);
+ h->bm_voff = get_signed_quad(fp);
+ h->pkt_len -= 28;
+ } else { /* extended short */
+ h->pkt_len = (opcode & 3) << 16 | get_unsigned_pair(fp);
+ h->chrcode = get_unsigned_byte(fp);
+ h->wd = get_unsigned_triple(fp);
+ h->dx = get_unsigned_pair(fp) << 16;
+ h->dy = 0;
+ h->bm_wd = get_unsigned_pair(fp);
+ h->bm_ht = get_unsigned_pair(fp);
+ h->bm_hoff = get_signed_pair(fp);
+ h->bm_voff = get_signed_pair(fp);
+ h->pkt_len -= 13;
+ }
+
+ h->dyn_f = opcode / 16;
+ h->run_color = (opcode & 8) ? 1 : 0;
+
+ if ((uint32_t)h->chrcode > 0xff)
+ {
+ WARN("Unable to handle long characters in PK files: code=0x%04x", h->chrcode);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* CCITT Group 4 filter may reduce file size. */
+static pdf_obj *
+create_pk_CharProc_stream (struct pk_header_ *pkh,
+ double chrwid,
+ unsigned char *pkt_ptr, uint32_t pkt_len)
+{
+ pdf_obj *stream; /* charproc */
+ int32_t llx, lly, urx, ury;
+ int len;
+
+ llx = -pkh->bm_hoff;
+ lly = pkh->bm_voff - pkh->bm_ht;
+ urx = pkh->bm_wd - pkh->bm_hoff;
+ ury = pkh->bm_voff;
+
+ stream = pdf_new_stream(STREAM_COMPRESS);
+ /*
+ * The following line is a "metric" for the PDF reader:
+ *
+ * PDF Reference Reference, 4th ed., p.385.
+ *
+ * The wx (first operand of d1) must be consistent with the corresponding
+ * width in the font's Widths array. The format string of sprint() must be
+ * consistent with write_number() in pdfobj.c.
+ */
+ len = pdf_sprint_number(work_buffer, chrwid);
+ len += sprintf (work_buffer + len, " 0 %d %d %d %d d1\n", llx, lly, urx, ury);
+ pdf_add_stream(stream, work_buffer, len);
+ /*
+ * Acrobat dislike transformation [0 0 0 0 dx dy].
+ * PDF Reference, 4th ed., p.147, says,
+ *
+ * Use of a noninvertible matrix when painting graphics objects can result in
+ * unpredictable behavior.
+ *
+ * but it does not forbid use of such transformation.
+ */
+ if (pkh->bm_wd != 0 && pkh->bm_ht != 0 && pkt_len > 0) {
+ /* Scale and translate origin to lower left corner for raster data */
+ len = sprintf (work_buffer, "q\n%u 0 0 %u %d %d cm\n", pkh->bm_wd, pkh->bm_ht, llx, lly);
+ pdf_add_stream(stream, work_buffer, len);
+ len = sprintf (work_buffer, "BI\n/W %u\n/H %u\n/IM true\n/BPC 1\nID ", pkh->bm_wd, pkh->bm_ht);
+ pdf_add_stream(stream, work_buffer, len);
+ /* Add bitmap data */
+ if (pkh->dyn_f == 14) /* bitmap */
+ pk_decode_bitmap(stream,
+ pkh->bm_wd, pkh->bm_ht,
+ pkh->dyn_f, pkh->run_color,
+ pkt_ptr, pkt_len);
+ else
+ pk_decode_packed(stream,
+ pkh->bm_wd, pkh->bm_ht,
+ pkh->dyn_f, pkh->run_color,
+ pkt_ptr, pkt_len);
+ len = sprintf (work_buffer, "\nEI\nQ");
+ pdf_add_stream(stream, work_buffer, len);
+ } /* Otherwise we embed an empty stream :-( */
+
+ return stream;
+}
+
+#define PK_XXX1 240
+#define PK_XXX2 241
+#define PK_XXX3 242
+#define PK_XXX4 243
+#define PK_YYY 244
+#define PK_POST 245
+#define PK_NO_OP 246
+#define PK_PRE 247
+
+#define pk_char2name(b,c) sprintf((b), "x%02X", (unsigned char)(c))
+int
+pdf_font_load_pkfont (pdf_font *font)
+{
+ char *pkname;
+ pdf_obj *fontdict;
+ char *usedchars;
+ char *ident;
+ unsigned dpi;
+ FILE *fp;
+ double point_size, pix2charu;
+ int opcode, code, firstchar, lastchar, prev;
+ pdf_obj *charprocs, *procset, *encoding, *tmp_array;
+ double widths[256];
+ pdf_rect bbox;
+ char charavail[256];
+#if ENABLE_GLYPHENC
+ int encoding_id;
+ char **enc_vec;
+#endif /* ENABLE_GLYPHENC */
+ int error = 0;
+
+ if (!font->reference)
+ return 0;
+
+ ident = font->filename;
+ point_size = font->point_size;
+ usedchars = font->usedchars;
+#if ENABLE_GLYPHENC
+ encoding_id = font->encoding_id;
+ if (encoding_id < 0)
+ enc_vec = NULL;
+ else {
+ enc_vec = pdf_encoding_get_encoding(encoding_id);
+ }
+#endif /* ENABLE_GLYPHENC */
+
+ ASSERT(ident && usedchars && point_size > 0.0);
+
+ dpi = truedpi(ident, point_size, base_dpi);
+ fp = dpx_open_pk_font_at(ident, dpi, &pkname);
+ if (!fp) {
+ ERROR("Could not find/open PK font file: %s (at %udpi)", ident, dpi);
+ }
+ font->filename = pkname;
+ memset(charavail, 0, 256);
+ charprocs = pdf_new_dict();
+ /* Include bitmap as 72dpi image:
+ * There seems to be problems in "scaled" bitmap glyph
+ * rendering in several viewers.
+ */
+ pix2charu = 72. * 1000. / ((double) base_dpi) / point_size;
+ bbox.llx = bbox.lly = HUGE_VAL;
+ bbox.urx = bbox.ury = -HUGE_VAL;
+ while ((opcode = fgetc(fp)) >= 0 && opcode != PK_POST) {
+ if (opcode < 240) {
+ struct pk_header_ pkh;
+
+ error = read_pk_char_header(&pkh, opcode, fp);
+ if (error)
+ ERROR("Error in reading PK character header.");
+ else if (charavail[pkh.chrcode & 0xff])
+ WARN("More than two bitmap image for single glyph?: font=\"%s\" code=0x%02x",
+ ident, pkh.chrcode);
+
+ if (!usedchars[pkh.chrcode & 0xff])
+ skip_bytes(pkh.pkt_len, fp);
+ else {
+ char *charname;
+ pdf_obj *charproc;
+ unsigned char *pkt_ptr;
+ size_t bytesread;
+ double charwidth;
+
+ /* Charwidth in PDF units */
+ charwidth = ROUND(1000.0 * pkh.wd / (((double) (1<<20))*pix2charu), 0.1);
+ widths[pkh.chrcode & 0xff] = charwidth;
+
+ /* Update font BBox info */
+ bbox.llx = MIN(bbox.llx, -pkh.bm_hoff);
+ bbox.lly = MIN(bbox.lly, (double)pkh.bm_voff - (double)pkh.bm_ht);
+ bbox.urx = MAX(bbox.urx, (double)pkh.bm_wd - (double)pkh.bm_hoff);
+ bbox.ury = MAX(bbox.ury, pkh.bm_voff);
+
+ pkt_ptr = NEW(pkh.pkt_len, unsigned char);
+ if ((bytesread = fread(pkt_ptr, 1, pkh.pkt_len, fp))!= pkh.pkt_len) {
+ ERROR("Only %ld bytes PK packet read. (expected %ld bytes)",
+ bytesread, pkh.pkt_len);
+ }
+ charproc = create_pk_CharProc_stream(&pkh, charwidth, pkt_ptr, bytesread);
+ RELEASE(pkt_ptr);
+ if (!charproc)
+ ERROR("Unpacking PK character data failed.");
+#if ENABLE_GLYPHENC
+ if (encoding_id >= 0 && enc_vec) {
+ charname = (char *) enc_vec[pkh.chrcode & 0xff];
+ if (!charname) {
+ WARN("\".notdef\" glyph used in font (code=0x%02x): %s", pkh.chrcode, ident);
+ charname = work_buffer;
+ pk_char2name(charname, pkh.chrcode);
+ }
+ }
+ else
+#endif /* ENABLE_GLYPHENC */
+ {
+ charname = work_buffer;
+ pk_char2name(charname, pkh.chrcode);
+ }
+
+ pdf_add_dict(charprocs, pdf_new_name(charname), pdf_ref_obj(charproc)); /* _FIXME_ */
+ pdf_release_obj(charproc);
+ }
+ charavail[pkh.chrcode & 0xff] = 1;
+ } else { /* A command byte */
+ switch (opcode) {
+ case PK_NO_OP: break;
+ case PK_XXX1: case PK_XXX2: case PK_XXX3: case PK_XXX4:
+ {
+ int32_t len = get_unsigned_num(fp, opcode-PK_XXX1);
+ if (len < 0)
+ WARN("PK: Special with %d bytes???", len);
+ else
+ skip_bytes(len, fp);
+ break;
+ }
+ case PK_YYY: skip_bytes(4, fp); break;
+ case PK_PRE: do_preamble(fp); break;
+ }
+ }
+ }
+ MFCLOSE(fp);
+
+ /* Check if we really got all glyphs needed. */
+ for (code = 0; code < 256; code++) {
+ if (usedchars[code] && !charavail[code])
+ WARN("Missing glyph code=0x%02x in PK font \"%s\".", code, ident);
+ }
+
+ /* Now actually fill fontdict. */
+ fontdict = pdf_font_get_resource(font);
+
+ pdf_add_dict(fontdict,
+ pdf_new_name("CharProcs"), pdf_ref_obj(charprocs));
+ pdf_release_obj(charprocs);
+
+ /*
+ * Resources:
+ *
+ * PDF Reference 4th ed. describes it as "Optional but strongly recommended".
+ * There are no reason to put it in our case, but we will put this.
+ * We do not care about compatibility with Acrobat 2.x. (See implementation
+ * note 47, Appendix H of PDF Ref., 4th ed.).
+ */
+ procset = pdf_new_dict();
+ tmp_array = pdf_new_array();
+ pdf_add_array(tmp_array, pdf_new_name("PDF"));
+ pdf_add_array(tmp_array, pdf_new_name("ImageB"));
+ pdf_add_dict(procset,
+ pdf_new_name("ProcSet"), tmp_array);
+ pdf_add_dict(fontdict,
+ pdf_new_name("Resources"), procset);
+
+ /* Encoding */
+ tmp_array = pdf_new_array();
+ prev = -2; firstchar = 255; lastchar = 0;
+ for (code = 0; code < 256; code++) {
+ char *charname;
+ if (usedchars[code]) {
+ if (code < firstchar) firstchar = code;
+ if (code > lastchar) lastchar = code;
+ if (code != prev + 1)
+ pdf_add_array(tmp_array, pdf_new_number(code));
+
+#if ENABLE_GLYPHENC
+ if (encoding_id >= 0 && enc_vec) {
+ charname = (char *) enc_vec[(unsigned char) code];
+ if (!charname) {
+ charname = work_buffer;
+ pk_char2name(charname, code);
+ }
+ }
+ else
+#endif /* ENABLE_GLYPHENC */
+ {
+ charname = work_buffer;
+ pk_char2name(charname, code);
+ }
+ pdf_add_array(tmp_array, pdf_new_name(charname));
+ prev = code;
+ }
+ }
+ if (firstchar > lastchar) {
+ ERROR("Unexpected error: firstchar > lastchar (%d %d)",
+ firstchar, lastchar);
+ pdf_release_obj(tmp_array);
+ return -1;
+ }
+#if ENABLE_GLYPHENC
+ if (encoding_id < 0 || !enc_vec) {
+#else
+ if (1) {
+#endif /* ENABLE_GLYPHENC */
+ encoding = pdf_new_dict();
+ pdf_add_dict(encoding,
+ pdf_new_name("Type"), pdf_new_name("Encoding"));
+ pdf_add_dict(encoding,
+ pdf_new_name("Differences"), tmp_array);
+ pdf_add_dict(fontdict,
+ pdf_new_name("Encoding"), pdf_ref_obj(encoding));
+ pdf_release_obj(encoding);
+ } else
+ pdf_release_obj(tmp_array);
+
+ /* FontBBox: Accurate value is important.
+ */
+ tmp_array = pdf_new_array();
+ pdf_add_array(tmp_array, pdf_new_number(bbox.llx));
+ pdf_add_array(tmp_array, pdf_new_number(bbox.lly));
+ pdf_add_array(tmp_array, pdf_new_number(bbox.urx));
+ pdf_add_array(tmp_array, pdf_new_number(bbox.ury));
+ pdf_add_dict (fontdict , pdf_new_name("FontBBox"), tmp_array);
+
+ /* Widths:
+ * Indirect reference preffered. (See PDF Reference)
+ */
+ tmp_array = pdf_new_array();
+ for (code = firstchar; code <= lastchar; code++) {
+ if (usedchars[code])
+ pdf_add_array(tmp_array, pdf_new_number(widths[code]));
+ else {
+ pdf_add_array(tmp_array, pdf_new_number(0));
+ }
+ }
+ pdf_add_dict(fontdict,
+ pdf_new_name("Widths"), pdf_ref_obj(tmp_array));
+ pdf_release_obj(tmp_array);
+
+ /* FontMatrix */
+ tmp_array = pdf_new_array();
+ pdf_add_array(tmp_array, pdf_new_number(0.001 * pix2charu));
+ pdf_add_array(tmp_array, pdf_new_number(0.0));
+ pdf_add_array(tmp_array, pdf_new_number(0.0));
+ pdf_add_array(tmp_array, pdf_new_number(0.001 * pix2charu));
+ pdf_add_array(tmp_array, pdf_new_number(0.0));
+ pdf_add_array(tmp_array, pdf_new_number(0.0));
+ pdf_add_dict (fontdict , pdf_new_name("FontMatrix"), tmp_array);
+
+
+ pdf_add_dict(fontdict,
+ pdf_new_name("FirstChar"), pdf_new_number(firstchar));
+ pdf_add_dict(fontdict,
+ pdf_new_name("LastChar"), pdf_new_number(lastchar));
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/pkfont.h b/Build/source/texk/dvipdfm-x/pkfont.h
new file mode 100644
index 00000000000..f65fdfa24e4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pkfont.h
@@ -0,0 +1,33 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PK_FONT_H_
+#define _PK_FONT_H_
+
+#include "pdffont.h"
+
+extern int pdf_font_open_pkfont (pdf_font *font, const char *ident, int index, int encoding_id, int embedding, double point_size);
+extern int pdf_font_load_pkfont (pdf_font *font);
+
+extern void PKFont_set_dpi(int dpi);
+
+#endif /* _PK_FONT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pngimage.c b/Build/source/texk/dvipdfm-x/pngimage.c
new file mode 100644
index 00000000000..10f267f4b2a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pngimage.c
@@ -0,0 +1,1143 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * PNG SUPPORT
+ *
+ * All bitdepth supported.
+ * Supported color types are: PALETTE, RGB, GRAY, RGB_ALPHA, GRAY_ALPHA.
+ * Supported ancillary chunks: tRNS, cHRM, gAMA, (sRGB), (iCCP)
+ *
+ * cHRM support is not tested well. CalRGB/CalGray colorspace is used for
+ * PNG images that have cHRM chunk.
+ *
+ */
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+
+#include "pdfcolor.h"
+#include "pdfobj.h"
+
+#define PNG_DEBUG_STR "PNG"
+#define PNG_DEBUG 3
+
+#ifdef HAVE_LIBPNG
+
+/*
+ * Write, MNG, Progressive not required.
+ */
+#define PNG_NO_WRITE_SUPPORTED
+#define PNG_NO_MNG_FEATURES
+#define PNG_NO_PROGRESSIVE_READ
+
+#include <png.h>
+#include "pngimage.h"
+
+#include "pdfximage.h"
+
+#define DPX_PNG_DEFAULT_GAMMA 2.2
+
+#define PDF_TRANS_TYPE_NONE 0
+#define PDF_TRANS_TYPE_BINARY 1
+#define PDF_TRANS_TYPE_ALPHA 2
+
+/* ColorSpace */
+static pdf_obj *create_cspace_Indexed (png_structp png_ptr, png_infop info_ptr);
+
+/* CIE-Based: CalRGB/CalGray */
+static pdf_obj *create_cspace_CalRGB (png_structp png_ptr, png_infop info_ptr);
+static pdf_obj *create_cspace_CalGray (png_structp png_ptr, png_infop info_ptr);
+static pdf_obj *make_param_Cal (png_byte color_type,
+ double G,
+ double xw, double yw,
+ double xr, double yr,
+ double xg, double yg,
+ double xb, double yb);
+
+/* sRGB:
+ *
+ * We (and PDF) do not have direct sRGB support. The sRGB color space can be
+ * precisely represented by ICC profile, but we use approximate CalRGB color
+ * space.
+ */
+static pdf_obj *create_cspace_sRGB (png_structp png_ptr, png_infop info_ptr);
+static pdf_obj *get_rendering_intent (png_structp png_ptr, png_infop info_ptr);
+
+/* ICCBased:
+ *
+ * Not supported yet.
+ * Must check if ICC profile is valid and can be imported to PDF.
+ * There are few restrictions (should be applied to PNG too?) in ICC profile
+ * support in PDF. Some information should be obtained from profile.
+ */
+static pdf_obj *create_cspace_ICCBased (png_structp png_ptr, png_infop info_ptr);
+
+/* Transparency */
+static int check_transparency (png_structp png_ptr, png_infop info_ptr);
+/* Color-Key Mask */
+static pdf_obj *create_ckey_mask (png_structp png_ptr, png_infop info_ptr);
+/* Soft Mask:
+ *
+ * create_soft_mask() is for PNG_COLOR_TYPE_PALLETE.
+ * Images with alpha chunnel use strip_soft_mask().
+ * An object representing mask itself is returned.
+ */
+static pdf_obj *create_soft_mask (png_structp png_ptr, png_infop info_ptr,
+ png_bytep image_data_ptr,
+ png_uint_32 width, png_uint_32 height);
+static pdf_obj *strip_soft_mask (png_structp png_ptr, png_infop info_ptr,
+ png_bytep image_data_ptr,
+ png_uint_32p rowbytes_ptr,
+ png_uint_32 width, png_uint_32 height);
+
+/* Read image body */
+static void read_image_data (png_structp png_ptr,
+ png_bytep dest_ptr,
+ png_uint_32 height, png_uint_32 rowbytes);
+
+int
+check_for_png (FILE *png_file)
+{
+ unsigned char sigbytes[4];
+
+ rewind (png_file);
+ if (fread (sigbytes, 1, sizeof(sigbytes), png_file) !=
+ sizeof(sigbytes) ||
+ (png_sig_cmp (sigbytes, 0, sizeof(sigbytes))))
+ return 0;
+ else
+ return 1;
+}
+
+static void warn(png_structp png_ptr, png_const_charp msg)
+{
+ (void)png_ptr; (void)msg; /* Make compiler happy */
+}
+
+int
+png_include_image (pdf_ximage *ximage, FILE *png_file)
+{
+ pdf_obj *stream;
+ pdf_obj *stream_dict;
+ pdf_obj *colorspace, *mask, *intent;
+ png_bytep stream_data_ptr;
+ int trans_type;
+ ximage_info info;
+ /* Libpng stuff */
+ png_structp png_ptr;
+ png_infop png_info_ptr;
+ png_byte bpc, color_type;
+ png_uint_32 width, height, rowbytes;
+
+ pdf_ximage_init_image_info(&info);
+
+ stream = NULL;
+ stream_dict = NULL;
+ colorspace = mask = intent = NULL;
+
+ rewind (png_file);
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, warn);
+ if (png_ptr == NULL ||
+ (png_info_ptr = png_create_info_struct (png_ptr)) == NULL) {
+ WARN("%s: Creating Libpng read/info struct failed.", PNG_DEBUG_STR);
+ if (png_ptr)
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ return -1;
+ }
+
+#if PNG_LIBPNG_VER >= 10603
+ /* ignore possibly incorrect CMF bytes */
+ png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON);
+#endif
+
+ /* Inititializing file IO. */
+ png_init_io (png_ptr, png_file);
+
+ /* Read PNG info-header and get some info. */
+ png_read_info(png_ptr, png_info_ptr);
+ color_type = png_get_color_type (png_ptr, png_info_ptr);
+ width = png_get_image_width (png_ptr, png_info_ptr);
+ height = png_get_image_height(png_ptr, png_info_ptr);
+ bpc = png_get_bit_depth (png_ptr, png_info_ptr);
+
+ /* Ask libpng to convert down to 8-bpc. */
+ if (bpc > 8) {
+ if (pdf_check_version(1, 5) < 0) {
+ WARN("%s: 16-bpc PNG requires PDF version 1.5.", PNG_DEBUG_STR);
+ png_set_strip_16(png_ptr);
+ bpc = 8;
+ }
+ }
+ /* Ask libpng to gamma-correct.
+ * It is wrong to assume screen gamma value 2.2 but...
+ * We do gamma correction here only when uncalibrated color space is used.
+ */
+ if (!png_get_valid(png_ptr, png_info_ptr, PNG_INFO_iCCP) &&
+ !png_get_valid(png_ptr, png_info_ptr, PNG_INFO_sRGB) &&
+ !png_get_valid(png_ptr, png_info_ptr, PNG_INFO_cHRM) &&
+ png_get_valid(png_ptr, png_info_ptr, PNG_INFO_gAMA)) {
+ double G = 1.0;
+ png_get_gAMA (png_ptr, png_info_ptr, &G);
+ png_set_gamma(png_ptr, 2.2, G);
+ }
+
+ trans_type = check_transparency(png_ptr, png_info_ptr);
+ /* check_transparency() does not do updata_info() */
+ png_read_update_info(png_ptr, png_info_ptr);
+ rowbytes = png_get_rowbytes(png_ptr, png_info_ptr);
+
+ /* Values listed below will not be modified in the remaining process. */
+ info.width = width;
+ info.height = height;
+ info.bits_per_component = bpc;
+
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode)
+ info.xdensity = info.ydensity = 72.0 / 100.0;
+ else
+ {
+ png_uint_32 xppm = png_get_x_pixels_per_meter(png_ptr, png_info_ptr);
+ png_uint_32 yppm = png_get_y_pixels_per_meter(png_ptr, png_info_ptr);
+
+ if (xppm > 0)
+ info.xdensity = 72.0 / 0.0254 / xppm;
+ if (yppm > 0)
+ info.ydensity = 72.0 / 0.0254 / yppm;
+ }
+
+ stream = pdf_new_stream (STREAM_COMPRESS);
+ stream_dict = pdf_stream_dict(stream);
+
+ stream_data_ptr = (png_bytep) NEW(rowbytes*height, png_byte);
+ read_image_data(png_ptr, stream_data_ptr, height, rowbytes);
+
+ /* Non-NULL intent means there is valid sRGB chunk. */
+ intent = get_rendering_intent(png_ptr, png_info_ptr);
+ if (intent)
+ pdf_add_dict(stream_dict, pdf_new_name("Intent"), intent);
+
+ switch (color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+
+ colorspace = create_cspace_Indexed(png_ptr, png_info_ptr);
+
+ switch (trans_type) {
+ case PDF_TRANS_TYPE_BINARY:
+ /* Color-key masking */
+ mask = create_ckey_mask(png_ptr, png_info_ptr);
+ break;
+ case PDF_TRANS_TYPE_ALPHA:
+ /* Soft mask */
+ mask = create_soft_mask(png_ptr, png_info_ptr, stream_data_ptr, width, height);
+ break;
+ default:
+ /* Nothing to be done here.
+ * No tRNS chunk or image already composited with background color.
+ */
+ break;
+ }
+ info.num_components = 1;
+
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+
+ if (png_get_valid(png_ptr, png_info_ptr, PNG_INFO_iCCP))
+ colorspace = create_cspace_ICCBased(png_ptr, png_info_ptr);
+ else if (intent) {
+ colorspace = create_cspace_sRGB(png_ptr, png_info_ptr);
+ } else {
+ colorspace = create_cspace_CalRGB(png_ptr, png_info_ptr);
+ }
+ if (!colorspace)
+ colorspace = pdf_new_name("DeviceRGB");
+
+ switch (trans_type) {
+ case PDF_TRANS_TYPE_BINARY:
+ mask = create_ckey_mask(png_ptr, png_info_ptr);
+ break;
+ /* rowbytes changes 4 to 3 at here */
+ case PDF_TRANS_TYPE_ALPHA:
+ mask = strip_soft_mask(png_ptr, png_info_ptr,
+ stream_data_ptr, &rowbytes, width, height);
+ break;
+ default:
+ mask = NULL;
+ }
+ info.num_components = 3;
+ break;
+
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+
+ if (png_get_valid(png_ptr, png_info_ptr, PNG_INFO_iCCP))
+ colorspace = create_cspace_ICCBased(png_ptr, png_info_ptr);
+ else if (intent) {
+ colorspace = create_cspace_sRGB(png_ptr, png_info_ptr);
+ } else {
+ colorspace = create_cspace_CalGray(png_ptr, png_info_ptr);
+ }
+ if (!colorspace)
+ colorspace = pdf_new_name("DeviceGray");
+
+ switch (trans_type) {
+ case PDF_TRANS_TYPE_BINARY:
+ mask = create_ckey_mask(png_ptr, png_info_ptr);
+ break;
+ case PDF_TRANS_TYPE_ALPHA:
+ mask = strip_soft_mask(png_ptr, png_info_ptr,
+ stream_data_ptr, &rowbytes, width, height);
+ break;
+ default:
+ mask = NULL;
+ }
+ info.num_components = 1;
+ break;
+
+ default:
+ WARN("%s: Unknown PNG colortype %d.", PNG_DEBUG_STR, color_type);
+ }
+ pdf_add_dict(stream_dict, pdf_new_name("ColorSpace"), colorspace);
+
+ pdf_add_stream(stream, stream_data_ptr, rowbytes*height);
+ RELEASE(stream_data_ptr);
+
+ if (mask) {
+ if (trans_type == PDF_TRANS_TYPE_BINARY)
+ pdf_add_dict(stream_dict, pdf_new_name("Mask"), mask);
+ else if (trans_type == PDF_TRANS_TYPE_ALPHA) {
+ if (info.bits_per_component >= 8 && info.width > 64) {
+ pdf_stream_set_predictor(mask, 2, info.width,
+ info.bits_per_component, 1);
+ }
+ pdf_add_dict(stream_dict, pdf_new_name("SMask"), pdf_ref_obj(mask));
+ pdf_release_obj(mask);
+ } else {
+ WARN("%s: Unknown transparency type...???", PNG_DEBUG_STR);
+ pdf_release_obj(mask);
+ }
+ }
+
+ /* Finally read XMP Metadata
+ * See, XMP Specification Part 3, Storage in Files
+ * http://www.adobe.com/jp/devnet/xmp.html
+ *
+ * We require libpng version >= 1.6.14 since prior versions
+ * of libpng had a bug that incorrectly treat the compression
+ * flag of iTxt chunks.
+ */
+#if PNG_LIBPNG_VER >= 10614
+ if (pdf_check_version(1, 4) >= 0) {
+ png_textp text_ptr;
+ pdf_obj *XMP_stream, *XMP_stream_dict;
+ int i, num_text;
+ int have_XMP = 0;
+
+ num_text = png_get_text(png_ptr, png_info_ptr, &text_ptr, NULL);
+ for (i = 0; i < num_text; i++) {
+ if (!memcmp(text_ptr[i].key, "XML:com.adobe.xmp", 17)) {
+ /* XMP found */
+ if (text_ptr[i].compression != PNG_ITXT_COMPRESSION_NONE ||
+ text_ptr[i].itxt_length == 0)
+ WARN("%s: Invalid value(s) in iTXt chunk for XMP Metadata.", PNG_DEBUG_STR);
+ else if (have_XMP)
+ WARN("%s: Multiple XMP Metadata. Don't know how to treat it.", PNG_DEBUG_STR);
+ else {
+ /* We compress XMP metadata for included images here.
+ * It is not recommended to compress XMP metadata for PDF documents but
+ * we compress XMP metadata for included images here to avoid confusing
+ * application programs that only want PDF document global XMP metadata
+ * and scan for that.
+ */
+ XMP_stream = pdf_new_stream(STREAM_COMPRESS);
+ XMP_stream_dict = pdf_stream_dict(XMP_stream);
+ pdf_add_dict(XMP_stream_dict,
+ pdf_new_name("Type"), pdf_new_name("Metadata"));
+ pdf_add_dict(XMP_stream_dict,
+ pdf_new_name("Subtype"), pdf_new_name("XML"));
+ pdf_add_stream(XMP_stream, text_ptr[i].text, text_ptr[i].itxt_length);
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Metadata"), pdf_ref_obj(XMP_stream));
+ pdf_release_obj(XMP_stream);
+ have_XMP = 1;
+ }
+ }
+ }
+ }
+#endif /* PNG_LIBPNG_VER */
+
+ png_read_end(png_ptr, NULL);
+
+ /* Cleanup */
+ if (png_info_ptr)
+ png_destroy_info_struct(png_ptr, &png_info_ptr);
+ if (png_ptr)
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ if (color_type != PNG_COLOR_TYPE_PALETTE &&
+ info.bits_per_component >= 8 &&
+ info.height > 64) {
+ pdf_stream_set_predictor(stream, 15, info.width,
+ info.bits_per_component, info.num_components);
+ }
+ pdf_ximage_set_image(ximage, &info, stream);
+
+ return 0;
+}
+
+/*
+ * The returned value trans_type is the type of transparency to be used for
+ * this image. Possible values are:
+ *
+ * PDF_TRANS_TYPE_NONE No Masking will be used/required.
+ * PDF_TRANS_TYPE_BINARY Pixels are either fully opaque/fully transparent.
+ * PDF_TRANS_TYPE_ALPHA Uses alpha channel, requies SMask.(PDF-1.4)
+ *
+ * check_transparency() must check the current setting of output PDF version
+ * and must choose appropriate trans_type value according to PDF version of
+ * current output PDF document.
+ *
+ * If the PDF version is less than 1.3, no transparency is supported for this
+ * version of PDF, hence PDF_TRANS_TYPE_NONE must be returned. And when the PDF
+ * version is equal to 1.3, possible retrun values are PDF_TRANS_TYPE_BINARY or
+ * PDF_TRANS_TYPE_NONE. The latter case arises when PNG file uses alpha channel
+ * explicitly (color type PNG_COLOR_TYPE_XXX_ALPHA), or the tRNS chunk for the
+ * PNG_COLOR_TYPE_PALETTE image contains intermediate values of opacity.
+ *
+ * Finally, in the case of PDF version 1.4, all kind of translucent pixels can
+ * be represented with Soft-Mask.
+ */
+
+static int
+check_transparency (png_structp png_ptr, png_infop info_ptr)
+{
+ int trans_type;
+ png_byte color_type;
+ png_color_16p trans_values;
+ png_bytep trans;
+ int num_trans;
+
+ color_type = png_get_color_type(png_ptr, info_ptr);
+
+ /*
+ * First we set trans_type to appropriate value for PNG image.
+ */
+ if (color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ trans_type = PDF_TRANS_TYPE_ALPHA;
+ } else if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) &&
+ png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values)) {
+ /* Have valid tRNS chunk. */
+ switch (color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+ /* Use color-key mask if possible. */
+ trans_type = PDF_TRANS_TYPE_BINARY;
+ while (num_trans-- > 0) {
+ if (trans[num_trans] != 0x00 && trans[num_trans] != 0xff) {
+ /* This seems not binary transparency */
+ trans_type = PDF_TRANS_TYPE_ALPHA;
+ break;
+ }
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_RGB:
+ /* RGB or GRAY, single color specified by trans_values is transparent. */
+ trans_type = PDF_TRANS_TYPE_BINARY;
+ break;
+ default:
+ /* Else tRNS silently ignored. */
+ trans_type = PDF_TRANS_TYPE_NONE;
+ }
+ } else { /* no transparency */
+ trans_type = PDF_TRANS_TYPE_NONE;
+ }
+
+ /*
+ * Now we check PDF version.
+ * We can convert alpha cahnnels to explicit mask via user supplied alpha-
+ * threshold value. But I will not do that.
+ */
+ if (( pdf_check_version(1, 3) < 0 && trans_type != PDF_TRANS_TYPE_NONE ) ||
+ ( pdf_check_version(1, 4) < 0 && trans_type == PDF_TRANS_TYPE_ALPHA )) {
+ /*
+ * No transparency supported but PNG uses transparency, or Soft-Mask
+ * required but no support for it is available in this version of PDF.
+ * We must do pre-composition of image with the background image here. But,
+ * we cannot do that in general since dvipdfmx is not a rasterizer. What we
+ * can do here is to composite image with a rectangle filled with the
+ * background color. However, images are stored as an Image XObject which
+ * can be referenced anywhere in the PDF document content. Hence, we cannot
+ * know the correct background color at this time. So we will choose white
+ * as background color, which is most probable color in our cases.
+ * We ignore bKGD chunk.
+ */
+ png_color_16 bg;
+ bg.red = 255; bg.green = 255; bg.blue = 255; bg.gray = 255; bg.index = 0;
+ png_set_background(png_ptr, &bg, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+ WARN("%s: Transparency will be ignored. (no support in PDF ver. < 1.3)", PNG_DEBUG_STR);
+ if (pdf_check_version(1, 3) < 0)
+ WARN("%s: Please use -V 3 option to enable binary transparency support.", PNG_DEBUG_STR);
+ if (pdf_check_version(1, 4) < 0)
+ WARN("%s: Please use -V 4 option to enable full alpha channel support.", PNG_DEBUG_STR);
+ trans_type = PDF_TRANS_TYPE_NONE;
+ }
+
+ return trans_type;
+}
+
+/*
+ * sRGB:
+ *
+ * If sRGB chunk is present, cHRM and gAMA chunk must be ignored.
+ *
+ */
+static pdf_obj *
+get_rendering_intent (png_structp png_ptr, png_infop info_ptr)
+{
+ pdf_obj *intent;
+ int srgb_intent;
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB) &&
+ png_get_sRGB (png_ptr, info_ptr, &srgb_intent)) {
+ switch (srgb_intent) {
+ case PNG_sRGB_INTENT_SATURATION:
+ intent = pdf_new_name("Saturation");
+ break;
+ case PNG_sRGB_INTENT_PERCEPTUAL:
+ intent = pdf_new_name("Perceptual");
+ break;
+ case PNG_sRGB_INTENT_ABSOLUTE:
+ intent = pdf_new_name("AbsoluteColorimetric");
+ break;
+ case PNG_sRGB_INTENT_RELATIVE:
+ intent = pdf_new_name("RelativeColorimetric");
+ break;
+ default:
+ WARN("%s: Invalid value in PNG sRGB chunk: %d", PNG_DEBUG_STR, srgb_intent);
+ intent = NULL;
+ }
+ } else
+ intent = NULL;
+
+ return intent;
+}
+
+/* Approximated sRGB */
+static pdf_obj *
+create_cspace_sRGB (png_structp png_ptr, png_infop info_ptr)
+{
+ pdf_obj *colorspace;
+ pdf_obj *cal_param;
+ png_byte color_type;
+
+ color_type = png_get_color_type(png_ptr, info_ptr);
+
+ /* Parameters taken from PNG spec. section 4.2.2.3. */
+ cal_param = make_param_Cal(color_type,
+ 2.2,
+ 0.3127, 0.329,
+ 0.64, 0.33, 0.3, 0.6, 0.15, 0.06);
+ if (!cal_param)
+ return NULL;
+
+ colorspace = pdf_new_array();
+
+ switch (color_type) {
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ case PNG_COLOR_TYPE_PALETTE:
+ pdf_add_array(colorspace, pdf_new_name("CalRGB"));
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ pdf_add_array(colorspace, pdf_new_name("CalGray"));
+ break;
+ }
+ pdf_add_array(colorspace, cal_param);
+
+ return colorspace;
+}
+
+static pdf_obj *
+create_cspace_ICCBased (png_structp png_ptr, png_infop info_ptr)
+{
+ pdf_obj *colorspace;
+ int csp_id, colortype;
+ png_byte color_type;
+ png_charp name;
+ int compression_type; /* Manual page for libpng does not
+ * clarify whether profile data is inflated by libpng.
+ */
+#if PNG_LIBPNG_VER_MINOR < 5
+ png_charp profile;
+#else
+ png_bytep profile;
+#endif
+ png_uint_32 proflen;
+
+ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP) ||
+ !png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile, &proflen))
+ return NULL;
+
+ color_type = png_get_color_type(png_ptr, info_ptr);
+
+ if (color_type & PNG_COLOR_MASK_COLOR) {
+ colortype = PDF_COLORSPACE_TYPE_RGB;
+#if 0
+ alternate = create_cspace_CalRGB(png_ptr, info_ptr);
+#endif
+ } else {
+ colortype = PDF_COLORSPACE_TYPE_GRAY;
+#if 0
+ alternate = create_cspace_CalGray(png_ptr, info_ptr);
+#endif
+ }
+
+#if 0
+ if (alternate)
+ pdf_add_dict(dict, pdf_new_name("Alternate"), alternate);
+#endif
+
+ if (iccp_check_colorspace(colortype, profile, proflen) < 0)
+ colorspace = NULL;
+ else {
+ csp_id = iccp_load_profile(name, profile, proflen);
+ if (csp_id < 0) {
+ colorspace = NULL;
+ } else {
+ colorspace = pdf_get_colorspace_reference(csp_id);
+ }
+ }
+
+ /* Rendering intent ... */
+
+ return colorspace;
+}
+
+/*
+ * gAMA, cHRM:
+ *
+ * If cHRM is present, we use CIE-Based color space. gAMA is also used here
+ * if available.
+ */
+
+#define INVALID_CHRM_VALUE(xw,yw,xr,yr,xg,yg,xb,yb) (\
+ (xw) <= 0.0 || (yw) < 1.0e-10 || \
+ (xr) < 0.0 || (yr) < 0.0 || (xg) < 0.0 || (yg) < 0.0 || \
+ (xb) < 0.0 || (yb) < 0.0)
+
+static pdf_obj *
+create_cspace_CalRGB (png_structp png_ptr, png_infop info_ptr)
+{
+ pdf_obj *colorspace;
+ pdf_obj *cal_param;
+ double xw, yw, xr, yr, xg, yg, xb, yb;
+ double G;
+
+ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM) ||
+ !png_get_cHRM(png_ptr, info_ptr, &xw, &yw, &xr, &yr, &xg, &yg, &xb, &yb))
+ return NULL;
+
+ if (xw <= 0.0 || yw < 1.0e-10 ||
+ xr < 0.0 || yr < 0.0 || xg < 0.0 || yg < 0.0 || xb < 0.0 || yb < 0.0) {
+ WARN("%s: Invalid cHRM chunk parameters found.", PNG_DEBUG_STR);
+ return NULL;
+ }
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) &&
+ png_get_gAMA (png_ptr, info_ptr, &G)) {
+ if (G < 1.0e-2) {
+ WARN("%s: Unusual Gamma value: 1.0 / %g", PNG_DEBUG_STR, G);
+ return NULL;
+ }
+ G = 1.0 / G; /* Gamma is inverted. */
+ } else {
+ G = DPX_PNG_DEFAULT_GAMMA;
+ }
+
+ cal_param = make_param_Cal(PNG_COLOR_TYPE_RGB, G, xw, yw, xr, yr, xg, yg, xb, yb);
+
+ if (!cal_param)
+ return NULL;
+
+ colorspace = pdf_new_array();
+ pdf_add_array(colorspace, pdf_new_name("CalRGB"));
+ pdf_add_array(colorspace, cal_param);
+
+ return colorspace;
+}
+
+static pdf_obj *
+create_cspace_CalGray (png_structp png_ptr, png_infop info_ptr)
+{
+ pdf_obj *colorspace;
+ pdf_obj *cal_param;
+ double xw, yw, xr, yr, xg, yg, xb, yb;
+ double G;
+
+ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM) ||
+ !png_get_cHRM(png_ptr, info_ptr, &xw, &yw, &xr, &yr, &xg, &yg, &xb, &yb))
+ return NULL;
+
+ if (xw <= 0.0 || yw < 1.0e-10 ||
+ xr < 0.0 || yr < 0.0 || xg < 0.0 || yg < 0.0 || xb < 0.0 || yb < 0.0) {
+ WARN("%s: Invalid cHRM chunk parameters found.", PNG_DEBUG_STR);
+ return NULL;
+ }
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) &&
+ png_get_gAMA (png_ptr, info_ptr, &G)) {
+ if (G < 1.0e-2) {
+ WARN("%s: Unusual Gamma value: 1.0 / %g", PNG_DEBUG_STR, G);
+ return NULL;
+ }
+ G = 1.0 / G; /* Gamma is inverted. */
+ } else {
+ G = DPX_PNG_DEFAULT_GAMMA;
+ }
+
+ cal_param = make_param_Cal(PNG_COLOR_TYPE_GRAY, G, xw, yw, xr, yr, xg, yg, xb, yb);
+
+ if (!cal_param)
+ return NULL;
+
+ colorspace = pdf_new_array();
+ pdf_add_array(colorspace, pdf_new_name("CalGray"));
+ pdf_add_array(colorspace, cal_param);
+
+ return colorspace;
+}
+
+static pdf_obj *
+make_param_Cal (png_byte color_type,
+ double G, /* Gamma */
+ double xw, double yw,
+ double xr, double yr, double xg, double yg, double xb, double yb)
+{
+ pdf_obj *cal_param;
+ pdf_obj *white_point, *matrix, *dev_gamma;
+ double Xw, Yw, Zw; /* Yw = 1.0 */
+ double Xr, Xg, Xb, Yr, Yb, Yg, Zr, Zg, Zb;
+
+#ifndef ABS
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#endif
+ /*
+ * TODO: Check validity
+ *
+ * Conversion found in
+ *
+ * com.sixlegs.image.png - Java package to read and display PNG images
+ * Copyright (C) 1998, 1999, 2001 Chris Nokleberg
+ *
+ * http://www.sixlegs.com/software/png/
+ *
+ */
+ {
+ double zw, zr, zg, zb;
+ double fr, fg, fb;
+ double det;
+
+ /* WhitePoint */
+ zw = 1 - (xw + yw);
+ zr = 1 - (xr + yr); zg = 1 - (xg + yg); zb = 1 - (xb + yb);
+ Xw = xw / yw; Yw = 1.0; Zw = zw / yw;
+
+ /* Matrix */
+ det = xr * (yg * zb - zg * yb) - xg * (yr * zb - zr * yb) + xb * (yr * zg - zr * yg);
+ if (ABS(det) < 1.0e-10) {
+ WARN("Non invertible matrix: Maybe invalid value(s) specified in cHRM chunk.");
+ return NULL;
+ }
+ fr = (Xw * (yg * zb - zg * yb) - xg * (zb - Zw * yb) + xb * (zg - Zw * yg)) / det;
+ fg = (xr * (zb - Zw * yb) - Xw * (yr * zb - zr * yb) + xb * (yr * Zw - zr)) / det;
+ fb = (xr * (yg * Zw - zg) - xg * (yr * Zw - zr) + Xw * (yr * zg - zr * yg)) / det;
+ Xr = fr * xr; Yr = fr * yr; Zr = fr * zr;
+ Xg = fg * xg; Yg = fg * yg; Zg = fg * zg;
+ Xb = fb * xb; Yb = fb * yb; Zb = fb * zb;
+ }
+
+ if (G < 1.0e-2) {
+ WARN("Unusual Gamma specified: 1.0 / %g", G);
+ return NULL;
+ }
+
+ cal_param = pdf_new_dict();
+
+ /* White point is always required. */
+ white_point = pdf_new_array();
+ pdf_add_array(white_point, pdf_new_number(ROUND(Xw, 0.00001)));
+ pdf_add_array(white_point, pdf_new_number(ROUND(Yw, 0.00001)));
+ pdf_add_array(white_point, pdf_new_number(ROUND(Zw, 0.00001)));
+ pdf_add_dict(cal_param, pdf_new_name("WhitePoint"), white_point);
+
+ /* Matrix - default: Identity */
+ if (color_type & PNG_COLOR_MASK_COLOR) {
+ if (G != 1.0) {
+ dev_gamma = pdf_new_array();
+ pdf_add_array(dev_gamma, pdf_new_number(ROUND(G, 0.00001)));
+ pdf_add_array(dev_gamma, pdf_new_number(ROUND(G, 0.00001)));
+ pdf_add_array(dev_gamma, pdf_new_number(ROUND(G, 0.00001)));
+ pdf_add_dict(cal_param, pdf_new_name("Gamma"), dev_gamma);
+ }
+
+ matrix = pdf_new_array();
+ pdf_add_array(matrix, pdf_new_number(ROUND(Xr, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Yr, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Zr, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Xg, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Yg, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Zg, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Xb, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Yb, 0.00001)));
+ pdf_add_array(matrix, pdf_new_number(ROUND(Zb, 0.00001)));
+ pdf_add_dict (cal_param, pdf_new_name("Matrix"), matrix);
+ } else { /* Gray */
+ if (G != 1.0)
+ pdf_add_dict(cal_param,
+ pdf_new_name("Gamma"),
+ pdf_new_number(ROUND(G, 0.00001)));
+ }
+
+ return cal_param;
+}
+
+/*
+ * Set up Indexed ColorSpace for color-type PALETTE:
+ *
+ * PNG allows only RGB color for base color space. If gAMA and/or cHRM
+ * chunk is available, we can use CalRGB color space instead of DeviceRGB
+ * for base color space.
+ *
+ */
+static pdf_obj *
+create_cspace_Indexed (png_structp png_ptr, png_infop info_ptr)
+{
+ pdf_obj *colorspace;
+ pdf_obj *base, *lookup;
+ png_byte *data_ptr;
+ png_colorp plte;
+ int num_plte, i;
+
+ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE) ||
+ !png_get_PLTE(png_ptr, info_ptr, &plte, &num_plte)) {
+ WARN("%s: PNG does not have valid PLTE chunk.", PNG_DEBUG_STR);
+ return NULL;
+ }
+
+ /* Order is important. */
+ colorspace = pdf_new_array ();
+ pdf_add_array(colorspace, pdf_new_name("Indexed"));
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP))
+ base = create_cspace_ICCBased(png_ptr, info_ptr);
+ else {
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB))
+ base = create_cspace_sRGB(png_ptr, info_ptr);
+ else
+ base = create_cspace_CalRGB(png_ptr, info_ptr);
+ }
+
+ if (!base)
+ base = pdf_new_name("DeviceRGB");
+
+ pdf_add_array(colorspace, base);
+ pdf_add_array(colorspace, pdf_new_number(num_plte-1));
+ data_ptr = NEW(num_plte*3, png_byte);
+ for (i = 0; i < num_plte; i++) {
+ data_ptr[3*i] = plte[i].red;
+ data_ptr[3*i+1] = plte[i].green;
+ data_ptr[3*i+2] = plte[i].blue;
+ }
+ lookup = pdf_new_string(data_ptr, num_plte*3);
+ RELEASE(data_ptr);
+ pdf_add_array(colorspace, lookup);
+
+ return colorspace;
+}
+
+/*
+ * Colorkey Mask: array
+ *
+ * [component_0_min component_0_max ... component_n_min component_n_max]
+ *
+ */
+
+static pdf_obj *
+create_ckey_mask (png_structp png_ptr, png_infop info_ptr)
+{
+ pdf_obj *colorkeys;
+ png_byte color_type;
+ png_bytep trans;
+ int num_trans, i;
+ png_color_16p colors;
+
+ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ||
+ !png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &colors)) {
+ WARN("%s: PNG does not have valid tRNS chunk!", PNG_DEBUG_STR);
+ return NULL;
+ }
+
+ colorkeys = pdf_new_array();
+ color_type = png_get_color_type(png_ptr, info_ptr);
+
+ switch (color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+ for (i = 0; i < num_trans; i++) {
+ if (trans[i] == 0x00) {
+ pdf_add_array(colorkeys, pdf_new_number(i));
+ pdf_add_array(colorkeys, pdf_new_number(i));
+ } else if (trans[i] != 0xff) {
+ WARN("%s: You found a bug in pngimage.c.", PNG_DEBUG_STR);
+ }
+ }
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ pdf_add_array(colorkeys, pdf_new_number(colors->red));
+ pdf_add_array(colorkeys, pdf_new_number(colors->red));
+ pdf_add_array(colorkeys, pdf_new_number(colors->green));
+ pdf_add_array(colorkeys, pdf_new_number(colors->green));
+ pdf_add_array(colorkeys, pdf_new_number(colors->blue));
+ pdf_add_array(colorkeys, pdf_new_number(colors->blue));
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ pdf_add_array(colorkeys, pdf_new_number(colors->gray));
+ pdf_add_array(colorkeys, pdf_new_number(colors->gray));
+ break;
+ default:
+ WARN("%s: You found a bug in pngimage.c.", PNG_DEBUG_STR);
+ pdf_release_obj(colorkeys);
+ colorkeys = NULL;
+ }
+
+ return colorkeys;
+}
+
+/*
+ * Soft-Mask: stream
+ *
+ * <<
+ * /Type /XObject
+ * /Subtype /Image
+ * /Width -int-
+ * /Height -int-
+ * /BitsPerComponent bpc
+ * >>
+ * stream .... endstream
+ *
+ * ColorSpace, Mask, SMask must be absent. ImageMask must be false or absent.
+ */
+
+static pdf_obj *
+create_soft_mask (png_structp png_ptr, png_infop info_ptr,
+ png_bytep image_data_ptr, png_uint_32 width, png_uint_32 height)
+{
+ pdf_obj *smask, *dict;
+ png_bytep smask_data_ptr;
+ png_bytep trans;
+ int num_trans;
+ png_uint_32 i;
+ png_byte bpc, mask, shift;
+
+ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ||
+ !png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL)) {
+ WARN("%s: PNG does not have valid tRNS chunk but tRNS is requested.", PNG_DEBUG_STR);
+ return NULL;
+ }
+ bpc = png_get_bit_depth(png_ptr, info_ptr);
+ mask = 0xff >> (8 - bpc);
+ shift = 8 - bpc;
+
+ smask = pdf_new_stream(STREAM_COMPRESS);
+ dict = pdf_stream_dict(smask);
+ smask_data_ptr = (png_bytep) NEW(width*height, png_byte);
+ pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("XObject"));
+ pdf_add_dict(dict, pdf_new_name("Subtype"), pdf_new_name("Image"));
+ pdf_add_dict(dict, pdf_new_name("Width"), pdf_new_number(width));
+ pdf_add_dict(dict, pdf_new_name("Height"), pdf_new_number(height));
+ pdf_add_dict(dict, pdf_new_name("ColorSpace"), pdf_new_name("DeviceGray"));
+ pdf_add_dict(dict, pdf_new_name("BitsPerComponent"), pdf_new_number(8));
+ for (i = 0; i < width*height; i++) {
+ /* data is packed for 1/2/4 bpc formats, msb first */
+ png_byte idx = (image_data_ptr[bpc * i / 8] >> (shift - bpc * i % 8)) & mask;
+ smask_data_ptr[i] = (idx < num_trans) ? trans[idx] : 0xff;
+ }
+ pdf_add_stream(smask, (char *)smask_data_ptr, width*height);
+ RELEASE(smask_data_ptr);
+
+ return smask;
+}
+
+/* bitdepth is always 8 (16 is not supported) */
+static pdf_obj *
+strip_soft_mask (png_structp png_ptr, png_infop info_ptr,
+ /* next two values will be modified. */
+ png_bytep image_data_ptr, png_uint_32p rowbytes_ptr,
+ png_uint_32 width, png_uint_32 height)
+{
+ pdf_obj *smask, *dict;
+ png_byte color_type, bpc;
+ png_bytep smask_data_ptr;
+ png_uint_32 i;
+
+ color_type = png_get_color_type(png_ptr, info_ptr);
+ bpc = png_get_bit_depth (png_ptr, info_ptr);
+ if (color_type & PNG_COLOR_MASK_COLOR) {
+ int bps = (bpc == 8) ? 4 : 8;
+ if (*rowbytes_ptr != bps*width*sizeof(png_byte)) { /* Something wrong */
+ WARN("%s: Inconsistent rowbytes value.", PNG_DEBUG_STR);
+ return NULL;
+ }
+ } else {
+ int bps = (bpc == 8) ? 2 : 4;
+ if (*rowbytes_ptr != bps*width*sizeof(png_byte)) { /* Something wrong */
+ WARN("%s: Inconsistent rowbytes value.", PNG_DEBUG_STR);
+ return NULL;
+ }
+ }
+
+ smask = pdf_new_stream(STREAM_COMPRESS);
+ dict = pdf_stream_dict(smask);
+ pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("XObject"));
+ pdf_add_dict(dict, pdf_new_name("Subtype"), pdf_new_name("Image"));
+ pdf_add_dict(dict, pdf_new_name("Width"), pdf_new_number(width));
+ pdf_add_dict(dict, pdf_new_name("Height"), pdf_new_number(height));
+ pdf_add_dict(dict, pdf_new_name("ColorSpace"), pdf_new_name("DeviceGray"));
+ pdf_add_dict(dict, pdf_new_name("BitsPerComponent"), pdf_new_number(bpc));
+
+ smask_data_ptr = (png_bytep) NEW((bpc/8)*width*height, png_byte);
+
+ switch (color_type) {
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ if (bpc == 8) {
+ for (i = 0; i < width*height; i++) {
+ memmove(image_data_ptr+(3*i), image_data_ptr+(4*i), 3);
+ smask_data_ptr[i] = image_data_ptr[4*i+3];
+ }
+ *rowbytes_ptr = 3*width*sizeof(png_byte);
+ } else {
+ for (i = 0; i < width*height; i++) {
+ memmove(image_data_ptr+(6*i), image_data_ptr+(8*i), 6);
+ smask_data_ptr[2*i] = image_data_ptr[8*i+6];
+ smask_data_ptr[2*i+1] = image_data_ptr[8*i+7];
+ }
+ *rowbytes_ptr = 6*width*sizeof(png_byte);
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ if (bpc == 8) {
+ for (i = 0; i < width*height; i++) {
+ image_data_ptr[i] = image_data_ptr[2*i];
+ smask_data_ptr[i] = image_data_ptr[2*i+1];
+ }
+ *rowbytes_ptr = width*sizeof(png_byte);
+ } else {
+ for (i = 0; i < width*height; i++) {
+ image_data_ptr[2*i] = image_data_ptr[4*i];
+ image_data_ptr[2*i+1] = image_data_ptr[4*i+1];
+ smask_data_ptr[2*i] = image_data_ptr[4*i+2];
+ smask_data_ptr[2*i+1] = image_data_ptr[4*i+3];
+ }
+ *rowbytes_ptr = 2*width*sizeof(png_byte);
+ }
+ break;
+ default:
+ WARN("You found a bug in pngimage.c!");
+ pdf_release_obj(smask);
+ RELEASE(smask_data_ptr);
+ return NULL;
+ }
+
+ pdf_add_stream(smask, smask_data_ptr, (bpc/8)*width*height);
+ RELEASE(smask_data_ptr);
+
+ return smask;
+}
+
+static void
+read_image_data (png_structp png_ptr, png_bytep dest_ptr,
+ png_uint_32 height, png_uint_32 rowbytes)
+{
+ png_bytepp rows_p;
+ png_uint_32 i;
+
+ rows_p = (png_bytepp) NEW (height, png_bytep);
+ for (i=0; i< height; i++)
+ rows_p[i] = dest_ptr + (rowbytes * i);
+ png_read_image(png_ptr, rows_p);
+ RELEASE(rows_p);
+}
+
+int
+png_get_bbox (FILE *png_file, uint32_t *width, uint32_t *height,
+ double *xdensity, double *ydensity)
+{
+ png_structp png_ptr;
+ png_infop png_info_ptr;
+
+ rewind (png_file);
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, warn);
+ if (png_ptr == NULL ||
+ (png_info_ptr = png_create_info_struct (png_ptr)) == NULL) {
+ WARN("%s: Creating Libpng read/info struct failed.", PNG_DEBUG_STR);
+ if (png_ptr)
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ return -1;
+ }
+
+ /* Inititializing file IO. */
+ png_init_io (png_ptr, png_file);
+
+ /* Read PNG info-header and get some info. */
+ png_read_info(png_ptr, png_info_ptr);
+ *width = png_get_image_width (png_ptr, png_info_ptr);
+ *height = png_get_image_height(png_ptr, png_info_ptr);
+
+ if (dpx_conf.compat_mode == dpx_mode_compat_mode)
+ *xdensity = *ydensity = 72.0 / 100.0;
+ else
+ {
+ png_uint_32 xppm = png_get_x_pixels_per_meter(png_ptr, png_info_ptr);
+ png_uint_32 yppm = png_get_y_pixels_per_meter(png_ptr, png_info_ptr);
+
+ *xdensity = xppm ? 72.0 / 0.0254 / xppm : 1.0;
+ *ydensity = yppm ? 72.0 / 0.0254 / yppm : 1.0;
+ }
+
+ /* Cleanup */
+ if (png_info_ptr)
+ png_destroy_info_struct(png_ptr, &png_info_ptr);
+ if (png_ptr)
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+
+ return 0;
+}
+
+#endif /* HAVE_LIBPNG */
diff --git a/Build/source/texk/dvipdfm-x/pngimage.h b/Build/source/texk/dvipdfm-x/pngimage.h
new file mode 100644
index 00000000000..26414306ea3
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pngimage.h
@@ -0,0 +1,39 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+
+#ifndef _PNGIMAGE_H_
+#define _PNGIMAGE_H_
+
+#ifdef HAVE_LIBPNG
+
+#include "mfileio.h"
+#include "pdfximage.h"
+
+extern int png_include_image (pdf_ximage *ximage, FILE *file);
+extern int check_for_png (FILE *file);
+extern int png_get_bbox (FILE *fp, uint32_t *width, uint32_t *height,
+ double *xdensity, double *ydensity);
+
+#endif
+
+#endif /* _PNGIMAGE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pst.c b/Build/source/texk/dvipdfm-x/pst.c
new file mode 100644
index 00000000000..77fd8246908
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pst.c
@@ -0,0 +1,184 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <ctype.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxutil.h"
+#include "pst_obj.h"
+#include "pst.h"
+
+
+#define TYPE_CHECK(o, t) do { \
+ if ((o) == NULL || pst_type_of((o)) != (t)) \
+ ERROR("typecheck: object %p not of type %d.", (o), (t)); \
+ } while (0)
+
+static pst_obj *
+pst_parse_any (unsigned char **inbuf, unsigned char *inbufend)
+{
+ unsigned char *data;
+ unsigned char *cur = *inbuf;
+ unsigned int len;
+
+ while (cur < inbufend && !PST_TOKEN_END(cur, inbufend))
+ cur++;
+
+ len = cur - (*inbuf);
+ data = NEW(len+1, unsigned char);
+ memcpy(data, *inbuf, len);
+ data[len] = '\0';
+
+ *inbuf = cur;
+ return pst_new_obj(PST_TYPE_UNKNOWN, data);
+}
+
+static void
+skip_line (unsigned char **inbuf, unsigned char *inbufend)
+{
+ while (*inbuf < inbufend && **inbuf != '\n' && **inbuf != '\r')
+ (*inbuf)++;
+ if (*inbuf < inbufend && **inbuf == '\r')
+ (*inbuf)++;
+ if (*inbuf < inbufend && **inbuf == '\n')
+ (*inbuf)++;
+}
+
+static void
+skip_comments (unsigned char **inbuf, unsigned char *inbufend)
+{
+ while (*inbuf < inbufend && **inbuf == '%') {
+ skip_line(inbuf, inbufend);
+ skip_white_spaces(inbuf, inbufend);
+ }
+}
+
+#if 0
+static pst_obj *
+pst_parse_comment (unsigned char **inbuf, unsigned char *inbufend)
+{
+ unsigned char *data;
+ unsigned char *cur = *inbuf;
+ unsigned int len;
+
+ if (*cur != '%')
+ return NULL;
+
+ while (cur < inbufend && *cur != '\n' && *cur != '\r')
+ cur++;
+ len = cur - (*inbuf);
+ data = NEW(len+1, unsigned char);
+ memcpy(data, *inbuf, len);
+ data[len] = '\0';
+
+ *inbuf = cur;
+ return pst_new_obj(PST_TYPE_UNKNOWN, data);
+}
+#endif
+
+/* NOTE: the input buffer must be null-terminated, i.e., *inbufend == 0 */
+pst_obj *
+pst_get_token (unsigned char **inbuf, unsigned char *inbufend)
+{
+ pst_obj *obj = NULL;
+ unsigned char c;
+
+ ASSERT(*inbuf <= inbufend && !*inbufend);
+
+ skip_white_spaces(inbuf, inbufend);
+ skip_comments(inbuf, inbufend);
+ if (*inbuf >= inbufend)
+ return NULL;
+ c = **inbuf;
+ switch (c) {
+#if 0
+ case '%':
+ obj = pst_parse_comment(inbuf, inbufend);
+ break;
+#endif
+ case '/':
+ obj = pst_parse_name(inbuf, inbufend);
+ break;
+ case '[': case '{': /* This is wrong */
+ obj = pst_new_mark();
+ (*inbuf)++;
+ break;
+ case '<':
+ if (*inbuf + 1 >= inbufend)
+ return NULL;
+ c = *(*inbuf+1);
+ if (c == '<') {
+ obj = pst_new_mark();
+ *inbuf += 2;
+ } else if (isxdigit(c))
+ obj = pst_parse_string(inbuf, inbufend);
+ else if (c == '~') /* ASCII85 */
+ obj = pst_parse_string(inbuf, inbufend);
+ break;
+ case '(':
+ obj = pst_parse_string(inbuf, inbufend);
+ break;
+ case '>':
+ if (*inbuf + 1 >= inbufend || *(*inbuf+1) != '>') {
+ ERROR("Unexpected end of ASCII hex string marker.");
+ } else {
+ char *mark;
+
+ mark = NEW(3, char);
+ mark[0] = '>'; mark[1] = '>'; mark[2] = '\0';
+ obj = pst_new_obj(PST_TYPE_UNKNOWN, mark);
+ (*inbuf) += 2;
+ }
+ break;
+ case ']': case '}':
+ {
+ char *mark;
+
+ mark = NEW(2, char);
+ mark[0] = c; mark[1] = '\0';
+ obj = pst_new_obj(PST_TYPE_UNKNOWN, mark);
+ (*inbuf)++;
+ }
+ break;
+ default:
+ if (c == 't' || c == 'f')
+ obj = pst_parse_boolean(inbuf, inbufend);
+ else if (c == 'n')
+ obj = pst_parse_null(inbuf, inbufend);
+ else if (c == '+' || c == '-' || isdigit(c) || c == '.')
+ obj = pst_parse_number(inbuf, inbufend);
+ break;
+ }
+
+ if (!obj) {
+ obj = pst_parse_any(inbuf, inbufend);
+ }
+
+ return obj;
+}
diff --git a/Build/source/texk/dvipdfm-x/pst.h b/Build/source/texk/dvipdfm-x/pst.h
new file mode 100644
index 00000000000..d7379409e9e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pst.h
@@ -0,0 +1,72 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PST_H_
+#define _PST_H_
+
+#include <stdio.h>
+
+#define PST_TYPE_UNKNOWN -1
+#define PST_TYPE_NULL 0
+#define PST_TYPE_BOOLEAN 1
+#define PST_TYPE_INTEGER 2
+#define PST_TYPE_REAL 3
+#define PST_TYPE_STRING 5
+#define PST_TYPE_NAME 6
+#define PST_TYPE_MARK 7
+
+typedef struct pst_obj pst_obj;
+typedef int pst_type;
+
+extern pst_obj *pst_get_token (unsigned char **inbuf, unsigned char *inbufend);
+
+extern pst_obj *pst_new_obj (pst_type type, void *data);
+extern void pst_release_obj(pst_obj *obj);
+extern pst_obj *pst_new_mark (void);
+
+extern pst_type pst_type_of (pst_obj *obj);
+extern int pst_length_of (pst_obj *obj);
+
+extern int pst_getIV (pst_obj *obj);
+extern double pst_getRV (pst_obj *obj);
+extern unsigned char *pst_getSV (pst_obj *obj);
+
+extern void *pst_data_ptr (pst_obj *obj);
+
+#define PST_NAME_LEN_MAX 127
+#define PST_STRING_LEN_MAX 4096
+#define PST_MAX_DIGITS 10
+#define PST_TOKEN_LEN_MAX PST_STRING_LEN_MAX
+
+#define PST_NULLTYPE(o) (pst_type_of((o)) == PST_TYPE_NULL)
+#define PST_BOOLEANTYPE(o) (pst_type_of((o)) == PST_TYPE_BOOLEAN)
+#define PST_NAMETYPE(o) (pst_type_of((o)) == PST_TYPE_NAME)
+#define PST_STRINGTYPE(o) (pst_type_of((o)) == PST_TYPE_STRING)
+#define PST_INTEGERTYPE(o) (pst_type_of((o)) == PST_TYPE_INTEGER)
+#define PST_REALTYPE(o) (pst_type_of((o)) == PST_TYPE_REAL)
+#define PST_NUMBERTYPE(o) (PST_INTEGERTYPE((o))||PST_REALTYPE((o)))
+#define PST_MARKTYPE(o) (pst_type_of((o)) == PST_TYPE_MARK)
+#define PST_UNKNOWNTYPE(o) (pst_type_of((o)) < 0)
+
+#define PST_TOKEN_END(s,e) ((s) == (e) || is_delim(*(s)) || is_space(*(s)))
+
+#endif /* _PST_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pst_obj.c b/Build/source/texk/dvipdfm-x/pst_obj.c
new file mode 100644
index 00000000000..f6770c94eb1
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pst_obj.c
@@ -0,0 +1,992 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxutil.h"
+#include "pst.h"
+#include "pst_obj.h"
+
+struct pst_obj
+{
+ pst_type type;
+ void *data;
+};
+
+static const char *pst_const_null = "null";
+static const char *pst_const_mark = "mark";
+/*
+static const char *pst_const_true = "true";
+static const char *pst_const_false = "false";
+*/
+
+typedef char * pst_null;
+typedef struct { char value; } pst_boolean;
+typedef struct { int value; } pst_integer;
+typedef struct { double value; } pst_real;
+typedef struct { char *value; } pst_name;
+typedef struct
+{
+ unsigned int length;
+ unsigned char *value;
+} pst_string;
+
+
+/* BOOLEAN */
+static pst_boolean *pst_boolean_new (char value) ;
+static void pst_boolean_release (pst_boolean *obj);
+static int pst_boolean_IV (pst_boolean *obj);
+static double pst_boolean_RV (pst_boolean *obj);
+static unsigned char *pst_boolean_SV (pst_boolean *obj);
+static unsigned int pst_boolean_length (void);
+static void *pst_boolean_data_ptr(pst_boolean *obj);
+
+/* NUMBERS */
+static pst_integer *pst_integer_new (int value) ;
+static void pst_integer_release (pst_integer *obj);
+static int pst_integer_IV (pst_integer *obj);
+static double pst_integer_RV (pst_integer *obj);
+static unsigned char *pst_integer_SV (pst_integer *obj);
+static unsigned int pst_integer_length (void);
+static void *pst_integer_data_ptr(pst_integer *obj);
+
+static pst_real *pst_real_new (double value) ;
+static void pst_real_release (pst_real *obj);
+static int pst_real_IV (pst_real *obj);
+static double pst_real_RV (pst_real *obj);
+static unsigned char *pst_real_SV (pst_real *obj);
+static void *pst_real_data_ptr (pst_real *obj);
+static unsigned int pst_real_length (void);
+
+/* NAME */
+static pst_name *pst_name_new (const char *name) ;
+static void pst_name_release (pst_name *obj);
+static int pst_name_IV (void);
+static double pst_name_RV (void);
+static unsigned char *pst_name_SV (pst_name *obj);
+static void *pst_name_data_ptr (pst_name *obj);
+static unsigned int pst_name_length (pst_name *obj);
+
+/* STRING */
+static pst_string *pst_string_parse_literal (unsigned char **inbuf, unsigned char *inbufend);
+static pst_string *pst_string_parse_hex (unsigned char **inbuf, unsigned char *inbufend);
+
+static pst_string *pst_string_new (unsigned char *str, unsigned int len);
+static void pst_string_release (pst_string *obj) ;
+static int pst_string_IV (pst_string *obj) ;
+static double pst_string_RV (pst_string *obj) ;
+static unsigned char *pst_string_SV (pst_string *obj) ;
+static void *pst_string_data_ptr (pst_string *obj) ;
+static unsigned int pst_string_length (pst_string *obj) ;
+
+
+#define TYPE_ERROR() ERROR("Operation not defined for this type of object.")
+
+pst_obj *
+pst_new_obj (pst_type type, void *data)
+{
+ pst_obj *obj;
+
+ obj = NEW(1, struct pst_obj);
+ obj->type = type;
+ obj->data = data;
+
+ return obj;
+}
+
+pst_obj *
+pst_new_mark (void)
+{
+ char *q;
+
+ q = NEW(strlen(pst_const_mark)+1, char);
+ strcpy(q, pst_const_mark);
+ return pst_new_obj(PST_TYPE_MARK, (void *)q);
+}
+
+void
+pst_release_obj (pst_obj *obj)
+{
+ ASSERT(obj);
+ switch (obj->type) {
+ case PST_TYPE_BOOLEAN: pst_boolean_release(obj->data); break;
+ case PST_TYPE_INTEGER: pst_integer_release(obj->data); break;
+ case PST_TYPE_REAL: pst_real_release(obj->data); break;
+ case PST_TYPE_NAME: pst_name_release(obj->data); break;
+ case PST_TYPE_STRING: pst_string_release(obj->data); break;
+ case PST_TYPE_NULL:
+ case PST_TYPE_MARK:
+ case PST_TYPE_UNKNOWN:
+ if (obj->data)
+ RELEASE(obj->data);
+ break;
+ default:
+ ERROR("Unrecognized object type: %d", obj->type);
+ }
+ RELEASE(obj);
+}
+
+pst_type
+pst_type_of (pst_obj *obj)
+{
+ ASSERT(obj);
+ return obj->type;
+}
+
+int
+pst_length_of (pst_obj *obj)
+{
+ int len = 0;
+
+ ASSERT(obj);
+ switch (obj->type) {
+ case PST_TYPE_BOOLEAN: len = pst_boolean_length(); break;
+ case PST_TYPE_INTEGER: len = pst_integer_length(); break;
+ case PST_TYPE_REAL: len = pst_real_length(); break;
+ case PST_TYPE_NAME: len = pst_name_length(obj->data); break;
+ case PST_TYPE_STRING: len = pst_string_length(obj->data); break;
+ case PST_TYPE_NULL:
+ case PST_TYPE_MARK:
+ TYPE_ERROR();
+ break;
+ case PST_TYPE_UNKNOWN:
+ len = strlen(obj->data);
+ break;
+ default:
+ ERROR("Unrecognized object type: %d", obj->type);
+ }
+
+ return len;
+}
+
+int
+pst_getIV (pst_obj *obj)
+{
+ int iv = 0;
+
+ ASSERT(obj);
+ switch (obj->type) {
+ case PST_TYPE_BOOLEAN: iv = pst_boolean_IV(obj->data); break;
+ case PST_TYPE_INTEGER: iv = pst_integer_IV(obj->data); break;
+ case PST_TYPE_REAL: iv = pst_real_IV(obj->data); break;
+ case PST_TYPE_NAME: iv = pst_name_IV(); break;
+ case PST_TYPE_STRING: iv = pst_string_IV(obj->data); break;
+ case PST_TYPE_NULL:
+ case PST_TYPE_MARK:
+ TYPE_ERROR();
+ break;
+ case PST_TYPE_UNKNOWN:
+ ERROR("Cannot convert object of type UNKNOWN to integer value.");
+ break;
+ default:
+ ERROR("Unrecognized object type: %d", obj->type);
+ }
+
+ return iv;
+}
+
+double
+pst_getRV (pst_obj *obj)
+{
+ double rv = 0.0;
+
+ ASSERT(obj);
+ switch (obj->type) {
+ case PST_TYPE_BOOLEAN: rv = pst_boolean_RV(obj->data); break;
+ case PST_TYPE_INTEGER: rv = pst_integer_RV(obj->data); break;
+ case PST_TYPE_REAL: rv = pst_real_RV(obj->data); break;
+ case PST_TYPE_NAME: rv = pst_name_RV(); break;
+ case PST_TYPE_STRING: rv = pst_string_RV(obj->data); break;
+ case PST_TYPE_NULL:
+ case PST_TYPE_MARK:
+ TYPE_ERROR();
+ break;
+ case PST_TYPE_UNKNOWN:
+ ERROR("Cannot convert object of type UNKNOWN to real value.");
+ break;
+ default:
+ ERROR("Unrecognized object type: %d", obj->type);
+ }
+
+ return rv;
+}
+
+/* Length can be obtained by pst_length_of(). */
+unsigned char *
+pst_getSV (pst_obj *obj)
+{
+ unsigned char *sv = NULL;
+
+ ASSERT(obj);
+ switch (obj->type) {
+ case PST_TYPE_BOOLEAN: sv = pst_boolean_SV(obj->data); break;
+ case PST_TYPE_INTEGER: sv = pst_integer_SV(obj->data); break;
+ case PST_TYPE_REAL: sv = pst_real_SV(obj->data); break;
+ case PST_TYPE_NAME: sv = pst_name_SV(obj->data); break;
+ case PST_TYPE_STRING: sv = pst_string_SV(obj->data); break;
+ case PST_TYPE_NULL:
+ case PST_TYPE_MARK:
+ TYPE_ERROR();
+ break;
+ case PST_TYPE_UNKNOWN:
+ {
+ int len;
+
+ len = strlen((char *) obj->data);
+ if (len > 0) {
+ sv = NEW(len+1, unsigned char);
+ memcpy(sv, obj->data, len);
+ sv[len] = '\0';
+ } else {
+ sv = NULL;
+ }
+ break;
+ }
+ default:
+ ERROR("Unrecognized object type: %d", obj->type);
+ }
+
+ return sv;
+}
+
+void *
+pst_data_ptr (pst_obj *obj)
+{
+ char *p = NULL;
+
+ ASSERT(obj);
+ switch (obj->type) {
+ case PST_TYPE_BOOLEAN: p = pst_boolean_data_ptr(obj->data); break;
+ case PST_TYPE_INTEGER: p = pst_integer_data_ptr(obj->data); break;
+ case PST_TYPE_REAL: p = pst_real_data_ptr(obj->data); break;
+ case PST_TYPE_NAME: p = pst_name_data_ptr(obj->data); break;
+ case PST_TYPE_STRING: p = pst_string_data_ptr(obj->data); break;
+ case PST_TYPE_NULL:
+ case PST_TYPE_MARK:
+ TYPE_ERROR();
+ break;
+ case PST_TYPE_UNKNOWN:
+ p = obj->data;
+ break;
+ default:
+ ERROR("Unrecognized object type: %d", obj->type);
+ }
+
+ return (void *)p;
+}
+
+/* BOOLEAN */
+static pst_boolean *
+pst_boolean_new (char value)
+{
+ pst_boolean *obj;
+ obj = NEW(1, pst_boolean);
+ obj->value = value;
+ return obj;
+}
+
+static void
+pst_boolean_release (pst_boolean *obj)
+{
+ ASSERT(obj);
+ RELEASE(obj);
+}
+
+static int
+pst_boolean_IV (pst_boolean *obj)
+{
+ ASSERT(obj);
+ return (int) obj->value;
+}
+
+static double
+pst_boolean_RV (pst_boolean *obj)
+{
+ ASSERT(obj);
+ return (double) obj->value;
+}
+
+static unsigned char *
+pst_boolean_SV (pst_boolean *obj)
+{
+ unsigned char *str;
+
+ ASSERT(obj);
+
+ if (obj->value) {
+ str = NEW(5, unsigned char);
+ memcpy(str, "true", 4);
+ str[4] = '\0';
+ } else {
+ str = NEW(6, unsigned char);
+ memcpy(str, "false", 5);
+ str[5] = '\0';
+ }
+
+ return str;
+}
+
+static unsigned int
+pst_boolean_length (void)
+{
+ TYPE_ERROR();
+ return 0;
+}
+
+static void *
+pst_boolean_data_ptr (pst_boolean *obj)
+{
+ ASSERT(obj);
+ return (void*) &(obj->value);
+}
+
+pst_obj *
+pst_parse_boolean (unsigned char **inbuf, unsigned char *inbufend)
+{
+ if (*inbuf + 4 <= inbufend &&
+ memcmp(*inbuf, "true", 4) == 0 &&
+ PST_TOKEN_END(*inbuf + 4, inbufend)) {
+ *inbuf += 4;
+ return pst_new_obj(PST_TYPE_BOOLEAN, pst_boolean_new(1));
+ } else if (*inbuf + 5 <= inbufend &&
+ memcmp(*inbuf, "false", 5) == 0 &&
+ PST_TOKEN_END(*inbuf + 5, inbufend)) {
+ *inbuf += 5;
+ return pst_new_obj(PST_TYPE_BOOLEAN, pst_boolean_new(0));
+ } else
+ return NULL;
+}
+
+
+/* NULL */
+pst_obj *
+pst_parse_null (unsigned char **inbuf, unsigned char *inbufend)
+{
+ if (*inbuf + 4 <= inbufend &&
+ memcmp(*inbuf, "null", 4) == 0 &&
+ PST_TOKEN_END(*inbuf+4, inbufend)) {
+ char *q;
+
+ *inbuf += 4;
+ q = NEW(strlen(pst_const_null)+1, char);
+ strcpy(q, pst_const_null);
+ return pst_new_obj(PST_TYPE_NULL, (void*)q);
+ } else
+ return NULL;
+}
+
+/* INTEGER */
+static pst_integer *
+pst_integer_new (int value)
+{
+ pst_integer *obj;
+ obj = NEW(1, pst_integer);
+ obj->value = value;
+ return obj;
+}
+
+static void
+pst_integer_release (pst_integer *obj)
+{
+ ASSERT(obj);
+ RELEASE(obj);
+}
+
+static int
+pst_integer_IV (pst_integer *obj)
+{
+ ASSERT(obj);
+ return (int) obj->value;
+}
+
+static double
+pst_integer_RV (pst_integer *obj)
+{
+ ASSERT(obj);
+ return (double) obj->value;
+}
+
+static unsigned char *
+pst_integer_SV (pst_integer *obj)
+{
+ char *value;
+ int len;
+ char fmt_buf[PST_MAX_DIGITS+5];
+
+ ASSERT(obj);
+
+ len = sprintf(fmt_buf, "%d", obj->value);
+
+ value = NEW(len + 1, char);
+ strcpy(value, fmt_buf);
+
+ return (unsigned char *) value;
+}
+
+static void *
+pst_integer_data_ptr (pst_integer *obj)
+{
+ ASSERT(obj);
+ return (void*) &(obj->value);
+}
+
+static unsigned int
+pst_integer_length (void)
+{
+ TYPE_ERROR();
+ return 0;
+}
+
+/* REAL */
+static pst_real *
+pst_real_new (double value)
+{
+ pst_real *obj;
+
+ obj = NEW(1, pst_real);
+ obj->value = value;
+
+ return obj;
+}
+
+static void
+pst_real_release (pst_real *obj)
+{
+ ASSERT(obj);
+ RELEASE(obj);
+}
+
+static int
+pst_real_IV (pst_real *obj)
+{
+ ASSERT(obj);
+ return (int) obj->value;
+}
+
+static double
+pst_real_RV (pst_real *obj)
+{
+ ASSERT(obj);
+ return (double) obj->value;
+}
+
+static unsigned char *
+pst_real_SV (pst_real *obj)
+{
+ char *value;
+ int len;
+ char fmt_buf[PST_MAX_DIGITS+5];
+
+ ASSERT(obj);
+
+ len = sprintf(fmt_buf, "%.5g", obj->value);
+
+ value = NEW(len, char);
+ strcpy(value, fmt_buf);
+
+ return (unsigned char *) value;
+}
+
+static void *
+pst_real_data_ptr (pst_real *obj)
+{
+ ASSERT(obj);
+
+ return (void*) &(obj->value);
+}
+
+static unsigned int
+pst_real_length (void)
+{
+ TYPE_ERROR();
+ return 0;
+}
+
+/* NOTE: the input buffer must be null-terminated, i.e., *inbufend == 0 */
+/* leading white-space is ignored */
+pst_obj *
+pst_parse_number (unsigned char **inbuf, unsigned char *inbufend)
+{
+ unsigned char *cur;
+ int lval;
+ double dval;
+
+ errno = 0;
+ lval = strtol((char *) *inbuf, (char **) (void *) &cur, 10);
+ if (errno || *cur == '.' || *cur == 'e' || *cur == 'E') {
+ /* real */
+ errno = 0;
+ dval = strtod((char *) *inbuf, (char **) (void *) &cur);
+ if (!errno && PST_TOKEN_END(cur, inbufend)) {
+ *inbuf = cur;
+ return pst_new_obj(PST_TYPE_REAL, pst_real_new(dval));
+ }
+ } else if (cur != *inbuf && PST_TOKEN_END(cur, inbufend)) {
+ /* integer */
+ *inbuf = cur;
+ return pst_new_obj(PST_TYPE_INTEGER, pst_integer_new(lval));
+ } else if (lval >= 2 && lval <= 36 && *cur == '#' && isalnum(*++cur) &&
+ /* strtod allows leading "0x" for hex numbers, but we don't */
+ (lval != 16 || (cur[1] != 'x' && cur[1] != 'X'))) {
+ /* integer with radix */
+ /* Can the base have a (plus) sign? I think yes. */
+ errno = 0;
+ lval = strtol((char *) cur, (char **) (void *) &cur, lval);
+ if (!errno && PST_TOKEN_END(cur, inbufend)) {
+ *inbuf = cur;
+ return pst_new_obj(PST_TYPE_INTEGER, pst_integer_new(lval));
+ }
+ }
+ /* error */
+ return NULL;
+}
+
+/* NAME */
+
+/*
+ * \0 is not allowed for name object.
+ */
+
+static pst_name *
+pst_name_new (const char *name)
+{
+ pst_name *obj;
+
+ obj = NEW(1, pst_name);
+ obj->value = NEW(strlen(name)+1, char);
+ strcpy(obj->value, name);
+
+ return obj;
+}
+
+static void
+pst_name_release (pst_name *obj)
+{
+ ASSERT(obj);
+ if (obj->value)
+ RELEASE(obj->value);
+ RELEASE(obj);
+}
+
+#if 0
+static int
+pst_name_is_valid (const char *name)
+{
+ static const char *valid_chars =
+ "!\"#$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~";
+ if (strspn(name, valid_chars) == strlen(name))
+ return 1;
+ else
+ return 0;
+}
+
+static int
+putxpair (unsigned char c, char **s)
+{
+ char hi = (c >> 4), lo = c & 0x0f;
+
+ **s = (hi < 10) ? hi + '0' : hi + '7';
+ *(*s+1) = (lo < 10) ? lo + '0' : lo + '7';
+ *s += 2;
+
+ return 2;
+}
+
+static char *
+pst_name_encode (const char *name)
+{
+ char *encoded_name, *p;
+ int i, len;
+ char c;
+
+ len = strlen(name);
+ if (len > PST_NAME_LEN_MAX) {
+ WARN("Input string too long for name object. String will be truncated.");
+ len = PST_NAME_LEN_MAX;
+ }
+
+ p = encoded_name = NEW(3*len+1, char);
+ for (i = 0; i < len; i++) {
+ c = name[i];
+ if (c < '!' || c > '~' ||
+ c == '#' || is_delim(c) || is_space(c)) {
+ *p++ = '#';
+ putxpair(c, &p);
+ } else {
+ *p++ = c;
+ }
+ }
+ *p = '\0';
+
+ return encoded_name;
+}
+#endif
+
+static int
+getxpair (unsigned char **s)
+{
+ int hi, lo;
+ hi = xtoi(**s);
+ if (hi < 0)
+ return hi;
+ (*s)++;
+ lo = xtoi(**s);
+ if (lo < 0)
+ return lo;
+ (*s)++;
+ return ((hi << 4)| lo);
+}
+
+pst_obj *
+pst_parse_name (unsigned char **inbuf, unsigned char *inbufend) /* / is required */
+{
+ unsigned char wbuf[PST_NAME_LEN_MAX+1];
+ unsigned char c, *p = wbuf, *cur = *inbuf;
+ int len = 0;
+
+ if (*cur != '/')
+ return NULL;
+ cur++;
+
+ while (!PST_TOKEN_END(cur, inbufend)) {
+ c = *cur++;
+ if (c == '#') {
+ int val;
+ if (cur + 2 >= inbufend) {
+ WARN("Premature end of input name string.");
+ break;
+ }
+ val = getxpair(&cur);
+ if (val <= 0) {
+ WARN("Invalid char for name object. (ignored)");
+ continue;
+ } else
+ c = (unsigned char) val;
+ }
+ if (len < PST_NAME_LEN_MAX)
+ *p++ = c;
+ len++;
+ }
+ *p = '\0';
+
+ if (len > PST_NAME_LEN_MAX)
+ WARN("String too long for name object. Output will be truncated.");
+
+ *inbuf = cur;
+ return pst_new_obj(PST_TYPE_NAME, pst_name_new((char *)wbuf));
+}
+
+static int
+pst_name_IV (void)
+{
+ TYPE_ERROR();
+ return 0;
+}
+
+static double
+pst_name_RV (void)
+{
+ TYPE_ERROR();
+ return 0;
+}
+
+static unsigned char *
+pst_name_SV (pst_name *obj)
+{
+ char *value;
+
+ value = NEW(strlen(obj->value)+1, char);
+ strcpy(value, obj->value);
+
+ return (unsigned char *) value;
+}
+
+static void *
+pst_name_data_ptr (pst_name *obj)
+{
+ ASSERT(obj);
+ return obj->value;
+}
+
+static unsigned int
+pst_name_length (pst_name *obj)
+{
+ ASSERT(obj);
+ return strlen(obj->value);
+}
+
+
+/* STRING */
+
+/*
+ * TODO: ascii85 string <~ .... ~>
+ */
+static pst_string *
+pst_string_new (unsigned char *str, unsigned int len)
+{
+ pst_string *obj;
+ obj = NEW(1, pst_string);
+ obj->length = len;
+ obj->value = NULL;
+ if (len > 0) {
+ obj->value = NEW(len, unsigned char);
+ if (str)
+ memcpy(obj->value, str, len);
+ }
+ return obj;
+}
+
+static void
+pst_string_release (pst_string *obj)
+{
+ ASSERT(obj);
+ if (obj->value)
+ RELEASE(obj->value);
+ RELEASE(obj);
+}
+
+pst_obj *
+pst_parse_string (unsigned char **inbuf, unsigned char *inbufend)
+{
+ if (*inbuf + 2 >= inbufend) {
+ return NULL;
+ } else if (**inbuf == '(')
+ return pst_new_obj(PST_TYPE_STRING, pst_string_parse_literal(inbuf, inbufend));
+ else if (**inbuf == '<' && *(*inbuf+1) == '~')
+ ERROR("ASCII85 string not supported yet.");
+ else if (**inbuf == '<')
+ return pst_new_obj(PST_TYPE_STRING, pst_string_parse_hex(inbuf, inbufend));
+ return NULL;
+}
+
+/* Overflowed value is set to invalid char. */
+static unsigned char
+ostrtouc (unsigned char **inbuf, unsigned char *inbufend, unsigned char *valid)
+{
+ unsigned char *cur = *inbuf;
+ unsigned int val = 0;
+
+ while (cur < inbufend && cur < *inbuf + 3 &&
+ (*cur >= '0' && *cur <= '7')) {
+ val = (val << 3) | (*cur - '0');
+ cur++;
+ }
+ if (val > 255 || cur == *inbuf)
+ *valid = 0;
+ else
+ *valid = 1;
+
+ *inbuf = cur;
+ return (unsigned char) val;
+}
+
+static unsigned char
+esctouc (unsigned char **inbuf, unsigned char *inbufend, unsigned char *valid)
+{
+ unsigned char unescaped, escaped;
+
+ escaped = **inbuf;
+ *valid = 1;
+ switch (escaped) {
+ /* Backslash, unbalanced paranthes */
+ case '\\': case ')': case '(':
+ unescaped = escaped;
+ (*inbuf)++;
+ break;
+ /* Other escaped char */
+ case 'n': unescaped = '\n'; (*inbuf)++; break;
+ case 'r': unescaped = '\r'; (*inbuf)++; break;
+ case 't': unescaped = '\t'; (*inbuf)++; break;
+ case 'b': unescaped = '\b'; (*inbuf)++; break;
+ case 'f': unescaped = '\f'; (*inbuf)++; break;
+ /*
+ * An end-of-line marker preceeded by backslash is not part of a
+ * literal string
+ */
+ case '\r':
+ unescaped = 0;
+ *valid = 0;
+ *inbuf += (*inbuf < inbufend - 1 && *(*inbuf+1) == '\n') ? 2 : 1;
+ break;
+ case '\n':
+ unescaped = 0;
+ *valid = 0;
+ (*inbuf)++;
+ break;
+ /* Possibly octal notion */
+ default:
+ unescaped = ostrtouc(inbuf, inbufend, valid);
+ }
+
+ return unescaped;
+}
+
+static pst_string *
+pst_string_parse_literal (unsigned char **inbuf, unsigned char *inbufend)
+{
+ unsigned char wbuf[PST_STRING_LEN_MAX];
+ unsigned char *cur = *inbuf, c = 0;
+ int len = 0, balance = 1;
+
+ if (cur + 2 > inbufend || *cur != '(')
+ return NULL;
+
+ cur++;
+ while (cur < inbufend && len < PST_STRING_LEN_MAX && balance > 0) {
+ c = *(cur++);
+ switch (c) {
+ case '\\':
+ {
+ unsigned char unescaped, valid;
+ unescaped = esctouc(&cur, inbufend, &valid);
+ if (valid)
+ wbuf[len++] = unescaped;
+ }
+ break;
+ case '(':
+ balance++;
+ wbuf[len++] = '(';
+ break;
+ case ')':
+ balance--;
+ if (balance > 0)
+ wbuf[len++] = ')';
+ break;
+ /*
+ * An end-of-line marker (\n, \r or \r\n), not preceeded by a backslash,
+ * must be converted to single \n.
+ */
+ case '\r':
+ if (cur < inbufend && *cur == '\n')
+ cur++;
+ wbuf[len++] = '\n';
+ break;
+ default:
+ wbuf[len++] = c;
+ }
+ }
+ if (c != ')')
+ return NULL;
+
+ *inbuf = cur;
+ return pst_string_new(wbuf, len);
+}
+
+static pst_string *
+pst_string_parse_hex (unsigned char **inbuf, unsigned char *inbufend)
+{
+ unsigned char wbuf[PST_STRING_LEN_MAX];
+ unsigned char *cur = *inbuf;
+ unsigned int len = 0;
+
+ if (cur + 2 > inbufend || *cur != '<' ||
+ (*cur == '<' && *(cur+1) == '<'))
+ return NULL;
+
+ cur++;
+ /* PDF Reference does not specify how to treat invalid char */
+ while (cur < inbufend && len < PST_STRING_LEN_MAX) {
+ int hi, lo;
+ skip_white_spaces(&cur, inbufend);
+ if (*cur == '>')
+ break;
+ hi = xtoi(*(cur++));
+ if (hi < 0) {
+ WARN("Invalid char for hex string <%x> treated as <0>.", *(cur-1));
+ hi = 0;
+ }
+ skip_white_spaces(&cur, inbufend);
+ if (*cur == '>')
+ break;
+ /* 0 is appended if final hex digit is missing */
+ lo = (cur < inbufend) ? xtoi(*(cur++)) : 0;
+ if (lo < 0) {
+ WARN("Invalid char for hex string <%x> treated as <0>.", *(cur-1));
+ lo = 0;
+ }
+ wbuf[len++] = (hi << 4) | lo;
+ }
+ if (*cur++ != '>')
+ return NULL;
+
+ *inbuf = cur;
+ return pst_string_new(wbuf, len);
+}
+
+static int
+pst_string_IV (pst_string *obj)
+{
+ return (int) pst_string_RV(obj);
+}
+
+static double
+pst_string_RV (pst_string *obj)
+{
+ pst_obj *nobj;
+ unsigned char *p, *end;
+ double rv;
+
+ ASSERT(obj);
+ p = obj->value;
+ end = p + obj->length;
+ nobj = pst_parse_number(&p, end);
+ if (nobj == NULL || p != end)
+ ERROR("Cound not convert string to real value.");
+ rv = pst_getRV(nobj);
+ pst_release_obj(nobj);
+
+ return rv;
+}
+
+static unsigned char *
+pst_string_SV (pst_string *obj)
+{
+ unsigned char *str = NULL;
+ ASSERT(obj);
+ str = NEW(obj->length + 1, unsigned char);
+ memcpy(str, obj->value, obj->length);
+ str[obj->length] = '\0';
+ return str;
+}
+
+static void *
+pst_string_data_ptr (pst_string *obj)
+{
+ ASSERT(obj);
+ return obj->value;
+}
+
+static unsigned int
+pst_string_length (pst_string *obj)
+{
+ ASSERT(obj);
+ return obj->length;
+}
diff --git a/Build/source/texk/dvipdfm-x/pst_obj.h b/Build/source/texk/dvipdfm-x/pst_obj.h
new file mode 100644
index 00000000000..a5283cea2ea
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/pst_obj.h
@@ -0,0 +1,34 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _PST_OBJ_H_
+#define _PST_OBJ_H_
+
+#include "pst.h"
+
+extern pst_obj *pst_parse_null (unsigned char **inbuf, unsigned char *inbufend);
+extern pst_obj *pst_parse_boolean(unsigned char **inbuf, unsigned char *inbufend);
+extern pst_obj *pst_parse_name (unsigned char **inbuf, unsigned char *inbufend);
+extern pst_obj *pst_parse_number (unsigned char **inbuf, unsigned char *inbufend);
+extern pst_obj *pst_parse_string (unsigned char **inbuf, unsigned char *inbufend);
+
+#endif /* _PST_OBJ_H_ */
diff --git a/Build/source/texk/dvipdfm-x/sfnt.c b/Build/source/texk/dvipdfm-x/sfnt.c
new file mode 100644
index 00000000000..43170aa9731
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/sfnt.c
@@ -0,0 +1,532 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/* Based on dvipdfmx-0.13.2c */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+
+#include "error.h"
+#include "mem.h"
+#include "mfileio.h"
+
+#include "sfnt.h"
+
+/*
+ * type:
+ * `true' (0x74727565): TrueType (Mac)
+ * `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper
+ * 0x00010000: TrueType (Win)/OpenType
+ * `OTTO': PostScript CFF font with OpenType wrapper
+ * `ttcf': TrueType Collection
+*/
+#define SFNT_TRUETYPE 0x00010000UL
+#define SFNT_MAC_TRUE 0x74727565UL
+#define SFNT_OPENTYPE 0x00010000UL
+#define SFNT_POSTSCRIPT 0x4f54544fUL
+#define SFNT_TTC 0x74746366UL
+
+sfnt *
+sfnt_open (FILE *fp)
+{
+ sfnt *sfont;
+ ULONG type;
+
+ ASSERT(fp);
+
+ rewind(fp);
+
+ sfont = NEW(1, sfnt);
+
+ sfont->stream = fp;
+
+ type = sfnt_get_ulong(sfont);
+
+ if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) {
+ sfont->type = SFNT_TYPE_TRUETYPE;
+ } else if (type == SFNT_OPENTYPE) {
+ sfont->type = SFNT_TYPE_OPENTYPE;
+ } else if (type == SFNT_POSTSCRIPT) {
+ sfont->type = SFNT_TYPE_POSTSCRIPT;
+ } else if (type == SFNT_TTC) {
+ sfont->type = SFNT_TYPE_TTC;
+ }
+
+ rewind(sfont->stream);
+
+ sfont->directory = NULL;
+ sfont->offset = 0UL;
+
+ return sfont;
+}
+
+sfnt *
+dfont_open (FILE *fp, int index)
+{
+ sfnt *sfont;
+ ULONG rdata_pos, map_pos, tags_pos, types_pos, res_pos, tag;
+ USHORT tags_num, types_num, i;
+
+ ASSERT(fp);
+
+ rewind(fp);
+
+ sfont = NEW(1, sfnt);
+
+ sfont->stream = fp;
+
+ rdata_pos = sfnt_get_ulong(sfont);
+ map_pos = sfnt_get_ulong(sfont);
+ sfnt_seek_set(sfont, map_pos + 0x18);
+ tags_pos = map_pos + sfnt_get_ushort(sfont);
+ sfnt_seek_set(sfont, tags_pos);
+ tags_num = sfnt_get_ushort(sfont);
+
+ for (i = 0; i <= tags_num; i++) {
+ tag = sfnt_get_ulong(sfont); /* tag name */
+ types_num = sfnt_get_ushort(sfont); /* typefaces number */
+ types_pos = tags_pos + sfnt_get_ushort(sfont); /* typefaces position */
+ if (tag == 0x73666e74UL) /* "sfnt" */
+ break;
+ }
+
+ if (i > tags_num) {
+ RELEASE(sfont);
+ return NULL;
+ }
+
+ sfnt_seek_set(sfont, types_pos);
+ if (index > types_num) {
+ ERROR("Invalid index %d for dfont.", index);
+ }
+
+ for (i = 0; i <= types_num; i++) {
+ (void) sfnt_get_ushort(sfont); /* resource id */
+ (void) sfnt_get_ushort(sfont); /* resource name position from name_list */
+ res_pos = sfnt_get_ulong(sfont); /* resource flag (byte) + resource offset */
+ sfnt_get_ulong(sfont); /* mbz */
+ if (i == index) break;
+ }
+
+ rewind(sfont->stream);
+
+ sfont->type = SFNT_TYPE_DFONT;
+ sfont->directory = NULL;
+ sfont->offset = (res_pos & 0x00ffffffUL) + rdata_pos + 4;
+
+ return sfont;
+}
+
+static void
+release_directory (struct sfnt_table_directory *td)
+{
+ int i;
+
+ if (td) {
+ if (td->tables) {
+ for (i = 0; i < td->num_tables; i++) {
+ if (td->tables[i].data)
+ RELEASE(td->tables[i].data);
+ }
+ RELEASE(td->tables);
+ }
+ if (td->flags)
+ RELEASE(td->flags);
+ RELEASE(td);
+ }
+
+ return;
+}
+
+void
+sfnt_close (sfnt *sfont)
+{
+
+ if (sfont) {
+ if (sfont->directory)
+ release_directory(sfont->directory);
+ RELEASE(sfont);
+ }
+
+ return;
+}
+
+int
+put_big_endian (void *s, LONG q, int n)
+{
+ int i;
+ char *p;
+
+ p = (char *) s;
+ for (i = n - 1; i >= 0; i--) {
+ p[i] = (char) (q & 0xff);
+ q >>= 8;
+ }
+
+ return n;
+}
+
+/* Convert four-byte number to big endianess
+ * in a machine independent way.
+ */
+static void
+convert_tag (char *tag, uint32_t u_tag)
+{
+ int i;
+
+ for (i = 3; i >= 0; i--) {
+ tag[i] = (char) (u_tag % 256);
+ u_tag /= 256;
+ }
+
+ return;
+}
+
+/*
+ * Computes the max power of 2 <= n
+ */
+static unsigned
+max2floor (unsigned n)
+{
+ int val = 1;
+
+ while (n > 1) {
+ n /= 2;
+ val *= 2;
+ }
+
+ return val;
+}
+
+/*
+ * Computes the log2 of the max power of 2 <= n
+ */
+static unsigned
+log2floor (unsigned n)
+{
+ unsigned val = 0;
+
+ while (n > 1) {
+ n /= 2;
+ val++;
+ }
+
+ return val;
+}
+
+static ULONG
+sfnt_calc_checksum(void *data, ULONG length)
+{
+ ULONG chksum = 0;
+ BYTE *p, *endptr;
+ int count = 0;
+
+ p = (BYTE *) data;
+ endptr = p + length;
+ while (p < endptr) {
+ chksum += (p[0] << (8 * ( 3 - count)));
+ count = ((count + 1) & 3);
+ p++;
+ }
+
+ return chksum;
+}
+
+static int
+find_table_index (struct sfnt_table_directory *td, const char *tag)
+{
+ int idx;
+
+ if (!td)
+ return -1;
+
+ for (idx = 0; idx < td->num_tables; idx++) {
+ if (!memcmp(td->tables[idx].tag, tag, 4))
+ return idx;
+ }
+
+ return -1;
+}
+
+void
+sfnt_set_table (sfnt *sfont, const char *tag, void *data, ULONG length)
+{
+ struct sfnt_table_directory *td;
+ int idx;
+
+ ASSERT(sfont);
+
+ td = sfont->directory;
+ idx = find_table_index(td, tag);
+
+ if (idx < 0) {
+ idx = td->num_tables;
+ td->num_tables++;
+ td->tables = RENEW(td->tables, td->num_tables, struct sfnt_table);
+ memcpy(td->tables[idx].tag, tag, 4);
+ }
+
+ td->tables[idx].check_sum = sfnt_calc_checksum(data, length);
+ td->tables[idx].offset = 0L;
+ td->tables[idx].length = length;
+ td->tables[idx].data = data;
+
+ return;
+}
+
+ULONG
+sfnt_find_table_len (sfnt *sfont, const char *tag)
+{
+ ULONG length;
+ struct sfnt_table_directory *td;
+ int idx;
+
+ ASSERT(sfont && tag);
+
+ td = sfont->directory;
+ idx = find_table_index(td, tag);
+ if (idx < 0)
+ length = 0;
+ else {
+ length = td->tables[idx].length;
+ }
+
+ return length;
+}
+
+ULONG
+sfnt_find_table_pos (sfnt *sfont, const char *tag)
+{
+ ULONG offset;
+ struct sfnt_table_directory *td;
+ int idx;
+
+ ASSERT(sfont && tag);
+
+ td = sfont->directory;
+ idx = find_table_index(td, tag);
+ if (idx < 0)
+ offset = 0;
+ else {
+ offset = td->tables[idx].offset;
+ }
+
+ return offset;
+}
+
+ULONG
+sfnt_locate_table (sfnt *sfont, const char *tag)
+{
+ ULONG offset;
+
+ ASSERT(sfont && tag);
+
+ offset = sfnt_find_table_pos(sfont, tag);
+ if (offset == 0)
+ ERROR("sfnt: table not found...");
+
+ sfnt_seek_set(sfont, offset);
+
+ return offset;
+}
+
+int
+sfnt_read_table_directory (sfnt *sfont, ULONG offset)
+{
+ struct sfnt_table_directory *td;
+ int i;
+ uint32_t u_tag;
+
+ ASSERT(sfont);
+
+ if (sfont->directory)
+ release_directory(sfont->directory);
+
+ sfont->directory = td = NEW (1, struct sfnt_table_directory);
+
+ ASSERT(sfont->stream);
+
+ sfnt_seek_set(sfont, offset);
+
+ td->version = sfnt_get_ulong(sfont);
+ td->num_tables = sfnt_get_ushort(sfont);
+ td->search_range = sfnt_get_ushort(sfont);
+ td->entry_selector = sfnt_get_ushort(sfont);
+ td->range_shift = sfnt_get_ushort(sfont);
+
+ td->flags = NEW(td->num_tables, char);
+ td->tables = NEW(td->num_tables, struct sfnt_table);
+
+ for (i = 0; i < td->num_tables; i++) {
+ u_tag = sfnt_get_ulong(sfont);
+
+ convert_tag(td->tables[i].tag, u_tag);
+ td->tables[i].check_sum = sfnt_get_ulong(sfont);
+ td->tables[i].offset = sfnt_get_ulong(sfont) + sfont->offset;
+ td->tables[i].length = sfnt_get_ulong(sfont);
+ td->tables[i].data = NULL;
+//fprintf(stderr, "[%4s:%x]", td->tables[i].tag, td->tables[i].offset);
+
+ td->flags[i] = 0;
+ }
+
+ td->num_kept_tables = 0;
+
+ return 0;
+}
+
+int
+sfnt_require_table (sfnt *sfont, const char *tag, int must_exist)
+{
+ struct sfnt_table_directory *td;
+ int idx;
+
+ ASSERT(sfont && sfont->directory);
+
+ td = sfont->directory;
+ idx = find_table_index(td, tag);
+ if (idx < 0) {
+ if (must_exist)
+ return -1;
+ } else {
+ td->flags[idx] |= SFNT_TABLE_REQUIRED;
+ td->num_kept_tables++;
+ }
+
+ return 0;
+}
+
+#include "pdfobj.h"
+
+/*
+ * o All tables begin on four byte boundries, and pad any remaining space
+ * between tables with zeros
+ *
+ * o Entries in the Table Directory must be sorted in ascending order by tag
+ *
+ * o The head table contains checksum of the whole font file.
+ * To compute: first set it to 0, sum the entire font as ULONG,
+ * then store 0xB1B0AFBA - sum.
+ */
+
+static unsigned char wbuf[1024], padbytes[4] = {0, 0, 0, 0};
+
+pdf_obj *
+sfnt_create_FontFile_stream (sfnt *sfont)
+{
+ pdf_obj *stream;
+ pdf_obj *stream_dict;
+ struct sfnt_table_directory *td;
+ int offset, nb_read, length;
+ int i, sr;
+ char *p;
+
+ ASSERT(sfont && sfont->directory);
+
+ stream = pdf_new_stream(STREAM_COMPRESS);
+
+ td = sfont->directory;
+
+ /* Header */
+ p = (char *) wbuf;
+ p += sfnt_put_ulong (p, td->version);
+ p += sfnt_put_ushort(p, td->num_kept_tables);
+ sr = max2floor(td->num_kept_tables) * 16;
+ p += sfnt_put_ushort(p, sr);
+ p += sfnt_put_ushort(p, log2floor(td->num_kept_tables));
+ p += sfnt_put_ushort(p, td->num_kept_tables * 16 - sr);
+
+ pdf_add_stream(stream, wbuf, 12);
+
+ /*
+ * Compute start of actual tables (after headers).
+ */
+ offset = 12 + 16 * td->num_kept_tables;
+ for (i = 0; i < td->num_tables; i++) {
+ /* This table must exist in FontFile */
+ if (td->flags[i] & SFNT_TABLE_REQUIRED) {
+ if ((offset % 4) != 0) {
+ offset += 4 - (offset % 4);
+ }
+
+ p = (char *) wbuf;
+ memcpy(p, td->tables[i].tag, 4);
+ p += 4;
+ p += sfnt_put_ulong(p, td->tables[i].check_sum);
+ p += sfnt_put_ulong(p, offset);
+ p += sfnt_put_ulong(p, td->tables[i].length);
+ pdf_add_stream(stream, wbuf, 16);
+
+ offset += td->tables[i].length;
+ }
+ }
+
+ offset = 12 + 16 * td->num_kept_tables;
+ for (i = 0; i < td->num_tables; i++) {
+ if (td->flags[i] & SFNT_TABLE_REQUIRED) {
+ if ((offset % 4) != 0) {
+ length = 4 - (offset % 4);
+ pdf_add_stream(stream, padbytes, length);
+ offset += length;
+ }
+ if (!td->tables[i].data) {
+ if (!sfont->stream)
+ {
+ pdf_release_obj(stream);
+ ERROR("Font file not opened or already closed...");
+ return NULL;
+ }
+
+ length = td->tables[i].length;
+ sfnt_seek_set(sfont, td->tables[i].offset);
+ while (length > 0) {
+ nb_read = sfnt_read(wbuf, MIN(length, 1024), sfont);
+ if (nb_read < 0) {
+ pdf_release_obj(stream);
+ ERROR("Reading file failed...");
+ return NULL;
+ } else if (nb_read > 0) {
+ pdf_add_stream(stream, wbuf, nb_read);
+ }
+ length -= nb_read;
+ }
+ } else {
+ pdf_add_stream(stream,
+ td->tables[i].data, td->tables[i].length);
+ RELEASE(td->tables[i].data);
+ td->tables[i].data = NULL;
+ }
+ /* Set offset for next table */
+ offset += td->tables[i].length;
+ }
+ }
+
+ stream_dict = pdf_stream_dict(stream);
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Length1"),
+ pdf_new_number(offset));
+
+ return stream;
+}
diff --git a/Build/source/texk/dvipdfm-x/sfnt.h b/Build/source/texk/dvipdfm-x/sfnt.h
new file mode 100644
index 00000000000..262ef0e14b3
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/sfnt.h
@@ -0,0 +1,121 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SFNT_H_
+#define _SFNT_H_
+
+#include "mfileio.h"
+#include "numbers.h"
+#include "pdfobj.h"
+
+/* Acoid conflict with CHAR ... from <winnt.h>. */
+#define CHAR SFNT_CHAR
+#define ULONG SFNT_ULONG
+#define LONG SFNT_LONG
+
+/* Data Types as described in Apple's TTRefMan */
+typedef unsigned char BYTE;
+typedef signed char CHAR;
+typedef unsigned short USHORT;
+typedef signed short SHORT;
+typedef uint32_t ULONG;
+typedef int32_t LONG;
+typedef uint32_t Fixed; /* 16.16-bit signed fixed-point number */
+typedef short FWord;
+typedef unsigned short uFWord;
+
+struct sfnt_table
+{
+ /* table header */
+ char tag[4];
+ ULONG check_sum;
+ ULONG offset;
+ ULONG length;
+ char *data; /* table data */
+};
+
+#define SFNT_TABLE_REQUIRED (1 << 0)
+
+struct sfnt_table_directory
+{
+ ULONG version; /* Fixed for Win */
+ USHORT num_tables;
+ USHORT search_range;
+ USHORT entry_selector;
+ USHORT range_shift;
+ USHORT num_kept_tables; /* number of kept tables */
+ char *flags; /* keep or omit */
+ struct sfnt_table *tables;
+};
+
+/* sfnt resource */
+#define SFNT_TYPE_TRUETYPE (1 << 0)
+#define SFNT_TYPE_OPENTYPE (1 << 1)
+#define SFNT_TYPE_POSTSCRIPT (1 << 2)
+#define SFNT_TYPE_TTC (1 << 4)
+#define SFNT_TYPE_DFONT (1 << 8)
+
+typedef struct
+{
+ int type;
+ struct sfnt_table_directory *directory;
+ FILE *stream;
+ ULONG offset;
+} sfnt;
+
+/* Convert sfnt "fixed" type to double */
+#define fixed(a) ((double)((a)%0x10000L)/(double)(0x10000L) + \
+ (a)/0x10000L - (((a)/0x10000L > 0x7fffL) ? 0x10000L : 0))
+
+/* get_***_*** from numbers.h */
+#define sfnt_get_byte(s) ((BYTE) get_unsigned_byte((s)->stream))
+#define sfnt_get_char(s) ((CHAR) get_signed_byte ((s)->stream))
+#define sfnt_get_ushort(s) ((USHORT) get_unsigned_pair((s)->stream))
+#define sfnt_get_short(s) ((SHORT) get_signed_pair ((s)->stream))
+#define sfnt_get_ulong(s) ((ULONG) get_unsigned_quad((s)->stream))
+#define sfnt_get_long(s) ((LONG) get_signed_quad ((s)->stream))
+
+#define sfnt_seek_set(s,o) seek_absolute((s)->stream, (o))
+#define sfnt_read(b,l,s) fread((b), 1, (l), (s)->stream)
+
+extern int put_big_endian (void *s, LONG q, int n);
+
+#define sfnt_put_ushort(s,v) put_big_endian((s), v, 2);
+#define sfnt_put_short(s,v) put_big_endian((s), v, 2);
+#define sfnt_put_ulong(s,v) put_big_endian((s), v, 4);
+#define sfnt_put_long(s,v) put_big_endian((s), v, 4);
+
+extern sfnt *sfnt_open (FILE *fp);
+extern sfnt *dfont_open (FILE *fp, int index);
+extern void sfnt_close (sfnt *sfont);
+
+/* table directory */
+extern int sfnt_read_table_directory (sfnt *sfont, ULONG offset);
+extern ULONG sfnt_find_table_len (sfnt *sfont, const char *tag);
+extern ULONG sfnt_find_table_pos (sfnt *sfont, const char *tag);
+extern ULONG sfnt_locate_table (sfnt *sfont, const char *tag);
+
+extern void sfnt_set_table (sfnt *sfont,
+ const char *tag, void *data, ULONG length);
+extern int sfnt_require_table (sfnt *sfont, const char *tag, int must_exist);
+
+extern pdf_obj *sfnt_create_FontFile_stream (sfnt *sfont);
+
+#endif /* _SFNT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_color.c b/Build/source/texk/dvipdfm-x/spc_color.c
new file mode 100644
index 00000000000..5584fe7ba60
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_color.c
@@ -0,0 +1,189 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxutil.h"
+
+#include "pdfdev.h"
+#include "pdfcolor.h"
+
+#include "specials.h"
+
+#include "spc_util.h"
+#include "spc_color.h"
+
+
+/* Color stack is actually placed into pdfcolor.c.
+ * The reason why we need to place stack there is
+ * that we must reinstall color after grestore and
+ * other operations that can change current color
+ * implicitely.
+ */
+
+static int
+spc_handler_color_push (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ pdf_color colorspec;
+
+ error = spc_util_read_colorspec(spe, &colorspec, args, 1);
+ if (!error) {
+ pdf_color_push(&colorspec, &colorspec);
+ }
+
+ return error;
+}
+
+static int
+spc_handler_color_pop (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_color_pop();
+
+ return 0;
+}
+
+/* Invoked by the special command "color rgb .625 0 0".
+ * DVIPS clears the color stack, and then saves and sets the given color.
+ */
+static int
+spc_handler_color_default (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ pdf_color colorspec;
+
+ error = spc_util_read_colorspec(spe, &colorspec, args, 1);
+ if (!error) {
+ pdf_color_clear_stack();
+ pdf_color_set(&colorspec, &colorspec);
+ }
+
+ return error;
+}
+
+
+/* This is from color special? */
+#include "pdfdoc.h"
+
+static int
+spc_handler_background (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ pdf_color colorspec;
+
+ error = spc_util_read_colorspec(spe, &colorspec, args, 1);
+ if (!error)
+ pdf_doc_set_bgcolor(&colorspec);
+
+ return error;
+}
+
+
+#ifndef ISBLANK
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t' || (c) == '\v')
+#endif
+static void
+skip_blank (const char **pp, const char *endptr)
+{
+ const char *p = *pp;
+ for ( ; p < endptr && ISBLANK(*p); p++);
+ *pp = p;
+}
+
+int
+spc_color_check_special (const char *buf, int len)
+{
+ int r = 0;
+ const char *p, *endptr;
+ char *q;
+
+ p = buf;
+ endptr = p + len;
+
+ skip_blank(&p, endptr);
+ q = parse_c_ident(&p, endptr);
+ if (!q)
+ return 0;
+ else if (!strcmp(q, "color"))
+ r = 1;
+ else if (!strcmp(q, "background")) {
+ r = 1;
+ }
+ RELEASE(q);
+
+ return r;
+}
+
+int
+spc_color_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap)
+{
+ const char *p;
+ char *q;
+
+ ASSERT(sph && spe && ap);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (!q)
+ return -1;
+ skip_blank(&ap->curptr, ap->endptr);
+
+ if (!strcmp(q, "background")) {
+ ap->command = "background";
+ sph->exec = &spc_handler_background;
+ RELEASE(q);
+ } else if (!strcmp(q, "color")) { /* color */
+ RELEASE(q);
+ p = ap->curptr;
+
+ q = parse_c_ident(&p, ap->endptr);
+ if (!q)
+ return -1;
+ else if (!strcmp(q, "push")) {
+ ap->command = "push";
+ sph->exec = &spc_handler_color_push;
+ ap->curptr = p;
+ } else if (!strcmp(q, "pop")) {
+ ap->command = "pop";
+ sph->exec = &spc_handler_color_pop;
+ ap->curptr = p;
+ } else { /* cmyk, rgb, ... */
+ ap->command = "";
+ sph->exec = &spc_handler_color_default;
+ }
+ RELEASE(q);
+ } else {
+ spc_warn(spe, "Not color/background special?");
+ RELEASE(q);
+ return -1;
+ }
+
+ skip_blank(&ap->curptr, ap->endptr);
+ return 0;
+}
+
diff --git a/Build/source/texk/dvipdfm-x/spc_color.h b/Build/source/texk/dvipdfm-x/spc_color.h
new file mode 100644
index 00000000000..eb9555cdc58
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_color.h
@@ -0,0 +1,30 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_COLOR_H_
+#define _SPC_COLOR_H_
+
+extern int spc_color_check_special (const char *buffer, int size);
+extern int spc_color_setup_handler (struct spc_handler *handle,
+ struct spc_env *spe, struct spc_arg *args);
+
+#endif /* _SPC_COLOR_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_dvipdfmx.c b/Build/source/texk/dvipdfm-x/spc_dvipdfmx.c
new file mode 100644
index 00000000000..6b3fa703959
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_dvipdfmx.c
@@ -0,0 +1,139 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxutil.h"
+#include "pdfparse.h"
+
+#include "specials.h"
+
+#include "spc_util.h"
+#include "spc_dvipdfmx.h"
+
+static int
+spc_handler_null (struct spc_env *spe, struct spc_arg *args)
+{
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_dvipdfmx_catch_phantom (struct spc_env *spe, struct spc_arg *args)
+{
+ int mode, error;
+
+ skip_white(&args->curptr, args->endptr);
+ {
+ pdf_obj *b = parse_pdf_boolean(&args->curptr, args->endptr);
+ if (!b) {
+ WARN("A boolean value expected but not found...");
+ return -1;
+ }
+ mode = pdf_boolean_value(b);
+ pdf_release_obj(b);
+ }
+ spc_set_linkmode(spe, mode);
+
+ skip_white(&args->curptr, args->endptr);
+ if (mode == 1 && args->curptr < args->endptr) {
+ transform_info ti;
+
+ transform_info_clear(&ti);
+ error = spc_util_read_dimtrns(spe, &ti, args, 0);
+ if (error)
+ return -1;
+ if (ti.flags & INFO_HAS_HEIGHT) {
+ spc_set_phantom(spe, ti.height, ti.depth);
+ }
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ return 0;
+}
+
+static struct spc_handler dvipdfmx_handlers[] = {
+ {"config", spc_handler_null}, /* handled at bop */
+ {"catch_phantom", spc_handler_dvipdfmx_catch_phantom},
+};
+
+int
+spc_dvipdfmx_check_special (const char *buf, int len)
+{
+ int r = 0;
+ const char *p, *endptr;
+
+ p = buf;
+ endptr = p + len;
+
+ skip_white(&p, endptr);
+ if (p + strlen("dvipdfmx:") <= endptr &&
+ !memcmp(p, "dvipdfmx:", strlen("dvipdfmx:"))) {
+ r = 1;
+ }
+
+ return r;
+}
+
+int
+spc_dvipdfmx_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap)
+{
+ int error = -1, i;
+ char *q;
+
+ ASSERT(sph && spe && ap);
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr + strlen("dvipdfmx:") >= ap->endptr ||
+ memcmp(ap->curptr, "dvipdfmx:", strlen("dvipdfmx:"))) {
+ spc_warn(spe, "Not dvipdfmx: special???");
+ return -1;
+ }
+ ap->curptr += strlen("dvipdfmx:");
+
+ skip_white(&ap->curptr, ap->endptr);
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (q) {
+ for (i = 0;
+ i < sizeof(dvipdfmx_handlers) / sizeof(struct spc_handler); i++) {
+ if (!strcmp(q, dvipdfmx_handlers[i].key)) {
+ ap->command = dvipdfmx_handlers[i].key;
+ sph->key = "dvipdfmx:";
+ sph->exec = dvipdfmx_handlers[i].exec;
+ skip_white(&ap->curptr, ap->endptr);
+ error = 0;
+ break;
+ }
+ }
+ RELEASE(q);
+ }
+
+ return error;
+}
diff --git a/Build/source/texk/dvipdfm-x/spc_dvipdfmx.h b/Build/source/texk/dvipdfm-x/spc_dvipdfmx.h
new file mode 100644
index 00000000000..242cc82a211
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_dvipdfmx.h
@@ -0,0 +1,30 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_DVIPDFMX_H_
+#define _SPC_DVIPDFMX_H_
+
+#include "specials.h"
+
+extern int spc_dvipdfmx_check_special (const char *buf, int len);
+extern int spc_dvipdfmx_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap);
+
+#endif /* _SPC_DVIPDFMX_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_dvips.c b/Build/source/texk/dvipdfm-x/spc_dvips.c
new file mode 100644
index 00000000000..8090d2664d4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_dvips.c
@@ -0,0 +1,1082 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "dpxfile.h"
+
+#include "dvi.h"
+#include "dvicodes.h"
+
+#include "pdfparse.h"
+
+#include "pdfdoc.h"
+
+#include "mpost.h"
+
+#include "pdfximage.h"
+#include "pdfdraw.h"
+#include "pdfcolor.h"
+#include "pdfdev.h"
+
+#include "specials.h"
+#include "spc_util.h"
+#include "spc_dvips.h"
+
+#include "mfileio.h"
+#include "spc_xtx.h"
+#include "epdf.h"
+
+static int block_pending = 0;
+static double pending_x = 0.0;
+static double pending_y = 0.0;
+static int position_set = 0;
+
+static char** ps_headers = 0;
+static int num_ps_headers = 0;
+
+static int
+spc_handler_ps_header (struct spc_env *spe, struct spc_arg *args)
+{
+ char *ps_header, *pro;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr + 1 >= args->endptr ||
+ args->curptr[0] != '=') {
+ spc_warn(spe, "No filename specified for PSfile special.");
+ return -1;
+ }
+ args->curptr++;
+
+ pro = malloc(args->endptr - args->curptr + 1);
+ strncpy(pro, args->curptr, args->endptr - args->curptr);
+ pro[args->endptr - args->curptr] = 0;
+ ps_header = kpse_find_file(pro, kpse_tex_ps_header_format, 0);
+ if (!ps_header) {
+ spc_warn(spe, "PS header %s not found.", pro);
+ return -1;
+ }
+ free(pro);
+
+ if (!(num_ps_headers & 0x0f))
+ ps_headers = realloc(ps_headers, sizeof(char*) * (num_ps_headers + 16));
+ ps_headers[num_ps_headers++] = ps_header;
+ args->curptr = args->endptr;
+ return 0;
+}
+
+static char *
+parse_filename (const char **pp, const char *endptr)
+{
+ char *r;
+ const char *q = NULL, *p = *pp;
+ char qchar;
+ int n;
+
+ if (!p || p >= endptr)
+ return NULL;
+ else if (*p == '\"' || *p == '\'')
+ qchar = *p++;
+ else {
+ qchar = ' ';
+ }
+ for (n = 0, q = p; p < endptr && *p != qchar; n++, p++);
+ if (qchar != ' ') {
+ if (*p != qchar)
+ return NULL;
+ p++;
+ }
+ if (!q || n == 0)
+ return NULL;
+
+#if 0
+ {
+ int i;
+ for (i = 0; i < n && isprint(q[i]); i++);
+ if (i != n) {
+ WARN("Non printable char in filename string...");
+ }
+ }
+#endif
+
+ r = NEW(n + 1, char);
+ memcpy(r, q, n); r[n] = '\0';
+
+ *pp = p;
+ return r;
+}
+
+/* =filename ... */
+static int
+spc_handler_ps_file (struct spc_env *spe, struct spc_arg *args)
+{
+ int form_id;
+ char *filename;
+ transform_info ti;
+ load_options options = {1, 0, NULL};
+
+ ASSERT(spe && args);
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr + 1 >= args->endptr ||
+ args->curptr[0] != '=') {
+ spc_warn(spe, "No filename specified for PSfile special.");
+ return -1;
+ }
+ args->curptr++;
+
+ filename = parse_filename(&args->curptr, args->endptr);
+ if (!filename) {
+ spc_warn(spe, "No filename specified for PSfile special.");
+ return -1;
+ }
+
+ transform_info_clear(&ti);
+ if (spc_util_read_dimtrns(spe, &ti, args, 1) < 0) {
+ RELEASE(filename);
+ return -1;
+ }
+
+ form_id = pdf_ximage_load_image(NULL, filename, options);
+ if (form_id < 0) {
+ spc_warn(spe, "Failed to read image file: %s", filename);
+ RELEASE(filename);
+ return -1;
+ }
+ RELEASE(filename);
+
+ spc_put_image(spe, form_id, &ti, spe->x_user, spe->y_user);
+
+ return 0;
+}
+
+/* This isn't correct implementation but dvipdfm supports... */
+static int
+spc_handler_ps_plotfile (struct spc_env *spe, struct spc_arg *args)
+{
+ int error = 0;
+ int form_id;
+ char *filename;
+ transform_info p;
+ load_options options = {1, 0, NULL};
+
+ ASSERT(spe && args);
+
+ spc_warn(spe, "\"ps: plotfile\" found (not properly implemented)");
+
+ skip_white(&args->curptr, args->endptr);
+ filename = parse_filename(&args->curptr, args->endptr);
+ if (!filename) {
+ spc_warn(spe, "Expecting filename but not found...");
+ return -1;
+ }
+
+ form_id = pdf_ximage_load_image(NULL, filename, options);
+ if (form_id < 0) {
+ spc_warn(spe, "Could not open PS file: %s", filename);
+ error = -1;
+ } else {
+ transform_info_clear(&p);
+ p.matrix.d = -1.0; /* xscale = 1.0, yscale = -1.0 */
+#if 0
+ /* I don't know how to treat this... */
+ pdf_dev_put_image(form_id, &p,
+ block_pending ? pending_x : spe->x_user,
+ block_pending ? pending_y : spe->y_user);
+#endif
+ spc_put_image(spe, form_id, &p, 0, 0);
+ }
+ RELEASE(filename);
+
+ return error;
+}
+
+static int
+spc_handler_ps_literal (struct spc_env *spe, struct spc_arg *args)
+{
+ int error = 0;
+ int st_depth, gs_depth;
+ double x_user, y_user;
+ pdf_coord cp;
+
+ spc_get_current_point(spe, &cp);
+ if (args->curptr + strlen(":[begin]") <= args->endptr &&
+ !strncmp(args->curptr, ":[begin]", strlen(":[begin]"))) {
+ block_pending++;
+ position_set = 1;
+
+ x_user = pending_x = cp.x;
+ y_user = pending_y = cp.y;
+ args->curptr += strlen(":[begin]");
+ } else if (args->curptr + strlen(":[end]") <= args->endptr &&
+ !strncmp(args->curptr, ":[end]", strlen(":[end]"))) {
+ if (block_pending <= 0) {
+ spc_warn(spe, "No corresponding ::[begin] found.");
+ return -1;
+ }
+ block_pending--;
+
+ position_set = 0;
+
+ x_user = pending_x;
+ y_user = pending_y;
+ args->curptr += strlen(":[end]");
+ } else if (args->curptr < args->endptr && args->curptr[0] == ':') {
+ x_user = position_set ? pending_x : cp.x;
+ y_user = position_set ? pending_y : cp.y;
+ args->curptr++;
+ } else {
+ position_set = 1;
+ x_user = pending_x = cp.x;
+ y_user = pending_y = cp.y;
+ }
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+
+ st_depth = mps_stack_depth();
+ gs_depth = pdf_dev_current_depth();
+
+ error = mps_exec_inline(&args->curptr, args->endptr, x_user, y_user);
+ if (error) {
+ spc_warn(spe, "Interpreting PS code failed!!! Output might be broken!!!");
+ pdf_dev_grestore_to(gs_depth);
+ } else if (st_depth != mps_stack_depth()) {
+ spc_warn(spe, "Stack not empty after execution of inline PostScript code.");
+ spc_warn(spe, ">> Your macro package makes some assumption on internal behaviour of DVI drivers.");
+ spc_warn(spe, ">> It may not compatible with dvipdfmx.");
+ }
+ }
+
+ return error;
+}
+
+static char *global_defs = 0;
+static char *page_defs = 0;
+static char *temporary_defs = 0;
+static char *distiller_template = 0;
+static pdf_coord *put_stack;
+static int put_stack_depth = -1;
+static char *gs_in = 0;
+
+#if 0
+/* Not used */
+static int
+spc_handler_ps_tricks_gdef (struct spc_env *spe, struct spc_arg *args)
+{
+ FILE* fp;
+
+ fp = fopen(global_defs, "ab");
+ fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
+ fprintf(fp, "\n");
+ fclose(fp);
+
+ return 0;
+}
+#endif
+
+static int
+spc_handler_ps_tricks_pdef (struct spc_env *spe, struct spc_arg *args)
+{
+ FILE* fp;
+ pdf_tmatrix M, T = { 1, 0, 0, 1, 0, 0 };
+ pdf_coord pt;
+
+ pdf_dev_currentmatrix(&M);
+ spc_get_fixed_point(spe, &pt.x, &pt.y);
+ T.e = pt.x;
+ T.f = pt.y;
+ pdf_concatmatrix(&M, &T);
+
+ if (!page_defs)
+ page_defs = dpx_create_temp_file();
+ if (!page_defs) {
+ WARN("Failed to create temporary input file for PSTricks image conversion.");
+ return -1;
+ }
+
+ fp = fopen(page_defs, "ab");
+ fprintf(fp, "gsave initmatrix [%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user - pt.x, spe->y_user - pt.y);
+ fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
+ fprintf(fp, "\ngrestore\n");
+ fclose(fp);
+
+ return 0;
+}
+
+static int
+spc_handler_ps_tricks_tdef (struct spc_env *spe, struct spc_arg *args)
+{
+ FILE* fp;
+ if (!temporary_defs)
+ temporary_defs = dpx_create_temp_file();
+ if (!temporary_defs) {
+ WARN("Failed to create temporary input file for PSTricks image conversion.");
+ return -1;
+ }
+
+ fp = fopen(temporary_defs, "wb");
+ fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
+ fprintf(fp, "\n");
+ fclose(fp);
+
+ return 0;
+}
+
+static int calculate_PS (char *strptr, int length, double *res1, double *res2, double *res3, double *res4, double *res5, double *res6);
+
+static int
+spc_handler_ps_tricks_bput (struct spc_env *spe, struct spc_arg *args, int must_def, int pre_def)
+{
+ char *PutBegin, *formula, *ncLabel;
+ int label = 0;
+ pdf_coord tr;
+ pdf_tmatrix M, T = { 1, 0, 0, 1, 0, 0 };
+
+ if (must_def != 0) {
+ ncLabel = strstr(args->curptr, "LPut");
+ if (ncLabel != 0 && ncLabel < args->endptr - 3)
+ label = 1;
+ ncLabel = strstr(args->curptr, "HPutPos");
+ if (ncLabel != 0 && ncLabel < args->endptr - 6)
+ label = 1;
+ }
+
+ if (pre_def == 0) {
+ dpx_delete_temp_file(temporary_defs, true);
+ temporary_defs = 0;
+ }
+
+ pdf_dev_currentmatrix(&M);
+ formula = malloc(args->endptr - args->curptr + 120);
+ if (label != 0) {
+ sprintf(formula, "[%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user + get_origin(1), spe->y_user + get_origin(0));
+ } else
+ sprintf(formula, "[%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
+ strncat(formula, args->curptr, args->endptr - args->curptr);
+ PutBegin = strstr(formula, "PutBegin");
+ strcpy(PutBegin, "exch = =");
+ *(PutBegin + 8) = 0;
+ if (calculate_PS(formula, strlen(formula), &tr.x, &tr.y, 0, 0, 0, 0) == 0) {
+ if (!(++put_stack_depth & 0x0f))
+ put_stack = realloc(put_stack, (put_stack_depth + 16) * sizeof(pdf_coord));
+ put_stack[put_stack_depth] = tr;
+ }
+ T.e = tr.x; T.f = tr.y;
+
+ pdf_dev_concat(&T);
+
+ if (must_def != 0) {
+ FILE* fp;
+ if (!temporary_defs)
+ temporary_defs = dpx_create_temp_file();
+ if (!temporary_defs) {
+ WARN("Failed to create temporary input file for PSTricks image conversion.");
+ return -1;
+ }
+
+ fp = fopen(temporary_defs, "ab");
+ fprintf(fp, "gsave\n");
+ if (label == 0)
+ fprintf(fp, "[%f %f %f %f %f %f] concat %f %f moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
+ fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
+ fprintf(fp, "\ngrestore\n");
+ fclose(fp);
+ }
+
+ free(formula);
+ return 0;
+}
+
+static int
+spc_handler_ps_tricks_eput (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_coord tr = put_stack[put_stack_depth--];
+ pdf_tmatrix M = { 1, 0, 0, 1, -tr.x, -tr.y };
+
+ pdf_dev_concat(&M);
+
+ return 0;
+}
+
+/* Rotation without gsave/grestore. */
+static double* RAngles = 0;
+static int RAngleCount = -1;
+
+static int
+spc_handler_ps_tricks_brotate (struct spc_env *spe, struct spc_arg *args)
+{
+ double value, RAngle = 0;
+ char *cmd, *RotBegin;
+ int i, l = args->endptr - args->curptr;
+
+ static const char pre[] = "tx@Dict begin /RAngle { %f } def\n";
+ static const char *post = "= end";
+
+ if (!(++RAngleCount & 0x0f))
+ RAngles = realloc(RAngles, (RAngleCount + 16) * sizeof(double));
+ for (i = 0; i < RAngleCount; i++)
+ RAngle += RAngles[i];
+ cmd = calloc(l + strlen(pre) + strlen(post) + 12, 1);
+ sprintf(cmd, pre, RAngle);
+ strncat(cmd, args->curptr, l);
+ RotBegin = strstr(cmd, "RotBegin");
+ strcpy(RotBegin, post);
+ if (calculate_PS(cmd, strlen(cmd), &value, 0, 0, 0, 0, 0) != 0)
+ return -1;
+ RAngles[RAngleCount] = value;
+
+ return spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user,
+ cos(value * M_PI / 180), sin(value * M_PI / 180),
+ -sin(value * M_PI / 180), cos(value * M_PI / 180),
+ 0, 0);
+}
+
+static int
+spc_handler_ps_tricks_erotate (struct spc_env *spe, struct spc_arg *args)
+{
+ double value = RAngles[RAngleCount--];
+
+ return spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user,
+ cos(value * M_PI / 180), -sin(value * M_PI / 180),
+ sin(value * M_PI / 180), cos(value * M_PI / 180),
+ 0, 0);
+}
+
+static int
+spc_handler_ps_tricks_transform (struct spc_env *spe, struct spc_arg *args)
+{
+ double d1, d2, d3, d4, d5, d6;
+ char *cmd, *concat;
+ int l = args->endptr - args->curptr;
+
+ static const char *post = "concat matrix currentmatrix ==";
+
+ cmd = calloc(l + 41, 1);
+ strncpy(cmd, "matrix setmatrix ", 18);
+ strncpy(cmd + 17, args->curptr, l);
+ concat = strstr(cmd, "concat");
+ if (concat != 0) {
+ strcpy(concat, post);
+ concat[strlen(post)] = 0;
+ concat = strstr(cmd, "{");
+ *concat = ' ';
+ if (calculate_PS(cmd, strlen(cmd), &d1, &d2, &d3, &d4, &d5, &d6) != 0)
+ return -1;
+ if (spc_handler_xtx_gsave (0, 0) != 0)
+ return -1;
+ return spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user, d1, d2, d3, d4, d5, d6);
+ }
+ return spc_handler_xtx_grestore (0, 0);
+}
+
+static int
+check_next_obj(const unsigned char * buffer)
+{
+ switch (buffer[0]) {
+ case XXX1:
+ if (buffer[1] < 5)
+ return 0;
+ buffer += 2;
+ break;
+ case XXX2:
+ buffer += 3;
+ break;
+ case XXX3:
+ buffer += 4;
+ break;
+ case XXX4:
+ buffer += 5;
+ break;
+ default:
+ return 0;
+ }
+
+ if (strncmp((const char*)buffer, "pst:", 4))
+ return 0;
+ return 1;
+}
+
+static int
+spc_handler_ps_tricks_parse_path (struct spc_env *spe, struct spc_arg *args)
+{
+ FILE* fp;
+ int k;
+ pdf_tmatrix M;
+ char *gs_out;
+ const char *clip;
+ int error;
+
+ if (!distiller_template)
+ distiller_template = get_distiller_template();
+
+ pdf_dev_currentmatrix(&M);
+ if (!gs_in) {
+ gs_in = dpx_create_temp_file();
+ if (!gs_in) {
+ WARN("Failed to create temporary input file for PSTricks image conversion.");
+ return -1;
+ }
+ fp = fopen(gs_in, "wb");
+ for (k = 0; k < num_ps_headers; k++)
+ fprintf(fp, "(%s) run\n", ps_headers[k]);
+ fprintf(fp, "[%f %f %f %f %f %f] concat %f %f translate 0 0 moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
+ fprintf(fp, "(%s) run\n", global_defs);
+ if (page_defs != 0)
+ fprintf(fp, "(%s) run\n", page_defs);
+
+#if 0
+ fprintf(fp, "/clip {stroke} def\n");
+ fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
+#else
+ clip = strstr(args->curptr, " clip");
+ if (clip == 0 || clip > args->endptr - 5) {
+ fprintf(fp, "tx@TextPathDict begin /stroke {} def\n");
+ fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
+ fprintf(fp, "\nend\n");
+ fclose(fp);
+ return 0;
+ } else {
+ fwrite(args->curptr, 1, clip - args->curptr, fp);
+ fprintf(fp, " stroke ");
+ skip_white(&clip, args->endptr);
+ parse_ident(&clip, args->endptr);
+ fwrite(clip, 1, args->endptr - clip, fp);
+ }
+#endif
+ } else {
+ fp = fopen(gs_in, "ab");
+ fprintf(fp, "flattenpath stroke\n");
+ }
+ fclose(fp);
+
+ gs_out = dpx_create_temp_file();
+ if (!gs_out) {
+ WARN("Failed to create temporary output file for PSTricks image conversion.");
+ RELEASE(gs_in);
+ gs_in = 0;
+ return -1;
+ }
+#ifdef MIKTEX
+ {
+ char *p;
+ for (p = (char *)gs_in; *p; p++) {
+ if (*p == '\\') *p = '/';
+ }
+ for (p = (char *)gs_out; *p; p++) {
+ if (*p == '\\') *p = '/';
+ }
+ }
+#endif
+/*
+ Ghostscript 9.15 needs showpage
+*/
+ fp = fopen(gs_in, "ab");
+ fprintf(fp, " showpage\n");
+ fclose(fp);
+
+ error = dpx_file_apply_filter(distiller_template, gs_in, gs_out,
+ pdf_get_version());
+ if (error) {
+ WARN("Image format conversion for PSTricks failed.");
+ RELEASE(gs_in);
+ gs_in = 0;
+ return error;
+ }
+
+ fp = fopen(gs_out, "rb");
+ if (pdf_copy_clip(fp, 1, 0, 0) != 0) {
+ spc_warn(spe, "Failed to parse the clipping path.");
+ RELEASE(gs_in);
+ gs_in = 0;
+ RELEASE(gs_out);
+ return -1;
+ }
+ fclose(fp);
+
+ dpx_delete_temp_file(gs_out, true);
+ dpx_delete_temp_file(gs_in, true);
+ gs_in = 0;
+
+ return 0;
+}
+
+static int
+spc_handler_ps_tricks_render (struct spc_env *spe, struct spc_arg *args)
+{
+ FILE *fp;
+ int k;
+ pdf_tmatrix M;
+ load_options options = {1, 0, NULL};
+
+ if (!distiller_template)
+ distiller_template = get_distiller_template();
+
+ pdf_dev_currentmatrix(&M);
+ if (!gs_in) {
+ gs_in = dpx_create_temp_file();
+ if (!gs_in) {
+ WARN("Failed to create temporary input file for PSTricks image conversion.");
+ return -1;
+ }
+ fp = fopen(gs_in, "wb");
+ for (k = 0; k < num_ps_headers; k++)
+ fprintf(fp, "(%s) run\n", ps_headers[k]);
+ fprintf(fp, "[%f %f %f %f %f %f] concat %f %f translate 0 0 moveto\n", M.a, M.b, M.c, M.d, M.e, M.f, spe->x_user, spe->y_user);
+ fprintf(fp, "(%s) run\n", global_defs);
+ if (page_defs != 0)
+ fprintf(fp, "(%s) run\n", page_defs);
+ } else
+ fp = fopen(gs_in, "ab");
+
+ fprintf(fp, "\nsave\n");
+ fwrite(args->curptr, 1, args->endptr - args->curptr, fp);
+ fprintf(fp, "\ncount 1 sub {pop} repeat restore\n");
+
+ if (check_next_obj((const unsigned char*)args->endptr)) {
+ fclose(fp);
+ } else {
+ char *gs_out;
+ int error, form_id;
+ transform_info p;
+ transform_info_clear(&p);
+ pdf_invertmatrix(&M);
+ p.matrix = M;
+
+ fclose(fp);
+
+ gs_out = dpx_create_temp_file();
+ if (!gs_out) {
+ WARN("Failed to create temporary output file for PSTricks image conversion.");
+ RELEASE(gs_in);
+ gs_in = 0;
+ return -1;
+ }
+#ifdef MIKTEX
+ {
+ char *p;
+ for (p = (char *)gs_in; *p; p++) {
+ if (*p == '\\') *p = '/';
+ }
+ for (p = (char *)gs_out; *p; p++) {
+ if (*p == '\\') *p = '/';
+ }
+ }
+#endif
+/*
+ Ghostscript 9.15 needs showpage
+*/
+ fp = fopen(gs_in, "ab");
+ fprintf(fp, " showpage\n");
+ fclose(fp);
+
+ error = dpx_file_apply_filter(distiller_template, gs_in, gs_out,
+ pdf_get_version());
+ if (error) {
+ WARN("Image format conversion for PSTricks failed.");
+ RELEASE(gs_in);
+ gs_in = 0;
+ return error;
+ }
+
+ form_id = pdf_ximage_load_image(NULL, gs_out, options);
+ if (form_id < 0) {
+ spc_warn(spe, "Failed to read converted PSTricks image file.");
+ RELEASE(gs_in);
+ gs_in = 0;
+ RELEASE(gs_out);
+ return -1;
+ }
+ spc_put_image(spe, form_id, &p, 0, 0);
+
+ dpx_delete_temp_file(gs_out, true);
+ dpx_delete_temp_file(gs_in, true);
+ gs_in = 0;
+ }
+
+ return 0;
+}
+
+typedef enum {
+ render = 1 << 0,
+ global_def = 1 << 1,
+ page_def = 1 << 2,
+ new_temp = 1 << 3,
+ add_temp = 1 << 4,
+ begin_put = 1 << 5,
+ end_put = 1 << 6,
+ begin_rotate = 1 << 7,
+ end_rotate = 1 << 8,
+ parse = 1 << 9,
+ req_ref = 1 << 10,
+ transform = 1 << 11
+} Operation;
+
+/* ToDo: all the substring search must be centralized so that *
+ * keys can be read from external configuration. */
+struct pstricks_key_ {
+ const char * key;
+ Operation exec;
+} pstricks_key[] = {
+ /* The first 5 are hard-coded here. */
+ {"LPut", add_temp | req_ref},
+ {"HPutPos", add_temp | req_ref},
+ {"PutBegin", begin_put},
+ {"RotBegin", begin_rotate},
+ {"clip", parse},
+ /* The rest can be read from an external source. */
+ {"NewNode", page_def | req_ref},
+ {"InitNC", render | new_temp},
+ {"/Glbx", add_temp},
+ {"NewtonSolving", add_temp},
+ {"tx@LightThreeDDict", page_def},
+ {"PutEnd", end_put},
+ {"RotEnd", end_rotate},
+ {"mtrxc", parse},
+ {"stroke", render},
+ {"fill", render},
+ {"Fill", render},
+ {" Glbx", req_ref},
+ {"TextPathShow", parse},
+ {"/rotAngle", page_def},
+ {"NAngle", req_ref},
+ {"TMatrix", transform}
+};
+
+static int
+spc_handler_ps_trickscmd (struct spc_env *spe, struct spc_arg *args)
+{
+ char *test_string;
+ int k, error = 0, f_exec = 0;
+
+ /* Hack time! */
+ /* The problem is that while any macros in pstricks.tex
+ * can be overridden by the codes in pstricks.con, you cannot
+ * modify the pst@Verb specials generated by other PSTricks
+ * packages. So pstricks generate specials won't signal what
+ * to expect for you.
+ */
+ test_string = malloc(args->endptr - args->curptr + 1);
+ strncpy(test_string, args->curptr, args->endptr - args->curptr);
+ test_string[args->endptr - args->curptr] = 0;
+ for (k = 0; k < sizeof(pstricks_key) / sizeof(pstricks_key[0]); k++) {
+ if (strstr(test_string, pstricks_key[k].key) != 0)
+ f_exec |= pstricks_key[k].exec;
+ }
+ free(test_string);
+
+ if (f_exec & new_temp)
+ error |= spc_handler_ps_tricks_tdef(spe, args);
+ if (f_exec & render)
+ error |= spc_handler_ps_tricks_render(spe, args);
+ if (f_exec & parse)
+ error |= spc_handler_ps_tricks_parse_path(spe, args);
+ if (f_exec & begin_put)
+ error |= spc_handler_ps_tricks_bput(spe, args, (f_exec & add_temp), (f_exec & req_ref));
+ if (f_exec & end_put)
+ error |= spc_handler_ps_tricks_eput(spe, args);
+ if (f_exec & begin_rotate)
+ error |= spc_handler_ps_tricks_brotate(spe, args);
+ if (f_exec & end_rotate)
+ error |= spc_handler_ps_tricks_erotate(spe, args);
+ if (f_exec & transform)
+ error |= spc_handler_ps_tricks_transform(spe, args);
+ if (f_exec & page_def)
+ error |= spc_handler_ps_tricks_pdef (spe, args);
+ if (f_exec == 0)
+ error |= spc_handler_ps_tricks_pdef (spe, args);
+
+ args->curptr = args->endptr;
+ return error;
+}
+
+static int
+spc_handler_ps_tricksobj (struct spc_env *spe, struct spc_arg *args)
+{
+ int error = spc_handler_ps_tricks_render(spe, args);
+ args->curptr = args->endptr;
+ return error;
+}
+
+static int
+spc_handler_ps_default (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ int st_depth, gs_depth;
+
+ ASSERT(spe && args);
+
+ pdf_dev_gsave();
+
+ st_depth = mps_stack_depth();
+ gs_depth = pdf_dev_current_depth();
+
+ {
+ pdf_tmatrix M;
+ pdf_coord cp;
+
+ spc_get_current_point(spe, &cp);
+ M.a = M.d = 1.0; M.b = M.c = 0.0; M.e = cp.x; M.f = cp.y;
+ pdf_dev_concat(&M);
+ error = mps_exec_inline(&args->curptr, args->endptr, cp.x, cp.y);
+ M.e = -cp.x; M.f = -cp.y;
+ pdf_dev_concat(&M);
+ }
+ if (error)
+ spc_warn(spe, "Interpreting PS code failed!!! Output might be broken!!!");
+ else {
+ if (st_depth != mps_stack_depth()) {
+ spc_warn(spe, "Stack not empty after execution of inline PostScript code.");
+ spc_warn(spe, ">> Your macro package makes some assumption on internal behaviour of DVI drivers.");
+ spc_warn(spe, ">> It may not compatible with dvipdfmx.");
+ }
+ }
+
+ pdf_dev_grestore_to(gs_depth);
+ pdf_dev_grestore();
+
+ return error;
+}
+
+static struct spc_handler dvips_handlers[] = {
+ {"header", spc_handler_ps_header},
+ {"PSfile", spc_handler_ps_file},
+ {"psfile", spc_handler_ps_file},
+ {"ps: plotfile ", spc_handler_ps_plotfile},
+ {"PS: plotfile ", spc_handler_ps_plotfile},
+ {"PS:", spc_handler_ps_literal},
+ {"ps:", spc_handler_ps_literal},
+ {"PST:", spc_handler_ps_trickscmd},
+ {"pst:", spc_handler_ps_tricksobj},
+ {"\" ", spc_handler_ps_default}
+};
+
+int
+spc_dvips_at_begin_document (void)
+{
+ FILE* fp;
+
+ /* This, together with \pscharpath support code, must be moved to xtex.pro header. */
+ global_defs = dpx_create_temp_file();
+ if (!global_defs) {
+ WARN("Failed to create temporary input file for PSTricks image conversion.");
+ return -1;
+ }
+
+ fp = fopen(global_defs, "wb");
+ fprintf(fp, "tx@Dict begin /STV {} def end\n");
+ fclose(fp);
+
+ return 0;
+}
+
+int
+spc_dvips_at_end_document (void)
+{
+ if (ps_headers) {
+ while (num_ps_headers > 0)
+ RELEASE(ps_headers[--num_ps_headers]);
+ free(ps_headers);
+ ps_headers = NULL;
+ }
+ dpx_delete_temp_file(global_defs, true);
+ dpx_delete_temp_file(page_defs, true);
+
+ return 0;
+}
+
+int
+spc_dvips_at_begin_page (void)
+{
+ if (page_defs) {
+ dpx_delete_temp_file(page_defs, true);
+ page_defs = 0;
+ }
+
+ put_stack_depth = -1;
+
+ return 0;
+}
+
+int
+spc_dvips_at_end_page (void)
+{
+ mps_eop_cleanup();
+ if (temporary_defs) {
+ dpx_delete_temp_file(temporary_defs, true);
+ temporary_defs = 0;
+ }
+ return 0;
+}
+
+int
+spc_dvips_check_special (const char *buf, int len)
+{
+ const char *p, *endptr;
+ int i;
+
+ p = buf;
+ endptr = p + len;
+
+ skip_white(&p, endptr);
+ if (p >= endptr)
+ return 0;
+
+ len = (int) (endptr - p);
+ for (i = 0;
+ i < sizeof(dvips_handlers)/sizeof(struct spc_handler); i++) {
+ if (len >= strlen(dvips_handlers[i].key) &&
+ !memcmp(p, dvips_handlers[i].key,
+ strlen(dvips_handlers[i].key))) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int
+spc_dvips_setup_handler (struct spc_handler *handle,
+ struct spc_env *spe, struct spc_arg *args)
+{
+ const char *key;
+ int i, keylen;
+
+ ASSERT(handle && spe && args);
+
+ skip_white(&args->curptr, args->endptr);
+
+ key = args->curptr;
+ while (args->curptr < args->endptr &&
+ isalpha((unsigned char)args->curptr[0])) {
+ args->curptr++;
+ }
+ /* Test for "ps:". The "ps::" special is subsumed under this case. */
+ if (args->curptr < args->endptr &&
+ args->curptr[0] == ':') {
+ args->curptr++;
+ if (args->curptr+strlen(" plotfile ") <= args->endptr &&
+ !strncmp(args->curptr, " plotfile ", strlen(" plotfile "))) {
+ args->curptr += strlen(" plotfile ");
+ }
+ } else if (args->curptr+1 < args->endptr &&
+ args->curptr[0] == '"' && args->curptr[1] == ' ') {
+ args->curptr += 2;
+ }
+
+ keylen = (int) (args->curptr - key);
+ if (keylen < 1) {
+ spc_warn(spe, "Not ps: special???");
+ return -1;
+ }
+
+ for (i = 0;
+ i < sizeof(dvips_handlers) / sizeof(struct spc_handler); i++) {
+ if (keylen == strlen(dvips_handlers[i].key) &&
+ !strncmp(key, dvips_handlers[i].key, keylen)) {
+
+ skip_white(&args->curptr, args->endptr);
+
+ args->command = dvips_handlers[i].key;
+
+ handle->key = "ps:";
+ handle->exec = dvips_handlers[i].exec;
+
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+#ifdef __EMX__
+#define GS_CALCULATOR "gsos2 -q -dALLOWPSTRANSPARENCY -dDELAYSAFER -dNOPAUSE -dBATCH -sDEVICE=nullpage -f "
+#elif defined(WIN32)
+#define GS_CALCULATOR "rungs -q -dALLOWPSTRANSPARENCY -dDELAYSAFER -dNOPAUSE -dBATCH -sDEVICE=nullpage -f "
+#else
+#define GS_CALCULATOR "gs -q -dALLOWPSTRANSPARENCY -dDELAYSAFER -dNOPAUSE -dBATCH -sDEVICE=nullpage -f "
+#endif
+
+static
+int calculate_PS (char *strptr, int length, double *res1, double *res2, double *res3, double *res4, double *res5, double *res6) {
+ char *formula, *cmd;
+ FILE *fp, *coord;
+ int k;
+
+ if (res1 == 0 && res2 == 0)
+ return -1;
+ formula = dpx_create_temp_file();
+ if (!formula) {
+ WARN("Failed to create temporary input file for PSTricks image conversion.");
+ return -1;
+ }
+
+ fp = fopen(formula, "wb");
+ for (k = 0; k < num_ps_headers; k++)
+ fprintf(fp, "(%s) run\n", ps_headers[k]);
+ fprintf(fp, "0 0 moveto\n");
+ fprintf(fp, "(%s) run\n", global_defs);
+ if (page_defs != 0)
+ fprintf(fp, "(%s) run\n", page_defs);
+ if (temporary_defs)
+ fprintf(fp, "(%s) run\n", temporary_defs);
+ fwrite(strptr, 1, length, fp);
+ fclose(fp);
+#ifdef MIKTEX
+ {
+ char *p;
+ for (p = formula; *p; p++)
+ if (*p == '\\')
+ *p = '/';
+ }
+#endif
+ k = strlen(GS_CALCULATOR) + strlen(formula) + 1;
+ cmd = NEW(k, char);
+ strcpy(cmd, GS_CALCULATOR);
+ strcat(cmd, formula);
+
+ coord = popen(cmd, "r");
+ if (coord) {
+ if (res1 == 0)
+ fscanf(coord, " %lf ", res2);
+ else if (res2 == 0)
+ fscanf(coord, " %lf ", res1);
+ else if (res3 == 0)
+ fscanf(coord, " %lf %lf ", res1, res2);
+ else
+ fscanf(coord, " [%lf %lf %lf %lf %lf %lf] ", res1, res2, res3, res4, res5, res6);
+ } else
+ return -1;
+
+ pclose(coord);
+ RELEASE(cmd);
+ dpx_delete_temp_file(formula, true);
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/spc_dvips.h b/Build/source/texk/dvipdfm-x/spc_dvips.h
new file mode 100644
index 00000000000..6e518b2d1af
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_dvips.h
@@ -0,0 +1,37 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_DVIPS_H_
+#define _SPC_DVIPS_H_
+
+#include "specials.h"
+
+extern int spc_dvips_at_begin_document (void);
+extern int spc_dvips_at_end_document (void);
+extern int spc_dvips_at_begin_page (void);
+extern int spc_dvips_at_end_page (void);
+
+extern int spc_dvips_check_special (const char *buffer, int size);
+extern int spc_dvips_setup_handler (struct spc_handler *handle,
+ struct spc_env *spe, struct spc_arg *args);
+
+#endif /* _SPC_DVIPS_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_html.c b/Build/source/texk/dvipdfm-x/spc_html.c
new file mode 100644
index 00000000000..14640be11b5
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_html.c
@@ -0,0 +1,867 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxutil.h"
+
+#include "pdfdraw.h"
+#include "pdfdev.h"
+#include "pdfximage.h"
+
+#include "pdfdoc.h"
+
+#include "specials.h"
+#include "spc_util.h"
+
+#include "spc_html.h"
+
+
+#define ENABLE_HTML_IMG_SUPPORT 1
+#define ENABLE_HTML_SVG_TRANSFORM 1
+#define ENABLE_HTML_SVG_OPACITY 1
+
+/* _FIXME_
+ * Please rewrite this or remove html special support
+ */
+
+#define ANCHOR_TYPE_HREF 0
+#define ANCHOR_TYPE_NAME 1
+
+struct spc_html_
+{
+ struct {
+ int extensions;
+ } opts;
+
+ pdf_obj *link_dict;
+ char *baseurl;
+ int pending_type;
+};
+
+static struct spc_html_ _html_state = {
+ { 0 },
+ NULL, NULL, -1
+};
+
+
+#ifdef ENABLE_HTML_SVG_TRANSFORM
+static int cvt_a_to_tmatrix (pdf_tmatrix *M, const char *ptr, const char **nextptr);
+#endif /* ENABLE_HTML_SVG_TRANSFORM */
+
+#define \
+downcasify(s) \
+if ((s)) { \
+ char *_p = (char *) (s); \
+ while (*(_p) != 0) { \
+ if (*(_p) >= 'A' && *(_p) <= 'Z') { \
+ *(_p) = (*(_p) - 'A') + 'a'; \
+ } \
+ _p++; \
+ } \
+}
+
+static int
+parse_key_val (const char **pp, const char *endptr, char **kp, char **vp)
+{
+ const char *q, *p;
+ char *k, *v;
+ int n, error = 0;
+
+ for (p = *pp ; p < endptr && isspace((unsigned char)*p); p++)
+ ;
+#if 0
+ while (!error && p < endptr &&
+ ((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z'))
+ ) {
+#endif
+ k = v = NULL;
+ for (q = p, n = 0;
+ p < endptr &&
+ ((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9') ||
+ *p == '-' || *p == ':'
+ ); n++, p++);
+ if (n == 0) {
+#if 0
+ break;
+#else
+ *kp = *vp = NULL;
+ return -1;
+#endif
+ }
+ k = NEW(n + 1, char);
+ memcpy(k, q, n); k[n] = '\0';
+ if (p + 2 >= endptr || p[0] != '=' || (p[1] != '\"' && p[1] != '\'')) {
+ RELEASE(k); k = NULL;
+ *pp = p;
+ error = -1;
+ } else {
+ char qchr = p[1];
+ p += 2; /* skip '="' */
+ for (q = p, n = 0; p < endptr && *p != qchr; p++, n++);
+ if (p == endptr || *p != qchr)
+ error = -1;
+ else {
+ v = NEW(n + 1, char);
+ memcpy(v, q, n); v[n] = '\0';
+#if 0
+ pdf_add_dict(t->attr,
+ pdf_new_name(k),
+ pdf_new_string(v, n));
+ RELEASE(v);
+#endif
+ p++;
+ }
+ }
+#if 0
+ RELEASE(k);
+ if (!error)
+ for ( ; p < endptr && isspace(*p); p++);
+ }
+#endif
+
+ *kp = k; *vp = v; *pp = p;
+ return error;
+}
+
+#define HTML_TAG_NAME_MAX 127
+#define HTML_TAG_TYPE_EMPTY 1
+#define HTML_TAG_TYPE_OPEN 1
+#define HTML_TAG_TYPE_CLOSE 2
+
+static int
+read_html_tag (char *name, pdf_obj *attr, int *type, const char **pp, const char *endptr)
+{
+ const char *p = *pp;
+ int n = 0, error = 0;
+
+ for ( ; p < endptr && isspace((unsigned char)*p); p++);
+ if (p >= endptr || *p != '<')
+ return -1;
+
+ *type = HTML_TAG_TYPE_OPEN;
+ for (++p; p < endptr && isspace((unsigned char)*p); p++);
+ if (p < endptr && *p == '/') {
+ *type = HTML_TAG_TYPE_CLOSE;
+ for (++p; p < endptr && isspace((unsigned char)*p); p++);
+ }
+
+#define ISDELIM(c) ((c) == '>' || (c) == '/' || isspace((unsigned char)c))
+ for (n = 0; p < endptr && n < HTML_TAG_NAME_MAX && !ISDELIM(*p); n++, p++) {
+ name[n] = *p;
+ }
+ name[n] = '\0';
+ if (n == 0 || p == endptr || !ISDELIM(*p)) {
+ *pp = p;
+ return -1;
+ }
+
+ for ( ; p < endptr && isspace((unsigned char)*p); p++);
+ while (p < endptr && !error && *p != '/' && *p != '>') {
+ char *kp = NULL, *vp = NULL;
+ error = parse_key_val(&p, endptr, &kp, &vp);
+ if (!error) {
+ downcasify(kp);
+ pdf_add_dict(attr,
+ pdf_new_name(kp),
+ pdf_new_string(vp, strlen(vp) + 1)); /* include trailing NULL here!!! */
+ RELEASE(kp);
+ RELEASE(vp);
+ }
+ for ( ; p < endptr && isspace((unsigned char)*p); p++);
+ }
+ if (error) {
+ *pp = p;
+ return error;
+ }
+
+ if (p < endptr && *p == '/') {
+ *type = HTML_TAG_TYPE_EMPTY;
+ for (++p; p < endptr && isspace((unsigned char)*p); p++);
+ }
+ if (p == endptr || *p != '>') {
+ *pp = p;
+ return -1;
+ }
+ p++;
+
+ downcasify(name);
+ *pp = p;
+ return 0;
+}
+
+
+static int
+spc_handler_html__init (void *dp)
+{
+ struct spc_html_ *sd = dp;
+
+ sd->link_dict = NULL;
+ sd->baseurl = NULL;
+ sd->pending_type = -1;
+
+ return 0;
+}
+
+static int
+spc_handler_html__clean (struct spc_env *spe, void *dp)
+{
+ struct spc_html_ *sd = dp;
+
+ if (sd->baseurl)
+ RELEASE(sd->baseurl);
+
+ if (sd->pending_type >= 0 || sd->link_dict)
+ spc_warn(spe, "Unclosed html anchor found.");
+
+ if (sd->link_dict)
+ pdf_release_obj(sd->link_dict);
+
+ sd->pending_type = -1;
+ sd->baseurl = NULL;
+ sd->link_dict = NULL;
+
+ return 0;
+}
+
+
+static int
+spc_handler_html__bophook (struct spc_env *spe, void *dp)
+{
+ struct spc_html_ *sd = dp;
+
+ if (sd->pending_type >= 0) {
+ spc_warn(spe, "...html anchor continues from previous page processed...");
+ }
+
+ return 0;
+}
+
+static int
+spc_handler_html__eophook (struct spc_env *spe, void *dp)
+{
+ struct spc_html_ *sd = dp;
+
+ if (sd->pending_type >= 0) {
+ spc_warn(spe, "Unclosed html anchor at end-of-page!");
+ }
+
+ return 0;
+}
+
+
+static char *
+fqurl (const char *baseurl, const char *name)
+{
+ char *q;
+ int len = 0;
+
+ len = strlen(name);
+ if (baseurl)
+ len += strlen(baseurl) + 1; /* we may want to add '/' */
+
+ q = NEW(len + 1, char);
+ *q = '\0';
+ if (baseurl && baseurl[0]) {
+ char *p;
+ strcpy(q, baseurl);
+ p = q + strlen(q) - 1;
+ if (*p == '/')
+ *p = '\0';
+ if (name[0] && name[0] != '/')
+ strcat(q, "/");
+ }
+ strcat(q, name);
+
+ return q;
+}
+
+static int
+html_open_link (struct spc_env *spe, const char *name, struct spc_html_ *sd)
+{
+ pdf_obj *color;
+ char *url;
+
+ ASSERT( name );
+ ASSERT( sd->link_dict == NULL ); /* Should be checked somewhere else */
+
+ sd->link_dict = pdf_new_dict();
+ pdf_add_dict(sd->link_dict, pdf_new_name("Type"), pdf_new_name ("Annot"));
+ pdf_add_dict(sd->link_dict, pdf_new_name("Subtype"), pdf_new_name ("Link"));
+
+ color = pdf_new_array ();
+ pdf_add_array(color, pdf_new_number(0.0));
+ pdf_add_array(color, pdf_new_number(0.0));
+ pdf_add_array(color, pdf_new_number(1.0));
+ pdf_add_dict(sd->link_dict, pdf_new_name("C"), color);
+
+ url = fqurl(sd->baseurl, name);
+ if (url[0] == '#') {
+ /* url++; causes memory leak in RELEASE(url) */
+ pdf_add_dict(sd->link_dict, pdf_new_name("Dest"), pdf_new_string(url+1, strlen(url+1)));
+ } else { /* Assume this is URL */
+ pdf_obj *action = pdf_new_dict();
+ pdf_add_dict(action, pdf_new_name("Type"), pdf_new_name("Action"));
+ pdf_add_dict(action, pdf_new_name("S"), pdf_new_name("URI"));
+ pdf_add_dict(action, pdf_new_name("URI"), pdf_new_string(url, strlen(url)));
+ pdf_add_dict(sd->link_dict, pdf_new_name("A"), pdf_link_obj(action));
+ pdf_release_obj(action);
+ }
+ RELEASE(url);
+
+ spc_begin_annot(spe, pdf_link_obj(sd->link_dict));
+
+ sd->pending_type = ANCHOR_TYPE_HREF;
+
+ return 0;
+}
+
+static int
+html_open_dest (struct spc_env *spe, const char *name, struct spc_html_ *sd)
+{
+ int error;
+ pdf_obj *array, *page_ref;
+ pdf_coord cp;
+
+ cp.x = spe->x_user; cp.y = spe->y_user;
+ pdf_dev_transform(&cp, NULL);
+
+ page_ref = pdf_doc_this_page_ref();
+ ASSERT( page_ref ); /* Otherwise must be bug */
+
+ array = pdf_new_array();
+ pdf_add_array(array, page_ref);
+ pdf_add_array(array, pdf_new_name("XYZ"));
+ pdf_add_array(array, pdf_new_null());
+ pdf_add_array(array, pdf_new_number(cp.y + 24.0));
+ pdf_add_array(array, pdf_new_null());
+
+ error = pdf_doc_add_names("Dests", name, strlen(name), array);
+
+ if (error)
+ spc_warn(spe, "Failed to add named destination: %s", name);
+
+ sd->pending_type = ANCHOR_TYPE_NAME;
+
+ return error;
+}
+
+#define ANCHOR_STARTED(s) ((s)->pending_type >= 0 || (s)->link_dict)
+
+static int
+spc_html__anchor_open (struct spc_env *spe, pdf_obj *attr, struct spc_html_ *sd)
+{
+ pdf_obj *href, *name;
+ int error = 0;
+
+ if (ANCHOR_STARTED(sd)) {
+ spc_warn(spe, "Nested html anchors found!");
+ return -1;
+ }
+
+ href = pdf_lookup_dict(attr, "href");
+ name = pdf_lookup_dict(attr, "name");
+ if (href && name) {
+ spc_warn(spe, "Sorry, you can't have both \"href\" and \"name\" in anchor tag...");
+ error = -1;
+ } else if (href) {
+ error = html_open_link(spe, pdf_string_value(href), sd);
+ } else if (name) { /* name */
+ error = html_open_dest(spe, pdf_string_value(name), sd);
+ } else {
+ spc_warn(spe, "You should have \"href\" or \"name\" in anchor tag!");
+ error = -1;
+ }
+
+ return error;
+}
+
+static int
+spc_html__anchor_close (struct spc_env *spe, struct spc_html_ *sd)
+{
+ int error = 0;
+
+ switch (sd->pending_type) {
+ case ANCHOR_TYPE_HREF:
+ if (sd->link_dict) {
+ spc_end_annot(spe);
+ pdf_release_obj(sd->link_dict);
+ sd->link_dict = NULL;
+ sd->pending_type = -1;
+ } else {
+ spc_warn(spe, "Closing html anchor (link) without starting!");
+ error = -1;
+ }
+ break;
+ case ANCHOR_TYPE_NAME:
+ sd->pending_type = -1;
+ break;
+ default:
+ spc_warn(spe, "No corresponding opening tag for html anchor.");
+ error = -1;
+ break;
+ }
+
+ return error;
+}
+
+static int
+spc_html__base_empty (struct spc_env *spe, pdf_obj *attr, struct spc_html_ *sd)
+{
+ pdf_obj *href;
+ char *vp;
+
+ href = pdf_lookup_dict(attr, "href");
+ if (!href) {
+ spc_warn(spe, "\"href\" not found for \"base\" tag!");
+ return -1;
+ }
+
+ vp = (char *) pdf_string_value(href);
+ if (sd->baseurl) {
+ spc_warn(spe, "\"baseurl\" changed: \"%s\" --> \"%s\"", sd->baseurl, vp);
+ RELEASE(sd->baseurl);
+ }
+ sd->baseurl = NEW(strlen(vp) + 1, char);
+ strcpy(sd->baseurl, vp);
+
+ return 0;
+}
+
+
+#ifdef ENABLE_HTML_IMG_SUPPORT
+/* This isn't completed.
+ * Please think about placement of images.
+ */
+static double
+atopt (const char *a)
+{
+ char *q;
+ const char *p = a;
+ double v, u = 1.0;
+ const char *_ukeys[] = {
+#define K_UNIT__PT 0
+#define K_UNIT__IN 1
+#define K_UNIT__CM 2
+#define K_UNIT__MM 3
+#define K_UNIT__BP 4
+#define K_UNIT__PC 5
+#define K_UNIT__DD 6
+#define K_UNIT__CC 7
+#define K_UNIT__SP 8
+ "pt", "in", "cm", "mm", "bp", "pc", "dd", "cc", "sp",
+#define K_UNIT__PX 9
+ "px",
+ NULL
+ };
+ int k;
+
+ q = parse_float_decimal(&p, p + strlen(p));
+ if (!q) {
+ WARN("Invalid length value: %s (%c)", a, *p);
+ return 0.0;
+ }
+
+ v = atof(q);
+ RELEASE(q);
+
+ q = parse_c_ident(&p, p + strlen(p));
+ if (q) {
+ for (k = 0; _ukeys[k] && strcmp(_ukeys[k], q); k++);
+ switch (k) {
+ case K_UNIT__PT: u *= 72.0 / 72.27; break;
+ case K_UNIT__IN: u *= 72.0; break;
+ case K_UNIT__CM: u *= 72.0 / 2.54 ; break;
+ case K_UNIT__MM: u *= 72.0 / 25.4 ; break;
+ case K_UNIT__BP: u *= 1.0 ; break;
+ case K_UNIT__PC: u *= 12.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__DD: u *= 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__CC: u *= 12.0 * 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__SP: u *= 72.0 / (72.27 * 65536) ; break;
+ case K_UNIT__PX: u *= 1.0 ; break; /* 72dpi */
+ default:
+ WARN("Unknown unit of measure: %s", q);
+ break;
+ }
+ RELEASE(q);
+ }
+
+ return v * u;
+}
+
+
+#ifdef ENABLE_HTML_SVG_OPACITY
+/* Replicated from spc_tpic */
+static pdf_obj *
+create_xgstate (double a)
+{
+ pdf_obj *dict;
+
+ dict = pdf_new_dict();
+ pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("ExtGState"));
+ pdf_add_dict(dict, pdf_new_name("ca"), pdf_new_number(a));
+
+ return dict;
+}
+#endif /* ENABLE_HTML_SVG_OPACITY */
+
+static int
+spc_html__img_empty (struct spc_env *spe, pdf_obj *attr)
+{
+ pdf_obj *src, *obj;
+ transform_info ti;
+ load_options options = {1, 0, NULL};
+ int id, error = 0;
+#ifdef ENABLE_HTML_SVG_OPACITY
+ double alpha = 1.0; /* meaning fully opaque */
+#endif /* ENABLE_HTML_SVG_OPACITY */
+
+ spc_warn(spe, "html \"img\" tag found (not completed, plese don't use!).");
+
+ src = pdf_lookup_dict(attr, "src");
+ if (!src) {
+ spc_warn(spe, "\"src\" attribute not found for \"img\" tag!");
+ return -1;
+ }
+
+ transform_info_clear(&ti);
+ obj = pdf_lookup_dict(attr, "width");
+ if (obj) {
+ ti.width = atopt(pdf_string_value(obj));
+ ti.flags |= INFO_HAS_WIDTH;
+ }
+ obj = pdf_lookup_dict(attr, "height");
+ if (obj) {
+ ti.height = atopt(pdf_string_value(obj));
+ ti.flags |= INFO_HAS_HEIGHT;
+ }
+
+#ifdef ENABLE_HTML_SVG_OPACITY
+ obj = pdf_lookup_dict(attr, "svg:opacity");
+ if (obj) {
+ alpha = atof(pdf_string_value(obj));
+ if (alpha < 0.0 || alpha > 1.0) {
+ spc_warn(spe, "Invalid opacity value: %s", pdf_string_value(obj));
+ alpha = 1.0;
+ }
+ }
+#endif /* ENABLE_HTML_SVG_OPCAITY */
+
+#ifdef ENABLE_HTML_SVG_TRANSFORM
+ obj = pdf_lookup_dict(attr, "svg:transform");
+ if (obj) {
+ const char *p = pdf_string_value(obj);
+ pdf_tmatrix N;
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ while (*p && !error) {
+ pdf_setmatrix(&N, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+ error = cvt_a_to_tmatrix(&N, p, &p);
+ if (!error) {
+ N.f = -N.f;
+ pdf_concatmatrix(&ti.matrix, &N);
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ if (*p == ',')
+ for (++p; *p && isspace((unsigned char)*p); p++);
+ }
+ }
+ }
+#endif /* ENABLE_HTML_SVG_TRANSFORM */
+
+ if (error) {
+ spc_warn(spe, "Error in html \"img\" tag attribute.");
+ return error;
+ }
+
+ id = pdf_ximage_load_image(NULL, pdf_string_value(src), options);
+ if (id < 0) {
+ spc_warn(spe, "Could not find/load image: %s", pdf_string_value(src));
+ error = -1;
+ } else {
+#ifdef ENABLE_HTML_SVG_OPACITY
+ if (alpha != 0.0) {
+ pdf_obj *dict;
+ dict = create_xgstate(alpha);
+ pdf_dev_xgstate_push(dict);
+ }
+#endif
+ spc_put_image(spe, id, &ti, spe->x_user, spe->y_user);
+#ifdef ENABLE_HTML_SVG_OPACITY
+ if (alpha != 0.0) {
+ pdf_dev_xgstate_pop();
+ }
+#endif
+ }
+
+ return error;
+}
+#else
+static int
+spc_html__img_empty (struct spc_env *spe, pdf_obj *attr)
+{
+ spc_warn(spe, "IMG tag not yet supported yet...");
+ return -1;
+}
+#endif /* ENABLE_HTML_IMG_SUPPORT */
+
+
+static int
+spc_handler_html_default (struct spc_env *spe, struct spc_arg *ap)
+{
+ struct spc_html_ *sd = &_html_state;
+ char name[HTML_TAG_NAME_MAX + 1];
+ pdf_obj *attr;
+ int error = 0, type = HTML_TAG_TYPE_OPEN;
+
+ if (ap->curptr >= ap->endptr)
+ return 0;
+
+ attr = pdf_new_dict();
+ error = read_html_tag(name, attr, &type, &ap->curptr, ap->endptr);
+ if (error) {
+ pdf_release_obj(attr);
+ return error;
+ }
+ if (!strcmp(name, "a")) {
+ switch (type) {
+ case HTML_TAG_TYPE_OPEN:
+ error = spc_html__anchor_open (spe, attr, sd);
+ break;
+ case HTML_TAG_TYPE_CLOSE:
+ error = spc_html__anchor_close(spe, sd);
+ break;
+ default:
+ spc_warn(spe, "Empty html anchor tag???");
+ error = -1;
+ break;
+ }
+ } else if (!strcmp(name, "base")) {
+ if (type == HTML_TAG_TYPE_CLOSE) {
+ spc_warn(spe, "Close tag for \"base\"???");
+ error = -1;
+ } else { /* treat "open" same as "empty" */
+ error = spc_html__base_empty(spe, attr, sd);
+ }
+ } else if (!strcmp(name, "img")) {
+ if (type == HTML_TAG_TYPE_CLOSE) {
+ spc_warn(spe, "Close tag for \"img\"???");
+ error = -1;
+ } else { /* treat "open" same as "empty" */
+ error = spc_html__img_empty(spe, attr);
+ }
+ }
+ pdf_release_obj(attr);
+
+ for ( ; ap->curptr < ap->endptr && isspace((unsigned char)ap->curptr[0]); ap->curptr++);
+
+ return error;
+}
+
+
+#ifdef ENABLE_HTML_SVG_TRANSFORM
+/* translate wsp* '(' wsp* number (comma-wsp number)? wsp* ')' */
+static int
+cvt_a_to_tmatrix (pdf_tmatrix *M, const char *ptr, const char **nextptr)
+{
+ char *q;
+ const char *p = ptr;
+ int n;
+ double v[6];
+ static const char *_tkeys[] = {
+#define K_TRNS__MATRIX 0
+ "matrix", /* a b c d e f */
+#define K_TRNS__TRANSLATE 1
+ "translate", /* tx [ty] : dflt. tf = 0 */
+#define K_TRNS__SCALE 2
+ "scale", /* sx [sy] : dflt. sy = sx */
+#define K_TRNS__ROTATE 3
+ "rotate", /* ang [cx cy] : dflt. cx, cy = 0 */
+#define K_TRNS__SKEWX 4
+#define K_TRNS__SKEWY 5
+ "skewX", /* ang */
+ "skewY", /* ang */
+ NULL
+ };
+ int k;
+
+ for ( ; *p && isspace((unsigned char)*p); p++);
+
+ q = parse_c_ident(&p, p + strlen(p));
+ if (!q)
+ return -1;
+ /* parsed transformation key */
+ for (k = 0; _tkeys[k] && strcmp(q, _tkeys[k]); k++);
+ RELEASE(q);
+
+ /* handle args */
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ if (*p != '(' || *(p + 1) == 0)
+ return -1;
+ for (++p; *p && isspace((unsigned char)*p); p++);
+ for (n = 0; n < 6 && *p && *p != ')'; n++) {
+ q = parse_float_decimal(&p, p + strlen(p));
+ if (!q)
+ break;
+ else {
+ v[n] = atof(q);
+ if (*p == ',')
+ p++;
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ if (*p == ',')
+ for (++p; *p && isspace((unsigned char)*p); p++);
+ RELEASE(q);
+ }
+ }
+ if (*p != ')')
+ return -1;
+ p++;
+
+ switch (k) {
+ case K_TRNS__MATRIX:
+ if (n != 6)
+ return -1;
+ M->a = v[0]; M->c = v[1];
+ M->b = v[2]; M->d = v[3];
+ M->e = v[4]; M->f = v[5];
+ break;
+ case K_TRNS__TRANSLATE:
+ if (n != 1 && n != 2)
+ return -1;
+ M->a = M->d = 1.0;
+ M->c = M->b = 0.0;
+ M->e = v[0]; M->f = (n == 2) ? v[1] : 0.0;
+ break;
+ case K_TRNS__SCALE:
+ if (n != 1 && n != 2)
+ return -1;
+ M->a = v[0]; M->d = (n == 2) ? v[1] : v[0];
+ M->c = M->b = 0.0;
+ M->e = M->f = 0.0;
+ break;
+ case K_TRNS__ROTATE:
+ if (n != 1 && n != 3)
+ return -1;
+ M->a = cos(v[0] * M_PI / 180.0);
+ M->c = sin(v[0] * M_PI / 180.0);
+ M->b = -M->c; M->d = M->a;
+ M->e = (n == 3) ? v[1] : 0.0;
+ M->f = (n == 3) ? v[2] : 0.0;
+ break;
+ case K_TRNS__SKEWX:
+ if (n != 1)
+ return -1;
+ M->a = M->d = 1.0;
+ M->c = 0.0;
+ M->b = tan(v[0] * M_PI / 180.0);
+ break;
+ case K_TRNS__SKEWY:
+ if (n != 1)
+ return -1;
+ M->a = M->d = 1.0;
+ M->c = tan(v[0] * M_PI / 180.0);
+ M->b = 0.0;
+ break;
+ }
+
+ if (nextptr)
+ *nextptr = p;
+ return 0;
+}
+#endif /* ENABLE_HTML_SVG_TRANSFORM */
+
+int
+spc_html_at_begin_document (void)
+{
+ struct spc_html_ *sd = &_html_state;
+ return spc_handler_html__init(sd);
+}
+
+int
+spc_html_at_begin_page (void)
+{
+ struct spc_html_ *sd = &_html_state;
+ return spc_handler_html__bophook(NULL, sd);
+}
+
+int
+spc_html_at_end_page (void)
+{
+ struct spc_html_ *sd = &_html_state;
+ return spc_handler_html__eophook(NULL, sd);
+}
+
+int
+spc_html_at_end_document (void)
+{
+ struct spc_html_ *sd = &_html_state;
+ return spc_handler_html__clean(NULL, sd);
+}
+
+
+int
+spc_html_check_special (const char *buffer, int size)
+{
+ const char *p, *endptr;
+
+ p = buffer;
+ endptr = p + size;
+
+ for ( ; p < endptr && isspace((unsigned char)*p); p++);
+ size = (int) (endptr - p);
+ if (size >= strlen("html:") &&
+ !memcmp(p, "html:", strlen("html:"))) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int
+spc_html_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap)
+{
+ ASSERT(sph && spe && ap);
+
+ for ( ; ap->curptr < ap->endptr && isspace((unsigned char)ap->curptr[0]); ap->curptr++);
+ if (ap->curptr + strlen("html:") > ap->endptr ||
+ memcmp(ap->curptr, "html:", strlen("html:"))) {
+ return -1;
+ }
+
+ ap->command = "";
+
+ sph->key = "html:";
+ sph->exec = &spc_handler_html_default;
+
+ ap->curptr += strlen("html:");
+ for ( ; ap->curptr < ap->endptr && isspace((unsigned char)ap->curptr[0]); ap->curptr++);
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/spc_html.h b/Build/source/texk/dvipdfm-x/spc_html.h
new file mode 100644
index 00000000000..0d7226bd323
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_html.h
@@ -0,0 +1,37 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_HTML_H_
+#define _SPC_HTML_H_
+
+#include "specials.h"
+
+extern int spc_html_at_begin_page (void);
+extern int spc_html_at_end_page (void);
+extern int spc_html_at_begin_document (void);
+extern int spc_html_at_end_document (void);
+
+extern int spc_html_check_special (const char *buffer, int size);
+extern int spc_html_setup_handler (struct spc_handler *handle,
+ struct spc_env *spe, struct spc_arg *args);
+
+#endif /* _SPC_HTML_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_misc.c b/Build/source/texk/dvipdfm-x/spc_misc.c
new file mode 100644
index 00000000000..e974596cca6
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_misc.c
@@ -0,0 +1,680 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "mfileio.h"
+
+#include "dpxutil.h"
+
+#include "pdfparse.h"
+#include "pdfobj.h"
+
+#include "pdfcolor.h"
+#include "pdfdraw.h"
+#include "pdfximage.h"
+#include "pdfdev.h"
+
+#include "mpost.h"
+
+#include "specials.h"
+
+#include "spc_util.h"
+#include "spc_misc.h"
+
+/* pdfcolorstack:
+ * This special is provoded as a compatibility feature to pdftex.
+ */
+struct stack
+{
+ int page;
+ int direct;
+ dpx_stack stack;
+};
+
+#define PDFCOLORSTACK_MAX_STACK 256
+struct spc_stack
+{
+ struct stack stacks[PDFCOLORSTACK_MAX_STACK];
+};
+
+static struct spc_stack spc_stack;
+
+static int
+pdfcolorstack__get_id (struct spc_env *spe, int *id, struct spc_arg *args)
+{
+ char *q;
+
+ if (args->curptr >= args->endptr) {
+ spc_warn(spe, "Stack ID number expected but not found.");
+ return -1;
+ }
+ q = parse_number(&args->curptr, args->endptr);
+ if (!q) {
+ spc_warn(spe, "Stack ID number expected but not found.");
+ return -1;
+ }
+ *id = atoi(q);
+ RELEASE(q);
+
+ skip_white(&args->curptr, args->endptr);
+
+ return 0;
+}
+
+static int
+pdfcolorstack__init (void *dp)
+{
+ struct spc_stack *sd = dp;
+ int i;
+
+ for (i = 0; i < PDFCOLORSTACK_MAX_STACK; i++) {
+ sd->stacks[i].page = 0;
+ sd->stacks[i].direct = 0;
+ dpx_stack_init(&sd->stacks[i].stack);
+ }
+
+ return 0;
+}
+
+static int
+pdfcolorstack__clean (void *dp)
+{
+ struct spc_stack *sd = dp;
+ int i;
+
+ for (i = 0; i < PDFCOLORSTACK_MAX_STACK; i++) {
+ pdf_obj *litstr;
+ dpx_stack *stk = &sd->stacks[i].stack;
+
+ while ((litstr = dpx_stack_pop(stk)) != NULL) {
+ pdf_release_obj(litstr);
+ }
+ }
+
+ return 0;
+}
+
+static void
+pdfcolorstack__set_litstr (pdf_coord cp, pdf_obj *litstr, int direct)
+{
+ pdf_tmatrix M;
+
+ if (!litstr)
+ return;
+
+ if (!direct) {
+ M.a = M.d = 1.0; M.b = M.c = 0.0;
+ M.e = cp.x; M.f = cp.y;
+ pdf_dev_concat(&M);
+ }
+ pdf_doc_add_page_content(" ", 1);
+ pdf_doc_add_page_content(pdf_string_value(litstr), pdf_string_length(litstr));
+ if (!direct) {
+ M.e = -cp.x; M.f = -cp.y;
+ pdf_dev_concat(&M);
+ }
+}
+
+static int
+spc_handler_pdfcolorstackinit (struct spc_env *spe, struct spc_arg *args)
+{
+ int id = -1;
+ struct stack *st;
+ char *q;
+ pdf_coord cp = {0.0, 0.0};
+ pdf_obj *litstr;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+
+ if (pdfcolorstack__get_id(spe, &id, args) < 0)
+ return -1;
+ if (id < 0 || id >= PDFCOLORSTACK_MAX_STACK) {
+ spc_warn(spe, "Invalid stack number specified: %d", id);
+ return -1;
+ }
+ skip_white(&args->curptr, args->endptr);
+
+ st = &spc_stack.stacks[id];
+ if (dpx_stack_depth(&st->stack) > 0) {
+ spc_warn(spe, "Stadk ID=%d already initialized?", id);
+ return -1;
+ }
+
+ while ((q = parse_c_ident(&args->curptr, args->endptr)) != NULL) {
+ if (!strcmp(q, "page")) {
+ st->page = 1;
+ } else if (!strcmp(q, "direct")) {
+ st->direct = 1;
+ } else {
+ spc_warn(spe, "Ignoring unknown option for pdfcolorstack special (init): %s", q);
+ }
+ RELEASE(q);
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ if (args->curptr < args->endptr) {
+ litstr = parse_pdf_string(&args->curptr, args->endptr);
+ if (litstr) {
+ dpx_stack_push(&st->stack, litstr);
+ pdfcolorstack__set_litstr(cp, litstr, st->direct);
+ }
+ skip_white(&args->curptr, args->endptr);
+ } else {
+ spc_warn(spe, "No valid PDF literal specified.");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+pdfcolorstack__set (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args)
+{
+ pdf_obj *litstr;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+
+ litstr = dpx_stack_pop(&st->stack);
+ if (!litstr) {
+ spc_warn(spe, "Stack empty!");
+ return -1;
+ }
+ pdf_release_obj(litstr);
+
+ litstr = parse_pdf_string(&args->curptr, args->endptr);
+ if (litstr) {
+ dpx_stack_push(&st->stack, litstr);
+ pdfcolorstack__set_litstr(cp, litstr, st->direct);
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ return 0;
+}
+
+static int
+pdfcolorstack__push (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args)
+{
+ pdf_obj *litstr;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+
+ litstr = parse_pdf_string(&args->curptr, args->endptr);
+ if (litstr) {
+ dpx_stack_push(&st->stack, litstr);
+ pdfcolorstack__set_litstr(cp, litstr, st->direct);
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ return 0;
+}
+
+static int
+pdfcolorstack__current (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args)
+{
+ pdf_obj *litstr;
+
+ litstr = dpx_stack_top(&st->stack);
+ if (litstr) {
+ pdfcolorstack__set_litstr(cp, litstr, st->direct);
+ skip_white(&args->curptr, args->endptr);
+ } else {
+ spc_warn(spe, "Stack empty!");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+pdfcolorstack__pop (struct spc_env *spe, struct stack *st, pdf_coord cp, struct spc_arg *args)
+{
+ int error = 0;
+ pdf_obj *litstr;
+
+ /* "default" at the bottom */
+ if (dpx_stack_depth(&st->stack) < 2) {
+ spc_warn(spe, "Stack underflow");
+ return -1;
+ }
+ litstr = dpx_stack_pop(&st->stack);
+ if (litstr) {
+ pdf_release_obj(litstr);
+ }
+ litstr = dpx_stack_top(&st->stack);
+ if (litstr) {
+ pdfcolorstack__set_litstr(cp, litstr, st->direct);
+ }
+
+ return error;
+}
+
+static int
+spc_handler_pdfcolorstack (struct spc_env *spe, struct spc_arg *args)
+{
+ int error = 0;
+ int id;
+ char *command;
+ struct stack *st;
+ pdf_coord cp;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+
+ if (pdfcolorstack__get_id(spe, &id, args) < 0)
+ return -1;
+ if (id < 0 || id >= PDFCOLORSTACK_MAX_STACK) {
+ spc_warn(spe, "Invalid stack ID specified: %d", id);
+ return -1;
+ }
+ skip_white(&args->curptr, args->endptr);
+
+ st = &spc_stack.stacks[id];
+ if (dpx_stack_depth(&st->stack) < 1) {
+ spc_warn(spe, "Stack ID=%d not properly initialized?", id);
+ return -1;
+ }
+
+ command = parse_c_ident(&args->curptr, args->endptr);
+ if (!command)
+ return -1;
+
+ spc_get_current_point(spe, &cp);
+ if (!strcmp(command, "set")) {
+ error = pdfcolorstack__set(spe, st, cp, args);
+ } else if (!strcmp(command, "push")) {
+ error = pdfcolorstack__push(spe, st, cp, args);
+ } else if (!strcmp(command, "pop")) {
+ error = pdfcolorstack__pop(spe, st, cp, args);
+ } else if (!strcmp(command, "current")) {
+ error = pdfcolorstack__current(spe, st, cp, args);
+ } else {
+ spc_warn(spe, "Unknown action: %s", command);
+ }
+
+ if (error) {
+ spc_warn(spe, "Error occurred while processing pdfcolorstack: id=%d command=\"%s\"", id, command);
+ }
+
+ RELEASE(command);
+
+ return error;
+}
+
+/* Duplicate from spc_pdfm */
+static pdf_obj *
+parse_pdf_reference (const char **start, const char *end, void *user_data)
+{
+ pdf_obj *result = NULL;
+ char *name;
+
+ skip_white(start, end);
+ name = parse_opt_ident(start, end);
+ if (name) {
+ result = spc_lookup_reference(name);
+ if (!result) {
+ WARN("Could not find the named reference (@%s).", name);
+ }
+ RELEASE(name);
+ } else {
+ WARN("Could not find a reference name.");
+ result = NULL;
+ }
+
+ return result;
+}
+
+/* pdffontattr */
+#include "pdffont.h"
+
+struct fontattr {
+ char *ident;
+ double size;
+ pdf_obj *attr;
+};
+
+struct fontattr *fontattrs = NULL;
+int num_fontattrs = 0;
+int max_fontattrs = 0;
+
+static int
+process_fontattr (const char *ident, double size, pdf_obj *attr)
+{
+ int font_id;
+ pdf_obj *fontdict;
+
+ ASSERT(ident && attr);
+
+ font_id = pdf_font_findresource(ident, size);
+ if (font_id < 0) {
+ WARN("Could not find specified font resource: %s (%gpt)", ident, size);
+ return -1;
+ }
+
+ fontdict = pdf_get_font_resource(font_id);
+ if (!fontdict) {
+ WARN("Specified object not exist: %s (%gpt)", ident, size);
+ return -1;
+ }
+
+ pdf_merge_dict(fontdict, attr);
+
+ return 0;
+}
+
+static int
+spc_handler_pdffontattr (struct spc_env *spe, struct spc_arg *ap)
+{
+ struct fontattr *fontattr;
+ char *ident = NULL;
+ double size = 0.0;
+ pdf_obj *attr = NULL;
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr)
+ return -1;
+
+ ident = parse_ident(&ap->curptr, ap->endptr);
+ if (!ident) {
+ spc_warn(spe, "Missing a font name.");
+ return -1;
+ }
+ skip_white(&ap->curptr, ap->endptr);
+
+ if (ap->curptr < ap->endptr && ap->curptr[0] != '<') {
+ int error = dpx_util_read_length(&size, 1.0, &ap->curptr, ap->endptr);
+ if (error) {
+ spc_warn(spe, "Font size expected but not found.");
+ RELEASE(ident);
+ return -1;
+ }
+ skip_white(&ap->curptr, ap->endptr);
+ }
+
+ attr = parse_pdf_object_extended(&ap->curptr, ap->endptr, NULL, parse_pdf_reference, spe);
+ if (!attr) {
+ spc_warn(spe, "Failed to parse a PDF dictionary object: %s", ident);
+ RELEASE(ident);
+ return -1;
+ } else if (!PDF_OBJ_DICTTYPE(attr)) {
+ spc_warn(spe, "PDF dict expected but non-dict object found: %s", ident);
+ RELEASE(ident);
+ pdf_release_obj(attr);
+ return -1;
+ }
+ skip_white(&ap->curptr, ap->endptr);
+
+ if (num_fontattrs >= max_fontattrs) {
+ fontattrs = RENEW(fontattrs, max_fontattrs + 256, struct fontattr);
+ max_fontattrs += 256;
+ }
+ fontattr = &fontattrs[num_fontattrs];
+ num_fontattrs += 1;
+
+ fontattr->ident = ident;
+ fontattr->size = size;
+ fontattr->attr = attr;
+
+ return 0;
+}
+
+int
+spc_misc_at_begin_document (void)
+{
+ struct spc_stack *sd = &spc_stack;
+
+ if (!fontattrs) {
+ fontattrs = NEW(256, struct fontattr);
+ num_fontattrs = 0;
+ max_fontattrs = 256;
+ }
+
+ return pdfcolorstack__init(sd);
+}
+
+int
+spc_misc_at_end_document (void)
+{
+ struct spc_stack *sd = &spc_stack;
+
+ if (fontattrs) {
+ int i;
+
+ for (i = 0; i < num_fontattrs; i++) {
+ process_fontattr(fontattrs[i].ident, fontattrs[i].size, fontattrs[i].attr);
+ RELEASE(fontattrs[i].ident);
+ pdf_release_obj(fontattrs[i].attr);
+ }
+ RELEASE(fontattrs);
+ fontattrs = NULL;
+ max_fontattrs = num_fontattrs = 0;
+ }
+
+ return pdfcolorstack__clean(sd);
+}
+
+int
+spc_misc_at_begin_page (void)
+{
+ struct spc_stack *sd = &spc_stack;
+ int i;
+
+ for (i = 0; i < PDFCOLORSTACK_MAX_STACK; i++) {
+ dpx_stack *stk = &sd->stacks[i].stack;
+
+ if (sd->stacks[i].page) {
+ pdf_obj *litstr = dpx_stack_top(stk);
+ pdf_coord cp = {0.0, 0.0};
+
+ if (litstr)
+ pdfcolorstack__set_litstr(cp, litstr, sd->stacks[i].direct);
+ }
+ }
+
+ return 0;
+}
+
+int
+spc_misc_at_begin_form (void)
+{
+ return spc_misc_at_begin_page();
+}
+
+int
+spc_misc_at_end_form (void)
+{
+ return spc_misc_at_begin_page();
+}
+
+static int
+spc_handler_postscriptbox (struct spc_env *spe, struct spc_arg *ap)
+{
+ int form_id, len;
+ transform_info ti;
+ load_options options = {1, 0, NULL};
+ char filename[256], *fullname;
+ char buf[512];
+ FILE *fp;
+
+ ASSERT(spe && ap);
+
+ if (ap->curptr >= ap->endptr) {
+ spc_warn(spe, "No width/height/filename given for postscriptbox special.");
+ return -1;
+ }
+
+ /* input is not NULL terminated */
+ len = (int) (ap->endptr - ap->curptr);
+ len = MIN(511, len);
+ memcpy(buf, ap->curptr, len);
+ buf[len] = '\0';
+
+ transform_info_clear(&ti);
+
+ spc_warn(spe, buf);
+ if (sscanf(buf, "{%lfpt}{%lfpt}{%255[^}]}",
+ &ti.width, &ti.height, filename) != 3) {
+ spc_warn(spe, "Syntax error in postscriptbox special?");
+ return -1;
+ }
+ ap->curptr = ap->endptr;
+
+ ti.width *= 72.0 / 72.27;
+ ti.height *= 72.0 / 72.27;
+
+ fullname = kpse_find_pict(filename);
+ if (!fullname) {
+ spc_warn(spe, "Image file \"%s\" not found.", filename);
+ return -1;
+ }
+
+ fp = MFOPEN(fullname, FOPEN_R_MODE);
+ if (!fp) {
+ spc_warn(spe, "Could not open image file: %s", fullname);
+ RELEASE(fullname);
+ return -1;
+ }
+ RELEASE(fullname);
+
+ ti.flags |= (INFO_HAS_WIDTH|INFO_HAS_HEIGHT);
+
+ for (;;) {
+ const char *p = mfgets(buf, 512, fp);
+ if (!p)
+ break;
+ if (mps_scan_bbox(&p, p + strlen(p), &ti.bbox) >= 0) {
+ ti.flags |= INFO_HAS_USER_BBOX;
+ break;
+ }
+ }
+ MFCLOSE(fp);
+
+ form_id = pdf_ximage_load_image(NULL, filename, options);
+ if (form_id < 0) {
+ spc_warn(spe, "Failed to load image file: %s", filename);
+ return -1;
+ }
+
+ spc_put_image(spe, form_id, &ti, spe->x_user, spe->y_user);
+
+ return 0;
+}
+
+static int
+spc_handler_null (struct spc_env *spe, struct spc_arg *args)
+{
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static struct spc_handler misc_handlers[] = {
+ {"postscriptbox", spc_handler_postscriptbox},
+ {"pdfcolorstackinit", spc_handler_pdfcolorstackinit},
+ {"pdfcolorstack", spc_handler_pdfcolorstack},
+ {"pdffontattr", spc_handler_pdffontattr},
+ {"landscape", spc_handler_null}, /* handled at bop */
+ {"papersize", spc_handler_null}, /* handled at bop */
+ {"src:", spc_handler_null}, /* simply ignore */
+ {"pos:", spc_handler_null}, /* simply ignore */
+ {"om:", spc_handler_null} /* simply ignore */
+};
+
+
+int
+spc_misc_check_special (const char *buffer, int size)
+{
+ const char *p, *endptr;
+ int i;
+
+ p = buffer;
+ endptr = p + size;
+
+ skip_white(&p, endptr);
+ size = (int) (endptr - p);
+ for (i = 0; i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) {
+ if (size >= strlen(misc_handlers[i].key) &&
+ !strncmp(p, misc_handlers[i].key, strlen(misc_handlers[i].key))) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int
+spc_misc_setup_handler (struct spc_handler *handle, struct spc_env *spe, struct spc_arg *args)
+{
+ const char *key;
+ int i, keylen;
+
+ ASSERT(handle && spe && args);
+
+ skip_white(&args->curptr, args->endptr);
+
+ key = args->curptr;
+ while (args->curptr < args->endptr && isalpha((unsigned char)args->curptr[0])) {
+ args->curptr++;
+ }
+
+ if (args->curptr < args->endptr &&
+ args->curptr[0] == ':') {
+ args->curptr++;
+ }
+
+ keylen = (int) (args->curptr - key);
+ if (keylen < 1) {
+ return -1;
+ }
+
+ for (i = 0; i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) {
+ if (keylen == strlen(misc_handlers[i].key) &&
+ !strncmp(key, misc_handlers[i].key, keylen)) {
+
+ skip_white(&args->curptr, args->endptr);
+
+ args->command = misc_handlers[i].key;
+
+ handle->key = "???:";
+ handle->exec = misc_handlers[i].exec;
+
+ return 0;
+ }
+ }
+
+ return -1;
+}
diff --git a/Build/source/texk/dvipdfm-x/spc_misc.h b/Build/source/texk/dvipdfm-x/spc_misc.h
new file mode 100644
index 00000000000..413c5d88ccc
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_misc.h
@@ -0,0 +1,36 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_MISC_H_
+#define _SPC_MISC_H_
+
+#include "specials.h"
+
+extern int spc_misc_check_special (const char *buffer, int size);
+extern int spc_misc_setup_handler (struct spc_handler *handle, struct spc_env *spe, struct spc_arg *args);
+extern int spc_misc_at_begin_document (void);
+extern int spc_misc_at_end_document (void);
+extern int spc_misc_at_begin_page (void);
+extern int spc_misc_at_begin_form (void);
+extern int spc_misc_at_end_form (void);
+
+#endif /* _SPC_MISC_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_pdfm.c b/Build/source/texk/dvipdfm-x/spc_pdfm.c
new file mode 100644
index 00000000000..d45e09330f2
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_pdfm.c
@@ -0,0 +1,2435 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+
+#include "numbers.h"
+
+#include "fontmap.h"
+#include "dpxfile.h"
+#include "dpxutil.h"
+#include "dpxconf.h"
+
+#include "unicode.h"
+
+#include "pdfobj.h"
+#include "pdfparse.h"
+
+#include "pdfdoc.h"
+
+#include "pdfximage.h"
+#include "pdfdraw.h"
+#include "pdfcolor.h"
+#include "pdfdev.h"
+
+#include "specials.h"
+
+#include "spc_util.h"
+#include "spc_pdfm.h"
+
+#include "dvipdfmx.h"
+
+#define SPC_PDFM_SUPPORT_ANNOT_TRANS 1
+
+struct tounicode {
+ int cmap_id;
+ int unescape_backslash;
+ pdf_obj *taintkeys; /* An array of PDF names. */
+};
+
+struct spc_pdf_
+{
+ pdf_obj *annot_dict; /* pending annotation dict */
+ int lowest_level; /* current min level of outlines */
+ struct tounicode cd; /* For to-UTF16-BE conversion :( */
+ pdf_obj *pageresources; /* Add to all page resource dict */
+};
+
+static struct spc_pdf_ _pdf_stat = {
+ NULL,
+ 255,
+ { -1, 0, NULL },
+ NULL
+};
+
+static pdf_obj *
+parse_pdf_reference (const char **start, const char *end, void *user_data)
+{
+ pdf_obj *result = NULL;
+ char *name;
+
+ skip_white(start, end);
+ name = parse_opt_ident(start, end);
+ if (name) {
+ result = spc_lookup_reference(name);
+ if (!result) {
+ WARN("Could not find the named reference (@%s).", name);
+ }
+ RELEASE(name);
+ } else {
+ WARN("Could not find a reference name.");
+ result = NULL;
+ }
+
+ return result;
+}
+
+static int
+spc_handler_pdfm__init (void *dp)
+{
+ struct spc_pdf_ *sd = dp;
+ /* The folllowing dictionary entry keys are considered as keys for
+ * text strings. Be sure that string object is NOT always a text string.
+ */
+ static const char *default_taintkeys[] = {
+ "Title", "Author", "Subject", "Keywords",
+ "Creator", "Producer", "Contents", "Subj",
+ "TU", "T", "TM", NULL /* EOD */
+ };
+ int i;
+
+ sd->annot_dict = NULL;
+ sd->lowest_level = 255;
+ sd->cd.taintkeys = pdf_new_array();
+ for (i = 0; default_taintkeys[i] != NULL; i++) {
+ pdf_add_array(sd->cd.taintkeys,
+ pdf_new_name(default_taintkeys[i]));
+ }
+ sd->pageresources = NULL;
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm__clean (void *dp)
+{
+ struct spc_pdf_ *sd = dp;
+
+ if (sd->annot_dict) {
+ WARN("Unbalanced bann and eann found.");
+ pdf_release_obj(sd->annot_dict);
+ }
+ sd->lowest_level = 255;
+ sd->annot_dict = NULL;
+ if (sd->cd.taintkeys)
+ pdf_release_obj(sd->cd.taintkeys);
+ sd->cd.taintkeys = NULL;
+ if (sd->pageresources)
+ pdf_release_obj(sd->pageresources);
+ sd->pageresources = NULL;
+
+ return 0;
+}
+
+
+int
+spc_pdfm_at_begin_document (void)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ return spc_handler_pdfm__init(sd);
+}
+
+int
+spc_pdfm_at_end_document (void)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ return spc_handler_pdfm__clean(sd);
+}
+
+/* Why should we have this kind of things? */
+static int
+safeputresdent (pdf_obj *kp, pdf_obj *vp, void *dp)
+{
+ char *key;
+
+ ASSERT(kp && vp && dp);
+
+ key = pdf_name_value(kp);
+ if (pdf_lookup_dict(dp, key))
+ WARN("Object \"%s\" already defined in dict! (ignored)", key);
+ else {
+ pdf_add_dict(dp,
+ pdf_link_obj(kp), pdf_link_obj(vp));
+ }
+ return 0;
+}
+
+static int
+safeputresdict (pdf_obj *kp, pdf_obj *vp, void *dp)
+{
+ char *key;
+ pdf_obj *dict;
+
+ ASSERT(kp && vp && dp);
+
+ key = pdf_name_value(kp);
+ dict = pdf_lookup_dict(dp, key);
+
+ /* Not sure what is the best way to handle this situation */
+ if (PDF_OBJ_INDIRECTTYPE(dict)) {
+ if (PDF_OBJ_INDIRECTTYPE(vp)) {
+ /* If two indirect objects are pointing the same object, do nothing. */
+ if (!pdf_compare_reference(dict, vp)) {
+ return 0;
+ } else {
+ /* otherwise merge the content of old one (see below) */
+ dict = pdf_deref_obj(dict);
+ pdf_release_obj(dict); /* decrement link count */
+ }
+ }
+ }
+
+ if (pdf_obj_typeof(vp) == PDF_INDIRECT) {
+ /* Copy the content of old resource category dict (if exists) */
+ if (dict) {
+ pdf_obj *dst = pdf_deref_obj(vp);
+ if (dst) {
+ if (pdf_obj_typeof(dst) == PDF_DICT) {
+ pdf_foreach_dict(dict, safeputresdent, dst);
+ pdf_release_obj(dst);
+ } else {
+ WARN("Invalid type (not DICT) for page/form resource dict entry: key=\"%s\"", key);
+ pdf_release_obj(dst);
+ return -1;
+ }
+ }
+ }
+ pdf_add_dict(dp, pdf_new_name(key), pdf_link_obj(vp));
+ } else if (pdf_obj_typeof(vp) == PDF_DICT) {
+ if (dict)
+ pdf_foreach_dict(vp, safeputresdent, dict);
+ else {
+ pdf_add_dict(dp, pdf_new_name(key), pdf_link_obj(vp));
+ }
+ } else {
+ WARN("Invalid type (not DICT) for page/form resource dict entry: key=\"%s\"", key);
+ return -1;
+ }
+
+ return 0;
+}
+
+static
+int putpageresources (pdf_obj *kp, pdf_obj *vp, void *dp)
+{
+ char *resource_name;
+
+ ASSERT(kp && vp);
+
+ resource_name = pdf_name_value(kp);
+ pdf_doc_add_page_resource(dp, resource_name, pdf_link_obj(vp));
+
+ return 0;
+}
+
+static
+int forallresourcecategory (pdf_obj *kp, pdf_obj *vp, void *dp)
+{
+ int r = -1;
+ char *category;
+
+ ASSERT(kp && vp);
+
+ category = pdf_name_value(kp);
+ switch (pdf_obj_typeof(vp)) {
+ case PDF_DICT:
+ r = pdf_foreach_dict(vp, putpageresources, category);
+ break;
+ case PDF_INDIRECT:
+ {
+ /* In case pdf:pageresouces << /Category @res >> */
+ pdf_obj *obj;
+ obj = pdf_deref_obj(vp);
+ if (!obj) {
+ WARN("Can't deref object for page resource: %s", category);
+ r = -1;
+ } else if (pdf_obj_typeof(obj) != PDF_DICT) {
+ WARN("Invalid object type for page resource: %s", category);
+ r = -1;
+ } else {
+ pdf_obj *res_dict, *dict;
+
+ res_dict = pdf_doc_current_page_resources();
+ dict = pdf_lookup_dict(res_dict, category);
+ if (!dict) {
+ pdf_add_dict(res_dict, pdf_new_name(category), pdf_link_obj(vp));
+ } else {
+ if (pdf_obj_typeof(dict) == PDF_INDIRECT) {
+ dict = pdf_deref_obj(dict);
+ pdf_release_obj(dict); /* FIXME: jus to decrement link counter */
+ }
+#if 0
+ /* This will leave garbage (object "res") since object "res"
+ * supplied as resource dictionary will have label but we copy the
+ * content of res here and never use reference to it.
+ */
+ pdf_foreach_dict(obj, safeputresdent, dict);
+#else
+ /* With the below code resource dictionary is replaced by user
+ * supplied one, @res. However, there is a problem that all
+ * resources including internally generated one may go into single
+ * dictionary referenced by @res, and will be visible from any
+ * subsequent pages.
+ */
+ pdf_foreach_dict(dict, safeputresdent, obj);
+ pdf_add_dict(res_dict, pdf_new_name(category), pdf_link_obj(vp));
+#endif
+ }
+ pdf_release_obj(obj);
+ }
+ }
+ break;
+ default:
+ WARN("Invalid object type for page resource specified for \"%s\"", category);
+ }
+
+ return r;
+}
+
+int
+spc_pdfm_at_end_page (void)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+
+ if (sd->pageresources) {
+ pdf_foreach_dict(sd->pageresources, forallresourcecategory, NULL);
+ }
+
+ return 0;
+}
+
+/* Dvipdfm specials */
+static int
+spc_handler_pdfm_bop (struct spc_env *spe, struct spc_arg *args)
+{
+ if (args->curptr < args->endptr) {
+ pdf_doc_set_bop_content(args->curptr,
+ (int) (args->endptr - args->curptr));
+ }
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_eop (struct spc_env *spe, struct spc_arg *args)
+{
+ if (args->curptr < args->endptr) {
+ pdf_doc_set_eop_content(args->curptr,
+ (int) (args->endptr - args->curptr));
+ }
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+#define streamfiltered(o) \
+ (pdf_lookup_dict(pdf_stream_dict((o)), "Filter") ? 1 : 0)
+
+/* Think what happens if you do
+ *
+ * pdf:put @resources << /Font << >> >>
+ *
+ */
+static int
+spc_handler_pdfm_put (struct spc_env *spe, struct spc_arg *ap)
+{
+ pdf_obj *obj1, *obj2; /* put obj2 into obj1 */
+ char *ident;
+ int error = 0;
+
+ skip_white(&ap->curptr, ap->endptr);
+
+ ident = parse_opt_ident(&ap->curptr, ap->endptr);
+ if (!ident) {
+ spc_warn(spe, "Missing object identifier.");
+ return -1;
+ }
+ obj1 = spc_lookup_object(ident);
+ if (!obj1) {
+ spc_warn(spe, "Specified object not exist: %s", ident);
+ RELEASE(ident);
+ return -1;
+ }
+ skip_white(&ap->curptr, ap->endptr);
+
+ obj2 = parse_pdf_object_extended(&ap->curptr, ap->endptr, NULL, parse_pdf_reference, spe);
+ if (!obj2) {
+ spc_warn(spe, "Missing (an) object(s) to put into \"%s\"!", ident);
+ RELEASE(ident);
+ return -1;
+ }
+
+ switch (pdf_obj_typeof(obj1)) {
+ case PDF_DICT:
+ if (pdf_obj_typeof(obj2) != PDF_DICT) {
+ spc_warn(spe, "Inconsistent object type for \"put\" (expecting DICT): %s", ident);
+ error = -1;
+ } else {
+ if (!strcmp(ident, "resources"))
+ error = pdf_foreach_dict(obj2, safeputresdict, obj1);
+ else {
+ pdf_merge_dict(obj1, obj2);
+ }
+ }
+ break;
+
+ case PDF_STREAM:
+ if (pdf_obj_typeof(obj2) == PDF_DICT)
+ pdf_merge_dict(pdf_stream_dict(obj1), obj2);
+ else if (pdf_obj_typeof(obj2) == PDF_STREAM)
+#if 0
+ {
+ pdf_merge_dict(pdf_stream_dict(obj1), pdf_stream_dict(obj2));
+ pdf_add_stream(obj1, pdf_stream_dataptr(obj2), pdf_stream_length(obj2));
+ }
+#else
+ {
+ spc_warn(spe, "\"put\" operation not supported for STREAM <- STREAM: %s", ident);
+ error = -1;
+ }
+#endif
+ else {
+ spc_warn(spe, "Invalid type: expecting a DICT or STREAM: %s", ident);
+ error = -1;
+ }
+ break;
+
+ case PDF_ARRAY:
+ /* dvipdfm */
+ pdf_add_array(obj1, pdf_link_obj(obj2));
+ while (ap->curptr < ap->endptr) {
+ pdf_obj *obj3 = parse_pdf_object_extended(&ap->curptr, ap->endptr, NULL, parse_pdf_reference, spe);
+ if (!obj3)
+ break;
+ pdf_add_array(obj1, obj3);
+ skip_white(&ap->curptr, ap->endptr);
+ }
+ break;
+
+ default:
+ spc_warn(spe, "Can't \"put\" object into non-DICT/STREAM/ARRAY type object: %s", ident);
+ error = -1;
+ break;
+ }
+ pdf_release_obj(obj2);
+ RELEASE(ident);
+
+ return error;
+}
+
+
+/* For pdf:tounicode support
+ * This feature is provided for convenience. TeX can't do
+ * input encoding conversion.
+ */
+#include "cmap.h"
+
+static size_t
+calculate_size_utf16 (const unsigned char *p, const unsigned char *endptr)
+{
+ size_t len = 0;
+
+ while (p < endptr) {
+ unsigned char c = *p;
+ if (c < 0x80) {
+ len += 2;
+ p += 1;
+ } else if (c < 0xE0) {
+ len += 2;
+ p += 2;
+ } else if (c < 0xF0) {
+ len += 2;
+ p += 3;
+ } else if (c < 0xF8) {
+ len += 4; /* Surrogate */
+ p += 4;
+ } else if (c < 0xFC) {
+ len += 4; /* Surrogate */
+ p += 5;
+ } else if (c < 0xFE) {
+ len += 4; /* Surrogate */
+ p += 6;
+ }
+ }
+
+ return len;
+}
+
+static int
+reencode_string_from_utf8_to_utf16be (pdf_obj *instring)
+{
+ int error = 0;
+ unsigned char *strptr;
+ size_t length;
+ int non_ascii;
+ const unsigned char *p, *endptr;
+
+ ASSERT(instring);
+ ASSERT(PDF_OBJ_STRINGTYPE(instring));
+
+ strptr = pdf_string_value(instring);
+ length = pdf_string_length(instring);
+
+ /* check if the input string is strictly ASCII */
+ p = strptr;
+ endptr = strptr + length;
+ non_ascii = 0;
+ for ( ; p < endptr; p++) {
+ if (*p > 127)
+ non_ascii++;
+ }
+ if (non_ascii == 0)
+ return 0; /* no need to reencode ASCII strings */
+
+ if (!UC_UTF8_is_valid_string(strptr, endptr)) {
+ error = -1;
+ } else {
+ unsigned char *q, *buf, *limptr;
+ size_t len;
+
+ p = strptr;
+ /* Rough estimate of output length. */
+ len = calculate_size_utf16(p, endptr) + 2;
+ buf = NEW(len, unsigned char);
+ q = buf;
+ limptr = buf + len;
+ q[0] = 0xfe; q[1] = 0xff;
+ q += 2;
+ while (p < endptr && q < limptr && !error) {
+ int32_t ucv;
+ size_t count;
+
+ ucv = UC_UTF8_decode_char(&p, endptr);
+ if (!UC_is_valid(ucv)) {
+ error = -1;
+ } else {
+ count = UC_UTF16BE_encode_char(ucv, &q, limptr);
+ if (count == 0) {
+ error = -1;
+ }
+ }
+ }
+ if (!error)
+ pdf_set_string(instring, buf, q - buf);
+ RELEASE(buf);
+ }
+
+ return error;
+}
+
+static int
+reencode_string (CMap *cmap, pdf_obj *instring)
+{
+ int error = 0;
+
+ if (!instring || !PDF_OBJ_STRINGTYPE(instring))
+ return -1;
+
+ if (cmap) {
+ unsigned char *obuf;
+ unsigned char *obufcur;
+ const unsigned char *inbufcur;
+ int inbufleft, obufleft, obufsize;
+
+ inbufleft = pdf_string_length(instring);
+ inbufcur = pdf_string_value (instring);
+
+ obufsize = inbufleft * 4 + 2;
+ obuf = NEW(obufsize, unsigned char);
+ obuf[0] = 0xfe;
+ obuf[1] = 0xff;
+ obufcur = obuf + 2;
+ obufleft = obufsize - 2;
+
+ CMap_decode(cmap, &inbufcur, &inbufleft, &obufcur, &obufleft);
+
+ if (inbufleft > 0)
+ error = -1;
+ if (!error)
+ pdf_set_string(instring, obuf, obufsize - obufleft);
+ RELEASE(obuf);
+ }
+
+ return error;
+}
+
+/* The purpose of this routine is to check if given string object is
+ * surely an object for *text* strings. It does not do a complete check
+ * but does a quick check. Please add entries for taintkeys if you have found
+ * additional dictionary entries which is considered as a text string.
+ */
+static int
+need_reencode (pdf_obj *kp, pdf_obj *vp, struct tounicode *cd)
+{
+ int r = 0, i;
+ pdf_obj *tk;
+
+ ASSERT( cd && cd->taintkeys );
+ ASSERT( pdf_obj_typeof(kp) == PDF_NAME );
+ ASSERT( pdf_obj_typeof(vp) == PDF_STRING );
+
+ for (i = 0; i < pdf_array_length(cd->taintkeys); i++) {
+ tk = pdf_get_array(cd->taintkeys, i);
+ ASSERT( tk && pdf_obj_typeof(tk) == PDF_NAME );
+ if (!strcmp(pdf_name_value(kp), pdf_name_value(tk))) {
+ r = 1;
+ break;
+ }
+ }
+ if (r) {
+ /* Check UTF-16BE BOM. */
+ if (pdf_string_length(vp) >= 2 &&
+ !memcmp(pdf_string_value(vp), "\xfe\xff", 2))
+ r = 0;
+ }
+
+ return r;
+}
+
+static int
+modify_strings (pdf_obj *kp, pdf_obj *vp, void *dp)
+{
+ int r = 0; /* continue */
+ struct tounicode *cd = dp;
+
+ ASSERT( pdf_obj_typeof(kp) == PDF_NAME );
+
+ switch (pdf_obj_typeof(vp)) {
+ case PDF_STRING:
+ if (cd && cd->cmap_id >= 0 && cd->taintkeys) {
+ CMap *cmap = CMap_cache_get(cd->cmap_id);
+ if (need_reencode(kp, vp, cd))
+ r = reencode_string(cmap, vp);
+ } else if ((dpx_conf.compat_mode == dpx_mode_xdv_mode) && cd && cd->taintkeys) {
+ if (need_reencode(kp, vp, cd))
+ r = reencode_string_from_utf8_to_utf16be(vp);
+ }
+ if (r < 0) /* error occured... */
+ WARN("Input string conversion (to UTF16BE) failed for %s...", pdf_name_value(kp));
+ break;
+ /* Array elements are also checked. */
+ case PDF_ARRAY:
+ {
+ int i;
+ for (i = 0; i < pdf_array_length(vp); i++) {
+ pdf_obj *obj;
+ obj = pdf_get_array(vp, i);
+ r = modify_strings(kp, obj, dp);
+ if (r < 0)
+ break;
+ }
+ }
+ break;
+ case PDF_DICT:
+ r = pdf_foreach_dict(vp, modify_strings, dp);
+ break;
+ case PDF_STREAM:
+ r = pdf_foreach_dict(pdf_stream_dict(vp), modify_strings, dp);
+ break;
+ }
+
+ return r;
+}
+
+static pdf_obj *
+parse_pdf_dict_with_tounicode (const char **pp, const char *endptr, struct tounicode *cd)
+{
+ pdf_obj *dict;
+
+ /* disable this test for XDV files, as we do UTF8 reencoding with no cmap */
+ if ((dpx_conf.compat_mode != dpx_mode_xdv_mode) && cd->cmap_id < 0) {
+ dict = parse_pdf_object_extended(pp, endptr, NULL, parse_pdf_reference, NULL);
+ if (dict && !PDF_OBJ_DICTTYPE(dict)) {
+ WARN("Dictionary type object expected but non-dictionary type found.");
+ pdf_release_obj(dict);
+ dict = NULL;
+ }
+ } else {
+ /* :( */
+ if (cd && cd->unescape_backslash) {
+ dict = parse_pdf_tainted_dict(pp, endptr, parse_pdf_reference, NULL);
+ } else {
+ dict = parse_pdf_object_extended(pp, endptr, NULL, parse_pdf_reference, NULL);
+ }
+ if (dict) {
+ if (!PDF_OBJ_DICTTYPE(dict)) {
+ WARN("Dictionary type object expected but non-dictionary type found.");
+ pdf_release_obj(dict);
+ dict = NULL;
+ } else {
+ pdf_foreach_dict(dict, modify_strings, cd);
+ }
+ }
+ }
+
+ return dict;
+}
+
+static void
+set_rect_for_annot (struct spc_env *spe, pdf_rect *rect, transform_info ti)
+{
+ pdf_coord cp, cp1, cp2, cp3, cp4;
+
+ spc_get_current_point(spe, &cp);
+
+ if (ti.flags & INFO_HAS_USER_BBOX) {
+ cp1.x = cp.x + ti.bbox.llx;
+ cp1.y = cp.y + ti.bbox.lly;
+ cp2.x = cp.x + ti.bbox.urx;
+ cp2.y = cp.y + ti.bbox.lly;
+ cp3.x = cp.x + ti.bbox.urx;
+ cp3.y = cp.y + ti.bbox.ury;
+ cp4.x = cp.x + ti.bbox.llx;
+ cp4.y = cp.y + ti.bbox.ury;
+ } else {
+ cp1.x = cp.x;
+ cp1.y = cp.y - spe->mag * ti.depth;
+ cp2.x = cp.x + spe->mag * ti.width;
+ cp2.y = cp.y - spe->mag * ti.depth;
+ cp3.x = cp.x + spe->mag * ti.width;
+ cp3.y = cp.y + spe->mag * ti.height;
+ cp4.x = cp.x;
+ cp4.y = cp.y + spe->mag * ti.height;
+ }
+ pdf_dev_transform(&cp1, NULL);
+ pdf_dev_transform(&cp2, NULL);
+ pdf_dev_transform(&cp3, NULL);
+ pdf_dev_transform(&cp4, NULL);
+ rect->llx = min4(cp1.x, cp2.x, cp3.x, cp4.x);
+ rect->lly = min4(cp1.y, cp2.y, cp3.y, cp4.y);
+ rect->urx = max4(cp1.x, cp2.x, cp3.x, cp4.x);
+ rect->ury = max4(cp1.y, cp2.y, cp3.y, cp4.y);
+}
+
+static int
+spc_handler_pdfm_annot (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ pdf_obj *annot_dict;
+ pdf_rect rect;
+ char *ident = NULL;
+ transform_info ti;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr[0] == '@') {
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ transform_info_clear(&ti);
+ if (spc_util_read_dimtrns(spe, &ti, args, 0) < 0) {
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ }
+
+ if ((ti.flags & INFO_HAS_USER_BBOX) &&
+ ((ti.flags & INFO_HAS_WIDTH) || (ti.flags & INFO_HAS_HEIGHT))) {
+ spc_warn(spe, "You can't specify both bbox and width/height.");
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ }
+
+ annot_dict = parse_pdf_dict_with_tounicode(&args->curptr, args->endptr, &sd->cd);
+ if (!annot_dict) {
+ spc_warn(spe, "Could not find dictionary object.");
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ } else if (!PDF_OBJ_DICTTYPE(annot_dict)) {
+ spc_warn(spe, "Invalid type: not dictionary object.");
+ if (ident)
+ RELEASE(ident);
+ pdf_release_obj(annot_dict);
+ return -1;
+ }
+
+ set_rect_for_annot(spe, &rect, ti);
+
+ /* Order is important... */
+ if (ident)
+ spc_push_object(spe, ident, pdf_link_obj(annot_dict));
+ /* Add this reference. */
+ pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict, 1);
+
+ if (ident) {
+ RELEASE(ident);
+ }
+ pdf_release_obj(annot_dict);
+
+ return 0;
+}
+
+/* NOTE: This can't have ident. See "Dvipdfm User's Manual".
+ * 1 Jul. 2020: ident allowed (upon request)
+ * Only first annotation can be accessed in line break cases.
+ */
+static int
+spc_handler_pdfm_bann (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ char *ident = NULL;
+ int error = 0;
+
+ if (sd->annot_dict) {
+ spc_warn(spe, "Can't begin an annotation when one is pending.");
+ return -1;
+ }
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr[0] == '@') {
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ sd->annot_dict = parse_pdf_dict_with_tounicode(&args->curptr, args->endptr, &sd->cd);
+ if (!sd->annot_dict) {
+ spc_warn(spe, "Ignoring annotation with invalid dictionary.");
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ } else if (!PDF_OBJ_DICTTYPE(sd->annot_dict)) {
+ spc_warn(spe, "Invalid type: not a dictionary object.");
+ pdf_release_obj(sd->annot_dict);
+ sd->annot_dict = NULL;
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ }
+
+ error = spc_begin_annot(spe, pdf_link_obj(sd->annot_dict));
+ if (ident) {
+ spc_push_object(spe, ident, pdf_link_obj(sd->annot_dict));
+ RELEASE(ident);
+ }
+
+ return error;
+}
+
+static int
+spc_handler_pdfm_eann (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ int error = 0;
+
+ if (!sd->annot_dict) {
+ spc_warn(spe, "Tried to end an annotation without starting one!");
+ return -1;
+ }
+
+ error = spc_end_annot(spe);
+
+ pdf_release_obj(sd->annot_dict);
+ sd->annot_dict = NULL;
+
+ return error;
+}
+
+/* For supporting \phantom within bann-eann.
+ *
+ * \special{pdf:xann width 50pt height 8pt depth 1pt}
+ *
+ * tells dvipdfmx to extend the current annotation rectangle
+ * by the amount specified (witdh 50pt, height 8pt, depth 1pt)
+ * This was introduced since in the following situation
+ *
+ * \special{pdf:bann ...}\phantom{Some texts}\special{pdf:eann}
+ *
+ * annotation is not created since there is no annotation
+ * rectangle calculated due to no object being put.
+ */
+static int
+spc_handler_pdfm_xann (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_rect rect;
+ transform_info ti;
+
+ if (!spc_is_tracking_boxes(spe)) {
+ /* Silently ignore */
+ args->curptr = args->endptr;
+ return 0;
+ }
+
+ skip_white(&args->curptr, args->endptr);
+
+ transform_info_clear(&ti);
+ if (spc_util_read_dimtrns(spe, &ti, args, 0) < 0) {
+ return -1;
+ }
+
+ if ((ti.flags & INFO_HAS_USER_BBOX) &&
+ ((ti.flags & INFO_HAS_WIDTH) || (ti.flags & INFO_HAS_HEIGHT))) {
+ spc_warn(spe, "You can't specify both bbox and width/height.");
+ return -1;
+ }
+
+ set_rect_for_annot(spe, &rect, ti);
+ pdf_doc_expand_box(&rect);
+
+ return 0;
+}
+
+/* Color:.... */
+static int
+spc_handler_pdfm_bcolor (struct spc_env *spe, struct spc_arg *ap)
+{
+ int error = 0;
+ pdf_color fc, sc;
+ pdf_color *pfc, *psc;
+
+ skip_white(&ap->curptr, ap->endptr);
+
+ pdf_color_get_current(&psc, &pfc);
+ if (ap->curptr < ap->endptr &&
+ (ap->curptr[0] == 'f' || ap->curptr[0] == 's')) {
+ pdf_color_copycolor(&sc, psc);
+ pdf_color_copycolor(&fc, pfc);
+ while (!error && ap->curptr < ap->endptr) {
+ if (ap->curptr <= ap->endptr + strlen("fill") &&
+ !memcmp(ap->curptr, "fill", strlen("fill"))) {
+ ap->curptr += strlen("fill");
+ skip_white(&ap->curptr, ap->endptr);
+ error = spc_util_read_pdfcolor(spe, &fc, ap, pfc);
+ } else if (ap->curptr <= ap->endptr + strlen("stroke") &&
+ !memcmp(ap->curptr, "stroke", strlen("stroke"))) {
+ ap->curptr += strlen("stroke");
+ skip_white(&ap->curptr, ap->endptr);
+ error = spc_util_read_pdfcolor(spe, &sc, ap, psc);
+ }
+ skip_white(&ap->curptr, ap->endptr);
+ }
+ } else {
+ error = spc_util_read_pdfcolor(spe, &fc, ap, pfc);
+ if (!error) {
+ if (ap->curptr < ap->endptr) {
+ error = spc_util_read_pdfcolor(spe, &sc, ap, psc);
+ } else {
+ pdf_color_copycolor(&sc, &fc);
+ }
+ }
+ }
+
+ if (error) {
+ spc_warn(spe, "Invalid color specification?");
+ } else {
+ skip_white(&ap->curptr, ap->endptr);
+ pdf_color_push(&sc, &fc); /* save currentcolor */
+ }
+
+ return error;
+}
+
+/*
+ * This special changes the current color without clearing the color stack.
+ * It therefore differs from "color rgb 1 0 0".
+ */
+static int
+spc_handler_pdfm_scolor (struct spc_env *spe, struct spc_arg *ap)
+{
+ int error = 0;
+ pdf_color fc, sc;
+ pdf_color *pfc, *psc;
+
+ skip_white(&ap->curptr, ap->endptr);
+
+ pdf_color_get_current(&psc, &pfc);
+ if (ap->curptr < ap->endptr &&
+ (ap->curptr[0] == 'f' || ap->curptr[0] == 's')) {
+ pdf_color_copycolor(&sc, psc);
+ pdf_color_copycolor(&fc, pfc);
+ while (!error && ap->curptr < ap->endptr) {
+ if (ap->curptr <= ap->endptr + strlen("fill") &&
+ !memcmp(ap->curptr, "fill", strlen("fill"))) {
+ ap->curptr += strlen("fill");
+ skip_white(&ap->curptr, ap->endptr);
+ error = spc_util_read_pdfcolor(spe, &fc, ap, pfc);
+ } else if (ap->curptr <= ap->endptr + strlen("stroke") &&
+ !memcmp(ap->curptr, "stroke", strlen("stroke"))) {
+ ap->curptr += strlen("stroke");
+ skip_white(&ap->curptr, ap->endptr);
+ error = spc_util_read_pdfcolor(spe, &sc, ap, psc);
+ }
+ skip_white(&ap->curptr, ap->endptr);
+ }
+ } else {
+ error = spc_util_read_pdfcolor(spe, &fc, ap, pfc);
+ if (!error) {
+ if (ap->curptr < ap->endptr) {
+ error = spc_util_read_pdfcolor(spe, &sc, ap, psc);
+ } else {
+ pdf_color_copycolor(&sc, &fc);
+ }
+ }
+ }
+
+ if (error) {
+ spc_warn(spe, "Invalid color specification?");
+ } else {
+ pdf_color_set(&sc, &fc);
+ }
+
+ return error;
+}
+
+static int
+spc_handler_pdfm_ecolor (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_color_pop();
+ return 0;
+}
+
+
+static int
+spc_handler_pdfm_btrans (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_tmatrix M;
+ pdf_coord cp;
+ transform_info ti;
+
+ transform_info_clear(&ti);
+ if (spc_util_read_dimtrns(spe, &ti, args, 0) < 0) {
+ return -1;
+ }
+
+ /* btrans inside bcontent-econtent bug fix.
+ * I don't know if this is the only place needs to be fixed...
+ */
+ spc_get_current_point(spe, &cp);
+ /* Create transformation matrix */
+ pdf_copymatrix(&M, &(ti.matrix));
+ M.e += ((1.0 - M.a) * cp.x - M.c * cp.y);
+ M.f += ((1.0 - M.d) * cp.y - M.b * cp.x);
+
+ pdf_dev_gsave();
+ pdf_dev_concat(&M);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_etrans (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_dev_grestore();
+
+ /*
+ * Unfortunately, the following line is necessary in case
+ * of a color change inside of the save/restore pair.
+ * (Font changes are automatically corrected by pdf_dev_grestore().)
+ * Anything that was done there must be redone, so in effect,
+ * we make no assumptions about what fonts. We act like we are
+ * starting a new page.
+ */
+ pdf_dev_reset_color(0);
+ pdf_dev_reset_xgstate(0);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_outline (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ pdf_obj *item_dict, *tmp;
+ int level, is_open = -1;
+ int current_depth;
+
+ skip_white(&args->curptr, args->endptr);
+
+ /*
+ * pdf:outline is extended to support open/close feature
+ *
+ * pdf:outline 1 ... (as DVIPDFM)
+ * pdf:outline [] 1 ... (open bookmark)
+ * pdf:outline [-] 1 ... (closed bookmark)
+ */
+ if (args->curptr+3 < args->endptr && *args->curptr == '[') {
+ args->curptr++;
+ if (*args->curptr == '-') {
+ args->curptr++;
+ } else {
+ is_open = 1;
+ }
+ args->curptr++;
+ }
+ skip_white(&args->curptr, args->endptr);
+
+ tmp = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ if (!tmp) {
+ spc_warn(spe, "Missing number for outline item depth.");
+ return -1;
+ } else if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ pdf_release_obj(tmp);
+ spc_warn(spe, "Expecting number for outline item depth.");
+ return -1;
+ }
+
+ item_dict = NULL;
+
+ level = (int) pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+
+ /* What is this? Starting at level 3 and can go down to level 1?
+ *
+ * Here is the original comment:
+ * Make sure we know where the starting level is
+ *
+ * NOTE: added
+ * We need this for converting pages from 3rd to... :(
+ */
+ sd->lowest_level = MIN(sd->lowest_level, level);
+
+ level += 1 - sd->lowest_level;
+
+ item_dict = parse_pdf_dict_with_tounicode(&args->curptr, args->endptr, &sd->cd);
+ if (!item_dict) {
+ spc_warn(spe, "Ignoring invalid dictionary.");
+ return -1;
+ }
+ current_depth = pdf_doc_bookmarks_depth();
+ if (current_depth > level) {
+ while (current_depth-- > level)
+ pdf_doc_bookmarks_up();
+ } else if (current_depth < level) {
+ while (current_depth++ < level)
+ pdf_doc_bookmarks_down();
+ }
+
+ pdf_doc_bookmarks_add(item_dict, is_open);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_article (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ char *ident;
+ pdf_obj *info_dict;
+
+ skip_white (&args->curptr, args->endptr);
+
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ if (!ident) {
+ spc_warn(spe, "Article name expected but not found.");
+ return -1;
+ }
+
+ info_dict = parse_pdf_dict_with_tounicode(&args->curptr, args->endptr, &sd->cd);
+ if (!info_dict) {
+ spc_warn(spe, "Ignoring article with invalid info dictionary.");
+ RELEASE(ident);
+ return -1;
+ }
+
+ pdf_doc_begin_article(ident, pdf_link_obj(info_dict));
+ spc_push_object(spe, ident, info_dict);
+ RELEASE(ident);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_bead (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ pdf_obj *article;
+ pdf_obj *article_info;
+ char *article_name;
+ pdf_rect rect;
+ int page_no;
+ transform_info ti;
+
+ skip_white(&args->curptr, args->endptr);
+
+ if (args->curptr[0] != '@') {
+ spc_warn(spe, "Article identifier expected but not found.");
+ return -1;
+ }
+
+ article_name = parse_opt_ident(&args->curptr, args->endptr);
+ if (!article_name) {
+ spc_warn(spe, "Article reference expected but not found.");
+ return -1;
+ }
+
+ /* If okay so far, try to get a bounding box */
+ transform_info_clear(&ti);
+ if (spc_util_read_dimtrns(spe, &ti, args, 0) < 0) {
+ RELEASE(article_name);
+ return -1;
+ }
+
+ if ((ti.flags & INFO_HAS_USER_BBOX) &&
+ ((ti.flags & INFO_HAS_WIDTH) || (ti.flags & INFO_HAS_HEIGHT))) {
+ spc_warn(spe, "You can't specify both bbox and width/height.");
+ RELEASE(article_name);
+ return -1;
+ }
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr[0] != '<') {
+ article_info = pdf_new_dict();
+ } else {
+ article_info = parse_pdf_dict_with_tounicode(&args->curptr, args->endptr, &sd->cd);
+ if (!article_info) {
+ spc_warn(spe, "Error in reading dictionary.");
+ RELEASE(article_name);
+ return -1;
+ }
+ }
+
+ /* Does this article exist yet */
+ article = spc_lookup_object(article_name);
+ if (article) {
+ pdf_merge_dict (article, article_info);
+ pdf_release_obj(article_info);
+ } else {
+ pdf_doc_begin_article(article_name, pdf_link_obj(article_info));
+ spc_push_object(spe, article_name, article_info);
+ }
+ page_no = pdf_doc_current_page_number();
+ set_rect_for_annot(spe, &rect, ti);
+ pdf_doc_add_bead(article_name, NULL, page_no, &rect);
+
+ RELEASE(article_name);
+ return 0;
+}
+
+static int
+spc_handler_pdfm_image (struct spc_env *spe, struct spc_arg *args)
+{
+ int xobj_id;
+ char *ident = NULL;
+ pdf_obj *fspec;
+ transform_info ti;
+ load_options options = {1, 0, NULL};
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr[0] == '@') {
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ /* 2015/12/29
+ * There should not be "page" and "pagebox" in read_dimtrns().
+ * It is for reading "dimensions" and "transformations" and "page" is
+ * completely unrelated.
+ */
+ transform_info_clear(&ti);
+ if (spc_util_read_blahblah(spe, &ti,
+ &options.page_no, &options.bbox_type, args) < 0) {
+ spc_warn(spe, "Reading option field in pdf:image failed.");
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ }
+
+ skip_white(&args->curptr, args->endptr);
+ fspec = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ if (!fspec) {
+ spc_warn(spe, "Missing filename string for pdf:image.");
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ } else if (!PDF_OBJ_STRINGTYPE(fspec)) {
+ spc_warn(spe, "Missing filename string for pdf:image.");
+ pdf_release_obj(fspec);
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ }
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+ options.dict = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ }
+
+ xobj_id = pdf_ximage_load_image(ident, pdf_string_value(fspec), options);
+
+ if (xobj_id < 0) {
+ spc_warn(spe, "Could not find image resource...");
+ pdf_release_obj(fspec);
+ if (ident)
+ RELEASE(ident);
+ return -1;
+ }
+
+ if (!(ti.flags & INFO_DO_HIDE)) {
+ spc_put_image(spe, xobj_id, &ti, spe->x_user, spe->y_user);
+ }
+
+ if (ident) {
+ if ((dpx_conf.compat_mode == dpx_mode_compat_mode) &&
+ pdf_ximage_get_subtype(xobj_id) == PDF_XOBJECT_TYPE_IMAGE)
+ pdf_ximage_set_attr(xobj_id, 1, 1, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0);
+ RELEASE(ident);
+ }
+
+ pdf_release_obj(fspec);
+
+ return 0;
+}
+
+/* Use do_names instead. */
+static int
+spc_handler_pdfm_dest (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_obj *name, *array;
+
+ skip_white(&args->curptr, args->endptr);
+
+ name = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ if (!name) {
+ spc_warn(spe, "PDF string expected for destination name but not found.");
+ return -1;
+ } else if (!PDF_OBJ_STRINGTYPE(name)) {
+ spc_warn(spe, "PDF string expected for destination name but invalid type.");
+ pdf_release_obj(name);
+ return -1;
+ }
+
+#if 0
+ if ((dpx_conf.compat_mode == dpx_mode_xdv_mode) && maybe_reencode_utf8(name) < 0)
+ WARN("Failed to convert input string to UTF16...");
+#endif
+
+ array = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!array) {
+ spc_warn(spe, "No destination specified for pdf:dest.");
+ pdf_release_obj(name);
+ return -1;
+ } else if (!PDF_OBJ_ARRAYTYPE(array)) {
+ spc_warn(spe, "Destination not specified as an array object!");
+ pdf_release_obj(name);
+ pdf_release_obj(array);
+ return -1;
+ }
+
+ pdf_doc_add_names("Dests",
+ pdf_string_value (name),
+ pdf_string_length(name),
+ array);
+ pdf_release_obj(name);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_names (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_obj *category, *key, *value, *tmp;
+ int i, size;
+
+ category = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ if (!category) {
+ spc_warn(spe, "PDF name expected but not found.");
+ return -1;
+ } else if (!PDF_OBJ_NAMETYPE(category)) {
+ spc_warn(spe, "PDF name expected but not found.");
+ pdf_release_obj(category);
+ return -1;
+ }
+
+ tmp = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!tmp) {
+ spc_warn(spe, "PDF object expected but not found.");
+ pdf_release_obj(category);
+ return -1;
+ } else if (PDF_OBJ_ARRAYTYPE(tmp)) {
+ size = pdf_array_length(tmp);
+ if (size % 2 != 0) {
+ spc_warn(spe, "Array size not multiple of 2 for pdf:names.");
+ pdf_release_obj(category);
+ pdf_release_obj(tmp);
+ return -1;
+ }
+
+ for (i = 0; i < size / 2; i++) {
+ key = pdf_get_array(tmp, 2 * i);
+ value = pdf_get_array(tmp, 2 * i + 1);
+ if (!PDF_OBJ_STRINGTYPE(key)) {
+ spc_warn(spe, "Name tree key must be string.");
+ pdf_release_obj(category);
+ pdf_release_obj(tmp);
+ return -1;
+ } else if (pdf_doc_add_names(pdf_name_value(category),
+ pdf_string_value (key),
+ pdf_string_length(key),
+ pdf_link_obj(value)) < 0) {
+ spc_warn(spe, "Failed to add Name tree entry...");
+ pdf_release_obj(category);
+ pdf_release_obj(tmp);
+ return -1;
+ }
+ }
+ pdf_release_obj(tmp);
+ } else if (PDF_OBJ_STRINGTYPE(tmp)) {
+ key = tmp;
+ value = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!value) {
+ pdf_release_obj(category);
+ pdf_release_obj(key);
+ spc_warn(spe, "PDF object expected but not found.");
+ return -1;
+ }
+ if (pdf_doc_add_names(pdf_name_value(category),
+ pdf_string_value (key),
+ pdf_string_length(key),
+ value) < 0) {
+ spc_warn(spe, "Failed to add Name tree entry...");
+ pdf_release_obj(category);
+ pdf_release_obj(key);
+ return -1;
+ }
+ pdf_release_obj(key);
+ } else {
+ pdf_release_obj(tmp);
+ pdf_release_obj(category);
+ spc_warn(spe, "Invalid object type for pdf:names.");
+ return -1;
+ }
+ pdf_release_obj(category);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_docinfo (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ pdf_obj *docinfo, *dict;
+
+ dict = parse_pdf_dict_with_tounicode(&args->curptr, args->endptr, &sd->cd);
+ if (!dict) {
+ spc_warn(spe, "Dictionary object expected but not found.");
+ return -1;
+ }
+
+ docinfo = pdf_doc_docinfo();
+ pdf_merge_dict(docinfo, dict);
+ pdf_release_obj(dict);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_docview (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ pdf_obj *catalog, *dict;
+ pdf_obj *pref_old, *pref_add;
+
+ dict = parse_pdf_dict_with_tounicode(&args->curptr, args->endptr, &sd->cd);
+ if (!dict) {
+ spc_warn(spe, "Dictionary object expected but not found.");
+ return -1;
+ }
+
+ catalog = pdf_doc_catalog();
+ /* Avoid overriding whole ViewerPreferences */
+ pref_old = pdf_lookup_dict(catalog, "ViewerPreferences");
+ pref_add = pdf_lookup_dict(dict, "ViewerPreferences");
+ if (pref_old && pref_add) {
+ pdf_merge_dict (pref_old, pref_add);
+ pdf_remove_dict(dict, "ViewerPreferences");
+ }
+ pdf_merge_dict (catalog, dict);
+ pdf_release_obj(dict);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_close (struct spc_env *spe, struct spc_arg *args)
+{
+ char *ident;
+
+ skip_white(&args->curptr, args->endptr);
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ if (ident) {
+ spc_flush_object(spe, ident);
+ RELEASE(ident);
+ } else { /* Close all? */
+ spc_warn(spe, "pdf:close without an argument no longer supported!");
+ spc_clear_objects(spe);
+ }
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_object (struct spc_env *spe, struct spc_arg *args)
+{
+ char *ident;
+ pdf_obj *object;
+
+ skip_white(&args->curptr, args->endptr);
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ if (!ident) {
+ spc_warn(spe, "Could not find a object identifier.");
+ return -1;
+ }
+
+ object = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!object) {
+ spc_warn(spe, "Could not find an object definition for \"%s\".", ident);
+ RELEASE(ident);
+ return -1;
+ } else {
+ spc_push_object(spe, ident, object);
+ }
+ RELEASE(ident);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_content (struct spc_env *spe, struct spc_arg *args)
+{
+ int len = 0;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+ pdf_tmatrix M;
+ pdf_coord cp;
+
+ spc_get_current_point(spe, &cp);
+ pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, cp.x, cp.y);
+ work_buffer[len++] = ' ';
+ work_buffer[len++] = 'q';
+ work_buffer[len++] = ' ';
+ len += pdf_sprint_matrix(work_buffer + len, &M);
+ work_buffer[len++] = ' ';
+ work_buffer[len++] = 'c';
+ work_buffer[len++] = 'm';
+ work_buffer[len++] = ' ';
+
+ pdf_doc_add_page_content(work_buffer, len); /* op: q cm */
+ len = (int) (args->endptr - args->curptr);
+ pdf_doc_add_page_content(args->curptr, len); /* op: ANY */
+ pdf_doc_add_page_content(" Q", 2); /* op: Q */
+ }
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_literal (struct spc_env *spe, struct spc_arg *args)
+{
+ int direct = 0;
+
+ skip_white(&args->curptr, args->endptr);
+ while (args->curptr < args->endptr) {
+ if (args->curptr + 7 <= args->endptr &&
+ !strncmp(args->curptr, "reverse", 7)) {
+ args->curptr += 7;
+ WARN("The special \"pdf:literal reverse ...\" is no longer supported.\nIgnore the \"reverse\" option.");
+ } else if (args->curptr + 6 <= args->endptr &&
+ !strncmp(args->curptr, "direct", 6)) {
+ direct = 1;
+ args->curptr += 6;
+ } else {
+ break;
+ }
+ skip_white(&args->curptr, args->endptr);
+ }
+
+ if (args->curptr < args->endptr) {
+ pdf_tmatrix M;
+ pdf_coord cp;
+
+ spc_get_current_point(spe, &cp);
+ if (!direct) {
+ M.a = M.d = 1.0; M.b = M.c = 0.0;
+ M.e = cp.x; M.f = cp.y;
+ pdf_dev_concat(&M);
+ }
+ pdf_doc_add_page_content(" ", 1); /* op: */
+ pdf_doc_add_page_content(args->curptr, (int) (args->endptr - args->curptr)); /* op: ANY */
+ if (!direct) {
+ M.e = -cp.x; M.f = -cp.y;
+ pdf_dev_concat(&M);
+ }
+ }
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_bcontent (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_tmatrix M;
+ double xpos, ypos;
+
+ pdf_dev_gsave();
+ spc_get_coord(spe, &xpos, &ypos);
+ pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user - xpos, spe->y_user - ypos);
+ pdf_dev_concat(&M);
+ spc_push_coord(spe, spe->x_user, spe->y_user);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_econtent (struct spc_env *spe, struct spc_arg *args)
+{
+ spc_pop_coord(spe);
+ pdf_dev_grestore();
+ pdf_dev_reset_color(0);
+ pdf_dev_reset_xgstate(0);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_code (struct spc_env *spe, struct spc_arg *args)
+{
+ skip_white(&args->curptr, args->endptr);
+
+ if (args->curptr < args->endptr) {
+ pdf_doc_add_page_content(" ", 1); /* op: */
+ pdf_doc_add_page_content(args->curptr, (int) (args->endptr - args->curptr)); /* op: ANY */
+ args->curptr = args->endptr;
+ }
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_do_nothing (struct spc_env *spe, struct spc_arg *args)
+{
+ args->curptr = args->endptr;
+ return 0;
+}
+
+#define STRING_STREAM 0
+#define FILE_STREAM 1
+
+static int
+spc_handler_pdfm_stream_with_type (struct spc_env *spe, struct spc_arg *args, int type)
+{
+ pdf_obj *fstream;
+ int nb_read;
+ char *ident, *instring, *fullname;
+ pdf_obj *tmp;
+ FILE *fp;
+
+ skip_white(&args->curptr, args->endptr);
+
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ if (!ident) {
+ spc_warn(spe, "Missing objname for pdf:(f)stream.");
+ return -1;
+ }
+
+ skip_white(&args->curptr, args->endptr);
+
+ tmp = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ if (!tmp) {
+ spc_warn(spe, "Missing input string for pdf:(f)stream.");
+ RELEASE(ident);
+ return -1;
+ } else if (!PDF_OBJ_STRINGTYPE(tmp)) {
+ spc_warn(spe, "Invalid type of input string for pdf:(f)stream.");
+ pdf_release_obj(tmp);
+ RELEASE(ident);
+ return -1;
+ }
+
+ instring = pdf_string_value(tmp);
+
+ switch (type) {
+ case FILE_STREAM:
+ if (!instring) {
+ spc_warn(spe, "Missing filename for pdf:fstream.");
+ pdf_release_obj(tmp);
+ RELEASE(ident);
+ return -1;
+ }
+ fullname = kpse_find_pict(instring);
+ if (!fullname) {
+ spc_warn(spe, "File \"%s\" not found.", instring);
+ pdf_release_obj(tmp);
+ RELEASE(ident);
+ return -1;
+ }
+ fp = DPXFOPEN(fullname, DPX_RES_TYPE_BINARY);
+ if (!fp) {
+ spc_warn(spe, "Could not open file: %s", instring);
+ pdf_release_obj(tmp);
+ RELEASE(ident);
+ RELEASE(fullname);
+ return -1;
+ }
+ fstream = pdf_new_stream(STREAM_COMPRESS);
+ while ((nb_read =
+ fread(work_buffer, sizeof(char), WORK_BUFFER_SIZE, fp)) > 0)
+ pdf_add_stream(fstream, work_buffer, nb_read);
+ MFCLOSE(fp);
+ RELEASE(fullname);
+ break;
+ case STRING_STREAM:
+ fstream = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_stream(fstream, pdf_string_value(tmp), pdf_string_length(tmp));
+ break;
+ default:
+ pdf_release_obj(tmp);
+ RELEASE(ident);
+ return -1;
+ }
+ pdf_release_obj(tmp);
+
+ /*
+ * Optional dict.
+ *
+ * TODO: check Length, Filter...
+ */
+ skip_white(&args->curptr, args->endptr);
+
+ if (args->curptr[0] == '<') {
+ pdf_obj *stream_dict;
+
+ stream_dict = pdf_stream_dict(fstream);
+
+ tmp = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!tmp) {
+ spc_warn(spe, "Parsing dictionary failed.");
+ pdf_release_obj(fstream);
+ RELEASE(ident);
+ return -1;
+ } else if (!PDF_OBJ_DICTTYPE(tmp)) {
+ spc_warn(spe, "Expecting dictionary type object but non-dictionary type found.");
+ pdf_release_obj(fstream);
+ pdf_release_obj(tmp);
+ RELEASE(ident);
+ return -1;
+ }
+ if (pdf_lookup_dict(tmp, "Length")) {
+ pdf_remove_dict(tmp, "Length");
+ } else if (pdf_lookup_dict(tmp, "Filter")) {
+ pdf_remove_dict(tmp, "Filter");
+ }
+ pdf_merge_dict(stream_dict, tmp);
+ pdf_release_obj(tmp);
+ }
+
+ /* Users should explicitly close this. */
+ spc_push_object(spe, ident, fstream);
+ RELEASE(ident);
+
+ return 0;
+}
+
+/*
+ * STREAM: Create a PDF stream object from an input string.
+ *
+ * pdf: stream @objname (input_string) [PDF_DICT]
+ */
+static int
+spc_handler_pdfm_stream (struct spc_env *spe, struct spc_arg *args)
+{
+ return spc_handler_pdfm_stream_with_type (spe, args, STRING_STREAM);
+}
+
+/*
+ * FSTREAM: Create a PDF stream object from an existing file.
+ *
+ * pdf: fstream @objname (filename) [PDF_DICT]
+ */
+static int
+spc_handler_pdfm_fstream (struct spc_env *spe, struct spc_arg *args)
+{
+ return spc_handler_pdfm_stream_with_type (spe, args, FILE_STREAM);
+}
+
+/* Grab page content as follows:
+ *
+ * Reference point = (x_user, y_user)
+ *
+ * Case 1. \special{pdf:bxobj @obj width WD height HT depth DP}
+ *
+ * Grab the box with the lower-left corner (x_user, y_user-DP)
+ * and the upper right corner (x_user+WD, y_user+HT).
+ *
+ * Case 2. \special{pdf:bxobj @obj bbox LLX LLY URX, URY}
+ *
+ * Grab the box with the lower-left corner (x_user+LLX, y_user+LLY)
+ * and the upper right corner (x_user+URX, y_user+URY).
+ *
+ * Note that scale, xscale, yscale, xoffset, yoffset options are ignored.
+ */
+static int
+spc_handler_pdfm_bform (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ char *ident;
+ pdf_rect cropbox;
+ pdf_coord cp;
+ transform_info ti;
+
+ skip_white(&args->curptr, args->endptr);
+
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ if (!ident) {
+ spc_warn(spe, "A form XObject must have name.");
+ return -1;
+ }
+
+ transform_info_clear(&ti);
+ if (spc_util_read_dimtrns(spe, &ti, args, 0) < 0) {
+ RELEASE(ident);
+ return -1;
+ }
+
+ /* A XForm with zero dimension results in a non-invertible transformation
+ * matrix. And it may result in unpredictable behaviour. It might be an
+ * error in Acrobat. Bounding box with zero dimension may cause division
+ * by zero.
+ */
+ if (ti.flags & INFO_HAS_USER_BBOX) {
+ if (ti.bbox.urx - ti.bbox.llx == 0.0 ||
+ ti.bbox.ury - ti.bbox.lly == 0.0) {
+ spc_warn(spe, "Bounding box has a zero dimension.");
+ RELEASE(ident);
+ return -1;
+ }
+ cropbox.llx = ti.bbox.llx;
+ cropbox.lly = ti.bbox.lly;
+ cropbox.urx = ti.bbox.urx;
+ cropbox.ury = ti.bbox.ury;
+ } else {
+ if (ti.width == 0.0 ||
+ ti.depth + ti.height == 0.0) {
+ spc_warn(spe, "Bounding box has a zero dimension.");
+ RELEASE(ident);
+ return -1;
+ }
+ cropbox.llx = 0.0;
+ cropbox.lly = -ti.depth;
+ cropbox.urx = ti.width;
+ cropbox.ury = ti.height;
+ }
+
+ spc_get_current_point(spe, &cp);
+ error = spc_begin_form(spe, ident, cp, &cropbox);
+
+ if (error)
+ spc_warn(spe, "Couldn't start form object.");
+
+ RELEASE(ident);
+
+ return error;
+}
+
+/* An extra dictionary after exobj must be merged to the form dictionary,
+ * not resource dictionary.
+ * Please use pdf:put @resources (before pdf:exobj) instead.
+ */
+static int
+spc_handler_pdfm_eform (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ pdf_obj *attrib = NULL;
+ struct spc_pdf_ *sd = &_pdf_stat;
+
+ skip_white(&args->curptr, args->endptr);
+
+ if (args->curptr < args->endptr) {
+ attrib = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (attrib && !PDF_OBJ_DICTTYPE(attrib)) {
+ pdf_release_obj(attrib);
+ attrib = NULL;
+ }
+ }
+ /* pageresources here too */
+ if (sd->pageresources) {
+ pdf_foreach_dict(sd->pageresources, forallresourcecategory, NULL);
+ }
+ error = spc_end_form(spe, attrib);
+
+ return error;
+}
+
+/* Saved XObjects can be used as follows:
+ *
+ * Reference point = (x_user, y_user)
+ *
+ * Case 1. \special{pdf:uxobj @obj width WD height HT depth DP}
+ *
+ * Scale the XObject to fit in the box
+ * [x_user, y_user-DP, x_user+WD, y_user+HT].
+ *
+ * Case 2. \special{pdf:uxobj @obj xscale XS yscale YS}
+ *
+ * Scale the XObject with XS and YS. Note that width and xscale
+ * or height and yscale cannot be used together.
+ *
+ * Case 3. \special{pdf:bxobj @obj bbox LLX LLY URX, URY}
+ *
+ * Scale the XObject to fit in the box
+ * [x_user+LLX, y_user+LLY, x_user+URX, y_user+URY].
+ *
+ * Note that xoffset and yoffset moves the reference point where the
+ * lower-left corner of the XObject will be put.
+ */
+static int
+spc_handler_pdfm_uxobj (struct spc_env *spe, struct spc_arg *args)
+{
+ int xobj_id;
+ char *ident;
+ transform_info ti;
+
+ skip_white(&args->curptr, args->endptr);
+
+ ident = parse_opt_ident(&args->curptr, args->endptr);
+ if (!ident) {
+ spc_warn(spe, "No object identifier given.");
+ return -1;
+ }
+
+ transform_info_clear(&ti);
+ if (args->curptr < args->endptr) {
+ if (spc_util_read_dimtrns(spe, &ti, args, 0) < 0) {
+ RELEASE(ident);
+ return -1;
+ }
+ }
+
+ xobj_id = pdf_ximage_findresource(ident);
+ if (xobj_id < 0) {
+ xobj_id = pdf_ximage_reserve(ident);
+ }
+
+ spc_put_image(spe, xobj_id, &ti, spe->x_user, spe->y_user);
+ RELEASE(ident);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_link (struct spc_env *spe, struct spc_arg *args)
+{
+ return spc_resume_annot(spe);
+}
+
+static int
+spc_handler_pdfm_nolink (struct spc_env *spe, struct spc_arg *args)
+{
+ return spc_suspend_annot(spe);
+}
+
+
+
+/* Handled at BOP */
+static int
+spc_handler_pdfm_pagesize (struct spc_env *spe, struct spc_arg *args)
+{
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+/* Please remove this.
+ * This should be handled before processing pages!
+ */
+static int
+spc_handler_pdfm_bgcolor (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ pdf_color colorspec;
+
+ error = spc_util_read_pdfcolor(spe, &colorspec, args, NULL);
+ if (error)
+ spc_warn(spe, "No valid color specified?");
+ else {
+ pdf_doc_set_bgcolor(&colorspec);
+ }
+
+ return error;
+}
+
+#define THEBUFFLENGTH 1024
+static int
+spc_handler_pdfm_mapline (struct spc_env *spe, struct spc_arg *ap)
+{
+ fontmap_rec *mrec;
+ char *map_name, opchr;
+ int error = 0;
+ static char buffer[THEBUFFLENGTH];
+ const char *p;
+ char *q;
+ int count;
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr) {
+ spc_warn(spe, "Empty mapline special?");
+ return -1;
+ }
+
+ opchr = ap->curptr[0];
+ if (opchr == '-' || opchr == '+')
+ ap->curptr++;
+
+ skip_white(&ap->curptr, ap->endptr);
+
+ switch (opchr) {
+ case '-':
+ map_name = parse_ident(&ap->curptr, ap->endptr);
+ if (map_name) {
+ pdf_remove_fontmap_record(map_name);
+ RELEASE(map_name);
+ } else {
+ spc_warn(spe, "Invalid fontmap line: Missing TFM name.");
+ error = -1;
+ }
+ break;
+ default:
+ p = ap->curptr;
+ q = buffer;
+ count = 0;
+ while (p < ap->endptr && count < THEBUFFLENGTH - 1) {
+ *q++ = *p++;
+ count++;
+ }
+ if (count == THEBUFFLENGTH - 1) {
+ spc_warn(spe, "Invalid fontmap line: Too long a line.");
+ *q = 0;
+ return -1;
+ }
+ *q = '\0';
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+ error = pdf_read_fontmap_line(mrec, buffer, (int) (ap->endptr - ap->curptr), is_pdfm_mapline(buffer));
+ if (error)
+ spc_warn(spe, "Invalid fontmap line.");
+ else if (opchr == '+')
+ pdf_append_fontmap_record(mrec->map_name, mrec);
+ else
+ pdf_insert_fontmap_record(mrec->map_name, mrec);
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+ break;
+ }
+ if (!error)
+ ap->curptr = ap->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_mapfile (struct spc_env *spe, struct spc_arg *args)
+{
+ char *mapfile;
+ int mode, error = 0;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return 0;
+
+ switch (args->curptr[0]) {
+ case '-':
+ mode = FONTMAP_RMODE_REMOVE;
+ args->curptr++;
+ break;
+ case '+':
+ mode = FONTMAP_RMODE_APPEND;
+ args->curptr++;
+ break;
+ default:
+ mode = FONTMAP_RMODE_REPLACE;
+ break;
+ }
+
+ mapfile = parse_val_ident(&args->curptr, args->endptr);
+ if (!mapfile) {
+ spc_warn(spe, "No fontmap file specified.");
+ return -1;
+ } else {
+ error = pdf_load_fontmap_file(mapfile, mode);
+ }
+ RELEASE(mapfile);
+
+ return error;
+}
+
+
+static int
+spc_handler_pdfm_tounicode (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ char *cmap_name;
+ pdf_obj *taint_keys;
+
+ /* First clear */
+ sd->cd.cmap_id = -1;
+ sd->cd.unescape_backslash = 0;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr) {
+ spc_warn(spe, "Missing CMap name for pdf:tounicode.");
+ return -1;
+ }
+
+ /* _FIXME_
+ * Any valid char allowed for PDF name object should be allowed here.
+ * The argument to this special should be a PDF name obejct.
+ * But it's too late to change this special.
+ */
+ cmap_name = parse_ident(&args->curptr, args->endptr);
+ if (!cmap_name) {
+ spc_warn(spe, "Missing ToUnicode mapping name...");
+ return -1;
+ }
+
+ sd->cd.cmap_id = CMap_cache_find(cmap_name);
+ if (sd->cd.cmap_id < 0) {
+ spc_warn(spe, "Failed to load ToUnicode mapping: %s", cmap_name);
+ RELEASE(cmap_name);
+ return -1;
+ }
+
+ /* Shift-JIS like encoding may contain backslash in 2nd byte.
+ * WARNING: This will add nasty extension to PDF parser.
+ */
+ if (sd->cd.cmap_id >= 0) {
+ if (strstr(cmap_name, "RKSJ") ||
+ strstr(cmap_name, "B5") ||
+ strstr(cmap_name, "GBK") ||
+ strstr(cmap_name, "KSC"))
+ sd->cd.unescape_backslash = 1;
+ }
+ RELEASE(cmap_name);
+
+ /* Additional "taint key"
+ * An array of PDF name objects can be supplied optionally.
+ * Dictionary entries specified by this option will be added to the list
+ * of dictionary keys to be treated as the target of "ToUnicode" conversion.
+ */
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+ taint_keys = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ if (taint_keys) {
+ if (PDF_OBJ_ARRAYTYPE(taint_keys)) {
+ int i;
+ for (i = 0; i < pdf_array_length(taint_keys); i++) {
+ pdf_obj *key;
+
+ key = pdf_get_array(taint_keys, i);
+ if (PDF_OBJ_NAMETYPE(key))
+ pdf_add_array(sd->cd.taintkeys, pdf_link_obj(key));
+ else {
+ spc_warn(spe, "Invalid argument specified in pdf:tounicode special.");
+ }
+ }
+ } else {
+ spc_warn(spe, "Invalid argument specified in pdf:unicode special.");
+ }
+ pdf_release_obj(taint_keys);
+ }
+ }
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_pageresources (struct spc_env *spe, struct spc_arg *args)
+{
+ struct spc_pdf_ *sd = &_pdf_stat;
+ pdf_obj *dict;
+
+ dict = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!dict) {
+ spc_warn(spe, "Dictionary object expected but not found.");
+ return -1;
+ }
+
+ if (sd->pageresources)
+ pdf_release_obj(sd->pageresources);
+ sd->pageresources = dict;
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_bxgstate (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_obj *obj;
+
+ skip_white(&args->curptr, args->endptr);
+ obj = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!obj) {
+ spc_warn(spe, "Could not find an object definition.");
+ return -1;
+ } else if (!PDF_OBJ_DICTTYPE(obj)) {
+ spc_warn(spe, "Parsed object for ExtGState not a dictionary object!");
+ pdf_release_obj(obj);
+ return -1;
+ }
+ pdf_dev_xgstate_push(obj);
+
+ skip_white(&args->curptr, args->endptr);
+
+ return 0;
+}
+
+static int
+spc_handler_pdfm_exgstate (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_dev_xgstate_pop();
+ skip_white(&args->curptr, args->endptr);
+ return 0;
+}
+
+static int
+spc_handler_pdft_compat_page (struct spc_env *spe, struct spc_arg *args)
+{
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+ pdf_doc_add_page_content(" ", 1); /* op: */
+ pdf_doc_add_page_content(args->curptr, (int) (args->endptr - args->curptr)); /* op: ANY */
+ }
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static struct spc_handler pdfm_handlers[] = {
+ {"annotation", spc_handler_pdfm_annot},
+ {"annotate", spc_handler_pdfm_annot},
+ {"annot", spc_handler_pdfm_annot},
+ {"ann", spc_handler_pdfm_annot},
+
+ {"outline", spc_handler_pdfm_outline},
+ {"out", spc_handler_pdfm_outline},
+
+ {"article", spc_handler_pdfm_article},
+ {"art", spc_handler_pdfm_article},
+
+ {"bead", spc_handler_pdfm_bead},
+ {"thread", spc_handler_pdfm_bead},
+
+ {"destination", spc_handler_pdfm_dest},
+ {"dest", spc_handler_pdfm_dest},
+
+
+ {"object", spc_handler_pdfm_object},
+ {"obj", spc_handler_pdfm_object},
+
+
+ {"docinfo", spc_handler_pdfm_docinfo},
+ {"docview", spc_handler_pdfm_docview},
+
+ {"content", spc_handler_pdfm_content},
+ {"put", spc_handler_pdfm_put},
+ {"close", spc_handler_pdfm_close},
+ {"bop", spc_handler_pdfm_bop},
+ {"eop", spc_handler_pdfm_eop},
+
+ {"image", spc_handler_pdfm_image},
+ {"img", spc_handler_pdfm_image},
+ {"epdf", spc_handler_pdfm_image},
+
+ {"link", spc_handler_pdfm_link},
+ {"nolink", spc_handler_pdfm_nolink},
+
+ {"begincolor", spc_handler_pdfm_bcolor},
+ {"bcolor", spc_handler_pdfm_bcolor},
+ {"bc", spc_handler_pdfm_bcolor},
+
+ {"setcolor", spc_handler_pdfm_scolor},
+ {"scolor", spc_handler_pdfm_scolor},
+ {"sc", spc_handler_pdfm_scolor},
+
+ {"endcolor", spc_handler_pdfm_ecolor},
+ {"ecolor", spc_handler_pdfm_ecolor},
+ {"ec", spc_handler_pdfm_ecolor},
+
+ {"begingray", spc_handler_pdfm_bcolor},
+ {"bgray", spc_handler_pdfm_bcolor},
+ {"bg", spc_handler_pdfm_bcolor},
+
+ {"endgray", spc_handler_pdfm_ecolor},
+ {"egray", spc_handler_pdfm_ecolor},
+ {"eg", spc_handler_pdfm_ecolor},
+
+ {"bgcolor", spc_handler_pdfm_bgcolor},
+ {"bgc", spc_handler_pdfm_bgcolor},
+ {"bbc", spc_handler_pdfm_bgcolor},
+ {"bbg", spc_handler_pdfm_bgcolor},
+
+ {"pagesize", spc_handler_pdfm_pagesize},
+
+ {"bannot", spc_handler_pdfm_bann},
+ {"beginann", spc_handler_pdfm_bann},
+ {"bann", spc_handler_pdfm_bann},
+
+ {"eannot", spc_handler_pdfm_eann},
+ {"endann", spc_handler_pdfm_eann},
+ {"eann", spc_handler_pdfm_eann},
+
+ {"btrans", spc_handler_pdfm_btrans},
+ {"begintransform", spc_handler_pdfm_btrans},
+ {"begintrans", spc_handler_pdfm_btrans},
+ {"bt", spc_handler_pdfm_btrans},
+
+ {"etrans", spc_handler_pdfm_etrans},
+ {"endtransform", spc_handler_pdfm_etrans},
+ {"endtrans", spc_handler_pdfm_etrans},
+ {"et", spc_handler_pdfm_etrans},
+
+ {"bform", spc_handler_pdfm_bform},
+ {"beginxobj", spc_handler_pdfm_bform},
+ {"bxobj", spc_handler_pdfm_bform},
+
+ {"eform", spc_handler_pdfm_eform},
+ {"endxobj", spc_handler_pdfm_eform},
+ {"exobj", spc_handler_pdfm_eform},
+
+ {"usexobj", spc_handler_pdfm_uxobj},
+ {"uxobj", spc_handler_pdfm_uxobj},
+
+ {"tounicode", spc_handler_pdfm_tounicode},
+ {"literal", spc_handler_pdfm_literal},
+ {"stream", spc_handler_pdfm_stream},
+ {"fstream", spc_handler_pdfm_fstream},
+ {"names", spc_handler_pdfm_names},
+ {"mapline", spc_handler_pdfm_mapline},
+ {"mapfile", spc_handler_pdfm_mapfile},
+
+ {"bcontent", spc_handler_pdfm_bcontent},
+ {"econtent", spc_handler_pdfm_econtent},
+ {"code", spc_handler_pdfm_code},
+
+ {"minorversion", spc_handler_pdfm_do_nothing},
+ {"majorversion", spc_handler_pdfm_do_nothing},
+ {"encrypt", spc_handler_pdfm_do_nothing},
+
+ {"pageresources", spc_handler_pdfm_pageresources},
+ {"trailerid", spc_handler_pdfm_do_nothing},
+
+ {"xannot", spc_handler_pdfm_xann},
+ {"extendann", spc_handler_pdfm_xann},
+ {"xann", spc_handler_pdfm_xann},
+
+ {"bxgstate", spc_handler_pdfm_bxgstate},
+ {"exgstate", spc_handler_pdfm_exgstate},
+};
+
+static struct spc_handler pdft_compat_handlers[] = {
+ /* Text supplied to "direct" command should go inside of BT/ET block
+ * but dvipdfmx currently can't be implemented so.
+ * Here, "direct" is for the moment just an alias of "page".
+ */
+ {"direct", spc_handler_pdft_compat_page},
+ {"page", spc_handler_pdft_compat_page},
+};
+
+int
+spc_pdfm_check_special (const char *buf, int len)
+{
+ int r = 0;
+ const char *p, *endptr;
+
+ p = buf;
+ endptr = p + len;
+
+ skip_white(&p, endptr);
+ if (p + strlen("pdf:") <= endptr &&
+ !memcmp(p, "pdf:", strlen("pdf:"))) {
+ r = 1;
+ }
+
+ return r;
+}
+
+int
+spc_pdfm_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap)
+{
+ int error = -1, i;
+ char *q;
+
+ ASSERT(sph && spe && ap);
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr + strlen("pdf:") >= ap->endptr ||
+ memcmp(ap->curptr, "pdf:", strlen("pdf:"))) {
+ spc_warn(spe, "Not pdf: special???");
+ return -1;
+ }
+ ap->curptr += strlen("pdf:");
+
+ skip_white(&ap->curptr, ap->endptr);
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (q) {
+ int is_pdft_compat = 0;
+ if (ap->curptr < ap->endptr) {
+ if (ap->curptr[0] == ':') {
+ is_pdft_compat = 1;
+ ap->curptr++;
+ }
+ }
+ if (is_pdft_compat) {
+ for (i = 0; i < sizeof(pdft_compat_handlers) / sizeof(struct spc_handler); i++) {
+ if (!strcmp(q, pdft_compat_handlers[i].key)) {
+ ap->command = pdft_compat_handlers[i].key;
+ sph->key = "pdf:";
+ sph->exec = pdft_compat_handlers[i].exec;
+ skip_white(&ap->curptr, ap->endptr);
+ error = 0;
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < sizeof(pdfm_handlers) / sizeof(struct spc_handler); i++) {
+ if (!strcmp(q, pdfm_handlers[i].key)) {
+ ap->command = pdfm_handlers[i].key;
+ sph->key = "pdf:";
+ sph->exec = pdfm_handlers[i].exec;
+ skip_white(&ap->curptr, ap->endptr);
+ error = 0;
+ break;
+ }
+ }
+ }
+ RELEASE(q);
+ }
+
+ return error;
+}
diff --git a/Build/source/texk/dvipdfm-x/spc_pdfm.h b/Build/source/texk/dvipdfm-x/spc_pdfm.h
new file mode 100644
index 00000000000..004181c260b
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_pdfm.h
@@ -0,0 +1,37 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_PDFM_H_
+#define _SPC_PDFM_H_
+
+#include "specials.h"
+
+extern int spc_pdfm_at_begin_document (void);
+extern int spc_pdfm_at_end_document (void);
+
+extern int spc_pdfm_at_end_page (void);
+
+extern int spc_pdfm_check_special (const char *buffer, int size);
+extern int spc_pdfm_setup_handler (struct spc_handler *handle,
+ struct spc_env *spe, struct spc_arg *args);
+
+#endif /* _SPC_PDFM_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_tpic.c b/Build/source/texk/dvipdfm-x/spc_tpic.c
new file mode 100644
index 00000000000..31d28972574
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_tpic.c
@@ -0,0 +1,1118 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "numbers.h"
+#include "dpxutil.h"
+
+#include "pdfdoc.h"
+
+#include "pdfdraw.h"
+#include "pdfdev.h"
+
+#include "specials.h"
+#include "spc_tpic.h"
+
+#define DEBUG 1
+#define ENABLE_SPC_NAMESPACE 1
+
+/*
+ * Following "constant" converts milli-inches to
+ * device (in this case PDF stream) coordinates.
+ */
+
+#define MI2DEV (0.072/pdf_dev_scale())
+
+/*
+ * Value for 'sh' command 'g' is interpreted as
+ *
+ * gray color value 1-g for "solid"
+ * opacity value g for "opacity"
+ * shape value g for "shape"
+ */
+#define TPIC_MODE__FILL_SOLID 0
+#define TPIC_MODE__FILL_OPACITY 1
+#define TPIC_MODE__FILL_SHAPE 2
+
+#ifndef ISBLANK
+# define ISBLANK(c) ( (c) == ' ' || (c) == '\t' )
+#endif
+
+static void
+skip_blank (const char **pp, const char *endptr)
+{
+ const char *p = *pp;
+ for ( ; p < endptr && ISBLANK(*p); p++);
+ *pp = p;
+}
+
+struct spc_tpic_
+{
+ struct {
+ int fill;
+ } mode;
+
+ /* state */
+ double pen_size;
+ int fill_shape; /* boolean */
+ double fill_color;
+
+ pdf_coord *points;
+ int num_points;
+ int max_points;
+};
+
+#if 1
+static struct spc_tpic_ _tpic_state;
+#endif
+
+/* We use pdf_doc_add_page_content() here
+ * since we always draw isolated graphics.
+ */
+static void
+tpic__clear (struct spc_tpic_ *tp)
+{
+ if (tp->points) {
+ RELEASE(tp->points);
+ tp->points = NULL;
+ }
+ tp->num_points = 0;
+ tp->max_points = 0;
+ tp->fill_shape = 0;
+ tp->fill_color = 0.0;
+}
+
+
+static pdf_obj *
+create_xgstate (double a /* alpha */, int f_ais /* alpha is shape */)
+{
+ pdf_obj *dict;
+
+ dict = pdf_new_dict();
+ pdf_add_dict(dict,
+ pdf_new_name("Type"),
+ pdf_new_name("ExtGState"));
+ if (f_ais) {
+ pdf_add_dict(dict,
+ pdf_new_name("AIS"),
+ pdf_new_boolean(1));
+ }
+ pdf_add_dict(dict,
+ pdf_new_name("ca"),
+ pdf_new_number(a));
+
+ return dict;
+}
+
+static int
+check_resourcestatus (const char *category, const char *resname)
+{
+ pdf_obj *dict1, *dict2;
+
+ dict1 = pdf_doc_current_page_resources();
+ if (!dict1)
+ return 0;
+
+ dict2 = pdf_lookup_dict(dict1, category);
+ if (dict2 &&
+ pdf_obj_typeof(dict2) == PDF_DICT) {
+ if (pdf_lookup_dict(dict2, resname))
+ return 1;
+ }
+ return 0;
+}
+
+static int
+set_linestyle (double pn, double da)
+{
+ double dp[2]; /* dash pattern */
+
+ pdf_dev_setlinejoin(1);
+ pdf_dev_setmiterlimit(1.4);
+ pdf_dev_setlinewidth(pn);
+ if (da > 0.0) {
+ dp[0] = da * 72.0;
+ pdf_dev_setdash(1, dp, 0);
+ pdf_dev_setlinecap(0);
+ } else if (da < 0.0) {
+ dp[0] = pn;
+ dp[1] = -da * 72.0;
+ pdf_dev_setdash(2, dp, 0);
+ pdf_dev_setlinecap(1);
+ } else {
+ pdf_dev_setlinecap(0);
+ }
+
+ return 0;
+}
+
+static int
+set_fillstyle (double g, double a, int f_ais)
+{
+ pdf_obj *dict;
+ char resname[32];
+ char buf[256];
+ int alp, len = 0;
+
+ if (a > 0.0) {
+ alp = round(100.0 * a);
+ sprintf(resname, "_Tps_a%03d_", alp);
+ if (!check_resourcestatus("ExtGState", resname)) {
+ dict = create_xgstate(ROUND(0.01 * alp, 0.01), f_ais);
+ pdf_doc_add_page_resource("ExtGState",
+ resname, pdf_ref_obj(dict));
+ pdf_release_obj(dict);
+ }
+ len += sprintf(buf + len, " /%s gs", resname);
+
+ pdf_doc_add_page_content(buf, len); /* op: gs */
+ }
+
+ {
+ pdf_color *sc, *fc, new_fc;
+
+ pdf_color_get_current (&sc, &fc); /* get stroking and fill colors */
+ pdf_color_brighten_color(&new_fc, fc, g);
+ pdf_dev_set_nonstrokingcolor(&new_fc);
+ }
+
+ return 0;
+}
+
+static void
+set_styles (struct spc_tpic_ *tp,
+ const pdf_coord *c,
+ int f_fs,
+ int f_vp,
+ double pn,
+ double da) {
+ pdf_tmatrix M;
+
+ pdf_setmatrix (&M, 1.0, 0.0, 0.0, -1.0, c->x, c->y);
+ pdf_dev_concat(&M);
+
+ if (f_vp)
+ set_linestyle(pn, da);
+
+ if (f_fs) {
+ double g, a;
+ int f_ais;
+
+ if (tp->mode.fill == TPIC_MODE__FILL_SOLID || !tp->fill_color) {
+ g = 1.0 - tp->fill_color;
+ a = 0.0;
+ } else {
+ g = 0.0;
+ a = tp->fill_color;
+ }
+
+ f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0;
+
+ set_fillstyle(g, a, f_ais);
+ }
+}
+
+static void
+showpath (int f_vp, int f_fs) /* visible_path, fill_shape */
+{
+ if (f_vp) {
+ if (f_fs)
+ pdf_dev_flushpath('b', PDF_FILL_RULE_NONZERO);
+ else {
+ pdf_dev_flushpath('S', PDF_FILL_RULE_NONZERO);
+ }
+ } else {
+ /*
+ * Acrobat claims 'Q' as illegal operation when there are unfinished
+ * path (a path without path-painting operator applied)?
+ */
+ if (f_fs)
+ pdf_dev_flushpath('f', PDF_FILL_RULE_NONZERO);
+ else {
+ pdf_dev_newpath();
+ }
+ }
+}
+
+#define CLOSED_PATH(s) (\
+ (s)->points[0].x == (s)->points[(s)->num_points-1].x && \
+ (s)->points[0].y == (s)->points[(s)->num_points-1].y \
+)
+
+static int
+tpic__polyline (struct spc_tpic_ *tp,
+ const pdf_coord *c,
+ int f_vp,
+ double da)
+{
+ double pn = tp->pen_size;
+ int f_fs = tp->fill_shape;
+ int i, error = 0;
+
+ /* Shading is applied only to closed path. */
+ f_fs = CLOSED_PATH(tp) ? f_fs : 0;
+ f_vp = (pn > 0.0) ? f_vp : 0;
+
+ if (f_vp || f_fs) {
+ pdf_dev_gsave();
+
+ set_styles(tp, c, f_fs, f_vp, pn, da);
+
+ pdf_dev_moveto(tp->points[0].x, tp->points[0].y);
+ for (i = 0; i < tp->num_points; i++)
+ pdf_dev_lineto(tp->points[i].x, tp->points[i].y);
+
+ showpath(f_vp, f_fs);
+
+ pdf_dev_grestore();
+ }
+
+ tpic__clear(tp);
+
+ return error;
+}
+
+/*
+ * Accroding to
+ * "Tpic: Pic for TEX", Tim Morgan, Original by Brian Kernighan, p.20:
+ *
+ * A spline is a smooth curve guided by a set of straight lines just
+ * like the line above. It begins at the same place, ends at the same
+ * place, and in between is tangent to the mid-point of each guiding
+ * line. The syntax for a spline is identical to a (path) line except
+ * for using spline instead of line.
+ *
+ * Spline is not a curve drawn by spline-fitting points p0, p1, ..., pn,
+ * defined by tpic special "pa" command. Instead, a path defined by set
+ * of points p0, p1, ... is guiding line mentioned above.
+ *
+ * Dvipsk draws them as a straight line from p0 to q1 = (p0 + p1)/2,
+ * followed by a quadratic B-spline curve with starting point q1, (off-
+ * curve) control point p1, end point q2 = (p1 + p2)/2, ..., and a
+ * straight line from qn to pn.
+ */
+
+static int
+tpic__spline (struct spc_tpic_ *tp,
+ const pdf_coord *c,
+ int f_vp,
+ double da)
+{
+ double v[6];
+ double pn = tp->pen_size;
+ int f_fs = tp->fill_shape;
+ int i, error = 0;
+
+ f_fs = CLOSED_PATH(tp) ? f_fs : 0;
+ f_vp = (pn > 0.0) ? f_vp : 0;
+
+ if (f_vp || f_fs) {
+ pdf_dev_gsave();
+
+ set_styles(tp, c, f_fs, f_vp, pn, da);
+
+ pdf_dev_moveto(tp->points[0].x, tp->points[0].y);
+
+ v[0] = 0.5 * (tp->points[0].x + tp->points[1].x);
+ v[1] = 0.5 * (tp->points[0].y + tp->points[1].y);
+ pdf_dev_lineto(v[0], v[1]);
+ for (i = 1; i < tp->num_points - 1; i++) {
+ /* B-spline control points */
+ v[0] = 0.5 * (tp->points[i-1].x + tp->points[i].x);
+ v[1] = 0.5 * (tp->points[i-1].y + tp->points[i].y);
+ v[2] = tp->points[i].x;
+ v[3] = tp->points[i].y;
+ v[4] = 0.5 * (tp->points[i].x + tp->points[i+1].x);
+ v[5] = 0.5 * (tp->points[i].y + tp->points[i+1].y);
+ pdf_dev_bspline(v[0], v[1], v[2], v[3], v[4], v[5]);
+ }
+ pdf_dev_lineto(tp->points[i].x, tp->points[i].y);
+
+ showpath(f_vp, f_fs);
+
+ pdf_dev_grestore();
+ }
+ tpic__clear(tp);
+
+ return error;
+}
+
+static int
+tpic__arc (struct spc_tpic_ *tp,
+ const pdf_coord *c,
+ int f_vp,
+ double da,
+ double *v /* 6 numbers */ )
+{
+ double pn = tp->pen_size;
+ int f_fs = tp->fill_shape;
+
+ f_fs = (round(fabs(v[4] - v[5]) + 0.5) >= 360) ? f_fs : 0;
+ f_vp = (pn > 0.0) ? f_vp : 0;
+
+ if (f_vp || f_fs) {
+ pdf_dev_gsave();
+
+ set_styles(tp, c, f_fs, f_vp, pn, da);
+
+ /* The arcx operator here draws an excess straight line from current
+ * point to the starting point of the arc if they are different, as in
+ * PostScript language. It may cuase an unexpected behavior when DVIPS
+ * transformation command is inserted before TPIC ar command: it invokes
+ * moveto and sets currentpoint which may be different from the starting
+ * point of arc to be drawn. We use newpath here to avoid drawing an
+ * excess line. I'm not sure if it is proper TPIC implementation but this
+ * seems to be DVIPS compatible behavior.
+ */
+ pdf_dev_newpath();
+ pdf_dev_arcx(v[0], v[1], v[2], v[3], v[4], v[5], +1, 0.0);
+
+ showpath(f_vp, f_fs);
+
+ pdf_dev_grestore();
+ }
+ tpic__clear(tp);
+
+ return 0;
+}
+
+#if 1
+static int
+spc_currentpoint (struct spc_env *spe, int *pg, pdf_coord *cp)
+{
+ *pg = 0;
+ cp->x = spe->x_user;
+ cp->y = spe->y_user;
+ return 0;
+}
+#endif
+
+static int
+spc_handler_tpic_pn (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ char *q;
+
+ ASSERT(spe && ap && tp);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!q) {
+ spc_warn(spe, "Invalid pen size specified?");
+ return -1;
+ }
+ tp->pen_size = atof(q) * MI2DEV;
+ RELEASE(q);
+
+ return 0;
+}
+
+static int
+spc_handler_tpic_pa (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ char *q;
+ int i;
+ double v[2];
+
+ ASSERT(spe && ap && tp);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ for (i = 0;
+ i < 2 && ap->curptr < ap->endptr; i++) {
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!q) {
+ spc_warn(spe, "Missing numbers for TPIC \"pa\" command.");
+ return -1;
+ }
+ v[i] = atof(q);
+ RELEASE(q);
+ skip_blank(&ap->curptr, ap->endptr);
+ }
+ if (i != 2) {
+ spc_warn(spe, "Invalid arg for TPIC \"pa\" command.");
+ return -1;
+ }
+
+ if (tp->num_points >= tp->max_points) {
+ tp->max_points += 256;
+ tp->points = RENEW(tp->points, tp->max_points, pdf_coord);
+ }
+ tp->points[tp->num_points].x = v[0] * MI2DEV;
+ tp->points[tp->num_points].y = v[1] * MI2DEV;
+ tp->num_points += 1;
+
+ return 0;
+}
+
+static int
+spc_handler_tpic_fp (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ pdf_coord cp;
+ int pg;
+
+ ASSERT(spe && ap && tp);
+
+ if (tp->num_points <= 1) {
+ spc_warn(spe, "Too few points (< 2) for polyline path.");
+ return -1;
+ }
+
+ spc_currentpoint(spe, &pg, &cp);
+
+ return tpic__polyline(tp, &cp, 1, 0.0);
+}
+
+static int
+spc_handler_tpic_ip (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ pdf_coord cp;
+ int pg;
+
+ ASSERT(spe && ap && tp);
+
+ if (tp->num_points <= 1) {
+ spc_warn(spe, "Too few points (< 2) for polyline path.");
+ return -1;
+ }
+
+ spc_currentpoint(spe, &pg, &cp);
+
+ return tpic__polyline(tp, &cp, 0, 0.0);
+}
+
+static int
+spc_handler_tpic_da (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ char *q;
+ double da = 0.0;
+ pdf_coord cp;
+ int pg;
+
+ ASSERT(spe && ap && tp);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (q) {
+ da = atof(q);
+ RELEASE(q);
+ }
+ if (tp->num_points <= 1) {
+ spc_warn(spe, "Too few points (< 2) for polyline path.");
+ return -1;
+ }
+
+ spc_currentpoint(spe, &pg, &cp);
+
+ return tpic__polyline(tp, &cp, 1, da);
+}
+
+static int
+spc_handler_tpic_dt (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ char *q;
+ double da = 0.0;
+ pdf_coord cp;
+ int pg;
+
+ ASSERT(spe && ap && tp);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (q) {
+ da = -atof(q);
+ RELEASE(q);
+ }
+ if (tp->num_points <= 1) {
+ spc_warn(spe, "Too few points (< 2) for polyline path.");
+ return -1;
+ }
+
+ spc_currentpoint(spe, &pg, &cp);
+
+ return tpic__polyline(tp, &cp, 1, da);
+}
+
+static int
+spc_handler_tpic_sp (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ char *q;
+ double da = 0.0;
+ pdf_coord cp;
+ int pg;
+
+ ASSERT(spe && ap && tp);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (q) {
+ da = atof(q);
+ RELEASE(q);
+ }
+ if (tp->num_points <= 2) {
+ spc_warn(spe, "Too few points (< 3) for spline path.");
+ return -1;
+ }
+
+ spc_currentpoint(spe, &pg, &cp);
+
+ return tpic__spline(tp, &cp, 1, da);
+}
+
+static int
+spc_handler_tpic_ar (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ double v[6];
+ pdf_coord cp;
+ int pg;
+ char *q;
+ int i;
+
+ ASSERT(spe && ap && tp);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ for (i = 0;
+ i < 6 && ap->curptr < ap->endptr; i++) {
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!q) {
+ spc_warn(spe, "Invalid args. in TPIC \"ar\" command.");
+ return -1;
+ }
+ v[i] = atof(q);
+ RELEASE(q);
+ skip_blank(&ap->curptr, ap->endptr);
+ }
+ if (i != 6) {
+ spc_warn(spe, "Invalid arg for TPIC \"ar\" command.");
+ return -1;
+ }
+
+ v[0] *= MI2DEV; v[1] *= MI2DEV;
+ v[2] *= MI2DEV; v[3] *= MI2DEV;
+ v[4] *= 180.0 / M_PI;
+ v[5] *= 180.0 / M_PI;
+
+ spc_currentpoint(spe, &pg, &cp);
+
+ return tpic__arc(tp, &cp, 1, 0.0, v);
+}
+
+static int
+spc_handler_tpic_ia (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ double v[6];
+ pdf_coord cp;
+ int pg;
+ char *q;
+ int i;
+
+ ASSERT(spe && ap && tp);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ for (i = 0;
+ i < 6 && ap->curptr < ap->endptr; i++) {
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!q) {
+ spc_warn(spe, "Invalid args. in TPIC \"ia\" command.");
+ return -1;
+ }
+ v[i] = atof(q);
+ RELEASE(q);
+ skip_blank(&ap->curptr, ap->endptr);
+ }
+ if (i != 6) {
+ spc_warn(spe, "Invalid arg for TPIC \"ia\" command.");
+ return -1;
+ }
+
+ v[0] *= MI2DEV; v[1] *= MI2DEV;
+ v[2] *= MI2DEV; v[3] *= MI2DEV;
+ v[4] *= 180.0 / M_PI;
+ v[5] *= 180.0 / M_PI;
+
+ spc_currentpoint(spe, &pg, &cp);
+
+ return tpic__arc(tp, &cp, 0, 0.0, v);
+}
+
+static int
+spc_handler_tpic_sh (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ char *q;
+
+ ASSERT(spe && ap && tp);
+
+ tp->fill_shape = 1;
+ tp->fill_color = 0.5;
+
+ skip_blank(&ap->curptr, ap->endptr);
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (q) {
+ double g = atof(q);
+ RELEASE(q);
+ if (g >= 0.0 && g <= 1.0)
+ tp->fill_color = g;
+ else {
+ WARN("Invalid fill color specified: %g\n", g);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+spc_handler_tpic_wh (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+
+ ASSERT(spe && ap && tp);
+
+ tp->fill_shape = 1;
+ tp->fill_color = 0.0;
+
+ return 0;
+}
+
+static int
+spc_handler_tpic_bk (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+
+ ASSERT(spe && ap && tp);
+
+ tp->fill_shape = 1;
+ tp->fill_color = 1.0;
+
+ return 0;
+}
+
+static int
+spc_handler_tpic_tx (struct spc_env *spe,
+ struct spc_arg *ap ) /* , void *dp) */
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+
+ ASSERT(spe && ap && tp);
+
+ spc_warn(spe, "TPIC command \"tx\" not supported.");
+
+ return -1;
+}
+
+
+static int
+spc_handler_tpic__init (struct spc_env *spe, void *dp)
+{
+ struct spc_tpic_ *tp = dp;
+
+#if 0
+ tp->mode.fill = TPIC_MODE__FILL_SOLID;
+#endif
+ tp->pen_size = 1.0;
+ tp->fill_shape = 0;
+ tp->fill_color = 0.0;
+
+ tp->points = NULL;
+ tp->num_points = 0;
+ tp->max_points = 0;
+
+ if (tp->mode.fill != TPIC_MODE__FILL_SOLID &&
+ pdf_check_version(1, 4) < 0) {
+ spc_warn(spe, "Tpic shading support requires PDF version 1.4.");
+ tp->mode.fill = TPIC_MODE__FILL_SOLID;
+ }
+
+ return 0;
+}
+
+static int
+spc_handler_tpic__bophook (void *dp)
+{
+ struct spc_tpic_ *tp = dp;
+
+ ASSERT(tp);
+
+ tpic__clear(tp);
+
+ return 0;
+}
+
+static int
+spc_handler_tpic__eophook (struct spc_env *spe, void *dp)
+{
+ struct spc_tpic_ *tp = dp;
+
+ ASSERT(tp);
+
+ if (tp->num_points > 0)
+ spc_warn(spe, "Unflushed tpic path at end of the page.");
+ tpic__clear(tp);
+
+ return 0;
+}
+
+static int
+spc_handler_tpic__clean (struct spc_env *spe, void *dp)
+{
+ struct spc_tpic_ *tp = dp;
+
+ ASSERT(tp);
+
+ if (tp->num_points > 0)
+ spc_warn(spe, "Unflushed tpic path at end of the document.");
+
+ tpic__clear(tp);
+#if 0
+ RELEASE(tp);
+#endif
+
+ return 0;
+}
+
+void
+tpic_set_fill_mode (int mode)
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ tp->mode.fill = mode;
+}
+
+
+int
+spc_tpic_at_begin_page (void)
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ return spc_handler_tpic__bophook(tp);
+}
+
+int
+spc_tpic_at_end_page (void)
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ return spc_handler_tpic__eophook(NULL, tp);
+}
+
+
+int
+spc_tpic_at_begin_document (void)
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ return spc_handler_tpic__init(NULL, tp);
+}
+
+int
+spc_tpic_at_end_document (void)
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ return spc_handler_tpic__clean(NULL, tp);
+}
+
+
+#if DEBUG
+#include "pdfparse.h" /* parse_val_ident :( */
+
+static pdf_obj *
+spc_parse_kvpairs (struct spc_arg *ap)
+{
+ pdf_obj *dict;
+ char *kp, *vp;
+ int error = 0;
+
+ dict = pdf_new_dict();
+
+ skip_blank(&ap->curptr, ap->endptr);
+ while (!error && ap->curptr < ap->endptr) {
+ kp = parse_val_ident(&ap->curptr, ap->endptr);
+ if (!kp)
+ break;
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr < ap->endptr &&
+ ap->curptr[0] == '=') {
+ ap->curptr++;
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr == ap->endptr) {
+ RELEASE(kp);
+ error = -1;
+ break;
+ }
+ vp = parse_c_string(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ pdf_add_dict(dict,
+ pdf_new_name(kp),
+ pdf_new_string(vp, strlen(vp) + 1)); /* NULL terminate */
+ RELEASE(vp);
+ }
+ } else {
+ /* Treated as 'flag' */
+ pdf_add_dict(dict,
+ pdf_new_name(kp),
+ pdf_new_boolean(1));
+ }
+ RELEASE(kp);
+ if (!error)
+ skip_blank(&ap->curptr, ap->endptr);
+ }
+
+ if (error) {
+ pdf_release_obj(dict);
+ dict = NULL;
+ }
+
+ return dict;
+}
+
+static int
+tpic_filter_getopts (pdf_obj *kp, pdf_obj *vp, void *dp)
+{
+ struct spc_tpic_ *tp = dp;
+ char *k, *v;
+ int error = 0;
+
+ ASSERT( kp && vp && tp );
+
+ k = pdf_name_value(kp);
+ if (!strcmp(k, "fill-mode")) {
+ if (pdf_obj_typeof(vp) != PDF_STRING) {
+ WARN("Invalid value for TPIC option fill-mode...");
+ error = -1;
+ } else {
+ v = pdf_string_value(vp);
+ if (!strcmp(v, "shape"))
+ tp->mode.fill = TPIC_MODE__FILL_SHAPE;
+ else if (!strcmp(v, "opacity"))
+ tp->mode.fill = TPIC_MODE__FILL_OPACITY;
+ else if (!strcmp(v, "solid"))
+ tp->mode.fill = TPIC_MODE__FILL_SOLID;
+ else {
+ WARN("Invalid value for TPIC option fill-mode: %s", v);
+ error = -1;
+ }
+ }
+ } else {
+ WARN("Unrecognized option for TPIC special handler: %s", k);
+ error = -1;
+ }
+
+ return error;
+}
+
+static int
+spc_handler_tpic__setopts (struct spc_env *spe,
+ struct spc_arg *ap)
+{
+ struct spc_tpic_ *tp = &_tpic_state;
+ pdf_obj *dict;
+ int error = 0;
+
+ dict = spc_parse_kvpairs(ap);
+ if (!dict)
+ return -1;
+ error = pdf_foreach_dict(dict, tpic_filter_getopts, tp);
+ if (!error) {
+ if (tp->mode.fill != TPIC_MODE__FILL_SOLID &&
+ pdf_check_version(1, 4) < 0) {
+ spc_warn(spe, "Transparent fill mode requires PDF version 1.4.");
+ tp->mode.fill = TPIC_MODE__FILL_SOLID;
+ }
+ }
+
+ return error;
+}
+#endif /* DEBUG */
+
+
+static struct spc_handler tpic_handlers[] = {
+ {"pn", spc_handler_tpic_pn},
+ {"pa", spc_handler_tpic_pa},
+ {"fp", spc_handler_tpic_fp},
+ {"ip", spc_handler_tpic_ip},
+ {"da", spc_handler_tpic_da},
+ {"dt", spc_handler_tpic_dt},
+ {"sp", spc_handler_tpic_sp},
+ {"ar", spc_handler_tpic_ar},
+ {"ia", spc_handler_tpic_ia},
+ {"sh", spc_handler_tpic_sh},
+ {"wh", spc_handler_tpic_wh},
+ {"bk", spc_handler_tpic_bk},
+ {"tx", spc_handler_tpic_tx}
+};
+
+int
+spc_tpic_check_special (const char *buf, int len)
+{
+ int istpic = 0;
+ char *q;
+ const char *p, *endptr;
+ int i, hasnsp = 0;
+
+ p = buf;
+ endptr = p + len;
+
+ skip_blank(&p, endptr);
+#if ENABLE_SPC_NAMESPACE
+ if (p + strlen("tpic:") < endptr &&
+ !memcmp(p, "tpic:", strlen("tpic:")))
+ {
+ p += strlen("tpic:");
+ hasnsp = 1;
+ }
+#endif
+ q = parse_c_ident(&p, endptr);
+
+ if (!q)
+ istpic = 0;
+ else if (q && hasnsp && !strcmp(q, "__setopt__")) {
+#if DEBUG
+ istpic = 1;
+#endif
+ RELEASE(q);
+ } else {
+ for (i = 0;
+ i < sizeof(tpic_handlers)/sizeof(struct spc_handler); i++) {
+ if (!strcmp(q, tpic_handlers[i].key)) {
+ istpic = 1;
+ break;
+ }
+ }
+ RELEASE(q);
+ }
+
+ return istpic;
+}
+
+
+int
+spc_tpic_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap)
+{
+ char *q;
+ int i, hasnsp = 0, error = -1;
+
+ ASSERT(sph && spe && ap);
+
+ skip_blank(&ap->curptr, ap->endptr);
+#if ENABLE_SPC_NAMESPACE
+ if (ap->curptr + strlen("tpic:") < ap->endptr &&
+ !memcmp(ap->curptr, "tpic:", strlen("tpic:")))
+ {
+ ap->curptr += strlen("tpic:");
+ hasnsp = 1;
+ }
+#endif
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+
+ if (!q)
+ error = -1;
+ else if (q && hasnsp && !strcmp(q, "__setopt__")) {
+#if DEBUG
+ ap->command = "__setopt__";
+ sph->key = "tpic:";
+ sph->exec = spc_handler_tpic__setopts;
+ skip_blank(&ap->curptr, ap->endptr);
+ error = 0;
+#endif
+ RELEASE(q);
+ } else {
+ for (i = 0;
+ i < sizeof(tpic_handlers)/sizeof(struct spc_handler); i++) {
+ if (!strcmp(q, tpic_handlers[i].key)) {
+ ap->command = tpic_handlers[i].key;
+ sph->key = "tpic:";
+ sph->exec = tpic_handlers[i].exec;
+ skip_blank(&ap->curptr, ap->endptr);
+ error = 0;
+ break;
+ }
+ }
+ RELEASE(q);
+ }
+
+ return error;
+}
+
+
+#if 0
+int
+spc_load_tpic_special (struct spc_env *spe, pdf_obj *lopts)
+{
+ struct spc_def *spd;
+ struct spc_tpic_ *sd;
+
+ sd = NEW(1, struct spc_tpic_);
+
+ spd = NEW(1, struct spc_def);
+ spc_init_def(spd);
+
+ spc_def_init (spd, &spc_handler_tpic__init);
+ spc_def_setopts(spd, &spc_handler_tpic__setopts);
+ spc_def_bophook(spd, &spc_handler_tpic__bophook);
+ spc_def_eophook(spd, &spc_handler_tpic__eophook);
+ spc_def_clean (spd, &spc_handler_tpic__clean);
+
+ spc_def_func(spd, "pn", &spc_handler_tpic_pn);
+ spc_def_func(spd, "pa", &spc_handler_tpic_pa);
+ spc_def_func(spd, "fp", &spc_handler_tpic_fp);
+ spc_def_func(spd, "ip", &spc_handler_tpic_ip);
+ spc_def_func(spd, "da", &spc_handler_tpic_da);
+ spc_def_func(spd, "dt", &spc_handler_tpic_dt);
+ spc_def_func(spd, "sp", &spc_handler_tpic_sp);
+ spc_def_func(spd, "ar", &spc_handler_tpic_ar);
+ spc_def_func(spd, "ia", &spc_handler_tpic_ia);
+ spc_def_func(spd, "sh", &spc_handler_tpic_sh);
+ spc_def_func(spd, "wh", &spc_handler_tpic_wh);
+ spc_def_func(spd, "bk", &spc_handler_tpic_bk);
+ spc_def_func(spd, "tx", &spc_handler_tpic_tx);
+
+ spc_add_special(spe, "tpic", spd, sd);
+
+ return 0;
+}
+#endif /* 0 */
diff --git a/Build/source/texk/dvipdfm-x/spc_tpic.h b/Build/source/texk/dvipdfm-x/spc_tpic.h
new file mode 100644
index 00000000000..c56279d2957
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_tpic.h
@@ -0,0 +1,39 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_TPIC_H_
+#define _SPC_TPIC_H_
+
+#include "specials.h"
+
+extern void tpic_set_fill_mode (int mode);
+
+extern int spc_tpic_at_begin_page (void);
+extern int spc_tpic_at_end_page (void);
+extern int spc_tpic_at_begin_document (void);
+extern int spc_tpic_at_end_document (void);
+
+extern int spc_tpic_check_special (const char *buffer, int size);
+extern int spc_tpic_setup_handler (struct spc_handler *handle,
+ struct spc_env *spe, struct spc_arg *args);
+
+#endif /* _SPC_TPIC_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_util.c b/Build/source/texk/dvipdfm-x/spc_util.c
new file mode 100644
index 00000000000..efe44bef6b6
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_util.c
@@ -0,0 +1,1204 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxutil.h"
+
+#include "pdfdoc.h"
+#include "pdfdev.h"
+#include "pdfparse.h"
+#include "pdfcolor.h"
+#include "pdfdraw.h"
+#include "pdfresource.h"
+
+#include "specials.h"
+
+#include "spc_util.h"
+
+
+#ifndef ISBLANK
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+static void
+skip_blank (const char **pp, const char *endptr)
+{
+ const char *p = *pp;
+ for ( ; p < endptr && ISBLANK(*p); p++);
+ *pp = p;
+}
+
+
+/* From pdfcolor.c */
+static int pdf_color_namedcolor (pdf_color *color, const char *colorname);
+
+int
+spc_util_read_numbers (double *values, int num_values, struct spc_arg *args)
+{
+ int count;
+ char *q;
+
+ skip_blank(&args->curptr, args->endptr);
+ for (count = 0;
+ count < num_values &&
+ args->curptr < args->endptr; ) {
+ q = parse_float_decimal(&args->curptr, args->endptr);
+ if (!q)
+ break;
+ else {
+ values[count] = atof(q);
+ RELEASE(q);
+ skip_blank(&args->curptr, args->endptr);
+ count++;
+ }
+ }
+
+ return count;
+}
+
+static void
+rgb_color_from_hsv (pdf_color *color, double h, double s, double v)
+{
+ double r, g, b;
+ ASSERT( color );
+ r = g = b = v;
+ if (s != 0.0) {
+ double h6, f, v1, v2, v3;
+ int i;
+ h6 = h * 6; /* 360 / 60 */
+ i = (int) h6;
+ f = h6 - i;
+ v1 = v * (1 - s);
+ v2 = v * (1 - s * f);
+ v3 = v * (1 - s * (1 - f));
+ switch (i) {
+ case 0: r = v ; g = v3; b = v1; break;
+ case 1: r = v2; g = v ; b = v1; break;
+ case 2: r = v1; g = v ; b = v3; break;
+ case 3: r = v1; g = v2; b = v ; break;
+ case 4: r = v3; g = v1; b = v ; break;
+ case 5: r = v ; g = v1; b = v2; break;
+ case 6: r = v ; g = v1; b = v2; break;
+ }
+ }
+ pdf_color_rgbcolor(color, r, g, b);
+}
+
+static int
+spc_read_color_color (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap)
+{
+ char *q;
+ double cv[4];
+ int nc;
+ int error = 0;
+
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (!q) {
+ spc_warn(spe, "No valid color specified?");
+ return -1;
+ }
+ skip_blank(&ap->curptr, ap->endptr);
+
+ if (!strcmp(q, "rgb")) { /* Handle rgb color */
+ nc = spc_util_read_numbers(cv, 3, ap);
+ if (nc != 3) {
+ spc_warn(spe, "Invalid value for RGB color specification.");
+ error = -1;
+ } else {
+ pdf_color_rgbcolor(colorspec, cv[0], cv[1], cv[2]);
+ }
+ } else if (!strcmp(q, "cmyk")) { /* Handle cmyk color */
+ nc = spc_util_read_numbers(cv, 4, ap);
+ if (nc != 4) {
+ spc_warn(spe, "Invalid value for CMYK color specification.");
+ error = -1;
+ } else {
+ pdf_color_cmykcolor(colorspec, cv[0], cv[1], cv[2], cv[3]);
+ }
+ } else if (!strcmp(q, "gray")) { /* Handle gray */
+ nc = spc_util_read_numbers(cv, 1, ap);
+ if (nc != 1) {
+ spc_warn(spe, "Invalid value for gray color specification.");
+ error = -1;
+ } else {
+ pdf_color_graycolor(colorspec, cv[0]);
+ }
+ } else if (!strcmp(q, "spot")) { /* Handle spot colors */
+ char *color_name = parse_c_ident(&ap->curptr, ap->endptr);
+ if (!color_name) {
+ spc_warn(spe, "No valid spot color name specified?");
+ return -1;
+ }
+ skip_blank(&ap->curptr, ap->endptr);
+ nc = spc_util_read_numbers(cv, 1, ap);
+ if (nc != 1) {
+ spc_warn(spe, "Invalid value for spot color specification.");
+ error = -1;
+ free(color_name);
+ } else {
+ pdf_color_spotcolor(colorspec, color_name, cv[0]);
+ }
+ } else if (!strcmp(q, "hsb")) {
+ nc = spc_util_read_numbers(cv, 3, ap);
+ if (nc != 3) {
+ spc_warn(spe, "Invalid value for HSB color specification.");
+ error = -1;
+ } else {
+ rgb_color_from_hsv(colorspec, cv[0], cv[1], cv[2]);
+ spc_warn(spe, "HSB color converted to RGB: hsb: <%g, %g, %g> ==> rgb: <%g, %g, %g>",
+ cv[0], cv[1], cv[2],
+ colorspec->values[0], colorspec->values[1], colorspec->values[2]);
+ }
+ } else { /* Must be a "named" color */
+ error = pdf_color_namedcolor(colorspec, q);
+ if (error)
+ spc_warn(spe, "Unrecognized color name: %s", q);
+ }
+ RELEASE(q);
+
+ return error;
+}
+
+/* Argument for this is PDF_Number or PDF_Array.
+ * But we ignore that since we don't want to add
+ * dependency to pdfxxx and @foo can not be
+ * allowed for color specification. "pdf" here
+ * means pdf: special syntax.
+ */
+static int
+spc_read_color_pdf (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap)
+{
+ double cv[PDF_COLOR_COMPONENT_MAX]; /* dvipdfmx limit */
+ int nc = -1, type = PDF_COLORSPACE_TYPE_INVALID, isarry = 0;
+ int error = 0;
+ char *q;
+
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr[0] == '@') {
+ char *ident = NULL;
+ int res_id = -1;
+ char *name = NULL;
+
+ ident = parse_opt_ident(&ap->curptr, ap->endptr);
+ skip_blank(&ap->curptr, ap->endptr);
+ res_id = pdf_findresource("ColorSpace", ident);
+ {
+ pdf_obj *cspace, *csname;
+
+ cspace = spc_lookup_object(ident);
+ if (!cspace || !PDF_OBJ_ARRAYTYPE(cspace)) {
+ WARN("Couldn't find ColorSpace resource for \"@%s\"... (or not an array object?)", ident);
+ RELEASE(ident);
+ return -1;
+ }
+ csname = pdf_get_array(cspace, 0);
+ if (!csname || !PDF_OBJ_NAMETYPE(csname)) {
+ WARN("Invalid ColorSpace resource for \"@%s\" found...", ident);
+ RELEASE(ident);
+ return -1;
+ }
+
+ name = pdf_name_value(csname);
+ if (!strcmp(name, "Separation")) {
+ type = PDF_COLORSPACE_TYPE_SEPARATION;
+ } else if (!strcmp(name, "CalGray")) {
+ type = PDF_COLORSPACE_TYPE_CALGRAY;
+ nc = 1;
+ } else if (!strcmp(name, "CalRGB")) {
+ type = PDF_COLORSPACE_TYPE_CALRGB;
+ nc = 3;
+ } else if (!strcmp(name, "LAB")) {
+ type = PDF_COLORSPACE_TYPE_LAB;
+ nc = 3;
+ } else if (!strcmp(name, "ICCBased")) {
+ type = PDF_COLORSPACE_TYPE_ICCBASED;
+ nc = -1;
+ } else if (!strcmp(name, "DeviceN")) {
+ type = PDF_COLORSPACE_TYPE_DEVICEN;
+ nc = -1;
+ } else if (!strcmp(name, "Indexed")) {
+ type = PDF_COLORSPACE_TYPE_INDEXED;
+ nc = 1;
+ } else if (!strcmp(name, "Pattern")) {
+ type = PDF_COLORSPACE_TYPE_PATTERN;
+ nc = -1;
+ } else {
+ WARN("Specified object \"%s\" not a ColorSpace???", ident);
+ return -1;
+ }
+ if (res_id < 0) {
+ res_id = pdf_defineresource("ColorSpace", ident, pdf_link_obj(cspace), 0);
+ }
+ RELEASE(ident);
+ }
+
+ colorspec->res_id = res_id;
+ colorspec->type = type;
+ if (ap->curptr[0] == '[') {
+ ap->curptr++; skip_blank(&ap->curptr, ap->endptr);
+ isarry = 1;
+ }
+ if (nc > 0) {
+ int n;
+ n = spc_util_read_numbers(cv, nc, ap);
+ if (n != nc) {
+ WARN("Wrong number of color components...");
+ return -1;
+ }
+ } else {
+ nc = spc_util_read_numbers(cv, PDF_COLOR_COMPONENT_MAX, ap);
+ }
+ colorspec->num_components = nc;
+ while (nc-- > 0) {
+ colorspec->values[nc] = cv[nc];
+ }
+ if (type == PDF_COLORSPACE_TYPE_PATTERN) {
+ /* reference appears */
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr[0] != '@') {
+ WARN("An object reference expected but not found for Pattern!");
+ return -1;
+ }
+ ident = parse_opt_ident(&ap->curptr, ap->endptr);
+ res_id = pdf_findresource("Pattern", ident);
+ if (res_id < 0) {
+ pdf_obj *pattern = spc_lookup_object(ident);
+ /* Skip checking. /Type entry is optional... */
+ res_id = pdf_defineresource("Pattern", ident, pdf_link_obj(pattern), 0);
+ }
+ colorspec->pattern_id = res_id;
+ RELEASE(ident);
+ }
+ if (isarry) {
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr || ap->curptr[0] != ']') {
+ spc_warn(spe, "Unbalanced '[' and ']' or wrong number of color components in color specification?");
+ error = -1;
+ } else {
+ ap->curptr++;
+ }
+ }
+ } else if (ap->curptr[0] == '/') { /* /DeviceGray... */
+ pdf_obj *csname;
+ csname = parse_pdf_name(&ap->curptr, ap->endptr);
+ if (!csname) {
+ WARN("Failed to read a name object while parsing colorspecification...");
+ return -1;
+ } else {
+ char *name = pdf_name_value(csname);
+ if (!strcmp(name, "DeviceGray")) {
+ type = PDF_COLORSPACE_TYPE_DEVICEGRAY;
+ nc = 1;
+ } else if (!strcmp(name, "DeviceRGB")) {
+ type = PDF_COLORSPACE_TYPE_DEVICERGB;
+ nc = 3;
+ } else if (!strcmp(name, "DeviceCMYK")) {
+ type = PDF_COLORSPACE_TYPE_DEVICECMYK;
+ nc = 4;
+ } else if (!strcmp(name, "Pattern")) {
+ type = PDF_COLORSPACE_TYPE_PATTERN;
+ nc = 0;
+ } else {
+ WARN("Unknown ColorSpace name specified: %s", name);
+ return -1;
+ }
+ pdf_release_obj(csname);
+ skip_blank(&ap->curptr, ap->endptr);
+ }
+ colorspec->res_id = -1;
+ colorspec->type = type;
+ if (ap->curptr[0] == '[') {
+ ap->curptr++; skip_blank(&ap->curptr, ap->endptr);
+ isarry = 1;
+ }
+ {
+ int n = spc_util_read_numbers(cv, nc, ap);
+ if (n != nc) {
+ WARN("Wrong number of color components for this ColorSpace...");
+ return -1;
+ }
+ }
+ colorspec->num_components = nc;
+ while (nc-- > 0) {
+ colorspec->values[nc] = cv[nc];
+ }
+ if (type == PDF_COLORSPACE_TYPE_PATTERN) {
+ char *ident = NULL;
+ int res_id = -1;
+ /* reference appears */
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr[0] != '@') {
+ WARN("An object reference expected but not found for Pattern!");
+ return -1;
+ }
+ ident = parse_opt_ident(&ap->curptr, ap->endptr);
+ res_id = pdf_findresource("Pattern", ident);
+ if (res_id < 0) {
+ pdf_obj *pattern = spc_lookup_object(ident);
+ /* Skip checking. /Type entry is optional... */
+ res_id = pdf_defineresource("Pattern", ident, pdf_link_obj(pattern), 0);
+ }
+ colorspec->pattern_id = res_id;
+ RELEASE(ident);
+ }
+ if (isarry) {
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr || ap->curptr[0] != ']') {
+ spc_warn(spe, "Unbalanced '[' and ']' or wrong number of color components in color specification?");
+ error = -1;
+ } else {
+ ap->curptr++;
+ }
+ }
+ } else {
+ if (ap->curptr[0] == '[') {
+ ap->curptr++; skip_blank(&ap->curptr, ap->endptr);
+ isarry = 1;
+ }
+ nc = spc_util_read_numbers(cv, 4, ap);
+ switch (nc) {
+ case 1:
+ pdf_color_graycolor(colorspec, cv[0]);
+ break;
+ case 3:
+ pdf_color_rgbcolor (colorspec, cv[0], cv[1], cv[2]);
+ break;
+ case 4:
+ pdf_color_cmykcolor(colorspec, cv[0], cv[1], cv[2], cv[3]);
+ break;
+ default:
+ /* Try to read the color names defined in dvipsname.def */
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (!q) {
+ spc_warn(spe, "No valid color specified?");
+ return -1;
+ }
+ error = pdf_color_namedcolor(colorspec, q);
+ if (error)
+ spc_warn(spe, "Unrecognized color name: %s, keep the current color", q);
+ RELEASE(q);
+ break;
+ }
+ if (isarry) {
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr || ap->curptr[0] != ']') {
+ spc_warn(spe, "Unbalanced '[' and ']' in color specification.");
+ error = -1;
+ } else {
+ ap->curptr++;
+ }
+ }
+ }
+
+ return error;
+}
+
+/* This is for reading *single* color specification. */
+int
+spc_util_read_colorspec (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap, int syntax)
+{
+ ASSERT(colorspec && spe && ap);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr) {
+ return -1;
+ }
+
+ pdf_color_black(colorspec); /* As initialization... */
+ if (syntax)
+ return spc_read_color_color(spe, colorspec, ap);
+ else
+ return spc_read_color_pdf(spe, colorspec, ap);
+}
+
+int
+spc_util_read_pdfcolor (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap, pdf_color *defaultcolor)
+{
+ int error = 0;
+
+ ASSERT(colorspec && spe && ap);
+
+ skip_blank(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr) {
+ return -1;
+ }
+ error = spc_read_color_pdf(spe, colorspec, ap);
+ if (error < 0 && defaultcolor) {
+ pdf_color_copycolor(colorspec, defaultcolor);
+ error = 0;
+ }
+ return error;
+}
+
+/* This need to allow 'true' prefix for unit and
+ * length value must be divided by current magnification.
+ */
+static int
+spc_util_read_length (struct spc_env *spe, double *vp /* ret. */, struct spc_arg *ap)
+{
+ char *q;
+ double v, u = 1.0;
+ const char *ukeys[] = {
+#define K_UNIT__PT 0
+#define K_UNIT__IN 1
+#define K_UNIT__CM 2
+#define K_UNIT__MM 3
+#define K_UNIT__BP 4
+#define K_UNIT__PC 5
+#define K_UNIT__DD 6
+#define K_UNIT__CC 7
+#define K_UNIT__SP 8
+ "pt", "in", "cm", "mm", "bp", "pc", "dd", "cc", "sp", NULL
+ };
+ int k, error = 0;
+
+ q = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!q)
+ return -1;
+
+ v = atof(q);
+ RELEASE(q);
+
+ skip_white(&ap->curptr, ap->endptr);
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (q) {
+ char *qq = q;
+ if (strlen(q) >= strlen("true") &&
+ !memcmp(q, "true", strlen("true"))) {
+ u /= spe->mag != 0.0 ? spe->mag : 1.0; /* inverse magnify */
+ q += strlen("true");
+
+ if (!*q) {
+ RELEASE(qq);
+ skip_white(&ap->curptr, ap->endptr);
+ qq = q = parse_c_ident(&ap->curptr, ap->endptr);
+ }
+ }
+
+ if (q) {
+ for (k = 0; ukeys[k] && strcmp(ukeys[k], q); k++);
+ switch (k) {
+ case K_UNIT__PT: u *= 72.0 / 72.27; break;
+ case K_UNIT__IN: u *= 72.0; break;
+ case K_UNIT__CM: u *= 72.0 / 2.54 ; break;
+ case K_UNIT__MM: u *= 72.0 / 25.4 ; break;
+ case K_UNIT__BP: u *= 1.0 ; break;
+ case K_UNIT__PC: u *= 12.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__DD: u *= 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__CC: u *= 12.0 * 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__SP: u *= 72.0 / (72.27 * 65536) ; break;
+ default:
+ spc_warn(spe, "Unknown unit of measure: %s", q);
+ error = -1;
+ break;
+ }
+ RELEASE(qq);
+ }
+ else {
+ spc_warn(spe, "Missing unit of measure after \"true\"");
+ error = -1;
+ }
+ }
+
+ *vp = v * u;
+ return error;
+}
+
+
+/*
+ * Compute a transformation matrix
+ * transformations are applied in the following
+ * order: scaling, rotate, displacement.
+ */
+static void
+make_transmatrix (pdf_tmatrix *M,
+ double xoffset, double yoffset,
+ double xscale, double yscale,
+ double rotate)
+{
+ double c, s;
+
+ c = cos(rotate);
+ s = sin(rotate);
+
+ M->a = xscale * c; M->b = xscale * s;
+ M->c = -yscale * s; M->d = yscale * c;
+ M->e = xoffset; M->f = yoffset;
+}
+
+static int
+spc_read_dimtrns_dvips (struct spc_env *spe,
+ transform_info *t, struct spc_arg *ap)
+{
+ static const char *_dtkeys[] = {
+#define K_TRN__HOFFSET 0
+#define K_TRN__VOFFSET 1
+ "hoffset", "voffset",
+#define K_DIM__HSIZE 2
+#define K_DIM__VSIZE 3
+ "hsize", "vsize",
+#define K_TRN__HSCALE 4
+#define K_TRN__VSCALE 5
+ "hscale", "vscale",
+#define K_TRN__ANGLE 6
+ "angle",
+#define K__CLIP 7
+ "clip",
+#define K_DIM__LLX 8
+#define K_DIM__LLY 9
+#define K_DIM__URX 10
+#define K_DIM__URY 11
+ "llx", "lly", "urx", "ury",
+#define K_DIM__RWI 12
+#define K_DIM__RHI 13
+ "rwi", "rhi",
+ NULL
+ };
+ double xoffset, yoffset, xscale, yscale, rotate;
+ int error = 0;
+
+ xoffset = yoffset = rotate = 0.0; xscale = yscale = 1.0;
+
+ skip_blank(&ap->curptr, ap->endptr);
+ while (!error && ap->curptr < ap->endptr) {
+ char *kp, *vp;
+ int k;
+
+ kp = parse_c_ident(&ap->curptr, ap->endptr);
+ if (!kp)
+ break;
+
+ for (k = 0; _dtkeys[k] && strcmp(kp, _dtkeys[k]); k++);
+ if (!_dtkeys[k]) {
+ spc_warn(spe, "Unrecognized dimension/transformation key: %s", kp);
+ error = -1;
+ RELEASE(kp);
+ break;
+ }
+
+ skip_blank(&ap->curptr, ap->endptr);
+ if (k == K__CLIP) {
+ t->flags |= INFO_DO_CLIP;
+ RELEASE(kp);
+ continue; /* not key-value */
+ }
+
+ if (ap->curptr < ap->endptr && ap->curptr[0] == '=') {
+ ap->curptr++;
+ skip_blank(&ap->curptr, ap->endptr);
+ }
+
+ vp = NULL;
+ if (ap->curptr[0] == '\'' || ap->curptr[0] == '\"') {
+ char qchr = ap->curptr[0];
+ ap->curptr++;
+ skip_blank(&ap->curptr, ap->endptr);
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ skip_blank(&ap->curptr, ap->endptr);
+ if (vp && qchr != ap->curptr[0]) {
+ spc_warn(spe, "Syntax error in dimension/transformation specification.");
+ error = -1;
+ RELEASE(vp); vp = NULL;
+ }
+ ap->curptr++;
+ } else {
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ }
+ if (!error && !vp) {
+ spc_warn(spe, "Missing value for dimension/transformation: %s", kp);
+ error = -1;
+ }
+ RELEASE(kp);
+ if (!vp || error) {
+ break;
+ }
+
+ switch (k) {
+ case K_TRN__HOFFSET:
+ xoffset = atof(vp);
+ break;
+ case K_TRN__VOFFSET:
+ yoffset = atof(vp);
+ break;
+ case K_DIM__HSIZE:
+ t->width = atof(vp);
+ t->flags |= INFO_HAS_WIDTH;
+ break;
+ case K_DIM__VSIZE:
+ t->height = atof(vp);
+ t->flags |= INFO_HAS_HEIGHT;
+ break;
+ case K_TRN__HSCALE:
+ xscale = atof(vp) / 100.0;
+ break;
+ case K_TRN__VSCALE:
+ yscale = atof(vp) / 100.0;
+ break;
+ case K_TRN__ANGLE:
+ rotate = M_PI * atof(vp) / 180.0;
+ break;
+ case K_DIM__LLX:
+ t->bbox.llx = atof(vp);
+ t->flags |= INFO_HAS_USER_BBOX;
+ break;
+ case K_DIM__LLY:
+ t->bbox.lly = atof(vp);
+ t->flags |= INFO_HAS_USER_BBOX;
+ break;
+ case K_DIM__URX:
+ t->bbox.urx = atof(vp);
+ t->flags |= INFO_HAS_USER_BBOX;
+ break;
+ case K_DIM__URY:
+ t->bbox.ury = atof(vp);
+ t->flags |= INFO_HAS_USER_BBOX;
+ break;
+ case K_DIM__RWI:
+ t->width = atof(vp) / 10.0;
+ t->flags |= INFO_HAS_WIDTH;
+ break;
+ case K_DIM__RHI:
+ t->height = atof(vp) / 10.0;
+ t->flags |= INFO_HAS_HEIGHT;
+ break;
+ }
+ skip_blank(&ap->curptr, ap->endptr);
+ RELEASE(vp);
+ }
+ make_transmatrix(&(t->matrix), xoffset, yoffset, xscale, yscale, rotate);
+
+ return error;
+}
+
+/* "page" and "pagebox" are not dimension nor transformation nor
+ * something acceptable to put into here.
+ * PLEASE DONT ADD HERE!
+ */
+static int
+spc_read_dimtrns_pdfm (struct spc_env *spe,
+ transform_info *p, struct spc_arg *ap)
+{
+ int has_scale, has_xscale, has_yscale, has_rotate, has_matrix;
+ const char *_dtkeys[] = {
+#define K_DIM__WIDTH 0
+#define K_DIM__HEIGHT 1
+#define K_DIM__DEPTH 2
+ "width", "height", "depth",
+#define K_TRN__SCALE 3
+#define K_TRN__XSCALE 4
+#define K_TRN__YSCALE 5
+#define K_TRN__ROTATE 6
+ "scale", "xscale", "yscale", "rotate", /* See "Dvipdfmx User's Manual", p.5 */
+#define K_TRN__BBOX 7
+ "bbox", /* See "Dvipdfmx User's Manual", p.5 */
+#define K_TRN__MATRIX 8
+ "matrix",
+#undef K__CLIP
+#define K__CLIP 9
+ "clip",
+#define K__HIDE 10
+ "hide",
+ NULL
+ };
+ double xscale, yscale, rotate;
+ int error = 0;
+
+ has_xscale = has_yscale = has_scale = has_rotate = has_matrix = 0;
+ xscale = yscale = 1.0; rotate = 0.0;
+ p->flags |= INFO_DO_CLIP; /* default: do clipping */
+ p->flags &= ~INFO_DO_HIDE; /* default: do clipping */
+
+ skip_blank(&ap->curptr, ap->endptr);
+
+ while (!error && ap->curptr < ap->endptr) {
+ char *kp, *vp;
+ int k;
+
+ kp = parse_c_ident(&ap->curptr, ap->endptr);
+ if (!kp)
+ break;
+
+ skip_blank(&ap->curptr, ap->endptr);
+ for (k = 0; _dtkeys[k] && strcmp(_dtkeys[k], kp); k++);
+ switch (k) {
+ case K_DIM__WIDTH:
+ error = spc_util_read_length(spe, &p->width , ap);
+ p->flags |= INFO_HAS_WIDTH;
+ break;
+ case K_DIM__HEIGHT:
+ error = spc_util_read_length(spe, &p->height, ap);
+ p->flags |= INFO_HAS_HEIGHT;
+ break;
+ case K_DIM__DEPTH:
+ error = spc_util_read_length(spe, &p->depth , ap);
+ p->flags |= INFO_HAS_HEIGHT;
+ break;
+ case K_TRN__SCALE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ xscale = yscale = atof(vp);
+ has_scale = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__XSCALE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ xscale = atof(vp);
+ has_xscale = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__YSCALE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ yscale = atof(vp);
+ has_yscale = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__ROTATE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ rotate = M_PI * atof(vp) / 180.0;
+ has_rotate = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__BBOX:
+ {
+ double v[4];
+ if (spc_util_read_numbers(v, 4, ap) != 4)
+ error = -1;
+ else {
+ p->bbox.llx = v[0];
+ p->bbox.lly = v[1];
+ p->bbox.urx = v[2];
+ p->bbox.ury = v[3];
+ p->flags |= INFO_HAS_USER_BBOX;
+ }
+ }
+ break;
+ case K_TRN__MATRIX:
+ {
+ double v[6];
+ if (spc_util_read_numbers(v, 6, ap) != 6)
+ error = -1;
+ else {
+ pdf_setmatrix(&(p->matrix), v[0], v[1], v[2], v[3], v[4], v[5]);
+ has_matrix = 1;
+ }
+ }
+ break;
+ case K__CLIP:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ if (atof(vp))
+ p->flags |= INFO_DO_CLIP;
+ else
+ p->flags &= ~INFO_DO_CLIP;
+ RELEASE(vp);
+ }
+ break;
+ case K__HIDE:
+ p->flags |= INFO_DO_HIDE;
+ break;
+
+ default:
+ error = -1;
+ break;
+ }
+ if (error)
+ spc_warn(spe, "Unrecognized key or invalid value for " \
+ "dimension/transformation: %s", kp);
+ else
+ skip_blank(&ap->curptr, ap->endptr);
+ RELEASE(kp);
+ }
+
+ if (!error) {
+ /* Check consistency */
+ if (has_xscale && (p->flags & INFO_HAS_WIDTH)) {
+ spc_warn(spe, "Can't supply both width and xscale. Ignore xscale.");
+ xscale = 1.0;
+ } else if (has_yscale &&
+ (p->flags & INFO_HAS_HEIGHT)) {
+ spc_warn(spe, "Can't supply both height/depth and yscale. Ignore yscale.");
+ yscale = 1.0;
+ } else if (has_scale &&
+ (has_xscale || has_yscale)) {
+ spc_warn(spe, "Can't supply overall scale along with axis scales.");
+ error = -1;
+ } else if (has_matrix &&
+ (has_scale || has_xscale || has_yscale || has_rotate)) {
+ spc_warn(spe, "Can't supply transform matrix along with scales or rotate. Ignore scales and rotate.");
+ }
+ }
+
+ if (!has_matrix) {
+ make_transmatrix(&(p->matrix), 0.0, 0.0, xscale, yscale, rotate);
+ }
+
+ if (!(p->flags & INFO_HAS_USER_BBOX)) {
+ p->flags &= ~INFO_DO_CLIP; /* no clipping needed */
+ }
+
+ return error;
+}
+
+int
+spc_util_read_dimtrns (struct spc_env *spe,
+ transform_info *ti, struct spc_arg *args, int syntax)
+{
+ if (!ti || !spe || !args)
+ return -1;
+
+ if (syntax) {
+ return spc_read_dimtrns_dvips(spe, ti, args);
+ } else {
+ return spc_read_dimtrns_pdfm (spe, ti, args);
+ }
+}
+
+int
+spc_util_read_blahblah (struct spc_env *spe,
+ transform_info *p, int *page_no,
+ enum pdf_page_boundary *bbox_type,
+ struct spc_arg *ap)
+{
+ int has_scale, has_xscale, has_yscale, has_rotate, has_matrix;
+ const char *_dtkeys[] = {
+ "width", "height", "depth",
+ "scale", "xscale", "yscale", "rotate",
+ "bbox",
+ "matrix",
+ "clip",
+ "hide",
+#define K__PAGE 11
+ "page",
+#define K__PAGEBOX 12
+ "pagebox",
+ NULL
+ };
+ double xscale, yscale, rotate;
+ int error = 0;
+
+ has_xscale = has_yscale = has_scale = has_rotate = has_matrix = 0;
+ xscale = yscale = 1.0; rotate = 0.0;
+ p->flags |= INFO_DO_CLIP; /* default: do clipping */
+ p->flags &= ~INFO_DO_HIDE; /* default: do clipping */
+
+ skip_blank(&ap->curptr, ap->endptr);
+
+ while (!error && ap->curptr < ap->endptr) {
+ char *kp, *vp;
+ int k;
+
+ kp = parse_c_ident(&ap->curptr, ap->endptr);
+ if (!kp)
+ break;
+
+ skip_blank(&ap->curptr, ap->endptr);
+ for (k = 0; _dtkeys[k] && strcmp(_dtkeys[k], kp); k++);
+ switch (k) {
+ case K_DIM__WIDTH:
+ error = spc_util_read_length(spe, &p->width , ap);
+ p->flags |= INFO_HAS_WIDTH;
+ break;
+ case K_DIM__HEIGHT:
+ error = spc_util_read_length(spe, &p->height, ap);
+ p->flags |= INFO_HAS_HEIGHT;
+ break;
+ case K_DIM__DEPTH:
+ error = spc_util_read_length(spe, &p->depth , ap);
+ p->flags |= INFO_HAS_HEIGHT;
+ break;
+ case K_TRN__SCALE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ xscale = yscale = atof(vp);
+ has_scale = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__XSCALE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ xscale = atof(vp);
+ has_xscale = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__YSCALE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ yscale = atof(vp);
+ has_yscale = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__ROTATE:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ rotate = M_PI * atof(vp) / 180.0;
+ has_rotate = 1;
+ RELEASE(vp);
+ }
+ break;
+ case K_TRN__BBOX:
+ {
+ double v[4];
+ if (spc_util_read_numbers(v, 4, ap) != 4)
+ error = -1;
+ else {
+ p->bbox.llx = v[0];
+ p->bbox.lly = v[1];
+ p->bbox.urx = v[2];
+ p->bbox.ury = v[3];
+ p->flags |= INFO_HAS_USER_BBOX;
+ }
+ }
+ break;
+ case K_TRN__MATRIX:
+ {
+ double v[6];
+ if (spc_util_read_numbers(v, 6, ap) != 6)
+ error = -1;
+ else {
+ pdf_setmatrix(&(p->matrix), v[0], v[1], v[2], v[3], v[4], v[5]);
+ has_matrix = 1;
+ }
+ }
+ break;
+ case K__CLIP:
+ vp = parse_float_decimal(&ap->curptr, ap->endptr);
+ if (!vp)
+ error = -1;
+ else {
+ if (atof(vp))
+ p->flags |= INFO_DO_CLIP;
+ else
+ p->flags &= ~INFO_DO_CLIP;
+ RELEASE(vp);
+ }
+ break;
+
+ case K__PAGE:
+ {
+ double page;
+ if (page_no && spc_util_read_numbers(&page, 1, ap) == 1)
+ *page_no = (int) page;
+ else
+ error = -1;
+ }
+ break;
+ case K__HIDE:
+ p->flags |= INFO_DO_HIDE;
+ break;
+ case K__PAGEBOX:
+ {
+ char *q;
+ q = parse_c_ident (&ap->curptr, ap->endptr);
+ if (q) {
+ if (bbox_type) {
+ if (strcasecmp(q, "cropbox") == 0) *bbox_type = pdf_page_boundary_cropbox;
+ else if (strcasecmp(q, "mediabox") == 0) *bbox_type = pdf_page_boundary_mediabox;
+ else if (strcasecmp(q, "artbox") == 0) *bbox_type = pdf_page_boundary_artbox;
+ else if (strcasecmp(q, "trimbox") == 0) *bbox_type = pdf_page_boundary_trimbox;
+ else if (strcasecmp(q, "bleedbox") == 0) *bbox_type = pdf_page_boundary_bleedbox;
+ }
+ RELEASE(q);
+ } else if (bbox_type) {
+ *bbox_type = pdf_page_boundary__auto;
+ }
+ }
+ break;
+
+ default:
+ error = -1;
+ break;
+ }
+ if (error)
+ spc_warn(spe, "Unrecognized key or invalid value for " \
+ "dimension/transformation: %s", kp);
+ else
+ skip_blank(&ap->curptr, ap->endptr);
+ RELEASE(kp);
+ }
+
+ if (!error) {
+ /* Check consistency */
+ if (has_xscale && (p->flags & INFO_HAS_WIDTH)) {
+ spc_warn(spe, "Can't supply both width and xscale. Ignore xscale.");
+ xscale = 1.0;
+ } else if (has_yscale &&
+ (p->flags & INFO_HAS_HEIGHT)) {
+ spc_warn(spe, "Can't supply both height/depth and yscale. Ignore yscale.");
+ yscale = 1.0;
+ } else if (has_scale &&
+ (has_xscale || has_yscale)) {
+ spc_warn(spe, "Can't supply overall scale along with axis scales.");
+ error = -1;
+ } else if (has_matrix &&
+ (has_scale || has_xscale || has_yscale || has_rotate)) {
+ spc_warn(spe, "Can't supply transform matrix along with scales or rotate. Ignore scales and rotate.");
+ }
+ }
+
+ if (!has_matrix) {
+ make_transmatrix(&(p->matrix), 0.0, 0.0, xscale, yscale, rotate);
+ }
+
+ if (!(p->flags & INFO_HAS_USER_BBOX)) {
+ p->flags &= ~INFO_DO_CLIP; /* no clipping needed */
+ }
+
+ return error;
+}
+
+/* Color names */
+#ifdef rgb
+#undef rgb
+#endif
+#ifdef cmyk
+#undef cmyk
+#endif
+#define gray(g) {-1, PDF_COLORSPACE_TYPE_GRAY, 1, NULL, {g}, -1}
+#define rgb8(r,g,b) {-1, PDF_COLORSPACE_TYPE_RGB, 3, NULL, {((r)/255.0), ((g)/255.0), ((b)/255.0), 0.0}, -1}
+#define cmyk(c,m,y,k) {-1, PDF_COLORSPACE_TYPE_CMYK, 4, NULL, {(c), (m), (y), (k)}, -1}
+
+static struct colordef_
+{
+ const char *key;
+ pdf_color color;
+} colordefs[] = {
+ {"GreenYellow", cmyk(0.15, 0.00, 0.69, 0.00)},
+ {"Yellow", cmyk(0.00, 0.00, 1.00, 0.00)},
+ {"Goldenrod", cmyk(0.00, 0.10, 0.84, 0.00)},
+ {"Dandelion", cmyk(0.00, 0.29, 0.84, 0.00)},
+ {"Apricot", cmyk(0.00, 0.32, 0.52, 0.00)},
+ {"Peach", cmyk(0.00, 0.50, 0.70, 0.00)},
+ {"Melon", cmyk(0.00, 0.46, 0.50, 0.00)},
+ {"YellowOrange", cmyk(0.00, 0.42, 1.00, 0.00)},
+ {"Orange", cmyk(0.00, 0.61, 0.87, 0.00)},
+ {"BurntOrange", cmyk(0.00, 0.51, 1.00, 0.00)},
+ {"Bittersweet", cmyk(0.00, 0.75, 1.00, 0.24)},
+ {"RedOrange", cmyk(0.00, 0.77, 0.87, 0.00)},
+ {"Mahogany", cmyk(0.00, 0.85, 0.87, 0.35)},
+ {"Maroon", cmyk(0.00, 0.87, 0.68, 0.32)},
+ {"BrickRed", cmyk(0.00, 0.89, 0.94, 0.28)},
+ {"Red", cmyk(0.00, 1.00, 1.00, 0.00)},
+ {"OrangeRed", cmyk(0.00, 1.00, 0.50, 0.00)},
+ {"RubineRed", cmyk(0.00, 1.00, 0.13, 0.00)},
+ {"WildStrawberry", cmyk(0.00, 0.96, 0.39, 0.00)},
+ {"Salmon", cmyk(0.00, 0.53, 0.38, 0.00)},
+ {"CarnationPink", cmyk(0.00, 0.63, 0.00, 0.00)},
+ {"Magenta", cmyk(0.00, 1.00, 0.00, 0.00)},
+ {"VioletRed", cmyk(0.00, 0.81, 0.00, 0.00)},
+ {"Rhodamine", cmyk(0.00, 0.82, 0.00, 0.00)},
+ {"Mulberry", cmyk(0.34, 0.90, 0.00, 0.02)},
+ {"RedViolet", cmyk(0.07, 0.90, 0.00, 0.34)},
+ {"Fuchsia", cmyk(0.47, 0.91, 0.00, 0.08)},
+ {"Lavender", cmyk(0.00, 0.48, 0.00, 0.00)},
+ {"Thistle", cmyk(0.12, 0.59, 0.00, 0.00)},
+ {"Orchid", cmyk(0.32, 0.64, 0.00, 0.00)},
+ {"DarkOrchid", cmyk(0.40, 0.80, 0.20, 0.00)},
+ {"Purple", cmyk(0.45, 0.86, 0.00, 0.00)},
+ {"Plum", cmyk(0.50, 1.00, 0.00, 0.00)},
+ {"Violet", cmyk(0.79, 0.88, 0.00, 0.00)},
+ {"RoyalPurple", cmyk(0.75, 0.90, 0.00, 0.00)},
+ {"BlueViolet", cmyk(0.86, 0.91, 0.00, 0.04)},
+ {"Periwinkle", cmyk(0.57, 0.55, 0.00, 0.00)},
+ {"CadetBlue", cmyk(0.62, 0.57, 0.23, 0.00)},
+ {"CornflowerBlue", cmyk(0.65, 0.13, 0.00, 0.00)},
+ {"MidnightBlue", cmyk(0.98, 0.13, 0.00, 0.43)},
+ {"NavyBlue", cmyk(0.94, 0.54, 0.00, 0.00)},
+ {"RoyalBlue", cmyk(1.00, 0.50, 0.00, 0.00)},
+ {"Blue", cmyk(1.00, 1.00, 0.00, 0.00)},
+ {"Cerulean", cmyk(0.94, 0.11, 0.00, 0.00)},
+ {"Cyan", cmyk(1.00, 0.00, 0.00, 0.00)},
+ {"ProcessBlue", cmyk(0.96, 0.00, 0.00, 0.00)},
+ {"SkyBlue", cmyk(0.62, 0.00, 0.12, 0.00)},
+ {"Turquoise", cmyk(0.85, 0.00, 0.20, 0.00)},
+ {"TealBlue", cmyk(0.86, 0.00, 0.34, 0.02)},
+ {"Aquamarine", cmyk(0.82, 0.00, 0.30, 0.00)},
+ {"BlueGreen", cmyk(0.85, 0.00, 0.33, 0.00)},
+ {"Emerald", cmyk(1.00, 0.00, 0.50, 0.00)},
+ {"JungleGreen", cmyk(0.99, 0.00, 0.52, 0.00)},
+ {"SeaGreen", cmyk(0.69, 0.00, 0.50, 0.00)},
+ {"Green", cmyk(1.00, 0.00, 1.00, 0.00)},
+ {"ForestGreen", cmyk(0.91, 0.00, 0.88, 0.12)},
+ {"PineGreen", cmyk(0.92, 0.00, 0.59, 0.25)},
+ {"LimeGreen", cmyk(0.50, 0.00, 1.00, 0.00)},
+ {"YellowGreen", cmyk(0.44, 0.00, 0.74, 0.00)},
+ {"SpringGreen", cmyk(0.26, 0.00, 0.76, 0.00)},
+ {"OliveGreen", cmyk(0.64, 0.00, 0.95, 0.40)},
+ {"RawSienna", cmyk(0.00, 0.72, 1.00, 0.45)},
+ {"Sepia", cmyk(0.00, 0.83, 1.00, 0.70)},
+ {"Brown", cmyk(0.00, 0.81, 1.00, 0.60)},
+ {"Tan", cmyk(0.14, 0.42, 0.56, 0.00)},
+ /* Adobe Reader 7 and 8 had problem when gray and cmyk black colors
+ * are mixed. No problem with Previewer.app.
+ * It happens when \usepackage[dvipdfm]{graphicx} and then called
+ * \usepackage{color} without dvipdfm option. */
+ {"Gray", gray(0.5)},
+ {"Black", gray(0.0)},
+ {"White", gray(1.0)},
+ {NULL}
+};
+
+
+static int
+pdf_color_namedcolor (pdf_color *color, const char *name)
+{
+ int i;
+ for (i = 0; colordefs[i].key; i++) {
+ if (!strcmp(colordefs[i].key, name)) {
+ pdf_color_copycolor(color, &colordefs[i].color);
+ return 0;
+ }
+ }
+ return -1;
+}
diff --git a/Build/source/texk/dvipdfm-x/spc_util.h b/Build/source/texk/dvipdfm-x/spc_util.h
new file mode 100644
index 00000000000..63ec8f83c68
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_util.h
@@ -0,0 +1,58 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_UTIL_H_
+#define _SPC_UTIL_H_
+
+#include "pdfcolor.h"
+#include "pdfdev.h"
+#include "pdfdoc.h"
+
+#include "specials.h"
+
+/* syntax 1: ((rgb|cmyk|hsb|gray) colorvalues)|colorname
+ * syntax 0: pdf_number|pdf_array
+ *
+ * This is for reading *single* color specification.
+ */
+extern int spc_util_read_colorspec (struct spc_env *spe,
+ pdf_color *colorspec,
+ struct spc_arg *args, int syntax);
+extern int spc_util_read_dimtrns (struct spc_env *spe,
+ transform_info *dimtrns,
+ struct spc_arg *args, int syntax);
+
+extern int spc_util_read_blahblah (struct spc_env *spe,
+ transform_info *dimtrns,
+ int *page_no,
+ enum pdf_page_boundary *bbox_type,
+ struct spc_arg *args);
+
+
+extern int spc_util_read_numbers (double *values, int num_values,
+ struct spc_arg *args);
+extern int spc_util_read_pdfcolor (struct spc_env *spe,
+ pdf_color *colorspec,
+ struct spc_arg *args,
+ pdf_color *defaultcolor);
+
+#endif /* _SPC_UTIL_H_ */
diff --git a/Build/source/texk/dvipdfm-x/spc_xtx.c b/Build/source/texk/dvipdfm-x/spc_xtx.c
new file mode 100644
index 00000000000..d68a6f170a9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_xtx.c
@@ -0,0 +1,465 @@
+/* This is xdvipdfmx, an extended version of dvipdfmx,
+ an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2013-2020 by the dvipdfmx project team.
+
+ Copyright (c) 2006 SIL International
+ Originally written by Jonathan Kew
+
+ This file based on spc_pdfm.c, part of the dvipdfmx project:
+
+ Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+
+#include "numbers.h"
+
+#include "fontmap.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+#include "pdfparse.h"
+
+#include "pdfdoc.h"
+
+#include "pdfdraw.h"
+#include "pdfcolor.h"
+#include "pdfdev.h"
+
+#include "specials.h"
+
+#include "spc_util.h"
+#include "spc_xtx.h"
+
+
+int
+spc_handler_xtx_do_transform (struct spc_env *spe, double x_user, double y_user, double a, double b, double c, double d, double e, double f)
+{
+ pdf_tmatrix M = { 0, 0, 0, 0, 0, 0 };
+ pdf_coord pt;
+
+ /* Create transformation matrix */
+ M.a = a;
+ M.b = b;
+ M.c = c;
+ M.d = d;
+ M.e = ((1.0 - M.a) * x_user - M.c * y_user) + e;
+ M.f = ((1.0 - M.d) * y_user - M.b * x_user) + f;
+
+ pdf_dev_concat(&M);
+ spc_get_fixed_point(spe, &pt.x, &pt.y);
+ spc_set_fixed_point(spe, x_user - pt.x, y_user - pt.y);
+
+ return 0;
+}
+
+static int
+spc_handler_xtx_scale (struct spc_env *spe, struct spc_arg *args)
+{
+ double values[2];
+
+ if (spc_util_read_numbers(&values[0], 2, args) < 2) {
+ return -1;
+ }
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform(spe, spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
+}
+
+/* Scaling without gsave/grestore. */
+static pdf_coord *scaleFactors = 0;
+static int scaleFactorCount = -1;
+
+static int
+spc_handler_xtx_bscale (struct spc_env *spe, struct spc_arg *args)
+{
+ double values[2];
+
+ if (!(++scaleFactorCount & 0x0f))
+ scaleFactors = realloc(scaleFactors, (scaleFactorCount + 16) * sizeof(pdf_coord));
+ if (spc_util_read_numbers(&values[0], 2, args) < 2) {
+ return -1;
+ }
+ if (fabs(values[0]) < 1.e-7 || fabs(values[1]) < 1.e-7) {
+ return -1;
+ }
+ scaleFactors[scaleFactorCount].x = 1 / values[0];
+ scaleFactors[scaleFactorCount].y = 1 / values[1];
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user, values[0], 0, 0, values[1], 0, 0);
+}
+
+static int
+spc_handler_xtx_escale (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_coord factor = scaleFactors[scaleFactorCount--];
+
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user, factor.x, 0, 0, factor.y, 0, 0);
+}
+
+static int
+spc_handler_xtx_rotate (struct spc_env *spe, struct spc_arg *args)
+{
+ double value;
+
+ if (spc_util_read_numbers(&value, 1, args) < 1) {
+ return -1;
+ }
+ args->curptr = args->endptr;
+
+ return spc_handler_xtx_do_transform (spe, spe->x_user, spe->y_user,
+ cos(value * M_PI / 180), sin(value * M_PI / 180),
+ -sin(value * M_PI / 180), cos(value * M_PI / 180),
+ 0, 0);
+}
+
+int
+spc_handler_xtx_gsave (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_dev_gsave();
+ spc_dup_fixed_point(spe);
+
+ return 0;
+}
+
+int
+spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args)
+{
+ pdf_dev_grestore();
+ spc_pop_fixed_point(spe);
+
+ /*
+ * Unfortunately, the following line is necessary in case
+ * of a font or color change inside of the save/restore pair.
+ * Anything that was done there must be redone, so in effect,
+ * we make no assumptions about what fonts. We act like we are
+ * starting a new page.
+ */
+ pdf_dev_reset_fonts(0);
+ pdf_dev_reset_color(0);
+ pdf_dev_reset_xgstate(0);
+
+ return 0;
+}
+
+/* Please remove this.
+ * This should be handled before processing pages!
+ */
+static int
+spc_handler_xtx_papersize (struct spc_env *spe, struct spc_arg *args)
+{
+ return 0;
+}
+
+static int
+spc_handler_xtx_backgroundcolor (struct spc_env *spe, struct spc_arg *args)
+{
+ int error;
+ pdf_color colorspec;
+
+ error = spc_util_read_colorspec(spe, &colorspec, args, 0);
+ if (error)
+ spc_warn(spe, "No valid color specified?");
+ else {
+ pdf_doc_set_bgcolor(&colorspec);
+ }
+
+ return error;
+}
+
+/* FIXME: xdv2pdf's x:fontmapline and x:fontmapfile may have slightly different syntax/semantics */
+#define THEBUFFLENGTH 1024
+static int
+spc_handler_xtx_fontmapline (struct spc_env *spe, struct spc_arg *ap)
+{
+ fontmap_rec *mrec;
+ char *map_name, opchr;
+ int error = 0;
+ static char buffer[THEBUFFLENGTH];
+ const char *p;
+ char *q;
+ int count;
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr >= ap->endptr) {
+ spc_warn(spe, "Empty fontmapline special?");
+ return -1;
+ }
+
+ opchr = ap->curptr[0];
+ if (opchr == '-' || opchr == '+')
+ ap->curptr++;
+
+ skip_white(&ap->curptr, ap->endptr);
+
+ switch (opchr) {
+ case '-':
+ map_name = parse_ident(&ap->curptr, ap->endptr);
+ if (map_name) {
+ pdf_remove_fontmap_record(map_name);
+ RELEASE(map_name);
+ } else {
+ spc_warn(spe, "Invalid fontmap line: Missing TFM name.");
+ error = -1;
+ }
+ break;
+ default:
+ p = ap->curptr;
+ q = buffer;
+ count = 0;
+ while (p < ap->endptr && count < THEBUFFLENGTH - 1) {
+ *q++ = *p++;
+ count++;
+ }
+ if (count == THEBUFFLENGTH - 1) {
+ spc_warn(spe, "Invalid fontmap line: Too long a line.");
+ *q = 0;
+ return -1;
+ }
+ *q = '\0';
+ mrec = NEW(1, fontmap_rec);
+ pdf_init_fontmap_record(mrec);
+ error = pdf_read_fontmap_line(mrec, buffer, (int) (ap->endptr - ap->curptr), is_pdfm_mapline(buffer));
+ if (error)
+ spc_warn(spe, "Invalid fontmap line.");
+ else if (opchr == '+')
+ pdf_append_fontmap_record(mrec->map_name, mrec);
+ else
+ pdf_insert_fontmap_record(mrec->map_name, mrec);
+ pdf_clear_fontmap_record(mrec);
+ RELEASE(mrec);
+ break;
+ }
+ if (!error)
+ ap->curptr = ap->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_xtx_fontmapfile (struct spc_env *spe, struct spc_arg *args)
+{
+ char *mapfile;
+ int mode, error = 0;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return 0;
+
+ switch (args->curptr[0]) {
+ case '-':
+ mode = FONTMAP_RMODE_REMOVE;
+ args->curptr++;
+ break;
+ case '+':
+ mode = FONTMAP_RMODE_APPEND;
+ args->curptr++;
+ break;
+ default:
+ mode = FONTMAP_RMODE_REPLACE;
+ break;
+ }
+
+ mapfile = parse_val_ident(&args->curptr, args->endptr);
+ if (!mapfile) {
+ spc_warn(spe, "No fontmap file specified.");
+ return -1;
+ } else {
+ error = pdf_load_fontmap_file(mapfile, mode);
+ }
+
+ return error;
+}
+
+static char overlay_name[256];
+
+static int
+spc_handler_xtx_initoverlay (struct spc_env *spe, struct spc_arg *args)
+{
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+ strncpy(overlay_name, args->curptr, args->endptr - args->curptr);
+ overlay_name[args->endptr - args->curptr] = 0;
+
+ args->curptr = args->endptr;
+ return 0;
+}
+
+static int
+spc_handler_xtx_clipoverlay (struct spc_env *spe, struct spc_arg *args)
+{
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr >= args->endptr)
+ return -1;
+ pdf_dev_grestore();
+ pdf_dev_gsave();
+ if (strncmp(overlay_name, args->curptr, strlen(overlay_name)) != 0
+ && strncmp("all", args->curptr, strlen("all")) != 0)
+ pdf_doc_add_page_content(" 0 0 m W n", 10);
+
+ args->curptr = args->endptr;
+ return 0;
+}
+
+static int
+spc_handler_xtx_renderingmode (struct spc_env *spe, struct spc_arg *args)
+{
+ double value;
+
+ if (spc_util_read_numbers(&value, 1, args) < 1) {
+ return -1;
+ }
+ if ((int) value < 0 || (int) value > 7) {
+ spc_warn(spe, "Invalid text rendering mode %d.\n", (int) value);
+ return -1;
+ }
+ sprintf(work_buffer, " %d Tr", (int) value);
+ pdf_doc_add_page_content(work_buffer, strlen(work_buffer));
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+ pdf_doc_add_page_content(" ", 1);
+ pdf_doc_add_page_content(args->curptr, args->endptr - args->curptr);
+ }
+
+ args->curptr = args->endptr;
+ return 0;
+}
+
+static int
+spc_handler_xtx_unsupportedcolor (struct spc_env *spe, struct spc_arg *args)
+{
+ spc_warn(spe, "xetex-style \\special{x:%s} is not supported by this driver;\n"
+ "update document or driver to use \\special{color} instead.", args->command);
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static int
+spc_handler_xtx_unsupported (struct spc_env *spe, struct spc_arg *args)
+{
+ spc_warn(spe, "xetex-style \\special{x:%s} is not supported by this driver.", args->command);
+
+ args->curptr = args->endptr;
+
+ return 0;
+}
+
+static struct spc_handler xtx_handlers[] = {
+ {"textcolor", spc_handler_xtx_unsupportedcolor},
+ {"textcolorpush", spc_handler_xtx_unsupportedcolor},
+ {"textcolorpop", spc_handler_xtx_unsupportedcolor},
+
+ {"rulecolor", spc_handler_xtx_unsupportedcolor},
+ {"rulecolorpush", spc_handler_xtx_unsupportedcolor},
+ {"rulecolorpop", spc_handler_xtx_unsupportedcolor},
+
+ {"papersize", spc_handler_xtx_papersize},
+ {"backgroundcolor", spc_handler_xtx_backgroundcolor},
+
+ {"gsave", spc_handler_xtx_gsave},
+ {"grestore", spc_handler_xtx_grestore},
+
+ {"scale", spc_handler_xtx_scale},
+ {"bscale", spc_handler_xtx_bscale},
+ {"escale", spc_handler_xtx_escale},
+ {"rotate", spc_handler_xtx_rotate},
+
+ {"fontmapline", spc_handler_xtx_fontmapline},
+ {"fontmapfile", spc_handler_xtx_fontmapfile},
+
+ {"shadow", spc_handler_xtx_unsupported},
+ {"colorshadow", spc_handler_xtx_unsupported},
+ {"renderingmode", spc_handler_xtx_renderingmode},
+
+ {"initoverlay", spc_handler_xtx_initoverlay},
+ {"clipoverlay", spc_handler_xtx_clipoverlay},
+};
+
+int
+spc_xtx_check_special (const char *buf, int len)
+{
+ int r = 0;
+ const char *p, *endptr;
+
+ p = buf;
+ endptr = p + len;
+
+ skip_white(&p, endptr);
+ if (p + strlen("x:") <= endptr &&
+ !memcmp(p, "x:", strlen("x:"))) {
+ r = 1;
+ }
+
+ return r;
+}
+
+int
+spc_xtx_setup_handler (struct spc_handler *sph,
+ struct spc_env *spe, struct spc_arg *ap)
+{
+ int error = -1, i;
+ char *q;
+
+ ASSERT(sph && spe && ap);
+
+ skip_white(&ap->curptr, ap->endptr);
+ if (ap->curptr + strlen("x:") >= ap->endptr ||
+ memcmp(ap->curptr, "x:", strlen("x:"))) {
+ spc_warn(spe, "Not x: special???");
+ return -1;
+ }
+ ap->curptr += strlen("x:");
+
+ skip_white(&ap->curptr, ap->endptr);
+ q = parse_c_ident(&ap->curptr, ap->endptr);
+ if (q) {
+ for (i = 0;
+ i < sizeof(xtx_handlers) / sizeof(struct spc_handler); i++) {
+ if (!strcmp(q, xtx_handlers[i].key)) {
+ ap->command = xtx_handlers[i].key;
+ sph->key = "x:";
+ sph->exec = xtx_handlers[i].exec;
+ skip_white(&ap->curptr, ap->endptr);
+ error = 0;
+ break;
+ }
+ }
+ RELEASE(q);
+ }
+
+ return error;
+}
+
diff --git a/Build/source/texk/dvipdfm-x/spc_xtx.h b/Build/source/texk/dvipdfm-x/spc_xtx.h
new file mode 100644
index 00000000000..25d6f849ae4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/spc_xtx.h
@@ -0,0 +1,41 @@
+/* This is xdvipdfmx, an extended version of dvipdfmx,
+ an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2013-2020 by the dvipdfmx project team.
+
+ Copyright (c) 2006 SIL International
+ Originally written by Jonathan Kew
+
+ Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPC_XTX_H_
+#define _SPC_XTX_H_
+
+#include "specials.h"
+
+extern int spc_xtx_check_special (const char *buffer, int size);
+extern int spc_xtx_setup_handler (struct spc_handler *handle,
+ struct spc_env *spe, struct spc_arg *args);
+extern int spc_handler_xtx_do_transform (struct spc_env *spe, double x_user, double y_user, double a, double b, double c, double d, double e, double f);
+extern int spc_handler_xtx_gsave (struct spc_env *spe, struct spc_arg *args);
+extern int spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args);
+
+#endif /* _SPC_XTX_H_ */
diff --git a/Build/source/texk/dvipdfm-x/specials.c b/Build/source/texk/dvipdfm-x/specials.c
new file mode 100644
index 00000000000..1b73b35be72
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/specials.c
@@ -0,0 +1,832 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "numbers.h"
+#include "dpxconf.h"
+
+#include "dvi.h"
+
+#include "pdfobj.h"
+#include "pdfparse.h"
+#include "pdfdoc.h"
+#include "pdfnames.h"
+
+#include "pdfdraw.h"
+#include "pdfdev.h"
+
+#include "spc_pdfm.h"
+#include "spc_tpic.h"
+#include "spc_html.h"
+#include "spc_misc.h"
+#include "spc_color.h"
+#include "spc_dvips.h"
+#include "spc_dvipdfmx.h"
+#include "spc_xtx.h"
+
+#include "specials.h"
+
+#define THEBUFFLENGTH 1024
+void
+spc_warn (struct spc_env *spe, const char *fmt, ...)
+{
+ va_list ap;
+ static char buf[THEBUFFLENGTH];
+
+ va_start(ap, fmt);
+
+ vsnprintf(buf, THEBUFFLENGTH, fmt, ap);
+ WARN(buf);
+
+ va_end(ap);
+
+ return;
+}
+
+
+/* This is currently just to make other spc_xxx to not directly
+ * call dvi_xxx.
+ */
+int
+spc_begin_annot (struct spc_env *spe, pdf_obj *dict)
+{
+ pdf_doc_begin_annot(dict);
+ dvi_tag_depth(); /* Tell dvi interpreter to handle line-break. */
+ return 0;
+}
+
+int
+spc_end_annot (struct spc_env *spe)
+{
+ dvi_untag_depth();
+ pdf_doc_end_annot();
+ return 0;
+}
+
+int
+spc_resume_annot (struct spc_env *spe)
+{
+ dvi_link_annot(1);
+ return 0;
+}
+
+int
+spc_suspend_annot (struct spc_env *spe)
+{
+ dvi_link_annot(0);
+ return 0;
+}
+
+/* Added this for supporting bann-eann erea only with \phantom text */
+int
+spc_is_tracking_boxes (struct spc_env *spe)
+{
+ return dvi_is_tracking_boxes();
+}
+
+void
+spc_set_linkmode (struct spc_env *spe, int mode)
+{
+ dvi_set_linkmode(mode);
+}
+
+void
+spc_set_phantom (struct spc_env *spe, double height, double depth)
+{
+ dvi_set_phantom_height(height, depth);
+}
+
+
+/* reserved keys */
+static const char *_rkeys[] = {
+#define K_OBJ__XPOS 0
+#define K_OBJ__YPOS 1
+ "xpos", "ypos",
+#define K_OBJ__THISPAGE 2
+#define K_OBJ__PREVPAGE 3
+#define K_OBJ__NEXTPAGE 4
+ "thispage", "prevpage", "nextpage",
+#define K_OBJ__RESOURCES 5
+ "resources",
+#define K_OBJ__PAGES 6
+#define K_OBJ__NAMES 7
+ "pages", "names",
+#define K_OBJ__CATALOG 8
+#define K_OBJ__DOCINFO 9
+ "catalog", "docinfo",
+#if 0
+#define K_OBJ__TRAILER 10
+ "trailer",
+#endif /* NYI */
+ NULL
+};
+
+/* pageN where N is a positive integer.
+ * Note that page need not exist at this time.
+ */
+static int
+ispageref (const char *key)
+{
+ const char *p;
+ if (strlen(key) <= strlen("page") ||
+ memcmp(key, "page", strlen("page")))
+ return 0;
+ else {
+ for (p = key + 4; *p && *p >= '0' && *p <= '9'; p++);
+ if (*p != '\0')
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * The following routine returns copies, not the original object.
+ */
+pdf_obj *
+spc_lookup_reference (const char *key)
+{
+ pdf_obj *value = NULL;
+ pdf_coord cp;
+ int k;
+
+ if (!key)
+ return NULL;
+
+ for (k = 0; _rkeys[k] && strcmp(key, _rkeys[k]); k++);
+ switch (k) {
+ /* xpos and ypos must be position in device space here. */
+ case K_OBJ__XPOS:
+ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos();
+ pdf_dev_transform(&cp, NULL);
+ value = pdf_new_number(ROUND(cp.x, .01));
+ break;
+ case K_OBJ__YPOS:
+ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos();
+ pdf_dev_transform(&cp, NULL);
+ value = pdf_new_number(ROUND(cp.y, .01));
+ break;
+ case K_OBJ__THISPAGE:
+ value = pdf_doc_this_page_ref();
+ break;
+ case K_OBJ__PREVPAGE:
+ value = pdf_doc_prev_page_ref();
+ break;
+ case K_OBJ__NEXTPAGE:
+ value = pdf_doc_next_page_ref();
+ break;
+ case K_OBJ__PAGES:
+ value = pdf_ref_obj(pdf_doc_page_tree());
+ break;
+ case K_OBJ__NAMES:
+ value = pdf_ref_obj(pdf_doc_names());
+ break;
+ case K_OBJ__RESOURCES:
+ value = pdf_ref_obj(pdf_doc_current_page_resources());
+ break;
+ case K_OBJ__CATALOG:
+ value = pdf_ref_obj(pdf_doc_catalog());
+ break;
+ case K_OBJ__DOCINFO:
+ value = pdf_ref_obj(pdf_doc_docinfo());
+ break;
+ default:
+ if (ispageref(key))
+ value = pdf_doc_ref_page(atoi(key + 4));
+ else {
+ value = pdf_names_lookup_reference(global_names, key, strlen(key));
+ }
+ break;
+ }
+
+ if (!value) {
+ ERROR("Object reference %s not exist.", key);
+ }
+
+ return value;
+}
+
+pdf_obj *
+spc_lookup_object (const char *key)
+{
+ pdf_obj *value = NULL;
+ pdf_coord cp;
+ int k;
+
+ if (!key)
+ return NULL;
+
+ for (k = 0; _rkeys[k] && strcmp(key, _rkeys[k]); k++);
+ switch (k) {
+ case K_OBJ__XPOS:
+ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos();
+ pdf_dev_transform(&cp, NULL);
+ value = pdf_new_number(ROUND(cp.x, .01));
+ break;
+ case K_OBJ__YPOS:
+ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos();
+ pdf_dev_transform(&cp, NULL);
+ value = pdf_new_number(ROUND(cp.y, .01));
+ break;
+ case K_OBJ__THISPAGE:
+ value = pdf_doc_this_page();
+ break;
+ case K_OBJ__PAGES:
+ value = pdf_doc_page_tree();
+ break;
+ case K_OBJ__NAMES:
+ value = pdf_doc_names();
+ break;
+ case K_OBJ__RESOURCES:
+ value = pdf_doc_current_page_resources();
+ break;
+ case K_OBJ__CATALOG:
+ value = pdf_doc_catalog();
+ break;
+ case K_OBJ__DOCINFO:
+ value = pdf_doc_docinfo();
+ break;
+ default:
+ value = pdf_names_lookup_object(global_names, key, strlen(key));
+ break;
+ }
+
+/* spc_handler_pdfm_bead() in spc_pdfm.c controls NULL too.
+ if (!value) {
+ ERROR("Object reference %s not exist.", key);
+ }
+*/
+
+ return value;
+}
+
+void
+spc_push_object (struct spc_env *spe, const char *key, pdf_obj *value)
+{
+ if (!key || !value)
+ return;
+
+ pdf_names_add_object(global_names, key, strlen(key), value);
+}
+
+void
+spc_flush_object (struct spc_env *spe, const char *key)
+{
+ pdf_names_close_object(global_names, key, strlen(key));
+}
+
+void
+spc_clear_objects (struct spc_env *spe)
+{
+ /* Do nothing... */
+}
+
+/* Migrated form pdf_dev.c
+ * No need to palce this into pdfdev.c at all.
+ */
+static dpx_stack coords;
+
+void
+spc_get_coord (struct spc_env *spe, double *x, double *y)
+{
+ ASSERT(x && y );
+
+ if (dpx_stack_depth(&coords) > 0) {
+ pdf_coord *p = dpx_stack_top(&coords);
+ *x = p->x;
+ *y = p->y;
+ } else {
+ *x = *y = 0.0;
+ }
+}
+
+void
+spc_push_coord (struct spc_env *spe, double x, double y)
+{
+ pdf_coord *p;
+
+ p = NEW(1, pdf_coord);
+ p->x = x; p->y = y;
+ dpx_stack_push(&coords, p);
+ dvi_set_compensation(x, y);
+}
+
+void
+spc_pop_coord (struct spc_env *spe)
+{
+ double x, y;
+ pdf_coord *p;
+
+ p = dpx_stack_pop(&coords);
+ if (p)
+ RELEASE(p);
+
+ spc_get_coord(spe, &x, &y);
+ dvi_set_compensation(x, y);
+}
+
+/* Migrated from pdfdraw.c.
+ *
+ * pt_fixee is obviously not a PDF graphics state parameter.
+ *
+ */
+
+static dpx_stack pt_fixee;
+
+void
+spc_set_fixed_point (struct spc_env *spe, double x, double y)
+{
+ pdf_coord *p;
+
+ p = dpx_stack_top(&pt_fixee);
+ if (p) {
+ p->x = x;
+ p->y = y;
+ } else {
+ p = NEW(1, pdf_coord);
+ p->x = x;
+ p->y = y;
+ dpx_stack_push(&pt_fixee, p);
+ }
+}
+
+void
+spc_get_fixed_point (struct spc_env *spe, double *x, double *y)
+{
+ pdf_coord *p;
+
+ ASSERT(x && y);
+
+ p = dpx_stack_top(&pt_fixee);
+ if (p) {
+ *x = p->x;
+ *y = p->y;
+ } else {
+ *x = 0.0;
+ *y = 0.0;
+ }
+}
+
+void
+spc_put_fixed_point (struct spc_env *spe, double x, double y)
+{
+ pdf_coord *p;
+
+ p = NEW(1, pdf_coord);
+ p->x = x;
+ p->y = y;
+ dpx_stack_push(&pt_fixee, p);
+}
+
+void
+spc_dup_fixed_point (struct spc_env *spe)
+{
+ pdf_coord *p1, *p2;
+
+ p1 = dpx_stack_top(&pt_fixee);
+ p2 = NEW(1, pdf_coord);
+ if (p1) {
+ p2->x = p1->x; p2->y = p1->y;
+ } else {
+ p2->x = 0.0; p2->y = 0.0;
+ }
+ dpx_stack_push(&pt_fixee, p2);
+}
+
+void
+spc_pop_fixed_point (struct spc_env *spe)
+{
+ pdf_coord *p;
+ p = dpx_stack_pop(&pt_fixee);
+ if (p)
+ RELEASE(p);
+}
+
+void
+spc_clear_fixed_point (struct spc_env *spe)
+{
+ pdf_coord *p;
+
+ for (;;) {
+ p = dpx_stack_pop(&pt_fixee);
+ if (!p)
+ break;
+ else
+ RELEASE(p);
+ }
+}
+
+void
+spc_get_current_point (struct spc_env *spe, pdf_coord *cp)
+{
+ double xoff, yoff;
+
+ if (!spe || !cp)
+ return;
+
+ spc_get_coord(spe, &xoff, &yoff);
+ cp->x = spe->x_user - xoff;
+ cp->y = spe->y_user - yoff;
+}
+
+void
+spc_put_image (struct spc_env *spe, int res_id, transform_info *ti, double xpos, double ypos)
+{
+ double xoff, yoff;
+
+ spc_get_coord(spe, &xoff, &yoff);
+ pdf_dev_put_image(res_id, ti, xpos - xoff, ypos - yoff, &spe->info.rect);
+ spe->info.is_drawable = 1;
+}
+
+
+static int
+spc_handler_unknown (struct spc_env *spe, struct spc_arg *args)
+{
+ ASSERT(spe && args);
+
+ args->curptr = args->endptr;
+
+ return -1;
+}
+
+static void
+init_special (struct spc_handler *special,
+ struct spc_env *spe,
+ struct spc_arg *args,
+ const char *p, uint32_t size,
+ double x_user, double y_user, double mag)
+{
+
+ special->key = NULL;
+ special->exec = (spc_handler_fn_ptr) &spc_handler_unknown;
+
+ spe->x_user = x_user;
+ spe->y_user = y_user;
+ spe->mag = mag;
+ spe->pg = pdf_doc_current_page_number(); /* _FIXME_ */
+ spe->info.is_drawable = 0;
+ spe->info.rect.llx = 0.0;
+ spe->info.rect.lly = 0.0;
+ spe->info.rect.urx = 0.0;
+ spe->info.rect.ury = 0.0;
+
+ args->curptr = p;
+ args->endptr = args->curptr + size;
+ args->base = args->curptr;
+ args->command = NULL;
+
+ return;
+}
+
+static void
+check_garbage (struct spc_arg *args)
+{
+ ASSERT(args);
+
+ if (args->curptr >= args->endptr)
+ return;
+
+ skip_white(&args->curptr, args->endptr);
+ if (args->curptr < args->endptr) {
+ WARN("Unparsed material at end of special ignored.");
+ dump(args->curptr, args->endptr);
+ }
+
+ return;
+}
+
+static struct {
+ const char *key;
+ int (*bodhk_func) (void);
+ int (*eodhk_func) (void);
+ int (*bophk_func) (void);
+ int (*eophk_func) (void);
+ int (*bofhk_func) (void);
+ int (*eofhk_func) (void);
+ int (*check_func) (const char *, int);
+ int (*setup_func) (struct spc_handler *, struct spc_env *, struct spc_arg *);
+} known_specials[] = {
+
+ {"pdf:",
+ spc_pdfm_at_begin_document,
+ spc_pdfm_at_end_document,
+ NULL,
+ spc_pdfm_at_end_page,
+ NULL,
+ NULL,
+ spc_pdfm_check_special,
+ spc_pdfm_setup_handler
+ },
+
+ {"x:",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ spc_xtx_check_special,
+ spc_xtx_setup_handler
+ },
+
+ {"dvipdfmx:",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ spc_dvipdfmx_check_special,
+ spc_dvipdfmx_setup_handler
+ },
+
+ {"ps:",
+ spc_dvips_at_begin_document,
+ spc_dvips_at_end_document,
+ spc_dvips_at_begin_page,
+ spc_dvips_at_end_page,
+ NULL,
+ NULL,
+ spc_dvips_check_special,
+ spc_dvips_setup_handler
+ },
+
+ {"color",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ spc_color_check_special,
+ spc_color_setup_handler
+ },
+
+ {"tpic",
+ spc_tpic_at_begin_document,
+ spc_tpic_at_end_document,
+ spc_tpic_at_begin_page,
+ spc_tpic_at_end_page,
+ NULL,
+ NULL,
+ spc_tpic_check_special,
+ spc_tpic_setup_handler
+ },
+
+ {"html:",
+ spc_html_at_begin_document,
+ spc_html_at_end_document,
+ spc_html_at_begin_page,
+ spc_html_at_end_page,
+ NULL,
+ NULL,
+ spc_html_check_special,
+ spc_html_setup_handler
+ },
+
+ {"compat",
+ spc_misc_at_begin_document,
+ spc_misc_at_end_document,
+ spc_misc_at_begin_page,
+ NULL,
+ spc_misc_at_begin_form,
+ spc_misc_at_end_form,
+ spc_misc_check_special,
+ spc_misc_setup_handler
+ },
+
+ {NULL} /* end */
+};
+
+int
+spc_begin_form (struct spc_env *spe, const char *ident, pdf_coord cp, pdf_rect *cropbox)
+{
+ int error = 0;
+ int i, xobj_id;
+
+ xobj_id = pdf_doc_begin_grabbing(ident, cp.x, cp.y, cropbox);
+
+ if (xobj_id < 0) {
+ error = -1;
+ } else {
+ for (i = 0; known_specials[i].key != NULL; i++) {
+ if (known_specials[i].bofhk_func) {
+ error = known_specials[i].bofhk_func();
+ }
+ }
+ }
+
+ return error;
+}
+
+int
+spc_end_form (struct spc_env *spe, pdf_obj *attr)
+{
+ int error = 0;
+ int i;
+
+ pdf_doc_end_grabbing(attr);
+
+ for (i = 0; known_specials[i].key != NULL; i++) {
+ if (known_specials[i].eofhk_func) {
+ error = known_specials[i].eofhk_func();
+ }
+ }
+
+ return error;
+}
+
+int
+spc_exec_at_begin_page (void)
+{
+ int error = 0;
+ int i;
+
+ for (i = 0; known_specials[i].key != NULL; i++) {
+ if (known_specials[i].bophk_func) {
+ error = known_specials[i].bophk_func();
+ }
+ }
+
+ return error;
+}
+
+int
+spc_exec_at_end_page (void)
+{
+ int error = 0;
+ int i;
+
+ for (i = 0; known_specials[i].key != NULL; i++) {
+ if (known_specials[i].eophk_func) {
+ error = known_specials[i].eophk_func();
+ }
+ }
+
+ return error;
+}
+
+int
+spc_exec_at_begin_document (void)
+{
+ int error = 0;
+ int i;
+
+ for (i = 0; known_specials[i].key != NULL; i++) {
+ if (known_specials[i].bodhk_func) {
+ error = known_specials[i].bodhk_func();
+ }
+ }
+
+ dpx_stack_init(&coords);
+ dpx_stack_init(&pt_fixee);
+
+ return error;
+}
+
+int
+spc_exec_at_end_document (void)
+{
+ int error = 0;
+ int i;
+ pdf_coord *p;
+
+ for (i = 0; known_specials[i].key != NULL; i++) {
+ if (known_specials[i].eodhk_func) {
+ error = known_specials[i].eodhk_func();
+ }
+ }
+
+ while ((p = dpx_stack_pop(&coords)) != NULL) {
+ RELEASE(p);
+ }
+ while ((p = dpx_stack_pop(&pt_fixee)) != NULL) {
+ RELEASE(p);
+ }
+
+ return error;
+}
+
+static void
+print_error (const char *name, struct spc_env *spe, struct spc_arg *ap)
+{
+ const char *p;
+ char ebuf[64];
+ int i;
+ int pg = spe->pg;
+ pdf_coord c;
+
+ c.x = spe->x_user; c.y = spe->y_user;
+ pdf_dev_transform(&c, NULL);
+
+ if (ap->command && name) {
+ WARN("Interpreting special command %s (%s) failed.", ap->command, name);
+ WARN(">> at page=\"%ld\" position=\"(%g, %g)\" (in PDF)", pg, c.x, c.y);
+ }
+ for (i = 0, p = ap->base; i < 63 && p < ap->endptr; p++) {
+ if (isprint((unsigned char)*p))
+ ebuf[i++] = *p;
+ else if (i + 4 < 63)
+ i += sprintf(ebuf + i, "\\x%02x", (unsigned char)*p);
+ else
+ break;
+ }
+ ebuf[i] = '\0';
+ if (ap->curptr < ap->endptr) {
+ while (i-- > 60)
+ ebuf[i] = '.';
+ }
+ WARN(">> xxx \"%s\"", ebuf);
+
+ if (ap->curptr < ap->endptr) {
+ for (i = 0, p = ap->curptr; i < 63 && p < ap->endptr; p++) {
+ if (isprint((unsigned char)*p))
+ ebuf[i++] = *p;
+ else if (i + 4 < 63)
+ i += sprintf(ebuf + i, "\\x%02x", (unsigned char)*p);
+ else
+ break;
+ }
+ ebuf[i] = '\0';
+ if (ap->curptr < ap->endptr) {
+ while (i-- > 60)
+ ebuf[i] = '.';
+ }
+ WARN(">> Reading special command stopped around >>%s<<", ebuf);
+
+ ap->curptr = ap->endptr;
+ }
+}
+
+int
+spc_exec_special (const char *buffer, int32_t size,
+ double x_user, double y_user, double mag,
+ int *is_drawable, pdf_rect *rect)
+{
+ int error = -1;
+ int i, found;
+ struct spc_env spe;
+ struct spc_arg args;
+ struct spc_handler special;
+
+ if (dpx_conf.verbose_level > 3) {
+ MESG("Executing special command: ");
+ dump(buffer, buffer + size);
+ }
+
+ init_special(&special, &spe, &args, buffer, size, x_user, y_user, mag);
+
+ for (i = 0; known_specials[i].key != NULL; i++) {
+ found = known_specials[i].check_func(buffer, size);
+ if (found) {
+ error = known_specials[i].setup_func(&special, &spe, &args);
+ if (!error) {
+ error = special.exec(&spe, &args);
+ }
+ if (error) {
+ print_error(known_specials[i].key, &spe, &args);
+ } else {
+ if (is_drawable)
+ *is_drawable = spe.info.is_drawable;
+ if (rect) {
+ rect->llx = spe.info.rect.llx;
+ rect->lly = spe.info.rect.lly;
+ rect->urx = spe.info.rect.urx;
+ rect->ury = spe.info.rect.ury;
+ }
+ }
+ break;
+ }
+ }
+
+ check_garbage(&args);
+
+ return error;
+}
diff --git a/Build/source/texk/dvipdfm-x/specials.h b/Build/source/texk/dvipdfm-x/specials.h
new file mode 100644
index 00000000000..17ced222335
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/specials.h
@@ -0,0 +1,103 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SPECIALS_H_
+#define _SPECIALS_H_
+
+#include "pdfobj.h"
+#include "pdfdev.h"
+
+struct spc_env {
+ double x_user, y_user;
+ double mag;
+ int pg; /* current page in PDF */
+ struct {
+ int is_drawable;
+ pdf_rect rect;
+ } info;
+};
+
+struct spc_arg {
+ const char *curptr;
+ const char *endptr;
+ const char *base;
+
+ const char *command;
+};
+
+typedef int (*spc_handler_fn_ptr) (struct spc_env *, struct spc_arg *);
+
+struct spc_handler {
+ const char *key;
+ spc_handler_fn_ptr exec;
+};
+
+
+#include <stdarg.h>
+extern void spc_warn (struct spc_env *spe, const char *fmt, ...);
+
+extern pdf_obj *spc_lookup_reference (const char *ident);
+extern pdf_obj *spc_lookup_object (const char *ident);
+
+extern int spc_begin_annot (struct spc_env *spe, pdf_obj *annot_dict);
+extern int spc_end_annot (struct spc_env *spe);
+extern int spc_resume_annot (struct spc_env *spe);
+extern int spc_suspend_annot (struct spc_env *spe);
+
+extern int spc_begin_form (struct spc_env *spe, const char *ident, pdf_coord cp, pdf_rect *cropbox);
+extern int spc_end_form (struct spc_env *spe, pdf_obj *attr);
+
+extern int spc_is_tracking_boxes (struct spc_env *spe);
+
+/* linkmode 0: normal, 1: capture phantom texts */
+extern void spc_set_linkmode (struct spc_env *spe, int mode);
+/* set default height of phantom texts */
+extern void spc_set_phantom (struct spc_env *spe, double height, double depth);
+
+extern void spc_push_object (struct spc_env *spe, const char *key, pdf_obj *value);
+extern void spc_flush_object (struct spc_env *spe, const char *key);
+extern void spc_clear_objects (struct spc_env *spe);
+
+extern void spc_put_image (struct spc_env *spe, int res_id, transform_info *ti, double xpos, double ypos);
+
+extern void spc_get_current_point (struct spc_env *spe, pdf_coord *cp);
+
+/* dvipdfmx pdf: special */
+extern void spc_get_coord (struct spc_env *spe, double *x, double *y);
+extern void spc_push_coord (struct spc_env *spe, double x, double y);
+extern void spc_pop_coord (struct spc_env *spe);
+/* XeTeX */
+extern void spc_set_fixed_point (struct spc_env *spe, double x, double y);
+extern void spc_get_fixed_point (struct spc_env *spe, double *x, double *y);
+extern void spc_put_fixed_point (struct spc_env *spe, double x, double y);
+extern void spc_dup_fixed_point (struct spc_env *spe);
+extern void spc_pop_fixed_point (struct spc_env *spe);
+extern void spc_clear_fixed_point (struct spc_env *spe);
+
+extern int spc_exec_at_begin_page (void);
+extern int spc_exec_at_end_page (void);
+extern int spc_exec_at_begin_document (void);
+extern int spc_exec_at_end_document (void);
+
+extern int spc_exec_special (const char *p, int32_t size, double x_user, double y_user, double mag, int *is_drawable, pdf_rect *rect);
+
+#endif /* _SPECIALS_H_ */
diff --git a/Build/source/texk/dvipdfm-x/subfont.c b/Build/source/texk/dvipdfm-x/subfont.c
new file mode 100644
index 00000000000..5f439986389
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/subfont.c
@@ -0,0 +1,649 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxfile.h"
+
+#include "subfont.h"
+
+/* Don't forget fontmap reading now requires information
+ * from SFD files. You must initialize at least sfd_file_
+ * cache before starting loading of fontmaps.
+ */
+
+/* Subfont Definition File:
+ * struct sfd_file_ is for storing subfont identifiers
+ * contained in a SFD file and for mapping string pair
+ * <SFD_file, Subfont_id> to internal code mapping table
+ * ID which is index within an array of struct sfd_rec_.
+ * We store code mapping tables in different place than
+ * struct sfd_file_.
+ */
+struct sfd_file_
+{
+ char *ident; /* SFD file name */
+ char **sub_id; /* Subfont IDs */
+
+ int *rec_id; /* indices within struct sfd_rec_ array "sfd_record" */
+
+ int max_subfonts;
+ int num_subfonts;
+};
+
+/* Mapping table */
+struct sfd_rec_
+{
+ /* unsigned char misbit[32]; */
+ unsigned short vector[256]; /* 0 for undefined */
+};
+
+static void
+init_sfd_file_ (struct sfd_file_ *sfd)
+{
+ sfd->ident = NULL;
+ sfd->sub_id = NULL;
+ sfd->rec_id = NULL;
+ sfd->max_subfonts = sfd->num_subfonts = 0;
+}
+
+static void
+clean_sfd_file_ (struct sfd_file_ *sfd)
+{
+ int i;
+ if (sfd->ident)
+ RELEASE(sfd->ident);
+ if (sfd->sub_id) {
+ for (i = 0; i < sfd->num_subfonts; i++) {
+ if (sfd->sub_id[i])
+ RELEASE(sfd->sub_id[i]);
+ }
+ RELEASE(sfd->sub_id);
+ }
+ if (sfd->rec_id)
+ RELEASE(sfd->rec_id);
+ init_sfd_file_(sfd);
+}
+
+static struct sfd_file_ *sfd_files = NULL;
+static int num_sfd_files = 0, max_sfd_files = 0;
+
+static struct sfd_rec_ *sfd_record = NULL;
+static int num_sfd_records = 0, max_sfd_records = 0;
+
+
+
+/* Another buffer...
+ * We want buffer size at least 7 x 256 + a
+ * 4096 is usually enough.
+ */
+#define LINE_BUF_SIZE 4096
+static char line_buf[LINE_BUF_SIZE];
+
+/* Each lines describes character code mapping for each
+ * subfonts. '#' is start of comment.
+ * SFD file format uses a '\' before newline sequence
+ * for line-continuation.
+ */
+static char *
+readline (char *buf, int buf_len, FILE *fp)
+{
+ char *r, *q, *p = buf;
+ int n = 0, c = 0;
+
+ while (buf_len - n > 0 && (q = mfgets(p, buf_len - n, fp))) {
+ c++;
+ r = strchr(q, '#');
+ /* Comment is converted to single wsp (followed by a newline). */
+ if (r) {
+ *r = ' ';
+ *(r + 1) = '\0';
+ }
+ if (strlen(q) == 0)
+ break; /* empty line */
+ n += strlen(q);
+ q += strlen(q) - 1;
+ if (*q != '\\')
+ break;
+ else { /* line continued */
+ n -= 1;
+ p = buf + n;
+ }
+ }
+ if (n >= buf_len - 1) {
+ WARN("Possible buffer overflow in reading SFD file (buffer full, size=%d bytes)",
+ buf_len - 1);
+ }
+
+ return (c > 0 ? buf : NULL);
+}
+
+#define clear_vector(v) if ((v)) { \
+ int __i; \
+ for (__i = 0; __i < 256; __i++) \
+ (v)[__i] = 0; \
+}
+
+/* subfont_id ( integer ':' | integer '_' integer | integer )*
+ *
+ * 0x32: ==> Subsequent integers are place into slots starting at 0x32.
+ * 0x32: 0xA1A1 0xA1A2 ... ==> 0x32 is mappned to 0xA1A1, 0x33 to 0xA1A2
+ * 0xA1A1_0xA1A5 ==> Expanded to 0xA1A1 0xA1A2 ... 0xA1A5
+ */
+
+/* subfont_id is already consumed here. */
+static int
+read_sfd_record (struct sfd_rec_ *rec, const char *lbuf)
+{
+ const char *p = lbuf, *q;
+ char *r;
+ int repos = 0;
+ int c, v1 = 0, v2 = 0;
+ int curpos = 0;
+ int error = 0;
+
+#define IS_TOKSEP(c) ((c) == '\0' || isspace((unsigned char)(c)))
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ while (!error && *p) {
+ repos = 0; q = p;
+ v1 = strtol(p, &r, 0);
+ q = r;
+ if (q == p ||
+ (!IS_TOKSEP(*q) && *q != ':' && *q != '_')) {
+ WARN("Unknown token in subfont mapping table: %c", *q);
+ return -1;
+ }
+
+ switch (*q) {
+ case ':':
+ if (v1 < 0 || v1 > 0xff) {
+ WARN("Invalud value for subfont table offset: %ld", v1);
+ return -1;
+ }
+ repos = 1;
+ q++;
+ break;
+ case '_':
+ p = q + 1;
+ v2 = strtol(p, &r, 0);
+ q = r;
+ if (v1 < 0 || v1 > 0xffffL ||
+ v2 < 0 || v2 > 0xffffL) {
+ WARN("Invalid value in subfont mapping table: 0x%x_0x%x", v1, v2);
+ return -1;
+ } else if (q == p || !IS_TOKSEP(*q)) {
+ WARN("Invalid char in subfont mapping table: %c", *q);
+ return -1;
+ }
+ break;
+ default:
+ if (v1 < 0 || v1 > 0xffffL) {
+ WARN("Invalid character code in subfont mapping table: 0x%x", v1);
+ return -1;
+ }
+ v2 = v1;
+ break;
+ }
+
+ if (repos)
+ curpos = v1;
+ else {
+ if (v2 < v1 || curpos + (v2 - v1) > 0xff) {
+ WARN("Invalid range in subfont mapping: curpos=\"0x%02x\" range=\"0x%04x,0x%04x\"",
+ curpos, v1, v2);
+ return -1;
+ }
+ for (c = v1; c <= v2; c++) {
+ if (rec->vector[curpos] != 0) {
+ WARN("Subfont mapping for slot=\"0x%02x\" already defined...", curpos);
+ return -1;
+ }
+ ASSERT( curpos >= 0 && curpos <= 255 );
+ rec->vector[curpos++] = (unsigned short) c;
+ }
+ }
+ for (p = q; *p && isspace((unsigned char)*p); p++);
+ }
+
+ return error;
+}
+
+/* Scan for subfont IDs */
+static int
+scan_sfd_file (struct sfd_file_ *sfd, FILE *fp)
+{
+ char *id;
+ char *q, *p;
+ int n, lpos = 0;
+
+ ASSERT( sfd && fp );
+
+ if (dpx_conf.verbose_level > 3) {
+ MESG("\nsubfont>> Scanning SFD file \"%s\"...\n", sfd->ident);
+ }
+
+ rewind(fp);
+ sfd->max_subfonts = sfd->num_subfonts = 0;
+ while ((p = readline(line_buf, LINE_BUF_SIZE, fp)) != NULL) {
+ lpos++;
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ if (*p == 0)
+ continue; /* empty */
+
+ /* Saw non-wsp here */
+ for (n = 0, q = p; *p && !isspace((unsigned char)*p); p++, n++);
+ id = NEW(n + 1, char);
+ memcpy(id, q, n); id[n] = '\0';
+ if (sfd->num_subfonts >= sfd->max_subfonts) {
+ sfd->max_subfonts += 16;
+ sfd->sub_id = RENEW(sfd->sub_id, sfd->max_subfonts, char *);
+ }
+
+ if (dpx_conf.verbose_level > 3) {
+ MESG("subfont>> id=\"%s\" at line=\"%d\"\n", id, lpos);
+ }
+ sfd->sub_id[sfd->num_subfonts] = id;
+ sfd->num_subfonts++;
+ }
+
+ sfd->rec_id = NEW(sfd->num_subfonts, int);
+ for (n = 0; n < sfd->num_subfonts; n++) {
+ sfd->rec_id[n] = -1; /* Not loaded yet. We do lazy loading of map definitions. */
+ }
+
+ if (dpx_conf.verbose_level > 3) {
+ MESG("subfont>> %d entries found in SFD file \"%s\".\n", sfd->num_subfonts, sfd->ident);
+ }
+
+ return 0;
+}
+
+
+/* Open SFD file and gather subfont IDs. We do not read mapping tables
+ * here but only read subfont IDs used in SFD file.
+ */
+static int
+find_sfd_file (const char *sfd_name)
+{
+ int id = -1;
+ int i, error = -1;
+
+ /* Check if we already opened SFD file */
+ for (i = 0; i < num_sfd_files; i++) {
+ if (!strcmp(sfd_files[i].ident, sfd_name)) {
+ id = i;
+ break;
+ }
+ }
+
+ if (id < 0) {
+ struct sfd_file_ *sfd = NULL;
+ FILE *fp;
+
+ if (num_sfd_files >= max_sfd_files) {
+ max_sfd_files += 8;
+ sfd_files = RENEW(sfd_files, max_sfd_files, struct sfd_file_);
+ }
+ sfd = &sfd_files[num_sfd_files];
+ init_sfd_file_(sfd);
+ sfd->ident = NEW(strlen(sfd_name) + 1, char);
+ strcpy(sfd->ident, sfd_name);
+ fp = DPXFOPEN(sfd->ident, DPX_RES_TYPE_SFD);
+ if (!fp) {
+ clean_sfd_file_(sfd);
+ return -1;
+ }
+ error = scan_sfd_file(sfd, fp);
+ DPXFCLOSE(fp);
+ if (!error)
+ id = num_sfd_files++;
+ else {
+ WARN("Error occured while reading SFD file \"%s\"", sfd_name);
+ clean_sfd_file_(sfd);
+ id = -1;
+ }
+ }
+
+ return id;
+}
+
+char **
+sfd_get_subfont_ids (const char *sfd_name, int *num_ids)
+{
+ int sfd_id;
+
+ if (!sfd_name)
+ return NULL;
+
+ sfd_id = find_sfd_file(sfd_name);
+ if (sfd_id < 0)
+ return NULL;
+
+ if (num_ids)
+ *num_ids = sfd_files[sfd_id].num_subfonts;
+ return sfd_files[sfd_id].sub_id;
+}
+
+/* Make sure that sfd_name does not have the extension '.sfd'.
+ * Mapping tables are actually read here.
+ */
+int
+sfd_load_record (const char *sfd_name, const char *subfont_id)
+{
+ int rec_id = -1;
+ struct sfd_file_ *sfd;
+ FILE *fp;
+ int sfd_id, i, error = 0;
+ char *p, *q;
+
+ if (!sfd_name || !subfont_id)
+ return -1;
+
+ sfd_id = find_sfd_file(sfd_name);
+ if (sfd_id < 0)
+ return -1;
+
+ sfd = &sfd_files[sfd_id];
+ /* Check if we already loaded mapping table. */
+ for (i = 0;
+ i < sfd->num_subfonts && strcmp(sfd->sub_id[i], subfont_id); i++);
+ if (i == sfd->num_subfonts) {
+ WARN("Subfont id=\"%s\" not exist in SFD file \"%s\"...",
+ subfont_id, sfd->ident);
+ return -1;
+ } else if (sfd->rec_id[i] >= 0) {
+ return sfd->rec_id[i];
+ }
+
+ if (dpx_conf.verbose_level > 3) {
+ MESG("\nsubfont>> Loading SFD mapping table for <%s,%s>...",
+ sfd->ident, subfont_id);
+ }
+
+ /* reopen */
+ fp = DPXFOPEN(sfd->ident, DPX_RES_TYPE_SFD);
+ if (!fp) {
+ return -1;
+ /* ERROR("Could not open SFD file \"%s\"", sfd_name); */
+ }
+
+ /* Seek to record for 'sub_name'. */
+ while ((p = readline(line_buf, LINE_BUF_SIZE, fp))) {
+ for ( ; *p && isspace((unsigned char)*p); p++);
+ if (*p == 0)
+ continue; /* empty line */
+
+ /* q = parse_ident(&p, p + strlen(p)); */
+ for (q = p; *p && !isspace((unsigned char)*p); p++);
+ *p = '\0'; p++;
+ if (!strcmp(q, subfont_id)) {
+ if (num_sfd_records >= max_sfd_records) {
+ max_sfd_records += 16;
+ sfd_record = RENEW(sfd_record, max_sfd_records, struct sfd_rec_);
+ }
+ clear_vector(sfd_record[num_sfd_records].vector);
+ error = read_sfd_record(&sfd_record[num_sfd_records], p);
+ if (error)
+ WARN("Error occured while reading SFD file: file=\"%s\" subfont_id=\"%s\"",
+ sfd->ident, subfont_id);
+ else {
+ rec_id = num_sfd_records++;
+ }
+ }
+ }
+ if (rec_id < 0) {
+ WARN("Failed to load subfont mapping table for SFD=\"%s\" subfont_id=\"%s\"",
+ sfd->ident, subfont_id);
+ }
+ sfd->rec_id[i] = rec_id;
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 3) {
+ int __i;
+ if (rec_id >= 0) {
+ MESG(" at id=\"%d\"", rec_id);
+ MESG("\nsubfont>> Content of mapping table:");
+ for (__i = 0; __i < 256; __i++) {
+ if (__i % 16 == 0)
+ MESG("\nsubfont>> ");
+ MESG(" %04x", sfd_record[rec_id].vector[__i]);
+ }
+ }
+ MESG("\n");
+ }
+
+ return rec_id;
+}
+
+
+/* Lookup mapping table */
+unsigned short
+lookup_sfd_record (int rec_id, unsigned char c)
+{
+ if (!sfd_record ||
+ rec_id < 0 || rec_id >= num_sfd_records)
+ ERROR("Invalid subfont_id: %d", rec_id);
+ return sfd_record[rec_id].vector[c];
+}
+
+void
+release_sfd_record (void)
+{
+ int i;
+
+ if (sfd_record) {
+ RELEASE(sfd_record);
+ }
+ if (sfd_files) {
+ for (i = 0; i < num_sfd_files; i++) {
+ clean_sfd_file_(&sfd_files[i]);
+ }
+ RELEASE(sfd_files);
+ }
+ sfd_record = NULL;
+ sfd_files = NULL;
+ num_sfd_records = max_sfd_records = 0;
+ num_sfd_files = max_sfd_files = 0;
+}
+
+
+#if DPXTEST
+/* SFD file dumper */
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#else
+typedef int iconv_t;
+#endif
+#include <string.h>
+
+static void
+dump_table (const char *sfd_name, const char *sub_name, iconv_t cd)
+{
+ int rec_id, i;
+
+ rec_id = sfd_load_record(sfd_name, sub_name);
+ if (rec_id < 0) {
+ WARN("Could not load SFD mapping for \"%s\"", sub_name);
+ return;
+ }
+ fprintf(stdout, " <subfont id=\"%s\">\n", sub_name);
+ for (i = 0; i < 256; i++) {
+ unsigned short c = lookup_sfd_record(rec_id, i);
+ char *p, inbuf[2];
+ char *q, outbuf[32];
+ size_t r, inbufleft = 2, outbufleft = 32;
+
+ if (c == 0)
+ fprintf(stdout, " <!-- %02x: undefined -->", i);
+ else {
+ fprintf(stdout, " <a bi=\"%02x\" bo=\"%02x %02x\"", i, (c >> 8) & 0xff, c & 0xff);
+ if (cd != (iconv_t) -1) {
+ p = inbuf; q = outbuf;
+ inbuf[0] = (c >> 8) & 0xff;
+ inbuf[1] = c & 0xff;
+#ifdef HAVE_ICONV
+ r = iconv(cd, &p, &inbufleft, &q, &outbufleft);
+ if (r == -1) {
+ if (dpx_conf.verbose_level > 0) {
+ WARN("Conversion to Unicode failed for subfont-id=\"%s\" code=\"0x%02x\"",
+ sub_name, i);
+ WARN(">> with: %s", strerror(errno));
+ }
+ } else {
+ outbuf[32-outbufleft] = 0;
+ fprintf(stdout, " uc=\"%s\"", outbuf);
+ }
+#endif /* HAVE_ICONV */
+ }
+ fprintf(stdout, " />");
+ }
+ fprintf(stdout, "\n");
+ }
+ fprintf(stdout, " </subfont>\n");
+ return;
+}
+
+#define subfontDefinition_DTD "\
+<!ELEMENT subfontDefinition (subfont+)>\n\
+<!ATTLIST subfontDefinition\n\
+ id CDATA #REQUIRED\n\
+ output-encoding CDATA #IMPLIED\n\
+>\n\
+<!ELEMENT subfont (a*)>\n\
+<!ATTLIST subfont\n\
+ id CDATA #REQUIRED\n\
+>\n\
+<!ELEMENT a EMPTY>\n\
+<!ATTLIST a\n\
+ bi NMTOKENS #REQUIRED\n\
+ bo NMTOKENS #REQUIRED\n\
+ uc CDATA #IMPLIED\n\
+>\
+"
+
+void
+test_subfont_help (void)
+{
+ fprintf(stdout, "usage: subfont [options] SFD_name\n");
+ fprintf(stdout, "-e, --encoding string\n");
+ fprintf(stdout, " Target (output) encoding of SFD mapping is 'string'.\n");
+ fprintf(stdout, " It must be an encoding name recognized by iconv.\n");
+ fprintf(stdout, " With this option write Unicode character in auxiliary attribute 'uc'.\n");
+ fprintf(stdout, "-s, --subfont-id string\n");
+ fprintf(stdout, " Load and dump mapping table only for subfont 'string'.\n");
+}
+
+int
+test_subfont_main (int argc, char *argv[])
+{
+ char *sfd_name = NULL, *sub_name = NULL;
+ char *from = NULL;
+ int i;
+ iconv_t cd = (iconv_t) -1;
+
+ for (;;) {
+ int c, optidx = 0;
+ static struct option long_options[] = {
+ {"encoding", 1, 0, 'e'}, /* for to-Unicode conversion */
+ {"subfont-id", 1, 0, 's'},
+ {"help", 0, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "e:s:h", long_options, &optidx);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'e':
+ from = optarg;
+ break;
+ case 's':
+ sub_name = optarg;
+ break;
+ case 'h':
+ test_subfont_help();
+ return 0;
+ break;
+ default:
+ test_subfont_help();
+ return -1;
+ break;
+ }
+ }
+ if (optind < argc) {
+ sfd_name = argv[optind++];
+ }
+
+ if (sfd_name == NULL) {
+ WARN("No SFD file name specified.");
+ test_subfont_help();
+ return -1;
+ }
+ if (!from)
+ cd = (iconv_t) -1;
+ else {
+#ifdef HAVE_ICONV
+ cd = iconv_open("utf-8", from);
+ if (cd == (iconv_t) -1) {
+ WARN("Can't open iconv conversion descriptor for %s --> utf-8", from);
+ return -1;
+ }
+#else
+ WARN("Your system doesn't have iconv() in libc!");
+#endif
+ }
+
+ fprintf(stdout, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ fprintf(stdout, "<!DOCTYPE subfontDefinition [\n%s\n]>\n",
+ subfontDefinition_DTD);
+ fprintf(stdout, "<subfontDefinition id=\"%s\" output-encoding=\"%s\">\n",
+ sfd_name, from ? from : "unknown");
+ if (sub_name == NULL || !strcmp(sub_name, "all")) {
+ char **sub_id;
+ int num_ids = 0;
+ sub_id = sfd_get_subfont_ids(sfd_name, &num_ids);
+ if (!sub_id)
+ WARN("Could not open SFD file: %s", sfd_name);
+ else {
+ for (i = 0; i < num_ids; i++)
+ dump_table(sfd_name, sub_id[i], cd);
+ }
+ } else {
+ dump_table(sfd_name, sub_name, cd);
+ }
+ fprintf(stdout, "</subfontDefinition>\n");
+
+#ifdef HAVE_ICONV
+ if (cd != (iconv_t) -1)
+ iconv_close(cd);
+#endif
+
+ return 0;
+}
+
+#endif /* DPXTEST */
diff --git a/Build/source/texk/dvipdfm-x/subfont.h b/Build/source/texk/dvipdfm-x/subfont.h
new file mode 100644
index 00000000000..e1d9f521349
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/subfont.h
@@ -0,0 +1,31 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SUBFONT_H_
+#define _SUBFONT_H_
+
+extern void release_sfd_record (void);
+
+extern unsigned short lookup_sfd_record(int rec_id, unsigned char code);
+
+extern int sfd_load_record (const char *sfd_name, const char *subfont_id);
+extern char **sfd_get_subfont_ids (const char *sfd_name, int *num_subfonts);
+
+#endif /* _SUBFONT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/system.h b/Build/source/texk/dvipdfm-x/system.h
new file mode 100644
index 00000000000..6b1c7b106a2
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/system.h
@@ -0,0 +1,40 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _SYSTEM_H_
+#define _SYSTEM_H_
+
+#ifdef MIKTEX
+#include <miktex/Core/Core>
+#include "gnu-miktex.h"
+#include <miktex/KPSE/Emulation>
+#else
+#include <kpathsea/kpathsea.h>
+#endif
+
+#ifdef WIN32
+#ifdef _MSC_VER
+# pragma warning(disable : 4101 4018)
+#endif /* _MSC_VER */
+#endif /* WIN32 */
+
+#endif /* _SYSTEM_H_ */
diff --git a/Build/source/texk/dvipdfm-x/t1_char.c b/Build/source/texk/dvipdfm-x/t1_char.c
new file mode 100644
index 00000000000..d2c6987fcbb
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/t1_char.c
@@ -0,0 +1,1588 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "numbers.h"
+
+#include "pdfobj.h"
+#include "pdffont.h"
+
+#include "pdfencoding.h"
+#include "unicode.h"
+
+#include "dpxutil.h"
+
+#include "pst_obj.h"
+#include "pst.h"
+
+#include "cff_limits.h"
+#include "cff_types.h"
+#include "cff_dict.h"
+#include "cff.h"
+
+#include "t1_char.h"
+
+/*
+ * Type 1 -> Type 1C
+ */
+
+/* Charstring decoder/encoder status codes */
+#define CS_OP_NOSUPPORT -4
+#define CS_BUFFER_ERROR -3
+#define CS_STACK_ERROR -2
+#define CS_PARSE_ERROR -1
+#define CS_PARSE_OK 0
+#define CS_PARSE_END 1
+#define CS_SUBR_RETURN 2
+#define CS_CHAR_END 3
+
+static int status = CS_PARSE_ERROR;
+
+#define DST_NEED(a,b) {if ((a) < (b)) { status = CS_BUFFER_ERROR ; return ; }}
+#define SRC_NEED(a,b) {if ((a) < (b)) { status = CS_PARSE_ERROR ; return ; }}
+#define NEED(a,b) {if ((a) < (b)) { status = CS_STACK_ERROR ; return ; }}
+
+#define T1_CS_PHASE_INIT 0
+#define T1_CS_PHASE_HINT 1
+#define T1_CS_PHASE_PATH 2
+#define T1_CS_PHASE_FLEX 3
+
+static int phase = -1;
+static int nest = -1;
+
+#ifndef CS_STEM_ZONE_MAX
+#define CS_STEM_ZONE_MAX 96
+#endif
+#ifndef CS_STEM_GROUP_MAX
+#define CS_STEM_GROUP_MAX CS_STEM_ZONE_MAX
+#endif
+#ifndef CS_ARG_STACK_MAX
+#define CS_ARG_STACK_MAX 48
+#endif
+#ifndef PS_ARG_STACK_MAX
+/*
+ * Counter control may have CS_STEM_ZONE_MAX*2+2 arguments.
+ */
+#define PS_ARG_STACK_MAX (CS_STEM_ZONE_MAX*2+2)
+#endif
+
+typedef struct t1_cpath {
+ int type;
+ int num_args;
+ double args[CS_ARG_STACK_MAX];
+ struct t1_cpath *next;
+} t1_cpath;
+
+#define HSTEM 0
+#define VSTEM 1
+typedef struct {
+ int id;
+ int dir;
+ double pos, del;
+} t1_stem;
+
+typedef struct {
+ int num_stems;
+ double stems[CS_STEM_ZONE_MAX]; /* int */
+} t1_stemgroup;
+
+#define T1_CS_FLAG_NONE 0
+#define T1_CS_FLAG_USE_HINTMASK (1 << 0)
+#define T1_CS_FLAG_USE_CNTRMASK (1 << 1)
+#define T1_CS_FLAG_USE_SEAC (1 << 2)
+
+typedef struct {
+ int flags;
+ struct {
+ double sbx, sby, wx, wy;
+ } sbw;
+ struct {
+ double llx, lly, urx, ury;
+ } bbox;
+ struct {
+ double asb, adx, ady;
+ card8 bchar, achar;
+ } seac;
+ int num_stems;
+ t1_stem stems[CS_STEM_ZONE_MAX];
+ t1_cpath *charpath;
+ t1_cpath *lastpath;
+} t1_chardesc;
+
+static int cs_stack_top = 0;
+static int ps_stack_top = 0;
+
+/* [vh]stem support require one more stack size. */
+static double cs_arg_stack[CS_ARG_STACK_MAX+1];
+static double ps_arg_stack[PS_ARG_STACK_MAX];
+
+#define CS_HINT_DECL -1
+#define CS_FLEX_CTRL -2
+#define CS_CNTR_CTRL -3
+
+/*
+ * Type 1/2 CharString encoding
+ */
+
+/*
+ * 1-byte CharString operaotrs:
+ * cs_escape is first byte of two-byte operator
+ */
+
+/* RESERVED 0 */
+#define cs_hstem 1
+/* RESERVED 2 */
+#define cs_vstem 3
+#define cs_vmoveto 4
+#define cs_rlineto 5
+#define cs_hlineto 6
+#define cs_vlineto 7
+#define cs_rrcurveto 8
+#define cs_closepath 9
+#define cs_callsubr 10
+#define cs_return 11
+#define cs_escape 12
+#define cs_hsbw 13
+#define cs_endchar 14
+/* RESERVED 15 */
+/* RESERVED 16 */
+/* RESERVED 17 */
+#define cs_hstemhm 18
+#define cs_hintmask 19
+#define cs_cntrmask 20
+#define cs_rmoveto 21
+#define cs_hmoveto 22
+#define cs_vstemhm 23
+#define cs_rcurveline 24
+#define cs_rlinecurve 25
+#define cs_vvcurveto 26
+#define cs_hhcurveto 27
+/* SHORTINT 28 : first byte of shortint*/
+#define cs_callgsubr 29
+#define cs_vhcurveto 30
+#define cs_hvcurveto 31
+
+/* 2-byte op. flex 34-37 used. */
+
+/*
+ * 2-byte CharString operaotrs:
+ * "dotsection" is obsoleted in Type 2 charstring.
+ */
+
+#define cs_dotsection 0
+#define cs_vstem3 1
+#define cs_hstem3 2
+#define cs_and 3
+#define cs_or 4
+#define cs_not 5
+#define cs_seac 6
+#define cs_sbw 7
+/* RESERVED 8 */
+#define cs_abs 9
+#define cs_add 10
+#define cs_sub 11
+#define cs_div 12
+/* RESERVED 13 */
+#define cs_neg 14
+#define cs_eq 15
+#define cs_callothersubr 16
+#define cs_pop 17
+#define cs_drop 18
+/* RESERVED 19 */
+#define cs_put 20
+#define cs_get 21
+#define cs_ifelse 22
+#define cs_random 23
+#define cs_mul 24
+/* RESERVED 25 */
+#define cs_sqrt 26
+#define cs_dup 27
+#define cs_exch 28
+#define cs_index 29
+#define cs_roll 30
+/* RESERVED 31 */
+/* RESERVED 32 */
+#define cs_setcurrentpoint 33
+#define cs_hflex 34
+#define cs_flex 35
+#define cs_hflex1 36
+#define cs_flex1 37
+
+#define IS_PATH_OPERATOR(o) (((o) >= cs_vmoveto && (o) <= cs_closepath) || \
+ ((o) >= cs_rmoveto && (o) <= cs_hvcurveto && \
+ (o) != cs_vstemhm && (o) != cs_callgsubr && (o) != 28)\
+ )
+
+/*
+ * Stem:
+ *
+ * 1. Stems must be sorted in the increasing bottom/left edge order.
+ * 2. The encoded values are all relative; The value x(y) of the first
+ * stem is relative to 0 for Type 2 charstring and is relative to
+ * the left(bottom) side-bearing for Type 1 charstring.
+ * 3. A width of -20(-21) specifies the top/right(bottom/left) edge
+ * of an edge hint in Type 2 charstring. But the width of 'ghost'
+ * hint in Type 1 charstring is positive with value 20 or 21.
+ * 4. The h(v)stemhm MUST be used instead of h(v)stem if charstring
+ * contains hintmask operator.
+ *
+ * TODO:
+ *
+ * Convert ghost hint to edge hint, Counter control for hstem3/vstem3.
+ */
+
+static inline int
+stem_compare (const void *v1, const void *v2)
+{
+ int cmp = 0;
+ const t1_stem *s1, *s2;
+
+ s1 = (const t1_stem *) v1;
+ s2 = (const t1_stem *) v2;
+ if (s1->dir == s2->dir) {
+ if (s1->pos == s2->pos) {
+ if (s1->del == s2->del)
+ cmp = 0;
+ else
+ cmp = (s1->del < s2->del) ? -1 : 1;
+ } else {
+ cmp = (s1->pos < s2->pos) ? -1 : 1;
+ }
+ } else {
+ cmp = (s1->dir == HSTEM) ? -1 : 1;
+ }
+
+ return cmp;
+}
+
+#define SORT_STEMS(cd) qsort((cd)->stems,(cd)->num_stems,sizeof(t1_stem),stem_compare)
+
+static int
+get_stem (t1_chardesc *cd, int stem_id)
+{
+ int i;
+
+ for (i = 0; i < cd->num_stems; i++) {
+ if (cd->stems[i].id == stem_id)
+ break;
+ }
+
+ return ((i < cd->num_stems) ? i : -1);
+}
+
+static int
+add_stem (t1_chardesc *cd, double pos, double del, int dir)
+{
+ int i;
+
+ ASSERT(cd);
+
+ pos += (dir == HSTEM) ? cd->sbw.sby : cd->sbw.sbx;
+ for (i = 0; i < cd->num_stems; i++) {
+ if (cd->stems[i].dir == dir &&
+ cd->stems[i].pos == pos &&
+ cd->stems[i].del == del)
+ break;
+ }
+ if (i == cd->num_stems) {
+ if (cd->num_stems == CS_STEM_ZONE_MAX)
+ return -1;
+ cd->stems[i].dir = dir;
+ cd->stems[i].pos = pos;
+ cd->stems[i].del = del;
+ cd->stems[i].id = cd->num_stems;
+ (cd->num_stems)++;
+ }
+
+ return cd->stems[i].id;
+}
+
+
+static void
+copy_args (double *args1, double *args2, int count)
+{
+ while (count-- > 0) {
+ *args1 = *args2;
+ args1++; args2++;
+ }
+}
+
+/*
+ * Stack:
+ */
+#define LIMITCHECK(n) do {\
+ if (cs_stack_top+(n) > CS_ARG_STACK_MAX) {\
+ status = CS_STACK_ERROR;\
+ return;\
+ }\
+ } while (0)
+#define CHECKSTACK(n) do {\
+ if (cs_stack_top < (n)) {\
+ status = CS_STACK_ERROR;\
+ return;\
+ }\
+ } while (0)
+#define CLEARSTACK() do {\
+ cs_stack_top = 0;\
+ } while (0)
+
+/*
+ * Path construction:
+ */
+/* Get operands from cs_arg_stack[] */
+static void
+add_charpath (t1_chardesc *cd, int type, double *argv, int argn)
+{
+ t1_cpath *p;
+
+ ASSERT(cd);
+ ASSERT(argn <= CS_ARG_STACK_MAX);
+
+ p = NEW(1, t1_cpath);
+ p->type = type;
+ p->num_args = argn;
+ p->next = NULL;
+
+ while (argn-- > 0)
+ p->args[argn] = argv[argn];
+
+ if (!cd->charpath)
+ cd->charpath = p;
+ if (cd->lastpath)
+ cd->lastpath->next = p;
+ cd->lastpath = p;
+
+ if (type >= 0 &&
+ phase != T1_CS_PHASE_FLEX && IS_PATH_OPERATOR(type))
+ phase = T1_CS_PHASE_PATH;
+}
+
+static void
+init_charpath (t1_chardesc *cd)
+{
+ cd->flags = T1_CS_FLAG_NONE;
+ cd->num_stems = 0;
+ cd->sbw.wx = cd->sbw.wy = 0.0;
+ cd->sbw.sbx = cd->sbw.sby = 0.0;
+ cd->bbox.llx = cd->bbox.lly = cd->bbox.urx = cd->bbox.ury = 0.0;
+ cd->charpath = cd->lastpath = NULL;
+}
+
+static void
+release_charpath (t1_chardesc *cd)
+{
+ t1_cpath *curr, *next;
+
+ ASSERT(cd);
+
+ curr = cd->charpath;
+ while (curr != NULL) {
+ next = curr->next;
+ RELEASE(curr);
+ curr = next;
+ }
+
+ cd->charpath = cd->lastpath = NULL;
+}
+
+/*
+ * Type 1 charstring operators:
+ */
+#define ADD_PATH(p,t,n) add_charpath((p),(t),&(cs_arg_stack[cs_stack_top-(n)]),(n))
+
+/*
+ * Single byte operators:
+ */
+static void
+do_operator1 (t1_chardesc *cd, card8 **data)
+{
+ card8 op = **data;
+
+ *data += 1;
+
+ switch (op) {
+ case cs_closepath:
+ /*
+ * From T1 spec.:
+ * Note that, unlike the closepath command in the PostScript language,
+ * this command does not reposition the current point. Any subsequent
+ * rmoveto must be relative to the current point in force before the
+ * Type 1 font format closepath command was given.
+ */
+ /* noop */
+ CLEARSTACK();
+ break;
+ case cs_hsbw:
+ CHECKSTACK(2);
+ cd->sbw.wx = cs_arg_stack[--cs_stack_top];
+ cd->sbw.wy = 0;
+ cd->sbw.sbx = cs_arg_stack[--cs_stack_top];
+ cd->sbw.sby = 0;
+ CLEARSTACK();
+ /* hsbw does NOT set currentpoint. */
+ break;
+ case cs_hstem:
+ case cs_vstem:
+ CHECKSTACK(2);
+ {
+ int stem_id;
+ stem_id = add_stem(cd,
+ cs_arg_stack[cs_stack_top-2],
+ cs_arg_stack[cs_stack_top-1],
+ ((op == cs_hstem) ? HSTEM : VSTEM));
+ if (stem_id < 0) {
+ WARN("Too many hints...");
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ /* Put stem_id onto the stack... */
+ cs_arg_stack[cs_stack_top++] = stem_id;
+ ADD_PATH(cd, CS_HINT_DECL, 1);
+ }
+ CLEARSTACK();
+ break;
+ case cs_rmoveto:
+ /*
+ * Reference point is (0, 0) in Type 2 charstring.
+ */
+ CHECKSTACK(2);
+ {
+ if (phase < T1_CS_PHASE_PATH) {
+ cs_arg_stack[cs_stack_top-2] += cd->sbw.sbx;
+ cs_arg_stack[cs_stack_top-1] += cd->sbw.sby;
+ }
+ ADD_PATH(cd, op, 2);
+ }
+ CLEARSTACK();
+ break;
+ case cs_hmoveto:
+ case cs_vmoveto:
+ CHECKSTACK(1);
+ {
+ int argn = 1;
+ if (phase < T1_CS_PHASE_PATH) {
+ /*
+ * The reference point for the first moveto operator is diferrent
+ * between Type 1 charstring and Type 2 charstring. We compensate it.
+ */
+ if (op == cs_hmoveto) {
+ cs_arg_stack[cs_stack_top-1] += cd->sbw.sbx;
+ if (cd->sbw.sby != 0.0) {
+ cs_arg_stack[cs_stack_top++] = cd->sbw.sby;
+ argn = 2;
+ op = cs_rmoveto;
+ }
+ } else {
+ cs_arg_stack[cs_stack_top-1] += cd->sbw.sby;
+ if (cd->sbw.sbx != 0.0) {
+ cs_arg_stack[cs_stack_top] = cs_arg_stack[cs_stack_top-1];
+ cs_arg_stack[cs_stack_top-1] = cd->sbw.sbx;
+ cs_stack_top++;
+ argn = 2;
+ op = cs_rmoveto;
+ }
+ }
+ }
+ ADD_PATH(cd, op, argn);
+ }
+ CLEARSTACK();
+ break;
+ case cs_endchar:
+ status = CS_CHAR_END;
+ CLEARSTACK();
+ break;
+ /* above oprators are candidate for first stack-clearing operator */
+ case cs_rlineto:
+ CHECKSTACK(2);
+ ADD_PATH(cd, op, 2);
+ CLEARSTACK();
+ break;
+ case cs_hlineto:
+ case cs_vlineto:
+ CHECKSTACK(1);
+ ADD_PATH(cd, op, 1);
+ CLEARSTACK();
+ break;
+ case cs_rrcurveto:
+ CHECKSTACK(6);
+ ADD_PATH(cd, op, 6);
+ CLEARSTACK();
+ break;
+ case cs_vhcurveto:
+ case cs_hvcurveto:
+ CHECKSTACK(4);
+ ADD_PATH(cd, op, 4);
+ CLEARSTACK();
+ break;
+ /* all operotors above are stack-clearing operator */
+ /* no output */
+ case cs_return:
+ break;
+ case cs_callsubr:
+ ERROR("Unexpected callsubr.");
+ break;
+ default:
+ /* no-op ? */
+ WARN("Unknown charstring operator: 0x%02x", op);
+ status = CS_PARSE_ERROR;
+ break;
+ }
+
+ return;
+}
+
+/*
+ * OtherSubrs:
+ *
+ * arg0 arg1 ... argn n othersubr# callothersubr
+ *
+ * 0: Build flex:
+ * fd x y 3 0 callothersubr
+ * Othersubr #0 pushes x and y to PostScript interpreter operand stack.
+ * 1: Start flex
+ * 0 1 callothersubr
+ * 2: Mark flex control points
+ * 0 2 callothersubr
+ * 3: Discard hint
+ * subr# 1 3 callothersubr pop callsubr
+ * Subroutine subr# (only) contains stem declaration.
+ * Othersubr #3 pushes subr# to PostScript interpreter operand stack.
+ * 12: Counter control
+ * A subr to avoid stack overflow.
+ * 13: Counter control
+ */
+
+/*
+ * Convert six control points marked as CS_FLEX_CTRL to a flex path.
+ */
+static void
+do_othersubr0 (t1_chardesc *cd)
+{
+ t1_cpath *flex, *cur, *next;
+
+ if (ps_stack_top < 1) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+
+ /* Seek first CS_FLEX_CTRL mark */
+ for (cur = cd->charpath; cur != NULL && cur->type != CS_FLEX_CTRL; cur = cur->next);
+ flex = cur;
+ {
+ int i;
+ cur = cur->next;
+ for (i = 1; i < 7; i++) {
+ if (cur == NULL || cur->type != CS_FLEX_CTRL ||
+ cur->num_args != 2) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ if (i == 1) {
+ flex->args[0] += cur->args[0];
+ flex->args[1] += cur->args[1];
+ } else {
+ copy_args(&(flex->args[2*i-2]), cur->args, 2);
+ }
+ next = cur->next;
+ RELEASE(cur);
+ cur = next;
+ }
+ }
+ if (cur != NULL) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ /*
+ * Now 'flex' have all six control points, the first pair is relative
+ * from starting point.
+ */
+ flex->type = cs_flex;
+ flex->args[12] = ps_arg_stack[--ps_stack_top]; /* flex depth */
+ flex->num_args = 13;
+ flex->next = NULL;
+ cd->lastpath = flex;
+
+ phase = T1_CS_PHASE_PATH;
+}
+
+/* Start flex */
+static void
+do_othersubr1 (void)
+{
+ phase = T1_CS_PHASE_FLEX;
+}
+
+/* Mark flex control point */
+static void
+do_othersubr2 (t1_chardesc *cd)
+{
+ if (phase != T1_CS_PHASE_FLEX || !cd->lastpath) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+
+ switch (cd->lastpath->type) {
+ case cs_rmoveto:
+ break;
+ case cs_hmoveto:
+ cd->lastpath->num_args = 2;
+ cd->lastpath->args[1] = 0.0;
+ break;
+ case cs_vmoveto:
+ cd->lastpath->num_args = 2;
+ cd->lastpath->args[1] = cd->lastpath->args[0];
+ cd->lastpath->args[0] = 0.0;
+ break;
+ default:
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ cd->lastpath->type = CS_FLEX_CTRL;
+}
+
+/*
+ * Hint Replacement:
+ * "Adobe Type 1 Font Format", Chapter 8.
+ */
+static void
+do_othersubr3 (t1_chardesc *cd)
+{
+ cd->flags |= T1_CS_FLAG_USE_HINTMASK;
+}
+
+static void
+do_othersubr12 (void)
+{
+ /* Othersubr12 call must immediately follow the hsbw or sbw. */
+ if (phase != T1_CS_PHASE_INIT) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ /* noop */
+}
+
+static void
+do_othersubr13 (t1_chardesc *cd)
+{
+ t1_stemgroup stemgroups[CS_STEM_GROUP_MAX];
+ int num_hgroups, num_vgroups, n, stem_id;
+ double pos, del;
+
+ /* After #12 callothersubr or hsbw or sbw. */
+ if (phase != T1_CS_PHASE_INIT) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ for (n = 0; n < CS_STEM_GROUP_MAX; n++) {
+ stemgroups[n].num_stems = 0;
+ }
+
+ num_hgroups = (int) ps_arg_stack[--ps_stack_top];
+ if (num_hgroups < 0 || num_hgroups > CS_STEM_GROUP_MAX) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ n = 0; pos = 0.0;
+ while (ps_stack_top >= 2 && n < num_hgroups) {
+ /* add_stem() add sidebearing */
+ pos += ps_arg_stack[--ps_stack_top];
+ del = ps_arg_stack[--ps_stack_top];
+ stem_id = add_stem(cd,
+ (del < 0.0) ? pos + del : pos,
+ (del < 0.0) ? -del : del,
+ HSTEM);
+ stemgroups[n].stems[stemgroups[n].num_stems] = stem_id;
+ stemgroups[n].num_stems += 1;
+ pos += del;
+ if (del < 0.0) {
+ pos = 0.0;
+ n++;
+ }
+ }
+ if (n != num_hgroups) {
+ status = CS_STACK_ERROR;
+ return;
+ }
+
+ num_vgroups = (int) ps_arg_stack[--ps_stack_top];
+ if (num_vgroups < 0 || num_vgroups > CS_STEM_GROUP_MAX) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ n = 0; pos = 0.0;
+ while (ps_stack_top >= 2 && n < num_vgroups) {
+ /* add_stem() add sidebearing */
+ pos += ps_arg_stack[--ps_stack_top];
+ del = ps_arg_stack[--ps_stack_top];
+ stem_id = add_stem(cd,
+ (del < 0.0) ? pos + del : pos,
+ (del < 0.0) ? -del : del,
+ VSTEM);
+ stemgroups[n].stems[stemgroups[n].num_stems] = stem_id;
+ stemgroups[n].num_stems += 1;
+ pos += del;
+ if (del < 0.0) {
+ pos = 0.0;
+ n++;
+ }
+ }
+ if (n != num_vgroups) {
+ status = CS_STACK_ERROR;
+ return;
+ }
+
+ for (n = 0; n < MAX(num_hgroups, num_vgroups); n++) {
+ add_charpath(cd, cs_cntrmask,
+ stemgroups[n].stems, stemgroups[n].num_stems);
+ }
+
+ cd->flags |= T1_CS_FLAG_USE_CNTRMASK;
+}
+
+static void
+do_callothersubr (t1_chardesc *cd)
+{
+ int argn, subrno;
+
+ CHECKSTACK(2);
+ subrno = (int) cs_arg_stack[--cs_stack_top];
+ argn = (int) cs_arg_stack[--cs_stack_top];
+
+ CHECKSTACK(argn);
+ if (ps_stack_top+argn > PS_ARG_STACK_MAX) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ while (argn-- > 0)
+ ps_arg_stack[ps_stack_top++] = cs_arg_stack[--cs_stack_top];
+
+ switch (subrno) {
+ case 0: do_othersubr0(cd) ; break;
+ case 1: do_othersubr1() ; break;
+ case 2: do_othersubr2(cd) ; break;
+ case 3: do_othersubr3(cd) ; break;
+ case 12: do_othersubr12() ; break;
+ case 13: do_othersubr13(cd); break;
+ default:
+ ERROR("Unknown othersubr #%ld.", subrno);
+ break;
+ }
+}
+
+/*
+ * Double byte operators:
+ */
+static void
+do_operator2 (t1_chardesc *cd, card8 **data, card8 *endptr)
+{
+ card8 op;
+
+ *data += 1;
+
+ SRC_NEED(endptr, *data + 1);
+
+ op = **data;
+ *data += 1;
+
+ switch(op) {
+ case cs_sbw:
+ CHECKSTACK(4);
+ cd->sbw.wy = cs_arg_stack[--cs_stack_top];
+ cd->sbw.wx = cs_arg_stack[--cs_stack_top];
+ cd->sbw.sby = cs_arg_stack[--cs_stack_top];
+ cd->sbw.sbx = cs_arg_stack[--cs_stack_top];
+ CLEARSTACK();
+ break;
+ case cs_hstem3:
+ case cs_vstem3:
+ /*
+ * TODO:
+ * The counter control can be used for hstem3 and vstem3
+ * operator if LanguageGroup is not equal to 1.
+ */
+ CHECKSTACK(6);
+ {
+ int i;
+ for (i = 2; i >= 0; i--) {
+ int stem_id;
+ stem_id = add_stem(cd,
+ cs_arg_stack[cs_stack_top-2*i-2],
+ cs_arg_stack[cs_stack_top-2*i-1],
+ ((op == cs_hstem3) ? HSTEM : VSTEM));
+ if (stem_id < 0) {
+ WARN("Too many hints...");
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ /* Put stem_id onto the stack... */
+ cs_arg_stack[cs_stack_top++] = stem_id;
+ ADD_PATH(cd, CS_HINT_DECL, 1);
+ cs_stack_top--;
+ }
+ }
+ CLEARSTACK();
+ break;
+ case cs_setcurrentpoint:
+ CHECKSTACK(2);
+ /* noop */
+ CLEARSTACK();
+ break;
+ /* all operator above are stack-clearing */
+ case cs_pop:
+ /*
+ * Transfer a operand from PS interpreter operand stack to BuildChar
+ * operand stack.
+ */
+ if (ps_stack_top < 1) {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+ LIMITCHECK(1);
+ cs_arg_stack[cs_stack_top++] = ps_arg_stack[--ps_stack_top];
+ break;
+ case cs_dotsection:
+#if 0
+ /*
+ * If the hint replacement feature is used in the font, the
+ * "dotsection" operator exist only for compatibility to older
+ * (more than 10 years old) Type 1 font rasterizer which can't
+ * perform hint replacement. In this case, we silently ignore
+ * the "dotsection" operator.
+ *
+ * The following code will wrongly warn about "dotsection" when
+ * the charstring only contains dot (e.g., "bullet") where the
+ * hint replacement is not necessary.
+ *
+ * Adobe ATM renderers always treat this operator as a no-op.
+ * (See, Adobe Technical Note #5177, Appendix C)
+ */
+ if (!(cd->flags & T1_CS_FLAG_USE_HINTMASK)) {
+ if (dpx_conf.verbose_level > 1)
+ WARN("Obsolete Type 1 charstring operator \"dotsection\" not supported.");
+ }
+#endif
+ /* noop */
+ break;
+ case cs_div: /* TODO: check overflow */
+ CHECKSTACK(2);
+ cs_arg_stack[cs_stack_top-2] /= cs_arg_stack[cs_stack_top-1];
+ cs_stack_top--;
+ break;
+ case cs_callothersubr:
+ do_callothersubr(cd);
+ break;
+ case cs_seac:
+ CHECKSTACK(5);
+ cd->flags |= T1_CS_FLAG_USE_SEAC;
+ cd->seac.achar = (card8) cs_arg_stack[--cs_stack_top];
+ cd->seac.bchar = (card8) cs_arg_stack[--cs_stack_top];
+ cd->seac.ady = cs_arg_stack[--cs_stack_top];
+ cd->seac.adx = cs_arg_stack[--cs_stack_top];
+ /* We must compensate the difference of the glyph origin. */
+ cd->seac.ady += cd->sbw.sby;
+ cd->seac.adx += cd->sbw.sbx - cs_arg_stack[--cs_stack_top];
+ CLEARSTACK();
+ break;
+ default:
+ /* no-op ? */
+ WARN("Unknown charstring operator: 0x0c%02x", op);
+ status = CS_PARSE_ERROR;
+ break;
+ }
+
+ return;
+}
+
+/*
+ * Charstring encoding:
+ * Copied from cs_type2.c
+ * Note:
+ * The Type 2 interpretation of a number encoded in five-bytes (those with
+ * an initial byte value of 255) differs from how it is interpreted in the
+ * Type 1 format.
+ */
+
+/* Type 2 5-bytes encoding used. */
+static void
+put_numbers (double *argv, int argn, card8 **dest, card8 *limit)
+{
+ int i;
+
+ for (i = 0; i < argn; i++) {
+ double value;
+ int ivalue;
+ value = argv[i];
+ /* Nearest integer value */
+ ivalue = (int) floor(value+0.5);
+ if (value >= 0x8000L || value <= (-0x8000L - 1)) {
+ /*
+ * This number cannot be represented as a single operand.
+ * We must use `a b mul ...' or `a c div' to represent large values.
+ */
+ ERROR("Argument value too large. (This is bug)");
+ } else if (fabs(value - ivalue) > 3.0e-5) {
+ /* 16.16-bit signed fixed value */
+ DST_NEED(limit, *dest + 5);
+ *(*dest)++ = 255;
+ ivalue = (int) floor(value); /* mantissa */
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ ivalue = (int)((value - ivalue) * 0x10000l); /* fraction */
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ /* Everything else are integers. */
+ } else if (ivalue >= -107 && ivalue <= 107) {
+ DST_NEED(limit, *dest + 1);
+ *(*dest)++ = ivalue + 139;
+ } else if (ivalue >= 108 && ivalue <= 1131) {
+ DST_NEED(limit, *dest + 2);
+ ivalue = 0xf700u + ivalue - 108;
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ } else if (ivalue >= -1131 && ivalue <= -108) {
+ DST_NEED(limit, *dest + 2);
+ ivalue = 0xfb00u - ivalue - 108;
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = ivalue & 0xff;
+ } else if (ivalue >= -32768 && ivalue <= 32767) { /* shortint */
+ DST_NEED(limit, *dest + 3);
+ *(*dest)++ = 28;
+ *(*dest)++ = (ivalue >> 8) & 0xff;
+ *(*dest)++ = (ivalue) & 0xff;
+ } else { /* Shouldn't come here */
+ ERROR("Unexpected error.");
+ }
+ }
+
+ return;
+}
+
+static void
+get_integer (card8 **data, card8 *endptr)
+{
+ int result = 0;
+ card8 b0 = **data, b1, b2;
+
+ *data += 1;
+
+ if (b0 == 28) { /* shortint */
+ SRC_NEED(endptr, *data + 2);
+ b1 = **data;
+ b2 = *(*data+1);
+ result = b1*256+b2;
+ if (result > 0x7fff)
+ result -= 0x10000L;
+ *data += 2;
+ } else if (b0 >= 32 && b0 <= 246) { /* int (1) */
+ result = b0 - 139;
+ } else if (b0 >= 247 && b0 <= 250) { /* int (2) */
+ SRC_NEED(endptr, *data + 1);
+ b1 = **data;
+ result = (b0-247)*256+b1+108;
+ *data += 1;
+ } else if (b0 >= 251 && b0 <= 254) {
+ SRC_NEED(endptr, *data + 1);
+ b1 = **data;
+ result = -(b0-251)*256-b1-108;
+ *data += 1;
+ } else {
+ status = CS_PARSE_ERROR;
+ return;
+ }
+
+ LIMITCHECK(1);
+ cs_arg_stack[cs_stack_top++] = (double) result;
+
+ return;
+}
+
+/* Type 1 */
+static void
+get_longint (card8 **data, card8 *endptr)
+{
+ int result = 0;
+ int i;
+
+ *data += 1;
+ SRC_NEED(endptr, *data + 4);
+ result = **data;
+ if (result >= 0x80L)
+ result -= 0x100L;
+ *data += 1;
+ for (i = 1; i < 4; i++) {
+ result = result*256 + (**data);
+ *data += 1;
+ }
+
+ LIMITCHECK(1);
+ cs_arg_stack[cs_stack_top++] = (double) result;
+
+ return;
+}
+
+/*
+ * TODO:
+ * Check "seac"
+ * We cannot do backword parsing due to subroutine, div etc.
+ */
+
+/* Parse charstring and build charpath. */
+static void
+t1char_build_charpath (t1_chardesc *cd,
+ card8 **data, card8 *endptr, cff_index *subrs)
+{
+ card8 b0 = 0, *subr;
+ int len;
+
+ if (nest > CS_SUBR_NEST_MAX)
+ ERROR("Subroutine nested too deeply.");
+
+ nest++;
+ while (*data < endptr && status == CS_PARSE_OK) {
+ b0 = **data;
+ if (b0 == 255) {
+ get_longint(data, endptr); /* Type 1 */
+ } else if (b0 == cs_return) {
+ status = CS_SUBR_RETURN;
+ } else if (b0 == cs_callsubr) {
+ if (cs_stack_top < 1) {
+ status = CS_STACK_ERROR;
+ } else {
+ int idx;
+
+ idx = cs_arg_stack[--cs_stack_top];
+ if (!subrs || idx >= subrs->count)
+ ERROR("Invalid Subr#.");
+ subr = subrs->data + subrs->offset[idx] - 1;
+ len = subrs->offset[idx+1] - subrs->offset[idx];
+ t1char_build_charpath(cd, &subr, subr+len, subrs);
+ *data += 1;
+ }
+ } else if (b0 == cs_escape) {
+ do_operator2(cd, data, endptr);
+ } else if (b0 < 32 && b0 != 28) { /* 19, 20 need mask */
+ do_operator1(cd, data);
+ } else if ((b0 <= 22 && b0 >= 27) || b0 == 31) { /* reserved */
+ status = CS_PARSE_ERROR; /* not an error ? */
+ } else { /* integer */
+ get_integer(data, endptr);
+ }
+ }
+
+ if (status == CS_SUBR_RETURN) {
+ status = CS_PARSE_OK;
+ } else if (status == CS_CHAR_END && *data < endptr) {
+ if (!(*data == endptr - 1 && **data == cs_return))
+ WARN("Garbage after endchar. (%d bytes)", (int) (endptr - *data));
+ } else if (status < CS_PARSE_OK) { /* error */
+ ERROR("Parsing charstring failed: (status=%d, stack=%d)", status, cs_stack_top);
+ }
+
+ nest--;
+
+ return;
+}
+
+/*
+ * Calculate BoundingBox and compress path.
+ * The essentials of PDF size reduction is not Type 2 charstring compression
+ * but Type 1 charstring encryption. Encryption makes lossless compression
+ * useless. We will only do very simple charstring compression.
+ */
+static void
+do_postproc (t1_chardesc *cd)
+{
+ int i;
+ t1_cpath *cur, *prev, *next;
+ double x, y;
+
+ if (!cd->charpath)
+ return;
+
+ /* Set dummy large value. */
+ cd->bbox.llx = cd->bbox.lly = 100000.0;
+ cd->bbox.urx = cd->bbox.ury = -100000.0;
+
+ cur = cd->charpath;
+ prev = NULL;
+ x = y = 0.0;
+
+#define UPDATE_BBOX(b,x,y) do {\
+ if ((b).llx > (x)) (b).llx = (x);\
+ if ((b).urx < (x)) (b).urx = (x);\
+ if ((b).lly > (y)) (b).lly = (y);\
+ if ((b).ury < (y)) (b).ury = (y);\
+} while (0)
+#define TRY_COMPACT (prev && cur && ((prev->num_args + cur->num_args) < CS_ARG_STACK_MAX))
+
+ while (cur != NULL) {
+ next = cur->next;
+ switch (cur->type) {
+ case cs_rmoveto:
+ x += cur->args[0]; y += cur->args[1];
+ UPDATE_BBOX(cd->bbox, x, y);
+ break;
+ case cs_rlineto:
+ x += cur->args[0]; y += cur->args[1];
+ UPDATE_BBOX(cd->bbox, x, y);
+ if (TRY_COMPACT) {
+ if (prev->type == cs_rlineto) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ } else if (prev->type == cs_rrcurveto) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->type = cs_rcurveline;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ }
+ }
+ break;
+ case cs_hmoveto:
+ x += cur->args[0];
+ UPDATE_BBOX(cd->bbox, x, y);
+ break;
+ case cs_hlineto:
+ x += cur->args[0];
+ UPDATE_BBOX(cd->bbox, x, y);
+ if (TRY_COMPACT) {
+ if ((prev->type == cs_vlineto && (prev->num_args % 2) == 1) ||
+ (prev->type == cs_hlineto && (prev->num_args % 2) == 0)) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ }
+ }
+ break;
+ case cs_vmoveto:
+ y += cur->args[0];
+ UPDATE_BBOX(cd->bbox, x, y);
+ break;
+ case cs_vlineto:
+ y += cur->args[0];
+ UPDATE_BBOX(cd->bbox, x, y);
+ if (TRY_COMPACT) {
+ if ((prev->type == cs_hlineto && (prev->num_args % 2) == 1) ||
+ (prev->type == cs_vlineto && (prev->num_args % 2) == 0)) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ }
+ }
+ break;
+ case cs_rrcurveto:
+ for (i = 0; i < 3; i++) {
+ x += cur->args[2*i]; y += cur->args[2*i+1];
+ UPDATE_BBOX(cd->bbox, x, y);
+ }
+ if (TRY_COMPACT) {
+ if (prev->type == cs_rrcurveto) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ } else if (prev->type == cs_rlineto) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->type = cs_rlinecurve;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ }
+ }
+ break;
+ case cs_vhcurveto:
+ y += cur->args[0];
+ UPDATE_BBOX(cd->bbox, x, y);
+ x += cur->args[1]; y += cur->args[2];
+ UPDATE_BBOX(cd->bbox, x, y);
+ x += cur->args[3];
+ UPDATE_BBOX(cd->bbox, x, y);
+ if (TRY_COMPACT) {
+ if ((prev->type == cs_hvcurveto && ((prev->num_args / 4) % 2) == 1) ||
+ (prev->type == cs_vhcurveto && ((prev->num_args / 4) % 2) == 0)) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ }
+ }
+ break;
+ case cs_hvcurveto:
+ x += cur->args[0];
+ UPDATE_BBOX(cd->bbox, x, y);
+ x += cur->args[1]; y += cur->args[2];
+ UPDATE_BBOX(cd->bbox, x, y);
+ y += cur->args[3];
+ UPDATE_BBOX(cd->bbox, x, y);
+ if (TRY_COMPACT) {
+ if ((prev->type == cs_vhcurveto && ((prev->num_args / 4) % 2) == 1) ||
+ (prev->type == cs_hvcurveto && ((prev->num_args / 4) % 2) == 0)) {
+ copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
+ prev->num_args += cur->num_args;
+ prev->next = next;
+ RELEASE(cur); cur = NULL;
+ }
+ }
+ break;
+ case cs_flex:
+ for (i = 0; i < 6; i++) {
+ x += cur->args[2*i]; y += cur->args[2*1+1];
+ UPDATE_BBOX(cd->bbox, x, y);
+ }
+ if (cur->args[12] == 50.0) {
+ if (cur->args[1] == 0.0 && cur->args[11] == 0.0 &&
+ cur->args[5] == 0.0 && cur->args[7] == 0.0 &&
+ cur->args[3] + cur->args[9] == 0.0) {
+ /* cur->args[0] = cur->args[0]; dx1 */
+ cur->args[1] = cur->args[2]; /* dx2 */
+ cur->args[2] = cur->args[3]; /* dy2 */
+ cur->args[3] = cur->args[4]; /* dx3 */
+ cur->args[4] = cur->args[6]; /* dx4 */
+ cur->args[5] = cur->args[8]; /* dx5 */
+ cur->args[6] = cur->args[10]; /* dx6 */
+ cur->num_args = 7;
+ cur->type = cs_hflex;
+ } else if (cur->args[5] == 0.0 && cur->args[7] == 0.0 &&
+ (cur->args[1] + cur->args[3] +
+ cur->args[9] + cur->args[11]) == 0) {
+ /* cur->args[0] = cur->args[0]; dx1 */
+ /* cur->args[1] = cur->args[1]; dy1 */
+ /* cur->args[2] = cur->args[2]; dx2 */
+ /* cur->args[3] = cur->args[3]; dy2 */
+ /* cur->args[4] = cur->args[4]; dx3 */
+ cur->args[5] = cur->args[6]; /* dx4 */
+ cur->args[6] = cur->args[8]; /* dx5 */
+ cur->args[7] = cur->args[9]; /* dy5 */
+ cur->args[8] = cur->args[10]; /* dx6 */
+ cur->num_args = 9;
+ cur->type = cs_hflex1;
+ }
+ }
+ break;
+ case CS_HINT_DECL:
+ case cs_cntrmask:
+ /* noop */
+ break;
+ default:
+ ERROR("Unexpected Type 2 charstring command %d.", cur->type);
+ break;
+ }
+ if (cur != NULL)
+ prev = cur;
+ cur = next;
+ }
+
+ /* Had no path. Fix lower-left point. */
+ if (cd->bbox.llx > cd->bbox.urx)
+ cd->bbox.llx = cd->bbox.urx = cd->sbw.wx;
+ if (cd->bbox.lly > cd->bbox.ury)
+ cd->bbox.lly = cd->bbox.ury = cd->sbw.wy;
+
+ return;
+}
+
+#define RESET_STATE() do {\
+ status = CS_PARSE_OK;\
+ phase = T1_CS_PHASE_INIT;\
+ nest = 0;\
+ ps_stack_top = 0;\
+} while (0)
+
+int
+t1char_get_metrics (card8 *src, int srclen, cff_index *subrs, t1_ginfo *ginfo)
+{
+ t1_chardesc t1char, *cd;
+
+ cd = &t1char;
+ init_charpath(cd);
+ RESET_STATE();
+ CLEARSTACK();
+ t1char_build_charpath(cd, &src, src+srclen, subrs);
+ if (cs_stack_top != 0 || ps_stack_top != 0)
+ WARN("Stack not empty. (%d, %d)", cs_stack_top, ps_stack_top);
+ do_postproc(cd);
+ if (ginfo) {
+ ginfo->wx = cd->sbw.wx;
+ ginfo->wy = cd->sbw.wy;
+ ginfo->bbox.llx = cd->bbox.llx;
+ ginfo->bbox.lly = cd->bbox.lly;
+ ginfo->bbox.urx = cd->bbox.urx;
+ ginfo->bbox.ury = cd->bbox.ury;
+ if (cd->flags & T1_CS_FLAG_USE_SEAC) {
+ ginfo->use_seac = 1;
+ ginfo->seac.adx = cd->seac.adx;
+ ginfo->seac.ady = cd->seac.ady;
+ ginfo->seac.bchar = cd->seac.bchar;
+ ginfo->seac.achar = cd->seac.achar;
+ } else {
+ ginfo->use_seac = 0;
+ }
+ }
+ release_charpath(cd);
+
+ return 0;
+}
+
+#define CHECK_BUFFER(n) if (dst+(n) >= endptr) {\
+ ERROR("Buffer overflow.");\
+}
+#define CHECK_STATUS() if (status != CS_PARSE_OK) {\
+ ERROR("Charstring encoder error: %d", status);\
+}
+
+/*
+ * Encode Charpath as a Type 2 Charstring
+ */
+static int
+t1char_encode_charpath (t1_chardesc *cd,
+ double default_width, double nominal_width,
+ card8 *dst, card8 *endptr)
+{
+ card8 *save;
+ t1_cpath *curr;
+
+ ASSERT(cd);
+
+ save = dst;
+ curr = cd->charpath;
+
+ RESET_STATE();
+ CLEARSTACK();
+ /*
+ * Advance Width
+ */
+ if (cd->sbw.wx != default_width) {
+ double wx = cd->sbw.wx - nominal_width;
+ put_numbers(&wx, 1, &dst, endptr);
+ CHECK_STATUS();
+ }
+ /*
+ * Hint Declaration
+ */
+ {
+ int num_hstems = 0, num_vstems = 0;
+ int i, reset = 1;
+ double stem[2];
+
+ for (i = 0; i < cd->num_stems && cd->stems[i].dir == HSTEM; i++) {
+ num_hstems++;
+ stem[0] = (reset ?
+ (cd->stems[i].pos) :
+ (cd->stems[i].pos - (cd->stems[i-1].pos + cd->stems[i-1].del)));
+ stem[1] = cd->stems[i].del;
+ put_numbers(stem, 2, &dst, endptr);
+ CHECK_STATUS();
+ reset = 0;
+ if (2*num_hstems > CS_ARG_STACK_MAX - 3) {
+ CHECK_BUFFER(1);
+ *dst++ = (card8) ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ? cs_hstemhm : cs_hstem);
+ reset = 1;
+ }
+ }
+ if (reset == 0) {
+ CHECK_BUFFER(1);
+ *dst++ = (card8) ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ? cs_hstemhm : cs_hstem);
+ }
+ reset = 1;
+ if (cd->num_stems - num_hstems > 0) {
+ for (i = num_hstems; i < cd->num_stems; i++) {
+ num_vstems++;
+ stem[0] = (reset ?
+ (cd->stems[i].pos) :
+ (cd->stems[i].pos - (cd->stems[i-1].pos + cd->stems[i-1].del)));
+ stem[1] = cd->stems[i].del;
+ put_numbers(stem, 2, &dst, endptr);
+ CHECK_STATUS();
+ reset = 0;
+ if (2*num_vstems > CS_ARG_STACK_MAX - 3) {
+ CHECK_BUFFER(1);
+ *dst++ = (card8) ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ? cs_vstemhm : cs_vstem);
+ reset = 1;
+ }
+ }
+ if (reset == 0) {
+ CHECK_BUFFER(1);
+ if ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ||
+ (cd->flags & T1_CS_FLAG_USE_CNTRMASK)) {
+ /*
+ * The vstem hint operator can be ommited if hstem and vstem hints
+ * are both declared at the beginning of a charstring, and is
+ * followed directly by the hintmask or cntrmask operators.
+ */
+ if (curr->type != CS_HINT_DECL &&
+ curr->type != cs_cntrmask) {
+ *dst++ = (card8) cs_vstemhm;
+ }
+ } else {
+ *dst++ = (card8) cs_vstem;
+ }
+ }
+ }
+ }
+ /*
+ * Path Construction and Hint Replacement
+ */
+ while (curr != NULL && curr->type != cs_endchar) {
+ switch (curr->type) {
+ case CS_HINT_DECL:
+ {
+ card8 hintmask[(CS_STEM_ZONE_MAX+7)/8];
+
+ memset(hintmask, 0, (cd->num_stems+7)/8);
+ while (curr != NULL && curr->type == CS_HINT_DECL) {
+ int stem_idx;
+
+ stem_idx = get_stem(cd, (int) curr->args[0]);
+ ASSERT(stem_idx < cd->num_stems);
+ hintmask[stem_idx/8] |= (1 << (7 - (stem_idx % 8)));
+ curr = curr->next;
+ }
+ if (cd->flags & T1_CS_FLAG_USE_HINTMASK) {
+ CHECK_BUFFER((cd->num_stems+7)/8 + 1);
+ *dst++ = (card8) cs_hintmask;
+ memcpy(dst, hintmask, (cd->num_stems+7)/8);
+ dst += (cd->num_stems+7)/8;
+ }
+ }
+ break;
+ case cs_cntrmask:
+ {
+ card8 cntrmask[(CS_STEM_ZONE_MAX+7)/8];
+ int stem_idx, i;
+
+ memset(cntrmask, 0, (cd->num_stems+7)/8);
+ for (i = 0; i < curr->num_args; i++) {
+ stem_idx = get_stem(cd, (int) curr->args[i]);
+ ASSERT(stem_idx < cd->num_stems);
+ cntrmask[stem_idx/8] |= (1 << (7 - (stem_idx % 8)));
+ }
+ CHECK_BUFFER((cd->num_stems+7)/8 + 1);
+ *dst++ = (card8) cs_cntrmask;
+ memcpy(dst, cntrmask, (cd->num_stems+7)/8);
+ dst += (cd->num_stems+7)/8;
+ curr = curr->next;
+ }
+ break;
+ case cs_rmoveto: case cs_hmoveto: case cs_vmoveto:
+ case cs_rlineto: case cs_hlineto: case cs_vlineto:
+ case cs_rrcurveto: case cs_hvcurveto: case cs_vhcurveto:
+ case cs_rlinecurve: case cs_rcurveline:
+ {
+ put_numbers(curr->args, curr->num_args, &dst, endptr);
+ CHECK_STATUS();
+ CHECK_BUFFER(1);
+ *dst++ = (card8) curr->type;
+ curr = curr->next;
+ }
+ break;
+ case cs_flex: case cs_hflex:
+ case cs_hflex1:
+ {
+ put_numbers(curr->args, curr->num_args, &dst, endptr);
+ CHECK_STATUS();
+ CHECK_BUFFER(2);
+ *dst++ = (card8) cs_escape;
+ *dst++ = (card8) curr->type;
+ curr = curr->next;
+ }
+ break;
+ default:
+ ERROR("Unknown Type 2 charstring command: %d", curr->type);
+ break;
+ }
+ }
+
+ /*
+ * (adx ady bchar achar) endchar
+ */
+ if (cd->flags & T1_CS_FLAG_USE_SEAC) {
+ double seac[4];
+ seac[0] = cd->seac.adx;
+ seac[1] = cd->seac.ady;
+ seac[2] = cd->seac.bchar;
+ seac[3] = cd->seac.achar;
+ put_numbers(seac, 4, &dst, endptr);
+ CHECK_STATUS();
+ CHECK_BUFFER(2);
+ WARN("Obsolete four arguments of \"endchar\" will be used for Type 1 \"seac\" operator.");
+ }
+ CHECK_BUFFER(1);
+ *dst++ = (card8) cs_endchar;
+
+ return (int) (dst - save);
+}
+
+int
+t1char_convert_charstring (card8 *dst, int dstlen,
+ card8 *src, int srclen, cff_index *subrs,
+ double default_width, double nominal_width,
+ t1_ginfo *ginfo)
+{
+ int length;
+ t1_chardesc t1char, *cd;
+
+ cd = &t1char;
+ init_charpath(cd);
+ RESET_STATE();
+ CLEARSTACK();
+ t1char_build_charpath(cd, &src, src+srclen, subrs);
+ if (cs_stack_top != 0 || ps_stack_top != 0)
+ WARN("Stack not empty. (%d, %d)", cs_stack_top, ps_stack_top);
+ do_postproc(cd);
+ SORT_STEMS(cd);
+
+ length = t1char_encode_charpath(cd, default_width, nominal_width, dst, dst+dstlen);
+
+ if (ginfo) {
+ ginfo->wx = cd->sbw.wx;
+ ginfo->wy = cd->sbw.wy;
+ ginfo->bbox.llx = cd->bbox.llx;
+ ginfo->bbox.lly = cd->bbox.lly;
+ ginfo->bbox.urx = cd->bbox.urx;
+ ginfo->bbox.ury = cd->bbox.ury;
+ if (cd->flags & T1_CS_FLAG_USE_SEAC) {
+ ginfo->use_seac = 1;
+ ginfo->seac.adx = cd->seac.adx;
+ ginfo->seac.ady = cd->seac.ady;
+ ginfo->seac.bchar = cd->seac.bchar;
+ ginfo->seac.achar = cd->seac.achar;
+ } else {
+ ginfo->use_seac = 0;
+ }
+ }
+ release_charpath(cd);
+
+ return length;
+}
diff --git a/Build/source/texk/dvipdfm-x/t1_char.h b/Build/source/texk/dvipdfm-x/t1_char.h
new file mode 100644
index 00000000000..74b2bfdd33f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/t1_char.h
@@ -0,0 +1,26 @@
+#ifndef _T1_CSTR_H_
+#define _T1_CSTR_H_
+
+#include "cff_types.h"
+
+typedef struct {
+ int use_seac;
+ double wx, wy;
+ struct {
+ double llx, lly, urx, ury;
+ } bbox;
+ struct {
+ double asb, adx, ady;
+ card8 bchar, achar;
+ } seac;
+} t1_ginfo;
+
+extern int t1char_get_metrics (card8 *src, int srclen,
+ cff_index *subrs, t1_ginfo *ginfo);
+extern int t1char_convert_charstring (card8 *dst, int dstlen,
+ card8 *src, int srclen,
+ cff_index *subrs,
+ double default_width, double nominal_width,
+ t1_ginfo *ginfo);
+
+#endif /* _T1_CSTR_H_ */
diff --git a/Build/source/texk/dvipdfm-x/t1_load.c b/Build/source/texk/dvipdfm-x/t1_load.c
new file mode 100644
index 00000000000..2a72f806614
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/t1_load.c
@@ -0,0 +1,1323 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <math.h>
+
+#include "system.h"
+#include "mfileio.h"
+#include "mem.h"
+#include "error.h"
+#include "numbers.h"
+
+#include "pdfobj.h"
+#include "pdffont.h"
+
+#include "pdfencoding.h"
+#include "unicode.h"
+
+#include "dpxutil.h"
+
+#include "pst_obj.h"
+#include "pst.h"
+
+#include "cff_limits.h"
+#include "cff_types.h"
+#include "cff_dict.h"
+#include "cff.h"
+
+#include "t1_load.h"
+
+/* Migrated from t1crypt */
+#define T1_EEKEY 55665u
+#define T1_CHARKEY 4330u
+
+#if 0
+/* We no longer need encryption. */
+static unsigned short r = T1_EEKEY, c1 = 52845, c2 = 22719;
+
+static unsigned char t1_encrypt (unsigned char plain)
+{
+ unsigned char cipher;
+ cipher = (plain ^ (r >> 8));
+ r = (cipher + r) * c1 + c2;
+ return cipher;
+}
+
+static void t1_crypt_init (unsigned short key)
+{
+ r = key;
+}
+#endif /* 0 */
+
+static void
+t1_decrypt (unsigned short key,
+ unsigned char *dst, const unsigned char *src,
+ int skip, int len)
+{
+ len -= skip;
+ while (skip--)
+ key = (key + *src++) * 52845u + 22719u;
+ while (len--) {
+ unsigned char c = *src++;
+ *dst++ = (c ^ (key >> 8));
+ key = (key + c) * 52845u + 22719u;
+ }
+}
+/* T1CRYPT */
+
+#define MATCH_NAME(t,n) (PST_NAMETYPE((t)) && (pst_length_of((t)) == strlen((n))) && !memcmp(pst_data_ptr((t)),(n),strlen((n))))
+#define MATCH_OP(t,n) (PST_UNKNOWNTYPE((t)) && (pst_length_of((t)) == strlen((n))) && !memcmp(pst_data_ptr((t)),(n),strlen((n))))
+
+#define RELEASE_TOK(t) if ((t) != NULL) {\
+ pst_release_obj((t));\
+ (t) = NULL;\
+}
+
+static char *
+get_next_key (unsigned char **start, unsigned char *end)
+{
+ char *key = NULL;
+ pst_obj *tok;
+
+ while (*start < end &&
+ (tok = pst_get_token(start, end)) != NULL) {
+ if (PST_NAMETYPE(tok)) {
+ key = (char *) pst_getSV(tok);
+ RELEASE_TOK(tok);
+ break;
+ }
+ RELEASE_TOK(tok);
+ }
+
+ return key;
+}
+
+static int
+seek_operator (unsigned char **start, unsigned char *end, const char *op)
+{
+ pst_obj *tok = NULL;
+
+ while (*start < end &&
+ (tok = pst_get_token(start, end)) != NULL) {
+ if (MATCH_OP(tok, op)) {
+ break;
+ }
+ RELEASE_TOK(tok);
+ }
+
+ if (tok == NULL)
+ return -1;
+ RELEASE_TOK(tok);
+
+ return 0;
+}
+
+
+static int
+parse_svalue (unsigned char **start, unsigned char *end, char **value)
+{
+ pst_obj *tok;
+
+ tok = pst_get_token(start, end);
+ if (tok == NULL)
+ return -1;
+ else if (PST_NAMETYPE(tok) || PST_STRINGTYPE(tok))
+ *value = (char *) pst_getSV(tok);
+ else {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ return 1;
+}
+
+static int
+parse_bvalue (unsigned char **start, unsigned char *end, double *value)
+{
+ pst_obj *tok;
+
+ tok = pst_get_token(start, end);
+ if (tok == NULL)
+ return -1;
+ else if (PST_BOOLEANTYPE(tok))
+ *value = (double) pst_getIV(tok);
+ else {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ return 1;
+}
+
+static int
+parse_nvalue (unsigned char **start, unsigned char *end, double *value, int max)
+{
+ int argn = 0;
+ pst_obj *tok;
+
+ tok = pst_get_token(start, end);
+ if (tok == NULL)
+ return -1;
+ /*
+ * All array elements must be numeric token. (ATM compatible)
+ */
+ if (PST_NUMBERTYPE(tok) && max > 0) {
+ value[0] = (double) pst_getRV(tok);
+ argn = 1;
+ } else if (PST_MARKTYPE(tok)) {
+ /* It does not distinguish '[' and '{'... */
+ RELEASE_TOK(tok);
+ while (*start < end &&
+ (tok = pst_get_token(start, end)) != NULL &&
+ PST_NUMBERTYPE(tok) && argn < max) {
+ value[argn++] = (double) pst_getRV(tok);
+ RELEASE_TOK(tok);
+ }
+ if (tok == NULL)
+ return -1;
+ if (!MATCH_OP(tok, "]") && !MATCH_OP(tok, "}")) {
+ argn = -1;
+ }
+ }
+ RELEASE_TOK(tok);
+
+ return argn;
+}
+
+static const char *const StandardEncoding[256] = {
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", "space", "exclam", "quotedbl",
+ "numbersign", "dollar", "percent", "ampersand", "quoteright",
+ "parenleft", "parenright", "asterisk", "plus", "comma",
+ "hyphen", "period", "slash", "zero", "one",
+ "two", "three", "four", "five", "six",
+ "seven", "eight", "nine", "colon", "semicolon",
+ "less", "equal", "greater", "question", "at",
+ "A", "B", "C", "D", "E",
+ "F", "G", "H", "I", "J",
+ "K", "L", "M", "N", "O",
+ "P", "Q", "R", "S", "T",
+ "U", "V", "W", "X", "Y",
+ "Z", "bracketleft", "backslash", "bracketright", "asciicircum",
+ "underscore", "quoteleft", "a", "b", "c",
+ "d", "e", "f", "g", "h",
+ "i", "j", "k", "l", "m",
+ "n", "o", "p", "q", "r",
+ "s", "t", "u", "v", "w",
+ "x", "y", "z", "braceleft", "bar",
+ "braceright", "asciitilde", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", "exclamdown", "cent", "sterling", "fraction",
+ "yen", "florin", "section", "currency", "quotesingle",
+ "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi",
+ "fl", ".notdef", "endash", "dagger", "daggerdbl",
+ "periodcentered", ".notdef", "paragraph", "bullet", "quotesinglbase",
+ "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand",
+ ".notdef", "questiondown", ".notdef", "grave", "acute",
+ "circumflex", "tilde", "macron", "breve", "dotaccent",
+ "dieresis", ".notdef", "ring", "cedilla", ".notdef",
+ "hungarumlaut", "ogonek", "caron", "emdash", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ "AE", ".notdef", "ordfeminine", ".notdef", ".notdef",
+ ".notdef", ".notdef", "Lslash", "Oslash", "OE",
+ "ordmasculine", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", "ae", ".notdef", ".notdef", ".notdef",
+ "dotlessi", ".notdef", ".notdef", "lslash", "oslash",
+ "oe", "germandbls", ".notdef", ".notdef", ".notdef",
+ ".notdef"
+};
+
+static const char *const ISOLatin1Encoding[256] = {
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", "space", "exclam", "quotedbl",
+ "numbersign", "dollar", "percent", "ampersand", "quotesingle",
+ "parenleft", "parenright", "asterisk", "plus", "comma",
+ "hyphen", "period", "slash", "zero", "one",
+ "two", "three", "four", "five", "six",
+ "seven", "eight", "nine", "colon", "semicolon",
+ "less", "equal", "greater", "question", "at",
+ "A", "B", "C", "D", "E",
+ "F", "G", "H", "I", "J",
+ "K", "L", "M", "N", "O",
+ "P", "Q", "R", "S", "T",
+ "U", "V", "W", "X", "Y",
+ "Z", "bracketleft", "backslash", "bracketright", "asciicircum",
+ "underscore", "grave", "a", "b", "c",
+ "d", "e", "f", "g", "h",
+ "i", "j", "k", "l", "m",
+ "n", "o", "p", "q", "r",
+ "s", "t", "u", "v", "w",
+ "x", "y", "z", "braceleft", "bar",
+ "braceright", "asciitilde", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
+ ".notdef", ".notdef", ".notdef", ".notdef", "dotlessi",
+ "quoteleft", "quoteright", "circumflex", "tilde", "macron",
+ "breve", "dotaccent", "dieresis", ".notdef", "ring",
+ "cedilla", ".notdef", "hungarumlaut", "ogonek", "caron",
+ "space", "exclamdown", "cent", "sterling", "currency",
+ "yen", "brokenbar", "section", "dieresis", "copyright",
+ "ordfeminine", "guillemotleft", "logicalnot", "hyphen",
+ "registered",
+ "macron", "degree", "plusminus", "twosuperior", "threesuperior",
+ "acute", "mu", "paragraph", "periodcentered", "cedilla",
+ "onesuperior", "ordmasculine", "guillemotright", "onequarter",
+ "onehalf",
+ "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex",
+ "Atilde", "Adieresis", "Aring", "AE", "Ccedilla",
+ "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave",
+ "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde",
+ "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis",
+ "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex",
+ "Udieresis", "Yacute", "Thorn", "germandbls", "agrave",
+ "aacute", "acircumflex", "atilde", "adieresis", "aring",
+ "ae", "ccedilla", "egrave", "eacute", "ecircumflex",
+ "edieresis", "igrave", "iacute", "icircumflex", "idieresis",
+ "eth", "ntilde", "ograve", "oacute", "ocircumflex",
+ "otilde", "odieresis", "divide", "oslash", "ugrave",
+ "uacute", "ucircumflex", "udieresis", "yacute", "thorn",
+ "ydieresis"
+};
+
+/* Treat cases such as "dup num num getinterval num exch putinterval"
+ * or "dup num exch num get put"
+ */
+static int
+try_put_or_putinterval (char **enc_vec, unsigned char **start, unsigned char *end)
+{
+ pst_obj *tok;
+ int i, num1, num2, num3;
+
+ tok = pst_get_token(start, end);
+ if (!tok || !PST_INTEGERTYPE(tok) ||
+ (num1 = pst_getIV(tok)) > 255 || num1 < 0) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!tok) {
+ return -1;
+ } else if (MATCH_OP(tok, "exch")) {
+ /* dup num exch num get put */
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!tok || !PST_INTEGERTYPE(tok) ||
+ (num2 = pst_getIV(tok)) > 255 || num2 < 0) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "get")) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "put")) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ if (enc_vec[num1])
+ RELEASE(enc_vec[num1]);
+ enc_vec[num1] = xstrdup(enc_vec[num2]);
+ } else if (PST_INTEGERTYPE(tok) &&
+ (num2 = pst_getIV(tok)) + num1 <= 255 && num2 >= 0) {
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "getinterval")) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!tok || !PST_INTEGERTYPE(tok) ||
+ (num3 = pst_getIV(tok)) + num2 > 255 || num3 < 0) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "exch")) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "putinterval")) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ for (i = 0; i < num2; i++) {
+ if (enc_vec[num1 + i]) { /* num1 + i < 256 here */
+ if (enc_vec[num3 + i]) { /* num3 + i < 256 here */
+ RELEASE(enc_vec[num3 + i]);
+ enc_vec[num3+i] = NULL;
+ }
+ enc_vec[num3 + i] = xstrdup(enc_vec[num1 + i]);
+ }
+ }
+ } else {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+parse_encoding (char **enc_vec, unsigned char **start, unsigned char *end)
+{
+ pst_obj *tok;
+ int code;
+
+ /*
+ * StandardEncoding def
+ * or
+ * ISOLatin1Encoding def
+ * or
+ * 0 1 255 {1 index exch /.notdef put } for
+ * dup int name put
+ * ...
+ * [readonly] def
+ */
+ tok = pst_get_token(start, end);
+ if (MATCH_OP(tok, "StandardEncoding")) {
+ RELEASE_TOK(tok);
+ if (enc_vec) {
+ for (code = 0; code < 256; code++) {
+ if (StandardEncoding[code] &&
+ strcmp(StandardEncoding[code], ".notdef") != 0) {
+ enc_vec[code] = NEW(strlen(StandardEncoding[code])+1, char);
+ strcpy(enc_vec[code], StandardEncoding[code]);
+ } else {
+ enc_vec[code] = NULL;
+ }
+ }
+ }
+ } else if (MATCH_OP(tok, "ISOLatin1Encoding")) {
+ RELEASE_TOK(tok);
+ if (enc_vec) {
+ for (code = 0; code < 256; code++) {
+ if (ISOLatin1Encoding[code] &&
+ strcmp(ISOLatin1Encoding[code], ".notdef") != 0) {
+ enc_vec[code] = NEW(strlen(ISOLatin1Encoding[code])+1, char);
+ strcpy(enc_vec[code], ISOLatin1Encoding[code]);
+ } else {
+ enc_vec[code] = NULL;
+ }
+ }
+ }
+ } else if (MATCH_OP(tok, "ExpertEncoding")) {
+ RELEASE_TOK(tok);
+ if (enc_vec) {
+ WARN("ExpertEncoding not supported.");
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ /*
+ * Not supported yet.
+ */
+ } else {
+ RELEASE_TOK(tok);
+ seek_operator(start, end, "array");
+ /*
+ * Pick all seaquences that matches "dup n /Name put" until
+ * occurrence of "def" or "readonly".
+ */
+ while (*start < end &&
+ (tok = pst_get_token(start, end)) != NULL) {
+ if (MATCH_OP(tok, "def") || MATCH_OP(tok, "readonly")) {
+ RELEASE_TOK(tok);
+ break;
+ } else if (!MATCH_OP(tok, "dup")) {
+ RELEASE_TOK(tok);
+ continue;
+ }
+ RELEASE_TOK(tok);
+
+ /* cmctt10.pfb for examples contains the following PS code
+ * dup num num getinterval num exch putinterval
+ * dup num exch num get put
+ */
+ tok = pst_get_token(start, end);
+ if (MATCH_OP(tok, "dup")) { /* possibly putinterval type */
+ if (enc_vec == NULL) {
+ WARN ("This kind of type1 fonts are not supported as native fonts.\n"
+ " They are supported if used with tfm fonts.\n");
+ } else {
+ try_put_or_putinterval(enc_vec, start, end);
+ }
+ RELEASE_TOK(tok)
+ continue;
+ } else if (!tok || !PST_INTEGERTYPE(tok) ||
+ (code = pst_getIV(tok)) > 255 || code < 0) {
+ RELEASE_TOK(tok);
+ continue;
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!tok || !PST_NAMETYPE(tok)) {
+ RELEASE_TOK(tok);
+ continue;
+ }
+ if (enc_vec) {
+ if (enc_vec[code])
+ RELEASE(enc_vec[code]);
+ enc_vec[code] = (char *) pst_getSV(tok);
+ }
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "put")) {
+ if (enc_vec[code]) {
+ RELEASE(enc_vec[code]);
+ enc_vec[code] = NULL;
+ }
+ RELEASE_TOK(tok);
+ continue;
+ }
+ RELEASE_TOK(tok);
+ }
+ }
+
+ return 0;
+}
+
+#ifndef CS_STR_LEN_MAX
+#define CS_STR_LEN_MAX 65536UL
+#endif
+#ifndef CFF_GLYPH_MAX
+#define CFF_GLYPH_MAX CFF_SID_MAX
+#endif
+
+static int
+parse_subrs (cff_font *font,
+ unsigned char **start, unsigned char *end, int lenIV, int mode)
+{
+ cff_index *subrs;
+ pst_obj *tok;
+ int i, count, offset, max_size;
+ int *offsets, *lengths;
+ card8 *data;
+
+ tok = pst_get_token(start, end);
+ if (!PST_INTEGERTYPE(tok) || pst_getIV(tok) < 0) {
+ WARN("Parsing Subrs failed.");
+ RELEASE_TOK(tok);
+ return -1;
+ }
+
+ count = pst_getIV(tok);
+ RELEASE_TOK(tok);
+
+ if (count == 0) {
+ font->subrs[0] = NULL;
+ return 0;
+ }
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "array")) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ if (mode != 1) {
+ max_size = CS_STR_LEN_MAX;
+ data = NEW(max_size, card8);
+ offsets = NEW(count, int);
+ lengths = NEW(count, int);
+ memset(offsets, 0, sizeof(int)*count);
+ memset(lengths, 0, sizeof(int)*count);
+ } else {
+ max_size = 0;
+ data = NULL;
+ offsets = NULL;
+ lengths = NULL;
+ }
+
+ offset = 0;
+ /* dup subr# n-bytes RD n-binary-bytes NP */
+ for (i = 0; i < count;) {
+ int idx, len;
+
+ tok = pst_get_token(start, end);
+ if (!tok) {
+ if (data) RELEASE(data);
+ if (offsets) RELEASE(offsets);
+ if (lengths) RELEASE(lengths);
+ return -1;
+ } else if (MATCH_OP(tok, "ND") ||
+ MATCH_OP(tok, "|-") || MATCH_OP(tok, "def")) {
+ RELEASE_TOK(tok);
+ break;
+ } else if (!MATCH_OP(tok, "dup")) {
+ RELEASE_TOK(tok);
+ continue;
+ }
+ RELEASE_TOK(tok);
+
+ /* Found "dup" */
+ tok = pst_get_token(start, end);
+ if (!PST_INTEGERTYPE(tok) || pst_getIV(tok) < 0 ||
+ pst_getIV(tok) >= count) {
+ RELEASE_TOK(tok);
+ if (data) RELEASE(data);
+ if (offsets) RELEASE(offsets);
+ if (lengths) RELEASE(lengths);
+ return -1;
+ }
+ idx = pst_getIV(tok);
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!PST_INTEGERTYPE(tok) || pst_getIV(tok) < 0 ||
+ pst_getIV(tok) > CS_STR_LEN_MAX) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ len = pst_getIV(tok);
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "RD") && !MATCH_OP(tok, "-|") &&
+ seek_operator(start, end, "readstring") < 0) {
+ RELEASE_TOK(tok);
+ if (data) RELEASE(data);
+ if (offsets) RELEASE(offsets);
+ if (lengths) RELEASE(lengths);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ *start += 1;
+ if (*start + len >= end) {
+ if (data) RELEASE(data);
+ if (offsets) RELEASE(offsets);
+ if (lengths) RELEASE(lengths);
+ return -1;
+ }
+ if (mode != 1) {
+ if (offset + len >= max_size) {
+ max_size += CS_STR_LEN_MAX;
+ data = RENEW(data, max_size, card8);
+ }
+ if (lenIV >= 0) {
+ t1_decrypt(T1_CHARKEY, data+offset, *start, lenIV, len);
+ offsets[idx] = offset;
+ offset += (lengths[idx] = len - lenIV);
+ } else if (len > 0) {
+ offsets[idx] = offset;
+ lengths[idx] = len;
+ memcpy(&data[offset], *start, len);
+ offset += len;
+ }
+ }
+ *start += len;
+ i++;
+ }
+
+ if (mode != 1) {
+ if (font->subrs[0] == NULL) {
+ subrs = font->subrs[0] = cff_new_index(count);
+ subrs->data = NEW(offset, card8);
+ offset = 0;
+ for (i = 0; i < count; i++) {
+ subrs->offset[i] = offset + 1;
+ if (lengths[i] > 0) {
+ memcpy(subrs->data + offset, data + offsets[i], lengths[i]);
+ offset += lengths[i];
+ }
+ }
+ subrs->offset[count] = offset + 1;
+ } else {
+ /* Adobe's OPO_____.PFB and OPBO____.PFB have two /Subrs dicts,
+ * and also have /CharStrings not followed by dicts.
+ * Simply ignores those data. By ChoF on 2009/04/08. */
+ WARN("Already found /Subrs; ignores the other /Subrs dicts.");
+ }
+ RELEASE(data);
+ RELEASE(offsets);
+ RELEASE(lengths);
+ }
+
+ return 0;
+}
+
+static int
+parse_charstrings (cff_font *font,
+ unsigned char **start, unsigned char *end, int lenIV, int mode)
+{
+ cff_index *charstrings;
+ cff_charsets *charset;
+ pst_obj *tok;
+ int i, count, have_notdef;
+ int max_size, offset;
+
+ /* /CharStrings n dict dup begin
+ * /GlyphName n-bytes RD -n-binary-bytes- ND
+ * ...
+ * end
+ * - stack - ... /CharStrings dict
+ */
+ tok = pst_get_token(start, end);
+ if (!PST_INTEGERTYPE(tok) ||
+ pst_getIV(tok) < 0 || pst_getIV(tok) > CFF_GLYPH_MAX) {
+ unsigned char *s = pst_getSV(tok);
+ WARN("Ignores non dict \"/CharStrings %s ...\"", s);
+ RELEASE(s);
+ RELEASE_TOK(tok);
+ return 0;
+ }
+ count = pst_getIV(tok);
+ RELEASE_TOK(tok);
+
+ if (mode != 1) {
+ charstrings = cff_new_index(count);
+ max_size = CS_STR_LEN_MAX;
+ charstrings->data = NEW(max_size, card8);
+ } else {
+ charstrings = NULL;
+ max_size = 0;
+ }
+ font->cstrings = charstrings;
+
+ charset = font->charsets = NEW(1, cff_charsets);
+ charset->format = 0;
+ charset->num_entries = count-1;
+ charset->data.glyphs = NEW(count-1, s_SID);
+ memset(charset->data.glyphs, 0, sizeof(s_SID)*(count-1));
+
+ offset = 0;
+ have_notdef = 0; /* .notdef must be at gid = 0 in CFF */
+
+ font->is_notdef_notzero = 0;
+ seek_operator(start, end, "begin");
+ for (i = 0; i < count; i++) {
+ char *glyph_name;
+ int len, gid, j;
+
+ /* BUG-20061126 (by ChoF):
+ * Some fonts (e.g., belleek/blsy.pfb) does not have the correct number
+ * of glyphs. Modify the codes even to work with these broken fonts.
+ */
+ tok = pst_get_token(start, end);
+ glyph_name = (char *)pst_getSV(tok);
+
+ if ((i == 0) && (glyph_name != NULL) && (strcmp (glyph_name, ".notdef") != 0))
+ font->is_notdef_notzero = 1;
+
+ if (PST_NAMETYPE(tok)) {
+ RELEASE_TOK(tok);
+ if (!glyph_name) {
+ return -1;
+ } else if (!strcmp(glyph_name, ".notdef")) {
+ gid = 0;
+ have_notdef = 1;
+ } else if (have_notdef) {
+ gid = i;
+ } else if (i == count - 1) {
+ WARN("No .notdef glyph???");
+ return -1;
+ } else {
+ gid = i+1;
+ }
+ } else if (PST_UNKNOWNTYPE(tok) && !strcmp(glyph_name, "end")) {
+ RELEASE_TOK(tok);
+ break;
+ } else {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+
+ if (gid > 0)
+ charset->data.glyphs[gid-1] = cff_add_string(font, glyph_name, 0);
+ /*
+ * We don't care about duplicate strings here since
+ * later a subset font of this font will be generated.
+ */
+
+ RELEASE(glyph_name);
+
+ tok = pst_get_token(start, end);
+ if (!PST_INTEGERTYPE(tok) ||
+ pst_getIV(tok) < 0 || pst_getIV(tok) > CS_STR_LEN_MAX) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ len = pst_getIV(tok);
+ RELEASE_TOK(tok);
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "RD") &&
+ !MATCH_OP(tok, "-|") &&
+ seek_operator(start, end, "readstring") < 0) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+
+ if (*start + len + 1 >= end) {
+ return -1;
+ }
+ if (mode != 1) {
+ if (offset + len >= max_size) {
+ max_size += MAX(len, CS_STR_LEN_MAX);
+ charstrings->data = RENEW(charstrings->data, max_size, card8);
+ }
+ if (gid == 0) {
+ if (lenIV >= 0) {
+ memmove(charstrings->data + len - lenIV, charstrings->data, offset);
+ for (j = 1; j <= i; j++) {
+ charstrings->offset[j] += len - lenIV;
+ }
+ } else {
+ memmove(charstrings->data + len, charstrings->data, offset);
+ for (j = 1; j <= i; j++) {
+ charstrings->offset[j] += len;
+ }
+ }
+ }
+ }
+
+ *start += 1;
+ if (mode != 1) {
+ if (lenIV >= 0) {
+ int offs = gid ? offset : 0;
+ charstrings->offset[gid] = offs + 1; /* start at 1 */
+ t1_decrypt(T1_CHARKEY, charstrings->data+offs, *start, lenIV, len);
+ offset += len - lenIV;
+ } else {
+ if (gid == 0) {
+ charstrings->offset[gid] = 1;
+ memcpy(&charstrings->data[0], *start, len);
+ } else {
+ charstrings->offset[gid] = offset + 1;
+ memcpy(&charstrings->data[offset], *start, len);
+ }
+ offset += len;
+ }
+ }
+ *start += len;
+
+ tok = pst_get_token(start, end);
+ if (!MATCH_OP(tok, "ND") && !MATCH_OP(tok, "|-")) {
+ RELEASE_TOK(tok);
+ return -1;
+ }
+ RELEASE_TOK(tok);
+ }
+ if (mode != 1)
+ charstrings->offset[count] = offset + 1;
+ font->num_glyphs = count;
+
+ return 0;
+}
+
+#define CHECK_ARGN_EQ(n) if (argn != (n)) {\
+ WARN("%d values expected but only %d read.", (n), argn);\
+ RELEASE(key);\
+ return -1;\
+}
+#define CHECK_ARGN_GE(n) if (argn < (n)) {\
+ WARN("%d values expected but only %d read.", (n), argn);\
+ RELEASE(key);\
+ return -1;\
+}
+
+#define MAX_ARGS 127
+static int
+parse_part2 (cff_font *font, unsigned char **start, unsigned char *end, int mode)
+{
+ char *key;
+ double argv[MAX_ARGS];
+ int argn, lenIV = 4;
+
+ while (*start < end &&
+ (key = get_next_key(start, end)) != NULL) {
+ if (!strcmp(key, "Subrs")) {
+ /* levIV must appear before Subrs */
+ if (parse_subrs(font, start, end, lenIV, mode) < 0) {
+ RELEASE(key);
+ return -1;
+ }
+ } else if (!strcmp(key, "CharStrings")) {
+ if (parse_charstrings(font, start, end, lenIV, mode) < 0) {
+ RELEASE(key);
+ return -1;
+ }
+ } else if (!strcmp(key, "lenIV")) {
+ argn = parse_nvalue(start, end, argv, 1);
+ CHECK_ARGN_EQ(1);
+ lenIV = (int) argv[0];
+ } else if (!strcmp(key, "BlueValues") ||
+ !strcmp(key, "OtherBlues") ||
+ !strcmp(key, "FamilyBlues") ||
+ !strcmp(key, "FamilyOtherBlues") ||
+ !strcmp(key, "StemSnapH") ||
+ !strcmp(key, "StemSnapV")) {
+ /*
+ * Operand values are delta in CFF font dictionary encoding.
+ */
+ argn = parse_nvalue(start, end, argv, MAX_ARGS);
+ CHECK_ARGN_GE(0);
+ cff_dict_add(font->private[0], key, argn);
+ while (argn-- > 0) {
+ cff_dict_set(font->private[0], key, argn,
+ (argn == 0) ? argv[argn] : argv[argn] - argv[argn-1]);
+ }
+ } else if (!strcmp(key, "StdHW") ||
+ !strcmp(key, "StdVW") ||
+ !strcmp(key, "BlueScale") ||
+ !strcmp(key, "BlueShift") ||
+ !strcmp(key, "BlueFuzz") ||
+ !strcmp(key, "LanguageGroup") ||
+ !strcmp(key, "ExpansionFactor")) {
+ /*
+ * Value of StdHW and StdVW is described as an array in the
+ * Type 1 Font Specification but is a number in CFF format.
+ */
+ argn = parse_nvalue(start, end, argv, 1);
+ CHECK_ARGN_EQ(1);
+ cff_dict_add(font->private[0], key, 1);
+ cff_dict_set(font->private[0], key, 0, argv[0]);
+ } else if (!strcmp(key, "ForceBold")) {
+ argn = parse_bvalue(start, end, &(argv[0]));
+ CHECK_ARGN_EQ(1);
+ if (argv[0] != 0) {
+ cff_dict_add(font->private[0], key, 1);
+ cff_dict_set(font->private[0], key, 0, 1);
+ }
+ }
+ /*
+ * MinFeature, RndStemUp, UniqueID, Password ignored.
+ */
+ RELEASE(key);
+ }
+
+ return 0;
+}
+
+#ifndef TYPE1_NAME_LEN_MAX
+#define TYPE1_NAME_LEN_MAX 127
+#endif
+
+static int
+parse_part1 (cff_font *font, char **enc_vec,
+ unsigned char **start, unsigned char *end)
+{
+ char *key, *strval;
+ double argv[MAX_ARGS];
+ int argn; /* Macro CHECK_ARGN_XX assume 'argn' is used. */
+
+ /*
+ * We skip PostScript code inserted before the beginning of
+ * font dictionary so that parser will not be confused with
+ * it. See LMRoman10-Regular (lmr10.pfb) for example.
+ */
+ if (seek_operator(start, end, "begin") < 0)
+ return -1;
+
+ while (*start < end &&
+ (key = get_next_key(start, end)) != NULL) {
+ if (!strcmp(key, "Encoding")) {
+ if (parse_encoding(enc_vec, start, end) < 0) {
+ RELEASE(key);
+ return -1;
+ }
+ } else if (!strcmp(key, "FontName")) {
+ argn = parse_svalue(start, end, &strval);
+ CHECK_ARGN_EQ(1);
+ if (strlen(strval) > TYPE1_NAME_LEN_MAX) {
+ WARN("FontName too long: %s (%d bytes)", strval, strlen(strval));
+ strval[TYPE1_NAME_LEN_MAX] = '\0';
+ }
+ cff_set_name(font, strval);
+ RELEASE(strval);
+ } else if (!strcmp(key, "FontType")) {
+ argn = parse_nvalue(start, end, argv, 1);
+ CHECK_ARGN_EQ(1);
+ if (argv[0] != 1.0) {
+ WARN("FontType %d not supported.", (int) argv[0]);
+ RELEASE(key);
+ return -1;
+ }
+#if 0
+ /* DISABLED:
+ *
+ * Subsetted font shouldn't have UniqueID.
+ */
+ } else if (!strcmp(key, "UniqueID")) {
+ argn = parse_nvalue(start, end, argv, 1);
+ CHECK_ARGN_EQ(1);
+ cff_dict_add(font->topdict, key, 1);
+ cff_dict_set(font->topdict, key, 0, argv[0]);
+#endif
+ } else if (!strcmp(key, "ItalicAngle") ||
+ !strcmp(key, "StrokeWidth") ||
+ !strcmp(key, "PaintType")) {
+ argn = parse_nvalue(start, end, argv, 1);
+ CHECK_ARGN_EQ(1);
+ if (argv[0] != 0.0) {
+#if 0
+ /*
+ * Positive value in Bitstream CharterBT-Italic ???
+ */
+ if (!strcmp(key, "ItalicAngle") && argv[0] > 0) {
+ WARN("Positive ItalicAngle value: %g", argv[0]);
+ argv[0] *= -1;
+ }
+#endif
+ cff_dict_add(font->topdict, key, 1);
+ cff_dict_set(font->topdict, key, 0, argv[0]);
+ }
+ } else if (!strcmp(key, "UnderLinePosition") ||
+ !strcmp(key, "UnderLineThickness")) {
+ argn = parse_nvalue(start, end, argv, 1);
+ CHECK_ARGN_EQ(1);
+ cff_dict_add(font->topdict, key, 1);
+ cff_dict_set(font->topdict, key, 0, argv[0]);
+ } else if (!strcmp(key, "FontBBox")) {
+ argn = parse_nvalue(start, end, argv, 4);
+ CHECK_ARGN_EQ(4);
+ cff_dict_add(font->topdict, key, 4);
+ while (argn-- > 0) {
+ cff_dict_set(font->topdict, key, argn, argv[argn]);
+ }
+ } else if (!strcmp(key, "FontMatrix")) {
+ argn = parse_nvalue(start, end, argv, 6);
+ CHECK_ARGN_EQ(6);
+ if (argv[0] != 0.001 || argv[1] != 0.0 || argv[2] != 0.0 ||
+ argv[3] != 0.001 || argv[4] != 0.0 || argv[5] != 0.0) {
+ cff_dict_add(font->topdict, key, 6);
+ while (argn-- > 0) {
+ cff_dict_set(font->topdict, key, argn, argv[argn]);
+ }
+ }
+ } else if (!strcmp(key, "version") || !strcmp(key, "Notice") ||
+ !strcmp(key, "FullName") || !strcmp(key, "FamilyName") ||
+ !strcmp(key, "Weight") || !strcmp(key, "Copyright")) {
+ /*
+ * FontInfo
+ */
+ argn = parse_svalue(start, end, &strval);
+ CHECK_ARGN_EQ(1);
+ {
+ s_SID sid;
+
+ cff_dict_add(font->topdict, key, 1);
+ if ((sid = cff_get_sid(font, strval)) == CFF_STRING_NOTDEF)
+ sid = cff_add_string(font, strval, 0); /* FIXME */
+ /*
+ * We don't care about duplicate strings here since
+ * later a subset font of this font will be generated.
+ */
+ cff_dict_set(font->topdict, key, 0, sid);
+ }
+ RELEASE(strval);
+ } else if (!strcmp(key, "IsFixedPitch")) {
+ argn = parse_bvalue(start, end, &(argv[0]));
+ CHECK_ARGN_EQ(1);
+ if (argv[0] != 0.0) {
+ cff_dict_add(font->private[0], key, 1);
+ cff_dict_set(font->private[0], key, 0, 1);
+ }
+ }
+ RELEASE(key);
+ }
+
+ return 0;
+}
+
+int
+is_pfb (FILE *fp)
+{
+ char sig[15];
+ int i, ch;
+
+ rewind(fp);
+ if ((ch = fgetc(fp)) != 128 ||
+ (ch = fgetc (fp)) < 0 || ch > 3) {
+ return 0;
+ }
+ for (i = 0; i < 4; i++) {
+ if ((ch = fgetc(fp)) < 0) {
+ return 0;
+ }
+ }
+ for (i = 0; i < 14; i++) {
+ if ((ch = fgetc(fp)) < 0) {
+ return 0;
+ }
+ sig[i] = (char) ch;
+ }
+ if (!memcmp(sig, "%!PS-AdobeFont", 14) ||
+ !memcmp(sig, "%!FontType1", 11)) {
+ return 1;
+ } else if (!memcmp(sig, "%!PS", 4)) {
+ sig[14] = '\0';
+ WARN("Ambiguous PostScript resource type: %s", sig);
+ return 1;
+ } else {
+ WARN("Not a PFB font file?");
+ return 0;
+ }
+}
+
+
+#define PFB_SEG_TYPE_ASCII 1
+#define PFB_SEG_TYPE_BINARY 2
+
+static unsigned char *
+get_pfb_segment (FILE *fp, int expected_type, int *length)
+{
+ unsigned char *buffer;
+ int bytesread;
+
+ buffer = NULL; bytesread = 0;
+ for (;;) {
+ int ch;
+
+ ch = fgetc(fp);
+ if (ch < 0) {
+ break;
+ } else if (ch != 128) {
+ ERROR("Not a pfb file?");
+ }
+ ch = fgetc(fp);
+ if (ch < 0 || ch != expected_type) {
+ seek_relative(fp, -2);
+ break;
+ }
+ {
+ int slen, rlen;
+ int i;
+
+ slen = 0;
+ for (i = 0; i < 4; i++) {
+ if ((ch = fgetc(fp)) < 0) {
+ if (buffer)
+ RELEASE(buffer);
+ return NULL;
+ }
+ slen = slen + (ch << (8*i));
+ }
+ buffer = RENEW(buffer, bytesread + slen, unsigned char);
+ while (slen > 0) {
+ rlen = fread(buffer + bytesread, sizeof(unsigned char), slen, fp);
+ if (rlen < 0) {
+ if (buffer)
+ RELEASE(buffer);
+ return NULL;
+ }
+ slen -= rlen;
+ bytesread += rlen;
+ }
+ }
+ }
+ if (bytesread == 0) {
+ ERROR("PFB segment length zero?");
+ }
+
+ buffer = RENEW(buffer, bytesread+1, unsigned char);
+ buffer[bytesread] = 0;
+
+ if (length)
+ *length = bytesread;
+ return buffer;
+}
+
+const char *
+t1_get_standard_glyph (int code)
+{
+ if (!StandardEncoding[code])
+ return NULL;
+
+ return StandardEncoding[code];
+}
+
+int
+t1_get_fontname (FILE *fp, char *fontname)
+{
+ unsigned char *buffer, *start, *end;
+ int length;
+ char *key;
+ int fn_found = 0;
+
+ rewind(fp);
+ buffer = get_pfb_segment(fp, PFB_SEG_TYPE_ASCII, &length);
+ if (buffer == NULL || length == 0)
+ ERROR("Reading PFB (ASCII part) file failed.");
+ start = buffer;
+ end = buffer + length;
+
+ if (seek_operator(&start, end, "begin") < 0) {
+ RELEASE(buffer);
+ return -1;
+ }
+
+ while (!fn_found && start < end &&
+ (key = get_next_key(&start, end)) != NULL) {
+ if (!strcmp(key, "FontName")) {
+ char *strval;
+ if (parse_svalue(&start, end, &strval) == 1) {
+ if (strlen(strval) > TYPE1_NAME_LEN_MAX) {
+ WARN("FontName \"%s\" too long. (%d bytes)", strval, strlen(strval));
+ strval[TYPE1_NAME_LEN_MAX] = '\0';
+ }
+ strcpy(fontname, strval);
+ RELEASE(strval);
+ fn_found = 1;
+ }
+ }
+ RELEASE(key);
+ }
+ RELEASE(buffer);
+
+ return 0;
+}
+
+static void
+init_cff_font (cff_font *cff)
+{
+ cff->stream = NULL;
+ cff->filter = 0;
+ cff->fontname = NULL;
+ cff->index = 0;
+ cff->flag = FONTTYPE_FONT;
+
+ cff->header.major = 1;
+ cff->header.minor = 0;
+ cff->header.hdr_size = 4;
+ cff->header.offsize = 4;
+ cff->name = cff_new_index(1);
+ cff->topdict = cff_new_dict();
+ cff->string = NULL;
+ cff->gsubr = cff_new_index(0); /* No Global Subr */
+ cff->encoding = NULL;
+ cff->charsets = NULL;
+ cff->fdselect = NULL;
+ cff->cstrings = NULL;
+ cff->fdarray = NULL;
+ cff->private = NEW(1, cff_dict *);
+ cff->private[0] = cff_new_dict();
+ cff->subrs = NEW(1, cff_index *);
+ cff->subrs[0] = NULL;
+
+ cff->offset = 0;
+ cff->gsubr_offset = 0;
+ cff->num_glyphs = 0;
+ cff->num_fds = 1;
+ cff->_string = cff_new_index(0);
+}
+
+cff_font *
+t1_load_font (char **enc_vec, int mode, FILE *fp)
+{
+ int length;
+ cff_font *cff;
+ unsigned char *buffer, *start, *end;
+
+ rewind(fp);
+ /* ASCII section */
+ buffer = get_pfb_segment(fp, PFB_SEG_TYPE_ASCII, &length);
+ if (buffer == NULL || length == 0) {
+ ERROR("Reading PFB (ASCII part) file failed.");
+ return NULL;
+ }
+
+ cff = NEW(1, cff_font);
+ init_cff_font(cff);
+
+ start = buffer; end = buffer + length;
+ if (parse_part1(cff, enc_vec, &start, end) < 0) {
+ cff_close(cff);
+ RELEASE(buffer);
+ ERROR("Reading PFB (ASCII part) file failed.");
+ return NULL;
+ }
+ RELEASE(buffer);
+
+ /* Binary section */
+ buffer = get_pfb_segment(fp, PFB_SEG_TYPE_BINARY, &length);
+ if (buffer == NULL || length == 0) {
+ cff_close(cff);
+ RELEASE(buffer);
+ ERROR("Reading PFB (BINARY part) file failed.");
+ return NULL;
+ } else {
+ t1_decrypt(T1_EEKEY, buffer, buffer, 0, length);
+ }
+ start = buffer + 4; end = buffer + length;
+ if (parse_part2(cff, &start, end, mode) < 0) {
+ cff_close(cff);
+ RELEASE(buffer);
+ ERROR("Reading PFB (BINARY part) file failed.");
+ return NULL;
+ }
+ RELEASE(buffer);
+
+ cff_update_string(cff);
+
+ /* Remaining section ignored. */
+
+ return cff;
+}
diff --git a/Build/source/texk/dvipdfm-x/t1_load.h b/Build/source/texk/dvipdfm-x/t1_load.h
new file mode 100644
index 00000000000..95683612fbf
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/t1_load.h
@@ -0,0 +1,11 @@
+
+#ifndef _T1_LOAD_H_
+#define _T1_LOAD_H_
+
+#include "cff.h"
+extern cff_font *t1_load_font (char **enc_vec, int mode, FILE *fp);
+extern int is_pfb (FILE *fp);
+extern int t1_get_fontname (FILE *fp, char *fontname);
+extern const char *t1_get_standard_glyph (int code);
+
+#endif /* _T1_LOAD_H_ */
diff --git a/Build/source/texk/dvipdfm-x/tests/Makefile_upjf b/Build/source/texk/dvipdfm-x/tests/Makefile_upjf
new file mode 100644
index 00000000000..d22dda7005c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/Makefile_upjf
@@ -0,0 +1,20 @@
+# Public domain.
+# You may freely use, modify and/or distribute this file.
+
+# test data for uptex virtual fonts
+uptex-vf: upjf_full.vf upjf_omit.vf upjf.dvi
+
+upjf.tfm:
+ cp -p `kpsewhich upjisr-h.tfm` upjf.tfm
+
+upjf_full.vf: upjf.tfm upjf_full.cnf
+ makejvf -i -u custom -e -t upjf_full.cnf -H upjf.tfm -K upjf-g upjf-r
+ mv upjf.vf upjf_full.vf
+
+upjf_omit.vf: upjf.tfm upjf_omit.cnf
+ makejvf -i -u custom -e -t upjf_omit.cnf -H upjf.tfm -K upjf-g upjf-r
+ mv upjf.vf upjf_omit.vf
+
+upjf.dvi: upjf.tex
+ uplatex upjf.tex
+
diff --git a/Build/source/texk/dvipdfm-x/tests/UPJF-UTF16-H b/Build/source/texk/dvipdfm-x/tests/UPJF-UTF16-H
new file mode 100644
index 00000000000..a63768ab58a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/UPJF-UTF16-H
@@ -0,0 +1,71 @@
+%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (UPJF-UTF16-H)
+%%Title: (UPJF-UTF16-H test sample)
+%%Version: 1.000
+%%Copyright: -----------------------------------------------------------
+%%Copyright: Copyright 2017-2020 Japanese TeX Development Community
+%%Copyright:
+%%Copyright: You may freely use, modify and/or distribute this file.
+%%Copyright: -----------------------------------------------------------
+%%EndComments
+
+/CIDInit /ProcSet findresource begin
+
+12 dict begin
+
+begincmap
+
+/CIDSystemInfo 3 dict dup begin
+ /Registry (Adobe) def
+ /Ordering (Japan1) def
+ /Supplement 7 def
+end def
+
+/CMapName /UPJF-UTF16-H def
+/CMapVersion 1.000 def
+/CMapType 1 def
+
+/WMode 0 def
+
+3 begincodespacerange
+ <0000> <D7FF>
+ <D800DC00> <DBFFDFFF>
+ <E000> <FFFF>
+endcodespacerange
+
+1 beginnotdefrange
+<0000> <001f> 1
+endnotdefrange
+
+3 begincidchar
+<6674> 2646
+<96ea> 2695
+<d842df9f> 13803
+endcidchar
+
+14 begincidrange
+<2600> <2603> 8215
+<3000> <3002> 633
+<3005> <3007> 657
+<3008> <3011> 682
+<3014> <3015> 676
+<3016> <3017> 16197
+<3018> <3019> 12129
+<3033> <3035> 12108
+<3041> <3093> 842
+<3094> <3096> 7958
+<3099> <309a> 16326
+<309b> <309c> 643
+<309d> <309e> 653
+<ff61> <ff9f> 327
+endcidrange
+
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+
+%%EndResource
+%%EOF
diff --git a/Build/source/texk/dvipdfm-x/tests/annot.dvi b/Build/source/texk/dvipdfm-x/tests/annot.dvi
new file mode 100644
index 00000000000..0cea9bacc12
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/annot.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/annot.tex b/Build/source/texk/dvipdfm-x/tests/annot.tex
new file mode 100644
index 00000000000..dd10e9fd223
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/annot.tex
@@ -0,0 +1,25 @@
+%
+\special{pdf:obj @tug <</S/URI /URI (http://www.tug.org)>>}
+
+Add some text and more text and still more text in order to get a link annotation
+extending
+\special{pdf:bann <</Subtype/Link /A @tug>>}%
+TUG on the web
+\special{pdf:eann}
+over two lines.
+
+\vskip 20 bp
+
+some text
+\special{pdf:ann @foo width 15 pt height 10truebp depth 5 true bp <</Subtype/Link /A @tug>>}
+\hskip 15 pt
+more text
+
+\vskip 150 bp
+
+some more text
+\special{pdf:ann @bar bbox 0 0 180 90 <</Subtype/Link /A @tug>>}
+\hskip 180 bp
+final text text
+
+\bye
diff --git a/Build/source/texk/dvipdfm-x/tests/bookm.dvi b/Build/source/texk/dvipdfm-x/tests/bookm.dvi
new file mode 100644
index 00000000000..7952eaa19fd
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/bookm.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/bookm.tex b/Build/source/texk/dvipdfm-x/tests/bookm.tex
new file mode 100644
index 00000000000..d42e12a51f4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/bookm.tex
@@ -0,0 +1,60 @@
+%
+\special{papersize=10cm,10cm}
+
+\special{pdf:out 1
+ <</Title(Contents)/A<</S/GoTo/D(contents)>>>>}
+\special{pdf:out 1
+ <</Title(1 First section)/A<</S/GoTo/D(section.1)>>>>}
+\special{pdf:out 2
+ <</Title(1.1 First subsection)/A<</S/GoTo/D(subsection.1.1)>>>>}
+\special{pdf:out 1
+ <</Title(2 Second section)/A<</S/GoTo/D(section.2)>>>>}
+
+\noindent Contents
+\special{pdf:dest (contents) [@thispage /XYZ @xpos @ypos null]}
+
+\vskip 5mm
+
+\hbox to 60mm{%
+\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/C[1 0 0]
+ /A<</S/GoTo/D(section.1)>>>>}1 First section\special{pdf:eann}
+\hfill 2}
+
+\hbox to 60mm{\hskip 5mm%
+\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/C[1 0 0]
+ /A<</S/GoTo/D(subsection.1.1)>>>>}1.1 First subsection\special{pdf:eann}
+\hfill 3}
+
+\hbox to 60mm{%
+\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/C[1 0 0]
+ /A<</S/GoTo/D(section.2)>>>>}2 Second section\special{pdf:eann}
+\hfill 4}
+
+\vfill\break
+
+\noindent 1 First section
+\special{pdf:dest (section.1) [@thispage /XYZ @xpos @ypos null]}
+
+\vskip 5mm
+
+\noindent The first section
+
+\vfill\break
+
+\noindent 1.1 First subsection
+\special{pdf:dest (subsection.1.1) [@thispage /XYZ @xpos @ypos null]}
+
+\vskip 5mm
+
+\noindent The first subsection
+
+\vfill\break
+
+\noindent 2 Second section
+\special{pdf:dest (section.2) [@thispage /XYZ @xpos @ypos null]}
+
+\vskip 5mm
+
+\noindent The second section
+
+\bye
diff --git a/Build/source/texk/dvipdfm-x/tests/cmr10.pfb b/Build/source/texk/dvipdfm-x/tests/cmr10.pfb
new file mode 100644
index 00000000000..337b4b58c45
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/cmr10.pfb
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/cmr10.tfm b/Build/source/texk/dvipdfm-x/tests/cmr10.tfm
new file mode 100644
index 00000000000..6594c9c4a7f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/cmr10.tfm
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/dvipdfmx.cfg b/Build/source/texk/dvipdfm-x/tests/dvipdfmx.cfg
new file mode 100644
index 00000000000..c3a2843b66a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/dvipdfmx.cfg
@@ -0,0 +1,222 @@
+%% dvipdfmx.cfg for dvipdfmx and xdvipdfmx. (Public domain.)
+%%
+%% PDF Version Setting
+%%
+%% PDF (minor) version stamp to use in output file.
+%% This also implies maximal version of PDF file allowed to be included.
+%% Dvipdfmx does not support 1.0, 1.1, 1.2 since TrueType font embedded
+%% as CIDFontType2 requires at least version 1.3. Transparent imaging
+%% model requires version 1.4. So if you want soft-masking support for
+%% PNG image with alpha channels, you should set version to 4 or higher.
+%% PDF 1.5 enables object compression.
+
+V 5
+
+%% Dvipdfmx Compatibility Flags
+%%
+%% 0x0002 Use semi-transparent filling for tpic shading command,
+%% instead of opaque gray color. (requires PDF 1.4)
+%% 0x0004 Treat all CIDFont as fixed-pitch font.
+%% This is only for backward compatibility. Don't use that.
+%% 0x0008 Do not replace duplicate fontmap entries.
+%% Dvipdfm's (not 'x') behaviour.
+%% 0x0010 Do not optimize PDF destinations. Use this if you want to
+%% refer from other files to destinations in the current file.
+
+%C 0x0000
+
+%% PDF Document Settings
+%%
+%% Papersize Option:
+%%
+%% p papersize-spec
+%%
+%% papersize-spec is 'paper-format' or length-pair, e.g., 'a4', 'letter',
+%% '20cm,30cm'. Recognized unit is 'cm', 'mm', 'bp', 'pt', 'in'.
+
+p a4
+
+%% Annotation Box Margin:
+%%
+%% g length
+%%
+%% Add margin to annotation rectangle created via various \specials. Many
+%% TeX macro packages set the annotation bounding box equal to the TeX box
+%% that encloses the material. That's not always what you want.
+%% Annotations created by pdf:bannot/pdf:eannot is also affected.
+
+%g 0
+
+%% Bookmark Open Level:
+%%
+%% O integer
+%%
+%% Mark bookmark (outline) item as initial state 'open' if the depth
+%% of that item (from root node) is less than or equal to the integer
+%% specified with this option.
+
+O 0
+
+%% PDF Security (Encryption) Setting
+%%
+%% Those options won't take effects unless you use flag 'S'.
+%%
+%% Key bits for PDF encryption (40 - 128)
+
+K 40
+
+%% Permission flag for PDF encryption: Revision will be 3 if the key size
+%% is greater than 40 bits.
+%%
+%% 0x0004 (Revision 2) Print the document.
+%% (Revision 3) Print the document (possibly not at the highest quality
+%% level, depending on whether bit 12[0x0800] is also set).
+%% 0x0008 Modify the contents of the document by operations other than those
+%% controlled by bits 6[0x0020], 9[0x0100], and 11[0x0400].
+%% 0x0010 (Revision 2) Copy or otherwise extract text and graphics from the
+%% document, including extracting text and graphics (in support of
+%% accessibility to disabled users or for other purposes).
+%% (Revision 3) Copy or otherwise extract text and grphics from the
+%% document by operations other than that controlled by bit 10[0x0200].
+%% 0x0020 Add or modify text annotations, fill in interactive form fields,
+%% and, if bit 4[0x0008] is also set, create or modify interactive
+%% form fields (including signature fields).
+%%
+%% (Revision 3 only)
+%% 0x0100 Fill in existing interactive form fields (including signature
+%% fields), even if bit 6 is clear.
+%% 0x0200 Extract text and graphics (in support of accessibility to disabled
+%% users or for other purposes).
+%% 0x0400 Assemble the document (insert, rotate, or delete pages and create
+%% bookmarks or thumbnail images), even if bit 4 is clear.
+%% 0x0800 Print the document to a representation from which a faithful digital
+%% copy of the PDF content could be generated. When this bit is clear
+%% (and bit 3 is set), printing is limited to a low-level representation
+%% of the appearance, possibly of degraded quality.
+
+P 0x003C
+
+%% Image Handler
+%%
+%% With 'D' option dvipdfmx may invoke shell command via system()
+%% function call.
+%%
+%% Command-line template for a-to-b conversion:
+%%
+%% Supported target format ('b') is currently PDF.
+%% Percent sign '%' is special character:
+%%
+%% %i Input file name (FQPN). Name of file to be converted to PDF.
+%% %o Output file name (FQPN). Temporary file to store conversion
+%% result. Removed after inclusion is finished. (regardless of
+%% success or failure)
+%% %b The "base" name of the input file, e.g., "foo" instead of
+%% "foo.eps".
+%% %v The PDF version to be converted to, e.g. "1.4" for PDF 1.4.
+%% %% Replaced with single '%'.
+
+%% Ghostscript (PS-to-PDF and PDF-to-PDF):
+%%
+%% ps2pdf is a front-end to gs. For a complete list of options, see
+%% http://ghostscript.com/doc/current/Ps2pdf.htm#Options
+%%
+%% By default, gs encodes all images contained in a PS file using
+%% the lossy DCT (i.e., JPEG) filter. This often leads to inferior
+%% result (see the discussion at http://electron.mit.edu/~gsteele/pdf/).
+%% The "-dAutoFilterXXXImages" and "-dXXXImageFilter" options used
+%% below force all images to be encoded with the lossless Flate (zlib,
+%% same as PNG) filter. Note that if the PS file already contains DCT
+%% encoded images (which is possible in PS level 2), then these images
+%% will also be re-encoded using Flate. To turn the conversion off,
+%% simply remove the options mentioned above.
+%%
+%% The -dEPSCROP below converts PS files. Before TL 2013,
+%% -sPAPERSIZE=a0 was used for this. In 2013, changes were made to
+%% xetex.def, dvipdfmx.def, etc., to handle non-zero llx/lly.
+%%
+%% In TeX Live, we use the rungs wrapper instead of ps2pdf, becuse we
+%% must omit the -dSAFER which ps2pdf specifies: in order for pstricks
+%% to work with xetex,
+%% /usr/local/texlive/*/texmf-dist/dvips/pstricks/pstricks.pro (for
+%% example) needs to be accessed. (Also, it is better to use our
+%% supplied gs on Windows.) You can also add -dNOSAFER to the ps2pdf
+%% command line.
+%%
+%% Incidentally, especially in TL, more than one dvipdfmx.cfg may be
+%% extant. You can find the one that is active by running:
+%% kpsewhich -progname=dvipdfmx -format='other text files' dvipdfmx.cfg
+%% and control which one is found by setting DVIPDFMXINPUTS.
+%%
+D "rungs -q -dNOPAUSE -dBATCH -dEPSCrop -sDEVICE=pdfwrite -dCompatibilityLevel=%v -dAutoFilterGrayImages=false -dGrayImageFilter=/FlateEncode -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -sOutputFile='%o' '%i' -c quit"
+
+% pre-2013 invocation using -sPAPERSIZE instead of -dEPSCrop, no other changes:
+%D "rungs -q -dNOPAUSE -dBATCH -sPAPERSIZE=a0 -sDEVICE=pdfwrite -dCompatibilityLevel=%v -dAutoFilterGrayImages=false -dGrayImageFilter=/FlateEncode -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -sOutputFile='%o' '%i' -c quit"
+
+% other random ps converters people have experimented with.
+%D "/usr/local/bin/ps2pdf -dEPSCrop '%i' '%o'"
+%D "/usr/texbin/epstopdf '%i' -o '%o'"
+%D "/usr/bin/pstopdf '%i' -o '%o'"
+%
+%% Frank Siegert's PStill:
+%D "/usr/local/bin/pstill -c -o '%o' '%i'"
+%
+%% Batik + Fop (SVG-to-PDF):
+%% If you want both PS and SVG, you need to write a script or program
+%% that selectively invokes converters.
+%D "java -classpath classpaths -jar /path/to/batik-rasterizer.jar -m application/pdf -d '%o' '%i'"
+%
+%% There are no way to directly know suggested size of (raster) images.
+%% You may want to use %b here, since you can try reading the ebb file
+%% to see what is natural (physical) size of images.
+%D "ras2pdf -r 300x300 -b '%b.bb' -o '%o' '%i'"
+%
+%% ImageMagick:
+%% Easiest way to support various file formats.
+%D "convert '%i' 'epdf:%o'"
+
+%% Other Options
+%%
+%% DPI for PK font creation
+
+%r 600
+
+%% Set number of fractional digit kept for various numbers in PDF page
+%% content output. By setting this to 2 (default), dvipdfmx rounds
+%% real numbers at 2nd fractional (decimal) digit; e.g., "3.14159" is
+%% written as "3.14". Increasing this to more than 2 isn't meaningful
+%% for old Acrobat due to implementation limit of Acrobat.
+%% Length 0.01 in unscaled coordinate system amount to width of 1 pixel
+%% in 7200ppi display.
+
+%d 5
+
+%% Image cache life in hours
+%% 0 means erase all old images and leave new images
+%% -1 means erase all old images and also erase new images
+%% -2 means ignore image cache
+%I -2
+
+%% Font Map Files
+%%
+%% teTeX 2.x and TeX Live using updmap (pdfTeX format)
+%f pdftex.map
+
+%% teTeX 2.x and TeX Live using updmap (DVIPDFM format)
+%f dvipdfm.map
+
+%% teTeX 2.x and TeX Live using updmap (DVIPS format)
+%% MiKTeX 2.2 and 2.3
+f psfonts.map
+
+%% Put additional fontmap files here (usually for Type0 fonts)
+f cid-x.map
+
+% the following file is generated by updmap(-sys) from the
+% KanjiMap entries in the updmap.cfg file.
+%f kanjix.map
+% minimal example for Chinese and Korean users
+% improvements please to tex-live@tug.org
+%f ckx.map
+
+%% Include other config files
+%i <filename>
diff --git a/Build/source/texk/dvipdfm-x/tests/fullmap.dvi b/Build/source/texk/dvipdfm-x/tests/fullmap.dvi
new file mode 100644
index 00000000000..a92561fd8bc
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/fullmap.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/fullmap.tex b/Build/source/texk/dvipdfm-x/tests/fullmap.tex
new file mode 100644
index 00000000000..fa764f3cd4f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/fullmap.tex
@@ -0,0 +1,7 @@
+\nopagenumbers
+%
+% For testing << in map lines.
+\special{pdf:mapline augie8r Augie <<augie___.pfb}
+\font\x = augie8r \x Hello.
+%
+\end
diff --git a/Build/source/texk/dvipdfm-x/tests/ids_2_6.dvi b/Build/source/texk/dvipdfm-x/tests/ids_2_6.dvi
new file mode 100644
index 00000000000..952754daef7
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ids_2_6.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/ids_3_2.dvi b/Build/source/texk/dvipdfm-x/tests/ids_3_2.dvi
new file mode 100644
index 00000000000..4f1c937c492
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ids_3_2.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/ids_a_b.dvi b/Build/source/texk/dvipdfm-x/tests/ids_a_b.dvi
new file mode 100644
index 00000000000..1fb1523d2c4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ids_a_b.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/image.bmp b/Build/source/texk/dvipdfm-x/tests/image.bmp
new file mode 100644
index 00000000000..d6904b27c3e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/image.bmp
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/image.dvi b/Build/source/texk/dvipdfm-x/tests/image.dvi
new file mode 100644
index 00000000000..9d0d1ed3aa2
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/image.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/image.jp2 b/Build/source/texk/dvipdfm-x/tests/image.jp2
new file mode 100644
index 00000000000..1f419b4a9ef
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/image.jp2
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/image.jpeg b/Build/source/texk/dvipdfm-x/tests/image.jpeg
new file mode 100644
index 00000000000..5312aab5fc4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/image.jpeg
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/image.pdf b/Build/source/texk/dvipdfm-x/tests/image.pdf
new file mode 100644
index 00000000000..12c4576b56f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/image.pdf
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/image.png b/Build/source/texk/dvipdfm-x/tests/image.png
new file mode 100644
index 00000000000..9b225237c0f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/image.png
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/image.tex b/Build/source/texk/dvipdfm-x/tests/image.tex
new file mode 100644
index 00000000000..78014374b14
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/image.tex
@@ -0,0 +1,37 @@
+%
+\shipout\vbox{
+\vbox to5cm{}
+\special{pdf:image @bmppic (image.bmp)}
+\special{pdf:uxobj @bmppic}
+}
+\advance\count0 by 1
+%
+\shipout\vbox{
+\vbox to5cm{}
+\special{pdf:image @jp2pic (image.jp2)}
+\special{pdf:uxobj @jp2pic}
+}
+\advance\count0 by 1
+%
+\shipout\vbox{
+\vbox to5cm{}
+\special{pdf:image @jpegpic (image.jpeg)}
+\special{pdf:uxobj @jpegpic}
+}
+\advance\count0 by 1
+%
+\shipout\vbox{
+\vbox to5cm{}
+\special{pdf:image @pdfpic (image.pdf)}
+\special{pdf:uxobj @pdfpic}
+}
+\advance\count0 by 1
+\shipout\vbox{
+\vbox to5cm{}
+\special{pdf:image @pngpic (image.png)}
+\special{pdf:uxobj @pngpic}
+}
+\advance\count0 by 1
+%
+%
+\bye
diff --git a/Build/source/texk/dvipdfm-x/tests/opc_fe.dvi b/Build/source/texk/dvipdfm-x/tests/opc_fe.dvi
new file mode 100644
index 00000000000..c3df8bf4517
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/opc_fe.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/paper.dvi b/Build/source/texk/dvipdfm-x/tests/paper.dvi
new file mode 100644
index 00000000000..5975677b4f9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/paper.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/paper.tex b/Build/source/texk/dvipdfm-x/tests/paper.tex
new file mode 100644
index 00000000000..761a28b048d
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/paper.tex
@@ -0,0 +1,6 @@
+%
+\special{papersize=10cm , 10 true cm}
+
+This is a test.
+
+\bye
diff --git a/Build/source/texk/dvipdfm-x/tests/picbmp.bb b/Build/source/texk/dvipdfm-x/tests/picbmp.bb
new file mode 100644
index 00000000000..0c587c2d5b8
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picbmp.bb
@@ -0,0 +1,3 @@
+%%Title: picbmp.bmp
+%%BoundingBox: 0 0 24 24
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picbmp.xbb b/Build/source/texk/dvipdfm-x/tests/picbmp.xbb
new file mode 100644
index 00000000000..e1fb0a12733
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picbmp.xbb
@@ -0,0 +1,4 @@
+%%Title: picbmp.bmp
+%%BoundingBox: 0 0 30 30
+%%HiResBoundingBox: 0.000000 0.000000 29.715155 29.715155
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picjp2.bb b/Build/source/texk/dvipdfm-x/tests/picjp2.bb
new file mode 100644
index 00000000000..86044ad93d3
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picjp2.bb
@@ -0,0 +1,3 @@
+%%Title: picjp2.jp2
+%%BoundingBox: 0 0 33 33
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picjp2.xbb b/Build/source/texk/dvipdfm-x/tests/picjp2.xbb
new file mode 100644
index 00000000000..b72d590b61a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picjp2.xbb
@@ -0,0 +1,4 @@
+%%Title: picjp2.jp2
+%%BoundingBox: 0 0 33 33
+%%HiResBoundingBox: 0.000000 0.000000 33.000000 33.000000
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picjpeg.bb b/Build/source/texk/dvipdfm-x/tests/picjpeg.bb
new file mode 100644
index 00000000000..8b8f042bea9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picjpeg.bb
@@ -0,0 +1,3 @@
+%%Title: picjpeg.jpeg
+%%BoundingBox: 0 0 108 148
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picjpeg.xbb b/Build/source/texk/dvipdfm-x/tests/picjpeg.xbb
new file mode 100644
index 00000000000..508f796d8ab
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picjpeg.xbb
@@ -0,0 +1,4 @@
+%%Title: picjpeg.jpeg
+%%BoundingBox: 0 0 150 205
+%%HiResBoundingBox: 0.000000 0.000000 150.000000 205.000000
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picpdf.bb b/Build/source/texk/dvipdfm-x/tests/picpdf.bb
new file mode 100644
index 00000000000..5a4c6fbb5c9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picpdf.bb
@@ -0,0 +1,3 @@
+%%Title: picpdf.pdf
+%%BoundingBox: 0 0 69 83
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picpdf.xbb b/Build/source/texk/dvipdfm-x/tests/picpdf.xbb
new file mode 100644
index 00000000000..6b25865023c
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picpdf.xbb
@@ -0,0 +1,6 @@
+%%Title: picpdf.pdf
+%%BoundingBox: 0 0 69 83
+%%HiResBoundingBox: 0.000000 0.000000 69.000000 83.000000
+%%PDFVersion: 1.4
+%%Pages: 1
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picpng.bb b/Build/source/texk/dvipdfm-x/tests/picpng.bb
new file mode 100644
index 00000000000..dfd42cd41cb
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picpng.bb
@@ -0,0 +1,3 @@
+%%Title: picpng.png
+%%BoundingBox: 0 0 124 89
+
diff --git a/Build/source/texk/dvipdfm-x/tests/picpng.xbb b/Build/source/texk/dvipdfm-x/tests/picpng.xbb
new file mode 100644
index 00000000000..5e1b90f1256
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/picpng.xbb
@@ -0,0 +1,4 @@
+%%Title: picpng.png
+%%BoundingBox: 0 0 172 124
+%%HiResBoundingBox: 0.000000 0.000000 172.000000 124.000000
+
diff --git a/Build/source/texk/dvipdfm-x/tests/psfonts.map b/Build/source/texk/dvipdfm-x/tests/psfonts.map
new file mode 100644
index 00000000000..2a799870993
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/psfonts.map
@@ -0,0 +1 @@
+cmr10 CMR10 <cmr10.pfb
diff --git a/Build/source/texk/dvipdfm-x/tests/ptex.dvi b/Build/source/texk/dvipdfm-x/tests/ptex.dvi
new file mode 100644
index 00000000000..8774e670763
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ptex.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/ptx_2_2.dvi b/Build/source/texk/dvipdfm-x/tests/ptx_2_2.dvi
new file mode 100644
index 00000000000..d34a5070f83
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ptx_2_2.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/ptx_6_6.dvi b/Build/source/texk/dvipdfm-x/tests/ptx_6_6.dvi
new file mode 100644
index 00000000000..19ed6ddb628
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ptx_6_6.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/resrc.dvi b/Build/source/texk/dvipdfm-x/tests/resrc.dvi
new file mode 100644
index 00000000000..8e16467e097
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/resrc.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/resrc.tex b/Build/source/texk/dvipdfm-x/tests/resrc.tex
new file mode 100644
index 00000000000..5c95c930e51
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/resrc.tex
@@ -0,0 +1,6 @@
+\documentclass[dvipdfmx]{article}
+\usepackage{tikz}
+\usetikzlibrary{patterns}
+\begin{document}
+\tikz \path[pattern=crosshatch] (0,0) -- (1,0) -- (0,1) -- cycle;
+\end{document}
diff --git a/Build/source/texk/dvipdfm-x/tests/rev_2_2.dvi b/Build/source/texk/dvipdfm-x/tests/rev_2_2.dvi
new file mode 100644
index 00000000000..814322571bd
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/rev_2_2.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/rev_2_3.dvi b/Build/source/texk/dvipdfm-x/tests/rev_2_3.dvi
new file mode 100644
index 00000000000..35dd637304f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/rev_2_3.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/reverse.dvi b/Build/source/texk/dvipdfm-x/tests/reverse.dvi
new file mode 100644
index 00000000000..d32b2ae8da4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/reverse.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/test.ttc b/Build/source/texk/dvipdfm-x/tests/test.ttc
new file mode 100644
index 00000000000..2eea577e9c1
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/test.ttc
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/test_extended_color.tex b/Build/source/texk/dvipdfm-x/tests/test_extended_color.tex
new file mode 100644
index 00000000000..d1d44517ed0
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/test_extended_color.tex
@@ -0,0 +1,137 @@
+% latex test_extended_color.tex
+% dvipdfmx test_extended_color.dvi
+\documentclass[dvipdfmx]{article}
+% for xelatex:
+%\documentclass{article}
+\newcommand{\specialbox}[3]{\makebox[#1][l]{\raisebox{-#2}[0bp][#2]{#3}}}
+\AtBeginDocument{%
+%% Separation ColorSpace (Spot color)
+\special{pdf:stream @tintTransform1
+ ({0 exch dup 0.62 mul exch 0})
+ << /FunctionType 4
+ /Domain [ 0.0 1.0 ]
+ /Range [ 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 ]
+ >>
+}
+\special{pdf:stream @tintTransform2
+ ({dup 0.78 mul exch dup 0.05 mul exch 0.71 mul 0})
+ << /FunctionType 4
+ /Domain [ 0.0 1.0 ]
+ /Range [ 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 ]
+ >>
+}
+%% -- Orange
+\special{pdf:obj @colorspace:orange [ /Separation
+ /Orange /DeviceCMYK @tintTransform1]}
+%% -- Green
+\special{pdf:obj @colorspace:green [ /Separation
+ /Green /DeviceCMYK @tintTransform2]}
+
+%% Pattern: Uncolored
+\special{pdf:stream @pattern:tile1
+ (0.16 0 0 0.16 0 0 cm 4 w
+ 50 0 m 50 28 28 50 0 50 c S 100 50
+ m 72 50 50 28 50 0 c S
+ 50 100 m 50 72 72 50 100 50 c S
+ 0 50 m 28 50 50 72 50 100 c S
+ 100 50 m 100 78 78 100 50 100 c 22 100 0 78 0 50 c
+ 0 22 22 0 50 0 c 78 0 100 22 100 50 c S
+ 0 0 m 20 10 25 5 25 0 c f 0 0 m 10 20 5 25 0 25 c f
+ 100 0 m 80 10 75 5 75 0 c f
+ 100 0 m 90 20 95 25 100 25 c f
+ 100 100 m 80 90 75 95 75 100 c f
+ 100 100 m 90 80 95 75 100 75 c f
+ 0 100 m 20 90 25 95 25 100 c f
+ 0 100 m 10 80 5 75 0 75 c f
+ 50 50 m 70 60 75 55 75 50 c 75 45 70 40 50 50 c f
+ 50 50 m 60 70 55 75 50 75 c 45 75 40 70 50 50 c f
+ 50 50 m 30 60 25 55 25 50 c
+ 25 45 30 40 50 50 c f
+ 50 50 m 60 30 55 25 50 25 c 45 25 40 30 50 50 c f)
+ <<
+ /BBox [0 0 16 16]
+ /PaintType 2
+ /PatternType 1
+ /Resources <<
+ /ProcSet [/PDF]
+ >>
+ /TilingType 3
+ /Type /Pattern
+ /XStep 16
+ /YStep 16
+ >>
+}
+\special{pdf:obj @colorspace:pattern [/Pattern /DeviceRGB]}
+%% Indexed
+\special{pdf:obj @colorspace:indexed [/Indexed
+ /DeviceRGB 3 <000000 FF0000 00FF00 0000FF>]}
+%% Calibrated Gray
+\special{pdf:obj @colorspace:calgray [ /CalGray << /WhitePoint [0.95505 1.00000 1.0890] /Gamma 2.222 >> ]}
+%% ICCBased (require ICC profile)
+\special{pdf:fstream @icc_profile:srgb (sRGB.icc) << /N 3 >>}
+\special{pdf:obj @colorspace:srgb [ /ICCBased @icc_profile:srgb ]}
+}
+\begin{document}
+Indexed:
+\special{pdf:bcolor @colorspace:indexed [2]}
+Green
+\special{pdf:ecolor}
+\special{pdf:bcolor @colorspace:indexed [3]}
+Blue
+\special{pdf:ecolor}
+\special{pdf:bcolor @colorspace:indexed [1]}
+Red
+\special{pdf:ecolor}
+\special{pdf:bcolor @colorspace:indexed [0]}
+Black
+\special{pdf:ecolor}
+
+Separation:
+\special{pdf:bcolor @colorspace:orange [0.4]}
+Orange 0.4
+\special{pdf:ecolor}
+\special{pdf:bcolor @colorspace:green [0.8]}
+Green 0.8
+\special{pdf:ecolor}
+
+Nesting and Page Break:
+\special{pdf:bcolor @colorspace:orange [0.9]}
+Orange 0.9
+\special{pdf:bcolor @colorspace:green [0.8]}
+Green 0.8
+\newpage
+...continued
+\special{pdf:ecolor}
+Orange 0.9
+
+\special{pdf:bcolor /DeviceCMYK [1 0 0 0.5]}
+CMYK 1 0 0 0.5
+\special{pdf:bcolor /DeviceRGB [1 0 0 ]}
+Red
+\special{pdf:ecolor}
+\special{pdf:ecolor}
+Finally... back to the first color: Orange 0.9.
+\special{pdf:ecolor}
+\newpage
+
+CalGray:
+\special{pdf:bcolor @colorspace:calgray [0.2]}
+CalGray example.
+\special{pdf:ecolor}
+
+ICCBased ColorSpace:
+
+\special{pdf:bcolor @colorspace:srgb [0.0 1.0 0.0]}
+{\Huge Hello again}
+\special{pdf:ecolor}
+\newpage
+
+Pattern Examples...
+
+\specialbox{320pt}{100pt}{%
+\special{pdf:bcolor @colorspace:pattern [0.8 @pattern:tile1]}%
+\special{pdf:content 0 0 320 100 re f}%
+\special{pdf:ecolor}%
+}
+
+\end{document}
diff --git a/Build/source/texk/dvipdfm-x/tests/ttc.dvi b/Build/source/texk/dvipdfm-x/tests/ttc.dvi
new file mode 100644
index 00000000000..31e3843ac16
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ttc.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/ttc.tex b/Build/source/texk/dvipdfm-x/tests/ttc.tex
new file mode 100644
index 00000000000..b9efd5d0038
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/ttc.tex
@@ -0,0 +1,3 @@
+\font\test="[test.ttc:0]"\test This is a test
+\font\test="[test.ttc:1]"\test This is a test
+\bye
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf-g.tfm b/Build/source/texk/dvipdfm-x/tests/upjf-g.tfm
new file mode 100644
index 00000000000..3f0bfdff987
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf-g.tfm
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf-r.tfm b/Build/source/texk/dvipdfm-x/tests/upjf-r.tfm
new file mode 100644
index 00000000000..8dbf787b3ec
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf-r.tfm
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf.dvi b/Build/source/texk/dvipdfm-x/tests/upjf.dvi
new file mode 100644
index 00000000000..1e5473dc81b
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf.map b/Build/source/texk/dvipdfm-x/tests/upjf.map
new file mode 100644
index 00000000000..8203ec49a68
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf.map
@@ -0,0 +1,9 @@
+%upjf-r UniJIS-UTF16-H HaranoAjiMincho-Regular.otf
+%upjf-g UniJIS-UTF16-H HaranoAjiGothic-Regular.otf
+
+%upjf-r UniJIS-UTF16-H !Ryumin-Light
+%upjf-g UniJIS-UTF16-H !GothicBBB-Medium
+
+upjf-r UPJF-UTF16-H !Ryumin-Light
+upjf-g UPJF-UTF16-H !GothicBBB-Medium
+
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf.tex b/Build/source/texk/dvipdfm-x/tests/upjf.tex
new file mode 100644
index 00000000000..de471281b2f
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf.tex
@@ -0,0 +1,19 @@
+% Copyright (C) 2020 Japanese TeX Development Community
+% You may freely use, modify and/or distribute this file.
+
+\documentclass{ujarticle}
+
+% for dvipdfmx
+%\AtBeginDvi{\special{pdf:mapline upjf-r UniJIS-UTF16-H HaranoAjiMincho-Regular.otf}}
+%\AtBeginDvi{\special{pdf:mapline upjf-g UniJIS-UTF16-H HaranoAjiGothic-Regular.otf}}
+%\AtBeginDvi{\special{pdf:mapline upjf-r UniJIS-UTF16-H !Ryumin-Light}}
+%\AtBeginDvi{\special{pdf:mapline upjf-g UniJIS-UTF16-H !GothicBBB-Medium}}
+%\AtBeginDvi{\special{pdf:mapline upjf-r UPJF-UTF16-H !Ryumin-Light}}
+%\AtBeginDvi{\special{pdf:mapline upjf-g UPJF-UTF16-H !GothicBBB-Medium}}
+
+\begin{document}
+\pagestyle{empty}
+\font\upjf=upjf at 10pt
+\upjf ã‚ã„ã†ãˆãŠï½±ï½²ï½³ï½´ï½µã€â˜ƒ~雪晴☀𠮟。
+\end{document}
+
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf.tfm b/Build/source/texk/dvipdfm-x/tests/upjf.tfm
new file mode 100644
index 00000000000..d18f4d546c8
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf.tfm
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf_full.cnf b/Build/source/texk/dvipdfm-x/tests/upjf_full.cnf
new file mode 100644
index 00000000000..5ba8a501631
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf_full.cnf
@@ -0,0 +1,13 @@
+% makejvf settings for test
+% You may freely use, modify and/or distribute this file.
+
+CHARSET %
++ 2600,% ☀
++ 2603,% ☃
++ 3000..303F,% CJK Symbols and Punctuation
++ 3040..309F,% Hiragana
++ 6674,% æ™´
++ 96EA,% 雪
++ FF00..FFEF,% Halfwidth and Fullwidth Forms
++ 20B9F% 𠮟
+
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf_full.vf b/Build/source/texk/dvipdfm-x/tests/upjf_full.vf
new file mode 100644
index 00000000000..342ea0fdc38
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf_full.vf
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf_omit.cnf b/Build/source/texk/dvipdfm-x/tests/upjf_omit.cnf
new file mode 100644
index 00000000000..dbb1af7ffc2
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf_omit.cnf
@@ -0,0 +1,13 @@
+% makejvf settings for test
+% You may freely use, modify and/or distribute this file.
+
+CHARSET %
++ 2600,% ☀
++ 2603,% ☃
++ 3000..303F,% CJK Symbols and Punctuation
++ 3040..309F,% Hiragana
++ 6674,% æ™´
+%+ 96EA,% 雪
++ FF00..FFEF,% Halfwidth and Fullwidth Forms
+%+ 20B9F% 𠮟
+
diff --git a/Build/source/texk/dvipdfm-x/tests/upjf_omit.vf b/Build/source/texk/dvipdfm-x/tests/upjf_omit.vf
new file mode 100644
index 00000000000..e9bbe6ea2fb
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/upjf_omit.vf
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/void.dvi b/Build/source/texk/dvipdfm-x/tests/void.dvi
new file mode 100644
index 00000000000..7ec6d6c1be6
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/void.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/xbmc.dvi b/Build/source/texk/dvipdfm-x/tests/xbmc.dvi
new file mode 100644
index 00000000000..eddae94621a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/xbmc.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/xbmc.tex b/Build/source/texk/dvipdfm-x/tests/xbmc.tex
new file mode 100644
index 00000000000..99a94cdb1fb
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/xbmc.tex
@@ -0,0 +1 @@
+\font\revrm=xbmc10\revrm E\bye
diff --git a/Build/source/texk/dvipdfm-x/tests/xbmc10.600pk b/Build/source/texk/dvipdfm-x/tests/xbmc10.600pk
new file mode 100644
index 00000000000..1c51bd1ab74
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/xbmc10.600pk
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tests/xbmc10.tfm b/Build/source/texk/dvipdfm-x/tests/xbmc10.tfm
new file mode 100644
index 00000000000..04f6429540e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tests/xbmc10.tfm
Binary files differ
diff --git a/Build/source/texk/dvipdfm-x/tfm.c b/Build/source/texk/dvipdfm-x/tfm.c
new file mode 100644
index 00000000000..629663d5c7e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tfm.c
@@ -0,0 +1,1245 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "mfileio.h"
+#include "error.h"
+
+#include "numbers.h"
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "tfm.h"
+
+#define TFM_FORMAT 1
+#define OFM_FORMAT 2
+
+#define FWBASE ((double) (1<<20))
+
+#ifndef WITHOUT_ASCII_PTEX
+/*
+ * ID is 9 for vertical JFM file.
+ */
+#define JFM_ID 11
+#define JFMV_ID 9
+#define IS_JFM(i) ((i) == JFM_ID || (i) == JFMV_ID)
+
+#define CHARACTER_INDEX(i) ((i > 0x10FFFFUL ? 0x110000UL : i))
+#else
+#define CHARACTER_INDEX(i) ((i))
+#endif
+
+/*
+ * TFM Record structure:
+ * Multiple TFM's may be read in at once.
+ */
+
+struct tfm_font
+{
+#ifndef WITHOUT_ASCII_PTEX
+ int id;
+ int nt;
+#endif /* !WITHOUT_ASCII_PTEX */
+#ifndef WITHOUT_OMEGA
+ int32_t level;
+#endif /* !WITHOUT_OMEGA */
+ uint32_t wlenfile;
+ uint32_t wlenheader;
+ uint32_t bc, ec;
+ uint32_t nwidths, nheights, ndepths;
+ uint32_t nitcor, nlig, nkern, nextens;
+ uint32_t nfonparm;
+#ifndef WITHOUT_OMEGA
+ uint32_t fontdir;
+ uint32_t nco, ncw, npc;
+#endif /* !WITHOUT_OMEGA */
+ fixword *header;
+#ifndef WITHOUT_ASCII_PTEX
+ unsigned int *chartypes;
+#endif /* !WITHOUT_ASCII_PTEX */
+ uint32_t *char_info;
+ unsigned short *width_index;
+ unsigned char *height_index;
+ unsigned char *depth_index;
+ fixword *width;
+ fixword *height;
+ fixword *depth;
+};
+
+static void
+tfm_font_init (struct tfm_font *tfm)
+{
+ tfm->header = NULL;
+#ifndef WITHOUT_ASCII_PTEX
+ tfm->id = 0;
+ tfm->nt = 0;
+ tfm->chartypes = NULL;
+#endif /* !WITHOUT_ASCII_PTEX */
+#ifndef WITHOUT_OMEGA
+ tfm->level = 0;
+ tfm->fontdir = 0;
+ tfm->nco = tfm->ncw = tfm->npc = 0;
+#endif
+ tfm->char_info = NULL;
+ tfm->width_index = NULL;
+ tfm->height_index = NULL;
+ tfm->depth_index = NULL;
+ tfm->width = tfm->height = tfm->depth = NULL;
+}
+
+static void
+tfm_font_clear (struct tfm_font *tfm)
+{
+ if (tfm) {
+ if (tfm->header) {
+ RELEASE(tfm->header);
+ tfm->header = NULL;
+ }
+ if (tfm->char_info) {
+ RELEASE(tfm->char_info);
+ tfm->char_info = NULL;
+ }
+ if (tfm->width) {
+ RELEASE(tfm->width);
+ tfm->width = NULL;
+ }
+ if (tfm->height) {
+ RELEASE(tfm->height);
+ tfm->height = NULL;
+ }
+ if (tfm->depth) {
+ RELEASE(tfm->depth);
+ tfm->depth = NULL;
+ }
+#ifndef WITHOUT_ASCII_PTEX
+ if (tfm->chartypes) {
+ RELEASE(tfm->chartypes);
+ tfm->chartypes = NULL;
+ }
+#endif /* !WITHOUT_ASCII_PTEX */
+ if (tfm->width_index) {
+ RELEASE(tfm->width_index);
+ tfm->width_index = NULL;
+ }
+ if (tfm->height_index) {
+ RELEASE(tfm->height_index);
+ tfm->height_index = NULL;
+ }
+ if (tfm->depth_index) {
+ RELEASE(tfm->depth_index);
+ tfm->depth_index = NULL;
+ }
+ }
+}
+
+
+struct coverage
+{
+ int first_char;
+ int num_chars;
+};
+
+/*
+ * All characters in the same range have same metrics.
+ */
+
+struct range_map {
+ unsigned short num_coverages;
+ struct coverage *coverages;
+ unsigned short *indices;
+};
+
+/* Special case of num_coverages = 1 */
+struct char_map
+{
+ struct coverage coverage;
+#ifndef WITHOUT_ASCII_PTEX
+ unsigned int *indices;
+#else
+ unsigned short *indices;
+#endif
+};
+
+static void
+release_char_map (struct char_map *map)
+{
+ if (map->indices)
+ RELEASE(map->indices);
+ map->indices = NULL;
+ RELEASE(map);
+}
+
+static void
+release_range_map (struct range_map *map)
+{
+ if (map->coverages)
+ RELEASE(map->coverages);
+ if (map->indices)
+ RELEASE(map->indices);
+ map->coverages = NULL;
+ map->indices = NULL;
+ RELEASE(map);
+}
+
+static int
+lookup_char (const struct char_map *map, int charcode)
+{
+ if (charcode >= map->coverage.first_char &&
+ charcode <= map->coverage.first_char + map->coverage.num_chars)
+ return map->indices[CHARACTER_INDEX(charcode - map->coverage.first_char)];
+ else
+ return -1;
+}
+
+static int
+lookup_range (const struct range_map *map, int charcode)
+{
+ int idx;
+
+ for (idx = map->num_coverages - 1; idx >= 0 &&
+ charcode >= map->coverages[idx].first_char; idx--) {
+ if (charcode <=
+ map->coverages[idx].first_char + map->coverages[idx].num_chars)
+ return map->indices[CHARACTER_INDEX(idx)];
+ }
+
+ return -1;
+}
+
+#define SOURCE_TYPE_TFM 0
+#define SOURCE_TYPE_JFM 1
+#define SOURCE_TYPE_OFM 2
+
+#define MAPTYPE_NONE 0
+#define MAPTYPE_CHAR 1
+#define MAPTYPE_RANGE 2
+
+#define FONT_DIR_HORIZ 0
+#define FONT_DIR_VERT 1
+
+struct font_metric
+{
+ char *tex_name;
+ fixword designsize;
+ char *codingscheme;
+
+ int fontdir;
+ int firstchar, lastchar;
+
+ fixword *widths;
+ fixword *heights;
+ fixword *depths;
+
+ struct {
+ int type;
+ void *data;
+ } charmap;
+
+ int source;
+};
+
+static void
+fm_init (struct font_metric *fm)
+{
+ fm->tex_name = NULL;
+ fm->firstchar = 0;
+ fm->lastchar = 0;
+ fm->fontdir = FONT_DIR_HORIZ;
+ fm->codingscheme = NULL;
+ fm->designsize = 0;
+
+ fm->widths = NULL;
+ fm->heights = NULL;
+ fm->depths = NULL;
+
+ fm->charmap.type = MAPTYPE_NONE;
+ fm->charmap.data = NULL;
+
+ fm->source = SOURCE_TYPE_TFM;
+}
+
+static void
+fm_clear (struct font_metric *fm)
+{
+ if (fm) {
+ if (fm->tex_name)
+ RELEASE(fm->tex_name);
+ if (fm->widths)
+ RELEASE(fm->widths);
+ if (fm->heights)
+ RELEASE(fm->heights);
+ if (fm->depths)
+ RELEASE(fm->depths);
+ if (fm->codingscheme)
+ RELEASE(fm->codingscheme);
+
+ switch (fm->charmap.type) {
+ case MAPTYPE_CHAR:
+ release_char_map(fm->charmap.data);
+ break;
+ case MAPTYPE_RANGE:
+ release_range_map(fm->charmap.data);
+ break;
+ }
+ }
+}
+
+#ifndef MAX_FONTS
+#define MAX_FONTS 16
+#endif
+
+struct font_metric *fms = NULL;
+static unsigned numfms = 0, max_fms = 0;
+
+static void
+fms_need (unsigned n)
+{
+ if (n > max_fms) {
+ max_fms = MAX(max_fms + MAX_FONTS, n);
+ fms = RENEW(fms, max_fms, struct font_metric);
+ }
+}
+
+static int
+fread_fwords (fixword *words, int32_t nmemb, FILE *fp)
+{
+ int i;
+
+ for (i = 0; i < nmemb; i++)
+ words[i] = get_signed_quad(fp);
+
+ return nmemb*4;
+}
+
+static int
+fread_uquads (uint32_t *quads, int32_t nmemb, FILE *fp)
+{
+ int i;
+
+ for (i = 0; i < nmemb; i++) {
+ quads[i] = get_unsigned_quad(fp);
+ }
+
+ return nmemb*4;
+}
+
+/*
+ * TFM and JFM
+ */
+static void
+tfm_check_size (struct tfm_font *tfm, off_t tfm_file_size)
+{
+ uint32_t expected_size = 6;
+
+ /* Removed the warning message caused by EC TFM metric files.
+ *
+ if (tfm->wlenfile != tfm_file_size / 4) {
+ WARN("TFM file size is %ld bytes but it says it is %ld bytes!",
+ tfm_file_size, tfm->wlenfile * 4);
+ if (tfm_file_size > tfm->wlenfile * 4) {
+ WARN("Proceeding nervously...");
+ } else {
+ ERROR("Can't proceed...");
+ }
+ }
+ */
+ if ((int64_t)tfm_file_size < (int64_t)tfm->wlenfile * 4) {
+ ERROR("Can't proceed...");
+ }
+
+ expected_size += (tfm->ec - tfm->bc + 1);
+ expected_size += tfm->wlenheader;
+ expected_size += tfm->nwidths;
+ expected_size += tfm->nheights;
+ expected_size += tfm->ndepths;
+ expected_size += tfm->nitcor;
+ expected_size += tfm->nlig;
+ expected_size += tfm->nkern;
+ expected_size += tfm->nextens;
+ expected_size += tfm->nfonparm;
+#ifndef WITHOUT_ASCII_PTEX
+ if (IS_JFM(tfm->id)) {
+ expected_size += tfm->nt + 1;
+ }
+#endif /* !WITHOUT_ASCII_PTEX */
+ if (expected_size != tfm->wlenfile) {
+ WARN("TFM file size is expected to be %" PRId64 " bytes but it says it is %" PRId64 "bytes!",
+ (int64_t)expected_size * 4, (int64_t)tfm->wlenfile * 4);
+ if ((int64_t)tfm_file_size > (int64_t)expected_size *4) {
+ WARN("Proceeding nervously...");
+ } else {
+ ERROR("Can't proceed...");
+ }
+ }
+}
+
+static void
+tfm_get_sizes (FILE *tfm_file, off_t tfm_file_size, struct tfm_font *tfm)
+{
+#ifndef WITHOUT_ASCII_PTEX
+ {
+ unsigned short first_hword;
+
+ /*
+ * The first half word of TFM/JFM is TFM ID for JFM or size of
+ * TFM file in word for TFM. TFM with 9*4 or 11*4 bytes is not
+ * expected to be a valid TFM. So, we always assume that TFMs
+ * starting with 00 09 or 00 0B is JFM.
+ */
+ first_hword = get_unsigned_pair(tfm_file);
+ if (IS_JFM(first_hword)) {
+ tfm->id = first_hword;
+ tfm->nt = get_unsigned_pair(tfm_file);
+ tfm->wlenfile = get_unsigned_pair(tfm_file);
+ } else {
+ tfm->wlenfile = first_hword;
+ }
+ }
+#else /* WITHOUT_ASCII_PTEX */
+ tfm->wlenfile = get_unsigned_pair(tfm_file);
+#endif /* !WITHOUT_ASCII_PTEX */
+
+ tfm->wlenheader = get_unsigned_pair(tfm_file);
+ tfm->bc = get_unsigned_pair(tfm_file);
+ tfm->ec = get_unsigned_pair(tfm_file);
+ if (tfm->ec < tfm->bc) {
+ ERROR("TFM file error: ec(%u) < bc(%u) ???", tfm->ec, tfm->bc);
+ }
+ tfm->nwidths = get_unsigned_pair(tfm_file);
+ tfm->nheights = get_unsigned_pair(tfm_file);
+ tfm->ndepths = get_unsigned_pair(tfm_file);
+ tfm->nitcor = get_unsigned_pair(tfm_file);
+ tfm->nlig = get_unsigned_pair(tfm_file);
+ tfm->nkern = get_unsigned_pair(tfm_file);
+ tfm->nextens = get_unsigned_pair(tfm_file);
+ tfm->nfonparm = get_unsigned_pair(tfm_file);
+
+ tfm_check_size(tfm, tfm_file_size);
+
+ return;
+}
+
+#ifndef WITHOUT_ASCII_PTEX
+static unsigned int
+get_unsigned_triple_kanji(FILE *file)
+{
+ unsigned int triple = get_unsigned_byte(file);
+ triple = (triple << 8) | get_unsigned_byte(file);
+ triple = triple | (get_unsigned_byte(file)<<16);
+ return triple;
+}
+
+static void
+jfm_do_char_type_array (FILE *tfm_file, struct tfm_font *tfm)
+{
+ unsigned int charcode;
+ unsigned short chartype;
+ unsigned int i;
+
+ tfm->chartypes = NEW(1114112, unsigned int);
+ for (i = 0; i < 1114112; i++) {
+ tfm->chartypes[i] = 0;
+ }
+ for (i = 0; i < tfm->nt; i++) {
+ /* support new JFM spec by texjporg */
+ charcode = get_unsigned_triple_kanji(tfm_file);
+ chartype = get_unsigned_byte(tfm_file);
+ tfm->chartypes[charcode] = chartype;
+ }
+}
+
+static void
+jfm_make_charmap (struct font_metric *fm, struct tfm_font *tfm)
+{
+ if (tfm->nt > 1) {
+ struct char_map *map;
+ int code;
+
+ fm->charmap.type = MAPTYPE_CHAR;
+ fm->charmap.data = map = NEW(1, struct char_map);
+ map->coverage.first_char = 0;
+#ifndef WITHOUT_ASCII_PTEX
+ map->coverage.num_chars = 0x10FFFFL;
+ map->indices = NEW(0x110001L, unsigned int);
+ map->indices[0x110000L] = tfm->chartypes[0];
+ for (code = 0; code <= 0x10FFFFU; code++) {
+#else
+ map->coverage.num_chars = 0xFFFFL;
+ map->indices = NEW(0x10000L, unsigned short);
+ for (code = 0; code <= 0xFFFFU; code++) {
+#endif
+ map->indices[code] = tfm->chartypes[code];
+ }
+ } else {
+ struct range_map *map;
+
+ fm->charmap.type = MAPTYPE_RANGE;
+ fm->charmap.data = map = NEW(1, struct range_map);
+ map->num_coverages = 1;
+ map->coverages = NEW(map->num_coverages, struct coverage);
+ map->coverages[0].first_char = 0;
+#ifndef WITHOUT_ASCII_PTEX
+ map->coverages[0].num_chars = 0x10FFFFL;
+#else
+ map->coverages[0].num_chars = 0xFFFFL;
+#endif
+ map->indices = NEW(1, unsigned short);
+ map->indices[0] = 0; /* Only default type used. */
+ }
+}
+#endif /* !WITHOUT_ASCII_PTEX */
+
+static void
+tfm_unpack_arrays (struct font_metric *fm, struct tfm_font *tfm)
+{
+ uint32_t charinfo;
+ unsigned short width_index;
+ unsigned char height_index, depth_index;
+ int i;
+
+ fm->widths = NEW(256, fixword);
+ fm->heights = NEW(256, fixword);
+ fm->depths = NEW(256, fixword);
+ for (i = 0; i < 256; i++) {
+ fm->widths [i] = 0;
+ fm->heights[i] = 0;
+ fm->depths [i] = 0;
+ }
+
+ for (i = tfm->bc; i <= tfm->ec; i++ ) {
+ charinfo = tfm->char_info[i - tfm->bc];
+ width_index = (charinfo >> 24);
+ height_index = (charinfo >> 20) & 0xf;
+ depth_index = (charinfo >> 16) & 0xf;
+ fm->widths [i] = tfm->width [width_index];
+ fm->heights[i] = tfm->height[height_index];
+ fm->depths [i] = tfm->depth [depth_index];
+ }
+
+ return;
+}
+
+static int
+sput_bigendian (char *s, int32_t v, int n)
+{
+ int i;
+
+ for (i = n-1; i >= 0; i--) {
+ s[i] = (char) (v & 0xff);
+ v >>= 8;
+ }
+
+ return n;
+}
+
+static void
+tfm_unpack_header (struct font_metric *fm, struct tfm_font *tfm)
+{
+ if (tfm->wlenheader < 12) {
+ fm->codingscheme = NULL;
+ } else {
+ int i, len;
+ char *p;
+
+ len = (tfm->header[2] >> 24);
+ if (len < 0 || len > 39)
+ ERROR("Invalid TFM header.");
+ if (len > 0) {
+ fm->codingscheme = NEW(40, char);
+ p = fm->codingscheme;
+ p += sput_bigendian(p, tfm->header[2], 3);
+ for (i = 1; i <= len / 4; i++) {
+ p += sput_bigendian(p, tfm->header[2+i], 4);
+ }
+ fm->codingscheme[len] = '\0';
+ } else {
+ fm->codingscheme = NULL;
+ }
+ }
+
+ fm->designsize = tfm->header[1];
+}
+
+#ifndef WITHOUT_OMEGA
+
+static void
+ofm_check_size_one (struct tfm_font *tfm, off_t ofm_file_size)
+{
+ uint32_t ofm_size = 14;
+
+ ofm_size += 2*(tfm->ec - tfm->bc + 1);
+ ofm_size += tfm->wlenheader;
+ ofm_size += tfm->nwidths;
+ ofm_size += tfm->nheights;
+ ofm_size += tfm->ndepths;
+ ofm_size += tfm->nitcor;
+ ofm_size += 2*(tfm->nlig);
+ ofm_size += tfm->nkern;
+ ofm_size += 2*(tfm->nextens);
+ ofm_size += tfm->nfonparm;
+ if (tfm->wlenfile != ofm_file_size / 4 ||
+ tfm->wlenfile != ofm_size) {
+ ERROR("OFM file problem. Table sizes don't agree.");
+ }
+}
+
+static void
+ofm_get_sizes (FILE *ofm_file, off_t ofm_file_size, struct tfm_font *tfm)
+{
+ tfm->level = get_signed_quad(ofm_file);
+
+ tfm->wlenfile = get_positive_quad(ofm_file, "OFM", "wlenfile");
+ tfm->wlenheader = get_positive_quad(ofm_file, "OFM", "wlenheader");
+ tfm->bc = get_positive_quad(ofm_file, "OFM", "bc");
+ tfm->ec = get_positive_quad(ofm_file, "OFM", "ec");
+ if (tfm->ec < tfm->bc) {
+ ERROR("OFM file error: ec(%u) < bc(%u) ???", tfm->ec, tfm->bc);
+ }
+ tfm->nwidths = get_positive_quad(ofm_file, "OFM", "nwidths");
+ tfm->nheights = get_positive_quad(ofm_file, "OFM", "nheights");
+ tfm->ndepths = get_positive_quad(ofm_file, "OFM", "ndepths");
+ tfm->nitcor = get_positive_quad(ofm_file, "OFM", "nitcor");
+ tfm->nlig = get_positive_quad(ofm_file, "OFM", "nlig");
+ tfm->nkern = get_positive_quad(ofm_file, "OFM", "nkern");
+ tfm->nextens = get_positive_quad(ofm_file, "OFM", "nextens");
+ tfm->nfonparm = get_positive_quad(ofm_file, "OFM", "nfonparm");
+ tfm->fontdir = get_positive_quad(ofm_file, "OFM", "fontdir");
+ if (tfm->fontdir) {
+ WARN("I may be interpreting a font direction incorrectly.");
+ }
+ if (tfm->level == 0) {
+ ofm_check_size_one(tfm, ofm_file_size);
+ } else if (tfm->level == 1) {
+ tfm->nco = get_positive_quad(ofm_file, "OFM", "nco");
+ tfm->ncw = get_positive_quad(ofm_file, "OFM", "nco");
+ tfm->npc = get_positive_quad(ofm_file, "OFM", "npc");
+ xseek_absolute(ofm_file, 4*(off_t)(tfm->nco - tfm->wlenheader), "OFM");
+ } else {
+ ERROR("Can't handle OFM files with level > 1");
+ }
+
+ return;
+}
+
+static void
+ofm_do_char_info_zero (FILE *tfm_file, struct tfm_font *tfm)
+{
+ uint32_t num_chars;
+
+ num_chars = tfm->ec - tfm->bc + 1;
+ if (num_chars != 0) {
+ uint32_t i;
+
+ tfm->width_index = NEW(num_chars, unsigned short);
+ tfm->height_index = NEW(num_chars, unsigned char);
+ tfm->depth_index = NEW(num_chars, unsigned char);
+ for (i = 0; i < num_chars; i++) {
+ tfm->width_index [i] = get_unsigned_pair(tfm_file);
+ tfm->height_index[i] = get_unsigned_byte(tfm_file);
+ tfm->depth_index [i] = get_unsigned_byte(tfm_file);
+ /* Ignore remaining quad */
+ skip_bytes(4, tfm_file);
+ }
+ }
+}
+
+static void
+ofm_do_char_info_one (FILE *tfm_file, struct tfm_font *tfm)
+{
+ uint32_t num_char_infos;
+ uint32_t num_chars;
+
+ num_char_infos = tfm->ncw / (3 + (tfm->npc / 2));
+ num_chars = tfm->ec - tfm ->bc + 1;
+
+ if (num_chars != 0) {
+ uint32_t i;
+ uint32_t char_infos_read;
+
+ tfm->width_index = NEW(num_chars, unsigned short);
+ tfm->height_index = NEW(num_chars, unsigned char);
+ tfm->depth_index = NEW(num_chars, unsigned char);
+ char_infos_read = 0;
+ for (i = 0; i < num_chars &&
+ char_infos_read < num_char_infos; i++) {
+ int repeats, j;
+
+ tfm->width_index [i] = get_unsigned_pair(tfm_file);
+ tfm->height_index[i] = get_unsigned_byte(tfm_file);
+ tfm->depth_index [i] = get_unsigned_byte(tfm_file);
+ /* Ignore next quad */
+ skip_bytes(4, tfm_file);
+ repeats = get_unsigned_pair(tfm_file);
+ /* Skip params */
+ for (j = 0; j < tfm->npc; j++) {
+ get_unsigned_pair(tfm_file);
+ }
+ /* Remove word padding if necessary */
+ if (ISEVEN(tfm->npc)){
+ get_unsigned_pair(tfm_file);
+ }
+ char_infos_read++;
+ if (i + repeats > num_chars) {
+ ERROR("Repeats causes number of characters to be exceeded.");
+ }
+ for (j = 0; j < repeats; j++) {
+ tfm->width_index [i+j+1] = tfm->width_index [i];
+ tfm->height_index[i+j+1] = tfm->height_index[i];
+ tfm->depth_index [i+j+1] = tfm->depth_index [i];
+ }
+ /* Skip ahead because we have already handled repeats */
+ i += repeats;
+ }
+ }
+}
+
+static void
+ofm_unpack_arrays (struct font_metric *fm,
+ struct tfm_font *tfm, uint32_t num_chars)
+{
+ int i;
+
+ fm->widths = NEW(tfm->bc + num_chars, fixword);
+ fm->heights = NEW(tfm->bc + num_chars, fixword);
+ fm->depths = NEW(tfm->bc + num_chars, fixword);
+ for (i = 0; i < num_chars; i++) {
+ fm->widths [tfm->bc + i] = tfm->width [ tfm->width_index [i] ];
+ fm->heights[tfm->bc + i] = tfm->height[ tfm->height_index[i] ];
+ fm->depths [tfm->bc + i] = tfm->depth [ tfm->depth_index [i] ];
+ }
+}
+
+static void
+read_ofm (struct font_metric *fm, FILE *ofm_file, off_t ofm_file_size)
+{
+ struct tfm_font tfm;
+
+ tfm_font_init(&tfm);
+
+ ofm_get_sizes(ofm_file, ofm_file_size, &tfm);
+
+ if (tfm.level < 0 || tfm.level > 1)
+ ERROR ("OFM level %d not supported.", tfm.level);
+
+ if (tfm.wlenheader > 0) {
+ tfm.header = NEW(tfm.wlenheader, fixword);
+ fread_fwords(tfm.header, tfm.wlenheader, ofm_file);
+ }
+ if (tfm.level == 0) {
+ ofm_do_char_info_zero(ofm_file, &tfm);
+ } else if (tfm.level == 1) {
+ ofm_do_char_info_one(ofm_file, &tfm);
+ }
+ if (tfm.nwidths > 0) {
+ tfm.width = NEW(tfm.nwidths, fixword);
+ fread_fwords(tfm.width, tfm.nwidths, ofm_file);
+ }
+ if (tfm.nheights > 0) {
+ tfm.height = NEW(tfm.nheights, fixword);
+ fread_fwords(tfm.height, tfm.nheights, ofm_file);
+ }
+ if (tfm.ndepths > 0) {
+ tfm.depth = NEW(tfm.ndepths, fixword);
+ fread_fwords(tfm.depth, tfm.ndepths, ofm_file);
+ }
+
+ ofm_unpack_arrays(fm, &tfm, tfm.ec - tfm.bc + 1);
+ tfm_unpack_header(fm, &tfm);
+ fm->firstchar = tfm.bc;
+ fm->lastchar = tfm.ec;
+ fm->source = SOURCE_TYPE_OFM;
+
+ tfm_font_clear(&tfm);
+
+ return;
+}
+#endif /* !WITHOUT_OMEGA */
+
+static void
+read_tfm (struct font_metric *fm, FILE *tfm_file, off_t tfm_file_size)
+{
+ struct tfm_font tfm;
+
+ tfm_font_init(&tfm);
+
+ tfm_get_sizes(tfm_file, tfm_file_size, &tfm);
+ fm->firstchar = tfm.bc;
+ fm->lastchar = tfm.ec;
+ if (tfm.wlenheader > 0) {
+ tfm.header = NEW(tfm.wlenheader, fixword);
+ fread_fwords(tfm.header, tfm.wlenheader, tfm_file);
+ }
+#ifndef WITHOUT_ASCII_PTEX
+ if (IS_JFM(tfm.id)) {
+ jfm_do_char_type_array(tfm_file, &tfm);
+ jfm_make_charmap(fm, &tfm);
+ fm->firstchar = 0;
+ fm->lastchar = 0x10FFFFL;
+ fm->fontdir = (tfm.id == JFMV_ID) ? FONT_DIR_VERT : FONT_DIR_HORIZ;
+ fm->source = SOURCE_TYPE_JFM;
+ }
+#endif /* !WITHOUT_ASCII_PTEX */
+ if (tfm.ec - tfm.bc + 1 > 0) {
+ tfm.char_info = NEW(tfm.ec - tfm.bc + 1, uint32_t);
+ fread_uquads(tfm.char_info, tfm.ec - tfm.bc + 1, tfm_file);
+ }
+ if (tfm.nwidths > 0) {
+ tfm.width = NEW(tfm.nwidths, fixword);
+ fread_fwords(tfm.width, tfm.nwidths, tfm_file);
+ }
+ if (tfm.nheights > 0) {
+ tfm.height = NEW(tfm.nheights, fixword);
+ fread_fwords(tfm.height, tfm.nheights, tfm_file);
+ }
+ if (tfm.ndepths > 0) {
+ tfm.depth = NEW(tfm.ndepths, fixword);
+ fread_fwords(tfm.depth, tfm.ndepths, tfm_file);
+ }
+ tfm_unpack_arrays(fm, &tfm);
+ tfm_unpack_header(fm, &tfm);
+
+ tfm_font_clear(&tfm);
+
+ return;
+}
+
+int
+tfm_open (const char *tfm_name, int must_exist)
+{
+ FILE *tfm_file;
+ int i, format = TFM_FORMAT;
+ off_t tfm_file_size;
+ char *file_name = NULL;
+
+ for (i = 0; i < numfms; i++) {
+ if (!strcmp(tfm_name, fms[i].tex_name))
+ return i;
+ }
+
+ /*
+ * The procedure to search tfm or ofm files:
+ * 1. Search tfm file with the given name with the must_exist flag unset.
+ * 2. Search ofm file with the given name with the must_exist flag unset.
+ * 3. If not found and must_exist flag is set, try again to search
+ * tfm file with the must_exist flag set.
+ * 4. If not found and must_exist flag is not set, return -1.
+ */
+
+
+ /*
+ * We first look for OFM and then TFM.
+ * The reason for this change is incompatibility introduced when dvipdfmx
+ * started to write correct glyph metrics to output PDF for CID fonts.
+ * I'll not explain this in detail... This change is mostly specific to
+ * Japanese support.
+ */
+#if 0
+ if ((file_name = kpse_find_file(tfm_name, kpse_tfm_format, 0))) {
+ format = TFM_FORMAT;
+ } else if ((file_name = kpse_find_file(tfm_name, kpse_ofm_format, 0))) {
+ format = OFM_FORMAT;
+ }
+#endif
+ {
+ char *ofm_name, *suffix;
+
+ suffix = strrchr(tfm_name, '.');
+ if (!suffix || (strcmp(suffix, ".tfm") != 0 &&
+ strcmp(suffix, ".ofm") != 0)) {
+ ofm_name = NEW(strlen(tfm_name) + strlen(".ofm") + 1, char);
+ strcpy(ofm_name, tfm_name);
+ strcat(ofm_name, ".ofm");
+ } else {
+ ofm_name = NULL;
+ }
+ if (ofm_name &&
+ (file_name = kpse_find_file(ofm_name, kpse_ofm_format, 0)) != NULL) {
+ format = OFM_FORMAT;
+ } else if ((file_name =
+ kpse_find_file(tfm_name, kpse_tfm_format, 0)) != NULL) {
+ format = TFM_FORMAT;
+ } else if ((file_name =
+ kpse_find_file(tfm_name, kpse_ofm_format, 0)) != NULL) {
+ format = OFM_FORMAT;
+ }
+ if (ofm_name)
+ RELEASE(ofm_name);
+ }
+
+ /*
+ * In case that must_exist is set, MiKTeX returns always non-NULL value
+ * even if the tfm file is not found.
+ */
+ if (file_name == NULL) {
+ if (must_exist) {
+ if ((file_name = kpse_find_file(tfm_name, kpse_tfm_format, 1)) != NULL)
+ format = TFM_FORMAT;
+ else {
+ ERROR("Unable to find TFM file \"%s\".", tfm_name);
+ }
+ } else {
+ return -1;
+ }
+ }
+
+ tfm_file = MFOPEN(file_name, FOPEN_RBIN_MODE);
+ if (!tfm_file) {
+ ERROR("Could not open specified TFM/OFM file \"%s\".", tfm_name);
+ }
+
+ if (dpx_conf.verbose_level > 0) {
+ if (format == TFM_FORMAT)
+ MESG("(TFM:%s", tfm_name);
+ else if (format == OFM_FORMAT)
+ MESG("(OFM:%s", tfm_name);
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%s]", file_name);
+ }
+
+ RELEASE(file_name);
+
+ tfm_file_size = xfile_size (tfm_file, "TFM/OFM");
+ if (tfm_file_size > 0x1ffffffff)
+ ERROR("TFM/OFM file size exceeds 33-bit");
+ if (tfm_file_size < 24) {
+ ERROR("TFM/OFM file too small to be a valid file.");
+ }
+
+ fms_need(numfms + 1);
+ fm_init(fms + numfms);
+
+#ifndef WITHOUT_OMEGA
+ if (format == OFM_FORMAT)
+ read_ofm(&fms[numfms], tfm_file, tfm_file_size);
+ else
+#endif /* !WITHOUT_OMEGA */
+ {
+ read_tfm(&fms[numfms], tfm_file, tfm_file_size);
+ }
+
+ MFCLOSE(tfm_file);
+
+ fms[numfms].tex_name = NEW(strlen(tfm_name)+1, char);
+ strcpy(fms[numfms].tex_name, tfm_name);
+
+ if (dpx_conf.verbose_level > 0)
+ MESG(")");
+
+ return numfms++;
+}
+
+void
+tfm_close_all (void)
+{
+ int i;
+
+ if (fms) {
+ for (i = 0; i < numfms; i++) {
+ fm_clear(&(fms[i]));
+ }
+ RELEASE(fms);
+ }
+}
+
+#define CHECK_ID(n) do {\
+ if ((n) < 0 || (n) >= numfms)\
+ ERROR("TFM: Invalid TFM ID: %d", (n));\
+} while (0)
+
+fixword
+tfm_get_fw_width (int font_id, int32_t ch)
+{
+ struct font_metric *fm;
+ int idx = 0;
+
+ CHECK_ID(font_id);
+
+ fm = &(fms[font_id]);
+ if (ch >= fm->firstchar && ch <= fm->lastchar) {
+ switch (fm->charmap.type) {
+ case MAPTYPE_CHAR:
+ idx = lookup_char(fm->charmap.data, ch);
+ if (idx < 0)
+ ERROR("Invalid char: %ld\n", ch);
+ break;
+ case MAPTYPE_RANGE:
+ idx = lookup_range(fm->charmap.data, ch);
+ if (idx < 0)
+ ERROR("Invalid char: %ld\n", ch);
+ break;
+ default:
+ idx = ch;
+ }
+ } else {
+ ERROR("Invalid char: %ld\n", ch);
+ }
+
+ return fm->widths[idx];
+}
+
+fixword
+tfm_get_fw_height (int font_id, int32_t ch)
+{
+ struct font_metric *fm;
+ int idx = 0;
+
+ CHECK_ID(font_id);
+
+ fm = &(fms[font_id]);
+ if (ch >= fm->firstchar && ch <= fm->lastchar) {
+ switch (fm->charmap.type) {
+ case MAPTYPE_CHAR:
+ idx = lookup_char(fm->charmap.data, ch);
+ if (idx < 0)
+ ERROR("Invalid char: %ld\n", ch);
+ break;
+ case MAPTYPE_RANGE:
+ idx = lookup_range(fm->charmap.data, ch);
+ if (idx < 0)
+ ERROR("Invalid char: %ld\n", ch);
+ break;
+ default:
+ idx = ch;
+ }
+ } else {
+ ERROR("Invalid char: %ld\n", ch);
+ }
+
+ return fm->heights[idx];
+}
+
+fixword
+tfm_get_fw_depth (int font_id, int32_t ch)
+{
+ struct font_metric *fm;
+ int idx = 0;
+
+ CHECK_ID(font_id);
+
+ fm = &(fms[font_id]);
+ if (ch >= fm->firstchar && ch <= fm->lastchar) {
+ switch (fm->charmap.type) {
+ case MAPTYPE_CHAR:
+ idx = lookup_char(fm->charmap.data, ch);
+ if (idx < 0)
+ ERROR("Invalid char: %ld\n", ch);
+ break;
+ case MAPTYPE_RANGE:
+ idx = lookup_range(fm->charmap.data, ch);
+ if (idx < 0)
+ ERROR("Invalid char: %ld\n", ch);
+ break;
+ default:
+ idx = ch;
+ }
+ } else {
+ ERROR("Invalid char: %ld\n", ch);
+ }
+
+ return fm->depths[idx];
+}
+
+
+/*
+ * tfm_get_width returns the width of the font
+ * as a (double) fraction of the design size.
+ */
+double
+tfm_get_width (int font_id, int32_t ch)
+{
+ return ((double) tfm_get_fw_width(font_id, ch)/FWBASE);
+}
+
+#if 0
+double
+tfm_get_height (int font_id, int32_t ch)
+{
+ return ((double) tfm_get_fw_height(font_id, ch)/FWBASE);
+}
+
+double
+tfm_get_depth (int font_id, Sint32_t ch)
+{
+ return ((double) tfm_get_fw_depth(font_id, ch)/FWBASE);
+}
+#endif
+
+/* tfm_string_xxx() do not work for OFM... */
+fixword
+tfm_string_width (int font_id, const unsigned char *s, unsigned len)
+{
+ fixword result = 0;
+ struct font_metric *fm;
+ unsigned i;
+
+ CHECK_ID(font_id);
+
+ fm = &(fms[font_id]);
+#ifndef WITHOUT_ASCII_PTEX
+ if (fm->source == SOURCE_TYPE_JFM) {
+ for (i = 0; i < len/2; i++) {
+ int32_t ch;
+
+ ch = (s[2*i] << 8)|s[2*i+1];
+ result += tfm_get_fw_width(font_id, ch);
+ }
+ } else
+#endif
+ for (i = 0; i < len; i++) {
+ result += tfm_get_fw_width(font_id, s[i]);
+ }
+
+ return result;
+}
+
+#if 0
+fixword
+tfm_string_depth (int font_id, const unsigned char *s, unsigned len)
+{
+ fixword result = 0;
+ struct font_metric *fm;
+ unsigned i;
+
+ CHECK_ID(font_id);
+
+ fm = &(fms[font_id]);
+#ifndef WITHOUT_ASCII_PTEX
+ if (fm->source == SOURCE_TYPE_JFM) {
+ for (i = 0; i < len/2; i++) {
+ int32_t ch;
+
+ ch = (s[2*i] << 8)|s[2*i+1];
+ result += tfm_get_fw_depth(font_id, ch);
+ }
+ } else
+#endif
+ for (i = 0; i < len; i++) {
+ result = MAX(result, tfm_get_fw_depth(font_id, s[i]));
+ }
+
+ return result;
+}
+
+fixword
+tfm_string_height (int font_id, const unsigned char *s, unsigned len)
+{
+ fixword result = 0;
+ struct font_metric *fm;
+ unsigned i;
+
+ CHECK_ID(font_id);
+
+ fm = &(fms[font_id]);
+#ifndef WITHOUT_ASCII_PTEX
+ if (fm->source == SOURCE_TYPE_JFM) {
+ for (i = 0; i < len/2; i++) {
+ int32_t ch;
+
+ ch = (s[2*i] << 8)|s[2*i+1];
+ result += tfm_get_fw_height(font_id, ch);
+ }
+ } else
+#endif
+ for (i = 0; i < len; i++) {
+ result = MAX(result, tfm_get_fw_height(font_id, s[i]));
+ }
+
+ return result;
+}
+#endif
+
+double
+tfm_get_design_size (int font_id)
+{
+ CHECK_ID(font_id);
+
+ return (double) (fms[font_id].designsize)/FWBASE*(72.0/72.27);
+}
+
+#if 0
+char *
+tfm_get_codingscheme (int font_id)
+{
+ CHECK_ID(font_id);
+
+ return fms[font_id].codingscheme;
+}
+
+#ifndef WITHOUT_ASCII_PTEX
+/* Vertical version of JFM */
+int
+tfm_is_vert (int font_id)
+{
+ CHECK_ID(font_id);
+
+ return (fms[font_id].fontdir == FONT_DIR_VERT) ? 1 : 0;
+}
+#else /* WITHOUT_ASCII_PTEX */
+int
+tfm_is_vert (int font_id)
+{
+ return 0;
+}
+#endif /* !WITHOUT_ASCII_PTEX */
+#endif
+
+#ifndef WITHOUT_ASCII_PTEX
+int
+tfm_is_jfm (int font_id)
+{
+ CHECK_ID(font_id);
+
+ return (fms[font_id].source == SOURCE_TYPE_JFM) ? 1 : 0;
+}
+#else /* WITHOUT_ASCII_PTEX */
+int
+tfm_is_jfm (int font_id)
+{
+ return 0;
+}
+#endif /* !WITHOUT_ASCII_PTEX */
+
+int
+tfm_exists (const char *tfm_name)
+{
+ char *fullname;
+
+ fullname = kpse_find_file(tfm_name, kpse_ofm_format, 0);
+ if (fullname) {
+ RELEASE(fullname);
+ return 1;
+ }
+ fullname = kpse_find_file(tfm_name, kpse_tfm_format, 0);
+ if (fullname) {
+ RELEASE(fullname);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/tfm.h b/Build/source/texk/dvipdfm-x/tfm.h
new file mode 100644
index 00000000000..1081c0f140b
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tfm.h
@@ -0,0 +1,57 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TFM_H_
+#define _TFM_H_
+
+#include "numbers.h"
+
+extern int tfm_open (const char * tex_name, int must_exist);
+extern void tfm_close_all (void);
+
+extern double tfm_get_width (int font_id, int32_t ch);
+#if 0
+extern double tfm_get_height (int font_id, int32_t ch);
+extern double tfm_get_depth (int font_id, int32_t ch);
+#endif
+
+extern fixword tfm_get_fw_width (int font_id, int32_t ch);
+extern fixword tfm_get_fw_height (int font_id, int32_t ch);
+extern fixword tfm_get_fw_depth (int font_id, int32_t ch);
+
+extern fixword tfm_string_width (int font_id, const unsigned char *s, unsigned len);
+#if 0
+extern fixword tfm_string_depth (int font_id, const unsigned char *s, unsigned len);
+extern fixword tfm_string_height (int font_id, const unsigned char *s, unsigned len);
+#endif
+
+/* From TFM header */
+extern double tfm_get_design_size (int font_id);
+#if 0
+extern char *tfm_get_codingscheme (int font_id);
+extern int tfm_is_vert (int font_id);
+#endif
+extern int tfm_is_jfm (int font_id);
+
+extern int tfm_exists (const char *tfm_name);
+
+#endif /* _TFM_H_ */
diff --git a/Build/source/texk/dvipdfm-x/truetype.c b/Build/source/texk/dvipdfm-x/truetype.c
new file mode 100644
index 00000000000..d9ba0ed6325
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/truetype.c
@@ -0,0 +1,994 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+
+#include "numbers.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxconf.h"
+#include "dpxfile.h"
+#include "dpxutil.h"
+
+#include "pdfobj.h"
+#include "pdfresource.h"
+#include "pdffont.h"
+
+#include "pdfencoding.h"
+#include "unicode.h"
+#include "agl.h"
+
+/* TrueType */
+#include "sfnt.h"
+#include "tt_cmap.h"
+#include "tt_table.h"
+#include "tt_glyf.h"
+#include "tt_post.h"
+#include "tt_gsub.h"
+#include "tt_aux.h"
+
+#include "truetype.h"
+
+/* Modifying this has no effect :P */
+#ifdef ENABLE_NOEMBED
+# undef ENABLE_NOEMBED
+#endif
+
+int
+pdf_font_open_truetype (pdf_font *font, const char *ident, int index, int encoding_id, int embedding)
+{
+ pdf_obj *fontdict, *descriptor;
+ sfnt *sfont;
+ FILE *fp = NULL;
+ int length, error = 0;
+
+ ASSERT(font);
+ ASSERT(ident);
+
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_DFONT);
+ if (!fp)
+ return -1;
+ sfont = dfont_open(fp, index);
+ } else {
+ sfont = sfnt_open(fp);
+ }
+
+ if (!sfont) {
+ WARN("Could not open TrueType font: %s", ident);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (sfont->type == SFNT_TYPE_TTC) {
+ ULONG offset;
+
+ offset = ttc_read_offset(sfont, index);
+ if (offset == 0) {
+ WARN("Invalid TTC index in %s.", ident);
+ error = -1;
+ } else {
+ error = sfnt_read_table_directory(sfont, offset);
+ }
+ } else {
+ error = sfnt_read_table_directory(sfont, sfont->offset);
+ }
+ if (error) {
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1; /* Silently */
+ }
+
+ /* Reading fontdict before checking fonttype conflicts with PKFONT
+ * because pdf_font_get_resource() always makes a dictionary.
+ */
+ fontdict = pdf_font_get_resource(font);
+ descriptor = pdf_font_get_descriptor(font);
+#ifndef ENABLE_NOEMBED
+ if (!embedding) {
+ WARN("No-embed option not supported for TrueType font: %s", ident);
+ embedding = 1;
+ font->flags &= ~PDF_FONT_FLAG_NOEMBED;
+ }
+#endif /* ENABLE_NOEMBED */
+
+ ASSERT( fontdict && descriptor );
+
+ {
+ char fontname[256];
+ int n;
+ pdf_obj *tmp;
+
+ memset(fontname, 0, 256);
+ length = tt_get_ps_fontname(sfont, fontname, 255);
+ if (length < 1) {
+ length = MIN(strlen(ident), 255);
+ memcpy(fontname, ident, length);
+ }
+ fontname[length] = '\0';
+ for (n = 0; n < length; n++) {
+ if (fontname[n] == 0) {
+ memmove(fontname + n, fontname + n + 1, length - n - 1);
+ }
+ }
+ if (strlen(fontname) == 0) {
+ WARN("Can't find valid fontname for \"%s\".", ident);
+ error = -1;
+ } else {
+ font->fontname = NEW(strlen(fontname)+1, char);
+ strcpy(font->fontname, fontname);
+ tmp = tt_get_fontdesc(sfont, &embedding, -1, 1, fontname);
+ if (!tmp) {
+ WARN("Could not obtain necessary font info: %s", ident);
+ error = -1;
+ } else {
+ ASSERT(pdf_obj_typeof(tmp) == PDF_DICT);
+ pdf_merge_dict(descriptor, tmp);
+ pdf_release_obj(tmp);
+ }
+ }
+ }
+ if (error) {
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (!embedding) {
+#ifndef ENABLE_NOEMBED
+ WARN("Font file=\"%s\" can't be embedded due to liscence restrictions.", ident);
+ error = -1;
+#else
+ if (encoding_id >= 0 && !pdf_encoding_is_predefined(encoding_id)) {
+ WARN("Custom encoding not allowed for non-embedded TrueType font: %s", ident);
+ error = -1;
+ } else {
+ /* There are basically no guarantee for font substitution
+ * can work with "symblic" fonts. At least all glyphs
+ * contained in the font must be identified; glyphs covers
+ * by this instance of font should contain glyphs only from
+ * Adobe Standard Latin Set. We allow non-embedded font
+ * only to predefined encodings for this reason. Note that
+ * "builtin" encoding means "MacRoman" here.
+ */
+ pdf_obj *tmp;
+ int flags;
+
+ font->flags |= PDF_FONT_FLAG_NOEMBED;
+ tmp = pdf_lookup_dict(descriptor, "Flags");
+ if (tmp && pdf_obj_typeof(tmp) == PDF_NUMBER) {
+ flags = (int) pdf_number_value(tmp);
+ flags &= (1 << 2); /* clear Symbolic */
+ flags |= (1 << 5); /* set Nonsymbolic */
+ pdf_add_dict(descriptor, pdf_new_name("Flags"), pdf_new_number(flags));
+ }
+ }
+#endif /* ENABLE_NOEMBED */
+ }
+
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+
+ if (!error) {
+ pdf_add_dict(fontdict,
+ pdf_new_name("Type"), pdf_new_name("Font"));
+ pdf_add_dict(fontdict,
+ pdf_new_name("Subtype"), pdf_new_name("TrueType"));
+ font->subtype = PDF_FONT_FONTTYPE_TRUETYPE;
+ }
+
+ return error;
+}
+
+/*
+ * The 'name' table should be preserved since it contains copyright
+ * information, but it might cause problem when there are invalid
+ * table entries (wrongly encoded text which is often the case in
+ * CJK fonts). Acrobat does not use 'name' table. Unicode TrueType
+ * fonts may have 10K bytes 'name' table...
+ *
+ * We preserve the 'OS/2' table too, since it contains the license
+ * information. PDF applications should use this table to decide
+ * whether the font is embedded only for the purpose of preview &
+ * printing. Otherwise, we must encrypt the document. Acrobat does
+ * not use 'OS/2' table, though...
+ */
+static struct
+{
+ const char *name;
+ int must_exist;
+} required_table[] = {
+ {"OS/2", 0}, {"head", 1}, {"hhea", 1}, {"loca", 1}, {"maxp", 1},
+ {"name", 1}, {"glyf", 1}, {"hmtx", 1}, {"fpgm", 0}, {"cvt ", 0},
+ {"prep", 0}, {"cmap", 1}, {NULL, 0}
+};
+
+static void
+do_widths (pdf_font *font, double *widths)
+{
+ pdf_obj *fontdict;
+ pdf_obj *array;
+ int code, firstchar, lastchar;
+ char *usedchars;
+
+ fontdict = font->resource;
+ usedchars = font->usedchars;
+
+ for (firstchar = 255, lastchar = 0, code = 0; code < 256; code++) {
+ if (usedchars[code]) {
+ if (code < firstchar) firstchar = code;
+ if (code > lastchar) lastchar = code;
+ }
+ }
+ if (firstchar > lastchar) {
+ WARN("No glyphs actually used???");
+ return;
+ }
+
+ pdf_check_tfm_widths(font->ident, widths, firstchar, lastchar, usedchars);
+
+ array = pdf_new_array();
+ for (code = firstchar; code <= lastchar; code++) {
+ if (usedchars[code]) {
+ pdf_add_array(array, pdf_new_number(ROUND(widths[code], 0.1)));
+ } else {
+ pdf_add_array(array, pdf_new_number(0.0));
+ }
+ }
+ if (pdf_array_length(array) > 0) {
+ pdf_add_dict(fontdict, pdf_new_name("Widths"), pdf_ref_obj(array));
+ }
+ pdf_release_obj(array);
+
+ pdf_add_dict(fontdict,
+ pdf_new_name("FirstChar"), pdf_new_number(firstchar));
+ pdf_add_dict(fontdict,
+ pdf_new_name("LastChar"), pdf_new_number(lastchar));
+
+ return;
+}
+
+#define PDFUNIT(v) ((double) (ROUND(1000.0*(v)/(glyphs->emsize), 1)))
+
+/*
+ * There are several issues in TrueType font support in PDF.
+ * How PDF viewers select TrueType cmap table is not so clear.
+ * Most reliable way seem to reencode font and sort glyphs as
+ * charcode == gid and to use Mac-Roman format 0 subtable.
+ * It does not work with encodings that uses full 256 range since
+ * GID = 0 is reserved for .notdef, so GID = 256 is not accessible.
+ */
+static int
+do_builtin_encoding (pdf_font *font, const char *usedchars, sfnt *sfont)
+{
+ struct tt_glyphs *glyphs;
+ char *cmap_table;
+ tt_cmap *ttcm;
+ USHORT gid, idx;
+ int code, count;
+ double widths[256];
+
+ ttcm = tt_cmap_read(sfont, TT_MAC, TT_MAC_ROMAN);
+ if (!ttcm) {
+ WARN("Could not read Mac-Roman TrueType cmap table...");
+ return -1;
+ }
+
+ cmap_table = NEW(274, char);
+ memset(cmap_table, 0, 274);
+ sfnt_put_ushort(cmap_table, 0); /* Version */
+ sfnt_put_ushort(cmap_table+2, 1); /* Number of subtables */
+ sfnt_put_ushort(cmap_table+4, TT_MAC); /* Platform ID */
+ sfnt_put_ushort(cmap_table+6, TT_MAC_ROMAN); /* Encoding ID */
+ sfnt_put_ulong (cmap_table+8, 12); /* Offset */
+ sfnt_put_ushort(cmap_table+12, 0); /* Format */
+ sfnt_put_ushort(cmap_table+14, 262); /* Length */
+ sfnt_put_ushort(cmap_table+16, 0); /* Language */
+
+ glyphs = tt_build_init();
+
+ if (dpx_conf.verbose_level > 2)
+ MESG("[glyphs:/.notdef");
+
+ count = 1; /* .notdef */
+ for (code = 0; code < 256; code++) {
+ if (!usedchars[code])
+ continue;
+
+ if (dpx_conf.verbose_level > 2)
+ MESG("/.c0x%02x", code);
+
+ gid = tt_cmap_lookup(ttcm, code);
+ if (gid == 0) {
+ WARN("Glyph for character code=0x%02x missing in font font-file=\"%s\".",
+ code, font->filename);
+ idx = 0;
+ } else {
+ idx = tt_find_glyph(glyphs, gid);
+ if (idx == 0)
+ idx = tt_add_glyph(glyphs, (USHORT)gid, (USHORT)count); /* count returned. */
+ }
+ cmap_table[18+code] = idx & 0xff; /* bug here */
+ count++;
+ }
+ tt_cmap_release(ttcm);
+
+ if (dpx_conf.verbose_level > 2)
+ MESG("]");
+
+ if (tt_build_tables(sfont, glyphs) < 0) {
+ WARN("Packing TrueType font into SFNT failed!");
+ tt_build_finish(glyphs);
+ RELEASE(cmap_table);
+ return -1;
+ }
+
+ for (code = 0; code < 256; code++) {
+ if (usedchars[code]) {
+ idx = tt_get_index(glyphs, (USHORT) cmap_table[18+code]);
+ widths[code] = PDFUNIT(glyphs->gd[idx].advw);
+ } else {
+ widths[code] = 0.0;
+ }
+ }
+ do_widths(font, widths);
+
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%d glyphs]", glyphs->num_glyphs);
+
+ tt_build_finish(glyphs);
+
+ sfnt_set_table(sfont, "cmap", cmap_table, 274);
+
+ return 0;
+}
+
+/* Order of lookup should be
+ * post, unicode+otl
+ */
+struct glyph_mapper
+{
+ tt_cmap *codetogid;
+ otl_gsub *gsub;
+ sfnt *sfont;
+ struct tt_post_table *nametogid;
+};
+
+
+/* WARNING: This modifies glyphname itself */
+static int
+agl_decompose_glyphname (char *glyphname, char **nptrs, int size, char **suffix)
+{
+ char *q, *p = glyphname;
+ int n;
+
+ q = strchr(p, '.'); /* chop every thing after *first* dot */
+ if (!q)
+ *suffix = NULL;
+ else {
+ *q = '\0'; q++;
+ *suffix = q;
+ }
+
+ nptrs[0] = p;
+ for (n = 1; p && *p; n++) {
+ p = strchr(p, '_');
+ if (!p || p[1] == '\0')
+ break;
+ if (n >= size)
+ ERROR("Uh ah..."); /* _FIXME_ */
+ *p = '\0'; p++;
+ nptrs[n] = p;
+ }
+
+ return n;
+}
+
+static int
+select_gsub (const char *feat, struct glyph_mapper *gm)
+{
+ int idx, error = 0;
+
+ if (!feat || *feat == 0 || !gm || !gm->gsub)
+ return -1;
+
+ /* First treat as is */
+ idx = otl_gsub_select(gm->gsub, "*", "*", feat);
+ if (idx >= 0)
+ return 0;
+
+ if (dpx_conf.verbose_level > 1)
+ MESG("\ntrutype>> Try loading OTL GSUB for \"*.*.%s\"...", feat);
+ error = otl_gsub_add_feat(gm->gsub, "*", "*", feat, gm->sfont);
+ if (!error) {
+ idx = otl_gsub_select(gm->gsub, "*", "*", feat);
+ return (idx >= 0 ? 0 : -1);
+ }
+
+ return -1;
+}
+
+static int findparanoiac (const char *glyph_name, USHORT *gid, struct glyph_mapper *gm);
+static int resolve_glyph (const char *glyph_name, USHORT *gid, struct glyph_mapper *gm);
+
+/* Apply GSUB. This is a bit tricky... */
+static int
+selectglyph (USHORT in, const char *suffix, struct glyph_mapper *gm, USHORT *out)
+{
+ char *s, *q, t[5];
+ const char *r;
+ int n, error = 0;
+
+ ASSERT(suffix && gm && out);
+ ASSERT(suffix && *suffix != 0);
+
+ s = NEW(strlen(suffix) + 1, char);
+ strcpy(s, suffix);
+
+ /* First try converting suffix to feature tag.
+ * agl.c currently only knows less ambiguos cases;
+ * e.g., 'sc', 'superior', etc.
+ */
+ r = agl_suffix_to_otltag(s);
+ if (r) { /* We found feature tag for 'suffix'. */
+ error = select_gsub(r, gm); /* no fallback for this */
+ if (!error)
+ error = otl_gsub_apply(gm->gsub, &in);
+ } else { /* 'suffix' may represent feature tag. */
+ /* Try loading GSUB only when length of 'suffix' is less
+ * than or equal to 4. tt_gsub give a warning otherwise.
+ */
+ if (strlen(s) > 4)
+ error = -1; /* Uh */
+ else if (strlen(s) == 4)
+ error = select_gsub(s, gm);
+ else { /* less than 4. pad ' '. */
+ memset(t, ' ', 4); t[4] = '\0';
+ memcpy(t, s, strlen(s));
+ error = select_gsub(t, gm);
+ }
+ if (!error) /* 'suffix' represents feature tag. */
+ error = otl_gsub_apply(gm->gsub, &in);
+ else { /* other case: alt1, nalt10... (alternates) */
+ for (q = s + strlen(s) - 1; q > s && *q >= '0' && *q <= '9'; q--);
+ if (q == s)
+ error = -1;
+ else { /* starting at 1 */
+ n = atoi(q + 1) - 1; q[1] = '\0';
+ if (strlen(s) > 4)
+ error = -1;
+ else { /* This may be alternate substitution. */
+ memset(t, ' ', 4); t[4] = '\0';
+ memcpy(t, s, strlen(s));
+ error = select_gsub(s, gm);
+ if (!error)
+ error = otl_gsub_apply_alt(gm->gsub, (USHORT)n, (USHORT *)&in);
+ }
+ }
+ }
+ }
+ RELEASE(s);
+
+ *out = in;
+ return error;
+}
+
+
+/* Compose glyphs via ligature substitution. */
+static int
+composeglyph (USHORT *glyphs, int n_glyphs,
+ const char *feat, struct glyph_mapper *gm, USHORT *gid)
+{
+ int error = 0;
+ char t[5] = {' ', ' ', ' ', ' ', 0};
+
+ ASSERT(glyphs && n_glyphs > 0 && gm && gid);
+
+ if (!feat || feat[0] == '\0') /* meaning "Unknown" */
+ error = select_gsub("(?lig|lig?|?cmp|cmp?|frac|afrc)", gm);
+ else {
+ if (strlen(feat) > 4)
+ error = -1;
+ else {
+ memcpy(t, feat, strlen(feat));
+ error = select_gsub(t, gm);
+ }
+ }
+
+ if (!error)
+ error = otl_gsub_apply_lig(gm->gsub, (USHORT *)glyphs, (USHORT)n_glyphs,
+ (USHORT *)gid);
+
+ return error;
+}
+
+/* This may be called by findparanoiac(). */
+static int
+composeuchar (int32_t *unicodes, int n_unicodes,
+ const char *feat, struct glyph_mapper *gm, USHORT *gid)
+{
+ USHORT *gids;
+ int i, error = 0;
+
+ if (!gm->codetogid)
+ return -1;
+
+ gids = NEW(n_unicodes, USHORT);
+ for (i = 0;
+ !error && i < n_unicodes; i++) {
+ gids[i] = tt_cmap_lookup(gm->codetogid, unicodes[i]);
+ error = (gids[i] == 0) ? -1 : 0;
+ }
+
+ if (!error)
+ error = composeglyph(gids, n_unicodes, feat, gm, gid);
+
+ RELEASE(gids);
+
+ return error;
+}
+
+/* Search 'post' table. */
+static int
+findposttable (const char *glyph_name, USHORT *gid, struct glyph_mapper *gm)
+{
+ if (!gm->nametogid)
+ return -1;
+
+ *gid = tt_lookup_post_table(gm->nametogid, glyph_name);
+#if 0
+ if (dpx_conf.verbose_level > 1)
+ {
+ if (*gid > 0)
+ MESG("%s =post=> 0x%04X\n", glyph_name, *gid);
+ }
+#endif
+
+ return (*gid == 0 ? -1 : 0);
+}
+
+/* This is wrong. We must care about '.'. */
+#define is_comp(n) (strchr((n), '_') != NULL)
+
+/* Glyph names are concatinated with '_'. */
+static int
+findcomposite (const char *glyphname, USHORT *gid, struct glyph_mapper *gm)
+{
+ char *gname, *suffix = NULL;
+ USHORT gids[32];
+ char *nptrs[32];
+ int i, n_comp;
+ int error = 0;
+
+ error = findposttable(glyphname, gid, gm);
+ if (!error)
+ return 0;
+
+ gname = NEW(strlen(glyphname) + 1, char);
+ strcpy(gname, glyphname);
+
+ memset(gids, 0, 32 * sizeof(USHORT));
+ n_comp = agl_decompose_glyphname(gname, nptrs, 32, &suffix);
+ for (error = 0, i = 0; !error && i < n_comp; i++) {
+ error = resolve_glyph(nptrs[i], &gids[i], gm);
+ if (error)
+ WARN("Could not resolve glyph \"%s\" (%dth component of glyph \"%s\").",
+ nptrs[i], i, glyphname);
+ }
+
+ if (!error) {
+ if (suffix &&
+ (!strcmp(suffix, "liga") || !strcmp(suffix, "dlig") ||
+ !strcmp(suffix, "hlig") || !strcmp(suffix, "frac") ||
+ !strcmp(suffix, "ccmp") || !strcmp(suffix, "afrc")
+ )
+ ) {
+ error = composeglyph(gids, n_comp, suffix, gm, gid);
+ } else { /* first try composing glyph */
+ error = composeglyph(gids, n_comp, NULL, gm, gid);
+ if (!error && suffix) /* a_b_c.vert */
+ error = selectglyph(*gid, suffix, gm, gid);
+ }
+ }
+ RELEASE(gname);
+
+ return error;
+}
+
+/* glyphname should not have suffix here */
+static int
+findparanoiac (const char *glyphname, USHORT *gid, struct glyph_mapper *gm)
+{
+ agl_name *agln;
+ USHORT idx = 0U;
+ int error = 0;
+
+ agln = agl_lookup_list(glyphname);
+ while (agln && idx == 0) {
+ if (agln->suffix) {
+ error = findparanoiac(agln->name, &idx, gm);
+ if (error)
+ return error;
+
+ error = selectglyph(idx, agln->suffix, gm, &idx);
+ if (error) {
+ WARN("Variant \"%s\" for glyph \"%s\" might not be found.",
+ agln->suffix, agln->name);
+ WARN("Using glyph name without suffix instead...");
+ error = 0; /* ignore */
+ }
+ } else {
+ if (agln->n_components == 1)
+ idx = tt_cmap_lookup(gm->codetogid, agln->unicodes[0]);
+ else if (agln->n_components > 1) {
+ if (dpx_conf.verbose_level >= 0) /* give warning */
+ WARN("Glyph \"%s\" looks like a composite glyph...",
+ agln->name);
+ error = composeuchar(agln->unicodes, agln->n_components, NULL, gm, &idx);
+ if (dpx_conf.verbose_level >= 0) {
+ if (error)
+ WARN("Not found...");
+ else {
+ int _i, _n = 0;
+ char *_p, _buf[256];
+ WARN(">> Composite glyph glyph-name=\"%s\" found at glyph-id=\"%u\".",
+ agln->name, idx);
+ for (_p = _buf, _i = 0; _i < agln->n_components && _n < 245; _i++) {
+ _p[_n++] = _i == 0 ? '<' : ' ';
+ if (agln->unicodes[_i] >= 0x10000)
+ _n += sprintf(_p+_n, "U+%06X", agln->unicodes[_i]);
+ else
+ _n += sprintf(_p+_n, "U+%04X", agln->unicodes[_i]);
+ _p[_n++] = _i == agln->n_components - 1 ? '>' : ',';
+ }
+ _p[_n++] = '\0';
+ WARN(">> Input Unicode seq.=\"%s\" ==> glyph-id=\"%u\" in font-file=\"_please_try_-v_\".", _buf, idx);
+ }
+ }
+ } else ASSERT(0); /* Boooo */
+ }
+ agln = agln->alternate;
+ }
+
+ *gid = idx;
+ return (idx == 0 ? -1 : 0);
+}
+
+static int
+resolve_glyph (const char *glyphname, USHORT *gid, struct glyph_mapper *gm)
+{
+ int error = 0;
+ char *name, *suffix = NULL;
+ int32_t ucv;
+
+ ASSERT(glyphname);
+
+ /*
+ * First we try glyph name to GID mapping using post table if post table
+ * is available. If post table is not available or glyph is not listed
+ * in the post table, then we try Unicode if Windows-Unicode TrueType
+ * cmap is available.
+ */
+ error = findposttable(glyphname, gid, gm);
+ if (!error)
+ return 0;
+
+ if (!gm->codetogid)
+ return -1;
+
+ name = agl_chop_suffix(glyphname, &suffix);
+ if (!name) /* .notdef, .foo */
+ error = -1;
+ else if (agl_name_is_unicode(name)) {
+ ucv = agl_name_convert_unicode(name);
+ *gid = tt_cmap_lookup(gm->codetogid, ucv);
+ error = (*gid == 0) ? -1 : 0;
+ } else {
+ error = findparanoiac(name, gid, gm);
+ }
+ if (!error && suffix) {
+ error = selectglyph(*gid, suffix, gm, gid);
+ if (error) {
+ WARN("Variant \"%s\" for glyph \"%s\" might not be found.",
+ suffix, name);
+ WARN("Using glyph name without suffix instead...");
+ error = 0; /* ignore */
+ }
+ }
+ if (suffix)
+ RELEASE(suffix);
+ if (name)
+ RELEASE(name);
+
+ return error;
+}
+
+/* Things are complicated. We still need to use PostScript
+ * glyph names. But OpenType fonts may not have PS name to
+ * glyph mapping. We use Unicode plus OTL GSUB for finding
+ * glyphs in this case.
+ */
+static int
+setup_glyph_mapper (struct glyph_mapper *gm, sfnt *sfont)
+{
+ gm->sfont = sfont;
+ gm->nametogid = tt_read_post_table(sfont);
+ gm->codetogid = tt_cmap_read(sfont, TT_WIN, TT_WIN_UCS4);
+ if (!gm->codetogid)
+ gm->codetogid = tt_cmap_read(sfont, TT_WIN, TT_WIN_UNICODE);
+
+ if (!gm->nametogid && !gm->codetogid)
+ return -1;
+
+ gm->gsub = otl_gsub_new();
+
+ return 0;
+}
+
+static void
+clean_glyph_mapper (struct glyph_mapper *gm)
+{
+ if (gm->gsub)
+ otl_gsub_release(gm->gsub);
+ if (gm->codetogid)
+ tt_cmap_release (gm->codetogid);
+ if (gm->nametogid)
+ tt_release_post_table(gm->nametogid);
+
+ gm->gsub = NULL;
+ gm->codetogid = NULL;
+ gm->nametogid = NULL;
+ gm->sfont = NULL;
+
+ return;
+}
+
+static int
+do_custom_encoding (pdf_font *font,
+ char **encoding, const char *usedchars, sfnt *sfont)
+{
+ struct tt_glyphs *glyphs;
+ char *cmap_table;
+ int code, count;
+ double widths[256];
+ struct glyph_mapper gm;
+ USHORT idx, gid;
+ int error = 0;
+
+ ASSERT(font && encoding && usedchars && sfont);
+
+ error = setup_glyph_mapper(&gm, sfont);
+ if (error) {
+ WARN("No post table nor Unicode cmap found in font: %s", font->filename);
+ WARN(">> I can't find glyphs without this!");
+ return -1;
+ }
+
+ cmap_table = NEW(274, char);
+ memset(cmap_table, 0, 274);
+ sfnt_put_ushort(cmap_table, 0); /* Version */
+ sfnt_put_ushort(cmap_table+2, 1); /* Number of subtables */
+ sfnt_put_ushort(cmap_table+4, TT_MAC); /* Platform ID */
+ sfnt_put_ushort(cmap_table+6, TT_MAC_ROMAN); /* Encoding ID */
+ sfnt_put_ulong (cmap_table+8, 12); /* Offset */
+ sfnt_put_ushort(cmap_table+12, 0); /* Format */
+ sfnt_put_ushort(cmap_table+14, 262); /* Length */
+ sfnt_put_ushort(cmap_table+16, 0); /* Language */
+
+ glyphs = tt_build_init();
+
+ count = 1; /* +1 for .notdef */
+ for (code = 0; code < 256; code++) {
+ if (!usedchars[code])
+ continue;
+
+ if (!encoding[code] || !strcmp(encoding[code], ".notdef")) {
+ WARN("Character code=\"0x%02X\" mapped to \".notdef\" glyph used in font font-file=\"%s\"",
+ code, font->filename);
+ WARN(">> Maybe incorrect encoding specified?");
+ idx = 0;
+ } else {
+ if (is_comp(encoding[code]))
+ error = findcomposite(encoding[code], &gid, &gm);
+ else
+ error = resolve_glyph(encoding[code], &gid, &gm);
+
+ /*
+ * Older versions of gs had problem with glyphs (other than .notdef)
+ * mapped to gid = 0.
+ */
+ if (error) {
+ WARN("Glyph \"%s\" not available in font \"%s\".",
+ encoding[code], font->filename);
+ } else {
+ if (dpx_conf.verbose_level > 1)
+ MESG("truetype>> Glyph glyph-name=\"%s\" found at glyph-id=\"%u\".\n", encoding[code], gid);
+ }
+ idx = tt_find_glyph(glyphs, gid);
+ if (idx == 0) {
+ idx = tt_add_glyph(glyphs, (USHORT)gid, (USHORT)count); /* count returned. */
+ count++;
+ }
+ }
+ cmap_table[18 + code] = idx & 0xff; /* bug here */
+ }
+ clean_glyph_mapper(&gm);
+
+ if (tt_build_tables(sfont, glyphs) < 0) {
+ WARN("Packing TrueType font into SFNT file faild..."); /* _FIXME_: wrong message */
+ tt_build_finish(glyphs);
+ RELEASE(cmap_table);
+ return -1;
+ }
+
+ for (code = 0; code < 256; code++) {
+ if (usedchars[code]) {
+ idx = tt_get_index(glyphs, (USHORT) cmap_table[18+code]);
+ widths[code] = PDFUNIT(glyphs->gd[idx].advw);
+ } else {
+ widths[code] = 0.0;
+ }
+ }
+ do_widths(font, widths);
+
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%d glyphs]", glyphs->num_glyphs);
+
+ tt_build_finish(glyphs);
+
+ sfnt_set_table(sfont, "cmap", cmap_table, 274);
+
+ return 0;
+}
+
+int
+pdf_font_load_truetype (pdf_font *font)
+{
+ pdf_obj *descriptor = font->descriptor;
+ char *ident = font->filename;
+ int encoding_id = font->encoding_id;
+ char *usedchars = font->usedchars;
+#ifdef ENABLE_NOEMBED
+ int embedding = font->flags & PDF_FONT_FLAG_NOEMBED ? 0 : 1;
+#endif /* ENABLE_NOEMBED */
+ int index = font->index;
+ char **enc_vec;
+ pdf_obj *fontfile;
+ FILE *fp = NULL;
+ sfnt *sfont;
+ int i, error = 0;
+
+ if (!font->reference)
+ return 0;
+
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_DFONT);
+ if (!fp) ERROR("Unable to open TrueType/dfont font file: %s", ident); /* Should find *truetype* here */
+ sfont = dfont_open(fp, index);
+ } else {
+ sfont = sfnt_open(fp);
+ }
+
+ if (!sfont) {
+ ERROR("Unable to open TrueType/dfont file: %s", ident);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ } else if (sfont->type != SFNT_TYPE_TRUETYPE &&
+ sfont->type != SFNT_TYPE_TTC &&
+ sfont->type != SFNT_TYPE_DFONT) {
+ ERROR("Font \"%s\" not a TrueType/dfont font?", ident);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (sfont->type == SFNT_TYPE_TTC) {
+ ULONG offset;
+ offset = ttc_read_offset(sfont, index);
+ if (offset == 0) ERROR("Invalid TTC index in %s.", ident);
+ error = sfnt_read_table_directory(sfont, offset);
+ } else {
+ error = sfnt_read_table_directory(sfont, sfont->offset);
+ }
+
+ if (error) {
+ ERROR("Reading SFND table dir failed for font-file=\"%s\"... Not a TrueType font?", ident);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ /*
+ * Create new TrueType cmap table with MacRoman encoding.
+ */
+ if (encoding_id < 0)
+ error = do_builtin_encoding(font, usedchars, sfont);
+ else {
+ enc_vec = pdf_encoding_get_encoding(encoding_id);
+ error = do_custom_encoding(font, enc_vec, usedchars, sfont);
+ }
+ if (error) {
+ ERROR("Error occured while creating font subfont for \"%s\"", ident);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+#if ENABLE_NOEMBED
+ if (!embedding) {
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return 0;
+ }
+#endif /* ENABLE_NOEMBED */
+
+ /*
+ * TODO: post table?
+ */
+
+ for (i = 0; required_table[i].name != NULL; i++) {
+ if (sfnt_require_table(sfont,
+ required_table[i].name,
+ required_table[i].must_exist) < 0) {
+ ERROR("Required TrueType table \"%s\" does not exist in font: %s",
+ required_table[i].name, ident);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ }
+
+ /*
+ * FontFile2
+ */
+ fontfile = sfnt_create_FontFile_stream(sfont);
+ if (!fontfile)
+ ERROR("Could not created FontFile stream for \"%s\".", ident);
+
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%ld bytes]", pdf_stream_length(fontfile));
+
+ pdf_add_dict(descriptor,
+ pdf_new_name("FontFile2"), pdf_ref_obj(fontfile)); /* XXX */
+ pdf_release_obj(fontfile);
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/truetype.h b/Build/source/texk/dvipdfm-x/truetype.h
new file mode 100644
index 00000000000..fa5464c1834
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/truetype.h
@@ -0,0 +1,31 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TRUETYPE_H_
+#define _TRUETYPE_H_
+
+#include "pdffont.h"
+
+extern int pdf_font_open_truetype (pdf_font *font, const char *ident, int index, int encoding_id, int embedding);
+extern int pdf_font_load_truetype (pdf_font *font);
+
+#endif /* _TRUETYPE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/tt_aux.c b/Build/source/texk/dvipdfm-x/tt_aux.c
new file mode 100644
index 00000000000..2d4b352cff7
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_aux.c
@@ -0,0 +1,281 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "numbers.h"
+#include "dpxconf.h"
+
+#include "pdfobj.h"
+
+#include "sfnt.h"
+#include "tt_table.h"
+#include "tt_post.h"
+#include "tt_aux.h"
+
+ULONG ttc_read_offset (sfnt *sfont, ULONG ttc_idx)
+{
+ ULONG offset = 0, num_dirs = 0;
+
+ if (sfont == NULL || sfont->stream == NULL)
+ ERROR("file not opened");
+
+ if (sfont->type != SFNT_TYPE_TTC)
+ ERROR("ttc_read_offset(): invalid font type");
+
+ sfnt_seek_set (sfont, 4); /* skip version tag */
+
+ /* version = */ sfnt_get_ulong(sfont);
+ num_dirs = sfnt_get_ulong(sfont);
+ if (ttc_idx > num_dirs - 1)
+ ERROR("Invalid TTC index number");
+
+ sfnt_seek_set (sfont, 12 + ttc_idx * 4);
+ offset = sfnt_get_ulong (sfont);
+
+ return offset;
+}
+
+/*
+ Build FontDescriptor (except FontName) from TrueType tables:
+
+ Most information found in FontDescriptor is used only when automatic
+ font substitution is needed. (in the case of missing/broken font data)
+ Some PDF viewers may ignore embedded TrueType glyph data. Especially,
+ any embedded TrueType data for CID-keyed (CIDFontType 2) font is ignored
+ by PDF viewers that only support PDF versions 1.2 or earlier.
+
+ We use those tables to obtain various values of FontDescriptor.
+
+ head: required
+
+ xMin, xMax, yMin, yMax - FontBBox
+ unitsPerEm - conversion to PDF unit (points). see PDFUNIT bellow.
+ The head table must exist in any TrueType font.
+
+ hhea: required
+
+ When the OS/2 table (Windows and OS/2 only) is not available,
+ Ascender and Descender values can be used to estimate Ascent
+ and Descent. The hhea table is required for all TrueType fonts.
+ MaxWidth can be obtained from this table.
+
+ OS/2: required for Windows and OS/2 TrueType, and OpenType
+
+ fsType - liscensing information
+ sCapHeight - CapHeight (version 2 only)
+
+ The sCapHeight is only available in newer TrueType fonts which has
+ version 2 OS/2 table and generally not available. Instead, we can
+ use height of uppercase letter `H'. But we don't use it, we simply
+ use Ascent value.
+
+ sTypoAscender, sTypoDescender - Ascent and Descent
+ usWeightClass - roughly estimate StemV.
+
+ Estimation is based on the following expression:
+
+ stemv = (os2->usWeightClass/65)*(os2->usWeightClass/65)+50
+
+ . I've found this expression in some Adobe document (lost). We use
+ this expression also, otherwise, we must analyze glyph data.
+
+ xAvgCharWidth - AvgWidth (optional)
+ sFamilyClass - Flags
+ sFamilyClass and panose - Panose in Style dictionary (optional)
+
+ post: required
+
+ italicAngle - ItalicAngle
+
+*/
+
+
+#ifndef PDFUNIT
+#define PDFUNIT(v) (ROUND((1000.0*(v))/(head->unitsPerEm),1))
+#endif
+
+/* Flags: should not come here */
+#define FIXEDWIDTH (1 << 0) /* Fixed-width font */
+#define SERIF (1 << 1) /* Serif font */
+#define SYMBOLIC (1 << 2) /* Symbolic font */
+#define SCRIPT (1 << 3) /* Script font */
+#define STANDARD (1 << 5) /* Uses the Adobe Standard Character Set */
+#define ITALIC (1 << 6) /* Italic */
+#define ALLCAP (1 << 16) /* All-cap font */
+#define SMALLCAP (1 << 17) /* Small-cap font */
+#define FORCEBOLD (1 << 18) /* Force bold at small text sizes */
+pdf_obj *tt_get_fontdesc (sfnt *sfont, int *embed, int stemv, int type, const char* fontname)
+{
+ pdf_obj *descriptor = NULL;
+ pdf_obj *bbox = NULL;
+ int flag = SYMBOLIC;
+ /* TrueType tables */
+ struct tt_head_table *head;
+ struct tt_os2__table *os2;
+ struct tt_post_table *post;
+
+ if (!sfont) {
+ ERROR("font file not opened");
+ }
+
+ os2 = tt_read_os2__table(sfont);
+ head = tt_read_head_table(sfont);
+ post = tt_read_post_table(sfont);
+ if (!post) {
+ if (os2)
+ RELEASE(os2);
+ RELEASE(head);
+ return NULL;
+ }
+
+ descriptor = pdf_new_dict();
+ pdf_add_dict (descriptor,
+ pdf_new_name ("Type"),
+ pdf_new_name ("FontDescriptor"));
+
+ if (*embed && os2) {
+ /*
+ License:
+
+ "Preview & Print embedding" (0x004) requires the document containing
+ Preview & Print font to be opened in read-only mode. However, licensing
+ information are lost when fonts are embedded in PDF document and
+ the only way to make the PDF document "read-only" is to encrypt it.
+ But we have no support for encryption yet. We do not embed any fonts
+ with "Preview & Print embedding" setting.
+
+ 2001/11/22: Changed to allow `Preview & Print' only fonts embedding
+
+ 2006/04/19: Added support for always_embed option
+ */
+ if (os2->fsType == 0x0000 || (os2->fsType & 0x0008)) {
+ /* the least restrictive license granted takes precedence. */
+ *embed = 1;
+ } else if (os2->fsType & 0x0004) {
+ if (dpx_conf.verbose_level > 0)
+ WARN("Font \"%s\" permits \"Preview & Print\" embedding only **\n", fontname);
+ *embed = 1;
+ } else {
+ if (dpx_conf.ignore_font_license) {
+ if (dpx_conf.verbose_level > 0)
+ WARN("Font \"%s\" may be subject to embedding restrictions **\n", fontname);
+ *embed = 1;
+ }
+ else {
+ if (dpx_conf.verbose_level > 0)
+ WARN("Embedding of font \"%s\" disabled due to license restrictions", fontname);
+ *embed = 0;
+ }
+ }
+ }
+
+ if (os2) {
+ pdf_add_dict (descriptor,
+ pdf_new_name ("Ascent"),
+ pdf_new_number (PDFUNIT(os2->sTypoAscender)));
+ pdf_add_dict (descriptor,
+ pdf_new_name ("Descent"),
+ pdf_new_number (PDFUNIT(os2->sTypoDescender)));
+ if (stemv < 0) /* if not given by the option '-v' */
+ stemv = (os2->usWeightClass/65.)*(os2->usWeightClass/65.)+50;
+ pdf_add_dict (descriptor,
+ pdf_new_name ("StemV"),
+ pdf_new_number (stemv));
+ if (os2->version == 0x0002) {
+ pdf_add_dict (descriptor,
+ pdf_new_name("CapHeight"),
+ pdf_new_number(PDFUNIT(os2->sCapHeight)));
+ /* optional */
+ pdf_add_dict (descriptor,
+ pdf_new_name("XHeight"),
+ pdf_new_number(PDFUNIT(os2->sxHeight)));
+ } else { /* arbitrary */
+ pdf_add_dict (descriptor,
+ pdf_new_name("CapHeight"),
+ pdf_new_number(PDFUNIT(os2->sTypoAscender)));
+ }
+ /* optional */
+ if (os2->xAvgCharWidth != 0) {
+ pdf_add_dict (descriptor,
+ pdf_new_name ("AvgWidth"),
+ pdf_new_number (PDFUNIT(os2->xAvgCharWidth)));
+ }
+ }
+
+ /* BoundingBox (array) */
+ bbox = pdf_new_array ();
+ pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->xMin)));
+ pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->yMin)));
+ pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->xMax)));
+ pdf_add_array (bbox, pdf_new_number (PDFUNIT(head->yMax)));
+ pdf_add_dict (descriptor, pdf_new_name ("FontBBox"), bbox);
+
+ /* post */
+ pdf_add_dict (descriptor,
+ pdf_new_name ("ItalicAngle"),
+ pdf_new_number(fixed(post->italicAngle)));
+
+ /* Flags */
+ if (os2) {
+ if (os2->fsSelection & (1 << 0))
+ flag |= ITALIC;
+ if (os2->fsSelection & (1 << 5))
+ flag |= FORCEBOLD;
+ if (((os2->sFamilyClass >> 8) & 0xff) != 8)
+ flag |= SERIF;
+ if (((os2->sFamilyClass >> 8) & 0xff) == 10)
+ flag |= SCRIPT;
+ if (post->isFixedPitch)
+ flag |= FIXEDWIDTH;
+ }
+
+ pdf_add_dict (descriptor,
+ pdf_new_name ("Flags"),
+ pdf_new_number (flag));
+
+ /* insert panose if you want */
+ if (type == 0 && os2) { /* cid-keyed font - add panose */
+ pdf_obj *styledict = NULL;
+ unsigned char panose[12];
+
+ panose[0] = os2->sFamilyClass >> 8;
+ panose[1] = os2->sFamilyClass & 0xff;
+ memcpy(panose+2, os2->panose, 10);
+
+ styledict = pdf_new_dict ();
+ pdf_add_dict (styledict, pdf_new_name ("Panose"),
+ pdf_new_string (panose, 12));
+ pdf_add_dict (descriptor, pdf_new_name ("Style"), styledict);
+ }
+
+ RELEASE(head);
+ if (os2)
+ RELEASE(os2);
+ tt_release_post_table(post);
+
+ return descriptor;
+}
+
diff --git a/Build/source/texk/dvipdfm-x/tt_aux.h b/Build/source/texk/dvipdfm-x/tt_aux.h
new file mode 100644
index 00000000000..cc41fd18e92
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_aux.h
@@ -0,0 +1,33 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TT_AUX_H_
+#define _TT_AUX_H_
+
+#include "pdfobj.h"
+#include "sfnt.h"
+
+/* TTC (TrueType Collection) */
+extern ULONG ttc_read_offset (sfnt *sfont, ULONG ttc_idx);
+
+/* FontDescriptor */
+extern pdf_obj *tt_get_fontdesc (sfnt *sfont, int *embed, int stemv, int type, const char* fontname);
+
+#endif /* _TT_AUX_H_ */
diff --git a/Build/source/texk/dvipdfm-x/tt_cmap.c b/Build/source/texk/dvipdfm-x/tt_cmap.c
new file mode 100644
index 00000000000..cb8afb69812
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_cmap.c
@@ -0,0 +1,1773 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * A large part of codes are brought from ttfdump-0.5.5.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+
+#include "sfnt.h"
+
+
+/* Sorry for placing this here.
+ * We need to rewrite TrueType font support code...
+ */
+#include "cmap.h"
+#include "cmap_write.h"
+
+#include "tt_aux.h"
+#include "tt_gsub.h"
+#include "tt_post.h"
+
+#include "unicode.h"
+#include "agl.h"
+
+#include "pdfresource.h"
+#include "dpxfile.h"
+/* Hash */
+#include "dpxutil.h"
+
+#include "tt_cmap.h"
+
+#define VERBOSE_LEVEL_MIN 0
+
+/* format 0: byte encoding table */
+struct cmap0
+{
+ BYTE glyphIndexArray[256];
+};
+
+static struct cmap0 *
+read_cmap0 (sfnt *sfont, ULONG len)
+{
+ struct cmap0 *map;
+ int i;
+
+ if (len < 256) {
+ WARN("invalid format 0 TT cmap subtable");
+ return NULL;
+ }
+
+ map = NEW(1, struct cmap0);
+ for (i = 0; i < 256; i++)
+ map->glyphIndexArray[i] = sfnt_get_byte(sfont);
+
+ return map;
+}
+
+static void
+release_cmap0(struct cmap0 *map)
+{
+ if (map)
+ RELEASE(map);
+}
+
+static USHORT
+lookup_cmap0 (struct cmap0 *map, USHORT cc)
+{
+ return ((cc > 255) ? 0 : map->glyphIndexArray[cc]);
+}
+
+/* format 2: high-byte mapping through table */
+struct SubHeader
+{
+ USHORT firstCode;
+ USHORT entryCount;
+ SHORT idDelta;
+ USHORT idRangeOffset;
+};
+
+struct cmap2
+{
+ USHORT subHeaderKeys[256];
+ struct SubHeader *subHeaders;
+ USHORT *glyphIndexArray;
+};
+
+static struct cmap2 *
+read_cmap2 (sfnt *sfont, ULONG len)
+{
+ struct cmap2 *map;
+ USHORT i, n;
+
+ if (len < 512) {
+ WARN("invalid fromt2 TT cmap subtable");
+ return NULL;
+ }
+
+ map = NEW(1, struct cmap2);
+ for (i = 0; i < 256; i++)
+ map->subHeaderKeys[i] = sfnt_get_ushort(sfont);
+ for (n = 0, i = 0; i < 256; i++) {
+ map->subHeaderKeys[i] /= 8;
+ if (n < map->subHeaderKeys[i])
+ n = map->subHeaderKeys[i];
+ }
+ n += 1; /* the number of subHeaders is one plus the max of subHeaderKeys */
+
+ if (len < 512 + n * 8 ) {
+ WARN("invalid/truncated format2 TT cmap subtable");
+ RELEASE(map);
+ return NULL;
+ }
+
+ map->subHeaders = NEW(n, struct SubHeader);
+ for (i = 0; i < n; i++) {
+ map->subHeaders[i].firstCode = sfnt_get_ushort(sfont);
+ map->subHeaders[i].entryCount = sfnt_get_ushort(sfont);
+ map->subHeaders[i].idDelta = sfnt_get_short(sfont);
+ map->subHeaders[i].idRangeOffset = sfnt_get_ushort(sfont);
+
+ /* It makes things easier to let the offset starts from
+ * the beginning of glyphIndexArray.
+ */
+ if (map->subHeaders[i].idRangeOffset != 0)
+ map->subHeaders[i].idRangeOffset -= (2 + (n - i - 1) * 8);
+ }
+
+ /* Caculate the length of glyphIndexArray, this is ugly,
+ * there should be a better way to get this information.
+ */
+ n = (USHORT) (len - 518 - n * 8) / 2;
+
+ map->glyphIndexArray = NEW(n, USHORT);
+ for (i = 0; i < n; i++)
+ map->glyphIndexArray[i] = sfnt_get_ushort(sfont);
+
+ return map;
+}
+
+static void
+release_cmap2 (struct cmap2 *map)
+{
+ if (map) {
+ if (map->subHeaders)
+ RELEASE(map->subHeaders);
+ if (map->glyphIndexArray)
+ RELEASE(map->glyphIndexArray);
+ RELEASE(map);
+ }
+}
+
+static USHORT
+lookup_cmap2 (struct cmap2 *map, USHORT cc)
+{
+ USHORT idx = 0;
+ SHORT idDelta;
+ USHORT firstCode, entryCount, idRangeOffset;
+ int hi, lo;
+ USHORT i;
+
+ hi = (cc >> 8) & 0xff;
+ lo = cc & 0xff;
+
+ /* select which subHeader to use */
+ i = map->subHeaderKeys[hi];
+
+ firstCode = map->subHeaders[i].firstCode;
+ entryCount = map->subHeaders[i].entryCount;
+ idDelta = map->subHeaders[i].idDelta;
+ idRangeOffset = map->subHeaders[i].idRangeOffset / 2;
+
+ if (lo >= firstCode &&
+ lo < firstCode + entryCount) {
+ idRangeOffset += lo - firstCode;
+ idx = map->glyphIndexArray[idRangeOffset];
+ if (idx != 0)
+ idx = (idx + idDelta) & 0xffff;
+ }
+
+ return idx;
+}
+
+/*
+ * format 4: segment mapping to delta values
+ * - Microsoft standard character to glyph index mapping table
+ */
+struct cmap4
+{
+ USHORT segCountX2;
+ USHORT searchRange;
+ USHORT entrySelector;
+ USHORT rangeShift;
+ USHORT *endCount;
+ USHORT reservedPad;
+ USHORT *startCount;
+ USHORT *idDelta;
+ USHORT *idRangeOffset;
+ USHORT *glyphIndexArray;
+};
+
+static struct cmap4 *
+read_cmap4(sfnt *sfont, ULONG len)
+{
+ struct cmap4 *map;
+ USHORT i, n, segCount;
+
+ if (len < 8) {
+ WARN("invalid format 4 TT cmap subtable");
+ return NULL;
+ }
+
+ map = NEW(1, struct cmap4);
+
+ map->segCountX2 = segCount = sfnt_get_ushort(sfont);
+ map->searchRange = sfnt_get_ushort(sfont);
+ map->entrySelector = sfnt_get_ushort(sfont);
+ map->rangeShift = sfnt_get_ushort(sfont);
+
+ segCount /= 2;
+
+ map->endCount = NEW(segCount, USHORT);
+ for (i = 0; i < segCount; i++)
+ map->endCount[i] = sfnt_get_ushort(sfont);
+
+ map->reservedPad = sfnt_get_ushort(sfont);
+
+ map->startCount = NEW(segCount, USHORT);
+ for (i = 0; i < segCount; i++)
+ map->startCount[i] = sfnt_get_ushort(sfont);
+
+ map->idDelta = NEW(segCount, USHORT);
+ for (i = 0; i < segCount; i++)
+ map->idDelta[i] = sfnt_get_ushort(sfont);
+
+ map->idRangeOffset = NEW(segCount, USHORT);
+ for (i = 0; i < segCount; i++)
+ map->idRangeOffset[i] = sfnt_get_ushort(sfont);
+
+ n = (len - 16 - 8 * segCount) / 2;
+ if (n == 0)
+ map->glyphIndexArray = NULL;
+ else {
+ map->glyphIndexArray = NEW(n, USHORT);
+ for (i = 0; i < n; i++)
+ map->glyphIndexArray[i] = sfnt_get_ushort(sfont);
+ }
+
+ return map;
+}
+
+static void
+release_cmap4 (struct cmap4 *map)
+{
+ if (map) {
+ if (map->endCount) RELEASE(map->endCount);
+ if (map->startCount) RELEASE(map->startCount);
+ if (map->idDelta) RELEASE(map->idDelta);
+ if (map->idRangeOffset) RELEASE(map->idRangeOffset);
+ if (map->glyphIndexArray) RELEASE(map->glyphIndexArray);
+ RELEASE(map);
+ }
+}
+
+static USHORT
+lookup_cmap4 (struct cmap4 *map, USHORT cc)
+{
+ USHORT gid = 0;
+ USHORT i, j, segCount;
+
+ /*
+ * Segments are sorted in order of increasing endCode values.
+ * Last segment maps 0xffff to gid 0 (?)
+ */
+ i = segCount = map->segCountX2 / 2;
+ while (i-- > 0 && cc <= map->endCount[i]) {
+ if (cc >= map->startCount[i]) {
+ if (map->idRangeOffset[i] == 0) {
+ gid = (cc + map->idDelta[i]) & 0xffff;
+ } else if (cc == 0xffff && map->idRangeOffset[i] == 0xffff) {
+ /* this is for protection against some old broken fonts... */
+ gid = 0;
+ } else {
+ j = map->idRangeOffset[i] - (segCount - i) * 2;
+ j = (cc - map->startCount[i]) + (j / 2);
+ gid = map->glyphIndexArray[j];
+ if (gid != 0)
+ gid = (gid + map->idDelta[i]) & 0xffff;
+ }
+ break;
+ }
+ }
+
+ return gid;
+}
+
+/* format 6: trimmed table mapping */
+struct cmap6
+{
+ USHORT firstCode;
+ USHORT entryCount;
+ USHORT *glyphIndexArray;
+};
+
+static struct cmap6 *
+read_cmap6 (sfnt *sfont, ULONG len)
+{
+ struct cmap6 *map;
+ USHORT i;
+
+ if (len < 4) {
+ WARN("invalid format 6 TT cmap subtable");
+ return NULL;
+ }
+
+ map = NEW(1, struct cmap6);
+ map->firstCode = sfnt_get_ushort(sfont);
+ map->entryCount = sfnt_get_ushort(sfont);
+ map->glyphIndexArray = NEW(map->entryCount, USHORT);
+ for (i = 0; i < map->entryCount; i++)
+ map->glyphIndexArray[i] = sfnt_get_ushort(sfont);
+
+ return map;
+}
+
+static void
+release_cmap6 (struct cmap6 *map)
+{
+ if (map) {
+ if (map->glyphIndexArray)
+ RELEASE(map->glyphIndexArray);
+ RELEASE(map);
+ }
+}
+
+static USHORT
+lookup_cmap6 (struct cmap6 *map, USHORT cc)
+{
+ USHORT idx;
+
+ idx = cc - map->firstCode;
+ if (idx < map->entryCount)
+ return map->glyphIndexArray[idx];
+ return 0;
+}
+
+/* Format 8 and 10 not supported...
+ *
+ * format 8: mixed 16-bit and 32-bit coverage
+ * format 10: trimmed array
+ */
+
+/*
+ * format 12: segmented coverage
+ *
+ * startGlyphID is 32-bit long, however, GlyphID is still 16-bit long !
+ */
+
+struct charGroup
+{
+ ULONG startCharCode;
+ ULONG endCharCode;
+ ULONG startGlyphID;
+};
+
+struct cmap12
+{
+ ULONG nGroups;
+ struct charGroup *groups;
+};
+
+/* ULONG length */
+static struct cmap12 *
+read_cmap12 (sfnt *sfont, ULONG len)
+{
+ struct cmap12 *map;
+ ULONG i;
+
+ if (len < 4) {
+ WARN("invalid format 12 TT cmap subtable");
+ return NULL;
+ }
+
+ map = NEW(1, struct cmap12);
+ map->nGroups = sfnt_get_ulong(sfont);
+ map->groups = NEW(map->nGroups, struct charGroup);
+ for (i = 0; i < map->nGroups; i++) {
+ map->groups[i].startCharCode = sfnt_get_ulong(sfont);
+ map->groups[i].endCharCode = sfnt_get_ulong(sfont);
+ map->groups[i].startGlyphID = sfnt_get_ulong(sfont);
+ }
+
+ return map;
+}
+
+static void
+release_cmap12 (struct cmap12 *map)
+{
+ if (map) {
+ if (map->groups)
+ RELEASE(map->groups);
+ RELEASE(map);
+ }
+}
+
+static USHORT
+lookup_cmap12 (struct cmap12 *map, ULONG cccc)
+{
+ USHORT gid = 0;
+ int i;
+
+ i = map->nGroups;
+ while (i-- > 0 &&
+ cccc <= map->groups[i].endCharCode) {
+ if (cccc >= map->groups[i].startCharCode) {
+ gid = (USHORT) ((cccc -
+ map->groups[i].startCharCode +
+ map->groups[i].startGlyphID) & 0xffff);
+ break;
+ }
+ }
+
+ return gid;
+}
+
+/* read cmap */
+tt_cmap *
+tt_cmap_read (sfnt *sfont, USHORT platform, USHORT encoding)
+{
+ tt_cmap *cmap = NULL;
+ ULONG offset, length = 0;
+ USHORT p_id, e_id;
+ USHORT i, n_subtabs;
+
+ ASSERT(sfont);
+
+ offset = sfnt_locate_table(sfont, "cmap");
+ (void) sfnt_get_ushort(sfont);
+ n_subtabs = sfnt_get_ushort(sfont);
+
+ for (i = 0; i < n_subtabs; i++) {
+ p_id = sfnt_get_ushort(sfont);
+ e_id = sfnt_get_ushort(sfont);
+ if (p_id != platform || e_id != encoding)
+ sfnt_get_ulong(sfont);
+ else {
+ offset += sfnt_get_ulong(sfont);
+ break;
+ }
+ }
+
+ if (i == n_subtabs)
+ return NULL;
+
+ cmap = NEW(1, tt_cmap);
+ cmap->map = NULL;
+ cmap->platform = platform;
+ cmap->encoding = encoding;
+
+ sfnt_seek_set(sfont, offset);
+ cmap->format = sfnt_get_ushort(sfont);
+ /* Length and version (language) is ULONG for
+ * format 8, 10, 12 !
+ */
+ if (cmap->format <= 6) {
+ length = sfnt_get_ushort(sfont);
+ cmap->language = sfnt_get_ushort(sfont); /* language (Mac) */
+ } else {
+ if (sfnt_get_ushort(sfont) != 0) { /* reverved - 0 */
+ WARN("Unrecognized cmap subtable format.");
+ tt_cmap_release(cmap);
+ return NULL;
+ } else {
+ length = sfnt_get_ulong(sfont);
+ cmap->language = sfnt_get_ulong(sfont);
+ }
+ }
+
+ switch(cmap->format) {
+ case 0:
+ cmap->map = read_cmap0(sfont, length);
+ break;
+ case 2:
+ cmap->map = read_cmap2(sfont, length);
+ break;
+ case 4:
+ cmap->map = read_cmap4(sfont, length);
+ break;
+ case 6:
+ cmap->map = read_cmap6(sfont, length);
+ break;
+ case 12:
+ /* WARN("UCS-4 TrueType cmap table..."); */
+ cmap->map = read_cmap12(sfont, length);
+ break;
+ default:
+ WARN("Unrecognized OpenType/TrueType cmap format.");
+ tt_cmap_release(cmap);
+ return NULL;
+ break;
+ }
+
+ if (!cmap->map) {
+ tt_cmap_release(cmap);
+ cmap = NULL;
+ }
+
+ return cmap;
+}
+
+void
+tt_cmap_release (tt_cmap *cmap)
+{
+
+ if (cmap) {
+ if (cmap->map) {
+ switch (cmap->format) {
+ case 0:
+ release_cmap0(cmap->map);
+ break;
+ case 2:
+ release_cmap2(cmap->map);
+ break;
+ case 4:
+ release_cmap4(cmap->map);
+ break;
+ case 6:
+ release_cmap6(cmap->map);
+ break;
+ case 12:
+ release_cmap12(cmap->map);
+ break;
+ default:
+ WARN("Unrecognized OpenType/TrueType cmap format: %d", cmap->format);
+ break;
+ }
+ }
+ RELEASE(cmap);
+ }
+
+ return;
+}
+
+
+USHORT
+tt_cmap_lookup (tt_cmap *cmap, ULONG cc)
+{
+ USHORT gid = 0;
+
+ ASSERT(cmap);
+
+ if (cc > 0xffffL && cmap->format < 12) {
+ WARN("Four bytes charcode not supported in OpenType/TrueType cmap format 0...6.");
+ return 0;
+ }
+
+ switch (cmap->format) {
+ case 0:
+ gid = lookup_cmap0(cmap->map, (USHORT) cc);
+ break;
+ case 2:
+ gid = lookup_cmap2(cmap->map, (USHORT) cc);
+ break;
+ case 4:
+ gid = lookup_cmap4(cmap->map, (USHORT) cc);
+ break;
+ case 6:
+ gid = lookup_cmap6(cmap->map, (USHORT) cc);
+ break;
+ case 12:
+ gid = lookup_cmap12(cmap->map, (ULONG) cc);
+ break;
+ default:
+ WARN("Unrecognized OpenType/TrueType cmap subtable format: %d", cmap->format);
+ break;
+ }
+
+ return gid;
+}
+
+
+
+static unsigned char srange_min[2] = {0x00, 0x00};
+static unsigned char srange_max[2] = {0xff, 0xff};
+static unsigned char lrange_min[4] = {0x00, 0x00, 0x00, 0x00};
+static unsigned char lrange_max[4] = {0x7f, 0xff, 0xff, 0xff};
+
+/* OpenType CIDFont:
+ *
+ * We don't use GID for them. OpenType cmap table is for
+ * charcode to GID mapping rather than to-CID mapping.
+ */
+#include "cid.h"
+
+#include "tt_table.h"
+#include "cff_types.h"
+#include "cff_dict.h"
+#include "cff.h"
+
+/* This should be moved to cff.c */
+static void
+create_GIDToCIDMap (uint16_t *GIDToCIDMap, uint16_t num_glyphs, cff_font *cffont)
+{
+ cff_charsets *charset;
+ uint16_t gid, i;
+
+ ASSERT(GIDToCIDMap);
+
+ if (!cffont || !(cffont->flag & FONTTYPE_CIDFONT)) {
+ for (gid = 0; gid < num_glyphs; gid++) {
+ GIDToCIDMap[gid] = gid;
+ }
+
+ return;
+ }
+
+ memset(GIDToCIDMap, 0, num_glyphs*sizeof(uint16_t));
+
+ charset = cffont->charsets;
+ if (!charset)
+ return;
+ switch (charset->format) {
+ case 0:
+ {
+ s_SID *cids; /* CID... */
+
+ cids = charset->data.glyphs;
+ for (gid = 1, i = 0; i < charset->num_entries; i++) {
+ GIDToCIDMap[gid] = cids[i];
+ gid++;
+ }
+ }
+ break;
+ case 1:
+ {
+ cff_range1 *ranges;
+ card16 cid, count;
+
+ ranges = charset->data.range1;
+ for (gid = 1, i = 0; i < charset->num_entries; i++) {
+ cid = ranges[i].first;
+ count = ranges[i].n_left + 1; /* card8 */
+ while (count-- > 0 && gid <= num_glyphs) {
+ GIDToCIDMap[gid] = cid;
+ gid++;
+ cid++;
+ }
+ }
+ }
+ break;
+ case 2:
+ {
+ cff_range2 *ranges;
+ card16 cid, count;
+
+ ranges = charset->data.range2;
+ if (charset->num_entries == 1 && ranges[0].first == 1) {
+ /* "Complete" CIDFont */
+ for (gid = 0; gid < num_glyphs; gid++) {
+ GIDToCIDMap[gid] = gid;
+ }
+ } else {
+ /* Not trivial mapping */
+ for (gid = 1, i = 0; i < charset->num_entries; i++) {
+ cid = ranges[i].first;
+ count = ranges[i].n_left + 1;
+ while (count-- > 0 && gid <= num_glyphs) {
+ GIDToCIDMap[gid] = cid;
+ gid++;
+ cid++;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ WARN("Unknown CFF charset format...: %d", charset->format);
+ break;
+ }
+
+ return;
+}
+
+/* Soft-hyphen (U+00AD) to lower its priority... added here for convenience */
+static int is_PUA_or_presentation (unsigned int uni)
+{
+ /* Some of CJK Radicals Supplement and Kangxi Radicals
+ * are commonly double encoded, lower the priority.
+ * CJK Compatibility Ideographs & Supplement added.
+ */
+ return ((uni >= 0x2E80 && uni <= 0x2EF3) || (uni >= 0x2F00 && uni <= 0x2FD5) ||
+ (uni >= 0xE000 && uni <= 0xF8FF) || (uni >= 0xFB00 && uni <= 0xFB4F) ||
+ (uni >= 0xF900 && uni <= 0xFAFF) || (uni >= 0x2F800 && uni <= 0x2FA1F) ||
+ (uni >= 0xF0000 && uni <= 0xFFFFD) || (uni >= 0x100000 && uni <= 0x10FFFD) ||
+ (uni == 0x00AD));
+}
+
+static char *
+lookup_glyph_name (struct tt_post_table *post, cff_font *cffont, USHORT gid)
+{
+ char *name = NULL;
+
+ if (post)
+ name = tt_get_glyphname(post, gid);
+ if (!name && cffont)
+ name = cff_get_glyphname(cffont, gid);
+
+ return name;
+}
+
+/*
+ * Substituted glyphs:
+ *
+ * Mapping information stored in cmap_add.
+ */
+#ifndef is_used_char2
+#define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8))))
+#endif
+
+static int32_t
+handle_subst_glyphs (CMap *cmap, CMap *cmap_add, char *used_chars)
+{
+ int32_t count = 0;
+ int32_t cid;
+
+ for (cid = 0; cid < 65536; cid++) {
+ if (!is_used_char2(used_chars, cid))
+ continue;
+ else {
+ unsigned char buf[256];
+ int inbytesleft = 2, outbytesleft = 254;
+ size_t len;
+ unsigned char *outbuf = buf + 2;
+ const unsigned char *inbuf = buf;
+
+ buf[0] = (cid >> 8) & 0xff;
+ buf[1] = cid & 0xff;
+ CMap_decode(cmap_add, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+ if (inbytesleft == 0) {
+ len = 254 - outbytesleft;
+ CMap_add_bfchar(cmap, buf, 2, buf + 2, len);
+ used_chars[cid / 8] &= ~(1 << (7 - (cid % 8)));
+ count++;
+ }
+ }
+ }
+
+ return count;
+}
+
+static int32_t
+add_ToUnicode_via_glyph_name (CMap *cmap, char *used_chars, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap,
+ sfnt *sfont, cff_font *cffont)
+{
+ int32_t count = 0;
+ USHORT gid;
+ struct tt_post_table *post = NULL;
+
+ post = tt_read_post_table(sfont);
+ if (!post && !cffont)
+ return count;
+
+ for (gid = 0; gid < num_glyphs; gid++) {
+ uint16_t cid = GIDToCIDMap[gid];
+ if (is_used_char2(used_chars, cid)) {
+#define MAX_UNICODES 32
+ char *name;
+ int32_t unicodes[MAX_UNICODES];
+ int unicode_count = -1;
+
+ name = lookup_glyph_name(post, cffont, gid);
+ if (name) {
+ unicode_count = agl_get_unicodes(name, unicodes, MAX_UNICODES);
+#undef MAX_UNICODES
+ RELEASE(name);
+ if (unicode_count > 0) {
+ unsigned char *buf;
+ unsigned char *p, *endptr;
+ int k;
+ size_t len = 0;
+
+ buf = NEW(unicode_count*4+2, unsigned char);
+ p = buf + 2;
+ endptr = buf + (unicode_count * 4 + 2);
+ for (k = 0; k < unicode_count; ++k) {
+ len += UC_UTF16BE_encode_char(unicodes[k], &p, endptr);
+ }
+ buf[0] = (cid >> 8) & 0xff;
+ buf[1] = cid & 0xff;
+ CMap_add_bfchar(cmap, buf, 2, buf + 2, len);
+ used_chars[cid / 8] &= ~(1 << (7 - (cid % 8)));
+ count++;
+
+ RELEASE(buf);
+ }
+ }
+ }
+ }
+
+ if (post)
+ tt_release_post_table(post);
+
+ return count;
+}
+
+static void
+create_inverse_cmap4 (int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ struct cmap4 *map)
+{
+ USHORT segCount = map->segCountX2 / 2;
+ USHORT i, j;
+
+ for (i = 0; i < segCount; i++) {
+ USHORT c0 = map->startCount[i];
+ USHORT c1 = map->endCount[i];
+ USHORT d = map->idRangeOffset[i] / 2 - (segCount - i);
+ for (j = 0; j <= c1 - c0; j++) {
+ USHORT ch = c0 + j;
+ USHORT gid;
+
+ if (map->idRangeOffset[i] == 0) {
+ gid = (ch + map->idDelta[i]) & 0xffff;
+ } else if (c0 == 0xffff && c1 == 0xffff && map->idRangeOffset[i] == 0xffff) {
+ /* this is for protection against some old broken fonts... */
+ gid = 0;
+ } else {
+ gid = (map->glyphIndexArray[j + d] + map->idDelta[i]) & 0xffff;
+ }
+ if (is_PUA_or_presentation(ch)) {
+ map_sub[gid] = ch;
+ } else {
+ map_base[gid] = ch;
+ }
+ }
+ }
+}
+
+static void
+create_inverse_cmap12 (int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ struct cmap12 *map)
+{
+ ULONG i, ch;
+
+ for (i = 0; i < map->nGroups; i++) {
+ for (ch = map->groups[i].startCharCode;
+ ch <= map->groups[i].endCharCode; ch++) {
+ int d = ch - map->groups[i].startCharCode;
+ USHORT gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff);
+ if (is_PUA_or_presentation(ch)) {
+ map_sub[gid] = ch;
+ } else {
+ map_base[gid] = ch;
+ }
+ }
+ }
+}
+
+/* NOTE: Reverse mapping code which had been placed here is removed since:
+ * - Implementation of reserve CMap mapping itself is imcomplete.
+ * - It is wrong to assume that all CMap passed here is Unicode to CID mapping.
+ * Especially, the second one causes problems.
+ */
+static pdf_obj *
+create_ToUnicode_cmap (tt_cmap *ttcmap,
+ const char *cmap_name,
+ CMap *cmap_add,
+ const char *used_chars,
+ sfnt *sfont)
+{
+ pdf_obj *stream = NULL;
+ int32_t *map_base = NULL, *map_sub = NULL;
+ USHORT gid, num_glyphs = 0;
+
+ ASSERT(ttcmap);
+
+ /* Get num_glyphs from maxp talbe */
+ {
+ struct tt_maxp_table *maxp;
+
+ maxp = tt_read_maxp_table(sfont);
+ if (maxp) {
+ num_glyphs = maxp->numGlyphs;
+ RELEASE(maxp);
+ }
+ }
+
+ /* Initialize GID to Unicode mapping table */
+ map_base = NEW(num_glyphs, int32_t);
+ map_sub = NEW(num_glyphs, int32_t);
+ for (gid = 0; gid < num_glyphs; gid++) {
+ map_base[gid] = -1;
+ map_sub [gid] = -1;
+ }
+
+ /* Create "base" mapping from inverse mapping of OpenType cmap */
+ switch (ttcmap->format) {
+ case 4:
+ create_inverse_cmap4(map_base, map_sub, num_glyphs, ttcmap->map);
+ break;
+ case 12:
+ create_inverse_cmap12(map_base, map_sub, num_glyphs, ttcmap->map);
+ break;
+ }
+
+ /* Now create ToUnicode CMap stream */
+ {
+ CMap *cmap;
+ int32_t count;
+ cff_font *cffont = NULL;
+ char is_cidfont = 0;
+ uint16_t *GIDToCIDMap = NULL;
+ char *used_chars_copy = NULL;
+
+ if (sfont->type == SFNT_TYPE_POSTSCRIPT) {
+ ULONG offset;
+ offset = sfnt_find_table_pos(sfont, "CFF ");
+ /* "CFF " table must exist here. Just abort... */
+ if (offset == 0) {
+ ERROR("\"CFF \" table not found. Must be found before... Can't continue.");
+ }
+ cffont = cff_open(sfont->stream, offset, 0);
+ cff_read_charsets(cffont);
+ }
+ is_cidfont = cffont && (cffont->flag & FONTTYPE_CIDFONT);
+
+ /* GIT to CID mapping info. */
+ GIDToCIDMap = NEW(num_glyphs, uint16_t);
+ if (is_cidfont) {
+ create_GIDToCIDMap(GIDToCIDMap, num_glyphs, cffont);
+ } else {
+ for (gid = 0; gid < num_glyphs; gid++) {
+ GIDToCIDMap[gid] = gid;
+ }
+ }
+ cmap = CMap_new();
+ CMap_set_name (cmap, cmap_name);
+ CMap_set_wmode(cmap, 0);
+ CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE);
+ CMap_set_CIDSysInfo(cmap, &CSI_UNICODE);
+ CMap_add_codespacerange(cmap, srange_min, srange_max, 2);
+
+ count = 0;
+ used_chars_copy = NEW(8192, char);
+ memcpy(used_chars_copy, used_chars, 8192);
+ for (gid = 0; gid < num_glyphs; gid++) {
+ uint16_t cid = GIDToCIDMap[gid];
+ if (is_used_char2(used_chars_copy, cid)) {
+ int32_t ch;
+ unsigned char src[2], dst[4];
+ unsigned char *p = dst, *endptr = dst + 4;
+ size_t len;
+
+ ch = map_base[gid];
+ if (UC_is_valid(ch)) {
+ src[0] = (cid >> 8) & 0xff;
+ src[1] = cid & 0xff;
+ len = UC_UTF16BE_encode_char(ch, &p, endptr);
+ CMap_add_bfchar(cmap, src, 2, dst, len);
+ used_chars_copy[cid / 8] &= ~(1 << (7 - (cid % 8)));
+ count++;
+ }
+ }
+ }
+
+ /* cmap_add here stores information about all unencoded glyphs which can be
+ * accessed only through OT Layout GSUB table.
+ * This is only availabel when encoding is "unicode".
+ */
+ if (cmap_add) {
+ count += handle_subst_glyphs(cmap, cmap_add, used_chars_copy);
+ } else {
+ /* Else, try gathering information from GSUB tables */
+ count += otl_gsub_add_ToUnicode(cmap, used_chars_copy,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, sfont);
+ }
+ /* Find Unicode mapping via PostScript glyph names... */
+ count += add_ToUnicode_via_glyph_name(cmap, used_chars_copy, num_glyphs,
+ GIDToCIDMap, sfont, is_cidfont ? NULL : cffont);
+ if (cffont)
+ cff_close(cffont);
+
+ /* Finaly, PUA and presentation forms... */
+ for (gid = 0; gid < num_glyphs; gid++) {
+ uint16_t cid = GIDToCIDMap[gid];
+ if (is_used_char2(used_chars_copy, cid)) {
+ int32_t ch;
+ unsigned char src[2], dst[4];
+ unsigned char *p = dst, *endptr = dst + 4;
+ size_t len;
+
+ ch = map_sub[gid];
+ if (UC_is_valid(ch)) {
+ src[0] = (cid >> 8) & 0xff;
+ src[1] = cid & 0xff;
+ len = UC_UTF16BE_encode_char(ch, &p, endptr);
+ CMap_add_bfchar(cmap, src, 2, dst, len);
+ used_chars_copy[cid / 8] &= ~(1 << (7 - (cid % 8)));
+ count++;
+ }
+ }
+ }
+
+ /* Check for missing mapping */
+ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ for (gid = 0; gid < num_glyphs; gid++) {
+ uint16_t cid = GIDToCIDMap[gid];
+ if (is_used_char2(used_chars_copy, cid)) {
+ WARN("Unable to find ToUnicode mapping for glyph CID=%u (GID=%u)", cid, gid);
+ }
+ }
+ }
+ RELEASE(GIDToCIDMap);
+ RELEASE(used_chars_copy);
+
+ if (count < 1)
+ stream = NULL;
+ else {
+ stream = CMap_create_stream(cmap);
+ }
+ CMap_release(cmap);
+ }
+ RELEASE(map_base);
+ RELEASE(map_sub);
+
+ return stream;
+}
+
+typedef struct {
+ short platform;
+ short encoding;
+} cmap_plat_enc_rec;
+
+static cmap_plat_enc_rec cmap_plat_encs[] = {
+ { 3, 10 },
+ { 0, 3 },
+ { 0, 0 },
+ { 3, 1 },
+ { 0, 1 }
+};
+
+pdf_obj *
+otf_create_ToUnicode_stream (const char *font_name,
+ uint32_t ttc_index, /* 0 for non-TTC */
+ const char *basefont,
+ const char *used_chars)
+{
+ pdf_obj *cmap_ref = NULL; /* returned value */
+ CMap *cmap_add = NULL;
+ char *cmap_name;
+ FILE *fp = NULL;
+ sfnt *sfont;
+ ULONG offset = 0;
+ tt_cmap *ttcmap;
+ int cmap_id, cmap_add_id;
+ int i;
+
+ cmap_name = NEW(strlen(basefont)+strlen("-UTF16")+1, char);
+ sprintf(cmap_name, "%s-UTF16", basefont);
+
+ cmap_id = pdf_findresource("CMap", cmap_name);
+ if (cmap_id >= 0) {
+ RELEASE(cmap_name);
+ cmap_ref = pdf_get_resource_reference(cmap_id);
+ return cmap_ref;
+ }
+
+ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("\n");
+ MESG("otf_cmap>> Creating ToUnicode CMap for \"%s\"...\n", font_name);
+ }
+
+
+ if ((fp = DPXFOPEN(font_name, DPX_RES_TYPE_TTFONT)) ||
+ (fp = DPXFOPEN(font_name, DPX_RES_TYPE_OTFONT))) {
+ sfont = sfnt_open(fp);
+ } else if ((fp = DPXFOPEN(font_name, DPX_RES_TYPE_DFONT))) {
+ sfont = dfont_open(fp, ttc_index);
+ } else {
+ RELEASE(cmap_name);
+ return NULL;
+ }
+
+ if (!sfont) {
+ WARN("Could not open OpenType/TrueType font file \"%s\"", font_name);
+ RELEASE(cmap_name);
+ DPXFCLOSE(fp);
+ return NULL;
+ }
+
+ switch (sfont->type) {
+ case SFNT_TYPE_DFONT:
+ offset = sfont->offset;
+ break;
+ case SFNT_TYPE_TTC:
+ offset = ttc_read_offset(sfont, ttc_index);
+ if (offset == 0) {
+ WARN("Invalid TTC index for font: %s", font_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ RELEASE(cmap_name);
+ return NULL;
+ }
+ break;
+ default:
+ offset = 0;
+ break;
+ }
+
+ if (sfnt_read_table_directory(sfont, offset) < 0) {
+ WARN("Could not read OpenType/TrueType table directory: %s", font_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ RELEASE(cmap_name);
+ return NULL;
+ }
+
+ /* cmap_add is used for storing information on ToUnicode mapping for
+ * unencoded glyphs which can be reached only through GSUB substitution.
+ * This is available only when "unicode" is specified in the encoding
+ * field of fontmap. We remember the inverse mapping via cmap_add in this
+ * case.
+ */
+ {
+ char *cmap_add_name;
+ size_t len;
+
+ len = strlen(font_name)+strlen("-UCS32-Add")+32;
+ cmap_add_name = NEW(len, char);
+ snprintf(cmap_add_name, len, "%s:%d-UCS32-Add", font_name, ttc_index);
+ cmap_add_name[len-1] = '\0';
+ cmap_add_id = CMap_cache_find(cmap_add_name);
+ RELEASE(cmap_add_name);
+ if (cmap_add_id < 0) {
+ cmap_add = NULL;
+ } else {
+ cmap_add = CMap_cache_get(cmap_add_id);
+ }
+ }
+
+ ttcmap = NULL;
+ for (i = 0; i < sizeof(cmap_plat_encs) / sizeof(cmap_plat_enc_rec); ++i) {
+ ttcmap = tt_cmap_read(sfont, cmap_plat_encs[i].platform, cmap_plat_encs[i].encoding);
+ if (!ttcmap)
+ continue;
+
+ if (ttcmap->format == 4 || ttcmap->format == 12) {
+ break;
+ } else {
+ tt_cmap_release(ttcmap);
+ ttcmap = NULL;
+ }
+ }
+ if (ttcmap) {
+ pdf_obj *cmap_obj;
+
+ CMap_set_silent(1); /* many warnings without this... */
+ cmap_obj = create_ToUnicode_cmap(ttcmap, cmap_name, cmap_add, used_chars, sfont);
+ CMap_set_silent(0);
+ if (cmap_obj) {
+ cmap_id = pdf_defineresource("CMap", cmap_name,
+ cmap_obj, PDF_RES_FLUSH_IMMEDIATE);
+ cmap_ref = pdf_get_resource_reference(cmap_id);
+ }
+ tt_cmap_release(ttcmap);
+ }
+
+ /* Cleanup */
+ RELEASE(cmap_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+#ifndef LIBDPX
+ if (!cmap_ref) {
+ WARN("Creating ToUnicode CMap failed for \"%s\"", font_name);
+ }
+#endif
+
+ return cmap_ref;
+}
+
+
+/* Creating input CMaps from OT cmap table */
+
+static void
+load_cmap4 (struct cmap4 *map, uint16_t *GIDToCIDMap, USHORT num_glyphs,
+ otl_gsub *gsub_vert, otl_gsub *gsub_list,
+ CMap *cmap, int32_t *map_base, int32_t *map_sub)
+{
+ USHORT c0, c1, gid, cid;
+ USHORT j, d, segCount;
+ USHORT ch;
+ int i;
+ unsigned char buf[4];
+
+ segCount = map->segCountX2 / 2;
+ for (i = segCount - 1; i >= 0 ; i--) {
+ c0 = map->startCount[i];
+ c1 = map->endCount[i];
+ d = map->idRangeOffset[i] / 2 - (segCount - i);
+ for (j = 0; j <= c1 - c0; j++) {
+ ch = c0 + j;
+ if (map->idRangeOffset[i] == 0) {
+ gid = (ch + map->idDelta[i]) & 0xffff;
+ } else if (c0 == 0xffff && c1 == 0xffff && map->idRangeOffset[i] == 0xffff) {
+ /* this is for protection against some old broken fonts... */
+ gid = 0;
+ } else {
+ gid = (map->glyphIndexArray[j+d] + map->idDelta[i]) & 0xffff;
+ }
+ if (gid != 0 && gid != 0xffff) {
+ /* Apply GSUB features */
+ if (gsub_list)
+ otl_gsub_apply_chain(gsub_list, &gid);
+ if (gsub_vert)
+ otl_gsub_apply(gsub_vert, &gid);
+ cid = (gid < num_glyphs) ? GIDToCIDMap[gid] : 0;
+ buf[0] = 0;
+ buf[1] = 0;
+ buf[2] = (ch >> 8) & 0xff;
+ buf[3] = ch & 0xff;
+ CMap_add_cidchar(cmap, buf, 4, cid);
+ /* For ToUnicode creation */
+ if (map_base && map_sub) {
+ if (is_PUA_or_presentation(ch)) {
+ map_sub[gid] = ch;
+ } else {
+ map_base[gid] = ch;
+ }
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+static void
+load_cmap12 (struct cmap12 *map, uint16_t *GIDToCIDMap, USHORT num_glyphs,
+ otl_gsub *gsub_vert, otl_gsub *gsub_list,
+ CMap *cmap, int32_t *map_base, int32_t *map_sub)
+{
+ ULONG i, ch;
+ USHORT gid, cid;
+ unsigned char buf[4];
+
+ for (i = 0; i < map->nGroups; i++) {
+ for (ch = map->groups[i].startCharCode;
+ ch <= map->groups[i].endCharCode; ch++) {
+ int d = ch - map->groups[i].startCharCode;
+ gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff);
+ if (gsub_list)
+ otl_gsub_apply_chain(gsub_list, &gid);
+ if (gsub_vert)
+ otl_gsub_apply(gsub_vert, &gid);
+ cid = (gid < num_glyphs) ? GIDToCIDMap[gid] : 0;
+ buf[0] = (ch >> 24) & 0xff;
+ buf[1] = (ch >> 16) & 0xff;
+ buf[2] = (ch >> 8) & 0xff;
+ buf[3] = ch & 0xff;
+ CMap_add_cidchar(cmap, buf, 4, cid);
+ if (map_base && map_sub) {
+ if (is_PUA_or_presentation(ch)) {
+ map_sub[gid] = ch;
+ } else {
+ map_base[gid] = ch;
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+int
+otf_load_Unicode_CMap (const char *map_name, uint32_t ttc_index, /* 0 for non-TTC font */
+ const char *otl_tags, int wmode)
+{
+ int cmap_id = -1;
+ char *cmap_name = NULL;
+ sfnt *sfont = NULL;
+ ULONG offset = 0;
+ uint16_t num_glyphs = 0;
+ FILE *fp = NULL;
+ tt_cmap *ttcmap = NULL;
+ CIDSysInfo csi = {NULL, NULL, 0};
+ uint16_t *GIDToCIDMap = NULL;
+
+ if (!map_name)
+ return -1;
+
+ /* First look for cache if it was already loaded */
+ if (otl_tags) {
+ size_t len;
+ len = strlen(map_name)+strlen("-UCS4-H")+strlen(otl_tags)+32;
+ cmap_name = NEW(len, char);
+ if (wmode)
+ snprintf(cmap_name, len, "%s:%d:%s-UCS4-V", map_name, ttc_index, otl_tags);
+ else
+ snprintf(cmap_name, len, "%s:%d:%s-UCS4-H", map_name, ttc_index, otl_tags);
+ cmap_name[len-1] = '\0';
+ } else {
+ size_t len;
+ len = strlen(map_name)+strlen("-UCS4-H")+32;
+ cmap_name = NEW(len, char);
+ if (wmode)
+ snprintf(cmap_name, len, "%s:%d-UCS4-V", map_name, ttc_index);
+ else {
+ snprintf(cmap_name, len, "%s:%d-UCS4-H", map_name, ttc_index);
+ }
+ cmap_name[len-1] = '\0';
+ }
+ cmap_id = CMap_cache_find(cmap_name);
+ if (cmap_id >= 0) {
+ RELEASE(cmap_name);
+ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN)
+ MESG("otf_cmap>> Found at cmap_id=%d.\n", cmap_id);
+
+ return cmap_id;
+ }
+
+ /* CMap not found */
+ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("\n");
+ MESG("otf_cmap>> Creating Unicode charmap for font=\"%s\" layout=\"%s\"\n",
+ map_name, (otl_tags ? otl_tags : "none"));
+ }
+
+ fp = DPXFOPEN(map_name, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(map_name, DPX_RES_TYPE_OTFONT);
+ }
+ if (!fp) {
+ fp = DPXFOPEN(map_name, DPX_RES_TYPE_DFONT);
+ if (!fp) {
+ RELEASE(cmap_name);
+ return -1;
+ }
+ sfont = dfont_open(fp, ttc_index);
+ } else {
+ sfont = sfnt_open(fp);
+ }
+
+ if (!sfont) {
+ WARN("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name);
+ RELEASE(cmap_name);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ switch (sfont->type) {
+ case SFNT_TYPE_TTC:
+ offset = ttc_read_offset(sfont, ttc_index);
+ if (offset == 0) {
+ WARN("Offset=0 returned for font=%s, TTC_index=%d", map_name, ttc_index);
+ RELEASE(cmap_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ break;
+ case SFNT_TYPE_TRUETYPE:
+ case SFNT_TYPE_POSTSCRIPT:
+ offset = 0;
+ break;
+ case SFNT_TYPE_DFONT:
+ offset = sfont->offset;
+ break;
+ default:
+ WARN("Not a OpenType/TrueType/TTC font?: %s", map_name);
+ RELEASE(cmap_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ break;
+ }
+
+ if (sfnt_read_table_directory(sfont, offset) < 0) {
+ WARN("Could not read OpenType/TrueType table directory: %s", map_name);
+ RELEASE(cmap_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ {
+ struct tt_maxp_table *maxp;
+
+ maxp = tt_read_maxp_table(sfont);
+ num_glyphs = (card16) maxp->numGlyphs;
+ RELEASE(maxp);
+ }
+
+ GIDToCIDMap = NEW(num_glyphs, uint16_t);
+ memset(GIDToCIDMap, 0, num_glyphs*sizeof(uint16_t));
+ if (sfont->type == SFNT_TYPE_POSTSCRIPT) {
+ cff_font *cffont;
+ card16 gid;
+
+ offset = sfnt_find_table_pos(sfont, "CFF ");
+ /* Possibly "CFF2" table for variable font: not supported. */
+ if (offset == 0) {
+ WARN("PS OpenType but no \"CFF \" table.. Maybe variable font? (not supported)");
+ RELEASE(cmap_name);
+ RELEASE(GIDToCIDMap);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ cffont = cff_open(sfont->stream, offset, 0);
+ if (!cffont) {
+ RELEASE(cmap_name);
+ RELEASE(GIDToCIDMap);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ if (!(cffont->flag & FONTTYPE_CIDFONT)) {
+ csi.registry = strdup("Adobe");
+ csi.ordering = strdup("Identity");
+ csi.supplement = 0;
+ for (gid = 0; gid < num_glyphs; gid++) {
+ GIDToCIDMap[gid] = gid;
+ }
+ } else {
+ if (!cff_dict_known(cffont->topdict, "ROS")) {
+ csi.registry = strdup("Adobe");
+ csi.ordering = strdup("Identity");
+ csi.supplement = 0;
+ } else {
+ card16 reg, ord;
+
+ reg = (card16) cff_dict_get(cffont->topdict, "ROS", 0);
+ ord = (card16) cff_dict_get(cffont->topdict, "ROS", 1);
+ csi.registry = cff_get_string(cffont, reg);
+ csi.ordering = cff_get_string(cffont, ord);
+ csi.supplement = (int) cff_dict_get(cffont->topdict, "ROS", 2);
+ }
+ cff_read_charsets(cffont);
+ create_GIDToCIDMap(GIDToCIDMap, num_glyphs, cffont);
+ }
+ cff_close(cffont);
+ } else {
+ uint16_t gid;
+
+ csi.registry = strdup("Adobe");
+ csi.ordering = strdup("Identity");
+ csi.supplement = 0;
+ for (gid = 0; gid < num_glyphs; gid++) {
+ GIDToCIDMap[gid] = gid;
+ }
+ }
+
+ ttcmap = tt_cmap_read(sfont, 3, 10); /* Microsoft UCS4 */
+ if (!ttcmap) {
+ ttcmap = tt_cmap_read(sfont, 3, 1); /* Microsoft UCS2 */
+ if (!ttcmap) {
+ ttcmap = tt_cmap_read(sfont, 0, 3); /* Unicode 2.0 or later */
+ }
+ }
+
+ if (ttcmap) {
+ CMap *cmap = NULL;
+ int32_t *map_base, *map_sub;
+ otl_gsub *gsub_vert = NULL;
+ otl_gsub *gsub_list = NULL;
+ uint32_t gid;
+
+ if (wmode == 1) {
+ gsub_vert = otl_gsub_new();
+ if (otl_gsub_add_feat(gsub_vert, "*", "*", "vrt2", sfont) < 0) {
+ if (otl_gsub_add_feat(gsub_vert, "*", "*", "vert", sfont) < 0) {
+ WARN("GSUB feature vrt2/vert not found.");
+ otl_gsub_release(gsub_vert);
+ gsub_vert = NULL;
+ } else {
+ otl_gsub_select(gsub_vert, "*", "*", "vert");
+ }
+ } else {
+ otl_gsub_select(gsub_vert, "*", "*", "vrt2");
+ }
+ } else {
+ gsub_vert = NULL;
+ }
+ if (otl_tags) {
+ gsub_list = otl_gsub_new();
+ if (otl_gsub_add_feat_list(gsub_list, otl_tags, sfont) < 0) {
+ WARN("Reading GSUB feature table(s) failed for \"%s\"", otl_tags);
+ } else {
+ otl_gsub_set_chain(gsub_list, otl_tags);
+ }
+ } else {
+ gsub_list = NULL;
+ }
+ cmap = CMap_new();
+ CMap_set_name(cmap, cmap_name);
+ CMap_set_type(cmap, CMAP_TYPE_CODE_TO_CID);
+ CMap_set_wmode(cmap, wmode);
+ CMap_add_codespacerange(cmap, lrange_min, lrange_max, 4);
+ CMap_set_CIDSysInfo(cmap, &csi);
+ map_base = NEW(num_glyphs, int32_t);
+ map_sub = NEW(num_glyphs, int32_t);
+ for (gid = 0; gid < num_glyphs; gid++) {
+ map_base[gid] = -1;
+ map_sub[gid] = -1;
+ }
+ switch (ttcmap->format) {
+ case 12:
+ load_cmap12(ttcmap->map, GIDToCIDMap, num_glyphs,
+ gsub_vert, gsub_list,
+ cmap, map_base, map_sub);
+ break;
+ case 4:
+ load_cmap4(ttcmap->map, GIDToCIDMap, num_glyphs,
+ gsub_vert, gsub_list,
+ cmap, map_base, map_sub);
+ break;
+ }
+ if (gsub_vert)
+ otl_gsub_release(gsub_vert);
+ if (gsub_list)
+ otl_gsub_release(gsub_list);
+ tt_cmap_release(ttcmap);
+
+ if (otl_tags) {
+ CMap *tounicode = NULL;
+ char *tounicode_name;
+ int tounicode_id;
+ size_t name_len;
+
+ name_len = strlen(map_name)+strlen("-UCS32-Add")+32;
+ tounicode_name = NEW(name_len, char);
+ snprintf(tounicode_name, name_len, "%s:%d-UCS32-Add", map_name, ttc_index);
+ tounicode_name[name_len-1] = '\0';
+ tounicode_id = CMap_cache_find(tounicode_name);
+ if (tounicode_id >= 0)
+ tounicode = CMap_cache_get(tounicode_id);
+ else {
+ tounicode = CMap_new();
+ CMap_set_name (tounicode, tounicode_name);
+ CMap_set_type (tounicode, CMAP_TYPE_TO_UNICODE);
+ CMap_set_wmode(tounicode, 0);
+ CMap_add_codespacerange(tounicode, srange_min, srange_max, 2);
+ CMap_set_CIDSysInfo(tounicode, &CSI_UNICODE);
+ CMap_add_bfchar(tounicode, srange_min, 2, srange_max, 2);
+ tounicode_id = CMap_cache_add(tounicode);
+ }
+ RELEASE(tounicode_name);
+
+ for (gid = 0; gid < num_glyphs; gid++) {
+ uint16_t cid = GIDToCIDMap[gid];
+ unsigned char src[2], dst[4];
+ if (cid > 0) {
+ int32_t ch = UC_is_valid(map_base[gid]) ? map_base[gid] : map_sub[gid];
+ if (UC_is_valid(ch)) {
+ unsigned char *p = dst;
+ unsigned char *endptr = dst + 4;
+ size_t len;
+ src[0] = (cid >> 8) & 0xff;
+ src[1] = cid & 0xff;
+ len = UC_UTF16BE_encode_char(ch, &p, endptr);
+ if (len > 0) {
+ CMap_add_bfchar(tounicode, src, 2, dst, len);
+ }
+ }
+ }
+ }
+ }
+ cmap_id = CMap_cache_add(cmap);
+ }
+
+ RELEASE(cmap_name);
+ RELEASE(GIDToCIDMap);
+ if (csi.registry)
+ RELEASE(csi.registry);
+ if (csi.ordering)
+ RELEASE(csi.ordering);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ return cmap_id;
+}
+
+int
+otf_try_load_GID_to_CID_map (const char *map_name, uint32_t ttc_index, int wmode)
+{
+ int cmap_id = -1;
+ sfnt *sfont = NULL;
+ ULONG offset = 0;
+ char *cmap_name = NULL;
+ FILE *fp = NULL;
+ int len;
+
+ if (!map_name)
+ return -1;
+
+ /* Check if already loaded */
+ len = strlen(map_name) + 32;
+ cmap_name = NEW(len, char);
+ snprintf(cmap_name, len, "%s:%d-%1d-GID", map_name, ttc_index, wmode);
+ cmap_name[len-1] = '\0';
+ cmap_id = CMap_cache_find(cmap_name);
+ if (cmap_id >= 0) {
+ RELEASE(cmap_name);
+ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN)
+ MESG("otf_cmap>> GID-to-CID mapping found at cmap_id=%d.\n", cmap_id);
+
+ return cmap_id;
+ }
+
+ fp = DPXFOPEN(map_name, DPX_RES_TYPE_TTFONT);
+ if (!fp) {
+ fp = DPXFOPEN(map_name, DPX_RES_TYPE_OTFONT);
+ }
+ if (!fp) {
+ fp = DPXFOPEN(map_name, DPX_RES_TYPE_DFONT);
+ if (!fp) {
+ RELEASE(cmap_name);
+ return -1;
+ }
+ sfont = dfont_open(fp, ttc_index);
+ } else {
+ sfont = sfnt_open(fp);
+ }
+
+ if (!sfont) {
+ WARN("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name);
+ RELEASE(cmap_name);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ switch (sfont->type) {
+ case SFNT_TYPE_TTC:
+ offset = ttc_read_offset(sfont, ttc_index);
+ if (offset == 0) {
+ WARN("Invalid TTC index for font \"%s\": %d", map_name, ttc_index);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ RELEASE(cmap_name);
+ return -1;
+ }
+ break;
+ case SFNT_TYPE_TRUETYPE:
+ case SFNT_TYPE_POSTSCRIPT:
+ offset = 0;
+ break;
+ case SFNT_TYPE_DFONT:
+ offset = sfont->offset;
+ break;
+ default:
+ WARN("Not a OpenType/TrueType/TTC font?: %s", map_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ RELEASE(cmap_name);
+ return -1;
+ }
+
+ if (sfnt_read_table_directory(sfont, offset) < 0) {
+ WARN("Could not read OpenType/TrueType table directory: %s", map_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ RELEASE(cmap_name);
+ return -1;
+ }
+ if (sfont->type != SFNT_TYPE_POSTSCRIPT) {
+ RELEASE(cmap_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ /* Read GID-to-CID mapping if CFF OpenType is found. */
+ if (sfont->type == SFNT_TYPE_POSTSCRIPT) {
+ cff_font *cffont;
+ struct tt_maxp_table *maxp;
+ const unsigned char csrange[4] = {0x00, 0x00, 0xff, 0xff};
+ uint16_t num_glyphs = 0;
+
+ maxp = tt_read_maxp_table(sfont);
+ num_glyphs = (card16) maxp->numGlyphs;
+ RELEASE(maxp);
+
+ offset = sfnt_find_table_pos(sfont, "CFF ");
+ if (offset == 0) {
+ WARN("PS OpenType but no \"CFF \" table.. Maybe variable font? (not supported)");
+ RELEASE(cmap_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ cffont = cff_open(sfont->stream, offset, 0);
+ if (cffont && cffont->flag & FONTTYPE_CIDFONT) {
+ CMap *cmap;
+ uint16_t gid;
+ uint16_t *GIDToCIDMap = NULL;
+ CIDSysInfo csi = {NULL, NULL, 0};
+
+ if (!cff_dict_known(cffont->topdict, "ROS")) {
+ csi.registry = strdup("Adobe");
+ csi.ordering = strdup("Identity");
+ csi.supplement = 0;
+ } else {
+ card16 reg, ord;
+
+ reg = (card16) cff_dict_get(cffont->topdict, "ROS", 0);
+ ord = (card16) cff_dict_get(cffont->topdict, "ROS", 1);
+ csi.registry = cff_get_string(cffont, reg);
+ csi.ordering = cff_get_string(cffont, ord);
+ csi.supplement = (int) cff_dict_get(cffont->topdict, "ROS", 2);
+ }
+ cff_read_charsets(cffont);
+ GIDToCIDMap = NEW(num_glyphs, uint16_t);
+ memset(GIDToCIDMap, 0, num_glyphs*sizeof(uint16_t));
+ create_GIDToCIDMap(GIDToCIDMap, num_glyphs, cffont);
+ cmap = CMap_new();
+ CMap_set_name (cmap, cmap_name);
+ CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID);
+ CMap_set_wmode(cmap, wmode);
+ CMap_add_codespacerange(cmap, &csrange[0], &csrange[2], 2);
+ CMap_set_CIDSysInfo(cmap, &csi);
+ for (gid = 0; gid < num_glyphs; gid++) {
+ unsigned char src[2], dst[2];
+ src[0] = (gid >> 8) & 0xff;
+ src[1] = gid & 0xff;
+ dst[0] = (GIDToCIDMap[gid] >> 8) & 0xff;
+ dst[1] = GIDToCIDMap[gid] & 0xff;
+ CMap_add_bfchar(cmap, src, 2, dst, 2);
+ }
+ cmap_id = CMap_cache_add(cmap);
+ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("\n");
+ MESG("otf_cmap>> Creating GID-to-CID mapping for font=\"%s\"\n", map_name);
+ }
+ RELEASE(GIDToCIDMap);
+ if (csi.registry)
+ RELEASE(csi.registry);
+ if (csi.ordering)
+ RELEASE(csi.ordering);
+ }
+ if (cffont)
+ cff_close(cffont);
+ }
+
+ RELEASE(cmap_name);
+ sfnt_close(sfont);
+ DPXFCLOSE(fp);
+
+ return cmap_id;
+}
diff --git a/Build/source/texk/dvipdfm-x/tt_cmap.h b/Build/source/texk/dvipdfm-x/tt_cmap.h
new file mode 100644
index 00000000000..439108c4797
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_cmap.h
@@ -0,0 +1,74 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TT_CMAP_H_
+#define _TT_CMAP_H_
+
+#include "sfnt.h"
+
+/* TrueType cmap table */
+typedef struct
+{
+ USHORT format;
+ USHORT platform;
+ USHORT encoding;
+ ULONG language; /* or version, only for Mac */
+ void *map;
+} tt_cmap;
+
+/* Paltform ID */
+#define TT_MAC 1u
+#define TT_WIN 3u
+
+/* Platform-specific encoding ID */
+
+/* Windows */
+#define TT_WIN_SYMBOL 0u
+#define TT_WIN_UNICODE 1u
+#define TT_WIN_SJIS 2u
+#define TT_WIN_RPC 3u
+#define TT_WIN_BIG5 4u
+#define TT_WIN_WANSUNG 5u
+#define TT_WIN_JOHAB 6u
+#define TT_WIN_UCS4 10u
+
+/* Mac */
+#define TT_MAC_ROMAN 0u
+#define TT_MAC_JAPANESE 1u
+#define TT_MAC_TRADITIONAL_CHINESE 2u
+#define TT_MAC_KOREAN 3u
+#define TT_MAC_SIMPLIFIED_CHINESE 25u
+
+extern tt_cmap *tt_cmap_read (sfnt *sfont, USHORT platform, USHORT encoding);
+
+extern USHORT tt_cmap_lookup (tt_cmap *cmap, ULONG cc);
+extern void tt_cmap_release (tt_cmap *cmap);
+
+#include "pdfobj.h"
+
+/* Indirect reference */
+extern pdf_obj *otf_create_ToUnicode_stream (const char *map_name,
+ uint32_t ttc_index,
+ const char *basefont,
+ const char *used_chars);
+/* CMap ID */
+extern int otf_load_Unicode_CMap (const char *map_name, uint32_t ttc_index, const char *otl_opts, int wmode);
+extern int otf_try_load_GID_to_CID_map (const char *map_name, uint32_t ttc_index, int wmode);
+#endif /* _TT_CMAP_H_ */
diff --git a/Build/source/texk/dvipdfm-x/tt_glyf.c b/Build/source/texk/dvipdfm-x/tt_glyf.c
new file mode 100644
index 00000000000..2f393016f42
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_glyf.c
@@ -0,0 +1,659 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * Subsetting glyf, updating loca, hmtx, ...
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxutil.h"
+
+#include "sfnt.h"
+#include "tt_table.h"
+#include "tt_glyf.h"
+
+#define NUM_GLYPH_LIMIT 65534
+#define TABLE_DATA_ALLOC_SIZE 40960
+#define GLYPH_ARRAY_ALLOC_SIZE 256
+
+static USHORT
+find_empty_slot (struct tt_glyphs *g)
+{
+ USHORT gid;
+
+ ASSERT(g);
+
+ for (gid = 0; gid < NUM_GLYPH_LIMIT; gid++) {
+ if (!(g->used_slot[gid/8] & (1 << (7 - (gid % 8)))))
+ break;
+ }
+ if (gid == NUM_GLYPH_LIMIT)
+ ERROR("No empty glyph slot available.");
+
+ return gid;
+}
+
+USHORT
+tt_find_glyph (struct tt_glyphs *g, USHORT gid)
+{
+ USHORT idx, new_gid = 0;
+
+ ASSERT(g);
+
+ for (idx = 0; idx < g->num_glyphs; idx++) {
+ if (gid == g->gd[idx].ogid) {
+ new_gid = g->gd[idx].gid;
+ break;
+ }
+ }
+
+ return new_gid;
+}
+
+USHORT
+tt_get_index (struct tt_glyphs *g, USHORT gid)
+{
+ USHORT idx;
+
+ ASSERT(g);
+
+ for (idx = 0; idx < g->num_glyphs; idx++) {
+ if (gid == g->gd[idx].gid)
+ break;
+ }
+ if (idx == g->num_glyphs)
+ idx = 0;
+
+ return idx;
+}
+
+USHORT
+tt_add_glyph (struct tt_glyphs *g, USHORT gid, USHORT new_gid)
+{
+ ASSERT(g);
+
+ if (g->used_slot[new_gid/8] & (1 << (7 - (new_gid % 8)))) {
+ WARN("Slot %u already used.", new_gid);
+ } else {
+ if (g->num_glyphs+1 >= NUM_GLYPH_LIMIT)
+ ERROR("Too many glyphs.");
+
+ if (g->num_glyphs >= g->max_glyphs) {
+ g->max_glyphs += GLYPH_ARRAY_ALLOC_SIZE;
+ g->gd = RENEW(g->gd, g->max_glyphs, struct tt_glyph_desc);
+ }
+ g->gd[g->num_glyphs].gid = new_gid;
+ g->gd[g->num_glyphs].ogid = gid;
+ g->gd[g->num_glyphs].length = 0;
+ g->gd[g->num_glyphs].data = NULL;
+ g->used_slot[new_gid/8] |= (1 << (7 - (new_gid % 8)));
+ g->num_glyphs += 1;
+ }
+
+ if (new_gid > g->last_gid) {
+ g->last_gid = new_gid;
+ }
+
+ return new_gid;
+}
+
+/*
+ * Initialization
+ */
+struct tt_glyphs *
+tt_build_init (void)
+{
+ struct tt_glyphs *g;
+
+ g = NEW(1, struct tt_glyphs);
+
+ g->num_glyphs = 0;
+ g->max_glyphs = 0;
+ g->last_gid = 0;
+ g->emsize = 1;
+ g->default_advh = 0;
+ g->default_tsb = 0;
+ g->gd = NULL;
+ g->used_slot = NEW(8192, unsigned char);
+ memset(g->used_slot, 0, 8192);
+ tt_add_glyph(g, 0, 0);
+
+ return g;
+}
+
+void
+tt_build_finish (struct tt_glyphs *g)
+{
+ if (g) {
+ if (g->gd) {
+ USHORT idx;
+ for (idx = 0; idx < g->num_glyphs; idx++) {
+ if (g->gd[idx].data)
+ RELEASE(g->gd[idx].data);
+ }
+ RELEASE(g->gd);
+ }
+ if (g->used_slot)
+ RELEASE(g->used_slot);
+ RELEASE(g);
+ }
+}
+
+static inline int
+glyf_cmp (const void *v1, const void *v2)
+{
+ int cmp = 0;
+ const struct tt_glyph_desc *sv1, *sv2;
+
+ sv1 = (const struct tt_glyph_desc *) v1;
+ sv2 = (const struct tt_glyph_desc *) v2;
+
+ if (sv1->gid == sv2->gid)
+ cmp = 0;
+ else if (sv1->gid < sv2->gid)
+ cmp = -1;
+ else
+ cmp = 1;
+
+ return cmp;
+}
+
+/*
+ * TrueType outline data.
+ */
+#define ARG_1_AND_2_ARE_WORDS (1 << 0)
+#define ARGS_ARE_XY_VALUES (1 << 1)
+#define ROUND_XY_TO_GRID (1 << 2)
+#define WE_HAVE_A_SCALE (1 << 3)
+#define RESERVED (1 << 4)
+#define MORE_COMPONENT (1 << 5)
+#define WE_HAVE_AN_X_AND_Y_SCALE (1 << 6)
+#define WE_HAVE_A_TWO_BY_TWO (1 << 7)
+#define WE_HAVE_INSTRUCTIONS (1 << 8)
+#define USE_MY_METRICS (1 << 9)
+
+int
+tt_build_tables (sfnt *sfont, struct tt_glyphs *g)
+{
+ char *hmtx_table_data = NULL, *loca_table_data = NULL;
+ char *glyf_table_data = NULL;
+ ULONG hmtx_table_size, loca_table_size, glyf_table_size;
+ /* some information available from other TrueType table */
+ struct tt_head_table *head = NULL;
+ struct tt_hhea_table *hhea = NULL;
+ struct tt_maxp_table *maxp = NULL;
+ struct tt_longMetrics *hmtx, *vmtx = NULL;
+ struct tt_os2__table *os2;
+ /* temp */
+ ULONG *location, offset;
+ int i;
+ USHORT *w_stat; /* Estimate most frequently appeared width */
+
+ ASSERT(g);
+
+ if (sfont == NULL || sfont->stream == NULL)
+ ERROR("File not opened.");
+
+ if (sfont->type != SFNT_TYPE_TRUETYPE &&
+ sfont->type != SFNT_TYPE_TTC &&
+ sfont->type != SFNT_TYPE_DFONT)
+ ERROR("Invalid font type");
+
+ if (g->num_glyphs > NUM_GLYPH_LIMIT)
+ ERROR("Too many glyphs.");
+
+ /*
+ * Read head, hhea, maxp, loca:
+ *
+ * unitsPerEm --> head
+ * numHMetrics --> hhea
+ * indexToLocFormat --> head
+ * numGlyphs --> maxp
+ */
+ head = tt_read_head_table(sfont);
+ hhea = tt_read_hhea_table(sfont);
+ maxp = tt_read_maxp_table(sfont);
+
+ if (hhea->metricDataFormat != 0)
+ ERROR("Unknown metricDataFormat.");
+
+ g->emsize = head->unitsPerEm;
+
+ sfnt_locate_table(sfont, "hmtx");
+ hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings);
+
+ os2 = tt_read_os2__table(sfont);
+ if (os2) {
+ g->default_advh = os2->sTypoAscender - os2->sTypoDescender;
+ g->default_tsb = g->default_advh - os2->sTypoAscender;
+ }
+
+ if (sfnt_find_table_pos(sfont, "vmtx") > 0) {
+ struct tt_vhea_table *vhea;
+ vhea = tt_read_vhea_table(sfont);
+ sfnt_locate_table(sfont, "vmtx");
+ vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics, vhea->numOfExSideBearings);
+ RELEASE(vhea);
+ } else {
+ vmtx = NULL;
+ }
+
+ sfnt_locate_table(sfont, "loca");
+ location = NEW(maxp->numGlyphs + 1, ULONG);
+ if (head->indexToLocFormat == 0) {
+ for (i = 0; i <= maxp->numGlyphs; i++)
+ location[i] = 2*((ULONG) sfnt_get_ushort(sfont));
+ } else if (head->indexToLocFormat == 1) {
+ for (i = 0; i <= maxp->numGlyphs; i++)
+ location[i] = sfnt_get_ulong(sfont);
+ } else {
+ ERROR("Unknown IndexToLocFormat.");
+ }
+
+ w_stat = NEW(g->emsize+2, USHORT);
+ memset(w_stat, 0, sizeof(USHORT)*(g->emsize+2));
+ /*
+ * Read glyf table.
+ */
+ offset = sfnt_locate_table(sfont, "glyf");
+ /*
+ * The num_glyphs may grow when composite glyph is found.
+ * A component of glyph refered by a composite glyph is appended
+ * to used_glyphs if it is not already registered in used_glyphs.
+ * Glyph programs of composite glyphs are modified so that it
+ * correctly refer to new gid of their components.
+ */
+ for (i = 0; i < NUM_GLYPH_LIMIT; i++) {
+ USHORT gid; /* old gid */
+ ULONG loc, len;
+ BYTE *p, *endptr;
+ SHORT number_of_contours;
+
+ if (i >= g->num_glyphs) /* finished */
+ break;
+
+ gid = g->gd[i].ogid;
+ if (gid >= maxp->numGlyphs)
+ ERROR("Invalid glyph index (gid %u)", gid);
+
+ loc = location[gid];
+ len = location[gid+1] - loc;
+ g->gd[i].advw = hmtx[gid].advance;
+ g->gd[i].lsb = hmtx[gid].sideBearing;
+ if (vmtx) {
+ g->gd[i].advh = vmtx[gid].advance;
+ g->gd[i].tsb = vmtx[gid].sideBearing;
+ } else {
+ g->gd[i].advh = g->default_advh;
+ g->gd[i].tsb = g->default_tsb;
+ }
+ g->gd[i].length = len;
+ g->gd[i].data = NULL;
+ if (g->gd[i].advw <= g->emsize) {
+ w_stat[g->gd[i].advw] += 1;
+ } else {
+ w_stat[g->emsize+1] += 1; /* larger than em */
+ }
+
+ if (len == 0) { /* Does not contains any data. */
+ continue;
+ } else if (len < 10) {
+ ERROR("Invalid TrueType glyph data (gid %u).", gid);
+ }
+
+ g->gd[i].data = p = NEW(len, BYTE);
+ endptr = p + len;
+
+ sfnt_seek_set(sfont, offset+loc);
+ number_of_contours = sfnt_get_short(sfont);
+ p += sfnt_put_short(p, number_of_contours);
+
+ /* BoundingBox: FWord x 4 */
+ g->gd[i].llx = sfnt_get_short(sfont);
+ g->gd[i].lly = sfnt_get_short(sfont);
+ g->gd[i].urx = sfnt_get_short(sfont);
+ g->gd[i].ury = sfnt_get_short(sfont);
+ /* _FIXME_ */
+#if 1
+ if (!vmtx) /* vertOriginY == sTypeAscender */
+ g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury;
+#endif
+ p += sfnt_put_short(p, g->gd[i].llx);
+ p += sfnt_put_short(p, g->gd[i].lly);
+ p += sfnt_put_short(p, g->gd[i].urx);
+ p += sfnt_put_short(p, g->gd[i].ury);
+
+ /* Read evrything else. */
+ sfnt_read(p, len - 10, sfont);
+ /*
+ * Fix GIDs of composite glyphs.
+ */
+ if (number_of_contours < 0) {
+ USHORT flags, cgid, new_gid; /* flag, gid of a component */
+ do {
+ if (p >= endptr)
+ ERROR("Invalid TrueType glyph data (gid %u): %u bytes", gid, len);
+ /*
+ * Flags and gid of component glyph are both USHORT.
+ */
+ flags = ((*p) << 8)| *(p+1);
+ p += 2;
+ cgid = ((*p) << 8)| *(p+1);
+ if (cgid >= maxp->numGlyphs) {
+ ERROR("Invalid gid (%u > %u) in composite glyph %u.", cgid, maxp->numGlyphs, gid);
+ }
+ new_gid = tt_find_glyph(g, cgid);
+ if (new_gid == 0) {
+ new_gid = tt_add_glyph(g, cgid, find_empty_slot(g));
+ }
+ p += sfnt_put_ushort(p, new_gid);
+ /*
+ * Just skip remaining part.
+ */
+ p += (flags & ARG_1_AND_2_ARE_WORDS) ? 4 : 2;
+ if (flags & WE_HAVE_A_SCALE) /* F2Dot14 */
+ p += 2;
+ else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) /* F2Dot14 x 2 */
+ p += 4;
+ else if (flags & WE_HAVE_A_TWO_BY_TWO) /* F2Dot14 x 4 */
+ p += 8;
+ } while (flags & MORE_COMPONENT);
+ /*
+ * TrueType instructions comes here:
+ * length_of_instruction (ushort)
+ * instruction (byte * length_of_instruction)
+ */
+ }
+ }
+ RELEASE(location);
+ RELEASE(hmtx);
+ if (vmtx)
+ RELEASE(vmtx);
+
+ {
+ int max_count = -1;
+
+ g->dw = g->gd[0].advw;
+ for (i = 0; i < g->emsize + 1; i++) {
+ if (w_stat[i] > max_count) {
+ max_count = w_stat[i];
+ g->dw = i;
+ }
+ }
+ }
+ RELEASE(w_stat);
+
+ qsort(g->gd, g->num_glyphs, sizeof(struct tt_glyph_desc), glyf_cmp);
+ {
+ USHORT prev, last_advw;
+ char *p, *q;
+ int padlen, num_hm_known;
+
+ glyf_table_size = 0UL;
+ num_hm_known = 0;
+ last_advw = g->gd[g->num_glyphs - 1].advw;
+ for (i = g->num_glyphs - 1; i >= 0; i--) {
+ padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0;
+ glyf_table_size += g->gd[i].length + padlen;
+ if (!num_hm_known && last_advw != g->gd[i].advw) {
+ hhea->numOfLongHorMetrics = g->gd[i].gid + 2;
+ num_hm_known = 1;
+ }
+ }
+ /* All advance widths are same. */
+ if (!num_hm_known) {
+ hhea->numOfLongHorMetrics = 1;
+ }
+ hmtx_table_size = hhea->numOfLongHorMetrics * 2 + (g->last_gid + 1) * 2;
+
+ /*
+ * Choosing short format does not always give good result
+ * when compressed. Sometimes increases size.
+ */
+ if (glyf_table_size < 0x20000UL) {
+ head->indexToLocFormat = 0;
+ loca_table_size = (g->last_gid + 2)*2;
+ } else {
+ head->indexToLocFormat = 1;
+ loca_table_size = (g->last_gid + 2)*4;
+ }
+
+ hmtx_table_data = p = NEW(hmtx_table_size, char);
+ loca_table_data = q = NEW(loca_table_size, char);
+ glyf_table_data = NEW(glyf_table_size, char);
+
+ offset = 0UL; prev = 0;
+ for (i = 0; i < g->num_glyphs; i++) {
+ int gap, j;
+ gap = g->gd[i].gid - prev - 1;
+ for (j = 1; j <= gap; j++) {
+ if (prev + j == hhea->numOfLongHorMetrics - 1) {
+ p += sfnt_put_ushort(p, last_advw);
+ } else if (prev + j < hhea->numOfLongHorMetrics) {
+ p += sfnt_put_ushort(p, 0);
+ }
+ p += sfnt_put_short (p, 0);
+ if (head->indexToLocFormat == 0) {
+ q += sfnt_put_ushort(q, (USHORT) (offset/2));
+ } else {
+ q += sfnt_put_ulong(q, offset);
+ }
+ }
+ padlen = (g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0;
+ if (g->gd[i].gid < hhea->numOfLongHorMetrics) {
+ p += sfnt_put_ushort(p, g->gd[i].advw);
+ }
+ p += sfnt_put_short (p, g->gd[i].lsb);
+ if (head->indexToLocFormat == 0) {
+ q += sfnt_put_ushort(q, (USHORT) (offset/2));
+ } else {
+ q += sfnt_put_ulong(q, offset);
+ }
+ memset(glyf_table_data + offset, 0, g->gd[i].length + padlen);
+ memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length);
+ offset += g->gd[i].length + padlen;
+ prev = g->gd[i].gid;
+ /* free data here since it consume much memory */
+ RELEASE(g->gd[i].data);
+ g->gd[i].length = 0; g->gd[i].data = NULL;
+ }
+ if (head->indexToLocFormat == 0) {
+ q += sfnt_put_ushort(q, (USHORT) (offset/2));
+ } else {
+ q += sfnt_put_ulong(q, offset);
+ }
+
+ sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data, hmtx_table_size);
+ sfnt_set_table(sfont, "loca", (char *) loca_table_data, loca_table_size);
+ sfnt_set_table(sfont, "glyf", (char *) glyf_table_data, glyf_table_size);
+ }
+
+ head->checkSumAdjustment = 0;
+ maxp->numGlyphs = g->last_gid + 1;
+
+ /* TODO */
+ sfnt_set_table(sfont, "maxp", tt_pack_maxp_table(maxp), TT_MAXP_TABLE_SIZE);
+ sfnt_set_table(sfont, "hhea", tt_pack_hhea_table(hhea), TT_HHEA_TABLE_SIZE);
+ sfnt_set_table(sfont, "head", tt_pack_head_table(head), TT_HEAD_TABLE_SIZE);
+ RELEASE(maxp);
+ RELEASE(hhea);
+ RELEASE(head);
+ if (os2)
+ RELEASE(os2);
+
+ return 0;
+}
+
+int
+tt_get_metrics (sfnt *sfont, struct tt_glyphs *g)
+{
+ struct tt_head_table *head = NULL;
+ struct tt_hhea_table *hhea = NULL;
+ struct tt_maxp_table *maxp = NULL;
+ struct tt_longMetrics *hmtx, *vmtx = NULL;
+ struct tt_os2__table *os2;
+ /* temp */
+ ULONG *location, offset;
+ int i;
+ USHORT *w_stat;
+
+ ASSERT(g);
+
+ if (sfont == NULL || sfont->stream == NULL)
+ ERROR("File not opened.");
+
+ if (sfont->type != SFNT_TYPE_TRUETYPE &&
+ sfont->type != SFNT_TYPE_TTC &&
+ sfont->type != SFNT_TYPE_DFONT)
+ ERROR("Invalid font type");
+
+ /*
+ * Read head, hhea, maxp, loca:
+ *
+ * unitsPerEm --> head
+ * numHMetrics --> hhea
+ * indexToLocFormat --> head
+ * numGlyphs --> maxp
+ */
+ head = tt_read_head_table(sfont);
+ hhea = tt_read_hhea_table(sfont);
+ maxp = tt_read_maxp_table(sfont);
+
+ if (hhea->metricDataFormat != 0)
+ ERROR("Unknown metricDataFormat.");
+
+ g->emsize = head->unitsPerEm;
+
+ sfnt_locate_table(sfont, "hmtx");
+ hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings);
+
+ os2 = tt_read_os2__table(sfont);
+ g->default_advh = os2->sTypoAscender - os2->sTypoDescender;
+ g->default_tsb = g->default_advh - os2->sTypoAscender;
+
+ if (sfnt_find_table_pos(sfont, "vmtx") > 0) {
+ struct tt_vhea_table *vhea;
+ vhea = tt_read_vhea_table(sfont);
+ sfnt_locate_table(sfont, "vmtx");
+ vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics, vhea->numOfExSideBearings);
+ RELEASE(vhea);
+ } else {
+ vmtx = NULL;
+ }
+
+ sfnt_locate_table(sfont, "loca");
+ location = NEW(maxp->numGlyphs + 1, ULONG);
+ if (head->indexToLocFormat == 0) {
+ for (i = 0; i <= maxp->numGlyphs; i++)
+ location[i] = 2*((ULONG) sfnt_get_ushort(sfont));
+ } else if (head->indexToLocFormat == 1) {
+ for (i = 0; i <= maxp->numGlyphs; i++)
+ location[i] = sfnt_get_ulong(sfont);
+ } else {
+ ERROR("Unknown IndexToLocFormat.");
+ }
+
+ w_stat = NEW(g->emsize+2, USHORT);
+ memset(w_stat, 0, sizeof(USHORT)*(g->emsize+2));
+ /*
+ * Read glyf table.
+ */
+ offset = sfnt_locate_table(sfont, "glyf");
+ for (i = 0; i < g->num_glyphs; i++) {
+ USHORT gid; /* old gid */
+ ULONG loc, len;
+
+ gid = g->gd[i].ogid;
+ if (gid >= maxp->numGlyphs)
+ ERROR("Invalid glyph index (gid %u)", gid);
+
+ loc = location[gid];
+ len = location[gid+1] - loc;
+ g->gd[i].advw = hmtx[gid].advance;
+ g->gd[i].lsb = hmtx[gid].sideBearing;
+ if (vmtx) {
+ g->gd[i].advh = vmtx[gid].advance;
+ g->gd[i].tsb = vmtx[gid].sideBearing;
+ } else {
+ g->gd[i].advh = g->default_advh;
+ g->gd[i].tsb = g->default_tsb;
+ }
+ g->gd[i].length = len;
+ g->gd[i].data = NULL;
+
+ if (g->gd[i].advw <= g->emsize) {
+ w_stat[g->gd[i].advw] += 1;
+ } else {
+ w_stat[g->emsize+1] += 1; /* larger than em */
+ }
+
+ if (len == 0) { /* Does not contains any data. */
+ continue;
+ } else if (len < 10) {
+ ERROR("Invalid TrueType glyph data (gid %u).", gid);
+ }
+
+ sfnt_seek_set(sfont, offset+loc);
+ (void) sfnt_get_short(sfont);
+
+ /* BoundingBox: FWord x 4 */
+ g->gd[i].llx = sfnt_get_short(sfont);
+ g->gd[i].lly = sfnt_get_short(sfont);
+ g->gd[i].urx = sfnt_get_short(sfont);
+ g->gd[i].ury = sfnt_get_short(sfont);
+ /* _FIXME_ */
+#if 1
+ if (!vmtx) /* vertOriginY == sTypeAscender */
+ g->gd[i].tsb = g->default_advh - g->default_tsb - g->gd[i].ury;
+#endif
+ }
+ RELEASE(location);
+ RELEASE(hmtx);
+ RELEASE(maxp);
+ RELEASE(hhea);
+ RELEASE(head);
+ RELEASE(os2);
+
+ if (vmtx)
+ RELEASE(vmtx);
+
+ {
+ int max_count = -1;
+
+ g->dw = g->gd[0].advw;
+ for (i = 0; i < g->emsize + 1; i++) {
+ if (w_stat[i] > max_count) {
+ max_count = w_stat[i];
+ g->dw = i;
+ }
+ }
+ }
+ RELEASE(w_stat);
+
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/tt_glyf.h b/Build/source/texk/dvipdfm-x/tt_glyf.h
new file mode 100644
index 00000000000..6370dbc4f17
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_glyf.h
@@ -0,0 +1,58 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TT_GLYF_H_
+#define _TT_GLYF_H_
+
+struct tt_glyph_desc
+{
+ USHORT gid;
+ USHORT ogid; /* GID in original font */
+ USHORT advw, advh;
+ SHORT lsb, tsb;
+ SHORT llx, lly, urx, ury;
+ ULONG length;
+ BYTE *data;
+};
+
+struct tt_glyphs
+{
+ USHORT num_glyphs;
+ USHORT max_glyphs;
+ USHORT last_gid;
+ USHORT emsize;
+ USHORT dw; /* optimal value for DW */
+ USHORT default_advh; /* default value */
+ SHORT default_tsb; /* default value */
+ struct tt_glyph_desc *gd;
+ unsigned char *used_slot;
+};
+
+extern struct tt_glyphs *tt_build_init (void);
+extern void tt_build_finish (struct tt_glyphs *g);
+
+extern USHORT tt_add_glyph (struct tt_glyphs *g, USHORT gid, USHORT new_gid);
+extern USHORT tt_get_index (struct tt_glyphs *g, USHORT gid);
+extern USHORT tt_find_glyph (struct tt_glyphs *g, USHORT gid);
+
+extern int tt_build_tables (sfnt *sfont, struct tt_glyphs *g);
+extern int tt_get_metrics (sfnt *sfont, struct tt_glyphs *g);
+
+#endif /* _TT_GLYF_H_ */
diff --git a/Build/source/texk/dvipdfm-x/tt_gsub.c b/Build/source/texk/dvipdfm-x/tt_gsub.c
new file mode 100644
index 00000000000..e99908a39fe
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_gsub.c
@@ -0,0 +1,2021 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * TrueType GSUB support: (incomplete)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+
+#include "error.h"
+#include "mem.h"
+#include "mfileio.h"
+#include "dpxconf.h"
+
+#include "sfnt.h"
+
+#include "otl_opt.h"
+#include "tt_gsub.h"
+
+#define VERBOSE_LEVEL_MIN 2
+
+typedef USHORT Offset;
+typedef USHORT GlyphID;
+
+/* OpenType Common Layout Table */
+/* Records */
+struct clt_record
+{
+ char tag[5]; /* 4-byte identifier */
+ Offset offset;
+};
+
+/* Ranges */
+/* RangeRecord */
+struct clt_range
+{
+ GlyphID Start; /* First GlyphID in the range */
+ GlyphID End; /* Last GlyphID in the range */
+ USHORT StartCoverageIndex; /* Converage Index of first GID */
+};
+
+static int
+clt_read_record (struct clt_record *rec, sfnt *sfont)
+{
+ int i;
+
+ ASSERT(rec && sfont);
+
+ for (i = 0; i < 4; i++) {
+ rec->tag[i] = sfnt_get_char(sfont);
+ }
+ rec->tag[4] = '\0';
+ rec->offset = sfnt_get_ushort(sfont);
+
+ return 6;
+}
+
+static int
+clt_read_range (struct clt_range *rec, sfnt *sfont)
+{
+ ASSERT(rec && sfont);
+
+ rec->Start = sfnt_get_ushort(sfont);
+ rec->End = sfnt_get_ushort(sfont);
+ rec->StartCoverageIndex = sfnt_get_ushort(sfont);
+
+ return 6;
+}
+
+/*
+ List structure:
+ ScriptRecord (records), FeatureRecord (records), Lookup (offsets)
+*/
+
+struct clt_record_list
+{
+ USHORT count;
+ struct clt_record *record;
+};
+
+/* offset and index list, Offset is USHORT */
+struct clt_number_list
+{
+ USHORT count;
+ USHORT *value;
+};
+
+static int
+clt_read_record_list (struct clt_record_list *list, sfnt *sfont)
+{
+ int len, i;
+
+ ASSERT(list && sfont);
+
+ list->count = sfnt_get_ushort(sfont);
+ len = 2;
+
+ if (list->count == 0)
+ list->record = NULL;
+ else {
+ list->record = NEW(list->count, struct clt_record);
+ for (i = 0; i < list->count; i++) {
+ len += clt_read_record(&(list->record[i]), sfont);
+ }
+ }
+
+ return len;
+}
+
+static void
+clt_release_record_list (struct clt_record_list *list)
+{
+ if (list) {
+ if (list->record)
+ RELEASE(list->record);
+ list->record = NULL;
+ list->count = 0;
+ }
+}
+
+static int
+clt_read_number_list (struct clt_number_list *list, sfnt *sfont)
+{
+ int i;
+
+ ASSERT(list && sfont);
+
+ list->count = sfnt_get_ushort(sfont);
+
+ if (list->count == 0)
+ list->value = NULL;
+ else {
+ list->value = NEW(list->count, USHORT);
+ for (i = 0; i < list->count; i++) {
+ list->value[i] = sfnt_get_ushort(sfont);
+ }
+ }
+
+ return (2 + 2 * list->count);
+}
+
+static void
+clt_release_number_list (struct clt_number_list *list)
+{
+ if (list) {
+ if (list->value)
+ RELEASE(list->value);
+ list->value = NULL;
+ list->count = 0;
+ }
+}
+
+/*
+ * Tables
+ */
+
+
+/* Coverage Table: format 1 and format 2 */
+struct clt_coverage
+{
+ USHORT format; /* Format identifier: 1 (list), 2 (range) */
+ USHORT count; /* Glyphs/Range Count */
+ GlyphID *list; /* Array of GlyphIDs - in numerical order */
+ struct clt_range *range; /* Array of glyph ranges
+ * - ordered by Start GlyphID
+ */
+};
+
+/* GSUB - The Glyph Substitution Table */
+struct otl_gsub_header
+{
+ Fixed version; /* 0x00010000 */
+ Offset ScriptList; /* offset */
+ Offset FeatureList; /* offset */
+ Offset LookupList; /* offset */
+};
+
+/* Single Substitution Format 1 */
+struct otl_gsub_single1
+{
+ SHORT DeltaGlyphID; /* Add to original GlyphID to get
+ * substitute GlyphID */
+ struct clt_coverage coverage; /* Coverage table */
+};
+
+/* Single Substitution Format 2 */
+struct otl_gsub_single2
+{
+ USHORT GlyphCount; /* Number of GlyphIDs in the Substitute array */
+ GlyphID *Substitute; /* Array of substitute GlyphIDs
+ * - ordered by Coverage Index */
+ struct clt_coverage coverage; /* Coverage table */
+};
+
+/* Alternate Subsutitution Format 1 */
+struct otl_gsub_altset
+{
+ USHORT GlyphCount; /* Number of GlyphIDs in the Alternate array */
+ GlyphID *Alternate; /* Array of alternate GlyphIDs
+ * - in arbitrary order
+ */
+};
+
+struct otl_gsub_alternate1
+{
+ USHORT AlternateSetCount;
+ struct otl_gsub_altset *AlternateSet;
+
+ struct clt_coverage coverage;
+};
+
+/* Faithfull */
+struct otl_gsub_ligtab
+{
+ GlyphID LigGlyph; /* GlyphID of ligature glyph */
+ USHORT CompCount;
+ GlyphID *Component; /* CompCount - 1 elements
+ * First component excluded.
+ * Ordered in writing direction...
+ */
+};
+
+struct otl_gsub_ligset
+{
+ USHORT LigatureCount;
+ struct otl_gsub_ligtab *Ligature;
+};
+
+struct otl_gsub_ligature1
+{
+ USHORT LigSetCount;
+ struct otl_gsub_ligset *LigatureSet;
+
+ struct clt_coverage coverage;
+};
+
+/* GSUB subtable (single) */
+struct otl_gsub_subtab
+{
+ USHORT LookupType; /* FIXME */
+
+ USHORT SubstFormat;
+ union {
+ struct otl_gsub_single1 *single1;
+ struct otl_gsub_single2 *single2;
+ struct otl_gsub_alternate1 *alternate1;
+ struct otl_gsub_ligature1 *ligature1;
+ } table;
+};
+
+/* Script Table */
+struct clt_script_table
+{
+ Offset DefaultLangSys;
+ struct clt_record_list LangSysRecord;
+};
+
+static int
+clt_read_script_table (struct clt_script_table *tab, sfnt *sfont)
+{
+ int len;
+
+ ASSERT(tab && sfont);
+
+ tab->DefaultLangSys = sfnt_get_ushort(sfont);
+ len = 2;
+ len += clt_read_record_list(&tab->LangSysRecord, sfont);
+
+ return len;
+}
+
+static void
+clt_release_script_table (struct clt_script_table *tab)
+{
+ if (tab)
+ clt_release_record_list(&tab->LangSysRecord);
+}
+
+/* LangSys Table */
+struct clt_langsys_table
+{
+ Offset LookupOrder; /* reserved */
+ USHORT ReqFeatureIndex;
+ struct clt_number_list FeatureIndex; /* Array of indices into the
+ * FeatureList in arbitary order.
+ */
+};
+
+static int
+clt_read_langsys_table (struct clt_langsys_table *tab, sfnt *sfont)
+{
+ int len;
+
+ ASSERT(tab && sfont);
+
+ tab->LookupOrder = sfnt_get_ushort(sfont);
+ tab->ReqFeatureIndex = sfnt_get_ushort(sfont);
+ len = 4;
+ len += clt_read_number_list(&tab->FeatureIndex, sfont);
+
+ return len;
+}
+
+static void
+clt_release_langsys_table (struct clt_langsys_table *tab)
+{
+ if (tab)
+ clt_release_number_list(&tab->FeatureIndex);
+}
+
+
+/* Feature Table */
+struct clt_feature_table
+{
+ Offset FeatureParams;
+ struct clt_number_list LookupListIndex; /* LookupListIndex List */
+};
+
+static int
+clt_read_feature_table (struct clt_feature_table *tab, sfnt *sfont)
+{
+ int len;
+
+ ASSERT(tab && sfont);
+
+ tab->FeatureParams = sfnt_get_ushort(sfont);
+ len = 2;
+ len += clt_read_number_list(&tab->LookupListIndex, sfont);
+
+ return len;
+}
+
+static void
+clt_release_feature_table (struct clt_feature_table *tab)
+{
+ if (tab)
+ clt_release_number_list(&tab->LookupListIndex);
+}
+
+/* Lookup Table:
+ * Currently, only single substitution is supported.
+ * LookupFlag is ignored.
+ */
+struct clt_lookup_table
+{
+ USHORT LookupType; /* Different enumerations for GSUB and GPOS */
+ USHORT LookupFlag; /* Lookup qualifiers */
+ struct clt_number_list SubTableList; /* offset */
+ /* offset is from beginning of Lookup table */
+};
+
+static int
+clt_read_lookup_table (struct clt_lookup_table *tab, sfnt *sfont)
+{
+ int len;
+
+ ASSERT(tab && sfont);
+
+ tab->LookupType = sfnt_get_ushort(sfont);
+ tab->LookupFlag = sfnt_get_ushort(sfont);
+ len = 4;
+ len += clt_read_number_list(&tab->SubTableList, sfont);
+
+ return len;
+}
+
+static void
+clt_release_lookup_table (struct clt_lookup_table *tab)
+{
+ if (tab)
+ clt_release_number_list(&tab->SubTableList);
+}
+
+static int
+clt_read_coverage (struct clt_coverage *cov, sfnt *sfont)
+{
+ int len, i;
+
+ ASSERT(cov && sfont);
+
+ cov->format = sfnt_get_ushort(sfont);
+ cov->count = sfnt_get_ushort(sfont);
+ len = 4;
+
+ switch (cov->format) {
+ case 1: /* list */
+ if (cov->count == 0)
+ cov->list = NULL;
+ else {
+ cov->list = NEW(cov->count, USHORT);
+ for (i = 0; i < cov->count; i++) {
+ cov->list[i] = sfnt_get_ushort(sfont);
+ }
+ }
+ cov->range = NULL;
+ len += 2 * cov->count;
+ break;
+ case 2: /* range */
+ if (cov->count == 0)
+ cov->range = NULL;
+ else {
+ cov->range = NEW(cov->count, struct clt_range);
+ for (i = 0; i < cov->count; i++) {
+ len += clt_read_range(&(cov->range[i]), sfont);
+ }
+ }
+ cov->list = NULL;
+ break;
+ default:
+ ERROR("Unknown coverage format");
+ }
+
+ return len;
+}
+
+static void
+clt_release_coverage (struct clt_coverage *cov)
+{
+ if (cov) {
+ switch (cov->format) {
+ case 1: /* list */
+ if (cov->list)
+ RELEASE(cov->list);
+ cov->list = NULL;
+ break;
+ case 2: /* range */
+ if (cov->range)
+ RELEASE(cov->range);
+ cov->range = NULL;
+ break;
+ default:
+ ERROR("Unknown coverage format");
+ }
+ }
+ cov->count = 0;
+}
+
+/* returns -1 if not found */
+static int
+clt_lookup_coverage (struct clt_coverage *cov, USHORT gid)
+{
+ int i;
+
+ ASSERT(cov);
+
+ switch (cov->format) {
+ case 1: /* list */
+ for (i = 0; i < cov->count; i++) {
+ if (cov->list[i] > gid) {
+ break;
+ } else if (cov->list[i] == gid) {
+ return i; /* found */
+ }
+ }
+ break;
+ case 2: /* range */
+ for (i = 0; i < cov->count; i++) {
+ if (gid < cov->range[i].Start) {
+ break;
+ } else if (gid <= cov->range[i].End) { /* found */
+ return (cov->range[i].StartCoverageIndex +
+ gid - cov->range[i].Start);
+ }
+ }
+ break;
+ default:
+ ERROR("Unknown coverage format");
+ }
+
+ return -1; /* not found */
+}
+
+static int
+otl_gsub_read_single (struct otl_gsub_subtab *subtab, sfnt *sfont)
+{
+ int len;
+ ULONG offset; /* not Offset which is USHORT */
+ Offset cov_offset; /* subtable offset, offset to Coverage table */
+
+ ASSERT(subtab && sfont);
+
+ offset = tell_position(sfont->stream);
+
+ subtab->LookupType = OTL_GSUB_TYPE_SINGLE;
+ subtab->SubstFormat = sfnt_get_ushort(sfont);
+ len = 2;
+
+ if (subtab->SubstFormat == 1) {
+ struct otl_gsub_single1 *data;
+
+ subtab->table.single1 = data = NEW(1, struct otl_gsub_single1);
+ cov_offset = sfnt_get_ushort(sfont);
+ data->DeltaGlyphID = sfnt_get_short(sfont);
+ len += 4;
+
+ sfnt_seek_set(sfont, offset + cov_offset);
+ len += clt_read_coverage(&data->coverage, sfont);
+
+ } else if (subtab->SubstFormat == 2) {
+ struct otl_gsub_single2 *data;
+ USHORT count;
+
+ subtab->table.single2 = data = NEW(1, struct otl_gsub_single2);
+ cov_offset = sfnt_get_ushort(sfont);
+ data->GlyphCount = sfnt_get_ushort(sfont);
+ len += 4;
+
+ if (data->GlyphCount == 0)
+ data->Substitute = NULL;
+ else {
+ data->Substitute = NEW(data->GlyphCount, GlyphID);
+ for (count = 0; count < data->GlyphCount; count++) {
+ data->Substitute[count] = sfnt_get_ushort(sfont);
+ }
+ len += 2 * data->GlyphCount;
+ }
+
+ sfnt_seek_set(sfont, offset + cov_offset);
+ len += clt_read_coverage(&data->coverage, sfont);
+
+ } else {
+ ERROR("unexpected SubstFormat");
+ }
+ /* not implemented yet */
+
+ return len;
+}
+
+static int
+otl_gsub_read_alternate (struct otl_gsub_subtab *subtab, sfnt *sfont)
+{
+ int len;
+ USHORT i, j;
+ ULONG offset; /* not Offset which is USHORT */
+ Offset cov_offset; /* subtable offset, offset to Coverage table */
+ struct clt_number_list altset_offsets;
+ struct otl_gsub_alternate1 *data;
+
+ ASSERT(subtab && sfont);
+
+ offset = tell_position(sfont->stream);
+
+ subtab->LookupType = OTL_GSUB_TYPE_ALTERNATE;
+ subtab->SubstFormat = sfnt_get_ushort(sfont); /* Must be 1 */
+ if (subtab->SubstFormat != 1) {
+ WARN("Unknown GSUB SubstFormat for Alternate: %u",
+ subtab->SubstFormat);
+ return -1;
+ }
+
+ len = 2;
+ subtab->table.alternate1 =
+ data = NEW(1, struct otl_gsub_alternate1);
+
+ cov_offset = sfnt_get_ushort(sfont);
+ len += 2;
+ len += clt_read_number_list(&altset_offsets, sfont);
+ data->AlternateSetCount = altset_offsets.count;
+ if (data->AlternateSetCount == 0) {
+ data->AlternateSet = NULL;
+ } else {
+ data->AlternateSet = NEW(data->AlternateSetCount,
+ struct otl_gsub_altset);
+ for (i = 0; i < data->AlternateSetCount; i++) {
+ struct otl_gsub_altset *altset;
+ ULONG altset_offset;
+
+ altset = &(data->AlternateSet[i]);
+
+ altset_offset = offset + altset_offsets.value[i];
+ sfnt_seek_set(sfont, altset_offset);
+ altset->GlyphCount = sfnt_get_ushort(sfont);
+ len += 2;
+ if (altset->GlyphCount == 0) {
+ altset->Alternate = NULL;
+ continue;
+ }
+ altset->Alternate = NEW(altset->GlyphCount, GlyphID);
+ for (j = 0; j < altset->GlyphCount; j++) {
+ altset->Alternate[j] = sfnt_get_ushort(sfont);
+ len += 2;
+ }
+ }
+ clt_release_number_list(&altset_offsets);
+ }
+ sfnt_seek_set(sfont, offset + cov_offset);
+ len += clt_read_coverage(&data->coverage, sfont);
+
+ return len;
+}
+
+static int
+otl_gsub_read_ligature (struct otl_gsub_subtab *subtab, sfnt *sfont)
+{
+ int len;
+ USHORT i, j;
+ ULONG offset; /* not Offset which is USHORT */
+ Offset cov_offset; /* subtable offset, offset to Coverage table */
+ struct clt_number_list ligset_offsets;
+ struct otl_gsub_ligature1 *data;
+
+ ASSERT(subtab && sfont);
+
+ offset = tell_position(sfont->stream);
+
+ subtab->LookupType = OTL_GSUB_TYPE_LIGATURE;
+ subtab->SubstFormat = sfnt_get_ushort(sfont); /* Must be 1 */
+ if (subtab->SubstFormat != 1) {
+ WARN("Unknown GSUB SubstFormat for Ligature: %u",
+ subtab->SubstFormat);
+ return -1;
+ }
+
+ len = 2;
+ subtab->table.ligature1 =
+ data = NEW(1, struct otl_gsub_ligature1);
+
+ cov_offset = sfnt_get_ushort(sfont);
+ len += 2;
+ len += clt_read_number_list(&ligset_offsets, sfont);
+ data->LigSetCount = ligset_offsets.count;
+ if (data->LigSetCount == 0) {
+ data->LigatureSet = NULL;
+ } else {
+ data->LigatureSet = NEW(data->LigSetCount,
+ struct otl_gsub_ligset);
+ for (i = 0; i < data->LigSetCount; i++) {
+ struct clt_number_list ligset_tab;
+ struct otl_gsub_ligset *ligset;
+ ULONG ligset_offset;
+ USHORT count;
+
+ ligset = &(data->LigatureSet[i]);
+
+ ligset_offset = offset + ligset_offsets.value[i];
+ sfnt_seek_set(sfont, ligset_offset);
+ len += clt_read_number_list(&ligset_tab, sfont);
+
+ ligset->LigatureCount = ligset_tab.count;
+ if (ligset_tab.count == 0) {
+ ligset->Ligature = NULL;
+ continue;
+ }
+ ligset->Ligature = NEW(ligset_tab.count,
+ struct otl_gsub_ligtab);
+ for (j = 0; j < ligset_tab.count; j++) {
+ sfnt_seek_set(sfont, ligset_offset + ligset_tab.value[j]);
+ ligset->Ligature[j].LigGlyph = sfnt_get_ushort(sfont);
+ ligset->Ligature[j].CompCount = sfnt_get_ushort(sfont);
+ if (ligset->Ligature[j].CompCount == 0) {
+ ligset->Ligature[j].Component = NULL;
+ continue;
+ }
+ ligset->Ligature[j].Component =
+ NEW(ligset->Ligature[j].CompCount - 1, GlyphID);
+ for (count = 0;
+ count < ligset->Ligature[j].CompCount - 1; count++) {
+ ligset->Ligature[j].Component[count] = sfnt_get_ushort(sfont);
+ }
+ len += 4 + count * 2;
+ }
+ clt_release_number_list(&ligset_tab);
+ }
+ }
+ clt_release_number_list(&ligset_offsets);
+
+ sfnt_seek_set(sfont, offset + cov_offset);
+ len += clt_read_coverage(&data->coverage, sfont);
+
+ return len;
+}
+
+static void
+otl_gsub_release_single (struct otl_gsub_subtab *subtab)
+{
+ if (subtab) {
+ switch((int) subtab->SubstFormat) {
+ case 1:
+ {
+ struct otl_gsub_single1 *data;
+
+ data = subtab->table.single1;
+ if (data) {
+ clt_release_coverage(&data->coverage);
+ RELEASE(data);
+ }
+ subtab->table.single1 = NULL;
+ }
+ break;
+ case 2:
+ {
+ struct otl_gsub_single2 *data;
+
+ data = subtab->table.single2;
+ if (data) {
+ if (data->Substitute)
+ RELEASE(data->Substitute);
+ clt_release_coverage(&data->coverage);
+ RELEASE(data);
+ }
+ subtab->table.single2 = NULL;
+ }
+ break;
+ default:
+ ERROR("Unknown format for single substitution");
+ }
+ }
+}
+
+static void
+otl_gsub_release_ligature (struct otl_gsub_subtab *subtab)
+{
+ if (subtab) {
+ struct otl_gsub_ligature1 *data;
+ USHORT i, j;
+
+ data = subtab->table.ligature1;
+ if (data && data->LigatureSet) {
+ for (i = 0; i < data->LigSetCount; i++) {
+ struct otl_gsub_ligset *ligset;
+
+ ligset = &(data->LigatureSet[i]);
+ for (j = 0;
+ j < ligset->LigatureCount; j++) {
+ if (ligset->Ligature[j].Component)
+ RELEASE(ligset->Ligature[j].Component);
+ ligset->Ligature[j].Component = NULL;
+ }
+ RELEASE(ligset->Ligature);
+ ligset->Ligature = NULL;
+ }
+ RELEASE(data->LigatureSet);
+ }
+ clt_release_coverage(&data->coverage);
+ data->LigatureSet = NULL;
+ RELEASE(data);
+ subtab->table.ligature1 = NULL;
+ }
+}
+
+static void
+otl_gsub_release_alternate (struct otl_gsub_subtab *subtab)
+{
+ if (subtab) {
+ struct otl_gsub_alternate1 *data;
+ USHORT i;
+
+ data = subtab->table.alternate1;
+ if (data && data->AlternateSet) {
+ for (i = 0; i < data->AlternateSetCount; i++) {
+ struct otl_gsub_altset *altset;
+
+ altset = &(data->AlternateSet[i]);
+ if (altset->Alternate)
+ RELEASE(altset->Alternate);
+ altset->Alternate = NULL;
+ }
+ RELEASE(data->AlternateSet);
+ }
+ clt_release_coverage(&data->coverage);
+ data->AlternateSet = NULL;
+ RELEASE(data);
+ subtab->table.alternate1 = NULL;
+ }
+}
+
+static int
+otl_gsub_read_header (struct otl_gsub_header *head, sfnt *sfont)
+{
+ ASSERT(head && sfont);
+
+ head->version = sfnt_get_ulong (sfont);
+ head->ScriptList = sfnt_get_ushort(sfont);
+ head->FeatureList = sfnt_get_ushort(sfont);
+ head->LookupList = sfnt_get_ushort(sfont);
+
+ return 10;
+}
+
+/*
+ * script -- langsys --> feature indices
+ * |
+ * +- langsys --> feature indices
+ *
+ * feature --> lookup indices
+ */
+
+struct otl_gsub_tab
+{
+ char *script;
+ char *language;
+ char *feature;
+
+ int num_subtables;
+ struct otl_gsub_subtab *subtables;
+};
+
+
+static int
+otl_gsub_read_feat (struct otl_gsub_tab *gsub, sfnt *sfont)
+{
+ int feat_idx, script_idx;
+ ULONG gsub_offset, offset;
+ struct otl_gsub_header head;
+ struct otl_gsub_subtab *subtab = NULL;
+ USHORT num_subtabs = 0;
+ unsigned char feat_bits[8192];
+ struct clt_record_list feature_list;
+ struct clt_record_list script_list;
+ struct clt_number_list lookup_list ;
+ otl_opt *script, *language, *feature;
+
+ ASSERT(gsub && sfont);
+
+ gsub_offset = sfnt_find_table_pos(sfont, "GSUB");
+ if (gsub_offset == 0)
+ return -1; /* not found */
+
+ script = otl_new_opt();
+ otl_parse_optstring(script, gsub->script);
+ language = otl_new_opt();
+ otl_parse_optstring(language, gsub->language);
+ feature = otl_new_opt();
+ otl_parse_optstring(feature, gsub->feature);
+
+ memset(feat_bits, 0, 8192);
+
+ /* GSUB header */
+ sfnt_seek_set(sfont, gsub_offset);
+ otl_gsub_read_header(&head, sfont);
+
+ /* Script */
+ offset = gsub_offset + head.ScriptList;
+ sfnt_seek_set(sfont, offset);
+ clt_read_record_list(&script_list, sfont);
+
+#define SET_BIT(b,p) do {\
+ (b)[(p)/8] |= (1<<(7-((p) % 8)));\
+} while (0)
+#define BIT_SET(b,p) (((b)[(p)/8]) & (1 << (7-((p)%8))))
+
+ for (script_idx = 0;
+ script_idx < script_list.count; script_idx++) {
+ if (otl_match_optrule(script,
+ script_list.record[script_idx].tag)) {
+ struct clt_script_table script_tab;
+ int langsys_idx;
+
+ offset = gsub_offset +
+ head.ScriptList + script_list.record[script_idx].offset;
+ sfnt_seek_set(sfont, offset);
+ clt_read_script_table(&script_tab, sfont);
+
+ if (otl_match_optrule(language, "dflt") &&
+ script_tab.DefaultLangSys != 0) {
+ struct clt_langsys_table langsys_tab;
+
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("otl_gsub>> OTL script-language enabled: %c%c%c%c.dflt\n",
+ script_list.record[script_idx].tag[0],
+ script_list.record[script_idx].tag[1],
+ script_list.record[script_idx].tag[2],
+ script_list.record[script_idx].tag[3]);
+ }
+
+ sfnt_seek_set(sfont, offset + script_tab.DefaultLangSys);
+ clt_read_langsys_table(&langsys_tab, sfont);
+ if (otl_match_optrule(feature, "____") && /* _FIXME_ */
+ langsys_tab.ReqFeatureIndex != 0xFFFF)
+ SET_BIT(feat_bits, langsys_tab.ReqFeatureIndex);
+ for (feat_idx = 0;
+ feat_idx < langsys_tab.FeatureIndex.count;
+ feat_idx++) {
+ SET_BIT(feat_bits,
+ langsys_tab.FeatureIndex.value[feat_idx]);
+ }
+ clt_release_langsys_table(&langsys_tab);
+ }
+ for (langsys_idx = 0;
+ langsys_idx < script_tab.LangSysRecord.count;
+ langsys_idx++) {
+ struct clt_record *langsys_rec;
+
+ langsys_rec = &(script_tab.LangSysRecord.record[langsys_idx]);
+ if (otl_match_optrule(language, langsys_rec->tag)) {
+ struct clt_langsys_table langsys_tab;
+
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("otl_gsub>> OTL script-language enabled: %c%c%c%c.%c%c%c%c\n",
+ script_list.record[script_idx].tag[0],
+ script_list.record[script_idx].tag[1],
+ script_list.record[script_idx].tag[2],
+ script_list.record[script_idx].tag[3],
+ langsys_rec->tag[0], langsys_rec->tag[1],
+ langsys_rec->tag[2], langsys_rec->tag[3]);
+ }
+
+ sfnt_seek_set(sfont, offset + langsys_rec->offset);
+ clt_read_langsys_table(&langsys_tab, sfont);
+ if (otl_match_optrule(feature, "____") || /* _FIXME_ */
+ langsys_tab.ReqFeatureIndex != 0xFFFF)
+ SET_BIT(feat_bits, langsys_tab.ReqFeatureIndex);
+ for (feat_idx = 0;
+ feat_idx < langsys_tab.FeatureIndex.count;
+ feat_idx++) {
+ SET_BIT(feat_bits,
+ langsys_tab.FeatureIndex.value[feat_idx]);
+ }
+ clt_release_langsys_table(&langsys_tab);
+ }
+ }
+ clt_release_script_table(&script_tab);
+ }
+ }
+
+ /* Feature List */
+ offset = gsub_offset + head.FeatureList;
+ sfnt_seek_set(sfont, offset);
+ clt_read_record_list(&feature_list, sfont);
+
+ /* Lookup List */
+ offset = gsub_offset + head.LookupList;
+ sfnt_seek_set(sfont, offset);
+ clt_read_number_list(&lookup_list, sfont);
+
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("otl_gsub>> Reading OTL feature(s):");
+ }
+
+ for (feat_idx = 0;
+ feat_idx < feature_list.count; feat_idx++) {
+ if (BIT_SET(feat_bits, feat_idx) &&
+ (otl_match_optrule(feature,
+ feature_list.record[feat_idx].tag))) {
+ struct clt_feature_table feature_table;
+ int i;
+
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG(" %c%c%c%c",
+ feature_list.record[feat_idx].tag[0],
+ feature_list.record[feat_idx].tag[1],
+ feature_list.record[feat_idx].tag[2],
+ feature_list.record[feat_idx].tag[3]);
+ }
+
+ /* Feature Table */
+ offset = gsub_offset +
+ head.FeatureList + feature_list.record[feat_idx].offset;
+
+ sfnt_seek_set(sfont, offset);
+ clt_read_feature_table(&feature_table, sfont);
+#if 0
+ if (feature_table.FeatureParams != 0) {
+ ERROR("unrecognized FeatureParams");
+ }
+#endif
+ /* Lookup table */
+ for (i = 0; i < feature_table.LookupListIndex.count; i++) {
+ struct clt_lookup_table lookup_table;
+ int ll_idx, st_idx, r, n_st;
+
+ ll_idx = feature_table.LookupListIndex.value[i];
+ if (ll_idx >= lookup_list.count)
+ ERROR("invalid Lookup index.");
+
+ offset = gsub_offset +
+ head.LookupList + (lookup_list.value)[ll_idx];
+ sfnt_seek_set(sfont, offset);
+ clt_read_lookup_table(&lookup_table, sfont);
+
+ if (lookup_table.LookupType != OTL_GSUB_TYPE_SINGLE &&
+ lookup_table.LookupType != OTL_GSUB_TYPE_ALTERNATE &&
+ lookup_table.LookupType != OTL_GSUB_TYPE_LIGATURE &&
+ lookup_table.LookupType != OTL_GSUB_TYPE_ESUBST) {
+ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN)
+ WARN("Skipping unsupported GSUB subtable: LookupType=%d", lookup_table.LookupType);
+ continue;
+ }
+
+ subtab = RENEW(subtab,
+ num_subtabs + lookup_table.SubTableList.count,
+ struct otl_gsub_subtab);
+ for (n_st = 0, st_idx = 0;
+ st_idx < lookup_table.SubTableList.count; st_idx++) {
+
+ offset = gsub_offset + head.LookupList +
+ lookup_list.value[ll_idx] +
+ (lookup_table.SubTableList.value)[st_idx];
+
+ sfnt_seek_set(sfont, offset);
+
+ switch ((int) lookup_table.LookupType) {
+ case OTL_GSUB_TYPE_SINGLE:
+ r = otl_gsub_read_single(&subtab[num_subtabs + n_st],
+ sfont);
+ if (r <= 0)
+ WARN("Reading GSUB subtable (single) failed...");
+ else {
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("(single)");
+ }
+ n_st++;
+ }
+ break;
+
+ case OTL_GSUB_TYPE_ALTERNATE:
+ r = otl_gsub_read_alternate(&subtab[num_subtabs + n_st],
+ sfont);
+ if (r <= 0)
+ WARN("Reading GSUB subtable (alternate) failed...");
+ else {
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("(alternate)");
+ }
+ n_st++;
+ }
+ break;
+
+ case OTL_GSUB_TYPE_LIGATURE:
+ r = otl_gsub_read_ligature(&subtab[num_subtabs + n_st],
+ sfont);
+ if (r <= 0)
+ WARN("Reading GSUB subtable (ligature) failed...");
+ else {
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("(ligature)");
+ }
+ n_st++;
+ }
+ break;
+
+ case OTL_GSUB_TYPE_ESUBST:
+ {
+ USHORT SubstFormat;
+ USHORT ExtensionLookupType;
+ ULONG ExtensionOffset;
+
+ SubstFormat = sfnt_get_ushort(sfont);
+ if (SubstFormat != 1)
+ break;
+ ExtensionLookupType = sfnt_get_ushort(sfont);
+ ExtensionOffset = sfnt_get_ulong (sfont);
+
+ sfnt_seek_set(sfont, offset + ExtensionOffset);
+ switch (ExtensionLookupType) {
+ case OTL_GSUB_TYPE_SINGLE:
+ r = otl_gsub_read_single(&subtab[num_subtabs + n_st],
+ sfont);
+ if (r <= 0)
+ WARN("Reading GSUB subtable (ext:single) failed...");
+ else {
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("(ext:single)");
+ }
+ n_st++;
+ }
+ break;
+
+ case OTL_GSUB_TYPE_ALTERNATE:
+ r = otl_gsub_read_alternate(&subtab[num_subtabs + n_st],
+ sfont);
+ if (r <= 0)
+ WARN("Reading GSUB subtable (alternate) failed...");
+ else {
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("(alternate)");
+ }
+ n_st++;
+ }
+ break;
+
+ case OTL_GSUB_TYPE_LIGATURE:
+ r = otl_gsub_read_ligature(&subtab[num_subtabs + n_st],
+ sfont);
+ if (r <= 0)
+ WARN("Reading GSUB subtable (ext:ligature) failed...");
+ else {
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("(ext:ligature)");
+ }
+ n_st++;
+ }
+ break;
+
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ num_subtabs += n_st; /* lookup_table.SubTableList.count; */
+ clt_release_lookup_table(&lookup_table);
+ }
+ clt_release_feature_table(&feature_table);
+ }
+ }
+
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("\n");
+ MESG("otl_gsub>> %ld subtable(s) read.\n", num_subtabs);
+ }
+
+ clt_release_number_list(&lookup_list);
+ clt_release_record_list(&feature_list);
+ clt_release_record_list(&script_list);
+
+ otl_release_opt(script);
+ otl_release_opt(language);
+ otl_release_opt(feature);
+
+ if (subtab != NULL) {
+ gsub->num_subtables = num_subtabs;
+ gsub->subtables = subtab;
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+otl_gsub_apply_single (struct otl_gsub_subtab *subtab, USHORT *gid)
+{
+ int idx;
+
+ ASSERT(subtab && gid);
+
+ if (subtab->SubstFormat == 1) {
+ struct otl_gsub_single1 *data;
+
+ data = (subtab->table).single1;
+ idx = clt_lookup_coverage(&data->coverage, *gid);
+ if (idx >= 0) {
+ *gid += data->DeltaGlyphID;
+ return 0; /* found */
+ }
+ } else if (subtab->SubstFormat == 2) {
+ struct otl_gsub_single2 *data;
+
+ data = (subtab->table).single2;
+ idx = clt_lookup_coverage(&data->coverage, *gid);
+ if (idx >= 0 &&
+ idx < data->GlyphCount) {
+ *gid = (data->Substitute)[idx];
+ return 0; /* found */
+ }
+ }
+
+ return -1;
+}
+
+static int
+otl_gsub_apply_alternate (struct otl_gsub_subtab *subtab,
+ USHORT alt_idx, USHORT *gid)
+{
+ int idx;
+
+ ASSERT(subtab && gid);
+
+ if (subtab->SubstFormat == 1) {
+ struct otl_gsub_alternate1 *data;
+
+ data = subtab->table.alternate1;
+ idx = clt_lookup_coverage(&data->coverage, *gid);
+ if (idx < 0 || idx >= data->AlternateSetCount)
+ return -1;
+ else {
+ struct otl_gsub_altset *altset;
+ altset = &(data->AlternateSet[idx]);
+ if (alt_idx >= altset->GlyphCount)
+ return -1;
+ else {
+ *gid = altset->Alternate[alt_idx];
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/* NOTE: Ligature table is in preference order */
+static int
+glyph_seq_cmp (GlyphID *glyph_seq0, USHORT n_glyphs0,
+ GlyphID *glyph_seq1, USHORT n_glyphs1)
+{
+ USHORT i;
+
+ if (n_glyphs0 != n_glyphs1)
+ return n_glyphs0 - n_glyphs1;
+
+ for (i = 0; i < n_glyphs0; i++) {
+ if (glyph_seq0[i] != glyph_seq1[i])
+ return glyph_seq0[i] - glyph_seq1[i];
+ }
+
+ return 0;
+}
+
+static int
+otl_gsub_apply_ligature (struct otl_gsub_subtab *subtab,
+ USHORT *gid_in, USHORT num_gids,
+ USHORT *gid_out)
+{
+ int idx;
+
+ ASSERT(subtab && gid_out);
+
+ if (!gid_in || num_gids < 1)
+ return -1;
+
+ if (subtab->SubstFormat == 1) {
+ struct otl_gsub_ligature1 *data;
+
+ data = subtab->table.ligature1;
+ idx = clt_lookup_coverage(&data->coverage, gid_in[0]);
+ if (idx >= 0 && idx < data->LigSetCount) {
+ struct otl_gsub_ligset *ligset;
+ USHORT j;
+
+ ligset = &(data->LigatureSet[idx]);
+ for (j = 0; j < ligset->LigatureCount; j++) {
+ if (!glyph_seq_cmp(&gid_in[1], (USHORT)(num_gids - 1),
+ ligset->Ligature[j].Component,
+ (USHORT)(ligset->Ligature[j].CompCount - 1))) {
+ *gid_out = ligset->Ligature[j].LigGlyph;
+ return 0; /* found */
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
+#define GSUB_LIST_MAX 32
+struct gsub_entry {
+ int index;
+ struct gsub_entry *next;
+};
+
+struct otl_gsub
+{
+ int num_gsubs;
+ int select;
+ struct gsub_entry *first;
+ struct otl_gsub_tab gsubs[GSUB_LIST_MAX];
+};
+
+otl_gsub *
+otl_gsub_new (void)
+{
+ struct otl_gsub *gsub_list;
+
+ gsub_list = NEW(1, struct otl_gsub);
+ gsub_list->num_gsubs = 0;
+ gsub_list->select = -1;
+ gsub_list->first = NULL;
+
+ return (otl_gsub *) gsub_list;
+}
+
+static void
+clear_chain (otl_gsub *gsub_list) {
+ struct gsub_entry *entry, *next;
+ for (entry = gsub_list->first; entry != NULL; entry = next) {
+ next = entry->next;
+ RELEASE(entry);
+ }
+ gsub_list->first = NULL;
+}
+
+int
+otl_gsub_add_feat (otl_gsub *gsub_list,
+ const char *script,
+ const char *language,
+ const char *feature,
+ sfnt *sfont)
+{
+ int retval = -1;
+ int i;
+ struct otl_gsub_tab *gsub;
+
+ if (gsub_list->num_gsubs > GSUB_LIST_MAX) {
+ ERROR("Too many GSUB features...");
+ return -1;
+ }
+ for (i = 0; i < gsub_list->num_gsubs; i++) {
+ gsub = &(gsub_list->gsubs[i]);
+ if (!strcmp(script, gsub->script) &&
+ !strcmp(language, gsub->language) &&
+ !strcmp(feature, gsub->feature)) {
+ gsub_list->select = i;
+ return 0;
+ }
+ }
+ gsub = &gsub_list->gsubs[i];
+
+ gsub->script = NEW(strlen(script) +1, char);
+ strcpy(gsub->script, script);
+ gsub->language = NEW(strlen(language)+1, char);
+ strcpy(gsub->language, language);
+ gsub->feature = NEW(strlen(feature) +1, char);
+ strcpy(gsub->feature, feature);
+
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("\n");
+ MESG("otl_gsub>> Reading \"%s.%s.%s\"...\n", script, language, feature);
+ }
+
+ retval = otl_gsub_read_feat(gsub, sfont);
+ if (retval >= 0) {
+ gsub_list->select = i;
+ gsub_list->num_gsubs++;
+ } else {
+ if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) {
+ MESG("otl_gsub>> Failed\n");
+ }
+ RELEASE(gsub->script);
+ RELEASE(gsub->language);
+ RELEASE(gsub->feature);
+ }
+
+ return retval;
+}
+
+static int
+scan_otl_tag (const char *otl_tags, const char *endptr,
+ char *script, char *language, char *feature)
+{
+ const char *p, *period;
+
+ ASSERT(script && language && feature);
+
+ if (!otl_tags || otl_tags >= endptr)
+ return -1;
+
+ memset(script, ' ', 4); script[4] = 0;
+ memset(language, ' ', 4); language[4] = 0;
+ memset(feature, ' ', 4); feature[4] = 0;
+
+ /* First parse otl_tags variable */
+ p = otl_tags;
+ period = strchr(p, '.');
+ if (period && period < endptr) {
+ /* Format scrp.lang.feat */
+ if (period < p + 5) {
+ strncpy(script, p, period - p);
+ } else {
+ WARN("Invalid OTL script tag found: %s", p);
+ return -1;
+ }
+ p = period + 1;
+ period = strchr(p, '.');
+ if (period && period < endptr) {
+ /* Now lang part */
+ if (period < p + 5) {
+ strncpy(language, p, period - p);
+ } else {
+ WARN("Invalid OTL lanuage tag found: %s", p);
+ return -1;
+ }
+ p = period + 1;
+ }
+ } else {
+ strcpy(script, "*");
+ strcpy(language, "*");
+ }
+
+ /* Finally feature */
+ if (p + 4 <= endptr) {
+ strncpy(feature, p, endptr - p);
+ p = endptr;
+ } else {
+ WARN("No valid OTL feature tag specified.");
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+otl_gsub_release (otl_gsub *gsub_list)
+{
+ struct otl_gsub_tab *gsub;
+ struct otl_gsub_subtab *subtab;
+ int i, j;
+
+ if (!gsub_list)
+ return;
+
+ for (i = 0; i < gsub_list->num_gsubs; i++) {
+ gsub = &(gsub_list->gsubs[i]);
+
+ if (gsub->script)
+ RELEASE(gsub->script);
+ if (gsub->language)
+ RELEASE(gsub->language);
+ if (gsub->feature)
+ RELEASE(gsub->feature);
+
+ for (j = 0; j < gsub->num_subtables; j++) {
+ subtab = &(gsub->subtables[j]);
+ switch ((int) subtab->LookupType) {
+ case OTL_GSUB_TYPE_SINGLE:
+ otl_gsub_release_single(subtab);
+ break;
+ case OTL_GSUB_TYPE_ALTERNATE:
+ otl_gsub_release_alternate(subtab);
+ break;
+ case OTL_GSUB_TYPE_LIGATURE:
+ otl_gsub_release_ligature(subtab);
+ break;
+ default:
+ ERROR("???");
+ break;
+ }
+ }
+ RELEASE(gsub->subtables);
+ }
+ clear_chain(gsub_list);
+ RELEASE(gsub_list);
+}
+
+int
+otl_gsub_apply (otl_gsub *gsub_list, USHORT *gid)
+{
+ int retval = -1;
+ struct otl_gsub_tab *gsub;
+ struct otl_gsub_subtab *subtab;
+ int i, j;
+
+ if (!gsub_list || !gid)
+ return retval;
+
+ i = gsub_list->select;
+ if (i < 0 || i >= gsub_list->num_gsubs) {
+ ERROR("GSUB not selected...");
+ return -1;
+ }
+ gsub = &(gsub_list->gsubs[i]);
+
+ for (j = 0;
+ retval < 0 && j < gsub->num_subtables; j++) {
+ subtab = &(gsub->subtables[j]);
+ switch ((int) subtab->LookupType){
+ case OTL_GSUB_TYPE_SINGLE:
+ retval = otl_gsub_apply_single(subtab, gid);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return retval;
+}
+
+int
+otl_gsub_apply_alt (otl_gsub *gsub_list, USHORT alt_idx, USHORT *gid)
+{
+ int retval = -1;
+ struct otl_gsub_tab *gsub;
+ struct otl_gsub_subtab *subtab;
+ int i, j;
+
+ if (!gsub_list || !gid)
+ return retval;
+
+ i = gsub_list->select;
+ if (i < 0 || i >= gsub_list->num_gsubs) {
+ ERROR("GSUB not selected...");
+ return -1;
+ }
+ gsub = &(gsub_list->gsubs[i]);
+
+ for (j = 0;
+ retval < 0 && j < gsub->num_subtables; j++) {
+ subtab = &(gsub->subtables[j]);
+ switch ((int) subtab->LookupType){
+ case OTL_GSUB_TYPE_ALTERNATE:
+ retval = otl_gsub_apply_alternate(subtab, alt_idx, gid);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return retval;
+}
+
+int
+otl_gsub_apply_lig (otl_gsub *gsub_list,
+ USHORT *gid_in, USHORT num_gids, USHORT *gid_out)
+{
+ int retval = -1;
+ struct otl_gsub_tab *gsub;
+ struct otl_gsub_subtab *subtab;
+ int i, j;
+
+ if (!gsub_list || !gid_out)
+ return retval;
+
+ i = gsub_list->select;
+ if (i < 0 || i >= gsub_list->num_gsubs) {
+ ERROR("GSUB not selected...");
+ return -1;
+ }
+ gsub = &(gsub_list->gsubs[i]);
+
+ for (j = 0;
+ retval < 0 && j < gsub->num_subtables; j++) {
+ subtab = &(gsub->subtables[j]);
+ switch ((int) subtab->LookupType){
+ case OTL_GSUB_TYPE_LIGATURE:
+ retval = otl_gsub_apply_ligature(subtab,
+ gid_in, num_gids, gid_out);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return retval;
+}
+
+static int
+gsub_find (otl_gsub *gsub_list,
+ const char *script,
+ const char *language,
+ const char *feature)
+{
+ int i;
+ struct otl_gsub_tab *gsub;
+
+ for (i = 0; i < gsub_list->num_gsubs; i++) {
+ gsub = &(gsub_list->gsubs[i]);
+ if (!strcmp(gsub->script, script) &&
+ !strcmp(gsub->language, language) &&
+ !strcmp(gsub->feature, feature)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int
+otl_gsub_select (otl_gsub *gsub_list,
+ const char *script,
+ const char *language,
+ const char *feature)
+{
+ gsub_list->select = gsub_find(gsub_list, script, language, feature);
+ return gsub_list->select;
+}
+
+int
+otl_gsub_set_chain (otl_gsub *gsub_list, const char *otl_tags) {
+ struct gsub_entry *prev = NULL;
+ const char *p, *nextptr, *endptr;
+ char script[5], language[5], feature[5];
+ int idx;
+
+ clear_chain(gsub_list);
+
+ endptr = otl_tags + strlen(otl_tags);
+ for (p = otl_tags; p < endptr; p = nextptr) {
+ nextptr = strchr(p, ':');
+ if (!nextptr)
+ nextptr = endptr;
+ if (scan_otl_tag(p, nextptr, script, language, feature) >= 0) {
+ idx = gsub_find(gsub_list, script, language, feature);
+ if (idx >= 0 && idx <= gsub_list->num_gsubs) {
+ struct gsub_entry *entry;
+ entry = NEW(1, struct gsub_entry);
+ if (!gsub_list->first)
+ gsub_list->first = entry;
+ if (prev)
+ prev->next = entry;
+ entry->index = idx;
+ prev = entry;
+ }
+ }
+ nextptr++;
+ }
+ if (prev)
+ prev->next = NULL;
+
+ return 0;
+}
+
+int
+otl_gsub_add_feat_list (otl_gsub *gsub_list, const char *otl_tags, sfnt *sfont)
+{
+ const char *p, *nextptr, *endptr;
+ char script[5], language[5], feature[5];
+ int idx;
+
+ if (!gsub_list || !otl_tags || !sfont)
+ return -1;
+
+ clear_chain(gsub_list);
+ endptr = otl_tags + strlen(otl_tags);
+ for (p = otl_tags; p < endptr; p = nextptr) {
+ nextptr = strchr(p, ':');
+ if (!nextptr)
+ nextptr = endptr;
+ if (scan_otl_tag(p, nextptr, script, language, feature) >= 0) {
+ idx = gsub_find(gsub_list, script, language, feature);
+ if (idx < 0) {
+ otl_gsub_add_feat(gsub_list, script, language, feature, sfont);
+ }
+ }
+ nextptr++;
+ }
+
+ return 0;
+}
+
+int
+otl_gsub_apply_chain (otl_gsub *gsub_list, USHORT *gid) {
+ int retval = -1;
+ struct otl_gsub_tab *gsub;
+ struct otl_gsub_subtab *subtab;
+ struct gsub_entry *entry;
+ int i, idx;
+
+ if (!gsub_list || !gid)
+ return retval;
+
+ for (entry = gsub_list->first;
+ entry != NULL; entry = entry->next) {
+ idx = entry->index;
+ if (idx < 0 || idx >= gsub_list->num_gsubs)
+ continue;
+ gsub = &(gsub_list->gsubs[idx]);
+ for (i = 0, retval = -1;
+ retval < 0 && i < gsub->num_subtables; i++) {
+ subtab = &(gsub->subtables[i]);
+ switch ((int) subtab->LookupType){
+ case OTL_GSUB_TYPE_SINGLE:
+ retval = otl_gsub_apply_single(subtab, gid);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
+
+#if 1
+#include "unicode.h"
+
+#ifndef is_used_char2
+#define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8))))
+#endif
+
+static int
+add_glyph_if_valid (CMap *cmap, char *used_chars,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap, USHORT gid, USHORT gid_sub)
+{
+ int count = 0;
+ unsigned char src[2], dst[4];
+ unsigned char *p = dst, *endptr = dst + 4;
+ size_t len;
+ uint16_t cid_sub;
+
+ if (gid_sub >= num_glyphs || gid >= num_glyphs)
+ return 0;
+
+ cid_sub = GIDToCIDMap[gid_sub];
+ if (is_used_char2(used_chars, cid_sub)) {
+ int32_t ch = map_base[gid];
+ if (UC_is_valid(ch)) {
+ src[0] = (cid_sub >> 8) & 0xff;
+ src[1] = cid_sub & 0xff;
+ len = UC_UTF16BE_encode_char(ch, &p, endptr);
+ CMap_add_bfchar(cmap, src, 2, dst, len);
+ used_chars[cid_sub / 8] &= ~(1 << (7 - (cid_sub % 8)));
+ count = 1;
+ } else {
+ ch = map_sub[gid];
+ if (UC_is_valid(ch)) {
+ src[0] = (cid_sub >> 8) & 0xff;
+ src[1] = cid_sub & 0xff;
+ len = UC_UTF16BE_encode_char(ch, &p, endptr);
+ CMap_add_bfchar(cmap, src, 2, dst, len);
+ used_chars[cid_sub / 8] &= ~(1 << (7 - (cid_sub % 8)));
+ count = 1;
+ }
+ }
+ }
+ return count;
+}
+
+static int
+add_ToUnicode_single (CMap *cmap, char *used_chars,
+ struct otl_gsub_subtab *subtab,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap)
+{
+ int count = 0;
+ USHORT i, idx, gid;
+ USHORT gid_sub;
+
+ ASSERT(subtab);
+
+ if (subtab->SubstFormat == 1) {
+ struct otl_gsub_single1 *data;
+ struct clt_coverage *cov;
+
+ data = (subtab->table).single1;
+ cov = &data->coverage;
+ switch (cov->format) {
+ case 1: /* list */
+ for (idx = 0; idx < cov->count; idx++) {
+ gid = cov->list[idx];
+ gid_sub = gid + data->DeltaGlyphID;
+ count += add_glyph_if_valid(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, gid_sub);
+ }
+ break;
+ case 2: /* range */
+ for (i = 0; i < cov->count; i++) {
+ for (gid = cov->range[i].Start;
+ gid <= cov->range[i].End && gid < num_glyphs; gid++) {
+ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start;
+ gid_sub = gid + data->DeltaGlyphID;
+ count += add_glyph_if_valid(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, gid_sub);
+ }
+ }
+ break;
+ }
+ } else if (subtab->SubstFormat == 2) {
+ struct otl_gsub_single2 *data;
+ struct clt_coverage *cov;
+
+ data = (subtab->table).single2;
+ cov = &data->coverage;
+ switch (cov->format) {
+ case 1: /* list */
+ for (idx = 0; idx < cov->count; idx++) {
+ gid = cov->list[idx];
+ if (idx >= 0 && idx < data->GlyphCount) {
+ gid_sub = (data->Substitute)[idx];
+ count += add_glyph_if_valid(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, gid_sub);
+ }
+ }
+ break;
+ case 2: /* range */
+ for (i = 0; i < cov->count; i++) {
+ for (gid = cov->range[i].Start;
+ gid <= cov->range[i].End && gid < num_glyphs; gid++) {
+ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start;
+ if (idx >= 0 && idx < data->GlyphCount) {
+ gid_sub = (data->Substitute)[idx];
+ count += add_glyph_if_valid(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, gid_sub);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return count;
+}
+
+static int32_t
+add_alternate1_inverse_map (CMap *cmap, char *used_chars,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap, USHORT gid, int idx,
+ struct otl_gsub_alternate1 *data)
+{
+ int32_t count = 0;
+
+ if (idx >= 0 && idx < data->AlternateSetCount) {
+ struct otl_gsub_altset *altset;
+ USHORT i;
+
+ altset = &(data->AlternateSet[idx]);
+ if (altset->GlyphCount == 0)
+ return count;
+ for (i = 0; i < altset->GlyphCount; i++) {
+ USHORT gid_alt = altset->Alternate[i];
+ count += add_glyph_if_valid(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, gid_alt);
+ }
+ }
+ return count;
+}
+
+static int32_t
+add_ToUnicode_alternate (CMap *cmap, char *used_chars,
+ struct otl_gsub_subtab *subtab,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap)
+{
+ int32_t count = 0;
+ USHORT i, gid, idx;
+
+ ASSERT(subtab);
+
+ if (subtab->SubstFormat == 1) {
+ struct otl_gsub_alternate1 *data;
+ struct clt_coverage *cov;
+ data = subtab->table.alternate1;
+ cov = &data->coverage;
+ switch (cov->format) {
+ case 1: /* list */
+ for (idx = 0; idx < cov->count; idx++) {
+ gid = cov->list[idx];
+ if (gid < num_glyphs) {
+ count += add_alternate1_inverse_map(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, idx, data);
+ }
+ }
+ break;
+ case 2: /* range */
+ for (i = 0; i < cov->count; i++) {
+ for (gid = cov->range[i].Start;
+ gid <= cov->range[i].End && gid < num_glyphs; gid++) {
+ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start;
+ count += add_alternate1_inverse_map(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, idx, data);
+ }
+ }
+ break;
+ }
+ }
+ return count;
+}
+
+static int32_t
+add_ligature1_inverse_map (CMap *cmap, char *used_chars,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap, USHORT gid_1, int idx,
+ struct otl_gsub_ligature1 *data)
+{
+ int32_t count = 0;
+
+ if (idx >= 0 && idx < data->LigSetCount) {
+ struct otl_gsub_ligset *ligset;
+ USHORT i, j;
+
+ ligset = &(data->LigatureSet[idx]);
+ for (j = 0; j < ligset->LigatureCount; j++) {
+ USHORT gid_sub = ligset->Ligature[j].LigGlyph;
+ if (gid_sub < num_glyphs) {
+ uint16_t cid = GIDToCIDMap[gid_sub];
+ if (is_used_char2(used_chars, cid)) {
+ int32_t ch, *ucv;
+ USHORT comp_count = ligset->Ligature[j].CompCount;
+ int fail_count = 0;
+
+ ucv = NEW(comp_count, int32_t);
+ ch = UC_is_valid(map_base[gid_1]) ? map_base[gid_1] : map_sub[gid_1];
+ ucv[0] = ch;
+ fail_count += UC_is_valid(ch) ? 0 : 1;
+ for (i = 0; i < ligset->Ligature[j].CompCount - 1; i++) {
+ USHORT gid = ligset->Ligature[j].Component[i];
+ if (gid < num_glyphs) {
+ ch = UC_is_valid(map_base[gid]) ? map_base[gid] : map_sub[gid];
+ ucv[i+1] = ch;
+ fail_count += UC_is_valid(ch) ? 0 : 1;
+ } else {
+ fail_count += 1;
+ }
+ }
+ if (fail_count == 0) {
+ unsigned char src[2], *dst;
+ unsigned char *p, *endptr;
+ size_t len = 0;
+
+ src[0] = (cid >> 8) & 0xff;
+ src[1] = cid & 0xff;
+ dst = NEW(comp_count*4, unsigned char);
+ p = dst;
+ endptr = dst + comp_count * 4;
+ for (i = 0; i < comp_count; i++) {
+ len += UC_UTF16BE_encode_char(ucv[i], &p, endptr);
+ }
+ CMap_add_bfchar(cmap, src, 2, dst, len);
+ used_chars[cid / 8] &= ~(1 << (7 - (cid % 8)));
+ count++;
+ RELEASE(dst);
+ }
+ RELEASE(ucv);
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+static int32_t
+add_ToUnicode_ligature (CMap *cmap, char *used_chars,
+ struct otl_gsub_subtab *subtab,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap)
+{
+ int32_t count = 0;
+ USHORT i, idx, gid;
+
+ ASSERT(subtab);
+
+ if (subtab->SubstFormat == 1) {
+ struct otl_gsub_ligature1 *data;
+ struct clt_coverage *cov;
+
+ data = subtab->table.ligature1;
+ cov = &data->coverage;
+ switch (cov->format) {
+ case 1: /* list */
+ for (idx = 0; idx < cov->count; idx++) {
+ gid = cov->list[idx];
+ if (gid < num_glyphs) {
+ count += add_ligature1_inverse_map(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, idx, data);
+ }
+ }
+ break;
+ case 2: /* range */
+ for (i = 0; i < cov->count; i++) {
+ for (gid = cov->range[i].Start;
+ gid <= cov->range[i].End && gid < num_glyphs; gid++) {
+ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start;
+ if (gid < num_glyphs) {
+ count += add_ligature1_inverse_map(cmap, used_chars,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap, gid, idx, data);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int
+otl_gsub_add_ToUnicode (CMap *cmap, char *used_chars,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap, sfnt *sfont)
+{
+ int count = 0;
+ otl_gsub *gsub_list;
+ struct otl_gsub_tab *gsub;
+ struct otl_gsub_subtab *subtab;
+ int i, j;
+
+ gsub_list = otl_gsub_new();
+ otl_gsub_add_feat(gsub_list, "*", "*", "*", sfont);
+
+ for (i = 0; i < gsub_list->num_gsubs; i++) {
+ gsub = &(gsub_list->gsubs[i]);
+ for (j = 0; j < gsub->num_subtables; j++) {
+ subtab = &(gsub->subtables[j]);
+ switch ((int) subtab->LookupType){
+ case OTL_GSUB_TYPE_SINGLE:
+ count += add_ToUnicode_single(cmap, used_chars, subtab,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap);
+ break;
+ case OTL_GSUB_TYPE_ALTERNATE:
+ count += add_ToUnicode_alternate(cmap, used_chars, subtab,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap);
+ break;
+ case OTL_GSUB_TYPE_LIGATURE:
+ count += add_ToUnicode_ligature(cmap, used_chars, subtab,
+ map_base, map_sub, num_glyphs,
+ GIDToCIDMap);
+ break;
+ }
+ }
+ }
+ otl_gsub_release(gsub_list);
+
+ return count;
+}
+#endif
diff --git a/Build/source/texk/dvipdfm-x/tt_gsub.h b/Build/source/texk/dvipdfm-x/tt_gsub.h
new file mode 100644
index 00000000000..07e9efe751d
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_gsub.h
@@ -0,0 +1,66 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TT_GSUB_H_
+#define _TT_GSUB_H_
+
+#include "sfnt.h"
+#include "otl_opt.h"
+#include "cmap.h"
+
+typedef struct otl_gsub otl_gsub;
+
+/* LookupType for GSUB */
+#define OTL_GSUB_TYPE_SINGLE 1
+#define OTL_GSUB_TYPE_MULTIPLE 2
+#define OTL_GSUB_TYPE_ALTERNATE 3
+#define OTL_GSUB_TYPE_LIGATURE 4
+#define OTL_GSUB_TYPE_CONTEXT 5
+#define OTL_GSUB_TYPE_CCONTEXT 6
+#define OTL_GSUB_TYPE_ESUBST 7
+
+extern otl_gsub *otl_gsub_new (void);
+extern void otl_gsub_release (otl_gsub *gsub_list);
+
+extern int otl_gsub_select (otl_gsub *gsub_list,
+ const char *script,
+ const char *language,
+ const char *feature);
+extern int otl_gsub_add_feat (otl_gsub *gsub_list,
+ const char *script,
+ const char *language,
+ const char *feature,
+ sfnt *sfont);
+extern int otl_gsub_apply (otl_gsub *gsub_list, USHORT *gid);
+extern int otl_gsub_apply_alt (otl_gsub *gsub_list, USHORT alt_idx, USHORT *gid);
+extern int otl_gsub_apply_lig (otl_gsub *gsub_list,
+ USHORT *gid_in, USHORT num_gids,
+ USHORT *gid_out);
+
+/* Handle a list of OTL features */
+extern int otl_gsub_add_feat_list (otl_gsub *gsub_list,
+ const char *otl_tags, sfnt *sfont);
+extern int otl_gsub_set_chain (otl_gsub *gsub_list, const char *otl_tags);
+extern int otl_gsub_apply_chain (otl_gsub *gsub_list, USHORT *gid);
+
+extern int otl_gsub_add_ToUnicode (CMap *cmap, char *used_chars,
+ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs,
+ uint16_t *GIDToCIDMap, sfnt *sfont);
+#endif /* _TT_GSUB_H_ */
diff --git a/Build/source/texk/dvipdfm-x/tt_post.c b/Build/source/texk/dvipdfm-x/tt_post.c
new file mode 100644
index 00000000000..737d4cd00d4
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_post.c
@@ -0,0 +1,286 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+
+#include "dpxfile.h"
+
+#include "sfnt.h"
+
+#include "tt_post.h"
+
+static const char *macglyphorder[258];
+
+/* offset from begenning of the post table */
+#define NAME_STR_OFFSET 32
+
+static int
+read_v2_post_names (struct tt_post_table *post, sfnt *sfont)
+{
+ USHORT i, idx, *indices, maxidx;
+ int len;
+
+ post->numberOfGlyphs = sfnt_get_ushort(sfont);
+
+ indices = NEW(post->numberOfGlyphs, USHORT);
+ maxidx = 257;
+ for (i = 0; i < post->numberOfGlyphs; i++) {
+ idx = sfnt_get_ushort(sfont);
+ if (idx >= 258) {
+ if (idx > maxidx)
+ maxidx = idx;
+#if 0
+ /*
+ * Apple's TrueType spec. describes as,
+ *
+ * Index numbers 32768 through 65535 are reserved for future use.
+ * If you do not want to associate a PostScript name with a particular
+ * glyph, use index number 0 which points to the name .notdef.
+ *
+ * -- https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html
+ *
+ * But there are no restriction in Microsoft's OpenType spec.
+ */
+
+ if (idx > 32767) {
+ /* Although this is strictly speaking out of spec, it seems to work
+ * and there are real-life fonts that use it.
+ * We show a warning only once, instead of thousands of times
+ */
+ static char warning_issued = 0;
+ if (!warning_issued) {
+ WARN("TrueType post table name index %u > 32767", idx);
+ warning_issued = 1;
+ }
+ /* In a real-life large font, (x)dvipdfmx crashes if we use
+ * nonvanishing idx in the case of idx > 32767.
+ * If we set idx = 0, (x)dvipdfmx works fine for the font and
+ * created pdf seems fine. The post table may not be important
+ * in such a case
+ */
+ idx = 0;
+ }
+#endif
+ }
+ indices[i] = idx;
+ }
+
+ post->count = maxidx - 257;
+ if (post->count < 1) {
+ post->names = NULL;
+ } else {
+ post->names = NEW(post->count, char *);
+ for (i = 0; i < post->count; i++) { /* read Pascal strings */
+ len = sfnt_get_byte(sfont);
+ if (len > 0) {
+ post->names[i] = NEW(len + 1, char);
+ sfnt_read(post->names[i], len, sfont);
+ post->names[i][len] = 0;
+ } else {
+ post->names[i] = NULL;
+ }
+ }
+ }
+
+ post->glyphNamePtr = NEW(post->numberOfGlyphs, const char *);
+ for (i = 0; i < post->numberOfGlyphs; i++) {
+ idx = indices[i];
+ if (idx < 258) {
+ post->glyphNamePtr[i] = macglyphorder[idx];
+ } else if (idx - 258 < post->count) {
+ post->glyphNamePtr[i] = post->names[idx - 258];
+ } else {
+ WARN("Invalid glyph name index number: %u (>= %u)",
+ idx, post->count + 258);
+ RELEASE(indices);
+ return -1;
+ }
+ }
+ RELEASE(indices);
+
+ return 0;
+}
+
+struct tt_post_table *
+tt_read_post_table (sfnt *sfont)
+{
+ struct tt_post_table *post;
+
+ /* offset = */ sfnt_locate_table(sfont, "post");
+
+ post = NEW(1, struct tt_post_table);
+
+ post->Version = sfnt_get_ulong(sfont); /* Fixed */
+ post->italicAngle = sfnt_get_ulong(sfont); /* Fixed */
+ post->underlinePosition = sfnt_get_short(sfont); /* FWord */
+ post->underlineThickness = sfnt_get_short(sfont); /* FWord */
+ post->isFixedPitch = sfnt_get_ulong(sfont);
+ post->minMemType42 = sfnt_get_ulong(sfont);
+ post->maxMemType42 = sfnt_get_ulong(sfont);
+ post->minMemType1 = sfnt_get_ulong(sfont);
+ post->maxMemType1 = sfnt_get_ulong(sfont);
+
+ post->numberOfGlyphs = 0;
+ post->glyphNamePtr = NULL;
+ post->count = 0;
+ post->names = NULL;
+
+ if (post->Version == 0x00010000UL) {
+ post->numberOfGlyphs = 258; /* wrong */
+ post->glyphNamePtr = macglyphorder;
+ } else if (post->Version == 0x00028000UL) {
+ WARN("TrueType 'post' version 2.5 found (deprecated)");
+ } else if (post->Version == 0x00020000UL) {
+ if (read_v2_post_names(post, sfont) < 0) {
+ WARN("Invalid version 2.0 'post' table");
+ tt_release_post_table(post);
+ post = NULL;
+ }
+ } else if (post->Version == 0x00030000UL || /* no glyph names provided */
+ post->Version == 0x00040000UL) { /* Apple format for printer-based fonts */
+ /* don't bother constructing char names, not sure if they'll ever be needed */
+ } else { /* some broken font files have 0x00000000UL and perhaps other values */
+ WARN("Unknown 'post' version: %08X, assuming version 3.0", post->Version);
+ }
+
+ return post;
+}
+
+USHORT
+tt_lookup_post_table (struct tt_post_table *post, const char *glyphname)
+{
+ USHORT gid;
+
+ ASSERT(post && glyphname);
+
+ for (gid = 0; gid < post->numberOfGlyphs; gid++) {
+ if (post->glyphNamePtr[gid] &&
+ !strcmp(glyphname, post->glyphNamePtr[gid])) {
+ return gid;
+ }
+ }
+
+ return 0;
+}
+
+char*
+tt_get_glyphname (struct tt_post_table *post, USHORT gid)
+{
+ if (gid < post->numberOfGlyphs && post->glyphNamePtr[gid])
+ return xstrdup(post->glyphNamePtr[gid]);
+ return NULL;
+}
+
+void
+tt_release_post_table (struct tt_post_table *post)
+{
+ USHORT i;
+
+ ASSERT(post);
+
+ if (post->glyphNamePtr && post->Version != 0x00010000UL)
+ RELEASE((void *)post->glyphNamePtr);
+ if (post->names) {
+ for (i = 0; i < post->count; i++) {
+ if (post->names[i])
+ RELEASE(post->names[i]);
+ }
+ RELEASE(post->names);
+ }
+ post->count = 0;
+ post->glyphNamePtr = NULL;
+ post->names = NULL;
+
+ RELEASE(post);
+
+ return;
+}
+
+/* Macintosh glyph order - from apple's TTRefMan */
+static const char *
+macglyphorder[258] = {
+ /* 0x0000 */
+ ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl",
+ "numbersign", "dollar", "percent", "ampersand", "quotesingle",
+ "parenleft", "parenright", "asterisk", "plus", "comma",
+ /* 0x0010 */
+ "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
+ /* 0x0020 */
+ "equal", "greater", "question", "at", "A", "B", "C", "D",
+ "E", "F", "G", "H", "I", "J", "K", "L",
+ /* 0x0030 */
+ "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
+ "Y", "Z", "bracketleft", "backslash",
+ /* 0x0040 */
+ "bracketright", "asciicircum", "underscore", "grave",
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
+ /* 0x0050 */
+ "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
+ "y", "z", "braceleft", "bar",
+ /* 0x0060 */
+ "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla",
+ "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave",
+ "acircumflex", "adieresis", "atilde", "aring", "ccedilla",
+ /* 0x0070 */
+ "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave",
+ "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex",
+ "odieresis", "otilde", "uacute", "ugrave",
+ /* 0x0080 */
+ "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
+ "section", "bullet", "paragraph", "germandbls", "registered",
+ "copyright", "trademark", "acute", "dieresis", "notequal",
+ /* 0x0090 */
+ "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
+ "yen", "mu", "partialdiff", "summation", "product", "pi", "integral",
+ "ordfeminine", "ordmasculine", "Omega",
+ /* 0x00a0 */
+ "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical",
+ "florin", "approxequal", "Delta", "guillemotleft", "guillemotright",
+ "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde",
+ /* 0x00b0 */
+ "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright",
+ "quoteleft", "quoteright", "divide", "lozenge", "ydieresis",
+ "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright",
+ /* 0x00c0 */
+ "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase",
+ "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute",
+ "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave",
+ /* 0x00d0 */
+ "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex",
+ "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve",
+ "dotaccent", "ring", "cedilla", "hungarumlaut",
+ /* 0x00e0 */
+ "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron",
+ "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn",
+ "thorn", "minus",
+ /* 0x00f0 */
+ "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
+ "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent",
+ "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron",
+ /* 0x0100 */
+ "ccaron", "dcroat"
+};
diff --git a/Build/source/texk/dvipdfm-x/tt_post.h b/Build/source/texk/dvipdfm-x/tt_post.h
new file mode 100644
index 00000000000..63dcd0ba807
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_post.h
@@ -0,0 +1,52 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TT_POST_H_
+#define _TT_POST_H_
+
+#include "sfnt.h"
+
+struct tt_post_table
+{
+ Fixed Version;
+ Fixed italicAngle;
+ FWord underlinePosition;
+ FWord underlineThickness;
+ ULONG isFixedPitch;
+ ULONG minMemType42;
+ ULONG maxMemType42;
+ ULONG minMemType1;
+ ULONG maxMemType1;
+
+ USHORT numberOfGlyphs;
+
+ const char **glyphNamePtr; /* Glyph names (pointer to C string) */
+ char **names; /* Non-standard glyph names */
+
+ USHORT count; /* Number of glyph names in names[] */
+};
+
+extern struct tt_post_table *tt_read_post_table (sfnt *sfont);
+extern void tt_release_post_table (struct tt_post_table *post);
+
+extern USHORT tt_lookup_post_table (struct tt_post_table *post, const char *glyphname);
+extern char* tt_get_glyphname (struct tt_post_table *post, USHORT gid);
+
+#endif /* _TT_POST_H_ */
diff --git a/Build/source/texk/dvipdfm-x/tt_table.c b/Build/source/texk/dvipdfm-x/tt_table.c
new file mode 100644
index 00000000000..ec915548e93
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_table.c
@@ -0,0 +1,513 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "system.h"
+#include "error.h"
+#include "mem.h"
+#include "mfileio.h"
+
+#include "sfnt.h"
+#include "tt_table.h"
+
+/*
+ tables contains information refered by other tables
+ maxp->numGlyphs, etc --> loca, etc
+ hhea->numOfLongHorMetrics --> hmtx
+ head->indexToLocFormat --> loca
+ head->glyphDataFormat --> glyf
+*/
+
+char *tt_pack_head_table (struct tt_head_table *table)
+{
+ int i;
+ char *p, *data;
+
+ if (table == NULL)
+ ERROR("passed NULL pointer\n");
+
+ p = data = NEW(TT_HEAD_TABLE_SIZE, char);
+ p += sfnt_put_ulong(p, table->version);
+ p += sfnt_put_ulong(p, table->fontRevision);
+ p += sfnt_put_ulong(p, table->checkSumAdjustment);
+ p += sfnt_put_ulong(p, table->magicNumber);
+ p += sfnt_put_ushort(p, table->flags);
+ p += sfnt_put_ushort(p, table->unitsPerEm);
+ for (i=0; i<8; i++) {
+ *(p++) = (table->created)[i];
+ }
+ for (i=0; i<8; i++) {
+ *(p++) = (table->modified)[i];
+ }
+ p += sfnt_put_short(p, table->xMin);
+ p += sfnt_put_short(p, table->yMin);
+ p += sfnt_put_short(p, table->xMax);
+ p += sfnt_put_short(p, table->yMax);
+ p += sfnt_put_ushort(p, table->macStyle);
+ p += sfnt_put_ushort(p, table->lowestRecPPEM);
+ p += sfnt_put_short(p, table->fontDirectionHint);
+ p += sfnt_put_short(p, table->indexToLocFormat);
+ p += sfnt_put_short(p, table->glyphDataFormat);
+
+ return data;
+}
+
+struct tt_head_table *tt_read_head_table (sfnt *sfont)
+{
+ int i;
+ struct tt_head_table *table = NEW(1, struct tt_head_table);
+
+ sfnt_locate_table(sfont, "head");
+
+ table->version = sfnt_get_ulong(sfont);
+ table->fontRevision = sfnt_get_ulong(sfont);
+ table->checkSumAdjustment = sfnt_get_ulong(sfont);
+ table->magicNumber = sfnt_get_ulong(sfont);
+ table->flags = sfnt_get_ushort(sfont);
+ table->unitsPerEm = sfnt_get_ushort(sfont);
+ for (i=0; i<8; i++) {
+ (table->created)[i] = sfnt_get_byte (sfont);
+ }
+ for (i=0; i<8; i++) {
+ (table->modified)[i] = sfnt_get_byte (sfont);
+ }
+ table->xMin = sfnt_get_short(sfont);
+ table->yMin = sfnt_get_short(sfont);
+ table->xMax = sfnt_get_short(sfont);
+ table->yMax = sfnt_get_short(sfont);
+ table->macStyle = sfnt_get_short(sfont);
+ table->lowestRecPPEM = sfnt_get_short(sfont);
+ table->fontDirectionHint = sfnt_get_short(sfont);
+ table->indexToLocFormat = sfnt_get_short(sfont);
+ table->glyphDataFormat = sfnt_get_short(sfont);
+
+ return table;
+}
+
+char *tt_pack_maxp_table (struct tt_maxp_table *table)
+{
+ char *p, *data;
+
+ p = data = NEW(TT_MAXP_TABLE_SIZE, char);
+ p += sfnt_put_ulong(p, table->version);
+ p += sfnt_put_ushort(p, table->numGlyphs);
+ p += sfnt_put_ushort(p, table->maxPoints);
+ p += sfnt_put_ushort(p, table->maxContours);
+ p += sfnt_put_ushort(p, table->maxComponentPoints);
+ p += sfnt_put_ushort(p, table->maxComponentContours);
+ p += sfnt_put_ushort(p, table->maxZones);
+ p += sfnt_put_ushort(p, table->maxTwilightPoints);
+ p += sfnt_put_ushort(p, table->maxStorage);
+ p += sfnt_put_ushort(p, table->maxFunctionDefs);
+ p += sfnt_put_ushort(p, table->maxInstructionDefs);
+ p += sfnt_put_ushort(p, table->maxStackElements);
+ p += sfnt_put_ushort(p, table->maxSizeOfInstructions);
+ p += sfnt_put_ushort(p, table->maxComponentElements);
+ p += sfnt_put_ushort(p, table->maxComponentDepth);
+
+ return data;
+}
+
+struct tt_maxp_table *tt_read_maxp_table (sfnt *sfont)
+{
+ struct tt_maxp_table *table = NEW(1, struct tt_maxp_table);
+
+ sfnt_locate_table(sfont, "maxp");
+
+ table->version = sfnt_get_ulong(sfont);
+ table->numGlyphs = sfnt_get_ushort(sfont);
+ table->maxPoints = sfnt_get_ushort(sfont);
+ table->maxContours = sfnt_get_ushort(sfont);
+ table->maxComponentPoints = sfnt_get_ushort(sfont);
+ table->maxComponentContours = sfnt_get_ushort(sfont);
+ table->maxZones = sfnt_get_ushort(sfont);
+ table->maxTwilightPoints = sfnt_get_ushort(sfont);
+ table->maxStorage = sfnt_get_ushort(sfont);
+ table->maxFunctionDefs = sfnt_get_ushort(sfont);
+ table->maxInstructionDefs = sfnt_get_ushort(sfont);
+ table->maxStackElements = sfnt_get_ushort(sfont);
+ table->maxSizeOfInstructions = sfnt_get_ushort(sfont);
+ table->maxComponentElements = sfnt_get_ushort(sfont);
+ table->maxComponentDepth = sfnt_get_ushort(sfont);
+
+ return table;
+}
+
+char *tt_pack_hhea_table (struct tt_hhea_table *table)
+{
+ int i;
+ char *p, *data;
+
+ p = data = NEW(TT_HHEA_TABLE_SIZE, char);
+ p += sfnt_put_ulong(p, table->version);
+ p += sfnt_put_short(p, table->ascent);
+ p += sfnt_put_short(p, table->descent);
+ p += sfnt_put_short(p, table->lineGap);
+ p += sfnt_put_ushort(p, table->advanceWidthMax);
+ p += sfnt_put_short(p, table->minLeftSideBearing);
+ p += sfnt_put_short(p, table->minRightSideBearing);
+ p += sfnt_put_short(p, table->xMaxExtent);
+ p += sfnt_put_short(p, table->caretSlopeRise);
+ p += sfnt_put_short(p, table->caretSlopeRun);
+ p += sfnt_put_short(p, table->caretOffset);
+ for (i = 0; i < 4; i++) {
+ p += sfnt_put_short(p, table->reserved[i]);
+ }
+ p += sfnt_put_short(p, table->metricDataFormat);
+ p += sfnt_put_ushort(p, table->numOfLongHorMetrics);
+
+ return data;
+}
+
+struct tt_hhea_table *
+tt_read_hhea_table (sfnt *sfont)
+{
+ int i;
+ ULONG len;
+ struct tt_hhea_table *table = NEW(1, struct tt_hhea_table);
+
+ sfnt_locate_table(sfont, "hhea");
+
+ table->version = sfnt_get_ulong(sfont);
+ table->ascent = sfnt_get_short (sfont);
+ table->descent = sfnt_get_short(sfont);
+ table->lineGap = sfnt_get_short(sfont);
+ table->advanceWidthMax = sfnt_get_ushort(sfont);
+ table->minLeftSideBearing = sfnt_get_short(sfont);
+ table->minRightSideBearing = sfnt_get_short(sfont);
+ table->xMaxExtent = sfnt_get_short(sfont);
+ table->caretSlopeRise = sfnt_get_short(sfont);
+ table->caretSlopeRun = sfnt_get_short(sfont);
+ table->caretOffset = sfnt_get_short(sfont);
+ for(i = 0; i < 4; i++) {
+ table->reserved[i] = sfnt_get_short(sfont);
+ }
+ table->metricDataFormat = sfnt_get_short(sfont);
+ if (table->metricDataFormat != 0)
+ ERROR("unknown metricDataFormat");
+ table->numOfLongHorMetrics = sfnt_get_ushort(sfont);
+
+ len = sfnt_find_table_len(sfont, "hmtx");
+ table->numOfExSideBearings = (USHORT)((len - table->numOfLongHorMetrics * 4) / 2);
+
+ return table;
+}
+
+/* vhea */
+#if 0
+char *
+tt_pack_vhea_table (struct tt_vhea_table *table)
+{
+ int i;
+ char *p, *data;
+
+ p = data = NEW(TT_VHEA_TABLE_SIZE, char);
+ p += sfnt_put_ulong(p, table->version);
+ p += sfnt_put_short(p, table->vertTypoAscender);
+ p += sfnt_put_short(p, table->vertTypoDescender);
+ p += sfnt_put_short(p, table->vertTypoLineGap);
+ p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */
+ p += sfnt_put_short(p, table->minTopSideBearing);
+ p += sfnt_put_short(p, table->minBottomSideBearing);
+ p += sfnt_put_short(p, table->yMaxExtent);
+ p += sfnt_put_short(p, table->caretSlopeRise);
+ p += sfnt_put_short(p, table->caretSlopeRun);
+ p += sfnt_put_short(p, table->caretOffset);
+ for(i = 0; i < 4; i++) {
+ p += sfnt_put_short(p, table->reserved[i]);
+ }
+ p += sfnt_put_short(p, table->metricDataFormat);
+ p += sfnt_put_ushort(p, table->numOfLongVerMetrics);
+
+ return data;
+}
+#endif
+
+struct tt_vhea_table *tt_read_vhea_table (sfnt *sfont)
+{
+ int i;
+ ULONG len;
+ struct tt_vhea_table *table = NEW(1, struct tt_vhea_table);
+
+ sfnt_locate_table(sfont, "vhea");
+
+ table->version = sfnt_get_ulong(sfont);
+ table->vertTypoAscender = sfnt_get_short (sfont);
+ table->vertTypoDescender = sfnt_get_short(sfont);
+ table->vertTypoLineGap = sfnt_get_short(sfont);
+ table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */
+ table->minTopSideBearing = sfnt_get_short(sfont);
+ table->minBottomSideBearing = sfnt_get_short(sfont);
+ table->yMaxExtent = sfnt_get_short(sfont);
+ table->caretSlopeRise = sfnt_get_short(sfont);
+ table->caretSlopeRun = sfnt_get_short(sfont);
+ table->caretOffset = sfnt_get_short(sfont);
+ for(i = 0; i < 4; i++) {
+ (table->reserved)[i] = sfnt_get_short(sfont);
+ }
+ table->metricDataFormat = sfnt_get_short(sfont);
+ table->numOfLongVerMetrics = sfnt_get_ushort(sfont);
+
+ len = sfnt_find_table_len(sfont, "vmtx");
+ table->numOfExSideBearings = (USHORT)((len - table->numOfLongVerMetrics * 4) / 2);
+
+ return table;
+}
+
+
+struct tt_VORG_table *
+tt_read_VORG_table (sfnt *sfont)
+{
+ struct tt_VORG_table *vorg;
+ ULONG offset;
+ USHORT i;
+
+ offset = sfnt_find_table_pos(sfont, "VORG");
+
+ if (offset > 0) {
+ vorg = NEW(1, struct tt_VORG_table);
+
+ sfnt_locate_table(sfont, "VORG");
+ if (sfnt_get_ushort(sfont) != 1 ||
+ sfnt_get_ushort(sfont) != 0)
+ ERROR("Unsupported VORG version.");
+
+ vorg->defaultVertOriginY = sfnt_get_short(sfont);
+ vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont);
+ vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics,
+ struct tt_vertOriginYMetrics);
+ /*
+ * The vertOriginYMetrics array must be sorted in increasing
+ * glyphIndex order.
+ */
+ for (i = 0;
+ i < vorg->numVertOriginYMetrics; i++) {
+ vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont);
+ vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont);
+ }
+ } else {
+ vorg = NULL;
+ }
+
+ return vorg;
+}
+
+/*
+ * hmtx and vmtx
+ *
+ * Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea.
+ */
+
+struct tt_longMetrics *
+tt_read_longMetrics (sfnt *sfont, USHORT numGlyphs, USHORT numLongMetrics, USHORT numExSideBearings)
+{
+ struct tt_longMetrics *m;
+ USHORT gid, last_adv = 0;
+ SHORT last_esb = 0;
+
+ m = NEW(numGlyphs, struct tt_longMetrics);
+ for (gid = 0; gid < numGlyphs; gid++) {
+ if (gid < numLongMetrics)
+ last_adv = sfnt_get_ushort(sfont);
+ if (gid < numLongMetrics + numExSideBearings)
+ last_esb = sfnt_get_short(sfont);
+ m[gid].advance = last_adv;
+ m[gid].sideBearing = last_esb;
+ }
+
+ return m;
+}
+
+/* OS/2 table */
+/* this table may not exist */
+struct tt_os2__table *
+tt_read_os2__table (sfnt *sfont)
+{
+ struct tt_os2__table *table = NULL;
+ int i;
+
+ table = NEW(1, struct tt_os2__table);
+
+ if (sfnt_find_table_pos(sfont, "OS/2") > 0) {
+ sfnt_locate_table(sfont, "OS/2");
+ table->version = sfnt_get_ushort(sfont);
+ table->xAvgCharWidth = sfnt_get_short(sfont);
+ table->usWeightClass = sfnt_get_ushort(sfont);
+ table->usWidthClass = sfnt_get_ushort(sfont);
+ table->fsType = sfnt_get_short(sfont);
+ table->ySubscriptXSize = sfnt_get_short(sfont);
+ table->ySubscriptYSize = sfnt_get_short(sfont);
+ table->ySubscriptXOffset = sfnt_get_short(sfont);
+ table->ySubscriptYOffset = sfnt_get_short(sfont);
+ table->ySuperscriptXSize = sfnt_get_short(sfont);
+ table->ySuperscriptYSize = sfnt_get_short(sfont);
+ table->ySuperscriptXOffset = sfnt_get_short(sfont);
+ table->ySuperscriptYOffset = sfnt_get_short(sfont);
+ table->yStrikeoutSize = sfnt_get_short(sfont);
+ table->yStrikeoutPosition = sfnt_get_short(sfont);
+ table->sFamilyClass = sfnt_get_short(sfont);
+ for (i = 0; i < 10; i++) {
+ table->panose[i] = sfnt_get_byte(sfont);
+ }
+ table->ulUnicodeRange1 = sfnt_get_ulong(sfont);
+ table->ulUnicodeRange2 = sfnt_get_ulong(sfont);
+ table->ulUnicodeRange3 = sfnt_get_ulong(sfont);
+ table->ulUnicodeRange4 = sfnt_get_ulong(sfont);
+ for (i = 0; i < 4; i++) {
+ table->achVendID[i] = sfnt_get_char(sfont);
+ }
+ table->fsSelection = sfnt_get_ushort(sfont);
+ table->usFirstCharIndex = sfnt_get_ushort(sfont);
+ table->usLastCharIndex = sfnt_get_ushort(sfont);
+ if (sfnt_find_table_len(sfont, "OS/2") >= 78) {
+ /* these fields are not present in the original Apple spec (68-byte table),
+ but Microsoft's version of "format 0" does include them... grr! */
+ table->sTypoAscender = sfnt_get_short(sfont);
+ table->sTypoDescender = sfnt_get_short(sfont);
+ table->sTypoLineGap = sfnt_get_short(sfont);
+ table->usWinAscent = sfnt_get_ushort(sfont);
+ table->usWinDescent = sfnt_get_ushort(sfont);
+ if (table->version > 0) {
+ /* format 1 adds the following 2 fields */
+ table->ulCodePageRange1 = sfnt_get_ulong(sfont);
+ table->ulCodePageRange2 = sfnt_get_ulong(sfont);
+ if (table->version > 1) {
+ /* and formats 2 and 3 (current) include 5 more.... these share the
+ same fields, only the precise definition of some was changed */
+ table->sxHeight = sfnt_get_short(sfont);
+ table->sCapHeight = sfnt_get_short(sfont);
+ table->usDefaultChar = sfnt_get_ushort(sfont);
+ table->usBreakChar = sfnt_get_ushort(sfont);
+ table->usMaxContext = sfnt_get_ushort(sfont);
+ }
+ }
+ }
+ } else {
+
+ /* used in add_CIDVMetrics() of cidtype0.c */
+ table->sTypoAscender = 880;
+ table->sTypoDescender = -120;
+ /* used in tt_get_fontdesc() of tt_aux.c */
+ table->usWeightClass = 400U; /* Normal(Regular) */
+ table->xAvgCharWidth = 0; /* ignore */
+ table->version = 0; /* TrueType rev 1.5 */
+ table->fsType = 0; /* Installable Embedding */
+ table->fsSelection = 0U; /* All undefined */
+ table->sFamilyClass = 0; /* No Classification */
+ for (i = 0; i < 10; i++) {
+ table->panose[i] = 0; /* All Any */
+ }
+ }
+
+ return table;
+}
+
+static USHORT
+tt_get_name (sfnt *sfont, char *dest, USHORT destlen,
+ USHORT plat_id, USHORT enco_id,
+ USHORT lang_id, USHORT name_id)
+{
+ USHORT length = 0;
+ USHORT num_names, string_offset;
+ ULONG name_offset;
+ int i, j;
+ int is_utf16_be;
+
+ name_offset = sfnt_locate_table (sfont, "name");
+ is_utf16_be = (plat_id == 3) && (enco_id == 1) &&
+ (lang_id == 0x0409u) && (name_id == 6);
+
+ if (sfnt_get_ushort(sfont))
+ ERROR ("Expecting zero");
+
+ num_names = sfnt_get_ushort(sfont);
+ string_offset = sfnt_get_ushort(sfont);
+ for (i=0;i<num_names;i++) {
+ USHORT p_id, e_id, n_id, l_id;
+ USHORT offset;
+
+ p_id = sfnt_get_ushort(sfont);
+ e_id = sfnt_get_ushort(sfont);
+ l_id = sfnt_get_ushort(sfont);
+ n_id = sfnt_get_ushort(sfont);
+ length = sfnt_get_ushort(sfont);
+ offset = sfnt_get_ushort(sfont);
+ /* language ID value 0xffffu for `accept any language ID' */
+ if ((p_id == plat_id) && (e_id == enco_id) &&
+ (lang_id == 0xffffu || l_id == lang_id) && (n_id == name_id)) {
+ if (is_utf16_be) {
+ length /= 2;
+ }
+ if (length > destlen - 1) {
+ WARN ("Name string too long (%u), truncating to %u", length, destlen);
+ length = destlen - 1;
+ }
+ sfnt_seek_set (sfont, name_offset+string_offset+offset);
+ if (is_utf16_be) {
+ for (j=0;j<length;j++) {
+ dest[j] = (unsigned char)(sfnt_get_ushort(sfont) & 0x00FF);
+ }
+ }
+ else {
+ sfnt_read((unsigned char*)dest, length, sfont);
+ }
+ dest[length] = '\0';
+ break;
+ }
+ }
+ if (i == num_names) {
+ length = 0;
+ }
+
+ return length;
+}
+
+USHORT
+tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen)
+{
+ USHORT namelen = 0;
+
+ /* First try Mac-Roman PS name and then Win-Unicode PS name */
+ if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 ||
+ (namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 ||
+ (namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0)
+ return namelen;
+
+ WARN ("No valid PostScript name available");
+ /*
+ Workaround for some bad TTfonts:
+ Language ID value 0xffffu for `accept any language ID'
+ */
+ if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) {
+ /*
+ Finally falling back to Mac Roman name field.
+ Warning: Some bad Japanese TTfonts using SJIS encoded string in the
+ Mac Roman name field.
+ */
+ namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1);
+ }
+
+ return namelen;
+}
diff --git a/Build/source/texk/dvipdfm-x/tt_table.h b/Build/source/texk/dvipdfm-x/tt_table.h
new file mode 100644
index 00000000000..72e44f37396
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/tt_table.h
@@ -0,0 +1,194 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TT_TABLE_H_
+#define _TT_TABLE_H_
+
+#include "sfnt.h"
+
+#define TT_HEAD_TABLE_SIZE 54UL
+#define TT_MAXP_TABLE_SIZE 32UL
+#define TT_HHEA_TABLE_SIZE 36UL
+#define TT_VHEA_TABLE_SIZE 36UL
+
+struct tt_head_table
+{
+ Fixed version;
+ Fixed fontRevision;
+ ULONG checkSumAdjustment;
+ ULONG magicNumber;
+ USHORT flags;
+ USHORT unitsPerEm;
+ BYTE created[8];
+ BYTE modified[8];
+ FWord xMin, yMin, xMax, yMax;
+ USHORT macStyle;
+ USHORT lowestRecPPEM;
+ SHORT fontDirectionHint;
+ SHORT indexToLocFormat;
+ SHORT glyphDataFormat;
+};
+
+struct tt_hhea_table
+{
+ Fixed version;
+ FWord ascent;
+ FWord descent;
+ FWord lineGap;
+ uFWord advanceWidthMax;
+ FWord minLeftSideBearing;
+ FWord minRightSideBearing;
+ FWord xMaxExtent;
+ SHORT caretSlopeRise;
+ SHORT caretSlopeRun;
+ FWord caretOffset;
+ SHORT reserved[4]; /* set to 0 */
+ SHORT metricDataFormat;
+ USHORT numOfLongHorMetrics;
+ USHORT numOfExSideBearings; /* extra information */
+};
+
+struct tt_vhea_table
+{
+ Fixed version;
+ SHORT vertTypoAscender; /* v.1.1 name */
+ SHORT vertTypoDescender; /* v.1.1 name */
+ SHORT vertTypoLineGap; /* v.1.1 name */
+ SHORT advanceHeightMax;
+ SHORT minTopSideBearing;
+ SHORT minBottomSideBearing;
+ SHORT yMaxExtent;
+ SHORT caretSlopeRise;
+ SHORT caretSlopeRun;
+ SHORT caretOffset;
+ SHORT reserved[4]; /* set to 0 */
+ SHORT metricDataFormat;
+ USHORT numOfLongVerMetrics;
+ USHORT numOfExSideBearings; /* extra information */
+};
+
+struct tt_maxp_table
+{
+ Fixed version;
+ USHORT numGlyphs;
+ USHORT maxPoints;
+ USHORT maxContours;
+ USHORT maxComponentPoints;
+ USHORT maxComponentContours;
+ USHORT maxZones;
+ USHORT maxTwilightPoints;
+ USHORT maxStorage;
+ USHORT maxFunctionDefs;
+ USHORT maxInstructionDefs;
+ USHORT maxStackElements;
+ USHORT maxSizeOfInstructions;
+ USHORT maxComponentElements;
+ USHORT maxComponentDepth;
+};
+
+struct tt_os2__table
+{
+ USHORT version; /* 0x0001 or 0x0002 */
+ SHORT xAvgCharWidth;
+ USHORT usWeightClass;
+ USHORT usWidthClass;
+ SHORT fsType; /* if (faType & 0x08) editable_embedding */
+ SHORT ySubscriptXSize;
+ SHORT ySubscriptYSize;
+ SHORT ySubscriptXOffset;
+ SHORT ySubscriptYOffset;
+ SHORT ySuperscriptXSize;
+ SHORT ySuperscriptYSize;
+ SHORT ySuperscriptXOffset;
+ SHORT ySuperscriptYOffset;
+ SHORT yStrikeoutSize;
+ SHORT yStrikeoutPosition;
+ SHORT sFamilyClass;
+ BYTE panose[10];
+ ULONG ulUnicodeRange1;
+ ULONG ulUnicodeRange2;
+ ULONG ulUnicodeRange3;
+ ULONG ulUnicodeRange4;
+ CHAR achVendID[4];
+ USHORT fsSelection;
+ USHORT usFirstCharIndex;
+ USHORT usLastCharIndex;
+ SHORT sTypoAscender; /* TTF spec. from MS is wrong */
+ SHORT sTypoDescender; /* TTF spec. from MS is wrong */
+ SHORT sTypoLineGap; /* TTF spec. from MS is wrong */
+ USHORT usWinAscent;
+ USHORT usWinDescent;
+ ULONG ulCodePageRange1;
+ ULONG ulCodePageRange2;
+ /* version 0x0002 */
+ SHORT sxHeight;
+ SHORT sCapHeight;
+ USHORT usDefaultChar;
+ USHORT usBreakChar;
+ USHORT usMaxContext;
+};
+
+struct tt_vertOriginYMetrics {
+ USHORT glyphIndex;
+ SHORT vertOriginY;
+};
+
+struct tt_VORG_table {
+ SHORT defaultVertOriginY;
+ USHORT numVertOriginYMetrics;
+ struct tt_vertOriginYMetrics *vertOriginYMetrics;
+};
+
+/* hmtx and vmtx */
+struct tt_longMetrics
+{
+ USHORT advance;
+ SHORT sideBearing;
+};
+
+
+/* head, hhea, maxp */
+extern char *tt_pack_head_table (struct tt_head_table *table);
+extern struct tt_head_table *tt_read_head_table (sfnt *sfont);
+extern char *tt_pack_hhea_table (struct tt_hhea_table *table);
+extern struct tt_hhea_table *tt_read_hhea_table (sfnt *sfont);
+extern char *tt_pack_maxp_table (struct tt_maxp_table *table);
+extern struct tt_maxp_table *tt_read_maxp_table (sfnt *sfont);
+
+/* vhea */
+#if 0
+extern char *tt_pack_vhea_table (struct tt_vhea_table *table);
+#endif
+extern struct tt_vhea_table *tt_read_vhea_table (sfnt *sfont);
+
+/* VORG */
+extern struct tt_VORG_table *tt_read_VORG_table (sfnt *sfont);
+
+/* hmtx and vmtx */
+extern struct tt_longMetrics *tt_read_longMetrics (sfnt *sfont,
+ USHORT numGlyphs, USHORT numLongMetrics, USHORT numExSideBearings);
+
+/* OS/2 table */
+extern struct tt_os2__table *tt_read_os2__table (sfnt *sfont);
+
+/* name table */
+extern USHORT tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen);
+
+#endif /* _TT_TABLE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/type0.c b/Build/source/texk/dvipdfm-x/type0.c
new file mode 100644
index 00000000000..7dbbd984ad5
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/type0.c
@@ -0,0 +1,363 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2021 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * Type0 font support:
+ *
+ * TODO:
+ *
+ * Composite font (multiple descendants) - not supported in PDF
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxfile.h"
+
+#include "pdfobj.h"
+#include "fontmap.h"
+
+#include "cmap.h"
+#include "cidtype0.h"
+#include "cid.h"
+
+#include "type0.h"
+
+
+static pdf_obj *pdf_read_ToUnicode_file (const char *cmap_name);
+
+/* PLEASE FIX THIS */
+#include "tt_cmap.h"
+
+/* Try to load ToUnicode CMap from file system first, if not found fallback to
+ * font CMap reverse lookup.
+ * CHANGED: CMap here is not always Unicode to CID mapping. Don't use reverse lookup.
+ */
+static pdf_obj *
+try_load_ToUnicode_file (char *cmap_base)
+{
+ pdf_obj *tounicode;
+ char *cmap_name;
+
+ cmap_name = NEW(strlen(cmap_base)+strlen("-UTF16")+1, char);
+ sprintf(cmap_name, "%s-UTF16", cmap_base);
+ tounicode = pdf_read_ToUnicode_file(cmap_name);
+ if (!tounicode) {
+ sprintf(cmap_name, "%s-UCS2", cmap_base);
+ tounicode = pdf_read_ToUnicode_file(cmap_name);
+ }
+ RELEASE(cmap_name);
+
+ return tounicode;
+}
+
+static void
+Type0Font_attach_ToUnicode_stream (pdf_font *font)
+{
+ pdf_obj *tounicode;
+ pdf_font *cidfont = pdf_get_font_data(font->type0.descendant);
+ CIDSysInfo *csi;
+ char *fontname;
+
+ /*
+ * ToUnicode CMap:
+ *
+ * ToUnicode CMaps are usually not required for standard character
+ * collections such as Adobe-Japan1. Identity-H is used for UCS
+ * ordering CID-keyed fonts. External resource must be loaded for
+ * others.
+ */
+ ASSERT(cidfont);
+
+ if (CIDFont_is_ACCFont(cidfont)) {
+ /* No need to embed ToUnicode */
+ return;
+ } else if (CIDFont_is_UCSFont(cidfont)) {
+ /*
+ * Old version of dvipdfmx mistakenly used Adobe-Identity as Unicode.
+ */
+ /* ref returned */
+ tounicode = pdf_read_ToUnicode_file("Adobe-Identity-UCS2");
+ if (!tounicode) { /* This should work */
+ tounicode = pdf_new_name("Identity-H");
+ }
+ pdf_add_dict(font->resource, pdf_new_name("ToUnicode"), tounicode);
+ return;
+ }
+
+ tounicode = NULL;
+ csi = &cidfont->cid.csi;
+ if (cidfont->cid.options.embed) {
+ fontname = NEW(strlen(cidfont->fontname)+8, char);
+ sprintf(fontname, "%s+%s", cidfont->uniqueID, cidfont->fontname);
+ } else {
+ fontname = NEW(strlen(cidfont->fontname)+1, char);
+ strcpy(fontname, cidfont->fontname);
+ }
+
+ switch (cidfont->subtype) {
+ case PDF_FONT_FONTTYPE_CIDTYPE2:
+ if (!strcmp(csi->registry, "Adobe") && !strcmp(csi->ordering, "Identity")) {
+ tounicode = otf_create_ToUnicode_stream(cidfont->ident, cidfont->index,
+ fontname, font->usedchars);
+ } else {
+ char *cmap_base = NEW(strlen(csi->registry) + strlen(csi->ordering) + 2, char);
+ sprintf(cmap_base, "%s-%s", csi->registry, csi->ordering);
+ tounicode = try_load_ToUnicode_file(cmap_base);
+ RELEASE(cmap_base);
+ /* In this case glyphs are re-ordered hance otf_create... won't work */
+ }
+ break;
+ default:
+ if (cidfont->flags & CIDFONT_FLAG_TYPE1C) {
+ tounicode = otf_create_ToUnicode_stream(cidfont->ident, cidfont->index,
+ fontname, font->usedchars);
+ } else if (cidfont->flags & CIDFONT_FLAG_TYPE1) {
+ tounicode = CIDFont_type0_t1create_ToUnicode_stream(cidfont->ident, fontname, font->usedchars);
+ } else {
+ tounicode = try_load_ToUnicode_file(cidfont->fontname);
+ if (!tounicode) {
+ tounicode = otf_create_ToUnicode_stream(cidfont->ident, cidfont->index,
+ fontname, font->usedchars);
+ }
+ }
+ }
+ RELEASE(fontname);
+
+ if (tounicode) {
+ pdf_add_dict(font->resource, pdf_new_name("ToUnicode"), tounicode);
+ } else {
+#if defined(LIBDPX)
+ if (dpx_conf.verbose_level > 0)
+ WARN("Failed to load ToUnicode CMap for font \"%s\"", cidfont->fontname);
+#else
+ WARN("Failed to load ToUnicode CMap for font \"%s\"", cidfont->filename);
+#endif /* LIBDPX */
+ }
+
+ return;
+}
+
+void
+pdf_font_load_type0 (pdf_font *font)
+{
+ if (!font || !font->reference)
+ return;
+
+ /* FIXME: Should move to pdffont.c */
+ if (!pdf_lookup_dict(font->resource, "ToUnicode")) {
+ Type0Font_attach_ToUnicode_stream(font);
+ }
+}
+
+int
+pdf_font_open_type0 (pdf_font *font, int cid_id, int wmode)
+{
+ pdf_font *cidfont;
+ CIDSysInfo *csi;
+ char *fontname = NULL;
+
+ if (cid_id < 0)
+ return -1;
+
+ cidfont = pdf_get_font_data(cid_id);
+
+ font->type0.wmode = wmode;
+ font->type0.descendant = cid_id;
+
+ /*
+ * PostScript Font name:
+ *
+ * Type0 font's fontname is usually descendant CID-keyed font's font name
+ * appended by -ENCODING.
+ */
+ if (cidfont->cid.options.embed) {
+ fontname = NEW(strlen(cidfont->fontname)+8, char);
+ sprintf(fontname, "%s+%s", cidfont->uniqueID, cidfont->fontname);
+ } else {
+ fontname = NEW(strlen(cidfont->fontname)+1, char);
+ strcpy(fontname, cidfont->fontname);
+ }
+
+ if (dpx_conf.verbose_level > 0) {
+ MESG("(CID:%s)", cidfont->fontname);
+ }
+
+ switch (cidfont->subtype) {
+ case PDF_FONT_FONTTYPE_CIDTYPE0:
+ font->fontname = NEW(strlen(fontname)+strlen("Identity-V")+2, char);
+ sprintf(font->fontname, "%s-%s", fontname, wmode ? "Identity-V" : "Identity-H");
+ font->usedchars = CIDFont_get_usedchars(cidfont);
+ font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED;
+ if (wmode) {
+ cidfont->cid.need_vmetrics = 1;
+ }
+ break;
+ case PDF_FONT_FONTTYPE_CIDTYPE2:
+ font->fontname = NEW(strlen(fontname)+1, char);
+ strcpy(font->fontname, fontname);
+ /* Adobe-Identity here means use GID as CID directly. No need to use GSUB for finding
+ * vertical glyphs hence separate used_chars for H and V instances are not needed.
+ */
+ csi = &cidfont->cid.csi;
+ if (!csi || (!strcmp(csi->registry, "Adobe") && !strcmp(csi->ordering, "Identity"))) {
+ font->usedchars = CIDFont_get_usedchars(cidfont);
+ font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED;
+ } else {
+ font->usedchars = wmode ? CIDFont_get_usedchars_v(cidfont) : CIDFont_get_usedchars(cidfont);
+ font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED;
+ }
+ if (wmode) {
+ cidfont->cid.need_vmetrics = 1;
+ }
+ break;
+ }
+
+ font->resource = pdf_new_dict();
+ pdf_add_dict(font->resource, pdf_new_name ("Type"), pdf_new_name ("Font"));
+ pdf_add_dict(font->resource, pdf_new_name ("Subtype"), pdf_new_name ("Type0"));
+ pdf_add_dict(font->resource,
+ pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
+ pdf_add_dict(font->resource,
+ pdf_new_name("Encoding"), pdf_new_name(wmode ? "Identity-V" : "Identity-H"));
+
+ return 0;
+}
+
+/******************************** COMPAT ********************************/
+
+#ifndef WITHOUT_COMPAT
+
+#include "cmap_read.h"
+#include "cmap_write.h"
+#include "pdfresource.h"
+#include "pdfencoding.h"
+
+static pdf_obj *
+create_dummy_CMap (void)
+{
+ pdf_obj *stream;
+ char buf[32];
+ int i, n;
+
+#define CMAP_PART0 "\
+%!PS-Adobe-3.0 Resource-CMap\n\
+%%DocumentNeededResources: ProcSet (CIDInit)\n\
+%%IncludeResource: ProcSet (CIDInit)\n\
+%%BeginResource: CMap (Adobe-Identity-UCS2)\n\
+%%Title: (Adobe-Identity-UCS2 Adobe UCS2 0)\n\
+%%Version: 1.0\n\
+%%Copyright:\n\
+%% ---\n\
+%%EndComments\n\n\
+"
+#define CMAP_PART1 "\
+/CIDInit /ProcSet findresource begin\n\
+\n\
+12 dict begin\n\nbegincmap\n\n\
+/CIDSystemInfo 3 dict dup begin\n\
+ /Registry (Adobe) def\n\
+ /Ordering (UCS2) def\n\
+ /Supplement 0 def\n\
+end def\n\n\
+/CMapName /Adobe-Identity-UCS2 def\n\
+/CMapVersion 1.0 def\n\
+/CMapType 2 def\n\n\
+2 begincodespacerange\n\
+<0000> <FFFF>\n\
+endcodespacerange\n\
+"
+#define CMAP_PART3 "\
+endcmap\n\n\
+CMapName currentdict /CMap defineresource pop\n\n\
+end\nend\n\n\
+%%EndResource\n\
+%%EOF\n\
+"
+
+ stream = pdf_new_stream(STREAM_COMPRESS);
+ pdf_add_stream(stream, CMAP_PART0, strlen(CMAP_PART0));
+ pdf_add_stream(stream, CMAP_PART1, strlen(CMAP_PART1));
+ pdf_add_stream(stream, "\n100 beginbfrange\n", strlen("\n100 beginbfrange\n"));
+ for (i = 0; i < 0x64; i++) {
+ n = sprintf(buf,
+ "<%02X00> <%02XFF> <%02X00>\n", i, i, i);
+ pdf_add_stream(stream, buf, n);
+ }
+ pdf_add_stream(stream, "endbfrange\n\n", strlen("endbfrange\n\n"));
+
+ pdf_add_stream(stream, "\n100 beginbfrange\n", strlen("\n100 beginbfrange\n"));
+ for (i = 0x64; i < 0xc8; i++) {
+ n = sprintf(buf,
+ "<%02X00> <%02XFF> <%02X00>\n", i, i, i);
+ pdf_add_stream(stream, buf, n);
+ }
+ pdf_add_stream(stream, "endbfrange\n\n", strlen("endbfrange\n\n"));
+
+ pdf_add_stream(stream, "\n48 beginbfrange\n", strlen("\n48 beginbfrange\n"));
+ for (i = 0xc8; i <= 0xd7; i++) {
+ n = sprintf(buf,
+ "<%02X00> <%02XFF> <%02X00>\n", i, i, i);
+ pdf_add_stream(stream, buf, n);
+ }
+ for (i = 0xe0; i <= 0xff; i++) {
+ n = sprintf(buf,
+ "<%02X00> <%02XFF> <%02X00>\n", i, i, i);
+ pdf_add_stream(stream, buf, n);
+ }
+ pdf_add_stream(stream, "endbfrange\n\n", strlen("endbfrange\n\n"));
+
+ pdf_add_stream(stream, CMAP_PART3, strlen(CMAP_PART3));
+
+ return stream;
+}
+
+static pdf_obj *
+pdf_read_ToUnicode_file (const char *cmap_name)
+{
+ pdf_obj *stream;
+ int res_id = -1;
+
+ ASSERT(cmap_name);
+
+ res_id = pdf_findresource("CMap", cmap_name);
+ if (res_id < 0) {
+ if (!strcmp(cmap_name, "Adobe-Identity-UCS2"))
+ stream = create_dummy_CMap();
+ else {
+ stream = pdf_load_ToUnicode_stream(cmap_name);
+ }
+ if (stream) {
+ res_id = pdf_defineresource("CMap",
+ cmap_name,
+ stream, PDF_RES_FLUSH_IMMEDIATE);
+ }
+ }
+
+ return (res_id < 0 ? NULL : pdf_get_resource_reference(res_id));
+}
+#endif /* !WITHOUT_COMPAT */
diff --git a/Build/source/texk/dvipdfm-x/type0.h b/Build/source/texk/dvipdfm-x/type0.h
new file mode 100644
index 00000000000..330ba532d53
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/type0.h
@@ -0,0 +1,29 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TYPE0_H_
+#define _TYPE0_H_
+
+#include "pdffont.h"
+
+extern void pdf_font_load_type0 (pdf_font *font);
+extern int pdf_font_open_type0 (pdf_font *font, int cid_id, int wmode);
+
+#endif /* _TYPE0_H_ */
diff --git a/Build/source/texk/dvipdfm-x/type1.c b/Build/source/texk/dvipdfm-x/type1.c
new file mode 100644
index 00000000000..c6c899b791d
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/type1.c
@@ -0,0 +1,844 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <math.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxfile.h"
+
+#include "numbers.h"
+
+#include "pdfobj.h"
+#include "pdffont.h"
+
+#include "pdfencoding.h"
+#include "unicode.h"
+
+#include "dpxutil.h"
+
+#include "pst_obj.h"
+#include "pst.h"
+
+#include "cff_limits.h"
+#include "cff_types.h"
+#include "cff_dict.h"
+#include "cff.h"
+
+#include "t1_load.h"
+#include "t1_char.h"
+
+#include "type1.h"
+
+#define FONT_FLAG_FIXEDPITCH (1 << 0) /* Fixed-width font */
+#define FONT_FLAG_SERIF (1 << 1) /* Serif font */
+#define FONT_FLAG_SYMBOLIC (1 << 2) /* Symbolic font */
+#define FONT_FLAG_SCRIPT (1 << 3) /* Script font */
+#define FONT_FLAG_STANDARD (1 << 5) /* Adobe Standard Character Set */
+#define FONT_FLAG_ITALIC (1 << 6) /* Italic */
+#define FONT_FLAG_ALLCAP (1 << 16) /* All-cap font */
+#define FONT_FLAG_SMALLCAP (1 << 17) /* Small-cap font */
+#define FONT_FLAG_FORCEBOLD (1 << 18) /* Force bold at small text sizes */
+
+static int
+is_basefont (const char *name)
+{
+ static const char *basefonts[] = {
+ "Courier", "Courier-Bold", "Courier-Oblique",
+ "Courier-BoldOblique", "Helvetica", "Helvetica-Bold",
+ "Helvetica-Oblique", "Helvetica-BoldOblique", "Symbol",
+ "Times-Roman", "Times-Bold", "Times-Italic",
+ "Times-BoldItalic", "ZapfDingbats"
+ };
+ int i;
+
+ for (i = 0; i < 14; i++) {
+ if (!strcmp(name, basefonts[i]))
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+pdf_font_open_type1 (pdf_font *font, const char *ident, int index, int encoding_id, int embedding)
+{
+ FILE *fp;
+ char fontname[PDF_NAME_LEN_MAX+1];
+
+ ASSERT(font);
+ ASSERT(ident);
+
+ if (index != 0) {
+ WARN("Ignoring non-zero font index: %s", ident);
+ }
+
+ if (is_basefont(ident)) {
+ font->fontname = NEW(strlen(ident)+1, char);
+ strcpy(font->fontname, ident);
+ font->subtype = PDF_FONT_FONTTYPE_TYPE1;
+ font->flags |= PDF_FONT_FLAG_NOEMBED;
+ font->flags |= PDF_FONT_FLAG_BASEFONT;
+ } else {
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT);
+ if (!fp)
+ return -1;
+
+ if (!embedding) {
+ WARN("Ignoring no-embed option for Type1 font: %s", ident);
+ font->flags &= ~PDF_FONT_FLAG_NOEMBED;
+ }
+ memset(fontname, 0, PDF_NAME_LEN_MAX+1);
+ if (!is_pfb(fp) || t1_get_fontname(fp, fontname) < 0) {
+ ERROR("Failed to read Type 1 font \"%s\".", ident);
+ }
+ DPXFCLOSE(fp);
+
+ font->fontname = NEW(strlen(fontname)+1, char);
+ strcpy(font->fontname, fontname);
+ font->subtype = PDF_FONT_FONTTYPE_TYPE1;
+ }
+
+ return 0;
+}
+
+static void
+get_font_attr (pdf_font *font, cff_font *cffont)
+{
+ char *fontname;
+ pdf_obj *descriptor;
+ double capheight, ascent, descent;
+ double italicangle, stemv;
+ double defaultwidth, nominalwidth;
+ int flags = 0, gid, i;
+ static const char *L_c[] = {
+ "H", "P", "Pi", "Rho", NULL
+ };
+ static const char *L_d[] = {
+ "p", "q", "mu", "eta", NULL
+ };
+ static const char *L_a[] = {
+ "b", "h", "lambda", NULL
+ };
+ t1_ginfo gm;
+
+ defaultwidth = 500.0;
+ nominalwidth = 0.0;
+
+ /*
+ * CapHeight, Ascent, and Descent is meaningfull only for Latin/Greek/Cyrillic.
+ * The BlueValues and OtherBlues also have those information.
+ */
+ if (cff_dict_known(cffont->topdict, "FontBBox")) {
+ /* Default values */
+ capheight = ascent = cff_dict_get(cffont->topdict, "FontBBox", 3);
+ descent = cff_dict_get(cffont->topdict, "FontBBox", 1);
+ } else {
+ capheight = 680.0;
+ ascent = 690.0;
+ descent = -190.0;
+ }
+ if (cff_dict_known(cffont->private[0], "StdVW")) {
+ stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
+ } else {
+ /*
+ * We may use the following values for StemV:
+ * Thin - ExtraLight: <= 50
+ * Light: 71
+ * Regular(Normal): 88
+ * Medium: 109
+ * SemiBold(DemiBold): 135
+ * Bold - Heavy: >= 166
+ */
+ stemv = 88.0;
+ }
+ if (cff_dict_known(cffont->topdict, "ItalicAngle")) {
+ italicangle = cff_dict_get(cffont->topdict, "ItalicAngle", 0);
+ if (italicangle != 0.0)
+ flags |= FONT_FLAG_ITALIC;
+ } else {
+ italicangle = 0.0;
+ }
+
+ /*
+ * Use "space", "H", "p", and "b" for various values.
+ * Those characters should not "seac". (no accent)
+ */
+ gid = cff_glyph_lookup(cffont, "space");
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ defaultwidth = gm.wx;
+ }
+
+ for (i = 0; L_c[i] != NULL; i++) {
+ gid = cff_glyph_lookup(cffont, L_c[i]);
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ capheight = gm.bbox.ury;
+ break;
+ }
+ }
+
+ for (i = 0; L_d[i] != NULL; i++) {
+ gid = cff_glyph_lookup(cffont, L_d[i]);
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ descent = gm.bbox.lly;
+ break;
+ }
+ }
+
+ for (i = 0; L_a[i] != NULL; i++) {
+ gid = cff_glyph_lookup(cffont, L_a[i]);
+ if (gid >= 0 && gid < cffont->cstrings->count) {
+ t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
+ cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
+ cffont->subrs[0], &gm);
+ ascent = gm.bbox.ury;
+ break;
+ }
+ }
+
+ if (defaultwidth != 0.0) {
+ cff_dict_add(cffont->private[0], "defaultWidthX", 1);
+ cff_dict_set(cffont->private[0], "defaultWidthX", 0, defaultwidth);
+ }
+ if (nominalwidth != 0.0) {
+ cff_dict_add(cffont->private[0], "nominalWidthX", 1);
+ cff_dict_set(cffont->private[0], "nominalWidthX", 0, nominalwidth);
+ }
+ if (cff_dict_known(cffont->private[0], "ForceBold") &&
+ cff_dict_get(cffont->private[0], "ForceBold", 0)) {
+ flags |= FONT_FLAG_FORCEBOLD;
+ }
+ if (cff_dict_known(cffont->private[0], "IsFixedPitch") &&
+ cff_dict_get(cffont->private[0], "IsFixedPitch", 0)) {
+ flags |= FONT_FLAG_FIXEDPITCH;
+ }
+
+ fontname = font->fontname;
+ descriptor = pdf_font_get_descriptor(font);
+
+ if (fontname && !strstr(fontname, "Sans")) {
+ flags |= FONT_FLAG_SERIF;
+ }
+ if (fontname && strstr(fontname, "Caps")) {
+ flags |= FONT_FLAG_SMALLCAP;
+ }
+ flags |= FONT_FLAG_SYMBOLIC; /* FIXME */
+
+ pdf_add_dict(descriptor,
+ pdf_new_name("CapHeight"), pdf_new_number(capheight));
+ pdf_add_dict(descriptor,
+ pdf_new_name("Ascent"), pdf_new_number(ascent));
+ pdf_add_dict(descriptor,
+ pdf_new_name("Descent"), pdf_new_number(descent));
+ pdf_add_dict(descriptor,
+ pdf_new_name("ItalicAngle"), pdf_new_number(italicangle));
+ pdf_add_dict(descriptor,
+ pdf_new_name("StemV"), pdf_new_number(stemv));
+ pdf_add_dict(descriptor,
+ pdf_new_name("Flags"), pdf_new_number(flags));
+}
+
+static void
+add_metrics (pdf_font *font, cff_font *cffont, char **enc_vec, double *widths, int num_glyphs)
+{
+ pdf_obj *fontdict, *descriptor;
+ pdf_obj *array;
+ int code, firstchar, lastchar;
+ double val;
+ int i;
+ char *usedchars;
+ double scaling = 1.0;
+ double norm_widths[256];
+
+ fontdict = pdf_font_get_resource (font);
+ descriptor = pdf_font_get_descriptor(font);
+ usedchars = font->usedchars;
+
+ /*
+ * The original FontBBox of the font is preserved, instead
+ * of replacing it with tight bounding box calculated from
+ * charstrings, to prevent Acrobat 4 from greeking text as
+ * much as possible.
+ */
+ if (!cff_dict_known(cffont->topdict, "FontBBox")) {
+ ERROR("No FontBBox?");
+ }
+
+ /* The widhts array in the font dictionary must be given relative
+ * to the default scaling of 1000:1, not relative to the scaling
+ * given by the font matrix.
+ */
+ if (cff_dict_known(cffont->topdict, "FontMatrix")) {
+ scaling = 1000*cff_dict_get(cffont->topdict, "FontMatrix", 0);
+ } else {
+ scaling = 1;
+ }
+
+ array = pdf_new_array();
+ for (i = 0; i < 4; i++) {
+ val = cff_dict_get(cffont->topdict, "FontBBox", i);
+ pdf_add_array(array, pdf_new_number(ROUND(val, 1.0)));
+ }
+ pdf_add_dict(descriptor, pdf_new_name("FontBBox"), pdf_link_obj(array));
+ pdf_release_obj(array);
+
+ array = pdf_new_array();
+ if (num_glyphs <= 1) { /* This must be an error. */
+ firstchar = lastchar = 0;
+ pdf_add_array(array, pdf_new_number(0.0));
+ } else {
+ for (firstchar = 255, lastchar = 0, code = 0; code < 256; code++) {
+ if (usedchars[code]) {
+ if (code < firstchar) firstchar = code;
+ if (code > lastchar) lastchar = code;
+ norm_widths[code] = scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])];
+ }
+ }
+ if (firstchar > lastchar) {
+ WARN("No glyphs actually used???");
+ pdf_release_obj(array);
+ return;
+ }
+
+ pdf_check_tfm_widths(font->ident, norm_widths, firstchar, lastchar, usedchars);
+
+ for (code = firstchar; code <= lastchar; code++) {
+ if (usedchars[code]) {
+ pdf_add_array(array, pdf_new_number(ROUND(norm_widths[code], 0.1)));
+ } else {
+ pdf_add_array(array, pdf_new_number(0.0));
+ }
+ }
+ }
+
+ if (pdf_array_length(array) > 0) {
+ pdf_add_dict(fontdict, pdf_new_name("Widths"), pdf_ref_obj(array));
+ }
+ pdf_release_obj(array);
+
+ pdf_add_dict(fontdict, pdf_new_name("FirstChar"), pdf_new_number(firstchar));
+ pdf_add_dict(fontdict, pdf_new_name("LastChar"), pdf_new_number(lastchar));
+
+ return;
+}
+
+
+static int
+#if defined(LIBDPX)
+write_fontfile (pdf_font *font, cff_font *cffont)
+#else
+write_fontfile (pdf_font *font, cff_font *cffont, pdf_obj *pdfcharset)
+#endif /* LIBDPX */
+{
+ pdf_obj *descriptor;
+ pdf_obj *fontfile, *stream_dict;
+ cff_index *topdict;
+ int private_size, stream_data_len, charstring_len;
+ int topdict_offset, offset;
+#define WBUF_SIZE 1024
+ card8 *stream_data_ptr, wbuf[WBUF_SIZE];
+
+ descriptor = pdf_font_get_descriptor(font);
+
+ topdict = cff_new_index(1);
+ /*
+ * Force existence of Encoding.
+ */
+ if (!cff_dict_known(cffont->topdict, "CharStrings"))
+ cff_dict_add(cffont->topdict, "CharStrings", 1);
+ if (!cff_dict_known(cffont->topdict, "charset"))
+ cff_dict_add(cffont->topdict, "charset", 1);
+ if (!cff_dict_known(cffont->topdict, "Encoding"))
+ cff_dict_add(cffont->topdict, "Encoding", 1);
+ private_size = cff_dict_pack((cffont->private)[0], wbuf, WBUF_SIZE);
+ /* Private dict is required (but may have size 0) */
+ if (!cff_dict_known(cffont->topdict, "Private"))
+ cff_dict_add(cffont->topdict, "Private", 2);
+ topdict->offset[1] = cff_dict_pack(cffont->topdict, wbuf, WBUF_SIZE) + 1;
+
+ /*
+ * Estimate total size of fontfile.
+ */
+ charstring_len = cff_index_size(cffont->cstrings);
+
+ stream_data_len = 4; /* header size */
+ stream_data_len += cff_index_size(cffont->name);
+ stream_data_len += cff_index_size(topdict);
+ stream_data_len += cff_index_size(cffont->string);
+ stream_data_len += cff_index_size(cffont->gsubr);
+ /* We are using format 1 for Encoding and format 0 for charset.
+ * TODO: Should implement cff_xxx_size().
+ */
+ stream_data_len += 2 + (cffont->encoding->num_entries)*2 + 1 + (cffont->encoding->num_supps)*3;
+ stream_data_len += 1 + (cffont->charsets->num_entries)*2;
+ stream_data_len += charstring_len;
+ stream_data_len += private_size;
+
+ /*
+ * Now we create FontFile data.
+ */
+ stream_data_ptr = NEW(stream_data_len, card8);
+ /*
+ * Data Layout order as described in CFF spec., sec 2 "Data Layout".
+ */
+ offset = 0;
+ /* Header */
+ offset += cff_put_header(cffont,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* Name */
+ offset += cff_pack_index(cffont->name,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* Top DICT */
+ topdict_offset = offset;
+ offset += cff_index_size(topdict);
+ /* Strings */
+ offset += cff_pack_index(cffont->string,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* Global Subrs */
+ offset += cff_pack_index(cffont->gsubr,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* Encoding */
+ /* TODO: don't write Encoding entry if the font is always used
+ * with PDF Encoding information. Applies to type1c.c as well.
+ */
+ cff_dict_set(cffont->topdict, "Encoding", 0, offset);
+ offset += cff_pack_encoding(cffont,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* charset */
+ cff_dict_set(cffont->topdict, "charset", 0, offset);
+ offset += cff_pack_charsets(cffont,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* CharStrings */
+ cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
+ offset += cff_pack_index(cffont->cstrings,
+ stream_data_ptr + offset, charstring_len);
+ /* Private */
+ if ((cffont->private)[0] && private_size > 0) {
+ private_size = cff_dict_pack(cffont->private[0],
+ stream_data_ptr + offset, private_size);
+ cff_dict_set(cffont->topdict, "Private", 1, offset);
+ cff_dict_set(cffont->topdict, "Private", 0, private_size);
+ }
+ offset += private_size;
+
+ /* Finally Top DICT */
+ topdict->data = NEW(topdict->offset[1] - 1, card8);
+ cff_dict_pack (cffont->topdict, topdict->data, topdict->offset[1] - 1);
+ cff_pack_index(topdict,
+ stream_data_ptr + topdict_offset, cff_index_size(topdict));
+ cff_release_index(topdict);
+
+ /* Copyright and Trademark Notice ommited. */
+
+ /* Flush Font File */
+ fontfile = pdf_new_stream(STREAM_COMPRESS);
+ stream_dict = pdf_stream_dict(fontfile);
+ pdf_add_dict(descriptor,
+ pdf_new_name("FontFile3"), pdf_ref_obj (fontfile));
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Subtype"), pdf_new_name("Type1C"));
+ pdf_add_stream (fontfile, (void *) stream_data_ptr, offset);
+ pdf_release_obj(fontfile);
+#if !defined(LIBDPX)
+ if (pdf_check_version(2, 0) < 0) {
+ pdf_add_dict(descriptor,
+ pdf_new_name("CharSet"),
+ pdf_new_string(pdf_stream_dataptr(pdfcharset),
+ pdf_stream_length(pdfcharset)));
+ }
+#endif /* !LIBDPX */
+ RELEASE(stream_data_ptr);
+
+ return offset;
+}
+
+
+int
+pdf_font_load_type1 (pdf_font *font)
+{
+ pdf_obj *fontdict;
+#if !defined(LIBDPX)
+ pdf_obj *pdfcharset; /* Actually string object */
+#endif /* !LIBDPX */
+ int encoding_id;
+ char *usedchars, *ident;
+ char *fontname, *uniqueTag;
+ char *fullname; /* With pseudo unique tag */
+ cff_font *cffont;
+ cff_charsets *charset;
+ char **enc_vec;
+ double defaultwidth, nominalwidth;
+ double *widths;
+ card16 *GIDMap, num_glyphs = 0;
+ FILE *fp;
+ int offset;
+ int code;
+
+ ASSERT(font);
+
+ if (!font->reference)
+ return 0;
+
+ fontdict = pdf_font_get_resource(font);
+ encoding_id = font->encoding_id;
+ usedchars = font->usedchars;
+ ident = font->filename;
+ fontname = font->fontname;
+ uniqueTag = pdf_font_get_uniqueTag(font);
+
+ ASSERT(usedchars);
+ ASSERT(ident);
+ ASSERT(fontname);
+
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT);
+ if (!fp) {
+ ERROR("Type1: Could not open Type1 font: %s", ident);
+ }
+
+ GIDMap = NULL;
+ num_glyphs = 0;
+
+ if (encoding_id >= 0) {
+ enc_vec = NULL;
+ } else {
+ enc_vec = NEW(256, char *);
+ for (code = 0; code <= 0xff; code++) {
+ enc_vec[code] = NULL;
+ }
+ }
+
+ cffont = t1_load_font(enc_vec, 0, fp);
+ if (!cffont) {
+ ERROR("Could not load Type 1 font: %s", ident);
+ }
+ DPXFCLOSE(fp);
+
+ fullname = NEW(strlen(fontname) + 8, char);
+ sprintf(fullname, "%6s+%s", uniqueTag, fontname);
+
+ /*
+ * Encoding related things.
+ */
+ if (encoding_id >= 0) {
+ enc_vec = pdf_encoding_get_encoding(encoding_id);
+ } else {
+ pdf_obj *tounicode;
+
+ /*
+ * Create enc_vec and ToUnicode CMap for built-in encoding.
+ */
+ if (!pdf_lookup_dict(fontdict, "ToUnicode")) {
+ tounicode = pdf_create_ToUnicode_CMap(fullname,
+ enc_vec, usedchars);
+ if (tounicode) {
+ pdf_add_dict(fontdict,
+ pdf_new_name("ToUnicode"),
+ pdf_ref_obj (tounicode));
+ pdf_release_obj(tounicode);
+ }
+ }
+ }
+
+ cff_set_name(cffont, fullname);
+ RELEASE(fullname);
+
+ /* defaultWidthX, CapHeight, etc. */
+ get_font_attr(font, cffont);
+ if (cff_dict_known(cffont->private[0], "defaultWidthX")) {
+ defaultwidth = cff_dict_get(cffont->private[0], "defaultWidthX", 0);
+ } else {
+ defaultwidth = 0.0;
+ }
+ if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
+ nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
+ } else {
+ nominalwidth = 0.0;
+ }
+
+ /* Create CFF encoding, charset, sort glyphs */
+#define MAX_GLYPHS 1024
+ GIDMap = NEW(MAX_GLYPHS, card16);
+#if !defined(LIBDPX)
+ pdfcharset = pdf_new_stream(0);
+#endif /* !LIBDPX */
+ {
+ int prev, duplicate;
+ int gid;
+ char *glyph;
+ s_SID sid;
+
+ cffont->encoding = NEW(1, cff_encoding);
+ cffont->encoding->format = 1;
+ cffont->encoding->num_entries = 0;
+ cffont->encoding->data.range1 = NEW(256, cff_range1);
+ cffont->encoding->num_supps = 0;
+ cffont->encoding->supp = NEW(256, cff_map);
+
+ charset = NEW(1, cff_charsets);
+ charset->format = 0;
+ charset->num_entries = 0;
+ charset->data.glyphs = NEW(MAX_GLYPHS, s_SID);
+
+ gid = cff_glyph_lookup(cffont, ".notdef");
+ if (gid < 0)
+ ERROR("Type 1 font with no \".notdef\" glyph???");
+ GIDMap[0] = (card16) gid;
+ if (dpx_conf.verbose_level > 2)
+ MESG("[glyphs:/.notdef");
+ num_glyphs = 1;
+ for (prev = -2, code = 0; code <= 0xff; code++) {
+ glyph = enc_vec[code];
+
+ if (!usedchars[code])
+ continue;
+ if (glyph && !strcmp(glyph, ".notdef")) {
+ WARN("Character mapped to .notdef used in font: %s",
+ fontname);
+ usedchars[code] = 0;
+ continue;
+ }
+
+ gid = cff_glyph_lookup(cffont, glyph);
+ if (gid < 1 || gid >= cffont->cstrings->count) {
+ WARN("Glyph \"%s\" missing in font \"%s\".", glyph, fontname);
+ usedchars[code] = 0;
+ continue;
+ }
+
+ for (duplicate = 0; duplicate < code; duplicate++) {
+ if (usedchars[duplicate] &&
+ enc_vec[duplicate] && !strcmp(enc_vec[duplicate], glyph))
+ break;
+ }
+
+ sid = cff_add_string(cffont, glyph, 1); /* FIXME */
+ if (duplicate < code) { /* found duplicates */
+ cffont->encoding->supp[cffont->encoding->num_supps].code = duplicate;
+ cffont->encoding->supp[cffont->encoding->num_supps].glyph = sid;
+ cffont->encoding->num_supps += 1;
+ } else {
+ GIDMap[num_glyphs] = (card16) gid;
+ charset->data.glyphs[charset->num_entries] = sid;
+ charset->num_entries += 1;
+ if (code != prev + 1) {
+ cffont->encoding->num_entries += 1;
+ cffont->encoding->data.range1[cffont->encoding->num_entries-1].first = code;
+ cffont->encoding->data.range1[cffont->encoding->num_entries-1].n_left = 0;
+ } else {
+ cffont->encoding->data.range1[cffont->encoding->num_entries-1].n_left += 1;
+ }
+ prev = code;
+ num_glyphs++;
+
+ if (dpx_conf.verbose_level > 2) {
+ MESG("/%s", glyph);
+ }
+#if !defined(LIBDPX)
+ /* CharSet is actually string object. */
+ {
+ pdf_add_stream(pdfcharset, "/", 1);
+ pdf_add_stream(pdfcharset, glyph, strlen(glyph));
+ }
+#endif /* !LIBDPX */
+ }
+ }
+ if (cffont->encoding->num_supps > 0) {
+ cffont->encoding->format |= 0x80;
+ } else {
+ RELEASE(cffont->encoding->supp); /* FIXME */
+ cffont->encoding->supp = NULL;
+ }
+ }
+
+ widths = NEW(cffont->cstrings->count, double);
+ /*
+ * No more string will be added.
+ * The Type 1 seac operator may add another glyph but the glyph name of
+ * those glyphs are contained in standard string. The String Index will
+ * not be modified after here.
+ * BUT: We cannot update the String Index yet because then we wouldn't be
+ * able to find the GIDs of the base and accent characters (unless they
+ * have been used already).
+ */
+
+ {
+ cff_index *cstring;
+ t1_ginfo gm;
+ card16 gid, gid_orig;
+ int dstlen_max, srclen;
+ card8 *srcptr, *dstptr;
+
+ offset = dstlen_max = 0L;
+ cstring = cff_new_index(cffont->cstrings->count);
+ cstring->data = NULL;
+ cstring->offset[0] = 1;
+
+ /* The num_glyphs increases if "seac" operators are used. */
+ for (gid = 0; gid < num_glyphs; gid++) {
+ if (offset + CS_STR_LEN_MAX >= dstlen_max) {
+ dstlen_max += CS_STR_LEN_MAX * 2;
+ cstring->data = RENEW(cstring->data, dstlen_max, card8);
+ }
+ gid_orig = GIDMap[gid];
+
+ dstptr = cstring->data + cstring->offset[gid] - 1;
+ srcptr = cffont->cstrings->data + cffont->cstrings->offset[gid_orig] - 1;
+ srclen = cffont->cstrings->offset[gid_orig + 1] - cffont->cstrings->offset[gid_orig];
+
+ offset += t1char_convert_charstring(dstptr, CS_STR_LEN_MAX,
+ srcptr, srclen,
+ cffont->subrs[0], defaultwidth, nominalwidth, &gm);
+ cstring->offset[gid + 1] = offset + 1;
+ if (gm.use_seac) {
+ int bchar_gid, achar_gid, i;
+ const char *bchar_name, *achar_name;
+
+ /*
+ * NOTE:
+ * 1. seac.achar and seac.bchar must be contained in the CFF standard string.
+ * 2. Those characters need not to be encoded.
+ * 3. num_glyphs == charsets->num_entries + 1.
+ */
+ achar_name = t1_get_standard_glyph(gm.seac.achar);
+ achar_gid = cff_glyph_lookup(cffont, achar_name);
+ bchar_name = t1_get_standard_glyph(gm.seac.bchar);
+ bchar_gid = cff_glyph_lookup(cffont, bchar_name);
+ if (achar_gid < 0) {
+ WARN("Accent char \"%s\" not found. Invalid use of \"seac\" operator.",
+ achar_name);
+ continue;
+ }
+ if (bchar_gid < 0) {
+ WARN("Base char \"%s\" not found. Invalid use of \"seac\" operator.",
+ bchar_name);
+ continue;
+ }
+
+ for (i = 0; i < num_glyphs; i++) {
+ if (GIDMap[i] == achar_gid)
+ break;
+ }
+ if (i == num_glyphs) {
+ if (dpx_conf.verbose_level > 2)
+ MESG("/%s", achar_name);
+ GIDMap[num_glyphs++] = achar_gid;
+ charset->data.glyphs[charset->num_entries] = cff_get_seac_sid(cffont, achar_name);
+ charset->num_entries += 1;
+#if !defined(LIBDPX)
+ /* CharSet is actually string object. */
+ {
+ pdf_add_stream(pdfcharset, "/", 1);
+ pdf_add_stream(pdfcharset, achar_name, strlen(achar_name));
+ }
+#endif /* !LIBDPX */
+ }
+
+ for (i = 0; i < num_glyphs; i++) {
+ if (GIDMap[i] == bchar_gid)
+ break;
+ }
+ if (i == num_glyphs) {
+ if (dpx_conf.verbose_level > 2)
+ MESG("/%s", bchar_name);
+ GIDMap[num_glyphs++] = bchar_gid;
+ charset->data.glyphs[charset->num_entries] = cff_get_seac_sid(cffont, bchar_name);
+ charset->num_entries += 1;
+ #if !defined(LIBDPX)
+ /* CharSet is actually string object. */
+ {
+ pdf_add_stream(pdfcharset, "/", 1);
+ pdf_add_stream(pdfcharset, bchar_name, strlen(bchar_name));
+ }
+#endif /* !LIBDPX */
+ }
+ }
+ widths[gid] = gm.wx;
+ }
+ cstring->count = num_glyphs;
+
+ cff_release_index(cffont->subrs[0]);
+ cffont->subrs[0] = NULL;
+ RELEASE(cffont->subrs);
+ cffont->subrs = NULL;
+
+ cff_release_index(cffont->cstrings);
+ cffont->cstrings = cstring;
+
+ cff_release_charsets(cffont->charsets);
+ cffont->charsets = charset;
+ }
+ if (dpx_conf.verbose_level > 2)
+ MESG("]");
+
+ /* Now we can update the String Index */
+ cff_dict_update (cffont->topdict, cffont);
+ cff_dict_update (cffont->private[0], cffont);
+ cff_update_string(cffont);
+
+ add_metrics(font, cffont, enc_vec, widths, num_glyphs);
+
+#if defined(LIBDPX)
+ offset = write_fontfile(font, cffont);
+#else
+ offset = write_fontfile(font, cffont, pdfcharset);
+#endif /* LIBDPX */
+ if (dpx_conf.verbose_level > 1)
+ MESG("[%u glyphs][%ld bytes]", num_glyphs, offset);
+
+#if !defined(LIBDPX)
+ pdf_release_obj(pdfcharset);
+#endif /* LIBDPX */
+
+ cff_close(cffont);
+
+ /* Cleanup */
+ if (encoding_id < 0 && enc_vec) {
+ for (code = 0; code < 256; code++) {
+ if (enc_vec[code])
+ RELEASE(enc_vec[code]);
+ enc_vec[code] = NULL;
+ }
+ RELEASE(enc_vec);
+ }
+ if (widths)
+ RELEASE(widths);
+ if (GIDMap)
+ RELEASE(GIDMap);
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/type1.h b/Build/source/texk/dvipdfm-x/type1.h
new file mode 100644
index 00000000000..112eb3b2489
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/type1.h
@@ -0,0 +1,31 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TYPE1_H_
+#define _TYPE1_H_
+
+#include "pdffont.h"
+
+extern int pdf_font_open_type1 (pdf_font *font, const char *ident, int index, int encoding_id, int embedding);
+extern int pdf_font_load_type1 (pdf_font *font);
+
+#endif /* _TYPE1_H_ */
diff --git a/Build/source/texk/dvipdfm-x/type1c.c b/Build/source/texk/dvipdfm-x/type1c.c
new file mode 100644
index 00000000000..3d0adfec09a
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/type1c.c
@@ -0,0 +1,754 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * CFF/OpenType Font support:
+ *
+ * Adobe Technical Note #5176, "The Compact Font Format Specfication"
+ *
+ * NOTE:
+ *
+ * Many CFF/OpenType does not have meaningful/correct CFF encoding.
+ * Encoding should be expilicitly supplied in the fontmap.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "dpxconf.h"
+#include "dpxfile.h"
+
+#include "pdfobj.h"
+#include "pdffont.h"
+
+#include "pdfencoding.h"
+#include "unicode.h"
+
+/* Font info. from OpenType tables */
+#include "sfnt.h"
+#include "tt_aux.h"
+
+#include "cff_types.h"
+#include "cff_limits.h"
+#include "cff.h"
+#include "cff_dict.h"
+#include "cs_type2.h"
+
+#include "type1c.h"
+
+int
+pdf_font_open_type1c (pdf_font *font, const char *ident, int index, int encoding_id, int embedding)
+{
+ char *fontname;
+ FILE *fp = NULL;
+ sfnt *sfont;
+ cff_font *cffont;
+ pdf_obj *descriptor, *tmp;
+ ULONG offset = 0;
+
+ ASSERT(font);
+ ASSERT(ident);
+
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_OTFONT);
+ if (!fp)
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_TTFONT);
+ if (!fp)
+ return -1;
+
+ sfont = sfnt_open(fp);
+ if (!sfont) {
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (sfont->type == SFNT_TYPE_TTC) {
+ offset = ttc_read_offset(sfont, index);
+ }
+
+ if ((sfont->type != SFNT_TYPE_TTC && sfont->type != SFNT_TYPE_POSTSCRIPT) ||
+ sfnt_read_table_directory(sfont, offset) < 0 ||
+ (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ cffont = cff_open(sfont->stream, offset, 0);
+ if (!cffont) {
+ WARN("Could not read CFF font data: %s", ident);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ if (cffont->flag & FONTTYPE_CIDFONT) {
+ cff_close (cffont);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ fontname = cff_get_name(cffont);
+ if (!fontname) {
+ WARN("No valid FontName found in CFF/OpenType font: %s", ident);
+ cff_close (cffont);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+ font->fontname = fontname;
+
+ cff_close(cffont);
+
+ if (!embedding) {
+ WARN("Ignoring no-embed option for Type1C font: %s", ident);
+ embedding = 1;
+ font->flags &= ~PDF_FONT_FLAG_NOEMBED;
+ }
+ /*
+ * Font like AdobePiStd does not have meaningful built-in encoding.
+ * Some software generate CFF/OpenType font with incorrect encoding.
+ */
+ if (encoding_id < 0) {
+ WARN("Built-in encoding used for CFF/OpenType font.");
+ WARN("CFF font in OpenType font sometimes have strange built-in encoding.");
+ WARN("If you find text is not encoded properly in the generated PDF file,");
+ WARN("please specify appropriate \".enc\" file in your fontmap.");
+ }
+ font->subtype = PDF_FONT_FONTTYPE_TYPE1C;
+
+ descriptor = pdf_font_get_descriptor(font);
+ /*
+ * Create font descriptor from OpenType tables.
+ * We can also use CFF TOP DICT/Private DICT for this.
+ */
+ tmp = tt_get_fontdesc(sfont, &embedding, -1, 1, fontname);
+ if (!tmp) {
+ ERROR("Could not obtain neccesary font info from OpenType table.");
+ return -1;
+ }
+ pdf_merge_dict (descriptor, tmp); /* copy */
+ pdf_release_obj(tmp);
+ if (!embedding) { /* tt_get_fontdesc may have changed this */
+ WARN("Font embedding disallowed for \"%s\"", ident);
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+ return -1;
+ }
+
+ sfnt_close(sfont);
+ if (fp)
+ DPXFCLOSE(fp);
+
+ return 0;
+}
+
+static void
+add_SimpleMetrics (pdf_font *font, cff_font *cffont, double *widths, card16 num_glyphs)
+{
+ pdf_obj *fontdict;
+ int code, firstchar, lastchar;
+ char *usedchars;
+ pdf_obj *array;
+ double scaling = 1.0;
+
+ fontdict = pdf_font_get_resource(font);
+ usedchars = font->usedchars;
+
+ /* The widhts array in the font dictionary must be given relative
+ * to the default scaling of 1000:1, not relative to the scaling
+ * given by the font matrix.
+ */
+ if (cff_dict_known(cffont->topdict, "FontMatrix")) {
+ scaling = 1000.0 * cff_dict_get(cffont->topdict, "FontMatrix", 0);
+ } else {
+ scaling = 1.0;
+ }
+
+ array = pdf_new_array();
+ if (num_glyphs <= 1) {
+ /* This should be error. */
+ firstchar = lastchar = 0;
+ pdf_add_array(array, pdf_new_number(0.0));
+ } else {
+ firstchar = 255; lastchar = 0;
+ for (code = 0; code < 256; code++) {
+ if (usedchars[code]) {
+ if (code < firstchar) firstchar = code;
+ if (code > lastchar) lastchar = code;
+ widths[code] *= scaling;
+ }
+ }
+ if (firstchar > lastchar) {
+ ERROR("No glyphs used at all!");
+ return;
+ }
+ pdf_check_tfm_widths(font->ident, widths, firstchar, lastchar, usedchars);
+
+ for (code = firstchar; code <= lastchar; code++) {
+ if (usedchars[code]) {
+ pdf_add_array(array, pdf_new_number(ROUND(widths[code], 0.1)));
+ } else {
+ pdf_add_array(array, pdf_new_number(0.0));
+ }
+ }
+ }
+
+ if (pdf_array_length(array) > 0) {
+ pdf_add_dict(fontdict, pdf_new_name("Widths"), pdf_ref_obj(array));
+ }
+ pdf_release_obj(array);
+
+ pdf_add_dict(fontdict, pdf_new_name("FirstChar"), pdf_new_number(firstchar));
+ pdf_add_dict(fontdict, pdf_new_name("LastChar"), pdf_new_number(lastchar));
+
+ return;
+}
+
+int
+pdf_font_load_type1c (pdf_font *font)
+{
+ pdf_obj *fontdict, *descriptor;
+ pdf_obj *pdfcharset; /* Actually string object */
+ char *usedchars;
+ char *fontname, *uniqueTag, *ident, *fullname;
+ FILE *fp = NULL;
+ int encoding_id;
+ pdf_obj *fontfile, *stream_dict;
+ char **enc_vec;
+ sfnt *sfont;
+ cff_font *cffont;
+ cff_index *charstrings, *topdict, *cs_idx;
+ cff_charsets *charset = NULL;
+ cff_encoding *encoding = NULL;
+ int topdict_offset, private_size;
+ int charstring_len, max_len;
+ int size, offset = 0;
+ int stream_data_len = 0;
+ card8 *stream_data_ptr, *data;
+ card16 num_glyphs, cs_count, code;
+ cs_ginfo ginfo;
+ double nominal_width, default_width, notdef_width;
+ double widths[256];
+
+ ASSERT(font);
+
+ if (!font->reference)
+ return 0;
+
+ if (font->flags & PDF_FONT_FLAG_NOEMBED) {
+ ERROR("Only embedded font supported for CFF/OpenType font.");
+ }
+
+ usedchars = font->usedchars;
+ fontname = font->fontname;
+ ident = font->filename;
+ uniqueTag = pdf_font_get_uniqueTag (font);
+
+ ASSERT(usedchars);
+ ASSERT(fontname);
+ ASSERT(ident);
+
+ fontdict = pdf_font_get_resource (font);
+ descriptor = pdf_font_get_descriptor(font);
+ encoding_id = font->encoding_id;
+
+ fp = DPXFOPEN(ident, DPX_RES_TYPE_OTFONT);
+ if (!fp) {
+ ERROR("Could not open OpenType font: %s", ident);
+ }
+
+ sfont = sfnt_open(fp);
+ if (!sfont) {
+ ERROR("Could not open OpenType font: %s", ident);
+ }
+ if (sfnt_read_table_directory(sfont, 0) < 0) {
+ ERROR("Could not read OpenType table directory: %s", ident);
+ }
+ if (sfont->type != SFNT_TYPE_POSTSCRIPT ||
+ (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
+ ERROR("Not a CFF/OpenType font (or variable font?) (11)?");
+ }
+
+ cffont = cff_open(fp, offset, 0);
+ if (!cffont) {
+ ERROR("Could not open CFF font.");
+ }
+ if (cffont->flag & FONTTYPE_CIDFONT) {
+ ERROR("This is CIDFont...");
+ }
+
+ fullname = NEW(strlen(fontname) + 8, char);
+ sprintf(fullname, "%6s+%s", uniqueTag, fontname);
+
+ /* Offsets from DICTs */
+ cff_read_charsets(cffont);
+ if (encoding_id < 0)
+ cff_read_encoding(cffont);
+ cff_read_private(cffont);
+ cff_read_subrs (cffont);
+
+ /* FIXME */
+ cffont->_string = cff_new_index(0);
+
+ /* New Charsets data */
+ charset = NEW(1, cff_charsets);
+ charset->format = 0;
+ charset->num_entries = 0;
+ charset->data.glyphs = NEW(256, s_SID);
+
+ /*
+ * Encoding related things.
+ */
+ enc_vec = NULL;
+ if (encoding_id >= 0) {
+ enc_vec = pdf_encoding_get_encoding(encoding_id);
+ } else {
+ pdf_obj *tounicode;
+
+ /*
+ * Create enc_vec and ToUnicode CMap for built-in encoding.
+ */
+ enc_vec = NEW(256, char *);
+ for (code = 0; code < 256; code++) {
+ if (usedchars[code]) {
+ card16 gid;
+
+ gid = cff_encoding_lookup(cffont, code);
+ enc_vec[code] = cff_get_string(cffont, cff_charsets_lookup_inverse(cffont, gid));
+ } else {
+ enc_vec[code] = NULL;
+ }
+ }
+ if (!pdf_lookup_dict(fontdict, "ToUnicode")) {
+ tounicode = pdf_create_ToUnicode_CMap(fullname, enc_vec, usedchars);
+ if (tounicode) {
+ pdf_add_dict(fontdict,
+ pdf_new_name("ToUnicode"),
+ pdf_ref_obj (tounicode));
+ pdf_release_obj(tounicode);
+ }
+ }
+ }
+
+ /*
+ * New Encoding data:
+ *
+ * We should not use format 0 here.
+ * The number of encoded glyphs (num_entries) is limited to 255 in format 0,
+ * and hence it causes problem for encodings that uses full 256 code-points.
+ * As we always sort glyphs by encoding, we can avoid this problem simply
+ * by using format 1; Using full range result in a single range, 0 255.
+ *
+ * Creating actual encoding date is delayed to eliminate character codes to
+ * be mapped to .notdef and to handle multiply-encoded glyphs.
+ */
+ encoding = NEW(1, cff_encoding);
+ encoding->format = 1;
+ encoding->num_entries = 0;
+ encoding->data.range1 = NEW(255, cff_range1);
+ encoding->num_supps = 0;
+ encoding->supp = NEW(255, cff_map);
+
+ /*
+ * Charastrings.
+ */
+ offset = cff_dict_get(cffont->topdict, "CharStrings", 0);
+ cff_seek_set(cffont, offset);
+ cs_idx = cff_get_index_header(cffont);
+
+ /* Offset is now absolute offset ... fixme */
+ offset = cff_tell(cffont);
+ cs_count = cs_idx->count;
+ if (cs_count < 2) {
+ ERROR("No valid charstring data found.");
+ }
+
+ /* New CharStrings INDEX */
+ charstrings = cff_new_index(257); /* 256 + 1 for ".notdef" glyph */
+ max_len = 2 * CS_STR_LEN_MAX;
+ charstrings->data = NEW(max_len, card8);
+ charstring_len = 0;
+
+ /*
+ * Information from OpenType table is rough estimate. Replace with accurate value.
+ */
+ if (cffont->private[0] &&
+ cff_dict_known(cffont->private[0], "StdVW")) {
+ double stemv;
+
+ stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
+ pdf_add_dict(descriptor, pdf_new_name("StemV"), pdf_new_number(stemv));
+ }
+
+ /*
+ * Widths
+ */
+ if (cffont->private[0] &&
+ cff_dict_known(cffont->private[0], "defaultWidthX")) {
+ default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0);
+ } else {
+ default_width = CFF_DEFAULTWIDTHX_DEFAULT;
+ }
+ if (cffont->private[0] &&
+ cff_dict_known(cffont->private[0], "nominalWidthX")) {
+ nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0);
+ } else {
+ nominal_width = CFF_NOMINALWIDTHX_DEFAULT;
+ }
+
+ data = NEW(CS_STR_LEN_MAX, card8);
+
+ /* First we add .notdef glyph.
+ * All Type 1 font requires .notdef glyph to be present.
+ */
+ if (dpx_conf.verbose_level > 2) {
+ MESG("[glyphs:/.notdef");
+ }
+ size = cs_idx->offset[1] - cs_idx->offset[0];
+ if (size > CS_STR_LEN_MAX) {
+ ERROR("Charstring too long: gid=%u, %ld bytes", 0, size);
+ }
+ charstrings->offset[0] = charstring_len + 1;
+ cff_seek(cffont, offset + cs_idx->offset[0] - 1);
+ cff_read_data(data, size, cffont);
+ charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
+ max_len - charstring_len,
+ data, size,
+ cffont->gsubr, cffont->subrs[0],
+ default_width, nominal_width, &ginfo);
+ notdef_width = ginfo.wx;
+
+ /*
+ * Subset font
+ */
+ num_glyphs = 1;
+ pdfcharset = pdf_new_stream(0);
+ for (code = 0; code < 256; code++) {
+ card16 gid, j;
+ s_SID sid_orig, sid;
+
+ widths[code] = notdef_width;
+
+ if (!usedchars[code] || !enc_vec[code] ||
+ !strcmp(enc_vec[code], ".notdef"))
+ continue;
+
+ /*
+ * FIXME:
+ * cff_get_sid() obtain SID from original String INDEX.
+ * It should be cff_string_get_sid(string, ...).
+ * cff_add_string(cff, ...) -> cff_string_add(string, ...).
+ */
+ sid_orig = cff_get_sid (cffont, enc_vec[code]);
+ sid = sid_orig < CFF_STDSTR_MAX ?
+ sid_orig : cff_add_string(cffont, enc_vec[code], 0);
+ /*
+ * We use "unique = 0" because duplicate strings are impossible
+ * at this stage unless the original font already had duplicates.
+ */
+
+ /*
+ * Check if multiply-encoded glyph.
+ */
+ for (j = 0; j < charset->num_entries; j++) {
+ if (sid == charset->data.glyphs[j]) {
+ /* Already have this glyph. */
+ encoding->supp[encoding->num_supps].code = code;
+ encoding->supp[encoding->num_supps].glyph = sid;
+ usedchars[code] = 0; /* Used but multiply-encoded. */
+ encoding->num_supps += 1;
+ break;
+ }
+ }
+ if (j < charset->num_entries) {
+ continue; /* Prevent duplication. */
+ }
+
+ /* This is new encoding entry. */
+ gid = cff_charsets_lookup(cffont, sid_orig); /* FIXME */
+ if (gid == 0) {
+ WARN("Glyph \"%s\" missing in font \"%s\".", enc_vec[code], fontname);
+ WARN("Maybe incorrect encoding specified.");
+ usedchars[code] = 0; /* Set unused for writing correct encoding */
+ continue;
+ }
+ pdf_add_stream(pdfcharset, "/", 1);
+ pdf_add_stream(pdfcharset, enc_vec[code], strlen(enc_vec[code]));
+
+ if (dpx_conf.verbose_level > 2) {
+ MESG("/%s", enc_vec[code]);
+ }
+
+ size = cs_idx->offset[gid+1] - cs_idx->offset[gid];
+ if (size > CS_STR_LEN_MAX) {
+ ERROR("Charstring too long: gid=%u, %ld bytes", gid, size);
+ }
+
+ if (charstring_len + CS_STR_LEN_MAX >= max_len) {
+ max_len = charstring_len + 2 * CS_STR_LEN_MAX;
+ charstrings->data = RENEW(charstrings->data, max_len, card8);
+ }
+ charstrings->offset[num_glyphs] = charstring_len + 1;
+ cff_seek(cffont, offset + cs_idx->offset[gid] - 1);
+ cff_read_data(data, size, cffont);
+ charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
+ max_len - charstring_len,
+ data, size,
+ cffont->gsubr, cffont->subrs[0],
+ default_width, nominal_width, &ginfo);
+ widths[code] = ginfo.wx;
+ charset->data.glyphs[charset->num_entries] = sid;
+ charset->num_entries += 1;
+ num_glyphs++;
+ }
+ if (dpx_conf.verbose_level > 2) {
+ MESG("]");
+ }
+ RELEASE(data);
+
+ /*
+ * Now we create encoding data.
+ */
+ if (encoding->num_supps > 0)
+ encoding->format |= 0x80; /* Have supplemantary data. */
+ else {
+ RELEASE(encoding->supp); /* FIXME */
+ }
+ for (code = 0; code < 256; code++) {
+ if (!usedchars[code] ||
+ !enc_vec[code] || !strcmp(enc_vec[code], ".notdef"))
+ continue;
+ encoding->data.range1[encoding->num_entries].first = code;
+ encoding->data.range1[encoding->num_entries].n_left = 0;
+ code++;
+ while (code < 256 && usedchars[code] &&
+ enc_vec[code] && strcmp(enc_vec[code], ".notdef")) {
+ encoding->data.range1[encoding->num_entries].n_left += 1;
+ code++;
+ }
+ encoding->num_entries += 1;
+ /* The above while() loop stopped at unused char or code == 256. */
+ }
+
+ /* cleanup */
+ if (encoding_id < 0 && enc_vec) {
+ for (code = 0; code < 256; code++) {
+ if (enc_vec[code]) {
+ RELEASE(enc_vec[code]);
+ }
+ }
+ RELEASE(enc_vec);
+ }
+
+ cff_release_index(cs_idx);
+
+ charstrings->offset[num_glyphs] = charstring_len + 1;
+ charstrings->count = num_glyphs;
+ charstring_len = cff_index_size(charstrings);
+ cffont->num_glyphs = num_glyphs;
+
+ /*
+ * Discard old one, set new data.
+ */
+ if (cffont->charsets)
+ cff_release_charsets(cffont->charsets);
+ cffont->charsets = charset;
+ if (cffont->encoding)
+ cff_release_encoding(cffont->encoding);
+ cffont->encoding = encoding;
+ /*
+ * We don't use subroutines at all.
+ */
+ if (cffont->gsubr)
+ cff_release_index(cffont->gsubr);
+ cffont->gsubr = cff_new_index(0);
+ if (cffont->subrs[0])
+ cff_release_index(cffont->subrs[0]);
+ cffont->subrs[0] = NULL;
+
+ /*
+ * Flag must be reset since cff_pack_encoding(charset) does not write
+ * encoding(charset) if HAVE_STANDARD_ENCODING(CHARSET) is set. We are
+ * re-encoding font.
+ */
+ cffont->flag = FONTTYPE_FONT;
+
+ /*
+ * FIXME:
+ * Update String INDEX to delete unused strings.
+ */
+ cff_dict_update(cffont->topdict, cffont);
+ if (cffont->private[0])
+ cff_dict_update(cffont->private[0], cffont);
+ cff_update_string(cffont);
+
+ /*
+ * Calculate sizes of Top DICT and Private DICT.
+ * All offset values in DICT are set to long (32-bit) integer
+ * in cff_dict_pack(), those values are updated later.
+ */
+ topdict = cff_new_index(1);
+
+ cff_dict_remove(cffont->topdict, "UniqueID");
+ cff_dict_remove(cffont->topdict, "XUID");
+
+ /*
+ * Force existence of Encoding.
+ */
+ if (!cff_dict_known(cffont->topdict, "Encoding"))
+ cff_dict_add(cffont->topdict, "Encoding", 1);
+ topdict->offset[1] = cff_dict_pack(cffont->topdict,
+ (card8 *) work_buffer,
+ WORK_BUFFER_SIZE) + 1;
+ private_size = 0;
+ if (cffont->private[0]) {
+ cff_dict_remove(cffont->private[0], "Subrs"); /* no Subrs */
+ private_size = cff_dict_pack(cffont->private[0],
+ (card8 *) work_buffer, WORK_BUFFER_SIZE);
+ }
+
+ /*
+ * Estimate total size of fontfile.
+ */
+ stream_data_len = 4; /* header size */
+
+ stream_data_len += cff_set_name(cffont, fullname);
+ RELEASE(fullname);
+
+ stream_data_len += cff_index_size(topdict);
+ stream_data_len += cff_index_size(cffont->string);
+ stream_data_len += cff_index_size(cffont->gsubr);
+
+ /* We are using format 1 for Encoding and format 0 for charset.
+ * TODO: Should implement cff_xxx_size().
+ */
+ stream_data_len += 2 + (encoding->num_entries)*2 + 1 + (encoding->num_supps)*3;
+ stream_data_len += 1 + (charset->num_entries)*2;
+ stream_data_len += charstring_len;
+ stream_data_len += private_size;
+
+ /*
+ * Now we create FontFile data.
+ */
+ stream_data_ptr = NEW(stream_data_len, card8);
+
+ /*
+ * Data Layout order as described in CFF spec., sec 2 "Data Layout".
+ */
+ offset = 0;
+ /* Header */
+ offset += cff_put_header(cffont, stream_data_ptr + offset, stream_data_len - offset);
+ /* Name */
+ offset += cff_pack_index(cffont->name, stream_data_ptr + offset, stream_data_len - offset);
+ /* Top DICT */
+ topdict_offset = offset;
+ offset += cff_index_size(topdict);
+ /* Strings */
+ offset += cff_pack_index(cffont->string,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* Global Subrs */
+ offset += cff_pack_index(cffont->gsubr,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* Encoding */
+ cff_dict_set(cffont->topdict, "Encoding", 0, offset);
+ offset += cff_pack_encoding(cffont,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* charset */
+ cff_dict_set(cffont->topdict, "charset", 0, offset);
+ offset += cff_pack_charsets(cffont,
+ stream_data_ptr + offset, stream_data_len - offset);
+ /* CharStrings */
+ cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
+ offset += cff_pack_index(charstrings,
+ stream_data_ptr + offset, charstring_len);
+ cff_release_index(charstrings);
+ /* Private */
+ cff_dict_set(cffont->topdict, "Private", 1, offset);
+ if (cffont->private[0] && private_size > 0)
+ private_size = cff_dict_pack(cffont->private[0],
+ stream_data_ptr + offset, private_size);
+ cff_dict_set(cffont->topdict, "Private", 0, private_size);
+ offset += private_size;
+
+ /* Finally Top DICT */
+ topdict->data = NEW(topdict->offset[1] - 1, card8);
+ cff_dict_pack (cffont->topdict, topdict->data, topdict->offset[1] - 1);
+ cff_pack_index(topdict,
+ stream_data_ptr + topdict_offset, cff_index_size(topdict));
+ cff_release_index(topdict);
+
+ /* Copyright and Trademark Notice ommited. */
+
+ /* Handle Widths in fontdict. */
+ add_SimpleMetrics(font, cffont, widths, num_glyphs);
+
+ /* Close font */
+ cff_close (cffont);
+ sfnt_close(sfont);
+
+ if (fp)
+ DPXFCLOSE(fp);
+
+ if (dpx_conf.verbose_level > 1) {
+ MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, offset);
+ }
+
+ /*
+ * CharSet
+ */
+ if (pdf_check_version(2, 0) < 0) {
+ pdf_add_dict(descriptor,
+ pdf_new_name("CharSet"),
+ pdf_new_string(pdf_stream_dataptr(pdfcharset),
+ pdf_stream_length(pdfcharset)));
+ }
+ pdf_release_obj(pdfcharset);
+ /*
+ * Write PDF FontFile data.
+ */
+ fontfile = pdf_new_stream(STREAM_COMPRESS);
+ stream_dict = pdf_stream_dict(fontfile);
+ pdf_add_dict(descriptor,
+ pdf_new_name("FontFile3"), pdf_ref_obj (fontfile));
+ pdf_add_dict(stream_dict,
+ pdf_new_name("Subtype"), pdf_new_name("Type1C"));
+ pdf_add_stream (fontfile, (void *) stream_data_ptr, offset);
+ pdf_release_obj(fontfile);
+
+ RELEASE(stream_data_ptr);
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/type1c.h b/Build/source/texk/dvipdfm-x/type1c.h
new file mode 100644
index 00000000000..bf81149e7cb
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/type1c.h
@@ -0,0 +1,31 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _TYPE1C_H_
+#define _TYPE1C_H_
+
+#include "pdffont.h"
+
+extern int pdf_font_open_type1c (pdf_font *font, const char *ident, int index, int encoding_id, int embedding);
+extern int pdf_font_load_type1c (pdf_font *font);
+
+#endif /* _TYPE1C_H_ */
diff --git a/Build/source/texk/dvipdfm-x/unicode.c b/Build/source/texk/dvipdfm-x/unicode.c
new file mode 100644
index 00000000000..aa094369256
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/unicode.c
@@ -0,0 +1,258 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * Unicode related:
+ * Conversion between UTF-* and UCS-*.
+ * ToUnicode CMap
+ *
+ * Normalization?
+ *
+ * I made some unused functions here for completeness and FUTURE USE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+
+#include "unicode.h"
+
+#define UC_DEBUG 3
+#define UC_DEBUG_STR "UC"
+
+#define UC_REPLACEMENT_CHAR 0x0000FFFD
+
+#define UC_SUR_SHIFT 10
+#define UC_SUR_MASK 0x03FFU
+#define UC_SUR_LOW_START 0xDC00U
+#define UC_SUR_HIGH_START 0xD800U
+#define UC_SUR_END 0xE000U
+
+int
+UC_is_valid (int32_t ucv)
+{
+ if ( ucv < 0 || ucv > 0x10FFFFL ||
+ (ucv >= 0x0000D800L && ucv <= 0x0000DFFFL))
+ return 0;
+ return 1;
+}
+
+int
+UC_UTF16BE_is_valid_string (const unsigned char *p, const unsigned char *endptr)
+{
+ if (p + 1 >= endptr)
+ return 0;
+ while (p < endptr) {
+ int32_t ucv = UC_UTF16BE_decode_char(&p, endptr);
+ if (!UC_is_valid(ucv))
+ return 0;
+ }
+ return 1;
+}
+
+int
+UC_UTF8_is_valid_string (const unsigned char *p, const unsigned char *endptr)
+{
+ if (p >= endptr)
+ return 0;
+ while (p < endptr) {
+ int32_t ucv = UC_UTF8_decode_char(&p, endptr);
+ if (!UC_is_valid(ucv))
+ return 0;
+ }
+ return 1;
+}
+
+int32_t
+UC_UTF16BE_decode_char (const unsigned char **pp, const unsigned char *endptr)
+{
+ const unsigned char *p = *pp;
+ int32_t ucv = -1;
+ uint16_t first, second;
+
+ if (p + 1 >= endptr)
+ return -1;
+
+ first = ((p[0]) << 8|p[1]); p += 2;
+ if (first >= UC_SUR_HIGH_START && first < UC_SUR_LOW_START) {
+ if (p + 1 >= endptr)
+ return -1;
+ second = (p[0] << 8|p[1]); p += 2;
+ ucv = second & UC_SUR_MASK;
+ ucv |= (first & UC_SUR_MASK) << UC_SUR_SHIFT;
+ ucv += 0x00010000;
+ } else if (first >= UC_SUR_LOW_START && first < UC_SUR_END) {
+ return -1;
+ } else {
+ ucv = first;
+ }
+
+ *pp = p;
+ return ucv;
+}
+
+size_t
+UC_UTF16BE_encode_char (int32_t ucv, unsigned char **pp, unsigned char *endptr)
+{
+ int count = 0;
+ unsigned char *p = *pp;
+
+ if (ucv >= 0 && ucv <= 0xFFFF) {
+ if (p + 2 > endptr)
+ return 0;
+ p[0] = (ucv >> 8) & 0xff;
+ p[1] = ucv & 0xff;
+ count = 2;
+ } else if (ucv >= 0x010000 && ucv <= 0x10FFFF) {
+ unsigned short high, low;
+
+ if (p + 4 > endptr)
+ return 0;
+ ucv -= 0x00010000;
+ high = (ucv >> UC_SUR_SHIFT) + UC_SUR_HIGH_START;
+ low = (ucv & UC_SUR_MASK) + UC_SUR_LOW_START;
+ p[0] = (high >> 8) & 0xff;
+ p[1] = (high & 0xff);
+ p[2] = (low >> 8) & 0xff;
+ p[3] = (low & 0xff);
+ count = 4;
+ } else {
+ if (p + 2 > endptr)
+ return 0;
+ p[0] = (UC_REPLACEMENT_CHAR >> 8) & 0xff;
+ p[1] = (UC_REPLACEMENT_CHAR & 0xff);
+ count = 2;
+ }
+
+ *pp += count;
+ return count;
+}
+
+int32_t
+UC_UTF8_decode_char (const unsigned char **pp, const unsigned char *endptr)
+{
+ const unsigned char *p = *pp;
+ int32_t ucv;
+ unsigned char c = *p++;
+ int nbytes;
+
+ if (c <= 0x7f) {
+ ucv = c;
+ nbytes = 0;
+ } else if ((c & 0xe0) == 0xc0) { /* 110x xxxx */
+ ucv = c & 31;
+ nbytes = 1;
+ } else if ((c & 0xf0) == 0xe0) { /* 1110 xxxx */
+ ucv = c & 0x0f;
+ nbytes = 2;
+ } else if ((c & 0xf8) == 0xf0) { /* 1111 0xxx */
+ ucv = c & 0x07;
+ nbytes = 3;
+ } else if ((c & 0xfc) == 0xf8) { /* 1111 10xx */
+ ucv = c & 0x03;
+ nbytes = 4;
+ } else if ((c & 0xfe) == 0xfc) { /* 1111 110x */
+ ucv = c & 0x01;
+ nbytes = 5;
+ } else {
+ return -1;
+ }
+ if (p + nbytes > endptr)
+ return -1;
+ while (nbytes-- > 0) {
+ c = *p++;
+ if ((c & 0xc0) != 0x80)
+ return -1;
+ ucv = (ucv << 6) | (c & 0x3f);
+ }
+
+ *pp = p;
+ return ucv;
+}
+
+size_t
+UC_UTF8_encode_char (int32_t ucv, unsigned char **pp, unsigned char *endptr)
+{
+ int count = 0;
+ unsigned char *p = *pp;
+
+ ASSERT( pp && *pp && endptr );
+
+ if (!UC_is_valid(ucv))
+ return 0;
+
+ if (ucv < 0x7f) {
+ if (p + 1 > endptr)
+ return 0;
+ p[0] = (unsigned char) ucv;
+ count = 1;
+ } else if (ucv <= 0x7ff) {
+ if (p + 2 > endptr)
+ return 0;
+ p[0] = (unsigned char) (0xc0 | (ucv >> 6));
+ p[1] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 2;
+ } else if (ucv <= 0xffff) {
+ if (p + 3 > endptr)
+ return 0;
+ p[0] = (unsigned char) (0xe0 | (ucv >> 12));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[2] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 3;
+ } else if (ucv <= 0x1fffff) {
+ if (p + 4 > endptr)
+ return 0;
+ p[0] = (unsigned char) (0xf0 | (ucv >> 18));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 12) & 0x3f));
+ p[2] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[3] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 4;
+ } else if (ucv <= 0x3ffffff) {
+ if (p + 5 > endptr)
+ return 0;
+ p[0] = (unsigned char) (0xf8 | (ucv >> 24));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 18) & 0x3f));
+ p[2] = (unsigned char) (0x80 | ((ucv >> 12) & 0x3f));
+ p[3] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[4] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 5;
+ } else if (ucv <= 0x7fffffff) {
+ if (p + 6 > endptr)
+ return 0;
+ p[0] = (unsigned char) (0xfc | (ucv >> 30));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 24) & 0x3f));
+ p[2] = (unsigned char) (0x80 | ((ucv >> 18) & 0x3f));
+ p[3] = (unsigned char) (0x80 | ((ucv >> 12) & 0x3f));
+ p[4] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[5] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 6;
+ }
+
+ *pp += count;
+ return count;
+}
diff --git a/Build/source/texk/dvipdfm-x/unicode.h b/Build/source/texk/dvipdfm-x/unicode.h
new file mode 100644
index 00000000000..3df04e28a04
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/unicode.h
@@ -0,0 +1,35 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _UNICODE_H_
+#define _UNICODE_H_
+
+extern int UC_is_valid (int32_t ucv);
+extern int UC_UTF16BE_is_valid_string (const unsigned char *p, const unsigned char *endptr);
+extern int UC_UTF8_is_valid_string (const unsigned char *p, const unsigned char *endptr);
+
+extern size_t UC_UTF16BE_encode_char (int32_t ucv, unsigned char **dstpp, unsigned char *endptr);
+extern int32_t UC_UTF16BE_decode_char (const unsigned char **pp, const unsigned char *endptr);
+extern int32_t UC_UTF8_decode_char (const unsigned char **pp, const unsigned char *endptr);
+extern size_t UC_UTF8_encode_char (int32_t ucv, unsigned char **dstpp, unsigned char *endptr);
+
+#endif /* _UNICODE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/vf.c b/Build/source/texk/dvipdfm-x/vf.c
new file mode 100644
index 00000000000..835e85de701
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/vf.c
@@ -0,0 +1,572 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "system.h"
+#include "numbers.h"
+#include "error.h"
+#include "mem.h"
+#include "dpxconf.h"
+#include "dpxfile.h"
+/* pdfdev... */
+#include "pdfdev.h"
+
+#include "tfm.h"
+#include "dvi.h"
+#include "vf.h"
+#include "dvipdfmx.h"
+
+#include "dvicodes.h"
+
+#define VF_ALLOC_SIZE 16u
+
+#define VF_ID 202
+#define FIX_WORD_BASE 1048576.0
+#define TEXPT2PT (72.0/72.27)
+#define FW2PT (TEXPT2PT/((double)(FIX_WORD_BASE)))
+
+struct font_def {
+ int32_t font_id /* id used internally in vf file */;
+ uint32_t checksum, size, design_size;
+ char *directory, *name;
+ int tfm_id; /* id returned by TFM module */
+ int dev_id; /* id returned by DEV module */
+};
+
+struct vf
+{
+ char *tex_name;
+ spt_t ptsize;
+ uint32_t design_size; /* A fixword-pts quantity */
+ int num_dev_fonts, max_dev_fonts;
+ struct font_def *dev_fonts;
+ unsigned char **ch_pkt, message_flag;
+ uint32_t *pkt_len;
+ unsigned num_chars;
+};
+
+struct vf *vf_fonts = NULL;
+int num_vf_fonts = 0, max_vf_fonts = 0;
+
+static void read_header(FILE *vf_file, int thisfont)
+{
+ /* Check for usual signature */
+ if (get_unsigned_byte (vf_file) == PRE &&
+ get_unsigned_byte (vf_file) == VF_ID) {
+
+ /* If here, assume it's a legitimate vf file */
+
+ /* skip comment */
+ skip_bytes (get_unsigned_byte (vf_file), vf_file);
+
+ /* Skip checksum */
+ skip_bytes (4, vf_file);
+
+ vf_fonts[thisfont].design_size = get_positive_quad(vf_file, "VF", "design_size");
+ } else { /* Try to fail gracefully and return an error to caller */
+ fprintf (stderr, "VF file may be corrupt\n");
+ }
+}
+
+
+static void resize_vf_fonts(int size)
+{
+ int i;
+ if (size > max_vf_fonts) {
+ vf_fonts = RENEW (vf_fonts, size, struct vf);
+ for (i=max_vf_fonts; i<size; i++) {
+ vf_fonts[i].num_dev_fonts = 0;
+ vf_fonts[i].max_dev_fonts = 0;
+ vf_fonts[i].dev_fonts = NULL;
+ vf_fonts[i].message_flag = 0;
+ }
+ max_vf_fonts = size;
+ }
+ return;
+}
+
+static void resize_one_vf_font (struct vf *a_vf, unsigned size)
+{
+ unsigned i;
+ if (size > (a_vf->num_chars)) {
+ size = MAX (size, a_vf->num_chars+256);
+ a_vf->ch_pkt = RENEW (a_vf->ch_pkt, size, unsigned char *);
+ a_vf->pkt_len = RENEW (a_vf->pkt_len, size, uint32_t);
+ for (i=a_vf->num_chars; i<size; i++) {
+ (a_vf->ch_pkt)[i] = NULL;
+ (a_vf->pkt_len)[i] = 0;
+ }
+ a_vf->num_chars = size;
+ }
+}
+
+static void read_a_char_def(FILE *vf_file, int thisfont, uint32_t pkt_len,
+ uint32_t ch)
+{
+ unsigned char *pkt;
+#ifdef DEBUG
+ fprintf (stderr, "read_a_char_def: len=%u, ch=%u\n", pkt_len, ch);
+#endif
+ /* Resize and initialize character arrays if necessary */
+ if (ch >= vf_fonts[thisfont].num_chars) {
+ resize_one_vf_font (vf_fonts+thisfont, ch+1);
+ }
+ if (pkt_len > 0) {
+ pkt = NEW (pkt_len, unsigned char);
+ if (fread (pkt, 1, pkt_len, vf_file) != pkt_len)
+ ERROR ("VF file ended prematurely.");
+ (vf_fonts[thisfont].ch_pkt)[ch] = pkt;
+ }
+ (vf_fonts[thisfont].pkt_len)[ch] = pkt_len;
+ return;
+}
+
+static void read_a_font_def(FILE *vf_file, int32_t font_id, int thisfont)
+{
+ struct font_def *dev_font;
+ int dir_length, name_length;
+#ifdef DEBUG
+ fprintf (stderr, "read_a_font_def: font_id = %d\n", font_id);
+#endif
+ if (vf_fonts[thisfont].num_dev_fonts >=
+ vf_fonts[thisfont].max_dev_fonts) {
+ vf_fonts[thisfont].max_dev_fonts += VF_ALLOC_SIZE;
+ vf_fonts[thisfont].dev_fonts = RENEW
+ (vf_fonts[thisfont].dev_fonts,
+ vf_fonts[thisfont].max_dev_fonts,
+ struct font_def);
+ }
+ dev_font = vf_fonts[thisfont].dev_fonts+
+ vf_fonts[thisfont].num_dev_fonts;
+ dev_font -> font_id = font_id;
+ dev_font -> checksum = get_unsigned_quad (vf_file);
+ dev_font -> size = get_positive_quad (vf_file, "VF", "font_size");
+ dev_font -> design_size = get_positive_quad (vf_file, "VF", "font_design_size");
+ dir_length = get_unsigned_byte (vf_file);
+ name_length = get_unsigned_byte (vf_file);
+ dev_font -> directory = NEW (dir_length+1, char);
+ dev_font -> name = NEW (name_length+1, char);
+ fread (dev_font -> directory, 1, dir_length, vf_file);
+ fread (dev_font -> name, 1, name_length, vf_file);
+ (dev_font -> directory)[dir_length] = 0;
+ (dev_font -> name)[name_length] = 0;
+ vf_fonts[thisfont].num_dev_fonts += 1;
+ dev_font->tfm_id = tfm_open (dev_font -> name, 1); /* must exist */
+ dev_font->dev_id =
+ dvi_locate_font (dev_font->name,
+ sqxfw (vf_fonts[thisfont].ptsize,
+ dev_font->size));
+#ifdef DEBUG
+ fprintf (stderr, "[%s/%s]\n", dev_font -> directory, dev_font -> name);
+#endif
+ return;
+}
+
+static void process_vf_file (FILE *vf_file, int thisfont)
+{
+ int eof = 0, code;
+ int32_t font_id;
+ while (!eof) {
+ code = get_unsigned_byte (vf_file);
+ switch (code) {
+ case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
+ font_id = get_unsigned_num (vf_file, code-FNT_DEF1);
+ read_a_font_def (vf_file, font_id, thisfont);
+ break;
+ default:
+ if (code < 242) {
+ /* For a short packet, code is the pkt_len */
+ uint32_t ch = get_unsigned_byte (vf_file);
+ /* Skip over TFM width since we already know it */
+ skip_bytes (3, vf_file);
+ read_a_char_def (vf_file, thisfont, code, ch);
+ break;
+ }
+ if (code == 242) {
+ uint32_t pkt_len = get_positive_quad (vf_file, "VF", "pkt_len");
+ uint32_t ch = get_unsigned_quad (vf_file);
+ /* Skip over TFM width since we already know it */
+ skip_bytes (4, vf_file);
+ if (ch < 0x1000000U)
+ read_a_char_def (vf_file, thisfont, pkt_len, ch);
+ else {
+ fprintf (stderr, "char=%u\n", ch);
+ ERROR ("Long character (>24 bits) in VF file.\nI can't handle long characters!\n");
+ }
+ break;
+ }
+ if (code == POST) {
+ eof = 1;
+ break;
+ }
+ fprintf (stderr, "Quitting on code=%d\n", code);
+ eof = 1;
+ break;
+ }
+ }
+ return;
+}
+
+/* Unfortunately, the following code isn't smart enough
+ to load the vf only once for multiple point sizes.
+ You will get a separate copy of each VF in memory (and a separate
+ opening and reading of the file) for
+ each point size. Since VFs are pretty small, I guess
+ this is tolerable for now. In any case,
+ the PDF file will never repeat a physical font name */
+/* Note: This code needs to be able to recurse */
+/* Global variables such as num_vf_fonts require careful attention */
+int vf_locate_font (const char *tex_name, spt_t ptsize)
+{
+ int thisfont = -1, i;
+ char *full_vf_file_name;
+ FILE *vf_file;
+ /* Has this name and ptsize already been loaded as a VF? */
+ for (i=0; i<num_vf_fonts; i++) {
+ if (!strcmp (vf_fonts[i].tex_name, tex_name) &&
+ vf_fonts[i].ptsize == ptsize)
+ break;
+ }
+ if (i != num_vf_fonts) {
+ thisfont = i;
+ } else {
+ /* It's hasn't already been loaded as a VF, so try to load it */
+ full_vf_file_name = kpse_find_file (tex_name,
+ kpse_vf_format,
+ 1);
+ if (!full_vf_file_name) {
+ full_vf_file_name = kpse_find_file (tex_name,
+ kpse_ovf_format,
+ 1);
+ }
+ if (full_vf_file_name &&
+ (vf_file = MFOPEN (full_vf_file_name, FOPEN_RBIN_MODE)) != NULL) {
+ if (dpx_conf.verbose_level == 1)
+ fprintf (stderr, "(VF:%s", tex_name);
+ if (dpx_conf.verbose_level > 1)
+ fprintf (stderr, "(VF:%s", full_vf_file_name);
+ if (num_vf_fonts >= max_vf_fonts) {
+ resize_vf_fonts (max_vf_fonts + VF_ALLOC_SIZE);
+ }
+ thisfont = num_vf_fonts++;
+ { /* Initialize some pointers and such */
+ vf_fonts[thisfont].tex_name = NEW (strlen(tex_name)+1, char);
+ strcpy (vf_fonts[thisfont].tex_name, tex_name);
+ vf_fonts[thisfont].ptsize = ptsize;
+ vf_fonts[thisfont].num_chars = 0;
+ vf_fonts[thisfont].ch_pkt = NULL;
+ vf_fonts[thisfont].pkt_len = NULL;
+ }
+ read_header(vf_file, thisfont);
+ process_vf_file (vf_file, thisfont);
+ if (dpx_conf.verbose_level > 0)
+ fprintf (stderr, ")");
+ MFCLOSE (vf_file);
+ }
+ if (full_vf_file_name)
+ RELEASE(full_vf_file_name);
+ }
+ return thisfont;
+}
+
+#define next_byte() (*((*start)++))
+static int unsigned_byte (unsigned char **start, unsigned char *end)
+{
+ int byte = 0;
+ if (*start < end)
+ byte = next_byte();
+ else
+ ERROR ("Premature end of DVI byte stream in VF font\n");
+ return byte;
+}
+
+static int32_t get_pkt_signed_num (unsigned char **start, unsigned char *end,
+ unsigned char num)
+{
+ int32_t val = 0;
+ if (end-*start > num) {
+ val = next_byte();
+ if (val > 0x7f)
+ val -= 0x100;
+ switch (num) {
+ case 3: val = (val << 8) | next_byte();
+ case 2: val = (val << 8) | next_byte();
+ case 1: val = (val << 8) | next_byte();
+ default: break;
+ }
+ } else
+ ERROR ("Premature end of DVI byte stream in VF font\n");
+ return val;
+}
+
+static int32_t get_pkt_unsigned_num (unsigned char **start, unsigned char *end,
+ unsigned char num)
+{
+ int32_t val = 0;
+ if (end-*start > num) {
+ val = next_byte();
+ switch (num) {
+ case 3: if (val > 0x7f)
+ val -= 0x100;
+ val = (val << 8) | next_byte();
+ case 2: val = (val << 8) | next_byte();
+ case 1: val = (val << 8) | next_byte();
+ default: break;
+ }
+ } else
+ ERROR ("Premature end of DVI byte stream in VF font\n");
+ return val;
+}
+
+static void vf_putrule (unsigned char **start, unsigned char *end, spt_t ptsize)
+{
+ int32_t height = get_pkt_signed_num (start, end, 3);
+ int32_t width = get_pkt_signed_num (start, end, 3);
+ dvi_rule (sqxfw (ptsize, width), sqxfw (ptsize, height));
+}
+
+static void vf_setrule (unsigned char **start, unsigned char *end, spt_t ptsize)
+{
+ int32_t height = get_pkt_signed_num (start, end, 3);
+ int32_t s_width = sqxfw (ptsize, get_pkt_signed_num (start, end, 3));
+ dvi_rule (s_width, sqxfw (ptsize, height));
+ dvi_right (s_width);
+}
+
+static void vf_fnt (int32_t font_id, int vf_font)
+{
+ int i;
+ for (i=0; i<vf_fonts[vf_font].num_dev_fonts; i++) {
+ if (font_id == ((vf_fonts[vf_font].dev_fonts)[i]).font_id) {
+ break;
+ }
+ }
+ if (i < vf_fonts[vf_font].num_dev_fonts) { /* Font was found */
+ dvi_set_font ((vf_fonts[vf_font].dev_fonts[i]).dev_id);
+ } else {
+ fprintf (stderr, "Font_id: %d not found in VF\n", font_id);
+ }
+}
+
+/* identical to do_xxx in dvi.c */
+static void vf_xxx (int32_t len, unsigned char **start, unsigned char *end)
+{
+ if (*start <= end - len) {
+ unsigned char *buffer = NEW(len+1, unsigned char);
+ memcpy(buffer, *start, len);
+ buffer[len] = '\0';
+ {
+ unsigned char *p = buffer;
+
+ while (p < buffer+len && *p == ' ') p++;
+ /*
+ * Warning message from virtual font.
+ */
+ if (!memcmp((char *)p, "Warning:", 8)) {
+ if (dpx_conf.verbose_level > 0)
+ WARN("VF:%s", p+8);
+ } else {
+ dvi_do_special(buffer, len);
+ }
+ }
+ RELEASE(buffer);
+ } else {
+ ERROR ("Premature end of DVI byte stream in VF font.");
+ }
+
+ *start += len;
+ return;
+}
+
+void vf_set_char(int32_t ch, int vf_font)
+{
+ unsigned char opcode;
+ unsigned char *start, *end;
+ spt_t ptsize;
+ int default_font = -1;
+ if (vf_font < num_vf_fonts) {
+ /* Initialize to the first font or -1 if undefined */
+ ptsize = vf_fonts[vf_font].ptsize;
+ if (vf_fonts[vf_font].num_dev_fonts > 0)
+ default_font = ((vf_fonts[vf_font].dev_fonts)[0]).dev_id;
+ dvi_vf_init (default_font);
+ if (ch >= vf_fonts[vf_font].num_chars ||
+ !(start = (vf_fonts[vf_font].ch_pkt)[ch])) {
+ if (tfm_is_jfm(vf_fonts[vf_font].dev_fonts[0].tfm_id) &&
+ ch < 0x1000000 && dpx_conf.compat_mode != dpx_mode_xdv_mode) {
+ /* fallback multibyte character for (u)pTeX */
+ if (dpx_conf.verbose_level == 1)
+ if (vf_fonts[vf_font].message_flag == 0) {
+ WARN ("Fallback multibyte character in virtual font: VF:%s to TFM:%s",
+ vf_fonts[vf_font].tex_name, vf_fonts[vf_font].dev_fonts[0].name);
+ vf_fonts[vf_font].message_flag = 1;
+ }
+ if (dpx_conf.verbose_level > 1)
+ WARN ("Fallback multibyte character in virtual font: VF:%s char=0x%06x(%d) to TFM:%s",
+ vf_fonts[vf_font].tex_name, ch, ch, vf_fonts[vf_font].dev_fonts[0].name);
+ dvi_set (ch);
+ dvi_vf_finish();
+ return;
+ }
+ fprintf (stderr, "\nchar=0x%x(%d)\n", ch, ch);
+ fprintf (stderr, "Tried to set a nonexistent character in a virtual font");
+ start = end = NULL;
+ } else {
+ end = start + (vf_fonts[vf_font].pkt_len)[ch];
+ }
+ while (start && start < end) {
+ opcode = *(start++);
+#ifdef DEBUG
+ fprintf (stderr, "VF opcode: %d", opcode);
+ if (isprint (opcode)) fprintf (stderr, " (\'%c\')\n", opcode);
+ else fprintf (stderr, "\n");
+#endif
+ switch (opcode)
+ {
+ case SET1: case SET2: case SET3:
+ dvi_set (get_pkt_unsigned_num (&start, end, opcode-SET1));
+ break;
+ case SET4:
+ ERROR ("Multibyte (>24 bits) character in VF packet.\nI can't handle this!");
+ break;
+ case SET_RULE:
+ vf_setrule(&start, end, ptsize);
+ break;
+ case PUT1: case PUT2: case PUT3:
+ dvi_put (get_pkt_unsigned_num (&start, end, opcode-PUT1));
+ break;
+ case PUT4:
+ ERROR ("Multibyte (>24 bits) character in VF packet.\nI can't handle this!");
+ break;
+ case PUT_RULE:
+ vf_putrule(&start, end, ptsize);
+ break;
+ case NOP:
+ break;
+ case PUSH:
+ dvi_push();
+ break;
+ case POP:
+ dvi_pop();
+ break;
+ case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4:
+ dvi_right (sqxfw (ptsize, get_pkt_signed_num (&start, end, opcode-RIGHT1)));
+ break;
+ case W0:
+ dvi_w0();
+ break;
+ case W1: case W2: case W3: case W4:
+ dvi_w (sqxfw (ptsize, get_pkt_signed_num (&start, end, opcode-W1)));
+ break;
+ case X0:
+ dvi_x0();
+ break;
+ case X1: case X2: case X3: case X4:
+ dvi_x (sqxfw (ptsize, get_pkt_signed_num (&start, end, opcode-X1)));
+ break;
+ case DOWN1: case DOWN2: case DOWN3: case DOWN4:
+ dvi_down (sqxfw (ptsize, get_pkt_signed_num (&start, end, opcode-DOWN1)));
+ break;
+ case Y0:
+ dvi_y0();
+ break;
+ case Y1: case Y2: case Y3: case Y4:
+ dvi_y (sqxfw (ptsize, get_pkt_signed_num (&start, end, opcode-Y1)));
+ break;
+ case Z0:
+ dvi_z0();
+ break;
+ case Z1: case Z2: case Z3: case Z4:
+ dvi_z (sqxfw (ptsize, get_pkt_signed_num (&start, end, opcode-Z1)));
+ break;
+ case FNT1: case FNT2: case FNT3: case FNT4:
+ vf_fnt (get_pkt_signed_num (&start, end, opcode-FNT1), vf_font);
+ break;
+ case XXX1: case XXX2: case XXX3: case XXX4:
+ {
+ int32_t len = get_pkt_unsigned_num (&start, end, opcode-XXX1);
+ if (len < 0)
+ WARN("VF: Special with %d bytes???", len);
+ else
+ vf_xxx (len, &start, end);
+ }
+ break;
+ case PTEXDIR:
+ dvi_dirchg (unsigned_byte (&start, end));
+ break;
+ default:
+ if (opcode <= SET_CHAR_127) {
+ dvi_set (opcode);
+ } else if (opcode >= FNT_NUM_0 && opcode <= FNT_NUM_63) {
+ vf_fnt (opcode - FNT_NUM_0, vf_font);
+ } else {
+ fprintf (stderr, "Unexpected opcode: %d\n", opcode);
+ ERROR ("Unexpected opcode in vf file\n");
+ }
+ }
+ }
+ dvi_vf_finish();
+ } else {
+ fprintf (stderr, "vf_set_char: font: %d", vf_font);
+ ERROR ("Font not loaded\n");
+ }
+ return;
+}
+
+
+void vf_close_all_fonts(void)
+{
+ int i;
+ int j;
+ struct font_def *one_font;
+ for (i=0; i<num_vf_fonts; i++) {
+ /* Release the packet for each character */
+ if (vf_fonts[i].ch_pkt) {
+ for (j=0; j<vf_fonts[i].num_chars; j++) {
+ if ((vf_fonts[i].ch_pkt)[j] != NULL)
+ RELEASE ((vf_fonts[i].ch_pkt)[j]);
+ }
+ RELEASE (vf_fonts[i].ch_pkt);
+ }
+ if (vf_fonts[i].pkt_len)
+ RELEASE (vf_fonts[i].pkt_len);
+ if (vf_fonts[i].tex_name)
+ RELEASE (vf_fonts[i].tex_name);
+ /* Release each font record */
+ for (j=0; j<vf_fonts[i].num_dev_fonts; j++) {
+ one_font = &(vf_fonts[i].dev_fonts)[j];
+ RELEASE (one_font -> directory);
+ RELEASE (one_font -> name);
+ }
+ if (vf_fonts[i].dev_fonts != NULL)
+ RELEASE (vf_fonts[i].dev_fonts);
+ }
+ if (vf_fonts != NULL)
+ RELEASE (vf_fonts);
+ return;
+}
+#if defined(LIBDPX)
+#include "vf_ng.c"
+#endif /* LIBDPX */
diff --git a/Build/source/texk/dvipdfm-x/vf.h b/Build/source/texk/dvipdfm-x/vf.h
new file mode 100644
index 00000000000..e402b5f2903
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/vf.h
@@ -0,0 +1,32 @@
+/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+#ifndef _VF_H_
+#define _VF_H_
+
+#include "pdfdev.h"
+
+extern int vf_locate_font (const char *tex_name, spt_t ptsize);
+extern void vf_set_char (int32_t ch, int vf_font);
+extern void vf_close_all_fonts(void);
+
+#endif /* _VF_H_ */
diff --git a/Build/source/texk/dvipdfm-x/xbb.c b/Build/source/texk/dvipdfm-x/xbb.c
new file mode 100644
index 00000000000..00b30501680
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xbb.c
@@ -0,0 +1,422 @@
+/* This is extractbb, a bounding box extraction program.
+ Copyright (C) 2008-2021 by Jin-Hwan Cho and Matthias Franz
+ and the dvipdfmx project team.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+
+#include "dpxconf.h"
+#include "dpxutil.h"
+
+#include "numbers.h"
+#include "system.h"
+#include "mem.h"
+#include "error.h"
+#include "mfileio.h"
+#include "pdfobj.h"
+#include "pdfdoc.h"
+#include "pdfparse.h"
+#include "pdfdraw.h"
+
+#include "bmpimage.h"
+#include "jpegimage.h"
+#include "jp2image.h"
+#include "pngimage.h"
+
+#include "dvipdfmx.h"
+#include "pdflimits.h"
+
+static enum pdf_page_boundary PageBox = pdf_page_boundary__auto;
+
+static int Include_Page = 1;
+
+static void show_version(void)
+{
+ fprintf (stdout, "\nThis is %s Version " VERSION "\n", my_name);
+ fprintf (stdout, "\nCopyright (C) 2008-2021 by Jin-Hwan Cho and Matthias Franz\n");
+ fprintf (stdout, "\nThis is free software; you can redistribute it and/or modify\n");
+ fprintf (stdout, "it under the terms of the GNU General Public License as published by\n");
+ fprintf (stdout, "the Free Software Foundation; either version 2 of the License, or\n");
+ fprintf (stdout, "(at your option) any later version.\n");
+}
+
+static void show_usage(void)
+{
+ printf ("\nUsage: %s [-B pagebox] [-p page] [-q|-v] [-O] [-m|-x] FILE...\n", my_name);
+ printf (" %s --help|--version\n", my_name);
+ printf ("Extract bounding box from PDF, PNG, JPEG, JP2, or BMP file; default output below.\n");
+ printf ("\nOptions:\n");
+ printf (" -B pagebox\tSpecify a PDF pagebox for bounding box\n");
+ printf (" \tpagebox=cropbox, mediabox, artbox, trimbox, bleedbox\n");
+ printf (" -h | --help\tShow this help message and exit\n");
+ printf (" --version\tOutput version information and exit\n");
+ printf (" -p page\tSpecify a PDF page to extract bounding box\n");
+ printf (" -q\t\tBe quiet\n");
+ printf (" -v\t\tBe verbose\n");
+ printf (" -O\t\tWrite output to stdout\n");
+ printf (" -m\t\tOutput .bb file used in DVIPDFM%s\n", my_name[1] == 'b' ? " (default)" : "");
+ printf (" -x\t\tOutput .xbb file used in DVIPDFMx%s\n", my_name[1] == 'b' ? "" : " (default)");
+}
+
+static void usage(void)
+{
+ fprintf(stdout, "\nTry \"%s --help\" for more information.\n", my_name);
+ exit(1);
+}
+
+static void do_time(FILE *file)
+{
+ time_t current_time;
+ struct tm *bd_time;
+
+ current_time = dpx_util_get_unique_time_if_given();
+ if (current_time == INVALID_EPOCH_VALUE) {
+ time(&current_time);
+ bd_time = localtime(&current_time);
+ } else {
+ bd_time = gmtime(&current_time);
+ }
+ fprintf(file, "%%%%CreationDate: %s\n", asctime(bd_time));
+}
+
+const char *extensions[] = {
+ ".ai", ".AI", ".bmp", ".BMP", ".jpeg", ".JPEG", ".jpg", ".JPG",
+ ".jp2", ".JP2", ".jpf", ".JPF", ".pdf", ".PDF", ".png", ".PNG"
+};
+
+static int xbb_to_file = 1;
+
+static char *make_xbb_filename(const char *name)
+{
+ char *result;
+ int i;
+
+ for (i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++) {
+ if (strlen(extensions[i]) < strlen(name) &&
+ strncmp(name+strlen(name)-strlen(extensions[i]), extensions[i], strlen(extensions[i])) == 0)
+ break;
+ }
+ if (i == sizeof(extensions) / sizeof(extensions[0])) {
+ WARN("%s: Filename does not end in a recognizable extension.\n", name);
+ result = NEW(strlen(name)+strlen(".xbb")+1, char);
+ strcpy(result, name);
+ } else { /* Remove extension */
+ size_t len;
+ len = strlen(name) - strlen(extensions[i]);
+ result = NEW(len+strlen(".xbb")+1, char);
+ strncpy(result, name, len);
+ result[len] = 0;
+ }
+ strcat(result, ((dpx_conf.compat_mode == dpx_mode_compat_mode) ? ".bb" : ".xbb"));
+ return result;
+}
+
+static void write_xbb(char *fname,
+ double bbllx_f, double bblly_f,
+ double bburx_f, double bbury_f,
+ int pdf_version, int pagecount)
+{
+ char *outname = NULL;
+ FILE *fp = NULL;
+
+ int bbllx = ROUND(bbllx_f, 1.0), bblly = ROUND(bblly_f, 1.0);
+ int bburx = ROUND(bburx_f, 1.0), bbury = ROUND(bbury_f, 1.0);
+
+ if (xbb_to_file) {
+ outname = make_xbb_filename(fname);
+ if (!kpse_out_name_ok(outname) || !(fp = MFOPEN(outname, FOPEN_W_MODE))) {
+ ERROR("Unable to open output file: %s\n", outname);
+ }
+ } else {
+ fp = stdout;
+#ifdef WIN32
+ setmode(fileno(fp), _O_BINARY);
+#endif
+ }
+
+ if (dpx_conf.verbose_level > 0) {
+ MESG("Writing to %s: ", xbb_to_file ? outname : "stdout");
+ MESG("Bounding box: %d %d %d %d\n", bbllx, bblly, bburx, bbury);
+ }
+
+ fprintf(fp, "%%%%Title: %s\n", fname);
+ fprintf(fp, "%%%%Creator: extractbb %s\n", VERSION);
+ fprintf(fp, "%%%%BoundingBox: %d %d %d %d\n", bbllx, bblly, bburx, bbury);
+
+ if (dpx_conf.compat_mode != dpx_mode_compat_mode) {
+ /* Note:
+ * According to Adobe Technical Note #5644, the arguments to
+ * "%%HiResBoundingBox:" must be of type real. And according
+ * to the PostScript Language Reference, a real number must
+ * be written with a decimal point (or an exponent). Hence
+ * it seems illegal to replace "0.0" by "0".
+ */
+ fprintf(fp, "%%%%HiResBoundingBox: %f %f %f %f\n",
+ bbllx_f, bblly_f, bburx_f, bbury_f);
+ if (pdf_version >= 0) {
+ fprintf(fp, "%%%%PDFVersion: %d.%d\n", pdf_version/10, pdf_version%10);
+ fprintf(fp, "%%%%Pages: %d\n", pagecount);
+ }
+ }
+
+ do_time(fp);
+
+ if (xbb_to_file) {
+ RELEASE(outname);
+ MFCLOSE(fp);
+ }
+}
+
+static void do_bmp (FILE *fp, char *filename)
+{
+ int width, height;
+ double xdensity, ydensity;
+
+ if (bmp_get_bbox(fp, &width, &height, &xdensity, &ydensity) < 0) {
+ WARN("%s does not look like a BMP file...\n", filename);
+ return;
+ }
+
+ write_xbb(filename, 0, 0, xdensity*width, ydensity*height, -1, -1);
+ return;
+}
+
+static void do_jpeg (FILE *fp, char *filename)
+{
+ int width, height;
+ double xdensity, ydensity;
+
+ if (jpeg_get_bbox(fp, &width, &height, &xdensity, &ydensity) < 0) {
+ WARN("%s does not look like a JPEG file...\n", filename);
+ return;
+ }
+
+ write_xbb(filename, 0, 0, xdensity*width, ydensity*height, -1, -1);
+ return;
+}
+
+static void do_jp2 (FILE *fp, char *filename)
+{
+ int width, height;
+ double xdensity, ydensity;
+
+ if (jp2_get_bbox(fp, &width, &height, &xdensity, &ydensity) < 0) {
+ WARN("%s does not look like a JP2/JPX file...\n", filename);
+ return;
+ }
+
+ write_xbb(filename, 0, 0, xdensity*width, ydensity*height, -1, -1);
+ return;
+}
+
+#ifdef HAVE_LIBPNG
+static void do_png (FILE *fp, char *filename)
+{
+ uint32_t width, height;
+ double xdensity, ydensity;
+
+ if (png_get_bbox(fp, &width, &height, &xdensity, &ydensity) < 0) {
+ WARN("%s does not look like a PNG file...\n", filename);
+ return;
+ }
+
+ write_xbb(filename, 0, 0, xdensity*width, ydensity*height, -1, -1);
+ return;
+}
+#endif /* HAVE_LIBPNG */
+
+static void do_pdf (FILE *fp, char *filename)
+{
+ pdf_obj *page;
+ pdf_file *pf;
+ int page_no = Include_Page;
+ int count;
+ pdf_rect bbox;
+ pdf_tmatrix matrix;
+ pdf_coord p1, p2, p3, p4;
+
+ pf = pdf_open(filename, fp);
+ if (!pf) {
+ WARN("%s does not look like a PDF file...\n", filename);
+ return;
+ }
+ count = pdf_doc_get_page_count(pf);
+ page = pdf_doc_get_page(pf, page_no, PageBox, &bbox, &matrix, NULL);
+
+ pdf_close(pf);
+
+ if (!page)
+ return;
+
+ pdf_release_obj(page);
+
+ /* Image's attribute "bbox" here is affected by /Rotate entry of included
+ * PDF page.
+ */
+ p1.x = bbox.llx; p1.y = bbox.lly;
+ pdf_dev_transform(&p1, &matrix);
+ p2.x = bbox.urx; p2.y = bbox.lly;
+ pdf_dev_transform(&p2, &matrix);
+ p3.x = bbox.urx; p3.y = bbox.ury;
+ pdf_dev_transform(&p3, &matrix);
+ p4.x = bbox.llx; p4.y = bbox.ury;
+ pdf_dev_transform(&p4, &matrix);
+
+ bbox.llx = min4(p1.x, p2.x, p3.x, p4.x);
+ bbox.lly = min4(p1.y, p2.y, p3.y, p4.y);
+ bbox.urx = max4(p1.x, p2.x, p3.x, p4.x);
+ bbox.ury = max4(p1.y, p2.y, p3.y, p4.y);
+
+ write_xbb(filename, bbox.llx, bbox.lly, bbox.urx, bbox.ury,
+ pdf_file_get_version(pf), count);
+}
+
+static const char *optstrig = ":hB:p:qvObmx";
+
+static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 130},
+ {0, 0, 0, 0}
+};
+
+int extractbb (int argc, char *argv[])
+{
+ int c;
+
+ pdf_files_init();
+
+ dpx_conf.is_xbb = 1;
+
+ opterr = 0;
+
+ while ((c = getopt_long(argc, argv, optstrig, long_options, NULL)) != -1) {
+ switch(c) {
+ case 'h':
+ show_usage();
+ exit(0);
+
+ case 130:
+ show_version();
+ exit(0);
+
+ case 'B':
+ if (strcasecmp (optarg, "cropbox") == 0) PageBox = pdf_page_boundary_cropbox;
+ else if (strcasecmp (optarg, "mediabox") == 0) PageBox = pdf_page_boundary_mediabox;
+ else if (strcasecmp (optarg, "artbox") == 0) PageBox = pdf_page_boundary_artbox;
+ else if (strcasecmp (optarg, "trimbox") == 0) PageBox = pdf_page_boundary_trimbox;
+ else if (strcasecmp (optarg, "bleedbox") == 0) PageBox = pdf_page_boundary_bleedbox;
+ else {
+ fprintf(stderr, "%s: Invalid argument \"-B %s\"", my_name, optarg);
+ usage();
+ }
+ break;
+
+ case 'p':
+ Include_Page = atol(optarg);
+ if (Include_Page == 0)
+ Include_Page = 1;
+ break;
+
+ case 'q':
+ dpx_conf.verbose_level = 0;
+ break;
+ case 'v':
+ dpx_conf.verbose_level++;
+ break;
+
+ case 'O':
+ xbb_to_file = 0;
+ case 'b': /* Ignored for backward compatibility */
+ break;
+
+ case 'm':
+ dpx_conf.compat_mode = dpx_mode_compat_mode;
+ break;
+ case 'x':
+ dpx_conf.compat_mode = dpx_mode_normal_mode;
+ break;
+
+ default:
+ fprintf(stderr, "%s: %s \"-%c\"", my_name,
+ c == ':' ? "Missing argument for" : "Unknown option",
+ optopt);
+ usage();
+ }
+ }
+
+ if (optind >= argc) {
+ fprintf (stderr, "%s: Missing filename argument", my_name);
+ usage();
+ }
+
+ for (; optind < argc; optind++) {
+ FILE *infile = NULL;
+ char *kpse_file_name = NULL;
+
+ if (kpse_in_name_ok(argv[optind])) {
+ infile = MFOPEN(argv[optind], FOPEN_RBIN_MODE);
+ if (infile) {
+ kpse_file_name = xstrdup(argv[optind]);
+ } else {
+ kpse_file_name = kpse_find_pict(argv[optind]);
+ if (kpse_file_name && kpse_in_name_ok(kpse_file_name))
+ infile = MFOPEN(kpse_file_name, FOPEN_RBIN_MODE);
+ }
+ }
+ if (infile == NULL) {
+ WARN("Can't find file (%s), or it is forbidden to read ...skipping\n", argv[optind]);
+ goto cont;
+ }
+ if (check_for_bmp(infile)) {
+ do_bmp(infile, kpse_file_name);
+ goto cont;
+ }
+ if (check_for_jpeg(infile)) {
+ do_jpeg(infile, kpse_file_name);
+ goto cont;
+ }
+ if (check_for_jp2(infile)) {
+ do_jp2(infile, kpse_file_name);
+ goto cont;
+ }
+ if (check_for_pdf(infile)) {
+ do_pdf(infile, kpse_file_name);
+ goto cont;
+ }
+#ifdef HAVE_LIBPNG
+ if (check_for_png(infile)) {
+ do_png(infile, kpse_file_name);
+ goto cont;
+ }
+#endif /* HAVE_LIBPNG */
+ WARN("Can't handle file type for file named %s\n", argv[optind]);
+ cont:
+ if (kpse_file_name)
+ RELEASE(kpse_file_name);
+ if (infile)
+ MFCLOSE(infile);
+ }
+
+ pdf_files_close();
+
+ return 0;
+}
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-ann.test b/Build/source/texk/dvipdfm-x/xdvipdfm-ann.test
new file mode 100755
index 00000000000..c80a06848a2
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-ann.test
@@ -0,0 +1,26 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2013 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS
+
+failed=
+
+echo "*** xdvipdfmx -v -z0 -o annot2.pdf annot" && echo \
+ && ./xdvipdfmx -v -z0 -o annot2.pdf $srcdir/tests/annot \
+ && echo && echo "xdvipdfmx-ann tests OK" && echo \
+ || failed="$failed xdvipdfmx-ann"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-bad.test b/Build/source/texk/dvipdfm-x/xdvipdfm-bad.test
new file mode 100755
index 00000000000..c35230a65e9
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-bad.test
@@ -0,0 +1,38 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2015 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS
+
+failed=
+
+list="ids_2_6 ids_3_2 ids_a_b opc_fe ptx_2_2 ptx_6_6 rev_2_2 rev_2_3 void"
+
+for f in $list
+do
+
+echo "*** xdvipdfmx -v -z0 -o bad.pdf $f" && echo \
+ && ./xdvipdfmx -v -z0 -o bad.pdf $srcdir/tests/$f \
+ && failed="$failed xdvipdfmx-$f" \
+ || { echo && echo "xdvipdfmx-$f tests OK" && echo; }
+
+echo "*** xdvipdfmx -v -z0 -o bad.pdf <$f.dvi" && echo \
+ && ./xdvipdfmx -v -z0 -o bad.pdf <$srcdir/tests/$f.dvi \
+ && failed="$failed xdvipdfmx-$f (stdin)" \
+ || { echo && echo "xdvipdfmx-$f (stdin) tests OK" && echo; }
+
+done
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-bb.test b/Build/source/texk/dvipdfm-x/xdvipdfm-bb.test
new file mode 100755
index 00000000000..3b203eda04e
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-bb.test
@@ -0,0 +1,67 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017-2018 Karl Berry <tex-live@tug.org>
+# Copyright 2013, 2014 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+LC_ALL=C; export LC_ALL; LANGUAGE=C; export LANGUAGE
+TEXMFCNF=$srcdir/../kpathsea; export TEXMFCNF
+DVIPDFMXINPUTS=$srcdir/tests:$srcdir/data; export DVIPDFMXINPUTS
+
+testsrc=$srcdir/tests
+
+failed=
+
+rm -f pic*.*
+
+# list of file types
+ext='bmp jp2 jpeg pdf png'
+
+for e in $ext; do
+ cp $testsrc/image.$e pic$e.$e
+done
+
+echo "*** xdvipdfmx --ebb --version" \
+ && ./xdvipdfmx --ebb --version \
+ && echo && echo "ebb-version tests OK" && echo \
+ || failed="$failed ebb-version"
+
+echo "*** xdvipdfmx --ebb --help" \
+ && ./xdvipdfmx --ebb --help \
+ && echo && echo "ebb-help tests OK" && echo \
+ || failed="$failed ebb-help"
+
+# get rid of both %%Creator: and %%CreationDate: lines.
+for e in $ext; do
+ echo "*** xdvipdfmx --ebb pic$e.$e" \
+ && ./xdvipdfmx --ebb pic$e.$e \
+ && sed '/^%%Creat/d' pic$e.bb >pic$e.bbx \
+ && diff $testsrc/pic$e.bb pic$e.bbx \
+ && echo && echo "ebb-$e tests OK" && echo \
+ || failed="$failed ebb-$e"
+done
+
+echo "*** xdvipdfmx --xbb --version" \
+ && ./xdvipdfmx --xbb --version \
+ && echo && echo "xbb-version tests OK" && echo \
+ || failed="$failed xbb-version"
+
+echo "*** xdvipdfmx --xbb --help" \
+ && ./xdvipdfmx --xbb --help \
+ && echo && echo "xbb-help tests OK" && echo \
+ || failed="$failed xbb-help"
+
+for e in $ext; do
+ echo "*** xdvipdfmx --xbb img$e.$e" \
+ && ./xdvipdfmx --xbb pic$e.$e \
+ && sed '/^%%Creat/d' pic$e.xbb >pic$e.xbbx \
+ && diff $testsrc/pic$e.xbb pic$e.xbbx \
+ && echo && echo "xbb-$e tests OK" && echo \
+ || failed="$failed xbb-$e"
+done
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-bkm.test b/Build/source/texk/dvipdfm-x/xdvipdfm-bkm.test
new file mode 100755
index 00000000000..5a5e62bdde6
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-bkm.test
@@ -0,0 +1,26 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2013 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS
+
+failed=
+
+echo "*** xdvipdfmx -v -z0 -o bookm2.pdf bookm" && echo \
+ && ./xdvipdfmx -v -z0 -o bookm2.pdf $srcdir/tests/bookm \
+ && echo && echo "xdvipdfmx-bkm tests OK" && echo \
+ || failed="$failed xdvipdfmx-bkm"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-psz.test b/Build/source/texk/dvipdfm-x/xdvipdfm-psz.test
new file mode 100755
index 00000000000..7825a41c4d8
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-psz.test
@@ -0,0 +1,31 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2013 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS
+
+failed=
+
+echo "*** xdvipdfmx -v -m 1.0 -o paper2.pdf <paper.dvi" && echo \
+ && ./xdvipdfmx -v -m 1.0 -o paper2.pdf <$srcdir/tests/paper.dvi \
+ && echo && echo "xdvipdfmx-paper tests OK" && echo \
+ || failed="$failed xdvipdfmx-paper"
+
+echo "*** xdvipdfmx -v -m 1.4 -o - paper >paper2m.pdf" && echo \
+ && ./xdvipdfmx -v -m 1.4 -o - $srcdir/tests/paper >paper2m.pdf \
+ && echo && echo "xdvipdfmx-paper-mag tests OK" && echo \
+ || failed="$failed xdvipdfmx-paper-mag"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-ptx.test b/Build/source/texk/dvipdfm-x/xdvipdfm-ptx.test
new file mode 100755
index 00000000000..319139bb4a2
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-ptx.test
@@ -0,0 +1,31 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2015 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS
+
+failed=
+
+echo "*** xdvipdfmx -v -z0 -o ptex1.pdf ptex" && echo \
+ && ./xdvipdfmx -v -z0 -o ptex1.pdf $srcdir/tests/ptex \
+ && echo && echo "xdvipdfmx-ptex tests OK" && echo \
+ || failed="$failed xdvipdfmx-ptex"
+
+echo "*** xdvipdfmx -v -z0 <ptex.dvi >ptex2.pdf" && echo \
+ && ./xdvipdfmx -v -z0 <$srcdir/tests/ptex.dvi >ptex2.pdf \
+ && echo && echo "xdvipdfmx-ptex (stdin->stdout) tests OK" && echo \
+ || failed="$failed xdvipdfmx-ptex (stdin->stdout)"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-res.test b/Build/source/texk/dvipdfm-x/xdvipdfm-res.test
new file mode 100755
index 00000000000..b249a8af068
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-res.test
@@ -0,0 +1,26 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2013 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS
+
+failed=
+
+echo "*** xdvipdfmx -v -z0 -o resrc2.pdf resrc" && echo \
+ && ./xdvipdfmx -v -z0 -o resrc2.pdf $srcdir/tests/resrc \
+ && echo && echo "xdvipdfmx-res tests OK" && echo \
+ || failed="$failed xdvipdfmx-res"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-rev.test b/Build/source/texk/dvipdfm-x/xdvipdfm-rev.test
new file mode 100755
index 00000000000..6aa3d7de55b
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-rev.test
@@ -0,0 +1,26 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2015 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+export TEXMFCNF TFMFONTS T1FONTS TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS
+
+failed=
+
+echo "*** xdvipdfmx -v -z0 -o reverse.pdf reverse" && echo \
+ && ./xdvipdfmx -v -z0 -o reverse.pdf $srcdir/tests/reverse \
+ && echo && echo "xdvipdfmx-reverse tests OK" && echo \
+ || failed="$failed xdvipdfmx-reverse"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfm-ttc.test b/Build/source/texk/dvipdfm-x/xdvipdfm-ttc.test
new file mode 100755
index 00000000000..a106d17c205
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfm-ttc.test
@@ -0,0 +1,26 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2015 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TFMFONTS="$srcdir/tests;$srcdir/data"
+T1FONTS="$srcdir/tests;$srcdir/data"
+TTFONTS="$srcdir/tests;$srcdir/data"
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+export TEXMFCNF TFMFONTS T1FONTS TTFONTS TEXFONTMAPS DVIPDFMXINPUTS
+
+failed=
+
+echo "*** xdvipdfmx -v -z0 -o ttc2.pdf ttc" && echo \
+ && ./xdvipdfmx -v -z0 -o ttc2.pdf $srcdir/tests/ttc \
+ && echo && echo "xdvipdfmx-ttc tests OK" && echo \
+ || failed="$failed xdvipdfmx-ttc"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1
+
diff --git a/Build/source/texk/dvipdfm-x/xdvipdfmx.test b/Build/source/texk/dvipdfm-x/xdvipdfmx.test
new file mode 100755
index 00000000000..4d6e7cd92ba
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/xdvipdfmx.test
@@ -0,0 +1,45 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2013, 2014 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea
+TEXFONTMAPS="$srcdir/tests;$srcdir/data"
+DVIPDFMXINPUTS="$srcdir/tests;$srcdir/data"
+TEXPICTS=$srcdir/tests
+TEXFONTS=$srcdir/tests
+PKFONTS=$srcdir/tests
+export TEXMFCNF TEXFONTMAPS DVIPDFMXINPUTS TEXPICTS TEXFONTS PKFONTS
+
+failed=
+
+echo "*** xdvipdfmx --version" \
+ && ./xdvipdfmx --version \
+ && echo && echo "xdvipdfmx-version tests OK" && echo \
+ || failed="$failed xdvipdfmx-version"
+
+echo "*** xdvipdfmx --help" \
+ && ./xdvipdfmx --help \
+ && echo && echo "xdvipdfmx-help tests OK" && echo \
+ || failed="$failed xdvipdfmx-help"
+
+echo "*** xdvipdfmx --showpaper" \
+ && ./xdvipdfmx --showpaper \
+ && echo && echo "xdvipdfmx-showpaper tests OK" && echo \
+ || failed="$failed xdvipdfmx-showpaper"
+
+echo "*** xdvipdfmx -v -o image2.pdf image" && echo \
+ && ./xdvipdfmx -v -o image2.pdf $srcdir/tests/image \
+ && echo && echo "xdvipdfmx-image tests OK" && echo \
+ || failed="$failed xdvipdfmx-image"
+
+echo "*** xdvipdfmx -v -o xbmc2.pdf xbmc" && echo \
+ && ./xdvipdfmx -v -o xbmc2.pdf $srcdir/tests/xbmc \
+ && echo && echo "xdvipdfmx-xbmc tests OK" && echo \
+ || failed="$failed xdvipdfmx-xbmc"
+
+test -z "$failed" && exit 0
+echo
+echo "failed tests:$failed"
+exit 1