From be2f62b1c99597ad47dde539964c3a4a3b5cf773 Mon Sep 17 00:00:00 2001 From: Peter Breitenlohner Date: Tue, 6 Aug 2013 12:39:49 +0000 Subject: Recover texk/dvipdfm-x@31034 (essentially dvipdfmx and xdvipdfmx from branch-2013) as texk/dvipdf-x. Not built by default, only used to analyze various problems git-svn-id: svn://tug.org/texlive/trunk@31364 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/Makefile.in | 2 + Build/source/configure | 58 +- Build/source/libs/Makefile.in | 2 + Build/source/libs/configure | 58 +- Build/source/m4/ChangeLog | 6 + Build/source/m4/kpse-pkgs.m4 | 1 + Build/source/texk/Makefile.in | 2 + Build/source/texk/configure | 69 +- Build/source/texk/dvipdf-x/AUTHORS | 12 + Build/source/texk/dvipdf-x/COPYING | 340 + Build/source/texk/dvipdf-x/ChangeLog | 3724 +++++ Build/source/texk/dvipdf-x/INSTALL | 182 + Build/source/texk/dvipdf-x/Makefile.am | 329 + Build/source/texk/dvipdf-x/Makefile.in | 4084 +++++ Build/source/texk/dvipdf-x/README | 510 + Build/source/texk/dvipdf-x/ac/dvipdf-x.ac | 13 + Build/source/texk/dvipdf-x/ac/withenable.ac | 8 + Build/source/texk/dvipdf-x/aclocal.m4 | 1236 ++ Build/source/texk/dvipdf-x/agl.c | 826 + Build/source/texk/dvipdf-x/agl.h | 68 + Build/source/texk/dvipdf-x/bmpimage.h | 39 + Build/source/texk/dvipdf-x/cff_dict.h | 47 + Build/source/texk/dvipdf-x/cff_limits.h | 46 + Build/source/texk/dvipdf-x/cff_stdstr.h | 109 + Build/source/texk/dvipdf-x/cff_types.h | 142 + Build/source/texk/dvipdf-x/cid.c | 835 + Build/source/texk/dvipdf-x/cid.h | 96 + Build/source/texk/dvipdf-x/cid_basefont.h | 489 + Build/source/texk/dvipdf-x/cid_p.h | 74 + Build/source/texk/dvipdf-x/cidtype0.h | 47 + Build/source/texk/dvipdf-x/cidtype2.h | 37 + Build/source/texk/dvipdf-x/cmap.c | 997 ++ Build/source/texk/dvipdf-x/cmap.h | 118 + Build/source/texk/dvipdf-x/cmap_p.h | 104 + Build/source/texk/dvipdf-x/cmap_read.c | 608 + Build/source/texk/dvipdf-x/cmap_read.h | 34 + Build/source/texk/dvipdf-x/cmap_write.c | 601 + Build/source/texk/dvipdf-x/cmap_write.h | 35 + Build/source/texk/dvipdf-x/config.h.in | 272 + Build/source/texk/dvipdf-x/configure | 18462 +++++++++++++++++++++ Build/source/texk/dvipdf-x/configure.ac | 94 + Build/source/texk/dvipdf-x/cs_type2.c | 807 + Build/source/texk/dvipdf-x/cs_type2.h | 45 + Build/source/texk/dvipdf-x/data/EUC-UCS2 | 6800 ++++++++ Build/source/texk/dvipdf-x/data/Makefile.am | 11 + Build/source/texk/dvipdf-x/data/Makefile.in | 586 + Build/source/texk/dvipdf-x/data/cid-x.map | 152 + Build/source/texk/dvipdf-x/data/dvipdfmx.cfg | 222 + Build/source/texk/dvipdf-x/data/glyphlist.txt | 4322 +++++ Build/source/texk/dvipdf-x/data/pdfglyphlist.txt | 385 + Build/source/texk/dvipdf-x/dpxconf.c | 112 + Build/source/texk/dvipdf-x/dpxconf.h | 62 + Build/source/texk/dvipdf-x/dpxcrypt.c | 375 + Build/source/texk/dvipdf-x/dpxcrypt.h | 49 + Build/source/texk/dvipdf-x/dvicodes.h | 131 + Build/source/texk/dvipdf-x/dvipdfm-ann.test | 25 + Build/source/texk/dvipdf-x/dvipdfmx.h | 28 + Build/source/texk/dvipdf-x/dvipdfmx.test | 33 + Build/source/texk/dvipdf-x/dvipdft | 105 + Build/source/texk/dvipdf-x/man/Makefile.am | 12 + Build/source/texk/dvipdf-x/man/Makefile.in | 557 + Build/source/texk/dvipdf-x/man/dvipdfm.1 | 358 + Build/source/texk/dvipdf-x/man/dvipdft.1 | 40 + Build/source/texk/dvipdf-x/man/extractbb.1 | 99 + Build/source/texk/dvipdf-x/mem.c | 55 + Build/source/texk/dvipdf-x/mem.h | 37 + Build/source/texk/dvipdf-x/mfileio.c | 127 + Build/source/texk/dvipdf-x/mfileio.h | 61 + Build/source/texk/dvipdf-x/mpost.h | 47 + Build/source/texk/dvipdf-x/numbers.c | 228 + Build/source/texk/dvipdf-x/numbers.h | 86 + Build/source/texk/dvipdf-x/otl_conf.c | 641 + Build/source/texk/dvipdf-x/otl_conf.h | 39 + Build/source/texk/dvipdf-x/otl_opt.c | 343 + Build/source/texk/dvipdf-x/otl_opt.h | 37 + Build/source/texk/dvipdf-x/pdfencoding.c | 1080 ++ Build/source/texk/dvipdf-x/pdfencoding.h | 80 + Build/source/texk/dvipdf-x/pdfencrypt.h | 39 + Build/source/texk/dvipdf-x/pdffont.c | 1012 ++ Build/source/texk/dvipdf-x/pdffont.h | 110 + Build/source/texk/dvipdf-x/pdflimits.h | 43 + Build/source/texk/dvipdf-x/pdfparse.h | 55 + Build/source/texk/dvipdf-x/pdfresource.c | 377 + Build/source/texk/dvipdf-x/pdfresource.h | 47 + Build/source/texk/dvipdf-x/pkfont.c | 794 + Build/source/texk/dvipdf-x/pkfont.h | 35 + Build/source/texk/dvipdf-x/pst.c | 182 + Build/source/texk/dvipdf-x/pst.h | 74 + Build/source/texk/dvipdf-x/pst_obj.c | 901 + Build/source/texk/dvipdf-x/pst_obj.h | 41 + Build/source/texk/dvipdf-x/sfnt.h | 161 + Build/source/texk/dvipdf-x/spc_color.h | 32 + Build/source/texk/dvipdf-x/spc_dvips.h | 41 + Build/source/texk/dvipdf-x/spc_html.h | 39 + Build/source/texk/dvipdf-x/spc_misc.c | 210 + Build/source/texk/dvipdf-x/spc_misc.h | 34 + Build/source/texk/dvipdf-x/spc_pdfm.h | 37 + Build/source/texk/dvipdf-x/spc_tpic.h | 41 + Build/source/texk/dvipdf-x/spc_xtx.c | 457 + Build/source/texk/dvipdf-x/spc_xtx.h | 40 + Build/source/texk/dvipdf-x/specials.h | 78 + Build/source/texk/dvipdf-x/src/bmpimage.c | 460 + Build/source/texk/dvipdf-x/src/cff.c | 1470 ++ Build/source/texk/dvipdf-x/src/cff.h | 146 + Build/source/texk/dvipdf-x/src/cff_dict.c | 713 + Build/source/texk/dvipdf-x/src/cidtype0.c | 2047 +++ Build/source/texk/dvipdf-x/src/cidtype2.c | 1105 ++ Build/source/texk/dvipdf-x/src/dpxfile.c | 1153 ++ Build/source/texk/dvipdf-x/src/dpxfile.h | 65 + Build/source/texk/dvipdf-x/src/dpxutil.c | 639 + Build/source/texk/dvipdf-x/src/dpxutil.h | 113 + Build/source/texk/dvipdf-x/src/dvi.c | 1967 +++ Build/source/texk/dvipdf-x/src/dvi.h | 96 + Build/source/texk/dvipdf-x/src/dvipdfmx.c | 1026 ++ Build/source/texk/dvipdf-x/src/epdf.c | 208 + Build/source/texk/dvipdf-x/src/epdf.h | 34 + Build/source/texk/dvipdf-x/src/error.c | 92 + Build/source/texk/dvipdf-x/src/error.h | 46 + Build/source/texk/dvipdf-x/src/fontmap.c | 1572 ++ Build/source/texk/dvipdf-x/src/fontmap.h | 111 + Build/source/texk/dvipdf-x/src/jpegimage.c | 792 + Build/source/texk/dvipdf-x/src/jpegimage.h | 38 + Build/source/texk/dvipdf-x/src/mpost.c | 1674 ++ Build/source/texk/dvipdf-x/src/pdfcolor.c | 1515 ++ Build/source/texk/dvipdf-x/src/pdfcolor.h | 105 + Build/source/texk/dvipdf-x/src/pdfdev.c | 1839 ++ Build/source/texk/dvipdf-x/src/pdfdev.h | 228 + Build/source/texk/dvipdf-x/src/pdfdoc.c | 2738 +++ Build/source/texk/dvipdf-x/src/pdfdoc.h | 143 + Build/source/texk/dvipdf-x/src/pdfdraw.c | 1811 ++ Build/source/texk/dvipdf-x/src/pdfdraw.h | 167 + Build/source/texk/dvipdf-x/src/pdfencrypt.c | 537 + Build/source/texk/dvipdf-x/src/pdfnames.c | 425 + Build/source/texk/dvipdf-x/src/pdfnames.h | 52 + Build/source/texk/dvipdf-x/src/pdfobj.c | 3163 ++++ Build/source/texk/dvipdf-x/src/pdfobj.h | 210 + Build/source/texk/dvipdf-x/src/pdfparse.c | 1044 ++ Build/source/texk/dvipdf-x/src/pdfximage.c | 940 ++ Build/source/texk/dvipdf-x/src/pdfximage.h | 94 + Build/source/texk/dvipdf-x/src/pngimage.c | 1064 ++ Build/source/texk/dvipdf-x/src/pngimage.h | 45 + Build/source/texk/dvipdf-x/src/sfnt.c | 529 + Build/source/texk/dvipdf-x/src/spc_color.c | 191 + Build/source/texk/dvipdf-x/src/spc_dvips.c | 434 + Build/source/texk/dvipdf-x/src/spc_html.c | 943 ++ Build/source/texk/dvipdf-x/src/spc_pdfm.c | 2021 +++ Build/source/texk/dvipdf-x/src/spc_tpic.c | 1114 ++ Build/source/texk/dvipdf-x/src/spc_util.c | 791 + Build/source/texk/dvipdf-x/src/spc_util.h | 43 + Build/source/texk/dvipdf-x/src/specials.c | 600 + Build/source/texk/dvipdf-x/src/tfm.c | 1216 ++ Build/source/texk/dvipdf-x/src/truetype.c | 1002 ++ Build/source/texk/dvipdf-x/src/tt_aux.c | 271 + Build/source/texk/dvipdf-x/src/tt_aux.h | 35 + Build/source/texk/dvipdf-x/src/tt_cmap.c | 1879 +++ Build/source/texk/dvipdf-x/src/tt_cmap.h | 79 + Build/source/texk/dvipdf-x/src/tt_glyf.c | 668 + Build/source/texk/dvipdf-x/src/tt_post.c | 271 + Build/source/texk/dvipdf-x/src/tt_table.c | 492 + Build/source/texk/dvipdf-x/src/type0.c | 677 + Build/source/texk/dvipdf-x/src/type0.h | 56 + Build/source/texk/dvipdf-x/src/type1.c | 806 + Build/source/texk/dvipdf-x/src/type1c.c | 740 + Build/source/texk/dvipdf-x/src/vf.c | 1058 ++ Build/source/texk/dvipdf-x/src/xbb.c | 343 + Build/source/texk/dvipdf-x/src/xbb.h | 31 + Build/source/texk/dvipdf-x/subfont.c | 657 + Build/source/texk/dvipdf-x/subfont.h | 35 + Build/source/texk/dvipdf-x/system.h | 53 + Build/source/texk/dvipdf-x/t1_char.c | 1590 ++ Build/source/texk/dvipdf-x/t1_char.h | 26 + Build/source/texk/dvipdf-x/t1_load.c | 1226 ++ Build/source/texk/dvipdf-x/t1_load.h | 11 + Build/source/texk/dvipdf-x/tests/cmr10.pfb | Bin 0 -> 26882 bytes Build/source/texk/dvipdf-x/tests/cmr10.tfm | Bin 0 -> 1296 bytes Build/source/texk/dvipdf-x/tests/dvipdfmx.cfg | 222 + Build/source/texk/dvipdf-x/tests/grahn.dvi | Bin 0 -> 328 bytes Build/source/texk/dvipdf-x/tests/grahn.tex | 8 + Build/source/texk/dvipdf-x/tests/image.dvi | Bin 0 -> 388 bytes Build/source/texk/dvipdf-x/tests/image.jpeg | Bin 0 -> 5778 bytes Build/source/texk/dvipdf-x/tests/image.pdf | Bin 0 -> 2690 bytes Build/source/texk/dvipdf-x/tests/image.png | Bin 0 -> 1436 bytes Build/source/texk/dvipdf-x/tests/image.tex | 23 + Build/source/texk/dvipdf-x/tests/psfonts.map | 1 + Build/source/texk/dvipdf-x/tfm.h | 60 + Build/source/texk/dvipdf-x/truetype.h | 33 + Build/source/texk/dvipdf-x/tt_glyf.h | 60 + Build/source/texk/dvipdf-x/tt_gsub.c | 1666 ++ Build/source/texk/dvipdf-x/tt_gsub.h | 67 + Build/source/texk/dvipdf-x/tt_post.h | 53 + Build/source/texk/dvipdf-x/tt_table.h | 199 + Build/source/texk/dvipdf-x/type1.h | 33 + Build/source/texk/dvipdf-x/type1c.h | 33 + Build/source/texk/dvipdf-x/unicode.c | 113 + Build/source/texk/dvipdf-x/unicode.h | 36 + Build/source/texk/dvipdf-x/vf.h | 35 + Build/source/texk/dvipdf-x/xdvipdfm-ann.test | 25 + Build/source/texk/dvipdf-x/xdvipdfmx.test | 37 + Build/source/texk/dvipdf-x/xsrc/bmpimage.c | 466 + Build/source/texk/dvipdf-x/xsrc/cff.c | 1484 ++ Build/source/texk/dvipdf-x/xsrc/cff.h | 156 + Build/source/texk/dvipdf-x/xsrc/cff_dict.c | 720 + Build/source/texk/dvipdf-x/xsrc/cidtype0.c | 2075 +++ Build/source/texk/dvipdf-x/xsrc/cidtype2.c | 1126 ++ Build/source/texk/dvipdf-x/xsrc/dpxfile.c | 1175 ++ Build/source/texk/dvipdf-x/xsrc/dpxfile.h | 70 + Build/source/texk/dvipdf-x/xsrc/dpxutil.c | 651 + Build/source/texk/dvipdf-x/xsrc/dpxutil.h | 105 + Build/source/texk/dvipdf-x/xsrc/dvi.c | 2737 +++ Build/source/texk/dvipdf-x/xsrc/dvi.h | 103 + Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c | 992 ++ Build/source/texk/dvipdf-x/xsrc/epdf.c | 906 + Build/source/texk/dvipdf-x/xsrc/epdf.h | 41 + Build/source/texk/dvipdf-x/xsrc/error.c | 92 + Build/source/texk/dvipdf-x/xsrc/error.h | 46 + Build/source/texk/dvipdf-x/xsrc/fontmap.c | 1513 ++ Build/source/texk/dvipdf-x/xsrc/fontmap.h | 109 + Build/source/texk/dvipdf-x/xsrc/jpegimage.c | 916 + Build/source/texk/dvipdf-x/xsrc/jpegimage.h | 36 + Build/source/texk/dvipdf-x/xsrc/mpost.c | 1671 ++ Build/source/texk/dvipdf-x/xsrc/pdfcolor.c | 1530 ++ Build/source/texk/dvipdf-x/xsrc/pdfcolor.h | 102 + Build/source/texk/dvipdf-x/xsrc/pdfdev.c | 2000 +++ Build/source/texk/dvipdf-x/xsrc/pdfdev.h | 231 + Build/source/texk/dvipdf-x/xsrc/pdfdoc.c | 2331 +++ Build/source/texk/dvipdf-x/xsrc/pdfdoc.h | 137 + Build/source/texk/dvipdf-x/xsrc/pdfdraw.c | 1842 ++ Build/source/texk/dvipdf-x/xsrc/pdfdraw.h | 172 + Build/source/texk/dvipdf-x/xsrc/pdfencrypt.c | 539 + Build/source/texk/dvipdf-x/xsrc/pdfnames.c | 488 + Build/source/texk/dvipdf-x/xsrc/pdfnames.h | 52 + Build/source/texk/dvipdf-x/xsrc/pdfobj.c | 3170 ++++ Build/source/texk/dvipdf-x/xsrc/pdfobj.h | 196 + Build/source/texk/dvipdf-x/xsrc/pdfparse.c | 1078 ++ Build/source/texk/dvipdf-x/xsrc/pdfximage.c | 924 ++ Build/source/texk/dvipdf-x/xsrc/pdfximage.h | 92 + Build/source/texk/dvipdf-x/xsrc/pngimage.c | 1013 ++ Build/source/texk/dvipdf-x/xsrc/pngimage.h | 43 + Build/source/texk/dvipdf-x/xsrc/sfnt.c | 652 + Build/source/texk/dvipdf-x/xsrc/spc_color.c | 192 + Build/source/texk/dvipdf-x/xsrc/spc_dvips.c | 1075 ++ Build/source/texk/dvipdf-x/xsrc/spc_html.c | 944 ++ Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c | 2115 +++ Build/source/texk/dvipdf-x/xsrc/spc_tpic.c | 1151 ++ Build/source/texk/dvipdf-x/xsrc/spc_util.c | 796 + Build/source/texk/dvipdf-x/xsrc/spc_util.h | 44 + Build/source/texk/dvipdf-x/xsrc/specials.c | 619 + Build/source/texk/dvipdf-x/xsrc/tfm.c | 1209 ++ Build/source/texk/dvipdf-x/xsrc/truetype.c | 1009 ++ Build/source/texk/dvipdf-x/xsrc/tt_aux.c | 294 + Build/source/texk/dvipdf-x/xsrc/tt_aux.h | 39 + Build/source/texk/dvipdf-x/xsrc/tt_cmap.c | 1940 +++ Build/source/texk/dvipdf-x/xsrc/tt_cmap.h | 80 + Build/source/texk/dvipdf-x/xsrc/tt_glyf.c | 671 + Build/source/texk/dvipdf-x/xsrc/tt_post.c | 276 + Build/source/texk/dvipdf-x/xsrc/tt_table.c | 505 + Build/source/texk/dvipdf-x/xsrc/type0.c | 687 + Build/source/texk/dvipdf-x/xsrc/type0.h | 58 + Build/source/texk/dvipdf-x/xsrc/type1.c | 805 + Build/source/texk/dvipdf-x/xsrc/type1c.c | 750 + Build/source/texk/dvipdf-x/xsrc/vf.c | 1042 ++ Build/source/texk/dvipdf-x/xsrc/xbb.c | 511 + Build/source/texk/dvipdf-x/xsrc/xbb.h | 31 + Build/source/texk/dvipdfm-x/ac/dvipdfm-x.ac | 2 +- Build/source/texk/dvipdfm-x/configure | 2 +- Build/source/utils/Makefile.in | 2 + Build/source/utils/configure | 58 +- 267 files changed, 162835 insertions(+), 6 deletions(-) create mode 100644 Build/source/texk/dvipdf-x/AUTHORS create mode 100644 Build/source/texk/dvipdf-x/COPYING create mode 100644 Build/source/texk/dvipdf-x/ChangeLog create mode 100644 Build/source/texk/dvipdf-x/INSTALL create mode 100644 Build/source/texk/dvipdf-x/Makefile.am create mode 100644 Build/source/texk/dvipdf-x/Makefile.in create mode 100644 Build/source/texk/dvipdf-x/README create mode 100644 Build/source/texk/dvipdf-x/ac/dvipdf-x.ac create mode 100644 Build/source/texk/dvipdf-x/ac/withenable.ac create mode 100644 Build/source/texk/dvipdf-x/aclocal.m4 create mode 100644 Build/source/texk/dvipdf-x/agl.c create mode 100644 Build/source/texk/dvipdf-x/agl.h create mode 100644 Build/source/texk/dvipdf-x/bmpimage.h create mode 100644 Build/source/texk/dvipdf-x/cff_dict.h create mode 100644 Build/source/texk/dvipdf-x/cff_limits.h create mode 100644 Build/source/texk/dvipdf-x/cff_stdstr.h create mode 100644 Build/source/texk/dvipdf-x/cff_types.h create mode 100644 Build/source/texk/dvipdf-x/cid.c create mode 100644 Build/source/texk/dvipdf-x/cid.h create mode 100644 Build/source/texk/dvipdf-x/cid_basefont.h create mode 100644 Build/source/texk/dvipdf-x/cid_p.h create mode 100644 Build/source/texk/dvipdf-x/cidtype0.h create mode 100644 Build/source/texk/dvipdf-x/cidtype2.h create mode 100644 Build/source/texk/dvipdf-x/cmap.c create mode 100644 Build/source/texk/dvipdf-x/cmap.h create mode 100644 Build/source/texk/dvipdf-x/cmap_p.h create mode 100644 Build/source/texk/dvipdf-x/cmap_read.c create mode 100644 Build/source/texk/dvipdf-x/cmap_read.h create mode 100644 Build/source/texk/dvipdf-x/cmap_write.c create mode 100644 Build/source/texk/dvipdf-x/cmap_write.h create mode 100644 Build/source/texk/dvipdf-x/config.h.in create mode 100755 Build/source/texk/dvipdf-x/configure create mode 100644 Build/source/texk/dvipdf-x/configure.ac create mode 100644 Build/source/texk/dvipdf-x/cs_type2.c create mode 100644 Build/source/texk/dvipdf-x/cs_type2.h create mode 100644 Build/source/texk/dvipdf-x/data/EUC-UCS2 create mode 100644 Build/source/texk/dvipdf-x/data/Makefile.am create mode 100644 Build/source/texk/dvipdf-x/data/Makefile.in create mode 100644 Build/source/texk/dvipdf-x/data/cid-x.map create mode 100644 Build/source/texk/dvipdf-x/data/dvipdfmx.cfg create mode 100644 Build/source/texk/dvipdf-x/data/glyphlist.txt create mode 100644 Build/source/texk/dvipdf-x/data/pdfglyphlist.txt create mode 100644 Build/source/texk/dvipdf-x/dpxconf.c create mode 100644 Build/source/texk/dvipdf-x/dpxconf.h create mode 100644 Build/source/texk/dvipdf-x/dpxcrypt.c create mode 100644 Build/source/texk/dvipdf-x/dpxcrypt.h create mode 100644 Build/source/texk/dvipdf-x/dvicodes.h create mode 100755 Build/source/texk/dvipdf-x/dvipdfm-ann.test create mode 100644 Build/source/texk/dvipdf-x/dvipdfmx.h create mode 100755 Build/source/texk/dvipdf-x/dvipdfmx.test create mode 100755 Build/source/texk/dvipdf-x/dvipdft create mode 100644 Build/source/texk/dvipdf-x/man/Makefile.am create mode 100644 Build/source/texk/dvipdf-x/man/Makefile.in create mode 100644 Build/source/texk/dvipdf-x/man/dvipdfm.1 create mode 100644 Build/source/texk/dvipdf-x/man/dvipdft.1 create mode 100644 Build/source/texk/dvipdf-x/man/extractbb.1 create mode 100644 Build/source/texk/dvipdf-x/mem.c create mode 100644 Build/source/texk/dvipdf-x/mem.h create mode 100644 Build/source/texk/dvipdf-x/mfileio.c create mode 100644 Build/source/texk/dvipdf-x/mfileio.h create mode 100644 Build/source/texk/dvipdf-x/mpost.h create mode 100644 Build/source/texk/dvipdf-x/numbers.c create mode 100644 Build/source/texk/dvipdf-x/numbers.h create mode 100644 Build/source/texk/dvipdf-x/otl_conf.c create mode 100644 Build/source/texk/dvipdf-x/otl_conf.h create mode 100644 Build/source/texk/dvipdf-x/otl_opt.c create mode 100644 Build/source/texk/dvipdf-x/otl_opt.h create mode 100644 Build/source/texk/dvipdf-x/pdfencoding.c create mode 100644 Build/source/texk/dvipdf-x/pdfencoding.h create mode 100644 Build/source/texk/dvipdf-x/pdfencrypt.h create mode 100644 Build/source/texk/dvipdf-x/pdffont.c create mode 100644 Build/source/texk/dvipdf-x/pdffont.h create mode 100644 Build/source/texk/dvipdf-x/pdflimits.h create mode 100644 Build/source/texk/dvipdf-x/pdfparse.h create mode 100644 Build/source/texk/dvipdf-x/pdfresource.c create mode 100644 Build/source/texk/dvipdf-x/pdfresource.h create mode 100644 Build/source/texk/dvipdf-x/pkfont.c create mode 100644 Build/source/texk/dvipdf-x/pkfont.h create mode 100644 Build/source/texk/dvipdf-x/pst.c create mode 100644 Build/source/texk/dvipdf-x/pst.h create mode 100644 Build/source/texk/dvipdf-x/pst_obj.c create mode 100644 Build/source/texk/dvipdf-x/pst_obj.h create mode 100644 Build/source/texk/dvipdf-x/sfnt.h create mode 100644 Build/source/texk/dvipdf-x/spc_color.h create mode 100644 Build/source/texk/dvipdf-x/spc_dvips.h create mode 100644 Build/source/texk/dvipdf-x/spc_html.h create mode 100644 Build/source/texk/dvipdf-x/spc_misc.c create mode 100644 Build/source/texk/dvipdf-x/spc_misc.h create mode 100644 Build/source/texk/dvipdf-x/spc_pdfm.h create mode 100644 Build/source/texk/dvipdf-x/spc_tpic.h create mode 100644 Build/source/texk/dvipdf-x/spc_xtx.c create mode 100644 Build/source/texk/dvipdf-x/spc_xtx.h create mode 100644 Build/source/texk/dvipdf-x/specials.h create mode 100644 Build/source/texk/dvipdf-x/src/bmpimage.c create mode 100644 Build/source/texk/dvipdf-x/src/cff.c create mode 100644 Build/source/texk/dvipdf-x/src/cff.h create mode 100644 Build/source/texk/dvipdf-x/src/cff_dict.c create mode 100644 Build/source/texk/dvipdf-x/src/cidtype0.c create mode 100644 Build/source/texk/dvipdf-x/src/cidtype2.c create mode 100644 Build/source/texk/dvipdf-x/src/dpxfile.c create mode 100644 Build/source/texk/dvipdf-x/src/dpxfile.h create mode 100644 Build/source/texk/dvipdf-x/src/dpxutil.c create mode 100644 Build/source/texk/dvipdf-x/src/dpxutil.h create mode 100644 Build/source/texk/dvipdf-x/src/dvi.c create mode 100644 Build/source/texk/dvipdf-x/src/dvi.h create mode 100644 Build/source/texk/dvipdf-x/src/dvipdfmx.c create mode 100644 Build/source/texk/dvipdf-x/src/epdf.c create mode 100644 Build/source/texk/dvipdf-x/src/epdf.h create mode 100644 Build/source/texk/dvipdf-x/src/error.c create mode 100644 Build/source/texk/dvipdf-x/src/error.h create mode 100644 Build/source/texk/dvipdf-x/src/fontmap.c create mode 100644 Build/source/texk/dvipdf-x/src/fontmap.h create mode 100644 Build/source/texk/dvipdf-x/src/jpegimage.c create mode 100644 Build/source/texk/dvipdf-x/src/jpegimage.h create mode 100644 Build/source/texk/dvipdf-x/src/mpost.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfcolor.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfcolor.h create mode 100644 Build/source/texk/dvipdf-x/src/pdfdev.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfdev.h create mode 100644 Build/source/texk/dvipdf-x/src/pdfdoc.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfdoc.h create mode 100644 Build/source/texk/dvipdf-x/src/pdfdraw.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfdraw.h create mode 100644 Build/source/texk/dvipdf-x/src/pdfencrypt.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfnames.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfnames.h create mode 100644 Build/source/texk/dvipdf-x/src/pdfobj.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfobj.h create mode 100644 Build/source/texk/dvipdf-x/src/pdfparse.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfximage.c create mode 100644 Build/source/texk/dvipdf-x/src/pdfximage.h create mode 100644 Build/source/texk/dvipdf-x/src/pngimage.c create mode 100644 Build/source/texk/dvipdf-x/src/pngimage.h create mode 100644 Build/source/texk/dvipdf-x/src/sfnt.c create mode 100644 Build/source/texk/dvipdf-x/src/spc_color.c create mode 100644 Build/source/texk/dvipdf-x/src/spc_dvips.c create mode 100644 Build/source/texk/dvipdf-x/src/spc_html.c create mode 100644 Build/source/texk/dvipdf-x/src/spc_pdfm.c create mode 100644 Build/source/texk/dvipdf-x/src/spc_tpic.c create mode 100644 Build/source/texk/dvipdf-x/src/spc_util.c create mode 100644 Build/source/texk/dvipdf-x/src/spc_util.h create mode 100644 Build/source/texk/dvipdf-x/src/specials.c create mode 100644 Build/source/texk/dvipdf-x/src/tfm.c create mode 100644 Build/source/texk/dvipdf-x/src/truetype.c create mode 100644 Build/source/texk/dvipdf-x/src/tt_aux.c create mode 100644 Build/source/texk/dvipdf-x/src/tt_aux.h create mode 100644 Build/source/texk/dvipdf-x/src/tt_cmap.c create mode 100644 Build/source/texk/dvipdf-x/src/tt_cmap.h create mode 100644 Build/source/texk/dvipdf-x/src/tt_glyf.c create mode 100644 Build/source/texk/dvipdf-x/src/tt_post.c create mode 100644 Build/source/texk/dvipdf-x/src/tt_table.c create mode 100644 Build/source/texk/dvipdf-x/src/type0.c create mode 100644 Build/source/texk/dvipdf-x/src/type0.h create mode 100644 Build/source/texk/dvipdf-x/src/type1.c create mode 100644 Build/source/texk/dvipdf-x/src/type1c.c create mode 100644 Build/source/texk/dvipdf-x/src/vf.c create mode 100644 Build/source/texk/dvipdf-x/src/xbb.c create mode 100644 Build/source/texk/dvipdf-x/src/xbb.h create mode 100644 Build/source/texk/dvipdf-x/subfont.c create mode 100644 Build/source/texk/dvipdf-x/subfont.h create mode 100644 Build/source/texk/dvipdf-x/system.h create mode 100644 Build/source/texk/dvipdf-x/t1_char.c create mode 100644 Build/source/texk/dvipdf-x/t1_char.h create mode 100644 Build/source/texk/dvipdf-x/t1_load.c create mode 100644 Build/source/texk/dvipdf-x/t1_load.h create mode 100644 Build/source/texk/dvipdf-x/tests/cmr10.pfb create mode 100644 Build/source/texk/dvipdf-x/tests/cmr10.tfm create mode 100644 Build/source/texk/dvipdf-x/tests/dvipdfmx.cfg create mode 100644 Build/source/texk/dvipdf-x/tests/grahn.dvi create mode 100644 Build/source/texk/dvipdf-x/tests/grahn.tex create mode 100644 Build/source/texk/dvipdf-x/tests/image.dvi create mode 100644 Build/source/texk/dvipdf-x/tests/image.jpeg create mode 100644 Build/source/texk/dvipdf-x/tests/image.pdf create mode 100644 Build/source/texk/dvipdf-x/tests/image.png create mode 100644 Build/source/texk/dvipdf-x/tests/image.tex create mode 100644 Build/source/texk/dvipdf-x/tests/psfonts.map create mode 100644 Build/source/texk/dvipdf-x/tfm.h create mode 100644 Build/source/texk/dvipdf-x/truetype.h create mode 100644 Build/source/texk/dvipdf-x/tt_glyf.h create mode 100644 Build/source/texk/dvipdf-x/tt_gsub.c create mode 100644 Build/source/texk/dvipdf-x/tt_gsub.h create mode 100644 Build/source/texk/dvipdf-x/tt_post.h create mode 100644 Build/source/texk/dvipdf-x/tt_table.h create mode 100644 Build/source/texk/dvipdf-x/type1.h create mode 100644 Build/source/texk/dvipdf-x/type1c.h create mode 100644 Build/source/texk/dvipdf-x/unicode.c create mode 100644 Build/source/texk/dvipdf-x/unicode.h create mode 100644 Build/source/texk/dvipdf-x/vf.h create mode 100755 Build/source/texk/dvipdf-x/xdvipdfm-ann.test create mode 100755 Build/source/texk/dvipdf-x/xdvipdfmx.test create mode 100644 Build/source/texk/dvipdf-x/xsrc/bmpimage.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/cff.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/cff.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/cff_dict.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/cidtype0.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/cidtype2.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/dpxfile.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/dpxfile.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/dpxutil.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/dpxutil.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/dvi.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/dvi.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/epdf.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/epdf.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/error.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/error.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/fontmap.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/fontmap.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/jpegimage.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/jpegimage.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/mpost.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfcolor.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfcolor.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfdev.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfdev.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfdoc.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfdoc.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfdraw.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfdraw.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfencrypt.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfnames.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfnames.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfobj.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfobj.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfparse.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfximage.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pdfximage.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/pngimage.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/pngimage.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/sfnt.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/spc_color.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/spc_dvips.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/spc_html.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/spc_tpic.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/spc_util.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/spc_util.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/specials.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/tfm.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/truetype.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/tt_aux.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/tt_aux.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/tt_cmap.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/tt_cmap.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/tt_glyf.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/tt_post.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/tt_table.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/type0.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/type0.h create mode 100644 Build/source/texk/dvipdf-x/xsrc/type1.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/type1c.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/vf.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/xbb.c create mode 100644 Build/source/texk/dvipdf-x/xsrc/xbb.h diff --git a/Build/source/Makefile.in b/Build/source/Makefile.in index 3199e008245..1e86c491098 100644 --- a/Build/source/Makefile.in +++ b/Build/source/Makefile.in @@ -147,6 +147,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/kpse-cairo-flags.m4 \ $(top_srcdir)/texk/dvi2tty/ac/withenable.ac \ $(top_srcdir)/texk/dvidvi/ac/withenable.ac \ $(top_srcdir)/texk/dviljk/ac/withenable.ac \ + $(top_srcdir)/texk/dvipdf-x/ac/withenable.ac \ + $(top_srcdir)/texk/dvipdf-x/ac/dvipdf-x.ac \ $(top_srcdir)/texk/dvipdfm-x/ac/withenable.ac \ $(top_srcdir)/texk/dvipdfm-x/ac/dvipdfm-x.ac \ $(top_srcdir)/texk/dvipng/ac/withenable.ac \ diff --git a/Build/source/configure b/Build/source/configure index 4f5dee98ad7..471e36a7ff9 100755 --- a/Build/source/configure +++ b/Build/source/configure @@ -849,6 +849,9 @@ enable_dtl enable_dvi2tty enable_dvidvi enable_dviljk +enable_dvipdf_x +enable_dvipdf +enable_xdvipdf enable_dvipdfm_x enable_dvipdfmx enable_xdvipdfmx @@ -1653,6 +1656,9 @@ Optional Features: --disable-dvi2tty do not build the dvi2tty package --disable-dvidvi do not build the dvidvi package --disable-dviljk do not build the dviljk package + --enable-dvipdf-x build the dvipdf-x package + --disable-dvipdf do not build the dvipdf program + --disable-xdvipdf do not build the xdvipdf program --disable-dvipdfm-x do not build the dvipdfm-x package --disable-dvipdfmx do not build the dvipdfmx program --disable-xdvipdfmx do not build the xdvipdfmx program @@ -4924,6 +4930,56 @@ test "x$enable_dviljk" = xno || { } +## texk/dvipdf-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdf-x/ +## configure options and TL libraries required for dvipdf-x +# Check whether --enable-dvipdf-x was given. +if test "${enable_dvipdf_x+set}" = set; then : + enableval=$enable_dvipdf_x; +fi +case $enable_dvipdf_x in #( + yes|no) : + ;; #( + *) : + + enable_dvipdf_x=no + { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&5 +$as_echo "$as_me: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipdf-x=$enable_dvipdf_x'" + ;; +esac + +test "x$enable_dvipdf_x" = xno || { + need_kpathsea=yes + need_libpng=yes +} + +## Define configure options for dvipdf-x. +# Check whether --enable-dvipdf was given. +if test "${enable_dvipdf+set}" = set; then : + enableval=$enable_dvipdf; +fi + +case enable_dvipdf in #( + yes | no) : + ;; #( + *) : + enable_dvipdf=yes ;; +esac +# Check whether --enable-xdvipdf was given. +if test "${enable_xdvipdf+set}" = set; then : + enableval=$enable_xdvipdf; +fi + +case enable_xdvipdf in #( + yes | no) : + ;; #( + *) : + enable_xdvipdf=yes ;; +esac + +test "x$enable_dvipdf_x:$enable_xdvipdf" = xyes:yes && need_freetype2=yes + + ## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/ ## configure options and TL libraries required for dvipdfm-x # Check whether --enable-dvipdfm-x was given. @@ -4971,7 +5027,7 @@ case enable_xdvipdfmx in #( enable_xdvipdfmx=yes ;; esac -test "x$enable_dvipdfm_x:$enable_xdviodfm" = xyes:yes && need_freetype2=yes +test "x$enable_dvipdfm_x:$enable_xdvipdfmx" = xyes:yes && need_freetype2=yes ## texk/dvipng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ diff --git a/Build/source/libs/Makefile.in b/Build/source/libs/Makefile.in index cfa202edea0..3d2afcc74d1 100644 --- a/Build/source/libs/Makefile.in +++ b/Build/source/libs/Makefile.in @@ -145,6 +145,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../texk/dvi2tty/ac/withenable.ac \ $(top_srcdir)/../texk/dvidvi/ac/withenable.ac \ $(top_srcdir)/../texk/dviljk/ac/withenable.ac \ + $(top_srcdir)/../texk/dvipdf-x/ac/withenable.ac \ + $(top_srcdir)/../texk/dvipdf-x/ac/dvipdf-x.ac \ $(top_srcdir)/../texk/dvipdfm-x/ac/withenable.ac \ $(top_srcdir)/../texk/dvipdfm-x/ac/dvipdfm-x.ac \ $(top_srcdir)/../texk/dvipng/ac/withenable.ac \ diff --git a/Build/source/libs/configure b/Build/source/libs/configure index db0ba34227c..347555e1e1f 100755 --- a/Build/source/libs/configure +++ b/Build/source/libs/configure @@ -761,6 +761,9 @@ enable_dtl enable_dvi2tty enable_dvidvi enable_dviljk +enable_dvipdf_x +enable_dvipdf +enable_xdvipdf enable_dvipdfm_x enable_dvipdfmx enable_xdvipdfmx @@ -1558,6 +1561,9 @@ Optional Features: --disable-dvi2tty do not build the dvi2tty package --disable-dvidvi do not build the dvidvi package --disable-dviljk do not build the dviljk package + --enable-dvipdf-x build the dvipdf-x package + --disable-dvipdf do not build the dvipdf program + --disable-xdvipdf do not build the xdvipdf program --disable-dvipdfm-x do not build the dvipdfm-x package --disable-dvipdfmx do not build the dvipdfmx program --disable-xdvipdfmx do not build the xdvipdfmx program @@ -4173,6 +4179,56 @@ test "x$enable_dviljk" = xno || { } +## texk/dvipdf-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdf-x/ +## configure options and TL libraries required for dvipdf-x +# Check whether --enable-dvipdf-x was given. +if test "${enable_dvipdf_x+set}" = set; then : + enableval=$enable_dvipdf_x; +fi +case $enable_dvipdf_x in #( + yes|no) : + ;; #( + *) : + + enable_dvipdf_x=no + { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&5 +$as_echo "$as_me: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipdf-x=$enable_dvipdf_x'" + ;; +esac + +test "x$enable_dvipdf_x" = xno || { + need_kpathsea=yes + need_libpng=yes +} + +## Define configure options for dvipdf-x. +# Check whether --enable-dvipdf was given. +if test "${enable_dvipdf+set}" = set; then : + enableval=$enable_dvipdf; +fi + +case enable_dvipdf in #( + yes | no) : + ;; #( + *) : + enable_dvipdf=yes ;; +esac +# Check whether --enable-xdvipdf was given. +if test "${enable_xdvipdf+set}" = set; then : + enableval=$enable_xdvipdf; +fi + +case enable_xdvipdf in #( + yes | no) : + ;; #( + *) : + enable_xdvipdf=yes ;; +esac + +test "x$enable_dvipdf_x:$enable_xdvipdf" = xyes:yes && need_freetype2=yes + + ## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/ ## configure options and TL libraries required for dvipdfm-x # Check whether --enable-dvipdfm-x was given. @@ -4220,7 +4276,7 @@ case enable_xdvipdfmx in #( enable_xdvipdfmx=yes ;; esac -test "x$enable_dvipdfm_x:$enable_xdviodfm" = xyes:yes && need_freetype2=yes +test "x$enable_dvipdfm_x:$enable_xdvipdfmx" = xyes:yes && need_freetype2=yes ## texk/dvipng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ diff --git a/Build/source/m4/ChangeLog b/Build/source/m4/ChangeLog index 1e7a8b5dfde..267e009bae9 100644 --- a/Build/source/m4/ChangeLog +++ b/Build/source/m4/ChangeLog @@ -1,3 +1,9 @@ +2013-08-06 Peter Breitenlohner + + * kpse-pkgs.m4 (KPSE_TEXK_PKGS): Recover dvipdfm-x@31034 + (essentially dvipdfmx and xdvipdfmx from branch-2013) as + dvipdf-x. + 2013-07-02 Peter Breitenlohner * kpse-common.m4: Drop checks for BSD string functions. diff --git a/Build/source/m4/kpse-pkgs.m4 b/Build/source/m4/kpse-pkgs.m4 index 8528c908d5a..da0b427d43c 100644 --- a/Build/source/m4/kpse-pkgs.m4 +++ b/Build/source/m4/kpse-pkgs.m4 @@ -105,6 +105,7 @@ dtl dvi2tty dvidvi dviljk +dvipdf-x dvipdfm-x dvipng dvipos diff --git a/Build/source/texk/Makefile.in b/Build/source/texk/Makefile.in index ebbdfb3e71b..8af34ab4ab4 100644 --- a/Build/source/texk/Makefile.in +++ b/Build/source/texk/Makefile.in @@ -145,6 +145,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../texk/dvi2tty/ac/withenable.ac \ $(top_srcdir)/../texk/dvidvi/ac/withenable.ac \ $(top_srcdir)/../texk/dviljk/ac/withenable.ac \ + $(top_srcdir)/../texk/dvipdf-x/ac/withenable.ac \ + $(top_srcdir)/../texk/dvipdf-x/ac/dvipdf-x.ac \ $(top_srcdir)/../texk/dvipdfm-x/ac/withenable.ac \ $(top_srcdir)/../texk/dvipdfm-x/ac/dvipdfm-x.ac \ $(top_srcdir)/../texk/dvipng/ac/withenable.ac \ diff --git a/Build/source/texk/configure b/Build/source/texk/configure index 8ea76e76a56..450247af9b9 100755 --- a/Build/source/texk/configure +++ b/Build/source/texk/configure @@ -761,6 +761,9 @@ enable_dtl enable_dvi2tty enable_dvidvi enable_dviljk +enable_dvipdf_x +enable_dvipdf +enable_xdvipdf enable_dvipdfm_x enable_dvipdfmx enable_xdvipdfmx @@ -863,6 +866,7 @@ dtl dvi2tty dvidvi dviljk +dvipdf-x dvipdfm-x dvipng dvipos @@ -1572,6 +1576,9 @@ Optional Features: --disable-dvi2tty do not build the dvi2tty package --disable-dvidvi do not build the dvidvi package --disable-dviljk do not build the dviljk package + --enable-dvipdf-x build the dvipdf-x package + --disable-dvipdf do not build the dvipdf program + --disable-xdvipdf do not build the xdvipdf program --disable-dvipdfm-x do not build the dvipdfm-x package --disable-dvipdfmx do not build the dvipdfmx program --disable-xdvipdfmx do not build the xdvipdfmx program @@ -4187,6 +4194,56 @@ test "x$enable_dviljk" = xno || { } +## texk/dvipdf-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdf-x/ +## configure options and TL libraries required for dvipdf-x +# Check whether --enable-dvipdf-x was given. +if test "${enable_dvipdf_x+set}" = set; then : + enableval=$enable_dvipdf_x; +fi +case $enable_dvipdf_x in #( + yes|no) : + ;; #( + *) : + + enable_dvipdf_x=no + { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&5 +$as_echo "$as_me: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipdf-x=$enable_dvipdf_x'" + ;; +esac + +test "x$enable_dvipdf_x" = xno || { + need_kpathsea=yes + need_libpng=yes +} + +## Define configure options for dvipdf-x. +# Check whether --enable-dvipdf was given. +if test "${enable_dvipdf+set}" = set; then : + enableval=$enable_dvipdf; +fi + +case enable_dvipdf in #( + yes | no) : + ;; #( + *) : + enable_dvipdf=yes ;; +esac +# Check whether --enable-xdvipdf was given. +if test "${enable_xdvipdf+set}" = set; then : + enableval=$enable_xdvipdf; +fi + +case enable_xdvipdf in #( + yes | no) : + ;; #( + *) : + enable_xdvipdf=yes ;; +esac + +test "x$enable_dvipdf_x:$enable_xdvipdf" = xyes:yes && need_freetype2=yes + + ## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/ ## configure options and TL libraries required for dvipdfm-x # Check whether --enable-dvipdfm-x was given. @@ -4234,7 +4291,7 @@ case enable_xdvipdfmx in #( enable_xdvipdfmx=yes ;; esac -test "x$enable_dvipdfm_x:$enable_xdviodfm" = xyes:yes && need_freetype2=yes +test "x$enable_dvipdfm_x:$enable_xdvipdfmx" = xyes:yes && need_freetype2=yes ## texk/dvipng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ @@ -6400,6 +6457,16 @@ if test -x $srcdir/dviljk/configure; then fi +if test -x $srcdir/dvipdf-x/configure; then + test "x$enable_dvipdf_x" = xno || MAKE_SUBDIRS="$MAKE_SUBDIRS dvipdf-x" + CONF_SUBDIRS="$CONF_SUBDIRS dvipdf-x" + if false; then + subdirs="$subdirs dvipdf-x" + + fi +fi + + if test -x $srcdir/dvipdfm-x/configure; then test "x$enable_dvipdfm_x" = xno || MAKE_SUBDIRS="$MAKE_SUBDIRS dvipdfm-x" CONF_SUBDIRS="$CONF_SUBDIRS dvipdfm-x" diff --git a/Build/source/texk/dvipdf-x/AUTHORS b/Build/source/texk/dvipdf-x/AUTHORS new file mode 100644 index 00000000000..99d52a91b1a --- /dev/null +++ b/Build/source/texk/dvipdf-x/AUTHORS @@ -0,0 +1,12 @@ +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. + +Other updates by TeX Live developers: Peter Breitenlohner, +Karl Berry, et al. + diff --git a/Build/source/texk/dvipdf-x/COPYING b/Build/source/texk/dvipdf-x/COPYING new file mode 100644 index 00000000000..60549be514a --- /dev/null +++ b/Build/source/texk/dvipdf-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. + + + Copyright (C) 19yy + + 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. + + , 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/dvipdf-x/ChangeLog b/Build/source/texk/dvipdf-x/ChangeLog new file mode 100644 index 00000000000..2e780b84764 --- /dev/null +++ b/Build/source/texk/dvipdf-x/ChangeLog @@ -0,0 +1,3724 @@ +2013-06-29 Peter Breitenlohner + + * 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. + * Makefile.am: Adjust. + +2013-06-28 Peter Breitenlohner + + * (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 + + * 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 + + Merge dvipdfmx and xdvipdfmx into dvipdfm-x. + + * README, ChangeLog: Merged and consolidated the files from + dvipdfmx and xdvipdfmx. + +2013-04-30 Akira Kakuto + + * 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 + + * (x)dvipdfmx.test: New shell scripts for a simple test. + * Makefile.am: Adapted. + +2013-04-30 Peter Breitenlohner + + * src/dvipdfmx.c: Default is not to cache image files. + Must not cast command line value to 'unsigned'. + +2013-04-30 Karl Berry + + * 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 + + * configure.ac: version 20130405 for TL'13. + +2013-03-28 Akira Kakuto + + * src/dpxfile.c, src/spc_dvips.c: Recover dpx_create_temp_file() + for PSTricks. + +2013-03-26 Peter Breitenlohner + + * src/dpxfile.[ch]: Avoid gcc warnings. + +2013-03-26 Akira Kakuto + + * src/dvi.c: Correct my mistake to delete RELEASE(q). + +2013-03-25 Peter Breitenlohner + + Patch from Tsuchimura Nobuyuki 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 + + * src/dpxfile.c: Change dpx_create_temp_file() because tmpnam() + sometimes fails on Windows. + +2013-03-20 Khaled Hosny + + 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 + + Only for xdvipdfmx: + * dvi.c (dvi_locate_native_font): Drop unused variable. + +2013-03-14 Khaled Hosny + + 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 + + * 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 + + 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 + + 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 + + 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 + + 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 + + * data/Makefile.am (configdatadir, mapdatadir, cmapdatadir): + Change texmf => texmf-dist. + +2013-01-29 Peter Breitenlohner + + Only for dvipdfmx: + * configure.ac, src/Makefile.am: Allow subdir-objects. + +2013-01-21 Peter Breitenlohner + + Only for xdvipdfmx: + * src/dvi.c: Avoid unused variables sbuf and slen. + +2013-01-19 Khaled Hosny + + 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 + + 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 + + * read_v2_post_names() in tt_post.c: Change calculation of post->count + for special fonts with unused index. + +2013-01-10 Peter Breitenlohner + + * src/cid.c: Avoid casts (const char *) -> (char *). + +2013-01-09 Peter Breitenlohner + + 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 + + * src/tt_cmap.c: Make sure CMapName of embedded CMaps does not contain + slashes. + +2012-12-11 Khaled Hosny + + 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 + + Only for xdvipdfmx: + * src/Makefile.am: Avoid use of deprecated INCLUDES. + +2012-09-24 Peter Breitenlohner + + Only for dvipdfmx: + * version.ac (removed): We now maintain dvipdfmx here. + * configure.ac: Adapted. + +2012-09-21 Karl Berry + + * many files: remove useless $Header$ from old repo, + do not point to dvipdfmx@ email address any more. + +2012-09-19 Peter Breitenlohner + + * ChangeLog.TL (removed): Now merged ... + * ChangeLog: ... into this. + +2012-09-07 Akira Kakuto + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + * 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 + + * src/cff.c, src/cff.h. src/type1.c: fix type1 SEAC bug. + +2012-08-21 Peter Breitenlohner + + 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 + + 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 + + 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 + + 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 + + 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 + + Only for dvipdfmx: + * patch-05-cid-x_map (new): add entries for rml-jis and gbm-jis + +2012-05-06 Akira Kakuto + + * fontmap.c: fix a typo. allow pdftex.map without PS name. + +2012-04-27 Peter Breitenlohner + + 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 + + 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 + + Only for dvipdfmx: + * dvipdfmx.c (show_version): Print "modified for TeX Live,". + +2012-04-20 Alexander Grahn + + * src/spc_pdfm.c: use kpse to find media + +2012-04-20 Norbert Preining + + * 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 + + * src/spc_dvips.c: Fixed bug in "ps: plotfile" special. + +2012-03-29 Peter Breitenlohner + + 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 + + * 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 + + 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 + + Only for xdvipdfmx: + * configure.ac: Fixed a typo (no libpaper for TeX Live builds). + +2012-01-17 Hironori Kitagawa + + Only for dvipdfmx: + * dvi.c, pdfdev.c: Support for (e-)(u)pTeX dtou direction. + +2011-12-06 Peter Breitenlohner + + * data/Makefile.am: + Replace ${prefix}/texmf => $(datarootdir)/texmf. + +2011-11-06 Akira Kakuto + + 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 + + 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 + + Only for xdvipdfmx: + * tt_cmap.c: Fix typo "featre" -> "feature". + +2011-09-07 Akira Kakuto + + 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 + + * 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 and Peter Breitenlohner. + +2011-06-06 Peter Breitenlohner + + * dpxfile.c (exec_spawn): Do not quote execvp() arguments. + +2011-06-03 Peter Breitenlohner + + * dpxfile.c (exec_spawn): Exit if execvp() fails, some clean up. + +2011-06-03 Akira Kakuto + + * dpxfile.c: fix a bug in exec_spawn(). + +2011-05-31 Peter Breitenlohner + + Only for dvipdfmx: + * man/extractbb.1: Update extractbb manpage. + +2011-05-09 Peter Breitenlohner + + Only for dvipdfmx: + * ../dvipdfmx-20110311/data/dvipdfmx.cfg: Synched from Master. + * patch-00-cfg: Adapted (by Karl Berry ). + +2011-05-03 Peter Breitenlohner + + Only for dvipdfmx: + Imported snapshot 20110311. + * configure.ac: Adapted. + +2011-04-29 Peter Breitenlohner + + 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 + + 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 + + * dpxcrypt.c: + Applied the patch for 64bit systems; suggested by Akira Kakuto. + +2011-03-10 Peter Breitenlohner + + * 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 + + 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 + + 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 + + * configure.ac: Check for , drop check for system(). + * src/pdfencrypt.c (compute_id_string): Drop unused function. + +2011-03-09 Akira Kakuto + + * src/dpxfile.c: Avoid to use system(). + +2011-03-07 Peter Breitenlohner + + 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 + + * dpxfile.c: + Applied the secutiry patch written by Akira Kakuto + (suggested by Karl Berry). + +2011-02-28 Peter Breitenlohner + + * src/pngimage.c (create_cspace_ICCBased): Avoid libpng-1.5.x + compiler warning. + +2011-02-15 Peter Breitenlohner + + Only for dvipdfmx: + * src/Makefile.am [WIN32]: Add dvipdfmx.exe, ebb.exe, and + extractbb.exe wrappers for MinGW. + +2010-02-11 Peter Breitenlohner + + 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 + + Only for dvipdfmx: + * src/dvipdfmx.c: Check for argv[0] with .exe via strcasecmp(). + +2010-12-29 Peter Breitenlohner + + 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 + + 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 + + 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 + + * configure.ac: Remove AC_TYPE_SIZE_T, now part of KPSE_COMMON. + +2010-03-28 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 . + +2010-02-20 Peter Breitenlohner + + * src/sfnt.h: #define CHAR as SFNT_CHAR to avoid conflict with + CHAR from . + +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 + + * 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 + + * configure.ac, src/dpxfile.c: Require recent kpathsea version. + +2009-10-10 Jin-Hwan Cho + + * dvipdfmx.c, xbb.c: + Change usage() as suggested by Matthias Franz and Karl Berry. + +2009-10-09 Jin-Hwan Cho + + * 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + * tt_post.c: + Fixed the crashing bug with Mona font found by Alexis Ballier. + +2009-07-17 Peter Breitenlohner + + * src/pdfximage.h: add prototype for pdf_ximage_get_subtype. + +2009-07-08 Jin-Hwan Cho + + * dvipdfmx.c: + Add -E option that enables DVIPDFM emulation mode in DVIPDFMx. + +2009-07-07 Jin-Hwan Cho + + * 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 + + * Makefile.am (AM_CFLAGS): enable compiler warnings. + * src/pdfobj.c (pdf_file_new): declare as static. + +2009-06-05 Peter Breitenlohner + + * configure.ac: replace '--enable-tetex-build' by + '--enable-texlive-build' (automatic if configured as part of the + TeXLive tree). + +2009-06-04 Karl Berry + + 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 + + Adapt to TL2009 build system. + +2009-05-25 Peter Breitenlohner + + * configure.ac, src/Makefile.am: Do not use CPPFLAGS for + required -I flags, leave it for the user. + +2009-05-22 Jin-Hwan Cho + + * 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 + + * pdfdoc.c (pdf_doc_get_page): Avoid C99isms + (variable declaration not at the beginning of a block). + + From Vladimir Volovich + +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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 ), 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 + + * 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 + + * 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 + + * 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 + + * spc_pdfm.c: + Fixed a bug on beads with nonzero depth; reported by + Alexander Grahn. + +2008-06-13 Jin-Hwan Cho + + * spc_pdfm.c: + Fixed a bug on annotations with nonzero depth; reported by + Alexander Grahn. + +2008-06-07 Jin-Hwan Cho + + * 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 + + * contrib/latex/animate.sty.sample: + Support animate.sty, version 2008/06/03. + +2008-06-05 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * dpxfile.c, pdffont.c: + Support Mac OS X Resource Fork Font (/rsrc) with TrueType outlines. + +2008-05-09 Jin-Hwan Cho + + * 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 + + * 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 via Karl Berry) + + * src/Makefile.am: + xbb needs zlib too. + (contributed by Karl Berry ) + + * 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 + via Karl Berry) + +2008-04-06 Peter Breitenlohner + + * configure.in: respect library dependencies. + +2008-03-04 Peter Breitenlohner + + * 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 + + 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 + + * 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 + + * spc_pdfm.c: + Fixed a memory deallocation problem in the ConTeXt sample of + Francesco Pretto. + +2007-12-03 Jin-Hwan Cho + + * 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 + + * pdfdev.c: + Restored the DVIPDFM code for calculation of kerns; + reported by Keiichirou Shikano. + +2007-11-22 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * xbb.c: + New program "xbb" extending "ebb". + +2007-05-03 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 + + * 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 + + * tt_cmap.c: + Support OpenType with PID=0, EID=3 + +2007-04-09 Jin-Hwan Cho + + * dvipdfmx.c: + Updated the usage as suggested by Matthias Franz + +2007-04-03 Jin-Hwan Cho + + * 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 + + * pdfobj.c: + Support xref stream for PDF v1.5 or higher; contributed by Matthias Franz + +2007-03-17 Jin-Hwan Cho + + * dpxfile.c: + Fixed a bug in reading .enc file; reported by Matthias Franz + + +2007-02-28 Jin-Hwan Cho + + * epdf.c: + Fixed a problem in handling Cropbox + +2007-02-14 Jin-Hwan Cho + + * 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 + + * fontmap.c: + Fixed typos found by Jonathan Kew + +2007-01-20 Jin-Hwan Cho + + * specials.h: + Fixed warning message in the IRIX compilation, + reported by Karl Berry and found by Olaf Weber + +2007-01-19 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 + + * 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 + + * pdfcolor.c: + Fixed the color bug reported by H. J. Lee and Pablo Rodriguez. + +2006-12-07 Jin-Hwan Cho + + * pdfobj.c: + Fixed a bug with xref, reported by Paul Guyot. + +2006-12-06 Jin-Hwan Cho + + * 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 + + * dpxfile.c: + Fixed a bug found by Karnes Kim. + +2005-10-14 Jin-Hwan Cho + + * 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 + + * pdfdoc.c, pdfdraw.c: + Stroke and fill color controls with gsave and grestore. + +2005-08-30 Jin-Hwan Cho + + * 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 + + * spc_pdfm.c: + Fix a bug on finding XObject. + +2005-08-23 Jin-Hwan Cho + + * 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 + + * pdfdoc.c, spc_pdfm.c, specials.c: + Fix a bug on article|bead|thread specials. + +2005-08-14 Jin-Hwan Cho + + * spc_html.c, spc_pdfm.c, specials.c: + Fix a bug causing memory leak, and correct a typo. + +2005-08-12 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 + + * 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 + + * specials.c, spc_html.c, spc_pdfm.c: + Various minor changes to specials. + Rewriting HTML special support. + +2005-07-31 Shunsaku Hirata + + * specials.c: + Fixed a bug introduced by changes in 2005-07-30. + (@page1 not handled correctly) + +2005-07-30 Shunsaku Hirata + + * 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 + + * pdfdev.c: + Simply use sprintf for printing numbers................. + Fixed an ancient bug causing very frequent (unnecessary) + font selection. + +2005-07-21 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * spc_dvips.c: + Fixes in psfile special. + +2005-07-17 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * 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 + + * agl.c: Fixed various small bugs + +2005-07-09 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * tt_gsub.c, tt_gsub.h: Alternate substitution + LookupType 3 (Alternate Substitution) GSUB lookup. + Unused. + +2005-06-13 Shunsaku Hirata + + * tt_gsub.c: + Added support for LookupType 7 (Extension Substitution). + Large CJK fonts may want them. Not tested well. + +2005-06-09 Shunsaku Hirata + + * tt_glyf.c: + Set top-side bearing to (sTypoAscender - bbox.ury) for + fonts without vmtx table (vertOriginY = sTypoAscender). + +2005-06-09 Shunsaku Hirata + + * dpxfile.c: + Fixes for old kpathsea library. + +2005-06-08 Shunsaku Hirata + + * 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 + + * cid_basefont.h: Update for Adobe Reader 7 + + * cid.c, pdfobj.c: Accept version tag 1.6 + +2005-06-06 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * 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 + + * mpost.c: + Text handling was not correct for subfonts. + + * pdfencoding.c: + Increased verbose level for ToUnicode warning. + +2005-02-03 Jin-Hwan Cho + + * 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 + + * cidtype2.c: + Fixed a critical bug on the DW entry for CIDType2 fonts. + + * cvs tag: DVIPDFMX-20050201 + +2005-01-06 Jin-Hwan Cho + + * 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 + + * 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 + + * ttf, tt_*: + ttf.[ch] -> truetype.[ch], renamed few files, added tt_post. + + * unicode, pdfencoding: + ToUnicode support migrated to pdfencoding. + +2004-09-05 Shunsaku Hirata + + * pdfencoding: encodings -> pdfencoding + + * bug fixes. + + * pdflimits: This was not pdflimits nor implementation limit + of PDF viewers at all. + +2004-09-02 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * cid_basefont.h: Bug fix + Added missing '['. + + * doc/dpxunicode.pdf: Update + + * tt_cmap.c: + +2004-08-22 Shunsaku Hirata + + * 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 + + * Unicode support for CID OpenType. + +2004-08-15 Shunsaku Hirata + + * 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 + + * otl_opt.[ch]: New file + Handle fontmap options for OTL features. + +2004-08-11 Shunsaku Hirata + + * 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 + + * tt_cmap.c, cidtype0.c: Bug fixes + +2004-08-08 Shunsaku Hirata + + * 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 + + * Type1 font accept "unicode" encoding. + Converted to CIDFontType 0 CIDFont. + +2004-08-02 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure, ...: + HAVE_KPSE_OPENTYPE_FORMAT and HAVE_KPSE_ENC_FORMAT is not + correctly set when compiled with gcc3. + +2004-06-28 Shunsaku Hirata + + * pdfximage.c: + Do not clip PDF images when "clip" option is not given. + +2004-06-27 Shunsaku Hirata + + * Workaround for "three dot leader" problem. + +2004-06-16 Shunsaku Hirata + + * 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 + + * pdfspecial.c: Bug fix on cropbox in do_bxobj(). + +2004-05-03 Shunsaku Hirata + + * jpegimage.c: Uninitialized variable. + +2004-04-09 Shunsaku Hirata + + * 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 + + * README: update + +2004-03-25 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * pdfspecial.c: + pdf:literal direct should not translate origin. + +2004-03-17 Shunsaku Hirata + + * type1.c, type1c.c, cmap.c, ...: Memory leak. + +2004-03-16 Shunsaku Hirata + + * mpost.c, psspecialc.: Fixed bugs. + +2004-03-14 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * 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 + + * pdfparse.c: Added missing () in macro PDF_TOKEN_END() + + * pdffont.c: Compiler warning on uninitialized variable. + +2004-03-02 Shunsaku Hirata + + * 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 + + * 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 + + * Too many warnings when compiled with -Wshadow... + pdfdoc.c need to be fixed. + + * -Wmissing-prototypes, -Wmissing-declarations + +2004-02-21 Shunsaku Hirata + + * type0.c: + Changes for New TDS/kpathsea. + Fixed a bug in get_tounicode_cmap()... + +2004-02-19 Shunsaku Hirata + + * cidtype0.c, type0.c: + Write CID glyph metrics for non-embedded CFF/OpenType fonts. + +2004-02-18 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * type1.c: + Bug fix. Compression of vhcurveto-hvcurveto was not actually done. + One more bug in flex handling. + +2004-02-08 Shunsaku Hirata + + * 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 + + * 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 + + * 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,h for papersize option. + +2004-02-03 Shunsaku Hirata + + * type1.c: + Counter control (othersubr #12 and #13) supported. + +2004-02-01 Shunsaku Hirata + + * 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 + + * type1.c: Bug fix. + + * Added many 'const'. + +2004-01-29 Shunsaku Hirata + + * 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 + + * cff.c, cff.h, cff_dict.c, cff_dict.h: + Added few functions for Type 1 -> Type 1C conversion. + +2004-01-24 Shunsaku Hirata + + * 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 + + * cs_type2.c: Don't use rint(). + +2004-01-21 Shunsaku Hirata + + * psimage.c, configure.in, config.h.in: + Use mkstemp() if available. + +2004-01-20 Shunsaku Hirata + + * tt_table.[ch], tt_build.[ch], cidtype[02].c: + CIDFont glyph metrics for embedded font. + +2004-01-17 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * Bug fixes in pdfparse.c and cid_basefont.h. + +2003-12-15 Shunsaku Hirata + + * 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 + + * JPEG moved to jpegimage.c. + + * Bug fixes. + +2003-12-06 Shunsaku Hirata + + * Changes in pdfspecail.c. + + * Fixed a bug in mpost.c. + +2003-12-02 Shunsaku Hirata + + * Added a patch for dvipdfm's ebb.c. (PDF ArtBox support) + +2003-11-29 Shunsaku Hirata + + * Bug fixes. + + * CFF/OpenType support for single-byte font. + +2003-11-26 Shunsaku Hirata + + * Little enhancement to epdf.c. + + * Merged epsbox.sty patch by Noda. + +2003-11-25 Shunsaku Hirata + + * Many part of font/encoding related code rewrote. + + * Unicode support for single-byte font. + +2003-11-10 Jin-Hwan Cho + + * 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 + + * 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 + + * Fixed bug that dvipdfmx stops with error "Invalid Subr Index" + when embedding CFF OpenType font. + +2003-10-09 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * New feature, hexadecimal Unicode, suggested by iNOUE Koich! + and Akira Kakuto is implemented. + +2003-03-13 Jin-Hwan Cho + + * Fixed bugs on reading and writing OpenType fonts. + +2003-03-12 Jin-Hwan Cho + + * Applied changes for MiKTeX in ps_include() (psimage.c). + +2003-03-11 Jin-Hwan Cho + + * Fixed a bug in cff_charsets_lookup() (cff.c). + +2003-02-06 Jin-Hwan Cho + + * Fixed a bug in string_mode() (pdfdev.c) reported by iNOUE Koich!. + +2002-12-30 Jin-Hwan Cho + + * Fixed a bug in writing null array. + + * Fixed a bug in reading CMap and encoding files in MiKTeX. + +2002-11-28 Jin-Hwan Cho + + * Support color shading feature in ConTeXt. + +2002-11-25 Jin-Hwan Cho + + * 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 + + * 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 + + * Fixed a bug in finding files with the kpathsea library 3.3.7. + +2002-10-28 Jin-Hwan Cho + + * 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 + + * 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 + + * 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 + + * 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 + + * Duplication is allowed for named_references[]. (pdfspecial.c) + +2002-06-05 Jin-Hwan Cho + + * Fixed a bug in parse_key_val() found by Yasuhiro Okazaki. + +2002-05-31 Jin-Hwan Cho + + * 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 + + * Support CJK characters in PDF outlines(bookmarks), docinfo, and + text annotations (contributed by Akira Kakuto). + +2002-05-15 Jin-Hwan Cho + + * PDF encryption support with the OpenSSL library. + +2002-04-30 Jin-Hwan Cho + + * ToUnicode CMap (only Unicode) support for Identity-H(V). + + * Included the ToUnicode CMap, Adobe-Identity-UCS2. + +2002-04-22 Jin-Hwan Cho + + * Included two CMaps, UniKSCms-UCS2-H(V) which fix a bug in + UniKS-UCS-H(V). + +2002-04-17 Jin-Hwan Cho + + * Changed xxx_set_debug() to #ifdef DEBUG. + +2002-04-16 Jin-Hwan Cho + + * 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 + + * Minor fix on 'source/pkfont.c'. + +2002-04-07 Jin-Hwan Cho + + * Fixed all warning messages generated with MSVC++. + + * Rewrote the functions 'xxx_locate_font()' again. + +2002-04-04 Jin-Hwan Cho + + * Changed the order of loading virtual and physical fonts as + suggested by Akira Kakuto . + If map entries are found, virtual fonts will not be used anymore. + +2002-04-02 Jin-Hwan Cho + + * Implemented no-embedding and stylistic variants for CIDFontType0. + +2002-03-31 Jin-Hwan Cho + + * Added two CMaps, ETenms-B5-H and ETenms-B5-V. + +2002-03-30 Shunsaku Hirata + + * Minor fix on the patch by Takanori Uchiyama. + +2002-03-29 Jin-Hwan Cho + + * Applied the patch by Takanori Uchiyama , + 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 + + * Applied the patch by Jungshik Shin, not embedding the unnecessary + character /.notdef in type1 fonts. + +2002-03-20 Shunsaku Hirata + + * Modified cid_basefont.h. + +2002-03-05 Jin-Hwan Cho + + * Support for UTF8 encoding through Identity CMap. + +2002-02-25 Jin-Hwan Cho + + * Implemented no-embedding feature for CIDFontType2. + + * Implemented Bold, Italic, BoldItalic attributes for CIDFontType2 + and CID predefined fonts. + +2002-02-22 Jin-Hwan Cho + + * Implemented subfont approach for CJK and HLaTeX. + +2002-01-07 Shunsaku Hirata + + * Fixed bug introduced on 2002-01-05. + +2002-01-05 Shunsaku Hirata + + * Workaround for some bad TrueType fonts that does not have US-English + PostScript font name. + +2001-12-27 Shunsaku Hirata + + * Changed to parse all charstrings. Check for the SEAC character. + + * Minor changes in CFF related codes. + +2001-12-26 Shunsaku Hirata + + * Merged cmap and cmap_parse. + +2001-12-25 Shunsaku Hirata + + * Cleaned up TrueType and CFF related codes. + + * Minor bug fixes. + +2001-12-23 Shunsaku Hirata + + * Fixed bug that always requires Private DICT(s) which may not exist. + + * Cleaned up TrueType and CFF related things. + +2001-12-18 Shunsaku Hirata + + * Biased subroutine number is signed in cs_type2.c. + +2001-12-14 Shunsaku Hirata + + * macglyphs.h regenerated from apple's TTRefMan. + +2001-12-13 Shunsaku Hirata + + * 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 + + * 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 + + * Bug fixes. + +2001-12-05 Shunsaku Hirata + + * 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 + + * Fixes. + +2001-12-03 Shunsaku Hirata + + * Minor charnges, cleanups. + + * Write CIDSet. + +2001-12-02 Shunsaku Hirata + + * Initial CFF CID-Keyed Font support. + Only Type 2 charstring is supported. + +2001-11-27 Shunsaku Hirata + + * Minor fixes, cleanups. + +2001-11-26 Shunsaku Hirata + + * 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 + + * Bug fix. + +2001-11-24 Shunsaku Hirata + + * Added missing free() (RELEASE) in cidtype2.c. + + * Minor fixes. + + * Fixed typos. + +2001-11-22 Shunsaku Hirata + + * Clean up. + + * Allow `Preview & Print' licensed fonts to be embedded. + TrueType OS/2 table is preserved. + +2001-11-20 Shunsaku Hirata + + * 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 + + * 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 + + * 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 + + * Bug fixes. + +2001-11-12 Shunsaku Hirata + + * (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 + + * Should return -1 when encoding_id >= 0 in type0_font(). + +2001-08-08 Shunsaku Hirata + + * Fixed a bug that raster images show up incorrectly in vertical + writing mode. + +2001-08-07 Shunsaku Hirata + + * 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 + + * Fixed a bug that do not reset text state in vertical writing. + +2001-07-20 Shunsaku Hirata + + * Fixed wrong positioning for slanted non-CJK font in vertical writing. + +2001-07-19 Shunsaku Hirata + + * Support OS/2 table version 0x0002. + +2001-07-17 Shunsaku Hirata + + * 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 + + * 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 + + * Minor fixes. + + * Updated out2uni.c + +2001-06-30 Shunsaku Hirata + + * --> dvipdfm-0.13.2c + +2001-06-29 Shunsaku Hirata + + * Fixed a bug that select incorrect indexToLocaFormat + (cidtype2.c). + + * Fixed several bugs in cidtype2.c. + +2001-06-27 Shunsaku Hirata + + * Added support for CJK-TrueType font embedding. + + * Cleaned up Type0 and CID font handling code. diff --git a/Build/source/texk/dvipdf-x/INSTALL b/Build/source/texk/dvipdf-x/INSTALL new file mode 100644 index 00000000000..b42a17ac464 --- /dev/null +++ b/Build/source/texk/dvipdf-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/dvipdf-x/Makefile.am b/Build/source/texk/dvipdf-x/Makefile.am new file mode 100644 index 00000000000..912596679fc --- /dev/null +++ b/Build/source/texk/dvipdf-x/Makefile.am @@ -0,0 +1,329 @@ +## Makefile.am for the TeX Live subdirectory texk/dvipdf-x/ +## +## Copyright (C) 2009-2013 Peter Breitenlohner +## You may freely use, modify and/or distribute this file. +## +ACLOCAL_AMFLAGS = -I ../../m4 + +SUBDIRS = data +bin_PROGRAMS = +bin_links = + +if DVIPDFMX +SUBDIRS += man +bin_PROGRAMS += dvipdfmx +if WIN32 +noinst_PROGRAMS = call_dvipdfmx +else !WIN32 +dist_bin_SCRIPTS = dvipdft +endif !WIN32 +bin_links += \ + dvipdfmx$(EXEEXT):dvipdfm \ + dvipdfmx$(EXEEXT):ebb \ + dvipdfmx$(EXEEXT):extractbb +endif DVIPDFMX + +if XDVIPDFMX +bin_PROGRAMS += xdvipdfmx +endif XDVIPDFMX +EXTRA_PROGRAMS = dvipdfmx xdvipdfmx + +AM_CPPFLAGS = $(KPATHSEA_INCLUDES) $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) +dvipdfmx_CPPFLAGS = -I$(srcdir)/src $(AM_CPPFLAGS) +xdvipdfmx_CPPFLAGS = -DXETEX -I$(srcdir)/xsrc $(FREETYPE2_INCLUDES) $(AM_CPPFLAGS) +AM_CFLAGS = $(WARNING_CFLAGS) + +nodist_dvipdfmx_SOURCES = $(common_sources) $(dvipdfmx_sources) +nodist_xdvipdfmx_SOURCES = $(common_sources) $(xdvipdfmx_sources) + +dvipdfmx_LDADD = $(KPATHSEA_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) +xdvipdfmx_LDADD = $(FREETYPE2_LIBS) $(dvipdfmx_LDADD) + +$(dvipdfmx_OBJECTS): config.force +$(xdvipdfmx_OBJECTS): config.force $(FREETYPE2_DEPEND) + +common_sources = \ + agl.c \ + agl.h \ + bmpimage.h \ + cff_dict.h \ + cff_limits.h \ + cff_stdstr.h \ + cff_types.h \ + cid.c \ + cid.h \ + cid_basefont.h \ + cid_p.h \ + cidtype0.h \ + 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 \ + dvicodes.h \ + mem.c \ + mem.h \ + mfileio.c \ + mfileio.h \ + mpost.h \ + numbers.c \ + numbers.h \ + otl_conf.c \ + otl_conf.h \ + otl_opt.c \ + otl_opt.h \ + pdfencoding.c \ + pdfencoding.h \ + pdfencrypt.h \ + pdffont.c \ + pdffont.h \ + pdflimits.h \ + pdfparse.h \ + pdfresource.c \ + pdfresource.h \ + pkfont.c \ + pkfont.h \ + pst.c \ + pst.h \ + pst_obj.c \ + pst_obj.h \ + sfnt.h \ + spc_color.h \ + spc_dvips.h \ + spc_html.h \ + spc_misc.c \ + spc_misc.h \ + spc_pdfm.h \ + spc_tpic.h \ + specials.h \ + subfont.c \ + subfont.h \ + system.h \ + t1_char.c \ + t1_char.h \ + t1_load.c \ + t1_load.h \ + tfm.h \ + truetype.h \ + tt_glyf.h \ + tt_gsub.c \ + tt_gsub.h \ + tt_post.h \ + tt_table.h \ + type1.h \ + type1c.h \ + unicode.c \ + unicode.h \ + vf.h + +dvipdfmx_sources = \ + src/bmpimage.c \ + src/cff.c \ + src/cff.h \ + src/cff_dict.c \ + src/cidtype0.c \ + src/cidtype2.c \ + src/dpxfile.c \ + src/dpxfile.h \ + src/dpxutil.c \ + src/dpxutil.h \ + src/dvi.c \ + src/dvi.h \ + src/dvipdfmx.c \ + dvipdfmx.h \ + src/epdf.c \ + src/epdf.h \ + src/error.c \ + src/error.h \ + src/fontmap.c \ + src/fontmap.h \ + src/jpegimage.c \ + src/jpegimage.h \ + src/mpost.c \ + src/pdfcolor.c \ + src/pdfcolor.h \ + src/pdfdev.c \ + src/pdfdev.h \ + src/pdfdoc.c \ + src/pdfdoc.h \ + src/pdfdraw.c \ + src/pdfdraw.h \ + src/pdfencrypt.c \ + src/pdfnames.c \ + src/pdfnames.h \ + src/pdfobj.c \ + src/pdfobj.h \ + src/pdfparse.c \ + src/pdfximage.c \ + src/pdfximage.h \ + src/pngimage.c \ + src/pngimage.h \ + src/sfnt.c \ + src/spc_color.c \ + src/spc_dvips.c \ + src/spc_html.c \ + src/spc_pdfm.c \ + src/spc_tpic.c \ + src/spc_util.c \ + src/spc_util.h \ + src/specials.c \ + src/tfm.c \ + src/truetype.c \ + src/tt_aux.c \ + src/tt_aux.h \ + src/tt_cmap.c \ + src/tt_cmap.h \ + src/tt_glyf.c \ + src/tt_post.c \ + src/tt_table.c \ + src/type0.c \ + src/type0.h \ + src/type1.c \ + src/type1c.c \ + src/vf.c \ + src/xbb.c \ + src/xbb.h + +xdvipdfmx_sources = \ + xsrc/bmpimage.c \ + xsrc/cff.c \ + xsrc/cff.h \ + xsrc/cff_dict.c \ + xsrc/cidtype0.c \ + xsrc/cidtype2.c \ + xsrc/dpxfile.c \ + xsrc/dpxfile.h \ + xsrc/dpxutil.c \ + xsrc/dpxutil.h \ + xsrc/dvi.c \ + xsrc/dvi.h \ + xsrc/dvipdfmx.c \ + xsrc/epdf.c \ + xsrc/epdf.h \ + xsrc/error.c \ + xsrc/error.h \ + xsrc/fontmap.c \ + xsrc/fontmap.h \ + xsrc/jpegimage.c \ + xsrc/jpegimage.h \ + xsrc/mpost.c \ + xsrc/pdfcolor.c \ + xsrc/pdfcolor.h \ + xsrc/pdfdev.c \ + xsrc/pdfdev.h \ + xsrc/pdfdoc.c \ + xsrc/pdfdoc.h \ + xsrc/pdfdraw.c \ + xsrc/pdfdraw.h \ + xsrc/pdfencrypt.c \ + xsrc/pdfnames.c \ + xsrc/pdfnames.h \ + xsrc/pdfobj.c \ + xsrc/pdfobj.h \ + xsrc/pdfparse.c \ + xsrc/pdfximage.c \ + xsrc/pdfximage.h \ + xsrc/pngimage.c \ + xsrc/pngimage.h \ + xsrc/sfnt.c \ + xsrc/spc_color.c \ + xsrc/spc_dvips.c \ + xsrc/spc_html.c \ + xsrc/spc_pdfm.c \ + xsrc/spc_tpic.c \ + xsrc/spc_util.c \ + xsrc/spc_util.h \ + spc_xtx.c \ + spc_xtx.h \ + xsrc/specials.c \ + xsrc/tfm.c \ + xsrc/truetype.c \ + xsrc/tt_aux.c \ + xsrc/tt_aux.h \ + xsrc/tt_cmap.c \ + xsrc/tt_cmap.h \ + xsrc/tt_glyf.c \ + xsrc/tt_post.c \ + xsrc/tt_table.c \ + xsrc/type0.c \ + xsrc/type0.h \ + xsrc/type1.c \ + xsrc/type1c.c \ + xsrc/vf.c \ + xsrc/xbb.c \ + xsrc/xbb.h + +EXTRA_DIST = $(common_sources) $(dvipdfmx_sources) $(xdvipdfmx_sources) + +call_dvipdfmx_CPPFLAGS = -DEXEPROG=\"dvipdfmx.exe\" +nodist_call_dvipdfmx_SOURCES = callexe.c + +include $(top_srcdir)/../../am/bin_links.am + +install-exec-hook: install-bin-links +if DVIPDFMX +if WIN32 + $(INSTALL_PROGRAM) call_dvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT) + $(INSTALL_PROGRAM) call_dvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/ebb$(EXEEXT) + $(INSTALL_PROGRAM) call_dvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/extractbb$(EXEEXT) +endif WIN32 +endif DVIPDFMX + +uninstall-hook: uninstall-bin-links +if DVIPDFMX +if WIN32 + rm -f $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT) + rm -f $(DESTDIR)$(bindir)/ebb$(EXEEXT) + rm -f $(DESTDIR)$(bindir)/extractbb$(EXEEXT) +endif WIN32 +endif DVIPDFMX + +all-local: config.force + +config.force: $(ZLIB_DEPEND) $(LIBPNG_DEPEND) $(KPATHSEA_DEPEND) $(FREETYPE2_DEPEND) + echo timestamp >config.force + $(SHELL) ./config.status --recheck + +DISTCLEANFILES = config.force + +## Rebuild libkpathsea +@KPATHSEA_RULE@ +## Rebuild libfreetype +@FREETYPE2_RULE@ +## Rebuild libpng +@LIBPNG_RULE@ +## Rebuild libz +@ZLIB_RULE@ + +## Tests +## +TESTS = +dvipdfmx_tests = dvipdfmx.test dvipdfm-ann.test +if DVIPDFMX +TESTS += $(dvipdfmx_tests) +endif DVIPDFMX +xdvipdfmx_tests = xdvipdfmx.test xdvipdfm-ann.test +if XDVIPDFMX +TESTS += $(xdvipdfmx_tests) +endif XDVIPDFMX +EXTRA_DIST += $(dvipdfmx_tests) $(xdvipdfmx_tests) +## +## FIXME +XFAIL_TESTS = dvipdfm-ann.test +## Test Data +## +EXTRA_DIST += tests/dvipdfmx.cfg tests/psfonts.map +EXTRA_DIST += tests/image.jpeg tests/image.pdf tests/image.png +EXTRA_DIST += tests/image.dvi tests/image.tex +EXTRA_DIST += tests/cmr10.pfb tests/cmr10.tfm tests/grahn.dvi tests/grahn.tex +DISTCLEANFILES += img*.* pic*.* image*.pdf grahn*.pdf + diff --git a/Build/source/texk/dvipdf-x/Makefile.in b/Build/source/texk/dvipdf-x/Makefile.in new file mode 100644 index 00000000000..0fe5d4e93c5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/Makefile.in @@ -0,0 +1,4084 @@ +# Makefile.in generated by automake 1.14 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +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 = $(am__EXEEXT_1) $(am__EXEEXT_2) +@DVIPDFMX_TRUE@am__append_1 = man +@DVIPDFMX_TRUE@am__append_2 = dvipdfmx +@DVIPDFMX_TRUE@@WIN32_TRUE@noinst_PROGRAMS = call_dvipdfmx$(EXEEXT) +@DVIPDFMX_TRUE@am__append_3 = \ +@DVIPDFMX_TRUE@ dvipdfmx$(EXEEXT):dvipdfm \ +@DVIPDFMX_TRUE@ dvipdfmx$(EXEEXT):ebb \ +@DVIPDFMX_TRUE@ dvipdfmx$(EXEEXT):extractbb + +@XDVIPDFMX_TRUE@am__append_4 = xdvipdfmx +EXTRA_PROGRAMS = dvipdfmx$(EXEEXT) xdvipdfmx$(EXEEXT) +DIST_COMMON = $(top_srcdir)/../../am/bin_links.am \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in \ + $(top_srcdir)/../texlive/w32_wrapper/callexe.c \ + $(am__dist_bin_SCRIPTS_DIST) \ + $(top_srcdir)/../../build-aux/depcomp \ + $(top_srcdir)/../../build-aux/test-driver AUTHORS COPYING \ + ChangeLog INSTALL README ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/missing ../../build-aux/texinfo.tex \ + ../../build-aux/ylwrap ../../build-aux/ltmain.sh \ + $(top_srcdir)/../../build-aux/compile \ + $(top_srcdir)/../../build-aux/config.guess \ + $(top_srcdir)/../../build-aux/config.sub \ + $(top_srcdir)/../../build-aux/install-sh \ + $(top_srcdir)/../../build-aux/ltmain.sh \ + $(top_srcdir)/../../build-aux/missing +@DVIPDFMX_TRUE@am__append_5 = $(dvipdfmx_tests) +@XDVIPDFMX_TRUE@am__append_6 = $(xdvipdfmx_tests) +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../m4/cho-libs.m4 \ + $(top_srcdir)/../../m4/kpse-common.m4 \ + $(top_srcdir)/../../m4/kpse-freetype2-flags.m4 \ + $(top_srcdir)/../../m4/kpse-kpathsea-flags.m4 \ + $(top_srcdir)/../../m4/kpse-libpng-flags.m4 \ + $(top_srcdir)/../../m4/kpse-lt-hack.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)/ac/dvipdf-x.ac $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +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 = +@DVIPDFMX_TRUE@am__EXEEXT_1 = dvipdfmx$(EXEEXT) +@XDVIPDFMX_TRUE@am__EXEEXT_2 = xdvipdfmx$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +nodist_call_dvipdfmx_OBJECTS = call_dvipdfmx-callexe.$(OBJEXT) +call_dvipdfmx_OBJECTS = $(nodist_call_dvipdfmx_OBJECTS) +call_dvipdfmx_LDADD = $(LDADD) +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__objects_1 = dvipdfmx-agl.$(OBJEXT) dvipdfmx-cid.$(OBJEXT) \ + dvipdfmx-cmap.$(OBJEXT) dvipdfmx-cmap_read.$(OBJEXT) \ + dvipdfmx-cmap_write.$(OBJEXT) dvipdfmx-cs_type2.$(OBJEXT) \ + dvipdfmx-dpxconf.$(OBJEXT) dvipdfmx-dpxcrypt.$(OBJEXT) \ + dvipdfmx-mem.$(OBJEXT) dvipdfmx-mfileio.$(OBJEXT) \ + dvipdfmx-numbers.$(OBJEXT) dvipdfmx-otl_conf.$(OBJEXT) \ + dvipdfmx-otl_opt.$(OBJEXT) dvipdfmx-pdfencoding.$(OBJEXT) \ + dvipdfmx-pdffont.$(OBJEXT) dvipdfmx-pdfresource.$(OBJEXT) \ + dvipdfmx-pkfont.$(OBJEXT) dvipdfmx-pst.$(OBJEXT) \ + dvipdfmx-pst_obj.$(OBJEXT) dvipdfmx-spc_misc.$(OBJEXT) \ + dvipdfmx-subfont.$(OBJEXT) dvipdfmx-t1_char.$(OBJEXT) \ + dvipdfmx-t1_load.$(OBJEXT) dvipdfmx-tt_gsub.$(OBJEXT) \ + dvipdfmx-unicode.$(OBJEXT) +am__dirstamp = $(am__leading_dot)dirstamp +am__objects_2 = src/dvipdfmx-bmpimage.$(OBJEXT) \ + src/dvipdfmx-cff.$(OBJEXT) src/dvipdfmx-cff_dict.$(OBJEXT) \ + src/dvipdfmx-cidtype0.$(OBJEXT) \ + src/dvipdfmx-cidtype2.$(OBJEXT) src/dvipdfmx-dpxfile.$(OBJEXT) \ + src/dvipdfmx-dpxutil.$(OBJEXT) src/dvipdfmx-dvi.$(OBJEXT) \ + src/dvipdfmx-dvipdfmx.$(OBJEXT) src/dvipdfmx-epdf.$(OBJEXT) \ + src/dvipdfmx-error.$(OBJEXT) src/dvipdfmx-fontmap.$(OBJEXT) \ + src/dvipdfmx-jpegimage.$(OBJEXT) src/dvipdfmx-mpost.$(OBJEXT) \ + src/dvipdfmx-pdfcolor.$(OBJEXT) src/dvipdfmx-pdfdev.$(OBJEXT) \ + src/dvipdfmx-pdfdoc.$(OBJEXT) src/dvipdfmx-pdfdraw.$(OBJEXT) \ + src/dvipdfmx-pdfencrypt.$(OBJEXT) \ + src/dvipdfmx-pdfnames.$(OBJEXT) src/dvipdfmx-pdfobj.$(OBJEXT) \ + src/dvipdfmx-pdfparse.$(OBJEXT) \ + src/dvipdfmx-pdfximage.$(OBJEXT) \ + src/dvipdfmx-pngimage.$(OBJEXT) src/dvipdfmx-sfnt.$(OBJEXT) \ + src/dvipdfmx-spc_color.$(OBJEXT) \ + src/dvipdfmx-spc_dvips.$(OBJEXT) \ + src/dvipdfmx-spc_html.$(OBJEXT) \ + src/dvipdfmx-spc_pdfm.$(OBJEXT) \ + src/dvipdfmx-spc_tpic.$(OBJEXT) \ + src/dvipdfmx-spc_util.$(OBJEXT) \ + src/dvipdfmx-specials.$(OBJEXT) src/dvipdfmx-tfm.$(OBJEXT) \ + src/dvipdfmx-truetype.$(OBJEXT) src/dvipdfmx-tt_aux.$(OBJEXT) \ + src/dvipdfmx-tt_cmap.$(OBJEXT) src/dvipdfmx-tt_glyf.$(OBJEXT) \ + src/dvipdfmx-tt_post.$(OBJEXT) src/dvipdfmx-tt_table.$(OBJEXT) \ + src/dvipdfmx-type0.$(OBJEXT) src/dvipdfmx-type1.$(OBJEXT) \ + src/dvipdfmx-type1c.$(OBJEXT) src/dvipdfmx-vf.$(OBJEXT) \ + src/dvipdfmx-xbb.$(OBJEXT) +nodist_dvipdfmx_OBJECTS = $(am__objects_1) $(am__objects_2) +dvipdfmx_OBJECTS = $(nodist_dvipdfmx_OBJECTS) +am__DEPENDENCIES_1 = +dvipdfmx_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_3 = xdvipdfmx-agl.$(OBJEXT) xdvipdfmx-cid.$(OBJEXT) \ + xdvipdfmx-cmap.$(OBJEXT) xdvipdfmx-cmap_read.$(OBJEXT) \ + xdvipdfmx-cmap_write.$(OBJEXT) xdvipdfmx-cs_type2.$(OBJEXT) \ + xdvipdfmx-dpxconf.$(OBJEXT) xdvipdfmx-dpxcrypt.$(OBJEXT) \ + xdvipdfmx-mem.$(OBJEXT) xdvipdfmx-mfileio.$(OBJEXT) \ + xdvipdfmx-numbers.$(OBJEXT) xdvipdfmx-otl_conf.$(OBJEXT) \ + xdvipdfmx-otl_opt.$(OBJEXT) xdvipdfmx-pdfencoding.$(OBJEXT) \ + xdvipdfmx-pdffont.$(OBJEXT) xdvipdfmx-pdfresource.$(OBJEXT) \ + xdvipdfmx-pkfont.$(OBJEXT) xdvipdfmx-pst.$(OBJEXT) \ + xdvipdfmx-pst_obj.$(OBJEXT) xdvipdfmx-spc_misc.$(OBJEXT) \ + xdvipdfmx-subfont.$(OBJEXT) xdvipdfmx-t1_char.$(OBJEXT) \ + xdvipdfmx-t1_load.$(OBJEXT) xdvipdfmx-tt_gsub.$(OBJEXT) \ + xdvipdfmx-unicode.$(OBJEXT) +am__objects_4 = xsrc/xdvipdfmx-bmpimage.$(OBJEXT) \ + xsrc/xdvipdfmx-cff.$(OBJEXT) xsrc/xdvipdfmx-cff_dict.$(OBJEXT) \ + xsrc/xdvipdfmx-cidtype0.$(OBJEXT) \ + xsrc/xdvipdfmx-cidtype2.$(OBJEXT) \ + xsrc/xdvipdfmx-dpxfile.$(OBJEXT) \ + xsrc/xdvipdfmx-dpxutil.$(OBJEXT) xsrc/xdvipdfmx-dvi.$(OBJEXT) \ + xsrc/xdvipdfmx-dvipdfmx.$(OBJEXT) \ + xsrc/xdvipdfmx-epdf.$(OBJEXT) xsrc/xdvipdfmx-error.$(OBJEXT) \ + xsrc/xdvipdfmx-fontmap.$(OBJEXT) \ + xsrc/xdvipdfmx-jpegimage.$(OBJEXT) \ + xsrc/xdvipdfmx-mpost.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfcolor.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfdev.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfdoc.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfdraw.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfencrypt.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfnames.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfobj.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfparse.$(OBJEXT) \ + xsrc/xdvipdfmx-pdfximage.$(OBJEXT) \ + xsrc/xdvipdfmx-pngimage.$(OBJEXT) \ + xsrc/xdvipdfmx-sfnt.$(OBJEXT) \ + xsrc/xdvipdfmx-spc_color.$(OBJEXT) \ + xsrc/xdvipdfmx-spc_dvips.$(OBJEXT) \ + xsrc/xdvipdfmx-spc_html.$(OBJEXT) \ + xsrc/xdvipdfmx-spc_pdfm.$(OBJEXT) \ + xsrc/xdvipdfmx-spc_tpic.$(OBJEXT) \ + xsrc/xdvipdfmx-spc_util.$(OBJEXT) xdvipdfmx-spc_xtx.$(OBJEXT) \ + xsrc/xdvipdfmx-specials.$(OBJEXT) xsrc/xdvipdfmx-tfm.$(OBJEXT) \ + xsrc/xdvipdfmx-truetype.$(OBJEXT) \ + xsrc/xdvipdfmx-tt_aux.$(OBJEXT) \ + xsrc/xdvipdfmx-tt_cmap.$(OBJEXT) \ + xsrc/xdvipdfmx-tt_glyf.$(OBJEXT) \ + xsrc/xdvipdfmx-tt_post.$(OBJEXT) \ + xsrc/xdvipdfmx-tt_table.$(OBJEXT) \ + xsrc/xdvipdfmx-type0.$(OBJEXT) xsrc/xdvipdfmx-type1.$(OBJEXT) \ + xsrc/xdvipdfmx-type1c.$(OBJEXT) xsrc/xdvipdfmx-vf.$(OBJEXT) \ + xsrc/xdvipdfmx-xbb.$(OBJEXT) +nodist_xdvipdfmx_OBJECTS = $(am__objects_3) $(am__objects_4) +xdvipdfmx_OBJECTS = $(nodist_xdvipdfmx_OBJECTS) +am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +xdvipdfmx_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +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__depfiles_maybe = depfiles +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_dvipdfmx_SOURCES) $(nodist_dvipdfmx_SOURCES) \ + $(nodist_xdvipdfmx_SOURCES) +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope check recheck distdir dist dist-all distcheck +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__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` +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 +DIST_SUBDIRS = data man +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) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +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@ +FREETYPE2_DEPEND = @FREETYPE2_DEPEND@ +FREETYPE2_INCLUDES = @FREETYPE2_INCLUDES@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +FT2_CONFIG = @FT2_CONFIG@ +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@ +LIBPNG_DEPEND = @LIBPNG_DEPEND@ +LIBPNG_INCLUDES = @LIBPNG_INCLUDES@ +LIBPNG_LIBS = @LIBPNG_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +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@ +ACLOCAL_AMFLAGS = -I ../../m4 +SUBDIRS = data $(am__append_1) +bin_links = $(am__append_3) +@DVIPDFMX_TRUE@@WIN32_FALSE@dist_bin_SCRIPTS = dvipdft +AM_CPPFLAGS = $(KPATHSEA_INCLUDES) $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) +dvipdfmx_CPPFLAGS = -I$(srcdir)/src $(AM_CPPFLAGS) +xdvipdfmx_CPPFLAGS = -DXETEX -I$(srcdir)/xsrc $(FREETYPE2_INCLUDES) $(AM_CPPFLAGS) +AM_CFLAGS = $(WARNING_CFLAGS) +nodist_dvipdfmx_SOURCES = $(common_sources) $(dvipdfmx_sources) +nodist_xdvipdfmx_SOURCES = $(common_sources) $(xdvipdfmx_sources) +dvipdfmx_LDADD = $(KPATHSEA_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) +xdvipdfmx_LDADD = $(FREETYPE2_LIBS) $(dvipdfmx_LDADD) +common_sources = \ + agl.c \ + agl.h \ + bmpimage.h \ + cff_dict.h \ + cff_limits.h \ + cff_stdstr.h \ + cff_types.h \ + cid.c \ + cid.h \ + cid_basefont.h \ + cid_p.h \ + cidtype0.h \ + 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 \ + dvicodes.h \ + mem.c \ + mem.h \ + mfileio.c \ + mfileio.h \ + mpost.h \ + numbers.c \ + numbers.h \ + otl_conf.c \ + otl_conf.h \ + otl_opt.c \ + otl_opt.h \ + pdfencoding.c \ + pdfencoding.h \ + pdfencrypt.h \ + pdffont.c \ + pdffont.h \ + pdflimits.h \ + pdfparse.h \ + pdfresource.c \ + pdfresource.h \ + pkfont.c \ + pkfont.h \ + pst.c \ + pst.h \ + pst_obj.c \ + pst_obj.h \ + sfnt.h \ + spc_color.h \ + spc_dvips.h \ + spc_html.h \ + spc_misc.c \ + spc_misc.h \ + spc_pdfm.h \ + spc_tpic.h \ + specials.h \ + subfont.c \ + subfont.h \ + system.h \ + t1_char.c \ + t1_char.h \ + t1_load.c \ + t1_load.h \ + tfm.h \ + truetype.h \ + tt_glyf.h \ + tt_gsub.c \ + tt_gsub.h \ + tt_post.h \ + tt_table.h \ + type1.h \ + type1c.h \ + unicode.c \ + unicode.h \ + vf.h + +dvipdfmx_sources = \ + src/bmpimage.c \ + src/cff.c \ + src/cff.h \ + src/cff_dict.c \ + src/cidtype0.c \ + src/cidtype2.c \ + src/dpxfile.c \ + src/dpxfile.h \ + src/dpxutil.c \ + src/dpxutil.h \ + src/dvi.c \ + src/dvi.h \ + src/dvipdfmx.c \ + dvipdfmx.h \ + src/epdf.c \ + src/epdf.h \ + src/error.c \ + src/error.h \ + src/fontmap.c \ + src/fontmap.h \ + src/jpegimage.c \ + src/jpegimage.h \ + src/mpost.c \ + src/pdfcolor.c \ + src/pdfcolor.h \ + src/pdfdev.c \ + src/pdfdev.h \ + src/pdfdoc.c \ + src/pdfdoc.h \ + src/pdfdraw.c \ + src/pdfdraw.h \ + src/pdfencrypt.c \ + src/pdfnames.c \ + src/pdfnames.h \ + src/pdfobj.c \ + src/pdfobj.h \ + src/pdfparse.c \ + src/pdfximage.c \ + src/pdfximage.h \ + src/pngimage.c \ + src/pngimage.h \ + src/sfnt.c \ + src/spc_color.c \ + src/spc_dvips.c \ + src/spc_html.c \ + src/spc_pdfm.c \ + src/spc_tpic.c \ + src/spc_util.c \ + src/spc_util.h \ + src/specials.c \ + src/tfm.c \ + src/truetype.c \ + src/tt_aux.c \ + src/tt_aux.h \ + src/tt_cmap.c \ + src/tt_cmap.h \ + src/tt_glyf.c \ + src/tt_post.c \ + src/tt_table.c \ + src/type0.c \ + src/type0.h \ + src/type1.c \ + src/type1c.c \ + src/vf.c \ + src/xbb.c \ + src/xbb.h + +xdvipdfmx_sources = \ + xsrc/bmpimage.c \ + xsrc/cff.c \ + xsrc/cff.h \ + xsrc/cff_dict.c \ + xsrc/cidtype0.c \ + xsrc/cidtype2.c \ + xsrc/dpxfile.c \ + xsrc/dpxfile.h \ + xsrc/dpxutil.c \ + xsrc/dpxutil.h \ + xsrc/dvi.c \ + xsrc/dvi.h \ + xsrc/dvipdfmx.c \ + xsrc/epdf.c \ + xsrc/epdf.h \ + xsrc/error.c \ + xsrc/error.h \ + xsrc/fontmap.c \ + xsrc/fontmap.h \ + xsrc/jpegimage.c \ + xsrc/jpegimage.h \ + xsrc/mpost.c \ + xsrc/pdfcolor.c \ + xsrc/pdfcolor.h \ + xsrc/pdfdev.c \ + xsrc/pdfdev.h \ + xsrc/pdfdoc.c \ + xsrc/pdfdoc.h \ + xsrc/pdfdraw.c \ + xsrc/pdfdraw.h \ + xsrc/pdfencrypt.c \ + xsrc/pdfnames.c \ + xsrc/pdfnames.h \ + xsrc/pdfobj.c \ + xsrc/pdfobj.h \ + xsrc/pdfparse.c \ + xsrc/pdfximage.c \ + xsrc/pdfximage.h \ + xsrc/pngimage.c \ + xsrc/pngimage.h \ + xsrc/sfnt.c \ + xsrc/spc_color.c \ + xsrc/spc_dvips.c \ + xsrc/spc_html.c \ + xsrc/spc_pdfm.c \ + xsrc/spc_tpic.c \ + xsrc/spc_util.c \ + xsrc/spc_util.h \ + spc_xtx.c \ + spc_xtx.h \ + xsrc/specials.c \ + xsrc/tfm.c \ + xsrc/truetype.c \ + xsrc/tt_aux.c \ + xsrc/tt_aux.h \ + xsrc/tt_cmap.c \ + xsrc/tt_cmap.h \ + xsrc/tt_glyf.c \ + xsrc/tt_post.c \ + xsrc/tt_table.c \ + xsrc/type0.c \ + xsrc/type0.h \ + xsrc/type1.c \ + xsrc/type1c.c \ + xsrc/vf.c \ + xsrc/xbb.c \ + xsrc/xbb.h + +EXTRA_DIST = $(common_sources) $(dvipdfmx_sources) \ + $(xdvipdfmx_sources) $(dvipdfmx_tests) $(xdvipdfmx_tests) \ + tests/dvipdfmx.cfg tests/psfonts.map tests/image.jpeg \ + tests/image.pdf tests/image.png tests/image.dvi \ + tests/image.tex tests/cmr10.pfb tests/cmr10.tfm \ + tests/grahn.dvi tests/grahn.tex +call_dvipdfmx_CPPFLAGS = -DEXEPROG=\"dvipdfmx.exe\" +nodist_call_dvipdfmx_SOURCES = callexe.c +DISTCLEANFILES = config.force img*.* pic*.* image*.pdf grahn*.pdf +TESTS = $(am__append_5) $(am__append_6) +dvipdfmx_tests = dvipdfmx.test dvipdfm-ann.test +xdvipdfmx_tests = xdvipdfmx.test xdvipdfm-ann.test +XFAIL_TESTS = dvipdfm-ann.test +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.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 $(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 +.PRECIOUS: 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__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; +$(top_srcdir)/../../am/bin_links.am: + +$(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_dvipdfmx$(EXEEXT): $(call_dvipdfmx_OBJECTS) $(call_dvipdfmx_DEPENDENCIES) $(EXTRA_call_dvipdfmx_DEPENDENCIES) + @rm -f call_dvipdfmx$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(call_dvipdfmx_OBJECTS) $(call_dvipdfmx_LDADD) $(LIBS) +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-bmpimage.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-cff.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-cff_dict.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-cidtype0.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-cidtype2.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-dpxfile.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-dpxutil.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-dvi.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-dvipdfmx.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-epdf.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-error.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-fontmap.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-jpegimage.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-mpost.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfcolor.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfdev.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfdoc.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfdraw.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfencrypt.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfnames.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfobj.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfparse.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pdfximage.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-pngimage.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-sfnt.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-spc_color.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-spc_dvips.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-spc_html.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-spc_pdfm.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-spc_tpic.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-spc_util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-specials.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-tfm.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-truetype.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-tt_aux.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-tt_cmap.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-tt_glyf.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-tt_post.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-tt_table.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-type0.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-type1.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-type1c.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-vf.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/dvipdfmx-xbb.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +dvipdfmx$(EXEEXT): $(dvipdfmx_OBJECTS) $(dvipdfmx_DEPENDENCIES) $(EXTRA_dvipdfmx_DEPENDENCIES) + @rm -f dvipdfmx$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(dvipdfmx_OBJECTS) $(dvipdfmx_LDADD) $(LIBS) +xsrc/$(am__dirstamp): + @$(MKDIR_P) xsrc + @: > xsrc/$(am__dirstamp) +xsrc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) xsrc/$(DEPDIR) + @: > xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-bmpimage.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-cff.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-cff_dict.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-cidtype0.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-cidtype2.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-dpxfile.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-dpxutil.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-dvi.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-dvipdfmx.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-epdf.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-error.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-fontmap.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-jpegimage.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-mpost.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfcolor.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfdev.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfdoc.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfdraw.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfencrypt.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfnames.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfobj.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfparse.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pdfximage.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-pngimage.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-sfnt.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-spc_color.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-spc_dvips.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-spc_html.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-spc_pdfm.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-spc_tpic.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-spc_util.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-specials.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-tfm.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-truetype.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-tt_aux.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-tt_cmap.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-tt_glyf.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-tt_post.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-tt_table.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-type0.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-type1.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-type1c.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-vf.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) +xsrc/xdvipdfmx-xbb.$(OBJEXT): xsrc/$(am__dirstamp) \ + xsrc/$(DEPDIR)/$(am__dirstamp) + +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) + -rm -f src/*.$(OBJEXT) + -rm -f xsrc/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/call_dvipdfmx-callexe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-agl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-cid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-cmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-cmap_read.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-cmap_write.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-cs_type2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-dpxconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-dpxcrypt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-mem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-mfileio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-numbers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-otl_conf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-otl_opt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-pdfencoding.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-pdffont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-pdfresource.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-pkfont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-pst.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-pst_obj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-spc_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-subfont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-t1_char.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-t1_load.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-tt_gsub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipdfmx-unicode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-agl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-cid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-cmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-cmap_read.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-cmap_write.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-cs_type2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-dpxconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-dpxcrypt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-mem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-mfileio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-numbers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-otl_conf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-otl_opt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-pdfencoding.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-pdffont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-pdfresource.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-pkfont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-pst.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-pst_obj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-spc_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-spc_xtx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-subfont.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-t1_char.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-t1_load.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-tt_gsub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-unicode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-bmpimage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-cff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-cff_dict.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-cidtype0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-cidtype2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-dpxfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-dpxutil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-dvi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-dvipdfmx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-epdf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-fontmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-jpegimage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-mpost.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfcolor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfdev.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfdoc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfdraw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfencrypt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfnames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfobj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfparse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pdfximage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-pngimage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-sfnt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-spc_color.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-spc_dvips.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-spc_html.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-spc_pdfm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-spc_tpic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-spc_util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-specials.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-tfm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-truetype.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-tt_aux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-tt_cmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-tt_glyf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-tt_post.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-tt_table.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-type0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-type1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-type1c.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-vf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dvipdfmx-xbb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-bmpimage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-cff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-cff_dict.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-cidtype0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-cidtype2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-dpxfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-dpxutil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-dvi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-dvipdfmx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-epdf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-fontmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-jpegimage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-mpost.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfcolor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfdev.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfdoc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfdraw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfencrypt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfnames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfobj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfparse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pdfximage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-pngimage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-sfnt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-spc_color.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-spc_dvips.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-spc_html.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-spc_pdfm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-spc_tpic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-spc_util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-specials.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-tfm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-truetype.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-tt_aux.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-tt_cmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-tt_glyf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-tt_post.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-tt_table.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-type0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-type1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-type1c.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-vf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@xsrc/$(DEPDIR)/xdvipdfmx-xbb.Po@am__quote@ + +.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_dvipdfmx-callexe.o: callexe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(call_dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT call_dvipdfmx-callexe.o -MD -MP -MF $(DEPDIR)/call_dvipdfmx-callexe.Tpo -c -o call_dvipdfmx-callexe.o `test -f 'callexe.c' || echo '$(srcdir)/'`callexe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/call_dvipdfmx-callexe.Tpo $(DEPDIR)/call_dvipdfmx-callexe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='callexe.c' object='call_dvipdfmx-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_dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o call_dvipdfmx-callexe.o `test -f 'callexe.c' || echo '$(srcdir)/'`callexe.c + +call_dvipdfmx-callexe.obj: callexe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(call_dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT call_dvipdfmx-callexe.obj -MD -MP -MF $(DEPDIR)/call_dvipdfmx-callexe.Tpo -c -o call_dvipdfmx-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_dvipdfmx-callexe.Tpo $(DEPDIR)/call_dvipdfmx-callexe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='callexe.c' object='call_dvipdfmx-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_dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o call_dvipdfmx-callexe.obj `if test -f 'callexe.c'; then $(CYGPATH_W) 'callexe.c'; else $(CYGPATH_W) '$(srcdir)/callexe.c'; fi` + +dvipdfmx-agl.o: agl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-agl.o -MD -MP -MF $(DEPDIR)/dvipdfmx-agl.Tpo -c -o dvipdfmx-agl.o `test -f 'agl.c' || echo '$(srcdir)/'`agl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-agl.Tpo $(DEPDIR)/dvipdfmx-agl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='agl.c' object='dvipdfmx-agl.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-agl.o `test -f 'agl.c' || echo '$(srcdir)/'`agl.c + +dvipdfmx-agl.obj: agl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-agl.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-agl.Tpo -c -o dvipdfmx-agl.obj `if test -f 'agl.c'; then $(CYGPATH_W) 'agl.c'; else $(CYGPATH_W) '$(srcdir)/agl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-agl.Tpo $(DEPDIR)/dvipdfmx-agl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='agl.c' object='dvipdfmx-agl.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-agl.obj `if test -f 'agl.c'; then $(CYGPATH_W) 'agl.c'; else $(CYGPATH_W) '$(srcdir)/agl.c'; fi` + +dvipdfmx-cid.o: cid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cid.o -MD -MP -MF $(DEPDIR)/dvipdfmx-cid.Tpo -c -o dvipdfmx-cid.o `test -f 'cid.c' || echo '$(srcdir)/'`cid.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cid.Tpo $(DEPDIR)/dvipdfmx-cid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cid.c' object='dvipdfmx-cid.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cid.o `test -f 'cid.c' || echo '$(srcdir)/'`cid.c + +dvipdfmx-cid.obj: cid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cid.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-cid.Tpo -c -o dvipdfmx-cid.obj `if test -f 'cid.c'; then $(CYGPATH_W) 'cid.c'; else $(CYGPATH_W) '$(srcdir)/cid.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cid.Tpo $(DEPDIR)/dvipdfmx-cid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cid.c' object='dvipdfmx-cid.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cid.obj `if test -f 'cid.c'; then $(CYGPATH_W) 'cid.c'; else $(CYGPATH_W) '$(srcdir)/cid.c'; fi` + +dvipdfmx-cmap.o: cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cmap.o -MD -MP -MF $(DEPDIR)/dvipdfmx-cmap.Tpo -c -o dvipdfmx-cmap.o `test -f 'cmap.c' || echo '$(srcdir)/'`cmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cmap.Tpo $(DEPDIR)/dvipdfmx-cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap.c' object='dvipdfmx-cmap.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cmap.o `test -f 'cmap.c' || echo '$(srcdir)/'`cmap.c + +dvipdfmx-cmap.obj: cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cmap.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-cmap.Tpo -c -o dvipdfmx-cmap.obj `if test -f 'cmap.c'; then $(CYGPATH_W) 'cmap.c'; else $(CYGPATH_W) '$(srcdir)/cmap.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cmap.Tpo $(DEPDIR)/dvipdfmx-cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap.c' object='dvipdfmx-cmap.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cmap.obj `if test -f 'cmap.c'; then $(CYGPATH_W) 'cmap.c'; else $(CYGPATH_W) '$(srcdir)/cmap.c'; fi` + +dvipdfmx-cmap_read.o: cmap_read.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cmap_read.o -MD -MP -MF $(DEPDIR)/dvipdfmx-cmap_read.Tpo -c -o dvipdfmx-cmap_read.o `test -f 'cmap_read.c' || echo '$(srcdir)/'`cmap_read.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cmap_read.Tpo $(DEPDIR)/dvipdfmx-cmap_read.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_read.c' object='dvipdfmx-cmap_read.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cmap_read.o `test -f 'cmap_read.c' || echo '$(srcdir)/'`cmap_read.c + +dvipdfmx-cmap_read.obj: cmap_read.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cmap_read.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-cmap_read.Tpo -c -o dvipdfmx-cmap_read.obj `if test -f 'cmap_read.c'; then $(CYGPATH_W) 'cmap_read.c'; else $(CYGPATH_W) '$(srcdir)/cmap_read.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cmap_read.Tpo $(DEPDIR)/dvipdfmx-cmap_read.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_read.c' object='dvipdfmx-cmap_read.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cmap_read.obj `if test -f 'cmap_read.c'; then $(CYGPATH_W) 'cmap_read.c'; else $(CYGPATH_W) '$(srcdir)/cmap_read.c'; fi` + +dvipdfmx-cmap_write.o: cmap_write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cmap_write.o -MD -MP -MF $(DEPDIR)/dvipdfmx-cmap_write.Tpo -c -o dvipdfmx-cmap_write.o `test -f 'cmap_write.c' || echo '$(srcdir)/'`cmap_write.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cmap_write.Tpo $(DEPDIR)/dvipdfmx-cmap_write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_write.c' object='dvipdfmx-cmap_write.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cmap_write.o `test -f 'cmap_write.c' || echo '$(srcdir)/'`cmap_write.c + +dvipdfmx-cmap_write.obj: cmap_write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cmap_write.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-cmap_write.Tpo -c -o dvipdfmx-cmap_write.obj `if test -f 'cmap_write.c'; then $(CYGPATH_W) 'cmap_write.c'; else $(CYGPATH_W) '$(srcdir)/cmap_write.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cmap_write.Tpo $(DEPDIR)/dvipdfmx-cmap_write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_write.c' object='dvipdfmx-cmap_write.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cmap_write.obj `if test -f 'cmap_write.c'; then $(CYGPATH_W) 'cmap_write.c'; else $(CYGPATH_W) '$(srcdir)/cmap_write.c'; fi` + +dvipdfmx-cs_type2.o: cs_type2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cs_type2.o -MD -MP -MF $(DEPDIR)/dvipdfmx-cs_type2.Tpo -c -o dvipdfmx-cs_type2.o `test -f 'cs_type2.c' || echo '$(srcdir)/'`cs_type2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cs_type2.Tpo $(DEPDIR)/dvipdfmx-cs_type2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cs_type2.c' object='dvipdfmx-cs_type2.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cs_type2.o `test -f 'cs_type2.c' || echo '$(srcdir)/'`cs_type2.c + +dvipdfmx-cs_type2.obj: cs_type2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-cs_type2.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-cs_type2.Tpo -c -o dvipdfmx-cs_type2.obj `if test -f 'cs_type2.c'; then $(CYGPATH_W) 'cs_type2.c'; else $(CYGPATH_W) '$(srcdir)/cs_type2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-cs_type2.Tpo $(DEPDIR)/dvipdfmx-cs_type2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cs_type2.c' object='dvipdfmx-cs_type2.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-cs_type2.obj `if test -f 'cs_type2.c'; then $(CYGPATH_W) 'cs_type2.c'; else $(CYGPATH_W) '$(srcdir)/cs_type2.c'; fi` + +dvipdfmx-dpxconf.o: dpxconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-dpxconf.o -MD -MP -MF $(DEPDIR)/dvipdfmx-dpxconf.Tpo -c -o dvipdfmx-dpxconf.o `test -f 'dpxconf.c' || echo '$(srcdir)/'`dpxconf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-dpxconf.Tpo $(DEPDIR)/dvipdfmx-dpxconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxconf.c' object='dvipdfmx-dpxconf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-dpxconf.o `test -f 'dpxconf.c' || echo '$(srcdir)/'`dpxconf.c + +dvipdfmx-dpxconf.obj: dpxconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-dpxconf.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-dpxconf.Tpo -c -o dvipdfmx-dpxconf.obj `if test -f 'dpxconf.c'; then $(CYGPATH_W) 'dpxconf.c'; else $(CYGPATH_W) '$(srcdir)/dpxconf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-dpxconf.Tpo $(DEPDIR)/dvipdfmx-dpxconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxconf.c' object='dvipdfmx-dpxconf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-dpxconf.obj `if test -f 'dpxconf.c'; then $(CYGPATH_W) 'dpxconf.c'; else $(CYGPATH_W) '$(srcdir)/dpxconf.c'; fi` + +dvipdfmx-dpxcrypt.o: dpxcrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-dpxcrypt.o -MD -MP -MF $(DEPDIR)/dvipdfmx-dpxcrypt.Tpo -c -o dvipdfmx-dpxcrypt.o `test -f 'dpxcrypt.c' || echo '$(srcdir)/'`dpxcrypt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-dpxcrypt.Tpo $(DEPDIR)/dvipdfmx-dpxcrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxcrypt.c' object='dvipdfmx-dpxcrypt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-dpxcrypt.o `test -f 'dpxcrypt.c' || echo '$(srcdir)/'`dpxcrypt.c + +dvipdfmx-dpxcrypt.obj: dpxcrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-dpxcrypt.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-dpxcrypt.Tpo -c -o dvipdfmx-dpxcrypt.obj `if test -f 'dpxcrypt.c'; then $(CYGPATH_W) 'dpxcrypt.c'; else $(CYGPATH_W) '$(srcdir)/dpxcrypt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-dpxcrypt.Tpo $(DEPDIR)/dvipdfmx-dpxcrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxcrypt.c' object='dvipdfmx-dpxcrypt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-dpxcrypt.obj `if test -f 'dpxcrypt.c'; then $(CYGPATH_W) 'dpxcrypt.c'; else $(CYGPATH_W) '$(srcdir)/dpxcrypt.c'; fi` + +dvipdfmx-mem.o: mem.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-mem.o -MD -MP -MF $(DEPDIR)/dvipdfmx-mem.Tpo -c -o dvipdfmx-mem.o `test -f 'mem.c' || echo '$(srcdir)/'`mem.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-mem.Tpo $(DEPDIR)/dvipdfmx-mem.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mem.c' object='dvipdfmx-mem.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-mem.o `test -f 'mem.c' || echo '$(srcdir)/'`mem.c + +dvipdfmx-mem.obj: mem.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-mem.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-mem.Tpo -c -o dvipdfmx-mem.obj `if test -f 'mem.c'; then $(CYGPATH_W) 'mem.c'; else $(CYGPATH_W) '$(srcdir)/mem.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-mem.Tpo $(DEPDIR)/dvipdfmx-mem.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mem.c' object='dvipdfmx-mem.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-mem.obj `if test -f 'mem.c'; then $(CYGPATH_W) 'mem.c'; else $(CYGPATH_W) '$(srcdir)/mem.c'; fi` + +dvipdfmx-mfileio.o: mfileio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-mfileio.o -MD -MP -MF $(DEPDIR)/dvipdfmx-mfileio.Tpo -c -o dvipdfmx-mfileio.o `test -f 'mfileio.c' || echo '$(srcdir)/'`mfileio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-mfileio.Tpo $(DEPDIR)/dvipdfmx-mfileio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mfileio.c' object='dvipdfmx-mfileio.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-mfileio.o `test -f 'mfileio.c' || echo '$(srcdir)/'`mfileio.c + +dvipdfmx-mfileio.obj: mfileio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-mfileio.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-mfileio.Tpo -c -o dvipdfmx-mfileio.obj `if test -f 'mfileio.c'; then $(CYGPATH_W) 'mfileio.c'; else $(CYGPATH_W) '$(srcdir)/mfileio.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-mfileio.Tpo $(DEPDIR)/dvipdfmx-mfileio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mfileio.c' object='dvipdfmx-mfileio.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-mfileio.obj `if test -f 'mfileio.c'; then $(CYGPATH_W) 'mfileio.c'; else $(CYGPATH_W) '$(srcdir)/mfileio.c'; fi` + +dvipdfmx-numbers.o: numbers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-numbers.o -MD -MP -MF $(DEPDIR)/dvipdfmx-numbers.Tpo -c -o dvipdfmx-numbers.o `test -f 'numbers.c' || echo '$(srcdir)/'`numbers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-numbers.Tpo $(DEPDIR)/dvipdfmx-numbers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='numbers.c' object='dvipdfmx-numbers.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-numbers.o `test -f 'numbers.c' || echo '$(srcdir)/'`numbers.c + +dvipdfmx-numbers.obj: numbers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-numbers.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-numbers.Tpo -c -o dvipdfmx-numbers.obj `if test -f 'numbers.c'; then $(CYGPATH_W) 'numbers.c'; else $(CYGPATH_W) '$(srcdir)/numbers.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-numbers.Tpo $(DEPDIR)/dvipdfmx-numbers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='numbers.c' object='dvipdfmx-numbers.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-numbers.obj `if test -f 'numbers.c'; then $(CYGPATH_W) 'numbers.c'; else $(CYGPATH_W) '$(srcdir)/numbers.c'; fi` + +dvipdfmx-otl_conf.o: otl_conf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-otl_conf.o -MD -MP -MF $(DEPDIR)/dvipdfmx-otl_conf.Tpo -c -o dvipdfmx-otl_conf.o `test -f 'otl_conf.c' || echo '$(srcdir)/'`otl_conf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-otl_conf.Tpo $(DEPDIR)/dvipdfmx-otl_conf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_conf.c' object='dvipdfmx-otl_conf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-otl_conf.o `test -f 'otl_conf.c' || echo '$(srcdir)/'`otl_conf.c + +dvipdfmx-otl_conf.obj: otl_conf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-otl_conf.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-otl_conf.Tpo -c -o dvipdfmx-otl_conf.obj `if test -f 'otl_conf.c'; then $(CYGPATH_W) 'otl_conf.c'; else $(CYGPATH_W) '$(srcdir)/otl_conf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-otl_conf.Tpo $(DEPDIR)/dvipdfmx-otl_conf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_conf.c' object='dvipdfmx-otl_conf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-otl_conf.obj `if test -f 'otl_conf.c'; then $(CYGPATH_W) 'otl_conf.c'; else $(CYGPATH_W) '$(srcdir)/otl_conf.c'; fi` + +dvipdfmx-otl_opt.o: otl_opt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-otl_opt.o -MD -MP -MF $(DEPDIR)/dvipdfmx-otl_opt.Tpo -c -o dvipdfmx-otl_opt.o `test -f 'otl_opt.c' || echo '$(srcdir)/'`otl_opt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-otl_opt.Tpo $(DEPDIR)/dvipdfmx-otl_opt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_opt.c' object='dvipdfmx-otl_opt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-otl_opt.o `test -f 'otl_opt.c' || echo '$(srcdir)/'`otl_opt.c + +dvipdfmx-otl_opt.obj: otl_opt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-otl_opt.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-otl_opt.Tpo -c -o dvipdfmx-otl_opt.obj `if test -f 'otl_opt.c'; then $(CYGPATH_W) 'otl_opt.c'; else $(CYGPATH_W) '$(srcdir)/otl_opt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-otl_opt.Tpo $(DEPDIR)/dvipdfmx-otl_opt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_opt.c' object='dvipdfmx-otl_opt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-otl_opt.obj `if test -f 'otl_opt.c'; then $(CYGPATH_W) 'otl_opt.c'; else $(CYGPATH_W) '$(srcdir)/otl_opt.c'; fi` + +dvipdfmx-pdfencoding.o: pdfencoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pdfencoding.o -MD -MP -MF $(DEPDIR)/dvipdfmx-pdfencoding.Tpo -c -o dvipdfmx-pdfencoding.o `test -f 'pdfencoding.c' || echo '$(srcdir)/'`pdfencoding.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pdfencoding.Tpo $(DEPDIR)/dvipdfmx-pdfencoding.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfencoding.c' object='dvipdfmx-pdfencoding.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pdfencoding.o `test -f 'pdfencoding.c' || echo '$(srcdir)/'`pdfencoding.c + +dvipdfmx-pdfencoding.obj: pdfencoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pdfencoding.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-pdfencoding.Tpo -c -o dvipdfmx-pdfencoding.obj `if test -f 'pdfencoding.c'; then $(CYGPATH_W) 'pdfencoding.c'; else $(CYGPATH_W) '$(srcdir)/pdfencoding.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pdfencoding.Tpo $(DEPDIR)/dvipdfmx-pdfencoding.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfencoding.c' object='dvipdfmx-pdfencoding.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pdfencoding.obj `if test -f 'pdfencoding.c'; then $(CYGPATH_W) 'pdfencoding.c'; else $(CYGPATH_W) '$(srcdir)/pdfencoding.c'; fi` + +dvipdfmx-pdffont.o: pdffont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pdffont.o -MD -MP -MF $(DEPDIR)/dvipdfmx-pdffont.Tpo -c -o dvipdfmx-pdffont.o `test -f 'pdffont.c' || echo '$(srcdir)/'`pdffont.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pdffont.Tpo $(DEPDIR)/dvipdfmx-pdffont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdffont.c' object='dvipdfmx-pdffont.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pdffont.o `test -f 'pdffont.c' || echo '$(srcdir)/'`pdffont.c + +dvipdfmx-pdffont.obj: pdffont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pdffont.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-pdffont.Tpo -c -o dvipdfmx-pdffont.obj `if test -f 'pdffont.c'; then $(CYGPATH_W) 'pdffont.c'; else $(CYGPATH_W) '$(srcdir)/pdffont.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pdffont.Tpo $(DEPDIR)/dvipdfmx-pdffont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdffont.c' object='dvipdfmx-pdffont.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pdffont.obj `if test -f 'pdffont.c'; then $(CYGPATH_W) 'pdffont.c'; else $(CYGPATH_W) '$(srcdir)/pdffont.c'; fi` + +dvipdfmx-pdfresource.o: pdfresource.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pdfresource.o -MD -MP -MF $(DEPDIR)/dvipdfmx-pdfresource.Tpo -c -o dvipdfmx-pdfresource.o `test -f 'pdfresource.c' || echo '$(srcdir)/'`pdfresource.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pdfresource.Tpo $(DEPDIR)/dvipdfmx-pdfresource.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfresource.c' object='dvipdfmx-pdfresource.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pdfresource.o `test -f 'pdfresource.c' || echo '$(srcdir)/'`pdfresource.c + +dvipdfmx-pdfresource.obj: pdfresource.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pdfresource.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-pdfresource.Tpo -c -o dvipdfmx-pdfresource.obj `if test -f 'pdfresource.c'; then $(CYGPATH_W) 'pdfresource.c'; else $(CYGPATH_W) '$(srcdir)/pdfresource.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pdfresource.Tpo $(DEPDIR)/dvipdfmx-pdfresource.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfresource.c' object='dvipdfmx-pdfresource.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pdfresource.obj `if test -f 'pdfresource.c'; then $(CYGPATH_W) 'pdfresource.c'; else $(CYGPATH_W) '$(srcdir)/pdfresource.c'; fi` + +dvipdfmx-pkfont.o: pkfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pkfont.o -MD -MP -MF $(DEPDIR)/dvipdfmx-pkfont.Tpo -c -o dvipdfmx-pkfont.o `test -f 'pkfont.c' || echo '$(srcdir)/'`pkfont.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pkfont.Tpo $(DEPDIR)/dvipdfmx-pkfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkfont.c' object='dvipdfmx-pkfont.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pkfont.o `test -f 'pkfont.c' || echo '$(srcdir)/'`pkfont.c + +dvipdfmx-pkfont.obj: pkfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pkfont.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-pkfont.Tpo -c -o dvipdfmx-pkfont.obj `if test -f 'pkfont.c'; then $(CYGPATH_W) 'pkfont.c'; else $(CYGPATH_W) '$(srcdir)/pkfont.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pkfont.Tpo $(DEPDIR)/dvipdfmx-pkfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkfont.c' object='dvipdfmx-pkfont.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pkfont.obj `if test -f 'pkfont.c'; then $(CYGPATH_W) 'pkfont.c'; else $(CYGPATH_W) '$(srcdir)/pkfont.c'; fi` + +dvipdfmx-pst.o: pst.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pst.o -MD -MP -MF $(DEPDIR)/dvipdfmx-pst.Tpo -c -o dvipdfmx-pst.o `test -f 'pst.c' || echo '$(srcdir)/'`pst.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pst.Tpo $(DEPDIR)/dvipdfmx-pst.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst.c' object='dvipdfmx-pst.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pst.o `test -f 'pst.c' || echo '$(srcdir)/'`pst.c + +dvipdfmx-pst.obj: pst.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pst.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-pst.Tpo -c -o dvipdfmx-pst.obj `if test -f 'pst.c'; then $(CYGPATH_W) 'pst.c'; else $(CYGPATH_W) '$(srcdir)/pst.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pst.Tpo $(DEPDIR)/dvipdfmx-pst.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst.c' object='dvipdfmx-pst.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pst.obj `if test -f 'pst.c'; then $(CYGPATH_W) 'pst.c'; else $(CYGPATH_W) '$(srcdir)/pst.c'; fi` + +dvipdfmx-pst_obj.o: pst_obj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pst_obj.o -MD -MP -MF $(DEPDIR)/dvipdfmx-pst_obj.Tpo -c -o dvipdfmx-pst_obj.o `test -f 'pst_obj.c' || echo '$(srcdir)/'`pst_obj.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pst_obj.Tpo $(DEPDIR)/dvipdfmx-pst_obj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst_obj.c' object='dvipdfmx-pst_obj.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pst_obj.o `test -f 'pst_obj.c' || echo '$(srcdir)/'`pst_obj.c + +dvipdfmx-pst_obj.obj: pst_obj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-pst_obj.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-pst_obj.Tpo -c -o dvipdfmx-pst_obj.obj `if test -f 'pst_obj.c'; then $(CYGPATH_W) 'pst_obj.c'; else $(CYGPATH_W) '$(srcdir)/pst_obj.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-pst_obj.Tpo $(DEPDIR)/dvipdfmx-pst_obj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst_obj.c' object='dvipdfmx-pst_obj.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-pst_obj.obj `if test -f 'pst_obj.c'; then $(CYGPATH_W) 'pst_obj.c'; else $(CYGPATH_W) '$(srcdir)/pst_obj.c'; fi` + +dvipdfmx-spc_misc.o: spc_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-spc_misc.o -MD -MP -MF $(DEPDIR)/dvipdfmx-spc_misc.Tpo -c -o dvipdfmx-spc_misc.o `test -f 'spc_misc.c' || echo '$(srcdir)/'`spc_misc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-spc_misc.Tpo $(DEPDIR)/dvipdfmx-spc_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spc_misc.c' object='dvipdfmx-spc_misc.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-spc_misc.o `test -f 'spc_misc.c' || echo '$(srcdir)/'`spc_misc.c + +dvipdfmx-spc_misc.obj: spc_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-spc_misc.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-spc_misc.Tpo -c -o dvipdfmx-spc_misc.obj `if test -f 'spc_misc.c'; then $(CYGPATH_W) 'spc_misc.c'; else $(CYGPATH_W) '$(srcdir)/spc_misc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-spc_misc.Tpo $(DEPDIR)/dvipdfmx-spc_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spc_misc.c' object='dvipdfmx-spc_misc.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-spc_misc.obj `if test -f 'spc_misc.c'; then $(CYGPATH_W) 'spc_misc.c'; else $(CYGPATH_W) '$(srcdir)/spc_misc.c'; fi` + +dvipdfmx-subfont.o: subfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-subfont.o -MD -MP -MF $(DEPDIR)/dvipdfmx-subfont.Tpo -c -o dvipdfmx-subfont.o `test -f 'subfont.c' || echo '$(srcdir)/'`subfont.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-subfont.Tpo $(DEPDIR)/dvipdfmx-subfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='subfont.c' object='dvipdfmx-subfont.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-subfont.o `test -f 'subfont.c' || echo '$(srcdir)/'`subfont.c + +dvipdfmx-subfont.obj: subfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-subfont.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-subfont.Tpo -c -o dvipdfmx-subfont.obj `if test -f 'subfont.c'; then $(CYGPATH_W) 'subfont.c'; else $(CYGPATH_W) '$(srcdir)/subfont.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-subfont.Tpo $(DEPDIR)/dvipdfmx-subfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='subfont.c' object='dvipdfmx-subfont.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-subfont.obj `if test -f 'subfont.c'; then $(CYGPATH_W) 'subfont.c'; else $(CYGPATH_W) '$(srcdir)/subfont.c'; fi` + +dvipdfmx-t1_char.o: t1_char.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-t1_char.o -MD -MP -MF $(DEPDIR)/dvipdfmx-t1_char.Tpo -c -o dvipdfmx-t1_char.o `test -f 't1_char.c' || echo '$(srcdir)/'`t1_char.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-t1_char.Tpo $(DEPDIR)/dvipdfmx-t1_char.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_char.c' object='dvipdfmx-t1_char.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-t1_char.o `test -f 't1_char.c' || echo '$(srcdir)/'`t1_char.c + +dvipdfmx-t1_char.obj: t1_char.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-t1_char.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-t1_char.Tpo -c -o dvipdfmx-t1_char.obj `if test -f 't1_char.c'; then $(CYGPATH_W) 't1_char.c'; else $(CYGPATH_W) '$(srcdir)/t1_char.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-t1_char.Tpo $(DEPDIR)/dvipdfmx-t1_char.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_char.c' object='dvipdfmx-t1_char.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-t1_char.obj `if test -f 't1_char.c'; then $(CYGPATH_W) 't1_char.c'; else $(CYGPATH_W) '$(srcdir)/t1_char.c'; fi` + +dvipdfmx-t1_load.o: t1_load.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-t1_load.o -MD -MP -MF $(DEPDIR)/dvipdfmx-t1_load.Tpo -c -o dvipdfmx-t1_load.o `test -f 't1_load.c' || echo '$(srcdir)/'`t1_load.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-t1_load.Tpo $(DEPDIR)/dvipdfmx-t1_load.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_load.c' object='dvipdfmx-t1_load.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-t1_load.o `test -f 't1_load.c' || echo '$(srcdir)/'`t1_load.c + +dvipdfmx-t1_load.obj: t1_load.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-t1_load.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-t1_load.Tpo -c -o dvipdfmx-t1_load.obj `if test -f 't1_load.c'; then $(CYGPATH_W) 't1_load.c'; else $(CYGPATH_W) '$(srcdir)/t1_load.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-t1_load.Tpo $(DEPDIR)/dvipdfmx-t1_load.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_load.c' object='dvipdfmx-t1_load.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-t1_load.obj `if test -f 't1_load.c'; then $(CYGPATH_W) 't1_load.c'; else $(CYGPATH_W) '$(srcdir)/t1_load.c'; fi` + +dvipdfmx-tt_gsub.o: tt_gsub.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-tt_gsub.o -MD -MP -MF $(DEPDIR)/dvipdfmx-tt_gsub.Tpo -c -o dvipdfmx-tt_gsub.o `test -f 'tt_gsub.c' || echo '$(srcdir)/'`tt_gsub.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-tt_gsub.Tpo $(DEPDIR)/dvipdfmx-tt_gsub.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tt_gsub.c' object='dvipdfmx-tt_gsub.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-tt_gsub.o `test -f 'tt_gsub.c' || echo '$(srcdir)/'`tt_gsub.c + +dvipdfmx-tt_gsub.obj: tt_gsub.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-tt_gsub.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-tt_gsub.Tpo -c -o dvipdfmx-tt_gsub.obj `if test -f 'tt_gsub.c'; then $(CYGPATH_W) 'tt_gsub.c'; else $(CYGPATH_W) '$(srcdir)/tt_gsub.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-tt_gsub.Tpo $(DEPDIR)/dvipdfmx-tt_gsub.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tt_gsub.c' object='dvipdfmx-tt_gsub.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-tt_gsub.obj `if test -f 'tt_gsub.c'; then $(CYGPATH_W) 'tt_gsub.c'; else $(CYGPATH_W) '$(srcdir)/tt_gsub.c'; fi` + +dvipdfmx-unicode.o: unicode.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-unicode.o -MD -MP -MF $(DEPDIR)/dvipdfmx-unicode.Tpo -c -o dvipdfmx-unicode.o `test -f 'unicode.c' || echo '$(srcdir)/'`unicode.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-unicode.Tpo $(DEPDIR)/dvipdfmx-unicode.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicode.c' object='dvipdfmx-unicode.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-unicode.o `test -f 'unicode.c' || echo '$(srcdir)/'`unicode.c + +dvipdfmx-unicode.obj: unicode.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dvipdfmx-unicode.obj -MD -MP -MF $(DEPDIR)/dvipdfmx-unicode.Tpo -c -o dvipdfmx-unicode.obj `if test -f 'unicode.c'; then $(CYGPATH_W) 'unicode.c'; else $(CYGPATH_W) '$(srcdir)/unicode.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dvipdfmx-unicode.Tpo $(DEPDIR)/dvipdfmx-unicode.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicode.c' object='dvipdfmx-unicode.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dvipdfmx-unicode.obj `if test -f 'unicode.c'; then $(CYGPATH_W) 'unicode.c'; else $(CYGPATH_W) '$(srcdir)/unicode.c'; fi` + +src/dvipdfmx-bmpimage.o: src/bmpimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-bmpimage.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-bmpimage.Tpo -c -o src/dvipdfmx-bmpimage.o `test -f 'src/bmpimage.c' || echo '$(srcdir)/'`src/bmpimage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-bmpimage.Tpo src/$(DEPDIR)/dvipdfmx-bmpimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/bmpimage.c' object='src/dvipdfmx-bmpimage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-bmpimage.o `test -f 'src/bmpimage.c' || echo '$(srcdir)/'`src/bmpimage.c + +src/dvipdfmx-bmpimage.obj: src/bmpimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-bmpimage.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-bmpimage.Tpo -c -o src/dvipdfmx-bmpimage.obj `if test -f 'src/bmpimage.c'; then $(CYGPATH_W) 'src/bmpimage.c'; else $(CYGPATH_W) '$(srcdir)/src/bmpimage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-bmpimage.Tpo src/$(DEPDIR)/dvipdfmx-bmpimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/bmpimage.c' object='src/dvipdfmx-bmpimage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-bmpimage.obj `if test -f 'src/bmpimage.c'; then $(CYGPATH_W) 'src/bmpimage.c'; else $(CYGPATH_W) '$(srcdir)/src/bmpimage.c'; fi` + +src/dvipdfmx-cff.o: src/cff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cff.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cff.Tpo -c -o src/dvipdfmx-cff.o `test -f 'src/cff.c' || echo '$(srcdir)/'`src/cff.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cff.Tpo src/$(DEPDIR)/dvipdfmx-cff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cff.c' object='src/dvipdfmx-cff.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cff.o `test -f 'src/cff.c' || echo '$(srcdir)/'`src/cff.c + +src/dvipdfmx-cff.obj: src/cff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cff.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cff.Tpo -c -o src/dvipdfmx-cff.obj `if test -f 'src/cff.c'; then $(CYGPATH_W) 'src/cff.c'; else $(CYGPATH_W) '$(srcdir)/src/cff.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cff.Tpo src/$(DEPDIR)/dvipdfmx-cff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cff.c' object='src/dvipdfmx-cff.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cff.obj `if test -f 'src/cff.c'; then $(CYGPATH_W) 'src/cff.c'; else $(CYGPATH_W) '$(srcdir)/src/cff.c'; fi` + +src/dvipdfmx-cff_dict.o: src/cff_dict.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cff_dict.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cff_dict.Tpo -c -o src/dvipdfmx-cff_dict.o `test -f 'src/cff_dict.c' || echo '$(srcdir)/'`src/cff_dict.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cff_dict.Tpo src/$(DEPDIR)/dvipdfmx-cff_dict.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cff_dict.c' object='src/dvipdfmx-cff_dict.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cff_dict.o `test -f 'src/cff_dict.c' || echo '$(srcdir)/'`src/cff_dict.c + +src/dvipdfmx-cff_dict.obj: src/cff_dict.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cff_dict.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cff_dict.Tpo -c -o src/dvipdfmx-cff_dict.obj `if test -f 'src/cff_dict.c'; then $(CYGPATH_W) 'src/cff_dict.c'; else $(CYGPATH_W) '$(srcdir)/src/cff_dict.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cff_dict.Tpo src/$(DEPDIR)/dvipdfmx-cff_dict.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cff_dict.c' object='src/dvipdfmx-cff_dict.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cff_dict.obj `if test -f 'src/cff_dict.c'; then $(CYGPATH_W) 'src/cff_dict.c'; else $(CYGPATH_W) '$(srcdir)/src/cff_dict.c'; fi` + +src/dvipdfmx-cidtype0.o: src/cidtype0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cidtype0.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cidtype0.Tpo -c -o src/dvipdfmx-cidtype0.o `test -f 'src/cidtype0.c' || echo '$(srcdir)/'`src/cidtype0.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cidtype0.Tpo src/$(DEPDIR)/dvipdfmx-cidtype0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cidtype0.c' object='src/dvipdfmx-cidtype0.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cidtype0.o `test -f 'src/cidtype0.c' || echo '$(srcdir)/'`src/cidtype0.c + +src/dvipdfmx-cidtype0.obj: src/cidtype0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cidtype0.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cidtype0.Tpo -c -o src/dvipdfmx-cidtype0.obj `if test -f 'src/cidtype0.c'; then $(CYGPATH_W) 'src/cidtype0.c'; else $(CYGPATH_W) '$(srcdir)/src/cidtype0.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cidtype0.Tpo src/$(DEPDIR)/dvipdfmx-cidtype0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cidtype0.c' object='src/dvipdfmx-cidtype0.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cidtype0.obj `if test -f 'src/cidtype0.c'; then $(CYGPATH_W) 'src/cidtype0.c'; else $(CYGPATH_W) '$(srcdir)/src/cidtype0.c'; fi` + +src/dvipdfmx-cidtype2.o: src/cidtype2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cidtype2.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cidtype2.Tpo -c -o src/dvipdfmx-cidtype2.o `test -f 'src/cidtype2.c' || echo '$(srcdir)/'`src/cidtype2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cidtype2.Tpo src/$(DEPDIR)/dvipdfmx-cidtype2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cidtype2.c' object='src/dvipdfmx-cidtype2.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cidtype2.o `test -f 'src/cidtype2.c' || echo '$(srcdir)/'`src/cidtype2.c + +src/dvipdfmx-cidtype2.obj: src/cidtype2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-cidtype2.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-cidtype2.Tpo -c -o src/dvipdfmx-cidtype2.obj `if test -f 'src/cidtype2.c'; then $(CYGPATH_W) 'src/cidtype2.c'; else $(CYGPATH_W) '$(srcdir)/src/cidtype2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-cidtype2.Tpo src/$(DEPDIR)/dvipdfmx-cidtype2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cidtype2.c' object='src/dvipdfmx-cidtype2.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-cidtype2.obj `if test -f 'src/cidtype2.c'; then $(CYGPATH_W) 'src/cidtype2.c'; else $(CYGPATH_W) '$(srcdir)/src/cidtype2.c'; fi` + +src/dvipdfmx-dpxfile.o: src/dpxfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dpxfile.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dpxfile.Tpo -c -o src/dvipdfmx-dpxfile.o `test -f 'src/dpxfile.c' || echo '$(srcdir)/'`src/dpxfile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dpxfile.Tpo src/$(DEPDIR)/dvipdfmx-dpxfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dpxfile.c' object='src/dvipdfmx-dpxfile.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dpxfile.o `test -f 'src/dpxfile.c' || echo '$(srcdir)/'`src/dpxfile.c + +src/dvipdfmx-dpxfile.obj: src/dpxfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dpxfile.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dpxfile.Tpo -c -o src/dvipdfmx-dpxfile.obj `if test -f 'src/dpxfile.c'; then $(CYGPATH_W) 'src/dpxfile.c'; else $(CYGPATH_W) '$(srcdir)/src/dpxfile.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dpxfile.Tpo src/$(DEPDIR)/dvipdfmx-dpxfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dpxfile.c' object='src/dvipdfmx-dpxfile.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dpxfile.obj `if test -f 'src/dpxfile.c'; then $(CYGPATH_W) 'src/dpxfile.c'; else $(CYGPATH_W) '$(srcdir)/src/dpxfile.c'; fi` + +src/dvipdfmx-dpxutil.o: src/dpxutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dpxutil.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dpxutil.Tpo -c -o src/dvipdfmx-dpxutil.o `test -f 'src/dpxutil.c' || echo '$(srcdir)/'`src/dpxutil.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dpxutil.Tpo src/$(DEPDIR)/dvipdfmx-dpxutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dpxutil.c' object='src/dvipdfmx-dpxutil.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dpxutil.o `test -f 'src/dpxutil.c' || echo '$(srcdir)/'`src/dpxutil.c + +src/dvipdfmx-dpxutil.obj: src/dpxutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dpxutil.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dpxutil.Tpo -c -o src/dvipdfmx-dpxutil.obj `if test -f 'src/dpxutil.c'; then $(CYGPATH_W) 'src/dpxutil.c'; else $(CYGPATH_W) '$(srcdir)/src/dpxutil.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dpxutil.Tpo src/$(DEPDIR)/dvipdfmx-dpxutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dpxutil.c' object='src/dvipdfmx-dpxutil.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dpxutil.obj `if test -f 'src/dpxutil.c'; then $(CYGPATH_W) 'src/dpxutil.c'; else $(CYGPATH_W) '$(srcdir)/src/dpxutil.c'; fi` + +src/dvipdfmx-dvi.o: src/dvi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dvi.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dvi.Tpo -c -o src/dvipdfmx-dvi.o `test -f 'src/dvi.c' || echo '$(srcdir)/'`src/dvi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dvi.Tpo src/$(DEPDIR)/dvipdfmx-dvi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dvi.c' object='src/dvipdfmx-dvi.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dvi.o `test -f 'src/dvi.c' || echo '$(srcdir)/'`src/dvi.c + +src/dvipdfmx-dvi.obj: src/dvi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dvi.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dvi.Tpo -c -o src/dvipdfmx-dvi.obj `if test -f 'src/dvi.c'; then $(CYGPATH_W) 'src/dvi.c'; else $(CYGPATH_W) '$(srcdir)/src/dvi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dvi.Tpo src/$(DEPDIR)/dvipdfmx-dvi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dvi.c' object='src/dvipdfmx-dvi.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dvi.obj `if test -f 'src/dvi.c'; then $(CYGPATH_W) 'src/dvi.c'; else $(CYGPATH_W) '$(srcdir)/src/dvi.c'; fi` + +src/dvipdfmx-dvipdfmx.o: src/dvipdfmx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dvipdfmx.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dvipdfmx.Tpo -c -o src/dvipdfmx-dvipdfmx.o `test -f 'src/dvipdfmx.c' || echo '$(srcdir)/'`src/dvipdfmx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dvipdfmx.Tpo src/$(DEPDIR)/dvipdfmx-dvipdfmx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dvipdfmx.c' object='src/dvipdfmx-dvipdfmx.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dvipdfmx.o `test -f 'src/dvipdfmx.c' || echo '$(srcdir)/'`src/dvipdfmx.c + +src/dvipdfmx-dvipdfmx.obj: src/dvipdfmx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-dvipdfmx.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-dvipdfmx.Tpo -c -o src/dvipdfmx-dvipdfmx.obj `if test -f 'src/dvipdfmx.c'; then $(CYGPATH_W) 'src/dvipdfmx.c'; else $(CYGPATH_W) '$(srcdir)/src/dvipdfmx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-dvipdfmx.Tpo src/$(DEPDIR)/dvipdfmx-dvipdfmx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dvipdfmx.c' object='src/dvipdfmx-dvipdfmx.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-dvipdfmx.obj `if test -f 'src/dvipdfmx.c'; then $(CYGPATH_W) 'src/dvipdfmx.c'; else $(CYGPATH_W) '$(srcdir)/src/dvipdfmx.c'; fi` + +src/dvipdfmx-epdf.o: src/epdf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-epdf.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-epdf.Tpo -c -o src/dvipdfmx-epdf.o `test -f 'src/epdf.c' || echo '$(srcdir)/'`src/epdf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-epdf.Tpo src/$(DEPDIR)/dvipdfmx-epdf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/epdf.c' object='src/dvipdfmx-epdf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-epdf.o `test -f 'src/epdf.c' || echo '$(srcdir)/'`src/epdf.c + +src/dvipdfmx-epdf.obj: src/epdf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-epdf.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-epdf.Tpo -c -o src/dvipdfmx-epdf.obj `if test -f 'src/epdf.c'; then $(CYGPATH_W) 'src/epdf.c'; else $(CYGPATH_W) '$(srcdir)/src/epdf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-epdf.Tpo src/$(DEPDIR)/dvipdfmx-epdf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/epdf.c' object='src/dvipdfmx-epdf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-epdf.obj `if test -f 'src/epdf.c'; then $(CYGPATH_W) 'src/epdf.c'; else $(CYGPATH_W) '$(srcdir)/src/epdf.c'; fi` + +src/dvipdfmx-error.o: src/error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-error.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-error.Tpo -c -o src/dvipdfmx-error.o `test -f 'src/error.c' || echo '$(srcdir)/'`src/error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-error.Tpo src/$(DEPDIR)/dvipdfmx-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/error.c' object='src/dvipdfmx-error.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-error.o `test -f 'src/error.c' || echo '$(srcdir)/'`src/error.c + +src/dvipdfmx-error.obj: src/error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-error.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-error.Tpo -c -o src/dvipdfmx-error.obj `if test -f 'src/error.c'; then $(CYGPATH_W) 'src/error.c'; else $(CYGPATH_W) '$(srcdir)/src/error.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-error.Tpo src/$(DEPDIR)/dvipdfmx-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/error.c' object='src/dvipdfmx-error.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-error.obj `if test -f 'src/error.c'; then $(CYGPATH_W) 'src/error.c'; else $(CYGPATH_W) '$(srcdir)/src/error.c'; fi` + +src/dvipdfmx-fontmap.o: src/fontmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-fontmap.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-fontmap.Tpo -c -o src/dvipdfmx-fontmap.o `test -f 'src/fontmap.c' || echo '$(srcdir)/'`src/fontmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-fontmap.Tpo src/$(DEPDIR)/dvipdfmx-fontmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/fontmap.c' object='src/dvipdfmx-fontmap.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-fontmap.o `test -f 'src/fontmap.c' || echo '$(srcdir)/'`src/fontmap.c + +src/dvipdfmx-fontmap.obj: src/fontmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-fontmap.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-fontmap.Tpo -c -o src/dvipdfmx-fontmap.obj `if test -f 'src/fontmap.c'; then $(CYGPATH_W) 'src/fontmap.c'; else $(CYGPATH_W) '$(srcdir)/src/fontmap.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-fontmap.Tpo src/$(DEPDIR)/dvipdfmx-fontmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/fontmap.c' object='src/dvipdfmx-fontmap.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-fontmap.obj `if test -f 'src/fontmap.c'; then $(CYGPATH_W) 'src/fontmap.c'; else $(CYGPATH_W) '$(srcdir)/src/fontmap.c'; fi` + +src/dvipdfmx-jpegimage.o: src/jpegimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-jpegimage.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-jpegimage.Tpo -c -o src/dvipdfmx-jpegimage.o `test -f 'src/jpegimage.c' || echo '$(srcdir)/'`src/jpegimage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-jpegimage.Tpo src/$(DEPDIR)/dvipdfmx-jpegimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/jpegimage.c' object='src/dvipdfmx-jpegimage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-jpegimage.o `test -f 'src/jpegimage.c' || echo '$(srcdir)/'`src/jpegimage.c + +src/dvipdfmx-jpegimage.obj: src/jpegimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-jpegimage.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-jpegimage.Tpo -c -o src/dvipdfmx-jpegimage.obj `if test -f 'src/jpegimage.c'; then $(CYGPATH_W) 'src/jpegimage.c'; else $(CYGPATH_W) '$(srcdir)/src/jpegimage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-jpegimage.Tpo src/$(DEPDIR)/dvipdfmx-jpegimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/jpegimage.c' object='src/dvipdfmx-jpegimage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-jpegimage.obj `if test -f 'src/jpegimage.c'; then $(CYGPATH_W) 'src/jpegimage.c'; else $(CYGPATH_W) '$(srcdir)/src/jpegimage.c'; fi` + +src/dvipdfmx-mpost.o: src/mpost.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-mpost.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-mpost.Tpo -c -o src/dvipdfmx-mpost.o `test -f 'src/mpost.c' || echo '$(srcdir)/'`src/mpost.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-mpost.Tpo src/$(DEPDIR)/dvipdfmx-mpost.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/mpost.c' object='src/dvipdfmx-mpost.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-mpost.o `test -f 'src/mpost.c' || echo '$(srcdir)/'`src/mpost.c + +src/dvipdfmx-mpost.obj: src/mpost.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-mpost.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-mpost.Tpo -c -o src/dvipdfmx-mpost.obj `if test -f 'src/mpost.c'; then $(CYGPATH_W) 'src/mpost.c'; else $(CYGPATH_W) '$(srcdir)/src/mpost.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-mpost.Tpo src/$(DEPDIR)/dvipdfmx-mpost.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/mpost.c' object='src/dvipdfmx-mpost.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-mpost.obj `if test -f 'src/mpost.c'; then $(CYGPATH_W) 'src/mpost.c'; else $(CYGPATH_W) '$(srcdir)/src/mpost.c'; fi` + +src/dvipdfmx-pdfcolor.o: src/pdfcolor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfcolor.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfcolor.Tpo -c -o src/dvipdfmx-pdfcolor.o `test -f 'src/pdfcolor.c' || echo '$(srcdir)/'`src/pdfcolor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfcolor.Tpo src/$(DEPDIR)/dvipdfmx-pdfcolor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfcolor.c' object='src/dvipdfmx-pdfcolor.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfcolor.o `test -f 'src/pdfcolor.c' || echo '$(srcdir)/'`src/pdfcolor.c + +src/dvipdfmx-pdfcolor.obj: src/pdfcolor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfcolor.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfcolor.Tpo -c -o src/dvipdfmx-pdfcolor.obj `if test -f 'src/pdfcolor.c'; then $(CYGPATH_W) 'src/pdfcolor.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfcolor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfcolor.Tpo src/$(DEPDIR)/dvipdfmx-pdfcolor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfcolor.c' object='src/dvipdfmx-pdfcolor.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfcolor.obj `if test -f 'src/pdfcolor.c'; then $(CYGPATH_W) 'src/pdfcolor.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfcolor.c'; fi` + +src/dvipdfmx-pdfdev.o: src/pdfdev.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfdev.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfdev.Tpo -c -o src/dvipdfmx-pdfdev.o `test -f 'src/pdfdev.c' || echo '$(srcdir)/'`src/pdfdev.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfdev.Tpo src/$(DEPDIR)/dvipdfmx-pdfdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfdev.c' object='src/dvipdfmx-pdfdev.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfdev.o `test -f 'src/pdfdev.c' || echo '$(srcdir)/'`src/pdfdev.c + +src/dvipdfmx-pdfdev.obj: src/pdfdev.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfdev.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfdev.Tpo -c -o src/dvipdfmx-pdfdev.obj `if test -f 'src/pdfdev.c'; then $(CYGPATH_W) 'src/pdfdev.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfdev.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfdev.Tpo src/$(DEPDIR)/dvipdfmx-pdfdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfdev.c' object='src/dvipdfmx-pdfdev.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfdev.obj `if test -f 'src/pdfdev.c'; then $(CYGPATH_W) 'src/pdfdev.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfdev.c'; fi` + +src/dvipdfmx-pdfdoc.o: src/pdfdoc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfdoc.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfdoc.Tpo -c -o src/dvipdfmx-pdfdoc.o `test -f 'src/pdfdoc.c' || echo '$(srcdir)/'`src/pdfdoc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfdoc.Tpo src/$(DEPDIR)/dvipdfmx-pdfdoc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfdoc.c' object='src/dvipdfmx-pdfdoc.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfdoc.o `test -f 'src/pdfdoc.c' || echo '$(srcdir)/'`src/pdfdoc.c + +src/dvipdfmx-pdfdoc.obj: src/pdfdoc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfdoc.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfdoc.Tpo -c -o src/dvipdfmx-pdfdoc.obj `if test -f 'src/pdfdoc.c'; then $(CYGPATH_W) 'src/pdfdoc.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfdoc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfdoc.Tpo src/$(DEPDIR)/dvipdfmx-pdfdoc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfdoc.c' object='src/dvipdfmx-pdfdoc.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfdoc.obj `if test -f 'src/pdfdoc.c'; then $(CYGPATH_W) 'src/pdfdoc.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfdoc.c'; fi` + +src/dvipdfmx-pdfdraw.o: src/pdfdraw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfdraw.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfdraw.Tpo -c -o src/dvipdfmx-pdfdraw.o `test -f 'src/pdfdraw.c' || echo '$(srcdir)/'`src/pdfdraw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfdraw.Tpo src/$(DEPDIR)/dvipdfmx-pdfdraw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfdraw.c' object='src/dvipdfmx-pdfdraw.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfdraw.o `test -f 'src/pdfdraw.c' || echo '$(srcdir)/'`src/pdfdraw.c + +src/dvipdfmx-pdfdraw.obj: src/pdfdraw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfdraw.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfdraw.Tpo -c -o src/dvipdfmx-pdfdraw.obj `if test -f 'src/pdfdraw.c'; then $(CYGPATH_W) 'src/pdfdraw.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfdraw.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfdraw.Tpo src/$(DEPDIR)/dvipdfmx-pdfdraw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfdraw.c' object='src/dvipdfmx-pdfdraw.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfdraw.obj `if test -f 'src/pdfdraw.c'; then $(CYGPATH_W) 'src/pdfdraw.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfdraw.c'; fi` + +src/dvipdfmx-pdfencrypt.o: src/pdfencrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfencrypt.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfencrypt.Tpo -c -o src/dvipdfmx-pdfencrypt.o `test -f 'src/pdfencrypt.c' || echo '$(srcdir)/'`src/pdfencrypt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfencrypt.Tpo src/$(DEPDIR)/dvipdfmx-pdfencrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfencrypt.c' object='src/dvipdfmx-pdfencrypt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfencrypt.o `test -f 'src/pdfencrypt.c' || echo '$(srcdir)/'`src/pdfencrypt.c + +src/dvipdfmx-pdfencrypt.obj: src/pdfencrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfencrypt.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfencrypt.Tpo -c -o src/dvipdfmx-pdfencrypt.obj `if test -f 'src/pdfencrypt.c'; then $(CYGPATH_W) 'src/pdfencrypt.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfencrypt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfencrypt.Tpo src/$(DEPDIR)/dvipdfmx-pdfencrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfencrypt.c' object='src/dvipdfmx-pdfencrypt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfencrypt.obj `if test -f 'src/pdfencrypt.c'; then $(CYGPATH_W) 'src/pdfencrypt.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfencrypt.c'; fi` + +src/dvipdfmx-pdfnames.o: src/pdfnames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfnames.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfnames.Tpo -c -o src/dvipdfmx-pdfnames.o `test -f 'src/pdfnames.c' || echo '$(srcdir)/'`src/pdfnames.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfnames.Tpo src/$(DEPDIR)/dvipdfmx-pdfnames.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfnames.c' object='src/dvipdfmx-pdfnames.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfnames.o `test -f 'src/pdfnames.c' || echo '$(srcdir)/'`src/pdfnames.c + +src/dvipdfmx-pdfnames.obj: src/pdfnames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfnames.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfnames.Tpo -c -o src/dvipdfmx-pdfnames.obj `if test -f 'src/pdfnames.c'; then $(CYGPATH_W) 'src/pdfnames.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfnames.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfnames.Tpo src/$(DEPDIR)/dvipdfmx-pdfnames.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfnames.c' object='src/dvipdfmx-pdfnames.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfnames.obj `if test -f 'src/pdfnames.c'; then $(CYGPATH_W) 'src/pdfnames.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfnames.c'; fi` + +src/dvipdfmx-pdfobj.o: src/pdfobj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfobj.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfobj.Tpo -c -o src/dvipdfmx-pdfobj.o `test -f 'src/pdfobj.c' || echo '$(srcdir)/'`src/pdfobj.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfobj.Tpo src/$(DEPDIR)/dvipdfmx-pdfobj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfobj.c' object='src/dvipdfmx-pdfobj.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfobj.o `test -f 'src/pdfobj.c' || echo '$(srcdir)/'`src/pdfobj.c + +src/dvipdfmx-pdfobj.obj: src/pdfobj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfobj.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfobj.Tpo -c -o src/dvipdfmx-pdfobj.obj `if test -f 'src/pdfobj.c'; then $(CYGPATH_W) 'src/pdfobj.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfobj.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfobj.Tpo src/$(DEPDIR)/dvipdfmx-pdfobj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfobj.c' object='src/dvipdfmx-pdfobj.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfobj.obj `if test -f 'src/pdfobj.c'; then $(CYGPATH_W) 'src/pdfobj.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfobj.c'; fi` + +src/dvipdfmx-pdfparse.o: src/pdfparse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfparse.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfparse.Tpo -c -o src/dvipdfmx-pdfparse.o `test -f 'src/pdfparse.c' || echo '$(srcdir)/'`src/pdfparse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfparse.Tpo src/$(DEPDIR)/dvipdfmx-pdfparse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfparse.c' object='src/dvipdfmx-pdfparse.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfparse.o `test -f 'src/pdfparse.c' || echo '$(srcdir)/'`src/pdfparse.c + +src/dvipdfmx-pdfparse.obj: src/pdfparse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfparse.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfparse.Tpo -c -o src/dvipdfmx-pdfparse.obj `if test -f 'src/pdfparse.c'; then $(CYGPATH_W) 'src/pdfparse.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfparse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfparse.Tpo src/$(DEPDIR)/dvipdfmx-pdfparse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfparse.c' object='src/dvipdfmx-pdfparse.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfparse.obj `if test -f 'src/pdfparse.c'; then $(CYGPATH_W) 'src/pdfparse.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfparse.c'; fi` + +src/dvipdfmx-pdfximage.o: src/pdfximage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfximage.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfximage.Tpo -c -o src/dvipdfmx-pdfximage.o `test -f 'src/pdfximage.c' || echo '$(srcdir)/'`src/pdfximage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfximage.Tpo src/$(DEPDIR)/dvipdfmx-pdfximage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfximage.c' object='src/dvipdfmx-pdfximage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfximage.o `test -f 'src/pdfximage.c' || echo '$(srcdir)/'`src/pdfximage.c + +src/dvipdfmx-pdfximage.obj: src/pdfximage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pdfximage.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pdfximage.Tpo -c -o src/dvipdfmx-pdfximage.obj `if test -f 'src/pdfximage.c'; then $(CYGPATH_W) 'src/pdfximage.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfximage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pdfximage.Tpo src/$(DEPDIR)/dvipdfmx-pdfximage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pdfximage.c' object='src/dvipdfmx-pdfximage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pdfximage.obj `if test -f 'src/pdfximage.c'; then $(CYGPATH_W) 'src/pdfximage.c'; else $(CYGPATH_W) '$(srcdir)/src/pdfximage.c'; fi` + +src/dvipdfmx-pngimage.o: src/pngimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pngimage.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pngimage.Tpo -c -o src/dvipdfmx-pngimage.o `test -f 'src/pngimage.c' || echo '$(srcdir)/'`src/pngimage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pngimage.Tpo src/$(DEPDIR)/dvipdfmx-pngimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pngimage.c' object='src/dvipdfmx-pngimage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pngimage.o `test -f 'src/pngimage.c' || echo '$(srcdir)/'`src/pngimage.c + +src/dvipdfmx-pngimage.obj: src/pngimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-pngimage.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-pngimage.Tpo -c -o src/dvipdfmx-pngimage.obj `if test -f 'src/pngimage.c'; then $(CYGPATH_W) 'src/pngimage.c'; else $(CYGPATH_W) '$(srcdir)/src/pngimage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-pngimage.Tpo src/$(DEPDIR)/dvipdfmx-pngimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pngimage.c' object='src/dvipdfmx-pngimage.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-pngimage.obj `if test -f 'src/pngimage.c'; then $(CYGPATH_W) 'src/pngimage.c'; else $(CYGPATH_W) '$(srcdir)/src/pngimage.c'; fi` + +src/dvipdfmx-sfnt.o: src/sfnt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-sfnt.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-sfnt.Tpo -c -o src/dvipdfmx-sfnt.o `test -f 'src/sfnt.c' || echo '$(srcdir)/'`src/sfnt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-sfnt.Tpo src/$(DEPDIR)/dvipdfmx-sfnt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sfnt.c' object='src/dvipdfmx-sfnt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-sfnt.o `test -f 'src/sfnt.c' || echo '$(srcdir)/'`src/sfnt.c + +src/dvipdfmx-sfnt.obj: src/sfnt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-sfnt.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-sfnt.Tpo -c -o src/dvipdfmx-sfnt.obj `if test -f 'src/sfnt.c'; then $(CYGPATH_W) 'src/sfnt.c'; else $(CYGPATH_W) '$(srcdir)/src/sfnt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-sfnt.Tpo src/$(DEPDIR)/dvipdfmx-sfnt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sfnt.c' object='src/dvipdfmx-sfnt.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-sfnt.obj `if test -f 'src/sfnt.c'; then $(CYGPATH_W) 'src/sfnt.c'; else $(CYGPATH_W) '$(srcdir)/src/sfnt.c'; fi` + +src/dvipdfmx-spc_color.o: src/spc_color.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_color.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_color.Tpo -c -o src/dvipdfmx-spc_color.o `test -f 'src/spc_color.c' || echo '$(srcdir)/'`src/spc_color.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_color.Tpo src/$(DEPDIR)/dvipdfmx-spc_color.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_color.c' object='src/dvipdfmx-spc_color.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_color.o `test -f 'src/spc_color.c' || echo '$(srcdir)/'`src/spc_color.c + +src/dvipdfmx-spc_color.obj: src/spc_color.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_color.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_color.Tpo -c -o src/dvipdfmx-spc_color.obj `if test -f 'src/spc_color.c'; then $(CYGPATH_W) 'src/spc_color.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_color.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_color.Tpo src/$(DEPDIR)/dvipdfmx-spc_color.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_color.c' object='src/dvipdfmx-spc_color.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_color.obj `if test -f 'src/spc_color.c'; then $(CYGPATH_W) 'src/spc_color.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_color.c'; fi` + +src/dvipdfmx-spc_dvips.o: src/spc_dvips.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_dvips.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_dvips.Tpo -c -o src/dvipdfmx-spc_dvips.o `test -f 'src/spc_dvips.c' || echo '$(srcdir)/'`src/spc_dvips.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_dvips.Tpo src/$(DEPDIR)/dvipdfmx-spc_dvips.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_dvips.c' object='src/dvipdfmx-spc_dvips.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_dvips.o `test -f 'src/spc_dvips.c' || echo '$(srcdir)/'`src/spc_dvips.c + +src/dvipdfmx-spc_dvips.obj: src/spc_dvips.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_dvips.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_dvips.Tpo -c -o src/dvipdfmx-spc_dvips.obj `if test -f 'src/spc_dvips.c'; then $(CYGPATH_W) 'src/spc_dvips.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_dvips.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_dvips.Tpo src/$(DEPDIR)/dvipdfmx-spc_dvips.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_dvips.c' object='src/dvipdfmx-spc_dvips.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_dvips.obj `if test -f 'src/spc_dvips.c'; then $(CYGPATH_W) 'src/spc_dvips.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_dvips.c'; fi` + +src/dvipdfmx-spc_html.o: src/spc_html.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_html.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_html.Tpo -c -o src/dvipdfmx-spc_html.o `test -f 'src/spc_html.c' || echo '$(srcdir)/'`src/spc_html.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_html.Tpo src/$(DEPDIR)/dvipdfmx-spc_html.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_html.c' object='src/dvipdfmx-spc_html.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_html.o `test -f 'src/spc_html.c' || echo '$(srcdir)/'`src/spc_html.c + +src/dvipdfmx-spc_html.obj: src/spc_html.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_html.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_html.Tpo -c -o src/dvipdfmx-spc_html.obj `if test -f 'src/spc_html.c'; then $(CYGPATH_W) 'src/spc_html.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_html.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_html.Tpo src/$(DEPDIR)/dvipdfmx-spc_html.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_html.c' object='src/dvipdfmx-spc_html.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_html.obj `if test -f 'src/spc_html.c'; then $(CYGPATH_W) 'src/spc_html.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_html.c'; fi` + +src/dvipdfmx-spc_pdfm.o: src/spc_pdfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_pdfm.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_pdfm.Tpo -c -o src/dvipdfmx-spc_pdfm.o `test -f 'src/spc_pdfm.c' || echo '$(srcdir)/'`src/spc_pdfm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_pdfm.Tpo src/$(DEPDIR)/dvipdfmx-spc_pdfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_pdfm.c' object='src/dvipdfmx-spc_pdfm.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_pdfm.o `test -f 'src/spc_pdfm.c' || echo '$(srcdir)/'`src/spc_pdfm.c + +src/dvipdfmx-spc_pdfm.obj: src/spc_pdfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_pdfm.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_pdfm.Tpo -c -o src/dvipdfmx-spc_pdfm.obj `if test -f 'src/spc_pdfm.c'; then $(CYGPATH_W) 'src/spc_pdfm.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_pdfm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_pdfm.Tpo src/$(DEPDIR)/dvipdfmx-spc_pdfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_pdfm.c' object='src/dvipdfmx-spc_pdfm.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_pdfm.obj `if test -f 'src/spc_pdfm.c'; then $(CYGPATH_W) 'src/spc_pdfm.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_pdfm.c'; fi` + +src/dvipdfmx-spc_tpic.o: src/spc_tpic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_tpic.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_tpic.Tpo -c -o src/dvipdfmx-spc_tpic.o `test -f 'src/spc_tpic.c' || echo '$(srcdir)/'`src/spc_tpic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_tpic.Tpo src/$(DEPDIR)/dvipdfmx-spc_tpic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_tpic.c' object='src/dvipdfmx-spc_tpic.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_tpic.o `test -f 'src/spc_tpic.c' || echo '$(srcdir)/'`src/spc_tpic.c + +src/dvipdfmx-spc_tpic.obj: src/spc_tpic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_tpic.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_tpic.Tpo -c -o src/dvipdfmx-spc_tpic.obj `if test -f 'src/spc_tpic.c'; then $(CYGPATH_W) 'src/spc_tpic.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_tpic.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_tpic.Tpo src/$(DEPDIR)/dvipdfmx-spc_tpic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_tpic.c' object='src/dvipdfmx-spc_tpic.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_tpic.obj `if test -f 'src/spc_tpic.c'; then $(CYGPATH_W) 'src/spc_tpic.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_tpic.c'; fi` + +src/dvipdfmx-spc_util.o: src/spc_util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_util.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_util.Tpo -c -o src/dvipdfmx-spc_util.o `test -f 'src/spc_util.c' || echo '$(srcdir)/'`src/spc_util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_util.Tpo src/$(DEPDIR)/dvipdfmx-spc_util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_util.c' object='src/dvipdfmx-spc_util.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_util.o `test -f 'src/spc_util.c' || echo '$(srcdir)/'`src/spc_util.c + +src/dvipdfmx-spc_util.obj: src/spc_util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-spc_util.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-spc_util.Tpo -c -o src/dvipdfmx-spc_util.obj `if test -f 'src/spc_util.c'; then $(CYGPATH_W) 'src/spc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-spc_util.Tpo src/$(DEPDIR)/dvipdfmx-spc_util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spc_util.c' object='src/dvipdfmx-spc_util.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-spc_util.obj `if test -f 'src/spc_util.c'; then $(CYGPATH_W) 'src/spc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/spc_util.c'; fi` + +src/dvipdfmx-specials.o: src/specials.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-specials.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-specials.Tpo -c -o src/dvipdfmx-specials.o `test -f 'src/specials.c' || echo '$(srcdir)/'`src/specials.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-specials.Tpo src/$(DEPDIR)/dvipdfmx-specials.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/specials.c' object='src/dvipdfmx-specials.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-specials.o `test -f 'src/specials.c' || echo '$(srcdir)/'`src/specials.c + +src/dvipdfmx-specials.obj: src/specials.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-specials.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-specials.Tpo -c -o src/dvipdfmx-specials.obj `if test -f 'src/specials.c'; then $(CYGPATH_W) 'src/specials.c'; else $(CYGPATH_W) '$(srcdir)/src/specials.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-specials.Tpo src/$(DEPDIR)/dvipdfmx-specials.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/specials.c' object='src/dvipdfmx-specials.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-specials.obj `if test -f 'src/specials.c'; then $(CYGPATH_W) 'src/specials.c'; else $(CYGPATH_W) '$(srcdir)/src/specials.c'; fi` + +src/dvipdfmx-tfm.o: src/tfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tfm.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tfm.Tpo -c -o src/dvipdfmx-tfm.o `test -f 'src/tfm.c' || echo '$(srcdir)/'`src/tfm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tfm.Tpo src/$(DEPDIR)/dvipdfmx-tfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tfm.c' object='src/dvipdfmx-tfm.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tfm.o `test -f 'src/tfm.c' || echo '$(srcdir)/'`src/tfm.c + +src/dvipdfmx-tfm.obj: src/tfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tfm.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tfm.Tpo -c -o src/dvipdfmx-tfm.obj `if test -f 'src/tfm.c'; then $(CYGPATH_W) 'src/tfm.c'; else $(CYGPATH_W) '$(srcdir)/src/tfm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tfm.Tpo src/$(DEPDIR)/dvipdfmx-tfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tfm.c' object='src/dvipdfmx-tfm.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tfm.obj `if test -f 'src/tfm.c'; then $(CYGPATH_W) 'src/tfm.c'; else $(CYGPATH_W) '$(srcdir)/src/tfm.c'; fi` + +src/dvipdfmx-truetype.o: src/truetype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-truetype.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-truetype.Tpo -c -o src/dvipdfmx-truetype.o `test -f 'src/truetype.c' || echo '$(srcdir)/'`src/truetype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-truetype.Tpo src/$(DEPDIR)/dvipdfmx-truetype.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/truetype.c' object='src/dvipdfmx-truetype.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-truetype.o `test -f 'src/truetype.c' || echo '$(srcdir)/'`src/truetype.c + +src/dvipdfmx-truetype.obj: src/truetype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-truetype.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-truetype.Tpo -c -o src/dvipdfmx-truetype.obj `if test -f 'src/truetype.c'; then $(CYGPATH_W) 'src/truetype.c'; else $(CYGPATH_W) '$(srcdir)/src/truetype.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-truetype.Tpo src/$(DEPDIR)/dvipdfmx-truetype.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/truetype.c' object='src/dvipdfmx-truetype.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-truetype.obj `if test -f 'src/truetype.c'; then $(CYGPATH_W) 'src/truetype.c'; else $(CYGPATH_W) '$(srcdir)/src/truetype.c'; fi` + +src/dvipdfmx-tt_aux.o: src/tt_aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_aux.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_aux.Tpo -c -o src/dvipdfmx-tt_aux.o `test -f 'src/tt_aux.c' || echo '$(srcdir)/'`src/tt_aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_aux.Tpo src/$(DEPDIR)/dvipdfmx-tt_aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_aux.c' object='src/dvipdfmx-tt_aux.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_aux.o `test -f 'src/tt_aux.c' || echo '$(srcdir)/'`src/tt_aux.c + +src/dvipdfmx-tt_aux.obj: src/tt_aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_aux.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_aux.Tpo -c -o src/dvipdfmx-tt_aux.obj `if test -f 'src/tt_aux.c'; then $(CYGPATH_W) 'src/tt_aux.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_aux.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_aux.Tpo src/$(DEPDIR)/dvipdfmx-tt_aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_aux.c' object='src/dvipdfmx-tt_aux.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_aux.obj `if test -f 'src/tt_aux.c'; then $(CYGPATH_W) 'src/tt_aux.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_aux.c'; fi` + +src/dvipdfmx-tt_cmap.o: src/tt_cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_cmap.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_cmap.Tpo -c -o src/dvipdfmx-tt_cmap.o `test -f 'src/tt_cmap.c' || echo '$(srcdir)/'`src/tt_cmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_cmap.Tpo src/$(DEPDIR)/dvipdfmx-tt_cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_cmap.c' object='src/dvipdfmx-tt_cmap.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_cmap.o `test -f 'src/tt_cmap.c' || echo '$(srcdir)/'`src/tt_cmap.c + +src/dvipdfmx-tt_cmap.obj: src/tt_cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_cmap.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_cmap.Tpo -c -o src/dvipdfmx-tt_cmap.obj `if test -f 'src/tt_cmap.c'; then $(CYGPATH_W) 'src/tt_cmap.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_cmap.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_cmap.Tpo src/$(DEPDIR)/dvipdfmx-tt_cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_cmap.c' object='src/dvipdfmx-tt_cmap.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_cmap.obj `if test -f 'src/tt_cmap.c'; then $(CYGPATH_W) 'src/tt_cmap.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_cmap.c'; fi` + +src/dvipdfmx-tt_glyf.o: src/tt_glyf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_glyf.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_glyf.Tpo -c -o src/dvipdfmx-tt_glyf.o `test -f 'src/tt_glyf.c' || echo '$(srcdir)/'`src/tt_glyf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_glyf.Tpo src/$(DEPDIR)/dvipdfmx-tt_glyf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_glyf.c' object='src/dvipdfmx-tt_glyf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_glyf.o `test -f 'src/tt_glyf.c' || echo '$(srcdir)/'`src/tt_glyf.c + +src/dvipdfmx-tt_glyf.obj: src/tt_glyf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_glyf.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_glyf.Tpo -c -o src/dvipdfmx-tt_glyf.obj `if test -f 'src/tt_glyf.c'; then $(CYGPATH_W) 'src/tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_glyf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_glyf.Tpo src/$(DEPDIR)/dvipdfmx-tt_glyf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_glyf.c' object='src/dvipdfmx-tt_glyf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_glyf.obj `if test -f 'src/tt_glyf.c'; then $(CYGPATH_W) 'src/tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_glyf.c'; fi` + +src/dvipdfmx-tt_post.o: src/tt_post.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_post.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_post.Tpo -c -o src/dvipdfmx-tt_post.o `test -f 'src/tt_post.c' || echo '$(srcdir)/'`src/tt_post.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_post.Tpo src/$(DEPDIR)/dvipdfmx-tt_post.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_post.c' object='src/dvipdfmx-tt_post.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_post.o `test -f 'src/tt_post.c' || echo '$(srcdir)/'`src/tt_post.c + +src/dvipdfmx-tt_post.obj: src/tt_post.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_post.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_post.Tpo -c -o src/dvipdfmx-tt_post.obj `if test -f 'src/tt_post.c'; then $(CYGPATH_W) 'src/tt_post.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_post.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_post.Tpo src/$(DEPDIR)/dvipdfmx-tt_post.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_post.c' object='src/dvipdfmx-tt_post.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_post.obj `if test -f 'src/tt_post.c'; then $(CYGPATH_W) 'src/tt_post.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_post.c'; fi` + +src/dvipdfmx-tt_table.o: src/tt_table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_table.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_table.Tpo -c -o src/dvipdfmx-tt_table.o `test -f 'src/tt_table.c' || echo '$(srcdir)/'`src/tt_table.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_table.Tpo src/$(DEPDIR)/dvipdfmx-tt_table.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_table.c' object='src/dvipdfmx-tt_table.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_table.o `test -f 'src/tt_table.c' || echo '$(srcdir)/'`src/tt_table.c + +src/dvipdfmx-tt_table.obj: src/tt_table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-tt_table.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-tt_table.Tpo -c -o src/dvipdfmx-tt_table.obj `if test -f 'src/tt_table.c'; then $(CYGPATH_W) 'src/tt_table.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_table.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-tt_table.Tpo src/$(DEPDIR)/dvipdfmx-tt_table.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tt_table.c' object='src/dvipdfmx-tt_table.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-tt_table.obj `if test -f 'src/tt_table.c'; then $(CYGPATH_W) 'src/tt_table.c'; else $(CYGPATH_W) '$(srcdir)/src/tt_table.c'; fi` + +src/dvipdfmx-type0.o: src/type0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-type0.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-type0.Tpo -c -o src/dvipdfmx-type0.o `test -f 'src/type0.c' || echo '$(srcdir)/'`src/type0.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-type0.Tpo src/$(DEPDIR)/dvipdfmx-type0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/type0.c' object='src/dvipdfmx-type0.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-type0.o `test -f 'src/type0.c' || echo '$(srcdir)/'`src/type0.c + +src/dvipdfmx-type0.obj: src/type0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-type0.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-type0.Tpo -c -o src/dvipdfmx-type0.obj `if test -f 'src/type0.c'; then $(CYGPATH_W) 'src/type0.c'; else $(CYGPATH_W) '$(srcdir)/src/type0.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-type0.Tpo src/$(DEPDIR)/dvipdfmx-type0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/type0.c' object='src/dvipdfmx-type0.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-type0.obj `if test -f 'src/type0.c'; then $(CYGPATH_W) 'src/type0.c'; else $(CYGPATH_W) '$(srcdir)/src/type0.c'; fi` + +src/dvipdfmx-type1.o: src/type1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-type1.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-type1.Tpo -c -o src/dvipdfmx-type1.o `test -f 'src/type1.c' || echo '$(srcdir)/'`src/type1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-type1.Tpo src/$(DEPDIR)/dvipdfmx-type1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/type1.c' object='src/dvipdfmx-type1.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-type1.o `test -f 'src/type1.c' || echo '$(srcdir)/'`src/type1.c + +src/dvipdfmx-type1.obj: src/type1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-type1.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-type1.Tpo -c -o src/dvipdfmx-type1.obj `if test -f 'src/type1.c'; then $(CYGPATH_W) 'src/type1.c'; else $(CYGPATH_W) '$(srcdir)/src/type1.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-type1.Tpo src/$(DEPDIR)/dvipdfmx-type1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/type1.c' object='src/dvipdfmx-type1.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-type1.obj `if test -f 'src/type1.c'; then $(CYGPATH_W) 'src/type1.c'; else $(CYGPATH_W) '$(srcdir)/src/type1.c'; fi` + +src/dvipdfmx-type1c.o: src/type1c.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-type1c.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-type1c.Tpo -c -o src/dvipdfmx-type1c.o `test -f 'src/type1c.c' || echo '$(srcdir)/'`src/type1c.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-type1c.Tpo src/$(DEPDIR)/dvipdfmx-type1c.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/type1c.c' object='src/dvipdfmx-type1c.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-type1c.o `test -f 'src/type1c.c' || echo '$(srcdir)/'`src/type1c.c + +src/dvipdfmx-type1c.obj: src/type1c.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-type1c.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-type1c.Tpo -c -o src/dvipdfmx-type1c.obj `if test -f 'src/type1c.c'; then $(CYGPATH_W) 'src/type1c.c'; else $(CYGPATH_W) '$(srcdir)/src/type1c.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-type1c.Tpo src/$(DEPDIR)/dvipdfmx-type1c.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/type1c.c' object='src/dvipdfmx-type1c.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-type1c.obj `if test -f 'src/type1c.c'; then $(CYGPATH_W) 'src/type1c.c'; else $(CYGPATH_W) '$(srcdir)/src/type1c.c'; fi` + +src/dvipdfmx-vf.o: src/vf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-vf.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-vf.Tpo -c -o src/dvipdfmx-vf.o `test -f 'src/vf.c' || echo '$(srcdir)/'`src/vf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-vf.Tpo src/$(DEPDIR)/dvipdfmx-vf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/vf.c' object='src/dvipdfmx-vf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-vf.o `test -f 'src/vf.c' || echo '$(srcdir)/'`src/vf.c + +src/dvipdfmx-vf.obj: src/vf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-vf.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-vf.Tpo -c -o src/dvipdfmx-vf.obj `if test -f 'src/vf.c'; then $(CYGPATH_W) 'src/vf.c'; else $(CYGPATH_W) '$(srcdir)/src/vf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-vf.Tpo src/$(DEPDIR)/dvipdfmx-vf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/vf.c' object='src/dvipdfmx-vf.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-vf.obj `if test -f 'src/vf.c'; then $(CYGPATH_W) 'src/vf.c'; else $(CYGPATH_W) '$(srcdir)/src/vf.c'; fi` + +src/dvipdfmx-xbb.o: src/xbb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-xbb.o -MD -MP -MF src/$(DEPDIR)/dvipdfmx-xbb.Tpo -c -o src/dvipdfmx-xbb.o `test -f 'src/xbb.c' || echo '$(srcdir)/'`src/xbb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-xbb.Tpo src/$(DEPDIR)/dvipdfmx-xbb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/xbb.c' object='src/dvipdfmx-xbb.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-xbb.o `test -f 'src/xbb.c' || echo '$(srcdir)/'`src/xbb.c + +src/dvipdfmx-xbb.obj: src/xbb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/dvipdfmx-xbb.obj -MD -MP -MF src/$(DEPDIR)/dvipdfmx-xbb.Tpo -c -o src/dvipdfmx-xbb.obj `if test -f 'src/xbb.c'; then $(CYGPATH_W) 'src/xbb.c'; else $(CYGPATH_W) '$(srcdir)/src/xbb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/dvipdfmx-xbb.Tpo src/$(DEPDIR)/dvipdfmx-xbb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/xbb.c' object='src/dvipdfmx-xbb.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) $(dvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/dvipdfmx-xbb.obj `if test -f 'src/xbb.c'; then $(CYGPATH_W) 'src/xbb.c'; else $(CYGPATH_W) '$(srcdir)/src/xbb.c'; fi` + +xdvipdfmx-agl.o: agl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-agl.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-agl.Tpo -c -o xdvipdfmx-agl.o `test -f 'agl.c' || echo '$(srcdir)/'`agl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-agl.Tpo $(DEPDIR)/xdvipdfmx-agl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='agl.c' object='xdvipdfmx-agl.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-agl.o `test -f 'agl.c' || echo '$(srcdir)/'`agl.c + +xdvipdfmx-agl.obj: agl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-agl.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-agl.Tpo -c -o xdvipdfmx-agl.obj `if test -f 'agl.c'; then $(CYGPATH_W) 'agl.c'; else $(CYGPATH_W) '$(srcdir)/agl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-agl.Tpo $(DEPDIR)/xdvipdfmx-agl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='agl.c' object='xdvipdfmx-agl.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-agl.obj `if test -f 'agl.c'; then $(CYGPATH_W) 'agl.c'; else $(CYGPATH_W) '$(srcdir)/agl.c'; fi` + +xdvipdfmx-cid.o: cid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cid.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-cid.Tpo -c -o xdvipdfmx-cid.o `test -f 'cid.c' || echo '$(srcdir)/'`cid.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cid.Tpo $(DEPDIR)/xdvipdfmx-cid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cid.c' object='xdvipdfmx-cid.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cid.o `test -f 'cid.c' || echo '$(srcdir)/'`cid.c + +xdvipdfmx-cid.obj: cid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cid.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-cid.Tpo -c -o xdvipdfmx-cid.obj `if test -f 'cid.c'; then $(CYGPATH_W) 'cid.c'; else $(CYGPATH_W) '$(srcdir)/cid.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cid.Tpo $(DEPDIR)/xdvipdfmx-cid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cid.c' object='xdvipdfmx-cid.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cid.obj `if test -f 'cid.c'; then $(CYGPATH_W) 'cid.c'; else $(CYGPATH_W) '$(srcdir)/cid.c'; fi` + +xdvipdfmx-cmap.o: cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cmap.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-cmap.Tpo -c -o xdvipdfmx-cmap.o `test -f 'cmap.c' || echo '$(srcdir)/'`cmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cmap.Tpo $(DEPDIR)/xdvipdfmx-cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap.c' object='xdvipdfmx-cmap.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cmap.o `test -f 'cmap.c' || echo '$(srcdir)/'`cmap.c + +xdvipdfmx-cmap.obj: cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cmap.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-cmap.Tpo -c -o xdvipdfmx-cmap.obj `if test -f 'cmap.c'; then $(CYGPATH_W) 'cmap.c'; else $(CYGPATH_W) '$(srcdir)/cmap.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cmap.Tpo $(DEPDIR)/xdvipdfmx-cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap.c' object='xdvipdfmx-cmap.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cmap.obj `if test -f 'cmap.c'; then $(CYGPATH_W) 'cmap.c'; else $(CYGPATH_W) '$(srcdir)/cmap.c'; fi` + +xdvipdfmx-cmap_read.o: cmap_read.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cmap_read.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-cmap_read.Tpo -c -o xdvipdfmx-cmap_read.o `test -f 'cmap_read.c' || echo '$(srcdir)/'`cmap_read.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cmap_read.Tpo $(DEPDIR)/xdvipdfmx-cmap_read.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_read.c' object='xdvipdfmx-cmap_read.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cmap_read.o `test -f 'cmap_read.c' || echo '$(srcdir)/'`cmap_read.c + +xdvipdfmx-cmap_read.obj: cmap_read.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cmap_read.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-cmap_read.Tpo -c -o xdvipdfmx-cmap_read.obj `if test -f 'cmap_read.c'; then $(CYGPATH_W) 'cmap_read.c'; else $(CYGPATH_W) '$(srcdir)/cmap_read.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cmap_read.Tpo $(DEPDIR)/xdvipdfmx-cmap_read.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_read.c' object='xdvipdfmx-cmap_read.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cmap_read.obj `if test -f 'cmap_read.c'; then $(CYGPATH_W) 'cmap_read.c'; else $(CYGPATH_W) '$(srcdir)/cmap_read.c'; fi` + +xdvipdfmx-cmap_write.o: cmap_write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cmap_write.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-cmap_write.Tpo -c -o xdvipdfmx-cmap_write.o `test -f 'cmap_write.c' || echo '$(srcdir)/'`cmap_write.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cmap_write.Tpo $(DEPDIR)/xdvipdfmx-cmap_write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_write.c' object='xdvipdfmx-cmap_write.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cmap_write.o `test -f 'cmap_write.c' || echo '$(srcdir)/'`cmap_write.c + +xdvipdfmx-cmap_write.obj: cmap_write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cmap_write.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-cmap_write.Tpo -c -o xdvipdfmx-cmap_write.obj `if test -f 'cmap_write.c'; then $(CYGPATH_W) 'cmap_write.c'; else $(CYGPATH_W) '$(srcdir)/cmap_write.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cmap_write.Tpo $(DEPDIR)/xdvipdfmx-cmap_write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap_write.c' object='xdvipdfmx-cmap_write.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cmap_write.obj `if test -f 'cmap_write.c'; then $(CYGPATH_W) 'cmap_write.c'; else $(CYGPATH_W) '$(srcdir)/cmap_write.c'; fi` + +xdvipdfmx-cs_type2.o: cs_type2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cs_type2.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-cs_type2.Tpo -c -o xdvipdfmx-cs_type2.o `test -f 'cs_type2.c' || echo '$(srcdir)/'`cs_type2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cs_type2.Tpo $(DEPDIR)/xdvipdfmx-cs_type2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cs_type2.c' object='xdvipdfmx-cs_type2.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cs_type2.o `test -f 'cs_type2.c' || echo '$(srcdir)/'`cs_type2.c + +xdvipdfmx-cs_type2.obj: cs_type2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-cs_type2.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-cs_type2.Tpo -c -o xdvipdfmx-cs_type2.obj `if test -f 'cs_type2.c'; then $(CYGPATH_W) 'cs_type2.c'; else $(CYGPATH_W) '$(srcdir)/cs_type2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-cs_type2.Tpo $(DEPDIR)/xdvipdfmx-cs_type2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cs_type2.c' object='xdvipdfmx-cs_type2.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-cs_type2.obj `if test -f 'cs_type2.c'; then $(CYGPATH_W) 'cs_type2.c'; else $(CYGPATH_W) '$(srcdir)/cs_type2.c'; fi` + +xdvipdfmx-dpxconf.o: dpxconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-dpxconf.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-dpxconf.Tpo -c -o xdvipdfmx-dpxconf.o `test -f 'dpxconf.c' || echo '$(srcdir)/'`dpxconf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-dpxconf.Tpo $(DEPDIR)/xdvipdfmx-dpxconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxconf.c' object='xdvipdfmx-dpxconf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-dpxconf.o `test -f 'dpxconf.c' || echo '$(srcdir)/'`dpxconf.c + +xdvipdfmx-dpxconf.obj: dpxconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-dpxconf.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-dpxconf.Tpo -c -o xdvipdfmx-dpxconf.obj `if test -f 'dpxconf.c'; then $(CYGPATH_W) 'dpxconf.c'; else $(CYGPATH_W) '$(srcdir)/dpxconf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-dpxconf.Tpo $(DEPDIR)/xdvipdfmx-dpxconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxconf.c' object='xdvipdfmx-dpxconf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-dpxconf.obj `if test -f 'dpxconf.c'; then $(CYGPATH_W) 'dpxconf.c'; else $(CYGPATH_W) '$(srcdir)/dpxconf.c'; fi` + +xdvipdfmx-dpxcrypt.o: dpxcrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-dpxcrypt.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-dpxcrypt.Tpo -c -o xdvipdfmx-dpxcrypt.o `test -f 'dpxcrypt.c' || echo '$(srcdir)/'`dpxcrypt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-dpxcrypt.Tpo $(DEPDIR)/xdvipdfmx-dpxcrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxcrypt.c' object='xdvipdfmx-dpxcrypt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-dpxcrypt.o `test -f 'dpxcrypt.c' || echo '$(srcdir)/'`dpxcrypt.c + +xdvipdfmx-dpxcrypt.obj: dpxcrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-dpxcrypt.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-dpxcrypt.Tpo -c -o xdvipdfmx-dpxcrypt.obj `if test -f 'dpxcrypt.c'; then $(CYGPATH_W) 'dpxcrypt.c'; else $(CYGPATH_W) '$(srcdir)/dpxcrypt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-dpxcrypt.Tpo $(DEPDIR)/xdvipdfmx-dpxcrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dpxcrypt.c' object='xdvipdfmx-dpxcrypt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-dpxcrypt.obj `if test -f 'dpxcrypt.c'; then $(CYGPATH_W) 'dpxcrypt.c'; else $(CYGPATH_W) '$(srcdir)/dpxcrypt.c'; fi` + +xdvipdfmx-mem.o: mem.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-mem.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-mem.Tpo -c -o xdvipdfmx-mem.o `test -f 'mem.c' || echo '$(srcdir)/'`mem.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-mem.Tpo $(DEPDIR)/xdvipdfmx-mem.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mem.c' object='xdvipdfmx-mem.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-mem.o `test -f 'mem.c' || echo '$(srcdir)/'`mem.c + +xdvipdfmx-mem.obj: mem.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-mem.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-mem.Tpo -c -o xdvipdfmx-mem.obj `if test -f 'mem.c'; then $(CYGPATH_W) 'mem.c'; else $(CYGPATH_W) '$(srcdir)/mem.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-mem.Tpo $(DEPDIR)/xdvipdfmx-mem.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mem.c' object='xdvipdfmx-mem.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-mem.obj `if test -f 'mem.c'; then $(CYGPATH_W) 'mem.c'; else $(CYGPATH_W) '$(srcdir)/mem.c'; fi` + +xdvipdfmx-mfileio.o: mfileio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-mfileio.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-mfileio.Tpo -c -o xdvipdfmx-mfileio.o `test -f 'mfileio.c' || echo '$(srcdir)/'`mfileio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-mfileio.Tpo $(DEPDIR)/xdvipdfmx-mfileio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mfileio.c' object='xdvipdfmx-mfileio.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-mfileio.o `test -f 'mfileio.c' || echo '$(srcdir)/'`mfileio.c + +xdvipdfmx-mfileio.obj: mfileio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-mfileio.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-mfileio.Tpo -c -o xdvipdfmx-mfileio.obj `if test -f 'mfileio.c'; then $(CYGPATH_W) 'mfileio.c'; else $(CYGPATH_W) '$(srcdir)/mfileio.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-mfileio.Tpo $(DEPDIR)/xdvipdfmx-mfileio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mfileio.c' object='xdvipdfmx-mfileio.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-mfileio.obj `if test -f 'mfileio.c'; then $(CYGPATH_W) 'mfileio.c'; else $(CYGPATH_W) '$(srcdir)/mfileio.c'; fi` + +xdvipdfmx-numbers.o: numbers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-numbers.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-numbers.Tpo -c -o xdvipdfmx-numbers.o `test -f 'numbers.c' || echo '$(srcdir)/'`numbers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-numbers.Tpo $(DEPDIR)/xdvipdfmx-numbers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='numbers.c' object='xdvipdfmx-numbers.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-numbers.o `test -f 'numbers.c' || echo '$(srcdir)/'`numbers.c + +xdvipdfmx-numbers.obj: numbers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-numbers.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-numbers.Tpo -c -o xdvipdfmx-numbers.obj `if test -f 'numbers.c'; then $(CYGPATH_W) 'numbers.c'; else $(CYGPATH_W) '$(srcdir)/numbers.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-numbers.Tpo $(DEPDIR)/xdvipdfmx-numbers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='numbers.c' object='xdvipdfmx-numbers.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-numbers.obj `if test -f 'numbers.c'; then $(CYGPATH_W) 'numbers.c'; else $(CYGPATH_W) '$(srcdir)/numbers.c'; fi` + +xdvipdfmx-otl_conf.o: otl_conf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-otl_conf.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-otl_conf.Tpo -c -o xdvipdfmx-otl_conf.o `test -f 'otl_conf.c' || echo '$(srcdir)/'`otl_conf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-otl_conf.Tpo $(DEPDIR)/xdvipdfmx-otl_conf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_conf.c' object='xdvipdfmx-otl_conf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-otl_conf.o `test -f 'otl_conf.c' || echo '$(srcdir)/'`otl_conf.c + +xdvipdfmx-otl_conf.obj: otl_conf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-otl_conf.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-otl_conf.Tpo -c -o xdvipdfmx-otl_conf.obj `if test -f 'otl_conf.c'; then $(CYGPATH_W) 'otl_conf.c'; else $(CYGPATH_W) '$(srcdir)/otl_conf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-otl_conf.Tpo $(DEPDIR)/xdvipdfmx-otl_conf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_conf.c' object='xdvipdfmx-otl_conf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-otl_conf.obj `if test -f 'otl_conf.c'; then $(CYGPATH_W) 'otl_conf.c'; else $(CYGPATH_W) '$(srcdir)/otl_conf.c'; fi` + +xdvipdfmx-otl_opt.o: otl_opt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-otl_opt.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-otl_opt.Tpo -c -o xdvipdfmx-otl_opt.o `test -f 'otl_opt.c' || echo '$(srcdir)/'`otl_opt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-otl_opt.Tpo $(DEPDIR)/xdvipdfmx-otl_opt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_opt.c' object='xdvipdfmx-otl_opt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-otl_opt.o `test -f 'otl_opt.c' || echo '$(srcdir)/'`otl_opt.c + +xdvipdfmx-otl_opt.obj: otl_opt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-otl_opt.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-otl_opt.Tpo -c -o xdvipdfmx-otl_opt.obj `if test -f 'otl_opt.c'; then $(CYGPATH_W) 'otl_opt.c'; else $(CYGPATH_W) '$(srcdir)/otl_opt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-otl_opt.Tpo $(DEPDIR)/xdvipdfmx-otl_opt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='otl_opt.c' object='xdvipdfmx-otl_opt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-otl_opt.obj `if test -f 'otl_opt.c'; then $(CYGPATH_W) 'otl_opt.c'; else $(CYGPATH_W) '$(srcdir)/otl_opt.c'; fi` + +xdvipdfmx-pdfencoding.o: pdfencoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pdfencoding.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-pdfencoding.Tpo -c -o xdvipdfmx-pdfencoding.o `test -f 'pdfencoding.c' || echo '$(srcdir)/'`pdfencoding.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pdfencoding.Tpo $(DEPDIR)/xdvipdfmx-pdfencoding.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfencoding.c' object='xdvipdfmx-pdfencoding.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pdfencoding.o `test -f 'pdfencoding.c' || echo '$(srcdir)/'`pdfencoding.c + +xdvipdfmx-pdfencoding.obj: pdfencoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pdfencoding.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-pdfencoding.Tpo -c -o xdvipdfmx-pdfencoding.obj `if test -f 'pdfencoding.c'; then $(CYGPATH_W) 'pdfencoding.c'; else $(CYGPATH_W) '$(srcdir)/pdfencoding.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pdfencoding.Tpo $(DEPDIR)/xdvipdfmx-pdfencoding.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfencoding.c' object='xdvipdfmx-pdfencoding.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pdfencoding.obj `if test -f 'pdfencoding.c'; then $(CYGPATH_W) 'pdfencoding.c'; else $(CYGPATH_W) '$(srcdir)/pdfencoding.c'; fi` + +xdvipdfmx-pdffont.o: pdffont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pdffont.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-pdffont.Tpo -c -o xdvipdfmx-pdffont.o `test -f 'pdffont.c' || echo '$(srcdir)/'`pdffont.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pdffont.Tpo $(DEPDIR)/xdvipdfmx-pdffont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdffont.c' object='xdvipdfmx-pdffont.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pdffont.o `test -f 'pdffont.c' || echo '$(srcdir)/'`pdffont.c + +xdvipdfmx-pdffont.obj: pdffont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pdffont.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-pdffont.Tpo -c -o xdvipdfmx-pdffont.obj `if test -f 'pdffont.c'; then $(CYGPATH_W) 'pdffont.c'; else $(CYGPATH_W) '$(srcdir)/pdffont.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pdffont.Tpo $(DEPDIR)/xdvipdfmx-pdffont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdffont.c' object='xdvipdfmx-pdffont.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pdffont.obj `if test -f 'pdffont.c'; then $(CYGPATH_W) 'pdffont.c'; else $(CYGPATH_W) '$(srcdir)/pdffont.c'; fi` + +xdvipdfmx-pdfresource.o: pdfresource.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pdfresource.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-pdfresource.Tpo -c -o xdvipdfmx-pdfresource.o `test -f 'pdfresource.c' || echo '$(srcdir)/'`pdfresource.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pdfresource.Tpo $(DEPDIR)/xdvipdfmx-pdfresource.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfresource.c' object='xdvipdfmx-pdfresource.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pdfresource.o `test -f 'pdfresource.c' || echo '$(srcdir)/'`pdfresource.c + +xdvipdfmx-pdfresource.obj: pdfresource.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pdfresource.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-pdfresource.Tpo -c -o xdvipdfmx-pdfresource.obj `if test -f 'pdfresource.c'; then $(CYGPATH_W) 'pdfresource.c'; else $(CYGPATH_W) '$(srcdir)/pdfresource.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pdfresource.Tpo $(DEPDIR)/xdvipdfmx-pdfresource.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pdfresource.c' object='xdvipdfmx-pdfresource.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pdfresource.obj `if test -f 'pdfresource.c'; then $(CYGPATH_W) 'pdfresource.c'; else $(CYGPATH_W) '$(srcdir)/pdfresource.c'; fi` + +xdvipdfmx-pkfont.o: pkfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pkfont.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-pkfont.Tpo -c -o xdvipdfmx-pkfont.o `test -f 'pkfont.c' || echo '$(srcdir)/'`pkfont.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pkfont.Tpo $(DEPDIR)/xdvipdfmx-pkfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkfont.c' object='xdvipdfmx-pkfont.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pkfont.o `test -f 'pkfont.c' || echo '$(srcdir)/'`pkfont.c + +xdvipdfmx-pkfont.obj: pkfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pkfont.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-pkfont.Tpo -c -o xdvipdfmx-pkfont.obj `if test -f 'pkfont.c'; then $(CYGPATH_W) 'pkfont.c'; else $(CYGPATH_W) '$(srcdir)/pkfont.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pkfont.Tpo $(DEPDIR)/xdvipdfmx-pkfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pkfont.c' object='xdvipdfmx-pkfont.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pkfont.obj `if test -f 'pkfont.c'; then $(CYGPATH_W) 'pkfont.c'; else $(CYGPATH_W) '$(srcdir)/pkfont.c'; fi` + +xdvipdfmx-pst.o: pst.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pst.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-pst.Tpo -c -o xdvipdfmx-pst.o `test -f 'pst.c' || echo '$(srcdir)/'`pst.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pst.Tpo $(DEPDIR)/xdvipdfmx-pst.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst.c' object='xdvipdfmx-pst.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pst.o `test -f 'pst.c' || echo '$(srcdir)/'`pst.c + +xdvipdfmx-pst.obj: pst.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pst.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-pst.Tpo -c -o xdvipdfmx-pst.obj `if test -f 'pst.c'; then $(CYGPATH_W) 'pst.c'; else $(CYGPATH_W) '$(srcdir)/pst.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pst.Tpo $(DEPDIR)/xdvipdfmx-pst.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst.c' object='xdvipdfmx-pst.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pst.obj `if test -f 'pst.c'; then $(CYGPATH_W) 'pst.c'; else $(CYGPATH_W) '$(srcdir)/pst.c'; fi` + +xdvipdfmx-pst_obj.o: pst_obj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pst_obj.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-pst_obj.Tpo -c -o xdvipdfmx-pst_obj.o `test -f 'pst_obj.c' || echo '$(srcdir)/'`pst_obj.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pst_obj.Tpo $(DEPDIR)/xdvipdfmx-pst_obj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst_obj.c' object='xdvipdfmx-pst_obj.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pst_obj.o `test -f 'pst_obj.c' || echo '$(srcdir)/'`pst_obj.c + +xdvipdfmx-pst_obj.obj: pst_obj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-pst_obj.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-pst_obj.Tpo -c -o xdvipdfmx-pst_obj.obj `if test -f 'pst_obj.c'; then $(CYGPATH_W) 'pst_obj.c'; else $(CYGPATH_W) '$(srcdir)/pst_obj.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-pst_obj.Tpo $(DEPDIR)/xdvipdfmx-pst_obj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pst_obj.c' object='xdvipdfmx-pst_obj.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-pst_obj.obj `if test -f 'pst_obj.c'; then $(CYGPATH_W) 'pst_obj.c'; else $(CYGPATH_W) '$(srcdir)/pst_obj.c'; fi` + +xdvipdfmx-spc_misc.o: spc_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-spc_misc.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-spc_misc.Tpo -c -o xdvipdfmx-spc_misc.o `test -f 'spc_misc.c' || echo '$(srcdir)/'`spc_misc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-spc_misc.Tpo $(DEPDIR)/xdvipdfmx-spc_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spc_misc.c' object='xdvipdfmx-spc_misc.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-spc_misc.o `test -f 'spc_misc.c' || echo '$(srcdir)/'`spc_misc.c + +xdvipdfmx-spc_misc.obj: spc_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-spc_misc.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-spc_misc.Tpo -c -o xdvipdfmx-spc_misc.obj `if test -f 'spc_misc.c'; then $(CYGPATH_W) 'spc_misc.c'; else $(CYGPATH_W) '$(srcdir)/spc_misc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-spc_misc.Tpo $(DEPDIR)/xdvipdfmx-spc_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spc_misc.c' object='xdvipdfmx-spc_misc.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-spc_misc.obj `if test -f 'spc_misc.c'; then $(CYGPATH_W) 'spc_misc.c'; else $(CYGPATH_W) '$(srcdir)/spc_misc.c'; fi` + +xdvipdfmx-subfont.o: subfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-subfont.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-subfont.Tpo -c -o xdvipdfmx-subfont.o `test -f 'subfont.c' || echo '$(srcdir)/'`subfont.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-subfont.Tpo $(DEPDIR)/xdvipdfmx-subfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='subfont.c' object='xdvipdfmx-subfont.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-subfont.o `test -f 'subfont.c' || echo '$(srcdir)/'`subfont.c + +xdvipdfmx-subfont.obj: subfont.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-subfont.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-subfont.Tpo -c -o xdvipdfmx-subfont.obj `if test -f 'subfont.c'; then $(CYGPATH_W) 'subfont.c'; else $(CYGPATH_W) '$(srcdir)/subfont.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-subfont.Tpo $(DEPDIR)/xdvipdfmx-subfont.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='subfont.c' object='xdvipdfmx-subfont.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-subfont.obj `if test -f 'subfont.c'; then $(CYGPATH_W) 'subfont.c'; else $(CYGPATH_W) '$(srcdir)/subfont.c'; fi` + +xdvipdfmx-t1_char.o: t1_char.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-t1_char.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-t1_char.Tpo -c -o xdvipdfmx-t1_char.o `test -f 't1_char.c' || echo '$(srcdir)/'`t1_char.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-t1_char.Tpo $(DEPDIR)/xdvipdfmx-t1_char.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_char.c' object='xdvipdfmx-t1_char.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-t1_char.o `test -f 't1_char.c' || echo '$(srcdir)/'`t1_char.c + +xdvipdfmx-t1_char.obj: t1_char.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-t1_char.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-t1_char.Tpo -c -o xdvipdfmx-t1_char.obj `if test -f 't1_char.c'; then $(CYGPATH_W) 't1_char.c'; else $(CYGPATH_W) '$(srcdir)/t1_char.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-t1_char.Tpo $(DEPDIR)/xdvipdfmx-t1_char.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_char.c' object='xdvipdfmx-t1_char.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-t1_char.obj `if test -f 't1_char.c'; then $(CYGPATH_W) 't1_char.c'; else $(CYGPATH_W) '$(srcdir)/t1_char.c'; fi` + +xdvipdfmx-t1_load.o: t1_load.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-t1_load.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-t1_load.Tpo -c -o xdvipdfmx-t1_load.o `test -f 't1_load.c' || echo '$(srcdir)/'`t1_load.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-t1_load.Tpo $(DEPDIR)/xdvipdfmx-t1_load.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_load.c' object='xdvipdfmx-t1_load.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-t1_load.o `test -f 't1_load.c' || echo '$(srcdir)/'`t1_load.c + +xdvipdfmx-t1_load.obj: t1_load.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-t1_load.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-t1_load.Tpo -c -o xdvipdfmx-t1_load.obj `if test -f 't1_load.c'; then $(CYGPATH_W) 't1_load.c'; else $(CYGPATH_W) '$(srcdir)/t1_load.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-t1_load.Tpo $(DEPDIR)/xdvipdfmx-t1_load.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1_load.c' object='xdvipdfmx-t1_load.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-t1_load.obj `if test -f 't1_load.c'; then $(CYGPATH_W) 't1_load.c'; else $(CYGPATH_W) '$(srcdir)/t1_load.c'; fi` + +xdvipdfmx-tt_gsub.o: tt_gsub.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-tt_gsub.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-tt_gsub.Tpo -c -o xdvipdfmx-tt_gsub.o `test -f 'tt_gsub.c' || echo '$(srcdir)/'`tt_gsub.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-tt_gsub.Tpo $(DEPDIR)/xdvipdfmx-tt_gsub.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tt_gsub.c' object='xdvipdfmx-tt_gsub.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-tt_gsub.o `test -f 'tt_gsub.c' || echo '$(srcdir)/'`tt_gsub.c + +xdvipdfmx-tt_gsub.obj: tt_gsub.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-tt_gsub.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-tt_gsub.Tpo -c -o xdvipdfmx-tt_gsub.obj `if test -f 'tt_gsub.c'; then $(CYGPATH_W) 'tt_gsub.c'; else $(CYGPATH_W) '$(srcdir)/tt_gsub.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-tt_gsub.Tpo $(DEPDIR)/xdvipdfmx-tt_gsub.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tt_gsub.c' object='xdvipdfmx-tt_gsub.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-tt_gsub.obj `if test -f 'tt_gsub.c'; then $(CYGPATH_W) 'tt_gsub.c'; else $(CYGPATH_W) '$(srcdir)/tt_gsub.c'; fi` + +xdvipdfmx-unicode.o: unicode.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-unicode.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-unicode.Tpo -c -o xdvipdfmx-unicode.o `test -f 'unicode.c' || echo '$(srcdir)/'`unicode.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-unicode.Tpo $(DEPDIR)/xdvipdfmx-unicode.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicode.c' object='xdvipdfmx-unicode.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-unicode.o `test -f 'unicode.c' || echo '$(srcdir)/'`unicode.c + +xdvipdfmx-unicode.obj: unicode.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-unicode.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-unicode.Tpo -c -o xdvipdfmx-unicode.obj `if test -f 'unicode.c'; then $(CYGPATH_W) 'unicode.c'; else $(CYGPATH_W) '$(srcdir)/unicode.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-unicode.Tpo $(DEPDIR)/xdvipdfmx-unicode.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicode.c' object='xdvipdfmx-unicode.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-unicode.obj `if test -f 'unicode.c'; then $(CYGPATH_W) 'unicode.c'; else $(CYGPATH_W) '$(srcdir)/unicode.c'; fi` + +xsrc/xdvipdfmx-bmpimage.o: xsrc/bmpimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-bmpimage.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-bmpimage.Tpo -c -o xsrc/xdvipdfmx-bmpimage.o `test -f 'xsrc/bmpimage.c' || echo '$(srcdir)/'`xsrc/bmpimage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-bmpimage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-bmpimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/bmpimage.c' object='xsrc/xdvipdfmx-bmpimage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-bmpimage.o `test -f 'xsrc/bmpimage.c' || echo '$(srcdir)/'`xsrc/bmpimage.c + +xsrc/xdvipdfmx-bmpimage.obj: xsrc/bmpimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-bmpimage.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-bmpimage.Tpo -c -o xsrc/xdvipdfmx-bmpimage.obj `if test -f 'xsrc/bmpimage.c'; then $(CYGPATH_W) 'xsrc/bmpimage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/bmpimage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-bmpimage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-bmpimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/bmpimage.c' object='xsrc/xdvipdfmx-bmpimage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-bmpimage.obj `if test -f 'xsrc/bmpimage.c'; then $(CYGPATH_W) 'xsrc/bmpimage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/bmpimage.c'; fi` + +xsrc/xdvipdfmx-cff.o: xsrc/cff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cff.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cff.Tpo -c -o xsrc/xdvipdfmx-cff.o `test -f 'xsrc/cff.c' || echo '$(srcdir)/'`xsrc/cff.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cff.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cff.c' object='xsrc/xdvipdfmx-cff.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cff.o `test -f 'xsrc/cff.c' || echo '$(srcdir)/'`xsrc/cff.c + +xsrc/xdvipdfmx-cff.obj: xsrc/cff.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cff.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cff.Tpo -c -o xsrc/xdvipdfmx-cff.obj `if test -f 'xsrc/cff.c'; then $(CYGPATH_W) 'xsrc/cff.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cff.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cff.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cff.c' object='xsrc/xdvipdfmx-cff.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cff.obj `if test -f 'xsrc/cff.c'; then $(CYGPATH_W) 'xsrc/cff.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cff.c'; fi` + +xsrc/xdvipdfmx-cff_dict.o: xsrc/cff_dict.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cff_dict.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cff_dict.Tpo -c -o xsrc/xdvipdfmx-cff_dict.o `test -f 'xsrc/cff_dict.c' || echo '$(srcdir)/'`xsrc/cff_dict.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cff_dict.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cff_dict.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cff_dict.c' object='xsrc/xdvipdfmx-cff_dict.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cff_dict.o `test -f 'xsrc/cff_dict.c' || echo '$(srcdir)/'`xsrc/cff_dict.c + +xsrc/xdvipdfmx-cff_dict.obj: xsrc/cff_dict.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cff_dict.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cff_dict.Tpo -c -o xsrc/xdvipdfmx-cff_dict.obj `if test -f 'xsrc/cff_dict.c'; then $(CYGPATH_W) 'xsrc/cff_dict.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cff_dict.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cff_dict.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cff_dict.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cff_dict.c' object='xsrc/xdvipdfmx-cff_dict.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cff_dict.obj `if test -f 'xsrc/cff_dict.c'; then $(CYGPATH_W) 'xsrc/cff_dict.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cff_dict.c'; fi` + +xsrc/xdvipdfmx-cidtype0.o: xsrc/cidtype0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cidtype0.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cidtype0.Tpo -c -o xsrc/xdvipdfmx-cidtype0.o `test -f 'xsrc/cidtype0.c' || echo '$(srcdir)/'`xsrc/cidtype0.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cidtype0.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cidtype0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cidtype0.c' object='xsrc/xdvipdfmx-cidtype0.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cidtype0.o `test -f 'xsrc/cidtype0.c' || echo '$(srcdir)/'`xsrc/cidtype0.c + +xsrc/xdvipdfmx-cidtype0.obj: xsrc/cidtype0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cidtype0.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cidtype0.Tpo -c -o xsrc/xdvipdfmx-cidtype0.obj `if test -f 'xsrc/cidtype0.c'; then $(CYGPATH_W) 'xsrc/cidtype0.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cidtype0.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cidtype0.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cidtype0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cidtype0.c' object='xsrc/xdvipdfmx-cidtype0.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cidtype0.obj `if test -f 'xsrc/cidtype0.c'; then $(CYGPATH_W) 'xsrc/cidtype0.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cidtype0.c'; fi` + +xsrc/xdvipdfmx-cidtype2.o: xsrc/cidtype2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cidtype2.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cidtype2.Tpo -c -o xsrc/xdvipdfmx-cidtype2.o `test -f 'xsrc/cidtype2.c' || echo '$(srcdir)/'`xsrc/cidtype2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cidtype2.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cidtype2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cidtype2.c' object='xsrc/xdvipdfmx-cidtype2.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cidtype2.o `test -f 'xsrc/cidtype2.c' || echo '$(srcdir)/'`xsrc/cidtype2.c + +xsrc/xdvipdfmx-cidtype2.obj: xsrc/cidtype2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-cidtype2.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-cidtype2.Tpo -c -o xsrc/xdvipdfmx-cidtype2.obj `if test -f 'xsrc/cidtype2.c'; then $(CYGPATH_W) 'xsrc/cidtype2.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cidtype2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-cidtype2.Tpo xsrc/$(DEPDIR)/xdvipdfmx-cidtype2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/cidtype2.c' object='xsrc/xdvipdfmx-cidtype2.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-cidtype2.obj `if test -f 'xsrc/cidtype2.c'; then $(CYGPATH_W) 'xsrc/cidtype2.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/cidtype2.c'; fi` + +xsrc/xdvipdfmx-dpxfile.o: xsrc/dpxfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dpxfile.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dpxfile.Tpo -c -o xsrc/xdvipdfmx-dpxfile.o `test -f 'xsrc/dpxfile.c' || echo '$(srcdir)/'`xsrc/dpxfile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dpxfile.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dpxfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dpxfile.c' object='xsrc/xdvipdfmx-dpxfile.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dpxfile.o `test -f 'xsrc/dpxfile.c' || echo '$(srcdir)/'`xsrc/dpxfile.c + +xsrc/xdvipdfmx-dpxfile.obj: xsrc/dpxfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dpxfile.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dpxfile.Tpo -c -o xsrc/xdvipdfmx-dpxfile.obj `if test -f 'xsrc/dpxfile.c'; then $(CYGPATH_W) 'xsrc/dpxfile.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dpxfile.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dpxfile.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dpxfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dpxfile.c' object='xsrc/xdvipdfmx-dpxfile.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dpxfile.obj `if test -f 'xsrc/dpxfile.c'; then $(CYGPATH_W) 'xsrc/dpxfile.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dpxfile.c'; fi` + +xsrc/xdvipdfmx-dpxutil.o: xsrc/dpxutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dpxutil.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dpxutil.Tpo -c -o xsrc/xdvipdfmx-dpxutil.o `test -f 'xsrc/dpxutil.c' || echo '$(srcdir)/'`xsrc/dpxutil.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dpxutil.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dpxutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dpxutil.c' object='xsrc/xdvipdfmx-dpxutil.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dpxutil.o `test -f 'xsrc/dpxutil.c' || echo '$(srcdir)/'`xsrc/dpxutil.c + +xsrc/xdvipdfmx-dpxutil.obj: xsrc/dpxutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dpxutil.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dpxutil.Tpo -c -o xsrc/xdvipdfmx-dpxutil.obj `if test -f 'xsrc/dpxutil.c'; then $(CYGPATH_W) 'xsrc/dpxutil.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dpxutil.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dpxutil.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dpxutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dpxutil.c' object='xsrc/xdvipdfmx-dpxutil.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dpxutil.obj `if test -f 'xsrc/dpxutil.c'; then $(CYGPATH_W) 'xsrc/dpxutil.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dpxutil.c'; fi` + +xsrc/xdvipdfmx-dvi.o: xsrc/dvi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dvi.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dvi.Tpo -c -o xsrc/xdvipdfmx-dvi.o `test -f 'xsrc/dvi.c' || echo '$(srcdir)/'`xsrc/dvi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dvi.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dvi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dvi.c' object='xsrc/xdvipdfmx-dvi.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dvi.o `test -f 'xsrc/dvi.c' || echo '$(srcdir)/'`xsrc/dvi.c + +xsrc/xdvipdfmx-dvi.obj: xsrc/dvi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dvi.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dvi.Tpo -c -o xsrc/xdvipdfmx-dvi.obj `if test -f 'xsrc/dvi.c'; then $(CYGPATH_W) 'xsrc/dvi.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dvi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dvi.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dvi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dvi.c' object='xsrc/xdvipdfmx-dvi.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dvi.obj `if test -f 'xsrc/dvi.c'; then $(CYGPATH_W) 'xsrc/dvi.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dvi.c'; fi` + +xsrc/xdvipdfmx-dvipdfmx.o: xsrc/dvipdfmx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dvipdfmx.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dvipdfmx.Tpo -c -o xsrc/xdvipdfmx-dvipdfmx.o `test -f 'xsrc/dvipdfmx.c' || echo '$(srcdir)/'`xsrc/dvipdfmx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dvipdfmx.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dvipdfmx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dvipdfmx.c' object='xsrc/xdvipdfmx-dvipdfmx.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dvipdfmx.o `test -f 'xsrc/dvipdfmx.c' || echo '$(srcdir)/'`xsrc/dvipdfmx.c + +xsrc/xdvipdfmx-dvipdfmx.obj: xsrc/dvipdfmx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-dvipdfmx.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-dvipdfmx.Tpo -c -o xsrc/xdvipdfmx-dvipdfmx.obj `if test -f 'xsrc/dvipdfmx.c'; then $(CYGPATH_W) 'xsrc/dvipdfmx.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dvipdfmx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-dvipdfmx.Tpo xsrc/$(DEPDIR)/xdvipdfmx-dvipdfmx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/dvipdfmx.c' object='xsrc/xdvipdfmx-dvipdfmx.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-dvipdfmx.obj `if test -f 'xsrc/dvipdfmx.c'; then $(CYGPATH_W) 'xsrc/dvipdfmx.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/dvipdfmx.c'; fi` + +xsrc/xdvipdfmx-epdf.o: xsrc/epdf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-epdf.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-epdf.Tpo -c -o xsrc/xdvipdfmx-epdf.o `test -f 'xsrc/epdf.c' || echo '$(srcdir)/'`xsrc/epdf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-epdf.Tpo xsrc/$(DEPDIR)/xdvipdfmx-epdf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/epdf.c' object='xsrc/xdvipdfmx-epdf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-epdf.o `test -f 'xsrc/epdf.c' || echo '$(srcdir)/'`xsrc/epdf.c + +xsrc/xdvipdfmx-epdf.obj: xsrc/epdf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-epdf.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-epdf.Tpo -c -o xsrc/xdvipdfmx-epdf.obj `if test -f 'xsrc/epdf.c'; then $(CYGPATH_W) 'xsrc/epdf.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/epdf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-epdf.Tpo xsrc/$(DEPDIR)/xdvipdfmx-epdf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/epdf.c' object='xsrc/xdvipdfmx-epdf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-epdf.obj `if test -f 'xsrc/epdf.c'; then $(CYGPATH_W) 'xsrc/epdf.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/epdf.c'; fi` + +xsrc/xdvipdfmx-error.o: xsrc/error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-error.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-error.Tpo -c -o xsrc/xdvipdfmx-error.o `test -f 'xsrc/error.c' || echo '$(srcdir)/'`xsrc/error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-error.Tpo xsrc/$(DEPDIR)/xdvipdfmx-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/error.c' object='xsrc/xdvipdfmx-error.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-error.o `test -f 'xsrc/error.c' || echo '$(srcdir)/'`xsrc/error.c + +xsrc/xdvipdfmx-error.obj: xsrc/error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-error.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-error.Tpo -c -o xsrc/xdvipdfmx-error.obj `if test -f 'xsrc/error.c'; then $(CYGPATH_W) 'xsrc/error.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/error.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-error.Tpo xsrc/$(DEPDIR)/xdvipdfmx-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/error.c' object='xsrc/xdvipdfmx-error.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-error.obj `if test -f 'xsrc/error.c'; then $(CYGPATH_W) 'xsrc/error.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/error.c'; fi` + +xsrc/xdvipdfmx-fontmap.o: xsrc/fontmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-fontmap.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-fontmap.Tpo -c -o xsrc/xdvipdfmx-fontmap.o `test -f 'xsrc/fontmap.c' || echo '$(srcdir)/'`xsrc/fontmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-fontmap.Tpo xsrc/$(DEPDIR)/xdvipdfmx-fontmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/fontmap.c' object='xsrc/xdvipdfmx-fontmap.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-fontmap.o `test -f 'xsrc/fontmap.c' || echo '$(srcdir)/'`xsrc/fontmap.c + +xsrc/xdvipdfmx-fontmap.obj: xsrc/fontmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-fontmap.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-fontmap.Tpo -c -o xsrc/xdvipdfmx-fontmap.obj `if test -f 'xsrc/fontmap.c'; then $(CYGPATH_W) 'xsrc/fontmap.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/fontmap.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-fontmap.Tpo xsrc/$(DEPDIR)/xdvipdfmx-fontmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/fontmap.c' object='xsrc/xdvipdfmx-fontmap.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-fontmap.obj `if test -f 'xsrc/fontmap.c'; then $(CYGPATH_W) 'xsrc/fontmap.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/fontmap.c'; fi` + +xsrc/xdvipdfmx-jpegimage.o: xsrc/jpegimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-jpegimage.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-jpegimage.Tpo -c -o xsrc/xdvipdfmx-jpegimage.o `test -f 'xsrc/jpegimage.c' || echo '$(srcdir)/'`xsrc/jpegimage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-jpegimage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-jpegimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/jpegimage.c' object='xsrc/xdvipdfmx-jpegimage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-jpegimage.o `test -f 'xsrc/jpegimage.c' || echo '$(srcdir)/'`xsrc/jpegimage.c + +xsrc/xdvipdfmx-jpegimage.obj: xsrc/jpegimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-jpegimage.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-jpegimage.Tpo -c -o xsrc/xdvipdfmx-jpegimage.obj `if test -f 'xsrc/jpegimage.c'; then $(CYGPATH_W) 'xsrc/jpegimage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/jpegimage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-jpegimage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-jpegimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/jpegimage.c' object='xsrc/xdvipdfmx-jpegimage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-jpegimage.obj `if test -f 'xsrc/jpegimage.c'; then $(CYGPATH_W) 'xsrc/jpegimage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/jpegimage.c'; fi` + +xsrc/xdvipdfmx-mpost.o: xsrc/mpost.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-mpost.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-mpost.Tpo -c -o xsrc/xdvipdfmx-mpost.o `test -f 'xsrc/mpost.c' || echo '$(srcdir)/'`xsrc/mpost.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-mpost.Tpo xsrc/$(DEPDIR)/xdvipdfmx-mpost.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/mpost.c' object='xsrc/xdvipdfmx-mpost.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-mpost.o `test -f 'xsrc/mpost.c' || echo '$(srcdir)/'`xsrc/mpost.c + +xsrc/xdvipdfmx-mpost.obj: xsrc/mpost.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-mpost.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-mpost.Tpo -c -o xsrc/xdvipdfmx-mpost.obj `if test -f 'xsrc/mpost.c'; then $(CYGPATH_W) 'xsrc/mpost.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/mpost.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-mpost.Tpo xsrc/$(DEPDIR)/xdvipdfmx-mpost.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/mpost.c' object='xsrc/xdvipdfmx-mpost.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-mpost.obj `if test -f 'xsrc/mpost.c'; then $(CYGPATH_W) 'xsrc/mpost.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/mpost.c'; fi` + +xsrc/xdvipdfmx-pdfcolor.o: xsrc/pdfcolor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfcolor.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfcolor.Tpo -c -o xsrc/xdvipdfmx-pdfcolor.o `test -f 'xsrc/pdfcolor.c' || echo '$(srcdir)/'`xsrc/pdfcolor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfcolor.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfcolor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfcolor.c' object='xsrc/xdvipdfmx-pdfcolor.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfcolor.o `test -f 'xsrc/pdfcolor.c' || echo '$(srcdir)/'`xsrc/pdfcolor.c + +xsrc/xdvipdfmx-pdfcolor.obj: xsrc/pdfcolor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfcolor.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfcolor.Tpo -c -o xsrc/xdvipdfmx-pdfcolor.obj `if test -f 'xsrc/pdfcolor.c'; then $(CYGPATH_W) 'xsrc/pdfcolor.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfcolor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfcolor.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfcolor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfcolor.c' object='xsrc/xdvipdfmx-pdfcolor.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfcolor.obj `if test -f 'xsrc/pdfcolor.c'; then $(CYGPATH_W) 'xsrc/pdfcolor.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfcolor.c'; fi` + +xsrc/xdvipdfmx-pdfdev.o: xsrc/pdfdev.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfdev.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfdev.Tpo -c -o xsrc/xdvipdfmx-pdfdev.o `test -f 'xsrc/pdfdev.c' || echo '$(srcdir)/'`xsrc/pdfdev.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfdev.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfdev.c' object='xsrc/xdvipdfmx-pdfdev.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfdev.o `test -f 'xsrc/pdfdev.c' || echo '$(srcdir)/'`xsrc/pdfdev.c + +xsrc/xdvipdfmx-pdfdev.obj: xsrc/pdfdev.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfdev.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfdev.Tpo -c -o xsrc/xdvipdfmx-pdfdev.obj `if test -f 'xsrc/pdfdev.c'; then $(CYGPATH_W) 'xsrc/pdfdev.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfdev.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfdev.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfdev.c' object='xsrc/xdvipdfmx-pdfdev.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfdev.obj `if test -f 'xsrc/pdfdev.c'; then $(CYGPATH_W) 'xsrc/pdfdev.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfdev.c'; fi` + +xsrc/xdvipdfmx-pdfdoc.o: xsrc/pdfdoc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfdoc.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfdoc.Tpo -c -o xsrc/xdvipdfmx-pdfdoc.o `test -f 'xsrc/pdfdoc.c' || echo '$(srcdir)/'`xsrc/pdfdoc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfdoc.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfdoc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfdoc.c' object='xsrc/xdvipdfmx-pdfdoc.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfdoc.o `test -f 'xsrc/pdfdoc.c' || echo '$(srcdir)/'`xsrc/pdfdoc.c + +xsrc/xdvipdfmx-pdfdoc.obj: xsrc/pdfdoc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfdoc.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfdoc.Tpo -c -o xsrc/xdvipdfmx-pdfdoc.obj `if test -f 'xsrc/pdfdoc.c'; then $(CYGPATH_W) 'xsrc/pdfdoc.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfdoc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfdoc.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfdoc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfdoc.c' object='xsrc/xdvipdfmx-pdfdoc.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfdoc.obj `if test -f 'xsrc/pdfdoc.c'; then $(CYGPATH_W) 'xsrc/pdfdoc.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfdoc.c'; fi` + +xsrc/xdvipdfmx-pdfdraw.o: xsrc/pdfdraw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfdraw.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfdraw.Tpo -c -o xsrc/xdvipdfmx-pdfdraw.o `test -f 'xsrc/pdfdraw.c' || echo '$(srcdir)/'`xsrc/pdfdraw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfdraw.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfdraw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfdraw.c' object='xsrc/xdvipdfmx-pdfdraw.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfdraw.o `test -f 'xsrc/pdfdraw.c' || echo '$(srcdir)/'`xsrc/pdfdraw.c + +xsrc/xdvipdfmx-pdfdraw.obj: xsrc/pdfdraw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfdraw.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfdraw.Tpo -c -o xsrc/xdvipdfmx-pdfdraw.obj `if test -f 'xsrc/pdfdraw.c'; then $(CYGPATH_W) 'xsrc/pdfdraw.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfdraw.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfdraw.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfdraw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfdraw.c' object='xsrc/xdvipdfmx-pdfdraw.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfdraw.obj `if test -f 'xsrc/pdfdraw.c'; then $(CYGPATH_W) 'xsrc/pdfdraw.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfdraw.c'; fi` + +xsrc/xdvipdfmx-pdfencrypt.o: xsrc/pdfencrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfencrypt.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfencrypt.Tpo -c -o xsrc/xdvipdfmx-pdfencrypt.o `test -f 'xsrc/pdfencrypt.c' || echo '$(srcdir)/'`xsrc/pdfencrypt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfencrypt.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfencrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfencrypt.c' object='xsrc/xdvipdfmx-pdfencrypt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfencrypt.o `test -f 'xsrc/pdfencrypt.c' || echo '$(srcdir)/'`xsrc/pdfencrypt.c + +xsrc/xdvipdfmx-pdfencrypt.obj: xsrc/pdfencrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfencrypt.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfencrypt.Tpo -c -o xsrc/xdvipdfmx-pdfencrypt.obj `if test -f 'xsrc/pdfencrypt.c'; then $(CYGPATH_W) 'xsrc/pdfencrypt.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfencrypt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfencrypt.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfencrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfencrypt.c' object='xsrc/xdvipdfmx-pdfencrypt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfencrypt.obj `if test -f 'xsrc/pdfencrypt.c'; then $(CYGPATH_W) 'xsrc/pdfencrypt.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfencrypt.c'; fi` + +xsrc/xdvipdfmx-pdfnames.o: xsrc/pdfnames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfnames.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfnames.Tpo -c -o xsrc/xdvipdfmx-pdfnames.o `test -f 'xsrc/pdfnames.c' || echo '$(srcdir)/'`xsrc/pdfnames.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfnames.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfnames.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfnames.c' object='xsrc/xdvipdfmx-pdfnames.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfnames.o `test -f 'xsrc/pdfnames.c' || echo '$(srcdir)/'`xsrc/pdfnames.c + +xsrc/xdvipdfmx-pdfnames.obj: xsrc/pdfnames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfnames.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfnames.Tpo -c -o xsrc/xdvipdfmx-pdfnames.obj `if test -f 'xsrc/pdfnames.c'; then $(CYGPATH_W) 'xsrc/pdfnames.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfnames.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfnames.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfnames.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfnames.c' object='xsrc/xdvipdfmx-pdfnames.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfnames.obj `if test -f 'xsrc/pdfnames.c'; then $(CYGPATH_W) 'xsrc/pdfnames.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfnames.c'; fi` + +xsrc/xdvipdfmx-pdfobj.o: xsrc/pdfobj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfobj.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfobj.Tpo -c -o xsrc/xdvipdfmx-pdfobj.o `test -f 'xsrc/pdfobj.c' || echo '$(srcdir)/'`xsrc/pdfobj.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfobj.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfobj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfobj.c' object='xsrc/xdvipdfmx-pdfobj.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfobj.o `test -f 'xsrc/pdfobj.c' || echo '$(srcdir)/'`xsrc/pdfobj.c + +xsrc/xdvipdfmx-pdfobj.obj: xsrc/pdfobj.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfobj.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfobj.Tpo -c -o xsrc/xdvipdfmx-pdfobj.obj `if test -f 'xsrc/pdfobj.c'; then $(CYGPATH_W) 'xsrc/pdfobj.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfobj.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfobj.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfobj.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfobj.c' object='xsrc/xdvipdfmx-pdfobj.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfobj.obj `if test -f 'xsrc/pdfobj.c'; then $(CYGPATH_W) 'xsrc/pdfobj.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfobj.c'; fi` + +xsrc/xdvipdfmx-pdfparse.o: xsrc/pdfparse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfparse.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfparse.Tpo -c -o xsrc/xdvipdfmx-pdfparse.o `test -f 'xsrc/pdfparse.c' || echo '$(srcdir)/'`xsrc/pdfparse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfparse.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfparse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfparse.c' object='xsrc/xdvipdfmx-pdfparse.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfparse.o `test -f 'xsrc/pdfparse.c' || echo '$(srcdir)/'`xsrc/pdfparse.c + +xsrc/xdvipdfmx-pdfparse.obj: xsrc/pdfparse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfparse.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfparse.Tpo -c -o xsrc/xdvipdfmx-pdfparse.obj `if test -f 'xsrc/pdfparse.c'; then $(CYGPATH_W) 'xsrc/pdfparse.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfparse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfparse.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfparse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfparse.c' object='xsrc/xdvipdfmx-pdfparse.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfparse.obj `if test -f 'xsrc/pdfparse.c'; then $(CYGPATH_W) 'xsrc/pdfparse.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfparse.c'; fi` + +xsrc/xdvipdfmx-pdfximage.o: xsrc/pdfximage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfximage.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfximage.Tpo -c -o xsrc/xdvipdfmx-pdfximage.o `test -f 'xsrc/pdfximage.c' || echo '$(srcdir)/'`xsrc/pdfximage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfximage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfximage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfximage.c' object='xsrc/xdvipdfmx-pdfximage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfximage.o `test -f 'xsrc/pdfximage.c' || echo '$(srcdir)/'`xsrc/pdfximage.c + +xsrc/xdvipdfmx-pdfximage.obj: xsrc/pdfximage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pdfximage.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pdfximage.Tpo -c -o xsrc/xdvipdfmx-pdfximage.obj `if test -f 'xsrc/pdfximage.c'; then $(CYGPATH_W) 'xsrc/pdfximage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfximage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pdfximage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pdfximage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pdfximage.c' object='xsrc/xdvipdfmx-pdfximage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pdfximage.obj `if test -f 'xsrc/pdfximage.c'; then $(CYGPATH_W) 'xsrc/pdfximage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pdfximage.c'; fi` + +xsrc/xdvipdfmx-pngimage.o: xsrc/pngimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pngimage.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pngimage.Tpo -c -o xsrc/xdvipdfmx-pngimage.o `test -f 'xsrc/pngimage.c' || echo '$(srcdir)/'`xsrc/pngimage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pngimage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pngimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pngimage.c' object='xsrc/xdvipdfmx-pngimage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pngimage.o `test -f 'xsrc/pngimage.c' || echo '$(srcdir)/'`xsrc/pngimage.c + +xsrc/xdvipdfmx-pngimage.obj: xsrc/pngimage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-pngimage.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-pngimage.Tpo -c -o xsrc/xdvipdfmx-pngimage.obj `if test -f 'xsrc/pngimage.c'; then $(CYGPATH_W) 'xsrc/pngimage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pngimage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-pngimage.Tpo xsrc/$(DEPDIR)/xdvipdfmx-pngimage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/pngimage.c' object='xsrc/xdvipdfmx-pngimage.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-pngimage.obj `if test -f 'xsrc/pngimage.c'; then $(CYGPATH_W) 'xsrc/pngimage.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/pngimage.c'; fi` + +xsrc/xdvipdfmx-sfnt.o: xsrc/sfnt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-sfnt.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-sfnt.Tpo -c -o xsrc/xdvipdfmx-sfnt.o `test -f 'xsrc/sfnt.c' || echo '$(srcdir)/'`xsrc/sfnt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-sfnt.Tpo xsrc/$(DEPDIR)/xdvipdfmx-sfnt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/sfnt.c' object='xsrc/xdvipdfmx-sfnt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-sfnt.o `test -f 'xsrc/sfnt.c' || echo '$(srcdir)/'`xsrc/sfnt.c + +xsrc/xdvipdfmx-sfnt.obj: xsrc/sfnt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-sfnt.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-sfnt.Tpo -c -o xsrc/xdvipdfmx-sfnt.obj `if test -f 'xsrc/sfnt.c'; then $(CYGPATH_W) 'xsrc/sfnt.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/sfnt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-sfnt.Tpo xsrc/$(DEPDIR)/xdvipdfmx-sfnt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/sfnt.c' object='xsrc/xdvipdfmx-sfnt.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-sfnt.obj `if test -f 'xsrc/sfnt.c'; then $(CYGPATH_W) 'xsrc/sfnt.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/sfnt.c'; fi` + +xsrc/xdvipdfmx-spc_color.o: xsrc/spc_color.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_color.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_color.Tpo -c -o xsrc/xdvipdfmx-spc_color.o `test -f 'xsrc/spc_color.c' || echo '$(srcdir)/'`xsrc/spc_color.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_color.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_color.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_color.c' object='xsrc/xdvipdfmx-spc_color.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_color.o `test -f 'xsrc/spc_color.c' || echo '$(srcdir)/'`xsrc/spc_color.c + +xsrc/xdvipdfmx-spc_color.obj: xsrc/spc_color.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_color.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_color.Tpo -c -o xsrc/xdvipdfmx-spc_color.obj `if test -f 'xsrc/spc_color.c'; then $(CYGPATH_W) 'xsrc/spc_color.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_color.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_color.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_color.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_color.c' object='xsrc/xdvipdfmx-spc_color.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_color.obj `if test -f 'xsrc/spc_color.c'; then $(CYGPATH_W) 'xsrc/spc_color.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_color.c'; fi` + +xsrc/xdvipdfmx-spc_dvips.o: xsrc/spc_dvips.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_dvips.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_dvips.Tpo -c -o xsrc/xdvipdfmx-spc_dvips.o `test -f 'xsrc/spc_dvips.c' || echo '$(srcdir)/'`xsrc/spc_dvips.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_dvips.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_dvips.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_dvips.c' object='xsrc/xdvipdfmx-spc_dvips.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_dvips.o `test -f 'xsrc/spc_dvips.c' || echo '$(srcdir)/'`xsrc/spc_dvips.c + +xsrc/xdvipdfmx-spc_dvips.obj: xsrc/spc_dvips.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_dvips.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_dvips.Tpo -c -o xsrc/xdvipdfmx-spc_dvips.obj `if test -f 'xsrc/spc_dvips.c'; then $(CYGPATH_W) 'xsrc/spc_dvips.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_dvips.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_dvips.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_dvips.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_dvips.c' object='xsrc/xdvipdfmx-spc_dvips.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_dvips.obj `if test -f 'xsrc/spc_dvips.c'; then $(CYGPATH_W) 'xsrc/spc_dvips.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_dvips.c'; fi` + +xsrc/xdvipdfmx-spc_html.o: xsrc/spc_html.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_html.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_html.Tpo -c -o xsrc/xdvipdfmx-spc_html.o `test -f 'xsrc/spc_html.c' || echo '$(srcdir)/'`xsrc/spc_html.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_html.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_html.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_html.c' object='xsrc/xdvipdfmx-spc_html.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_html.o `test -f 'xsrc/spc_html.c' || echo '$(srcdir)/'`xsrc/spc_html.c + +xsrc/xdvipdfmx-spc_html.obj: xsrc/spc_html.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_html.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_html.Tpo -c -o xsrc/xdvipdfmx-spc_html.obj `if test -f 'xsrc/spc_html.c'; then $(CYGPATH_W) 'xsrc/spc_html.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_html.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_html.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_html.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_html.c' object='xsrc/xdvipdfmx-spc_html.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_html.obj `if test -f 'xsrc/spc_html.c'; then $(CYGPATH_W) 'xsrc/spc_html.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_html.c'; fi` + +xsrc/xdvipdfmx-spc_pdfm.o: xsrc/spc_pdfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_pdfm.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_pdfm.Tpo -c -o xsrc/xdvipdfmx-spc_pdfm.o `test -f 'xsrc/spc_pdfm.c' || echo '$(srcdir)/'`xsrc/spc_pdfm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_pdfm.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_pdfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_pdfm.c' object='xsrc/xdvipdfmx-spc_pdfm.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_pdfm.o `test -f 'xsrc/spc_pdfm.c' || echo '$(srcdir)/'`xsrc/spc_pdfm.c + +xsrc/xdvipdfmx-spc_pdfm.obj: xsrc/spc_pdfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_pdfm.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_pdfm.Tpo -c -o xsrc/xdvipdfmx-spc_pdfm.obj `if test -f 'xsrc/spc_pdfm.c'; then $(CYGPATH_W) 'xsrc/spc_pdfm.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_pdfm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_pdfm.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_pdfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_pdfm.c' object='xsrc/xdvipdfmx-spc_pdfm.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_pdfm.obj `if test -f 'xsrc/spc_pdfm.c'; then $(CYGPATH_W) 'xsrc/spc_pdfm.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_pdfm.c'; fi` + +xsrc/xdvipdfmx-spc_tpic.o: xsrc/spc_tpic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_tpic.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_tpic.Tpo -c -o xsrc/xdvipdfmx-spc_tpic.o `test -f 'xsrc/spc_tpic.c' || echo '$(srcdir)/'`xsrc/spc_tpic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_tpic.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_tpic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_tpic.c' object='xsrc/xdvipdfmx-spc_tpic.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_tpic.o `test -f 'xsrc/spc_tpic.c' || echo '$(srcdir)/'`xsrc/spc_tpic.c + +xsrc/xdvipdfmx-spc_tpic.obj: xsrc/spc_tpic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_tpic.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_tpic.Tpo -c -o xsrc/xdvipdfmx-spc_tpic.obj `if test -f 'xsrc/spc_tpic.c'; then $(CYGPATH_W) 'xsrc/spc_tpic.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_tpic.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_tpic.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_tpic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_tpic.c' object='xsrc/xdvipdfmx-spc_tpic.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_tpic.obj `if test -f 'xsrc/spc_tpic.c'; then $(CYGPATH_W) 'xsrc/spc_tpic.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_tpic.c'; fi` + +xsrc/xdvipdfmx-spc_util.o: xsrc/spc_util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_util.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_util.Tpo -c -o xsrc/xdvipdfmx-spc_util.o `test -f 'xsrc/spc_util.c' || echo '$(srcdir)/'`xsrc/spc_util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_util.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_util.c' object='xsrc/xdvipdfmx-spc_util.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_util.o `test -f 'xsrc/spc_util.c' || echo '$(srcdir)/'`xsrc/spc_util.c + +xsrc/xdvipdfmx-spc_util.obj: xsrc/spc_util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-spc_util.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-spc_util.Tpo -c -o xsrc/xdvipdfmx-spc_util.obj `if test -f 'xsrc/spc_util.c'; then $(CYGPATH_W) 'xsrc/spc_util.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-spc_util.Tpo xsrc/$(DEPDIR)/xdvipdfmx-spc_util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/spc_util.c' object='xsrc/xdvipdfmx-spc_util.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-spc_util.obj `if test -f 'xsrc/spc_util.c'; then $(CYGPATH_W) 'xsrc/spc_util.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/spc_util.c'; fi` + +xdvipdfmx-spc_xtx.o: spc_xtx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-spc_xtx.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-spc_xtx.Tpo -c -o xdvipdfmx-spc_xtx.o `test -f 'spc_xtx.c' || echo '$(srcdir)/'`spc_xtx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-spc_xtx.Tpo $(DEPDIR)/xdvipdfmx-spc_xtx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spc_xtx.c' object='xdvipdfmx-spc_xtx.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-spc_xtx.o `test -f 'spc_xtx.c' || echo '$(srcdir)/'`spc_xtx.c + +xdvipdfmx-spc_xtx.obj: spc_xtx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-spc_xtx.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-spc_xtx.Tpo -c -o xdvipdfmx-spc_xtx.obj `if test -f 'spc_xtx.c'; then $(CYGPATH_W) 'spc_xtx.c'; else $(CYGPATH_W) '$(srcdir)/spc_xtx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-spc_xtx.Tpo $(DEPDIR)/xdvipdfmx-spc_xtx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spc_xtx.c' object='xdvipdfmx-spc_xtx.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-spc_xtx.obj `if test -f 'spc_xtx.c'; then $(CYGPATH_W) 'spc_xtx.c'; else $(CYGPATH_W) '$(srcdir)/spc_xtx.c'; fi` + +xsrc/xdvipdfmx-specials.o: xsrc/specials.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-specials.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-specials.Tpo -c -o xsrc/xdvipdfmx-specials.o `test -f 'xsrc/specials.c' || echo '$(srcdir)/'`xsrc/specials.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-specials.Tpo xsrc/$(DEPDIR)/xdvipdfmx-specials.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/specials.c' object='xsrc/xdvipdfmx-specials.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-specials.o `test -f 'xsrc/specials.c' || echo '$(srcdir)/'`xsrc/specials.c + +xsrc/xdvipdfmx-specials.obj: xsrc/specials.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-specials.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-specials.Tpo -c -o xsrc/xdvipdfmx-specials.obj `if test -f 'xsrc/specials.c'; then $(CYGPATH_W) 'xsrc/specials.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/specials.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-specials.Tpo xsrc/$(DEPDIR)/xdvipdfmx-specials.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/specials.c' object='xsrc/xdvipdfmx-specials.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-specials.obj `if test -f 'xsrc/specials.c'; then $(CYGPATH_W) 'xsrc/specials.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/specials.c'; fi` + +xsrc/xdvipdfmx-tfm.o: xsrc/tfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tfm.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tfm.Tpo -c -o xsrc/xdvipdfmx-tfm.o `test -f 'xsrc/tfm.c' || echo '$(srcdir)/'`xsrc/tfm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tfm.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tfm.c' object='xsrc/xdvipdfmx-tfm.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tfm.o `test -f 'xsrc/tfm.c' || echo '$(srcdir)/'`xsrc/tfm.c + +xsrc/xdvipdfmx-tfm.obj: xsrc/tfm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tfm.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tfm.Tpo -c -o xsrc/xdvipdfmx-tfm.obj `if test -f 'xsrc/tfm.c'; then $(CYGPATH_W) 'xsrc/tfm.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tfm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tfm.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tfm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tfm.c' object='xsrc/xdvipdfmx-tfm.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tfm.obj `if test -f 'xsrc/tfm.c'; then $(CYGPATH_W) 'xsrc/tfm.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tfm.c'; fi` + +xsrc/xdvipdfmx-truetype.o: xsrc/truetype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-truetype.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-truetype.Tpo -c -o xsrc/xdvipdfmx-truetype.o `test -f 'xsrc/truetype.c' || echo '$(srcdir)/'`xsrc/truetype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-truetype.Tpo xsrc/$(DEPDIR)/xdvipdfmx-truetype.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/truetype.c' object='xsrc/xdvipdfmx-truetype.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-truetype.o `test -f 'xsrc/truetype.c' || echo '$(srcdir)/'`xsrc/truetype.c + +xsrc/xdvipdfmx-truetype.obj: xsrc/truetype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-truetype.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-truetype.Tpo -c -o xsrc/xdvipdfmx-truetype.obj `if test -f 'xsrc/truetype.c'; then $(CYGPATH_W) 'xsrc/truetype.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/truetype.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-truetype.Tpo xsrc/$(DEPDIR)/xdvipdfmx-truetype.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/truetype.c' object='xsrc/xdvipdfmx-truetype.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-truetype.obj `if test -f 'xsrc/truetype.c'; then $(CYGPATH_W) 'xsrc/truetype.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/truetype.c'; fi` + +xsrc/xdvipdfmx-tt_aux.o: xsrc/tt_aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_aux.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_aux.Tpo -c -o xsrc/xdvipdfmx-tt_aux.o `test -f 'xsrc/tt_aux.c' || echo '$(srcdir)/'`xsrc/tt_aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_aux.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_aux.c' object='xsrc/xdvipdfmx-tt_aux.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_aux.o `test -f 'xsrc/tt_aux.c' || echo '$(srcdir)/'`xsrc/tt_aux.c + +xsrc/xdvipdfmx-tt_aux.obj: xsrc/tt_aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_aux.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_aux.Tpo -c -o xsrc/xdvipdfmx-tt_aux.obj `if test -f 'xsrc/tt_aux.c'; then $(CYGPATH_W) 'xsrc/tt_aux.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_aux.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_aux.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_aux.c' object='xsrc/xdvipdfmx-tt_aux.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_aux.obj `if test -f 'xsrc/tt_aux.c'; then $(CYGPATH_W) 'xsrc/tt_aux.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_aux.c'; fi` + +xsrc/xdvipdfmx-tt_cmap.o: xsrc/tt_cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_cmap.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_cmap.Tpo -c -o xsrc/xdvipdfmx-tt_cmap.o `test -f 'xsrc/tt_cmap.c' || echo '$(srcdir)/'`xsrc/tt_cmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_cmap.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_cmap.c' object='xsrc/xdvipdfmx-tt_cmap.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_cmap.o `test -f 'xsrc/tt_cmap.c' || echo '$(srcdir)/'`xsrc/tt_cmap.c + +xsrc/xdvipdfmx-tt_cmap.obj: xsrc/tt_cmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_cmap.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_cmap.Tpo -c -o xsrc/xdvipdfmx-tt_cmap.obj `if test -f 'xsrc/tt_cmap.c'; then $(CYGPATH_W) 'xsrc/tt_cmap.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_cmap.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_cmap.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_cmap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_cmap.c' object='xsrc/xdvipdfmx-tt_cmap.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_cmap.obj `if test -f 'xsrc/tt_cmap.c'; then $(CYGPATH_W) 'xsrc/tt_cmap.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_cmap.c'; fi` + +xsrc/xdvipdfmx-tt_glyf.o: xsrc/tt_glyf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_glyf.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_glyf.Tpo -c -o xsrc/xdvipdfmx-tt_glyf.o `test -f 'xsrc/tt_glyf.c' || echo '$(srcdir)/'`xsrc/tt_glyf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_glyf.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_glyf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_glyf.c' object='xsrc/xdvipdfmx-tt_glyf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_glyf.o `test -f 'xsrc/tt_glyf.c' || echo '$(srcdir)/'`xsrc/tt_glyf.c + +xsrc/xdvipdfmx-tt_glyf.obj: xsrc/tt_glyf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_glyf.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_glyf.Tpo -c -o xsrc/xdvipdfmx-tt_glyf.obj `if test -f 'xsrc/tt_glyf.c'; then $(CYGPATH_W) 'xsrc/tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_glyf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_glyf.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_glyf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_glyf.c' object='xsrc/xdvipdfmx-tt_glyf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_glyf.obj `if test -f 'xsrc/tt_glyf.c'; then $(CYGPATH_W) 'xsrc/tt_glyf.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_glyf.c'; fi` + +xsrc/xdvipdfmx-tt_post.o: xsrc/tt_post.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_post.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_post.Tpo -c -o xsrc/xdvipdfmx-tt_post.o `test -f 'xsrc/tt_post.c' || echo '$(srcdir)/'`xsrc/tt_post.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_post.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_post.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_post.c' object='xsrc/xdvipdfmx-tt_post.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_post.o `test -f 'xsrc/tt_post.c' || echo '$(srcdir)/'`xsrc/tt_post.c + +xsrc/xdvipdfmx-tt_post.obj: xsrc/tt_post.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_post.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_post.Tpo -c -o xsrc/xdvipdfmx-tt_post.obj `if test -f 'xsrc/tt_post.c'; then $(CYGPATH_W) 'xsrc/tt_post.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_post.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_post.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_post.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_post.c' object='xsrc/xdvipdfmx-tt_post.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_post.obj `if test -f 'xsrc/tt_post.c'; then $(CYGPATH_W) 'xsrc/tt_post.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_post.c'; fi` + +xsrc/xdvipdfmx-tt_table.o: xsrc/tt_table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_table.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_table.Tpo -c -o xsrc/xdvipdfmx-tt_table.o `test -f 'xsrc/tt_table.c' || echo '$(srcdir)/'`xsrc/tt_table.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_table.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_table.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_table.c' object='xsrc/xdvipdfmx-tt_table.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_table.o `test -f 'xsrc/tt_table.c' || echo '$(srcdir)/'`xsrc/tt_table.c + +xsrc/xdvipdfmx-tt_table.obj: xsrc/tt_table.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-tt_table.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-tt_table.Tpo -c -o xsrc/xdvipdfmx-tt_table.obj `if test -f 'xsrc/tt_table.c'; then $(CYGPATH_W) 'xsrc/tt_table.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_table.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-tt_table.Tpo xsrc/$(DEPDIR)/xdvipdfmx-tt_table.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/tt_table.c' object='xsrc/xdvipdfmx-tt_table.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-tt_table.obj `if test -f 'xsrc/tt_table.c'; then $(CYGPATH_W) 'xsrc/tt_table.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/tt_table.c'; fi` + +xsrc/xdvipdfmx-type0.o: xsrc/type0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-type0.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-type0.Tpo -c -o xsrc/xdvipdfmx-type0.o `test -f 'xsrc/type0.c' || echo '$(srcdir)/'`xsrc/type0.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-type0.Tpo xsrc/$(DEPDIR)/xdvipdfmx-type0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/type0.c' object='xsrc/xdvipdfmx-type0.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-type0.o `test -f 'xsrc/type0.c' || echo '$(srcdir)/'`xsrc/type0.c + +xsrc/xdvipdfmx-type0.obj: xsrc/type0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-type0.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-type0.Tpo -c -o xsrc/xdvipdfmx-type0.obj `if test -f 'xsrc/type0.c'; then $(CYGPATH_W) 'xsrc/type0.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/type0.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-type0.Tpo xsrc/$(DEPDIR)/xdvipdfmx-type0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/type0.c' object='xsrc/xdvipdfmx-type0.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-type0.obj `if test -f 'xsrc/type0.c'; then $(CYGPATH_W) 'xsrc/type0.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/type0.c'; fi` + +xsrc/xdvipdfmx-type1.o: xsrc/type1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-type1.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-type1.Tpo -c -o xsrc/xdvipdfmx-type1.o `test -f 'xsrc/type1.c' || echo '$(srcdir)/'`xsrc/type1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-type1.Tpo xsrc/$(DEPDIR)/xdvipdfmx-type1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/type1.c' object='xsrc/xdvipdfmx-type1.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-type1.o `test -f 'xsrc/type1.c' || echo '$(srcdir)/'`xsrc/type1.c + +xsrc/xdvipdfmx-type1.obj: xsrc/type1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-type1.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-type1.Tpo -c -o xsrc/xdvipdfmx-type1.obj `if test -f 'xsrc/type1.c'; then $(CYGPATH_W) 'xsrc/type1.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/type1.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-type1.Tpo xsrc/$(DEPDIR)/xdvipdfmx-type1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/type1.c' object='xsrc/xdvipdfmx-type1.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-type1.obj `if test -f 'xsrc/type1.c'; then $(CYGPATH_W) 'xsrc/type1.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/type1.c'; fi` + +xsrc/xdvipdfmx-type1c.o: xsrc/type1c.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-type1c.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-type1c.Tpo -c -o xsrc/xdvipdfmx-type1c.o `test -f 'xsrc/type1c.c' || echo '$(srcdir)/'`xsrc/type1c.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-type1c.Tpo xsrc/$(DEPDIR)/xdvipdfmx-type1c.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/type1c.c' object='xsrc/xdvipdfmx-type1c.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-type1c.o `test -f 'xsrc/type1c.c' || echo '$(srcdir)/'`xsrc/type1c.c + +xsrc/xdvipdfmx-type1c.obj: xsrc/type1c.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-type1c.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-type1c.Tpo -c -o xsrc/xdvipdfmx-type1c.obj `if test -f 'xsrc/type1c.c'; then $(CYGPATH_W) 'xsrc/type1c.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/type1c.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-type1c.Tpo xsrc/$(DEPDIR)/xdvipdfmx-type1c.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/type1c.c' object='xsrc/xdvipdfmx-type1c.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-type1c.obj `if test -f 'xsrc/type1c.c'; then $(CYGPATH_W) 'xsrc/type1c.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/type1c.c'; fi` + +xsrc/xdvipdfmx-vf.o: xsrc/vf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-vf.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-vf.Tpo -c -o xsrc/xdvipdfmx-vf.o `test -f 'xsrc/vf.c' || echo '$(srcdir)/'`xsrc/vf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-vf.Tpo xsrc/$(DEPDIR)/xdvipdfmx-vf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/vf.c' object='xsrc/xdvipdfmx-vf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-vf.o `test -f 'xsrc/vf.c' || echo '$(srcdir)/'`xsrc/vf.c + +xsrc/xdvipdfmx-vf.obj: xsrc/vf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-vf.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-vf.Tpo -c -o xsrc/xdvipdfmx-vf.obj `if test -f 'xsrc/vf.c'; then $(CYGPATH_W) 'xsrc/vf.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/vf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-vf.Tpo xsrc/$(DEPDIR)/xdvipdfmx-vf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/vf.c' object='xsrc/xdvipdfmx-vf.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-vf.obj `if test -f 'xsrc/vf.c'; then $(CYGPATH_W) 'xsrc/vf.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/vf.c'; fi` + +xsrc/xdvipdfmx-xbb.o: xsrc/xbb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-xbb.o -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-xbb.Tpo -c -o xsrc/xdvipdfmx-xbb.o `test -f 'xsrc/xbb.c' || echo '$(srcdir)/'`xsrc/xbb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-xbb.Tpo xsrc/$(DEPDIR)/xdvipdfmx-xbb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/xbb.c' object='xsrc/xdvipdfmx-xbb.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-xbb.o `test -f 'xsrc/xbb.c' || echo '$(srcdir)/'`xsrc/xbb.c + +xsrc/xdvipdfmx-xbb.obj: xsrc/xbb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsrc/xdvipdfmx-xbb.obj -MD -MP -MF xsrc/$(DEPDIR)/xdvipdfmx-xbb.Tpo -c -o xsrc/xdvipdfmx-xbb.obj `if test -f 'xsrc/xbb.c'; then $(CYGPATH_W) 'xsrc/xbb.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/xbb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xsrc/$(DEPDIR)/xdvipdfmx-xbb.Tpo xsrc/$(DEPDIR)/xdvipdfmx-xbb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsrc/xbb.c' object='xsrc/xdvipdfmx-xbb.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) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsrc/xdvipdfmx-xbb.obj `if test -f 'xsrc/xbb.c'; then $(CYGPATH_W) 'xsrc/xbb.c'; else $(CYGPATH_W) '$(srcdir)/xsrc/xbb.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(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-recursive + +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-recursive + +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; \ + else \ + 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 for $(PACKAGE_STRING)$${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: $(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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || 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) | GZIP=$(GZIP_ENV) gzip -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-tarZ: distdir + @echo WARNING: "Support for shar distribution archives 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 distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -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*) \ + GZIP=$(GZIP_ENV) gzip -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*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(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 \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(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-recursive +all-am: Makefile $(PROGRAMS) $(SCRIPTS) config.h all-local +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +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) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + -rm -f xsrc/$(DEPDIR)/$(am__dirstamp) + -rm -f xsrc/$(am__dirstamp) + -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-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) src/$(DEPDIR) xsrc/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-dist_binSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) src/$(DEPDIR) xsrc/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-dist_binSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: $(am__recursive_targets) all check-am install-am \ + install-exec-am install-strip uninstall-am + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ + 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 \ + 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-dist_binSCRIPTS 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-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am 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-hook + + +$(dvipdfmx_OBJECTS): config.force +$(xdvipdfmx_OBJECTS): config.force $(FREETYPE2_DEPEND) +.PHONY: install-bin-links uninstall-bin-links + +install-bin-links: +@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 + +install-exec-hook: install-bin-links +@DVIPDFMX_TRUE@@WIN32_TRUE@ $(INSTALL_PROGRAM) call_dvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT) +@DVIPDFMX_TRUE@@WIN32_TRUE@ $(INSTALL_PROGRAM) call_dvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/ebb$(EXEEXT) +@DVIPDFMX_TRUE@@WIN32_TRUE@ $(INSTALL_PROGRAM) call_dvipdfmx$(EXEEXT) $(DESTDIR)$(bindir)/extractbb$(EXEEXT) + +uninstall-hook: uninstall-bin-links +@DVIPDFMX_TRUE@@WIN32_TRUE@ rm -f $(DESTDIR)$(bindir)/dvipdfm$(EXEEXT) +@DVIPDFMX_TRUE@@WIN32_TRUE@ rm -f $(DESTDIR)$(bindir)/ebb$(EXEEXT) +@DVIPDFMX_TRUE@@WIN32_TRUE@ rm -f $(DESTDIR)$(bindir)/extractbb$(EXEEXT) + +all-local: config.force + +config.force: $(ZLIB_DEPEND) $(LIBPNG_DEPEND) $(KPATHSEA_DEPEND) $(FREETYPE2_DEPEND) + echo timestamp >config.force + $(SHELL) ./config.status --recheck + +@KPATHSEA_RULE@ +@FREETYPE2_RULE@ +@LIBPNG_RULE@ +@ZLIB_RULE@ + +# 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/dvipdf-x/README b/Build/source/texk/dvipdf-x/README new file mode 100644 index 00000000000..ec0d59db051 --- /dev/null +++ b/Build/source/texk/dvipdf-x/README @@ -0,0 +1,510 @@ +dvipdfmx and xdvipdfmx for TeX Live +=================================== + +xdvipdfmx +========= + +xdvipdfmx is an extended version of dvipdfmx; see dvipdfmx's README for +more information. + +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. + +There is a hope to merge xdvipdfmx into dvipdfmx. + +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 ... + +The dvipdfmx Project +==================== + +Copyright (C) 2002-2013 by Jin-Hwan Cho, Shunsaku Hirata, and +Matthias Franz, the dvipdfmx project team. 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. + +Contents +-------- + +1. Introduction + +2. Installation + + 2.1. Compiling and Installation + + 2.2. TeX Directory Structure (TDS) + + 2.3. Auxiliary Files + +3. CJK Support + + 3.1. Quick Test of Installation + + 3.2. CJK-LaTeX and HLaTeX + + 3.3. Omega and Other Extended TeX + + 3.4. Vertical Typesetting + +4. Unicode Support + + 4.1. Unicode Support in General + + 4.2. ToUnicode CMap Support + + 4.3. OpenType Support and Unicode + + 4.4. Type1 Font Support and Unicode + +5. Graphics and Image Format + + 5.1. Supported Graphics File Format + + 5.2. Graphics Extension + + 5.3. Using External Programs for Format Conversion + +6. DVI Specials + + 6.1. Compatibility + + 6.2. Additions to Dvipdfm's pdf: Special + +7. Font Mapping + +8. Incompatible Changes From Dvipdfm + +9. Other Improvement Over Dvipdfm + +10. Font Licensing and Embedding + + + +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 + ----------------------- + + Typical usage and installation steps are not different from the original dvipdfm. + Please refer documents from dvipdfm distribution for detailed instruction on how + to install and how to use dvipdfm. + + +2.1. Compiling and Installation + + + If you have obtained older version, please use latest version unless you have a + clear reason to choose older versions. The latest snapshot of dvipdfmx source is + available at: + + http://project.ktug.or.kr/dvipdfmx/snapshot/ + + And the CVS repository for this project can be obtained through anonymous CVS + access with the following command: + + cvs -d:pserver:anonymous@cvs.ktug.or.kr:/home/cvsroot login + cvs -d:pserver:anonymous@cvs.ktug.or.kr:/home/cvsroot co dvipdfmx + + When prompted for a password, simply press the Enter key. + + + The kpathsea library is required to compile and install dvipdfmx in UNIX or + UNIX-like platforms. It is usually included for most of TeX distributions. + If you already have installed dvipdfm (the original) by yourself, you should + already have kpathsea library and it's headers. And zlib library is highly + recommended as dvipdfmx can't compress data without this. + + + Before starting things, you must check the location of your TeX installation. + If other TeX related programs are installed under, e.g., '/usr/local/TeX/bin', + you should specify directory '/usr/local/TeX' as an for ./configure script as + + ./configure --prefix=/usr/local/TeX --with-kpathsea=/usr/local/TeX + + If you are using libpaper to handle paper sizes for various program, you can + use --with-paper option to ./configure. The location of libpaper library can + be specified with this option as + + --with-paper=DIR + + Please note thath dvipdfmx uses JIS paper size for B-series paper instead of + ISO's one for historical reason. (too late to change the default behavior) + The most easiest way to fix this is to use libpaper if you already have that, + otherwise define ISO_PAPERSIZE macro at compilation time. + + Dvipdfmx requires libpng library available from + + http://www.libpng.org/pub/png/libpng.html + + to read PNG format images. To tell dvipdfmx the location of libpng header + and library, use configure option + + --with-png=DIR + + After you have finished ./configure, just type + + make && make install + + then dvipdfmx will be installed under the directory specified by the --prefix + option to ./configure script. After you have successfully installed dvipdfmx, + you may need to install various auxiliary files and slightly adjust location + of files or configuration. Amount of additional files and modification depends + on your environment, and briefly described in the sections follows. + + +2.2. TeX Directory Structure (TDS) + + + If your TeX installation is conforming with TDS version 1.1 described in + + http://www.tug.org/ftp/tex/tds-1.1/ + + , then you'll need to adjust your dvipdfmx installtion. This also applies when + you have updated programs without modifying existing platform independent files + (files in texmf directory). Dvipdfmx installs few files in addition to dvipdfmx + program itself, dvipdfmx.cnf, cid-x.map and others, but it currently does not + choose installation directory as appropriate for TDS 1.1. + + If your 'kpsewhich' program recognizes '.sfd' file format, i.e., + + kpsewhich --show-path --format=.sfd + + does not answer as 'unknown format', then you should move several files under + appropriate locations or should modify texmf.cnf as follows: + + * Subfont Definition (SFD) Files + + Recommended location of SFD files (.sfd) is + + $TEXMF/fonts/sfd/ + + and environmental variable for specifying additional search path for this + file format files is + + SFDFONTS + + . To make those files visible to dvipdfmx under TDS 1.1 installation, you + must move all .sfd files to the directory mentioned above or set SFDFONTS + variable in texmf.cnf. As some programs may not be updated to follow this + convention yet, it is recommended to preserve old installation directory. + If you have .sfd files under "$TEXMF/dvipdfm/", please do not use that, + please move all files to the directory mentioned above. + + * PostScript CMap Resources + + Recommended location of CMap files (no suffix or with suffix .cmap) is + + $TEXMF/fonts/cmap/ + + and environmental variable for adding extra search path for this format files + is + + CMAPFONTS + + You may want to set CMAPFONTS to include GhostScript's Resource path, e.g., + + /usr/share/ghostscript/Resource/CMap// + + in your texmf.cnf file as this resource can be used by various programs that + manipulates PS/PDF files. Dvipdfmx installs few additional files into the + directory "$TEXMF/dvipdfm/CMap", please move this files to the directory for + CMap files. But please note that file "Adobe-Identity-UCS2" is not meaningful + to other programs at all, so you should place at least this file in different + location than CMap files. (Or you can just remove this unless you see problems + in copy-and-pasting text from dvipdfmx output PDF.) + + * Font Mapping Files + + Suggested place for dvipdfm's font mapping files (.map) is + + $TEXMF/fonts/map/dvipdfm/ + + and environmental variable for this format files is + + TEXFONTMAPS + + For files containing dvipdfmx extension to dvipdfm format, place them into + + $TEXMF/fonts/map/dvipdfmx/ + + instead of sub-directory 'dvipdfm'. + + * OpenType Fonts + + Appropriate place for OpenType font with PostScript outline (.otf) is + + $TEXMF/fonts/opentype/supplier/typeface/ + + where 'supplier' and 'typeface' should be replaced with font's supplier and + typeface identifier strings. + + +2.3. Auxiliary Files + + + 1) CMap PostScript Resources + + Dvipdfmx internally identifies glyphs in a font with identifier represented + as numbers ranging from 0 to 65535. CMap PostScript Resources defines how the + input character codes are translated to those ID's (CID). CID's should be + uniquely assigned to every glyphs contained in a collection of glyphs. Adobe + has defined several "character collection"s; Adobe-GB1 (Simplified Chinese), + Adobe-CNS1 (Traditional Chinese), Adobe-Japan1 (Japanese), and Adobe-Korea1 + (Korean), which contains much of glyphs necessary for publishing for each + languages. Details on Adobe's character collections can be found at Adobe's + developer site: + + http://partners.adobe.com/public/developer/font/index.html + + Please install CMap resource files under the directory + + ${TEXMF}/fonts/cmap + + , or set CMAPFONTS variable to point the directory containing CMap resource + in texmf.cnf. If your TeX installation does not conforming TDS 1.1, then you + should set CMAPINPUTS variable to make those files visible to dvipdfmx. For + examples, + + CMAPINPUTS= .;$TEXMF/fonts/cmap// + + Adobe's "CMaps for PDF 1.4 CJK Fonts" are available from: + + http://partners.adobe.com/public/developer/acrobat/index_advanced.html + + or + + ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/ + + You can find a short explanation of each CMap files in cid2code.txt contained + in the archive files found at the above FTP site. + + + 2) SubFont Definition Files + + ..... + + + 3) Adobe Glyph List and ToUnicode Mapping Files + + The Adobe glyph list (AGL) file describes correspondence between PostScript + glyph names (e.g., AE, Aacute, ...) and it's Unicode character sequences. + Most features described in the section "Unicode Support" requires this file. + + Dvipdfmx looks for file "glyphlist.txt" when conversion from PostScript glyph + names to Unicode is necessary. This conversion is done in various situations; + when creating ToUnicode CMap for 8bit encoded fonts, finding glyph description + from TrueType/OpenType fonts supporting Unicode when the font itself does not + provide the mapping from PostScript glyph names to glyph indices (version 2.0 + "post" table), and when encoding "unicode" is specified for Type 1 font. + + The "glyphlist.txt" file written by Adobe is found at + + http://partners.adobe.com/asn/tech/type/glyphlist.txt + + You should place file "glyphlist.txt" in a directory shown by + + kpsewhich --progname=dvipdfm --show-path="other text files" + + Please check kpathsea library can find this file by 'kpsewhich' command: + + kpsewhich --progname=dvipdfm --format="other text files" glyphlist.txt + + The 'progname' is not dvipdfmx but dvipdfm here. + + ToUnicode mapping is similar to glyph list file but describes correspondence + between CID numbers and Unicode values. The content of this file look like a + CMap files and is contained in "CMaps for PDF 1.4 CJK Fonts" from Adobe (see + "CMap PostScript Resources" above). This file is required to support TrueType + font (including OpenType fonts with TrueType outline). Those files should be + installed same directory as ordinary CMap files. + + +3. CJK Support + +3.1. Quick Test of Installation + +3.2. CJK-LaTeX and HLaTeX + +3.3. Omega and Other Extended TeX + + +4. Unicode Support + +4.1. Unicode Support in General + +4.2. ToUnicode CMap Support + +4.3. OpenType Support and Unicode + +4.4. Type1 Font Support and Unicode + + +5. Graphics and Image Format + +5.1. Supported Graphics File Format + +5.2. Graphics Extension + +5.3. Using External Programs for Format Conversion + + +6. DVI Specials + +6.1. Compatibility + +6.2. Additions to Dvipdfm's pdf: Special + + +7. Font Mapping + + +7.1. Options for CJK Font + + Few options are available in dvipdfmx (for CID-keyed fonts) in addition + to the original dvipdfm. + + + 1) TTC Index + + You can specify TrueType Collection index number with :n: option in front + of TrueType font name. + + min10 H :1:mincho + + In this example, the option :1: tells dvipdfmx to select TrueType font #1 + from TrueType collection font "mincho.ttc". + + + 2) No-embed Switch + + It is possible to block embedding glyph data with the character `!' + in front of the font name in the font mapping file. + + This feature reduces the size of the final PDF output, but the PDF file + may not be viewed exactly in other systems on which appropriate fonts + are not installed. + + Use of this option is not recommended for fonts that contains unusual + characters (and characters having different width from default value). + Please note that glyph metric information is not written in the output + PDF file for TrueType fonts without embedding. It will be treated as + fixed-pitch with all widths equal to the default value (will be fixed + someday). + + + 3) Stylistic Variants + + Keywords ",Bold", ",Italic", and ",BoldItalic" can be used to create + synthetic bold, italic, and bolditalic style variants from other font + using PDF viewer's (or OS's) function. + + jbtmo@UKS@ UniKSCms-UCS2-H :0:!batang,Italic + jbtb@Unicode@ Identity-H !batang/UCS,Bold + + Availability of this feature highly depends on the implementation of PDF + viewers. This feature is not supported for embedded fonts in the most of + PDF viewers, like Adobe Acrobat Reader and GNU Ghostscript. + + Notice that this option automatically disable font embedding. + + + +8. Incompatible Changes From Dvipdfm + + + +9. Other Improvement Over Dvipdfm + + +9.1. Encryption + + +9.2. Font + + + +10. Font Licensing and Embedding + + In OpenType format, information regarding how the font should be treated + when creating documents can be recorded. Dvipdfmx uses this information + to decide whether embedding font into the document is permitted. + + This font embedding information is indicated by a flag called as "fsType" + flag; each bit representing different restrictions on font embedding. + If multiple flag bits are set in fsType, the least restrictive license + granted takes precedence in dvipdfmx. The fsType flag bits recognized by + dvipdfmx is as follows: + + * Installable embedding + + All font with this type of license can be embedded. + + * Editable embedding + + All font with this type of license can be embedded. + + * Embedding for Preview & Print only + + Dvipdfmx give the following warning message for fonts with this + type of license: + + This document contains `Preview & Print' only licensed font + + For the font with this type of licensing, font embedding is allowed + solely for the purpose of (on-screen) viewing and/or printing the + document; further editing of the document or extracting an embedded + font data for other purpose is not allowed. To ensure this condition, + you must at least protect your document with non-empty password. + + All other flags are treated as more restrictive license than any of the + above flags and treated as "No embedding allowed"; e.g., if both of the + editable-embedding flag and unrecognized license flag is set, the font + is treated as editable-embedding allowed, however, if only unrecognized + flags are set, the font is not embedded. + + Embedding flags are preserved in embedded font if the font is embedded + as a TrueType font or a CIDFontType 2 CIDFont. For all font embedded as + a PostScript font (CFF, CIDFontType 0 CIDFont), they are not preserved. + Only /Copyright and /Notice in the FontInfo dictionary are preserved in + this case. + + Some font vendors put different embedding restrictions for different + condition; e.g., font embedding might be not permitted for commercial + materials unless you acquire "commercial license" separately. + Please read EULA carefully before making decision on font usage. + + + Adobe provide a font licensing FAQ and a list of embedding permissions + for Adobe Type Library fonts: + + http://www.adobe.com/type/browser/legal/ + + For Japanese font in general, embedding permission tend to be somewhat + restrictive. Japanese users should read the statement regarding font + embedding from Japan Typography Association (in Japanese): + + http://www.typo.or.jp/info/morals/moral4.html diff --git a/Build/source/texk/dvipdf-x/ac/dvipdf-x.ac b/Build/source/texk/dvipdf-x/ac/dvipdf-x.ac new file mode 100644 index 00000000000..06d1dc87357 --- /dev/null +++ b/Build/source/texk/dvipdf-x/ac/dvipdf-x.ac @@ -0,0 +1,13 @@ +## Define configure options for dvipdf-x. +m4_define_default([kpse_indent_26], [26])[]dnl +m4_define([kpse_dvipdf_x_progs], [dvipdf xdvipdf])[]dnl +AC_FOREACH([Kpse_Prog], kpse_dvipdf_x_progs, [dnl +AC_ARG_ENABLE(Kpse_Prog, + AS_HELP_STRING([--disable-]Kpse_Prog, + [do not build the ]Kpse_Prog[ program], + kpse_indent_26)) +AS_CASE([enable_]Kpse_Prog, + [yes | no], , + [enable_]Kpse_Prog[=yes]) +]) +test "x$enable_dvipdf_x:$enable_xdvipdf" = xyes:yes && need_freetype2=yes diff --git a/Build/source/texk/dvipdf-x/ac/withenable.ac b/Build/source/texk/dvipdf-x/ac/withenable.ac new file mode 100644 index 00000000000..fddd09736ba --- /dev/null +++ b/Build/source/texk/dvipdf-x/ac/withenable.ac @@ -0,0 +1,8 @@ +## texk/dvipdf-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdf-x/ +dnl +dnl Copyright (C) 2009-2013 Peter Breitenlohner +dnl You may freely use, modify and/or distribute this file. +dnl +## configure options and TL libraries required for dvipdf-x +KPSE_ENABLE_PROG([dvipdf-x], [kpathsea libpng], [disable]) +m4_include(kpse_TL[texk/dvipdf-x/ac/dvipdf-x.ac]) diff --git a/Build/source/texk/dvipdf-x/aclocal.m4 b/Build/source/texk/dvipdf-x/aclocal.m4 new file mode 100644 index 00000000000..7b601c3d0f0 --- /dev/null +++ b/Build/source/texk/dvipdf-x/aclocal.m4 @@ -0,0 +1,1236 @@ +# generated automatically by aclocal 1.14 -*- Autoconf -*- + +# Copyright (C) 1996-2013 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-2013 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.14' +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.14], [], + [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.14])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-2013 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], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_COND_IF -*- Autoconf -*- + +# Copyright (C) 2008-2013 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-2013 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-2013 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-2013 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. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _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. FIXME. This creates each '.P' file that we will +# 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" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2013 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: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target. 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: + +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: . + +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 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-2013 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}" != 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-2013 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-2013 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-2013 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 to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2013 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 + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +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-2013 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-2013 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-2013 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-2013 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-2013 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-2013 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-2013 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-2013 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 /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/cho-libs.m4]) +m4_include([../../m4/kpse-common.m4]) +m4_include([../../m4/kpse-freetype2-flags.m4]) +m4_include([../../m4/kpse-kpathsea-flags.m4]) +m4_include([../../m4/kpse-libpng-flags.m4]) +m4_include([../../m4/kpse-lt-hack.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/dvipdf-x/agl.c b/Build/source/texk/dvipdf-x/agl.c new file mode 100644 index 00000000000..d5a4edd7730 --- /dev/null +++ b/Build/source/texk/dvipdf-x/agl.c @@ -0,0 +1,826 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" + +#include "mfileio.h" +#include "pdfparse.h" + +/* Hash */ +#include "dpxutil.h" + +#include "dpxfile.h" + +#include "unicode.h" + +#include "agl.h" + +static int verbose = 0; + +void +agl_set_verbose (void) +{ + verbose++; +} + +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) +{ + long slen = 0, len; + + len = (long) (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) +{ + long slen = 0, len; + int i; + + len = (long) (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) +{ + long 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(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 void CDECL +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 + +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 (verbose) + MESG("= 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 (verbose > 3) { + 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 (verbose) + 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(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(c) && (c < 'A' || c > 'F')) + return 0; + } + return 1; + } + + return 0; +} + +long +agl_name_convert_unicode (const char *glyphname) +{ + long 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(*p) && (*p < 'A' || *p > 'F')) { + WARN("Invalid char %c in Unicode glyph name %s.", *p, glyphname); + return -1; + } + ucv <<= 4; + ucv += isdigit(*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 long +xtol (const char *start, int len) +{ + long v = 0; + + while (len-- > 0) { + v <<= 4; + if (isdigit(*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 long +put_unicode_glyph (const char *name, + unsigned char **dstpp, unsigned char *limptr) +{ + const char *p; + long len = 0, ucv; + + p = name; + ucv = 0; + + if (p[1] != 'n') { + p += 1; + ucv = xtol(p, strlen(p)); + len += UC_sput_UTF16BE (ucv, dstpp, limptr); + } else { + p += 3; + while (*p != '\0') { + ucv = xtol(p, 4); + len += UC_sput_UTF16BE (ucv, dstpp, limptr); + p += 4; + } + } + + return len; +} + +long +agl_sput_UTF16BE (const char *glyphstr, + unsigned char **dstpp, unsigned char *limptr, + int *fail_count) +{ + long 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; + long 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 = (long) (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 (verbose > 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_sput_UTF16BE (agln1->unicodes[i], dstpp, limptr); + } + } else { + if (verbose) { + 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, + long *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; + long 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 = (long) (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 (verbose > 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 (verbose > 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/dvipdf-x/agl.h b/Build/source/texk/dvipdf-x/agl.h new file mode 100644 index 00000000000..d771c994675 --- /dev/null +++ b/Build/source/texk/dvipdf-x/agl.h @@ -0,0 +1,68 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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; + long 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 long agl_sput_UTF16BE (const char *name, + unsigned char **dstpp, + unsigned char *limptr, int *num_fails); + +extern int agl_get_unicodes (const char *glyphstr, + long *unicodes, int max_uncodes); + +extern int agl_name_is_unicode (const char *glyphname); +extern long 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); +extern int agl_load_listfile (const char *filename, int format); + +#if 0 +extern int agl_select_listfile (const char *mapfile); +#endif + +extern void agl_set_verbose (void); +extern void agl_init_map (void); +extern void agl_close_map (void); + +#endif /* _AGL_H_ */ diff --git a/Build/source/texk/dvipdf-x/bmpimage.h b/Build/source/texk/dvipdf-x/bmpimage.h new file mode 100644 index 00000000000..2259ba79c9e --- /dev/null +++ b/Build/source/texk/dvipdf-x/bmpimage.h @@ -0,0 +1,39 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "mfileio.h" +#include "pdfximage.h" + +extern int bmp_include_image (pdf_ximage *ximage, FILE *file); +extern int check_for_bmp (FILE *file); + +#endif /* _BMPIMAGE_H_ */ diff --git a/Build/source/texk/dvipdf-x/cff_dict.h b/Build/source/texk/dvipdf-x/cff_dict.h new file mode 100644 index 00000000000..62dc7114b68 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cff_dict.h @@ -0,0 +1,47 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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 long cff_dict_pack (cff_dict *dict, card8 *dest, long destlen); + +extern void cff_dict_update (cff_dict *dict, cff_font *cff); + +#endif /* _CFF_DICT_H_ */ diff --git a/Build/source/texk/dvipdf-x/cff_limits.h b/Build/source/texk/dvipdf-x/cff_limits.h new file mode 100644 index 00000000000..25411cdfcf2 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cff_limits.h @@ -0,0 +1,46 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 + +#define CFF_INT_MAX 0x7fffffff +#define CFF_INT_MIN (-0x7fffffff - 1) + +#if (LONG_MAX < CFF_INT_MAX || LONG_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/dvipdf-x/cff_stdstr.h b/Build/source/texk/dvipdf-x/cff_stdstr.h new file mode 100644 index 00000000000..20cf8513d42 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cff_stdstr.h @@ -0,0 +1,109 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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/dvipdf-x/cff_types.h b/Build/source/texk/dvipdf-x/cff_types.h new file mode 100644 index 00000000000..2c58f825139 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cff_types.h @@ -0,0 +1,142 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 unsigned long l_offset; /* 1, 2, 3, or 4-byte offset */ +typedef unsigned short s_SID; /* 2-byte string identifier */ + +typedef unsigned long l_size; + +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/dvipdf-x/cid.c b/Build/source/texk/dvipdf-x/cid.c new file mode 100644 index 00000000000..c1ccbaf0585 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cid.c @@ -0,0 +1,835 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxutil.h" + +#include "pdfobj.h" + +#include "cidtype0.h" +#include "cidtype2.h" +#include "cid_p.h" +#include "cid.h" + +#define CIDFONT_DEBUG 3 +#define CIDFONT_DEBUG_STR "CIDFont" + +#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[16]; +} CIDFont_stdcc_def[] = { + {"Adobe", "UCS", {-1, -1, 0, 0, 0, 0, 0, 0}}, + {"Adobe", "GB1", {-1, -1, 0, 2, 4, 4, 4, 4}}, + {"Adobe", "CNS1", {-1, -1, 0, 0, 3, 4, 4, 4}}, + {"Adobe", "Japan1", {-1, -1, 2, 2, 4, 5, 6, 6}}, + {"Adobe", "Korea1", {-1, -1, 1, 1, 2, 2, 2, 2}}, + {"Adobe", "Identity", {-1, -1, 0, 0, 0, 0, 0, 0}}, + {NULL, NULL, { 0, 0, 0, 0, 0, 0, 0, 0}} +}; +#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 CIDSysInfo *get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt); + +static int __verbose = 0; +static long cidoptflags = 0; + +void +CIDFont_set_verbose (void) +{ + CIDFont_type0_set_verbose(); + CIDFont_type2_set_verbose(); + __verbose++; +} + +#if 0 +int +CIDFont_require_version (void) +{ + return PDF_CID_SUPPORT_MIN; +} +#endif + +CIDFont * +CIDFont_new (void) +{ + CIDFont *font = NULL; + + font = NEW(1, struct CIDFont); + + font->name = NULL; + font->fontname = NULL; + font->ident = NULL; + +#ifdef XETEX + font->ft_face = NULL; + font->ft_to_gid = NULL; +#endif + + /* + * CIDFont + */ + font->subtype = -1; + font->flags = FONT_FLAG_NONE; + font->csi = NULL; + font->options = NULL; + (font->parent)[0] = -1; /* Horizontal */ + (font->parent)[1] = -1; /* Vertical */ + + /* + * PDF Font Resource + */ + font->indirect = NULL; + font->fontdict = NULL; + font->descriptor = NULL; + + return font; +} + +/* It does write PDF objects. */ +void +CIDFont_flush (CIDFont *font) +{ + if (font) { + if (font->indirect) pdf_release_obj(font->indirect); + font->indirect = NULL; + if (font->fontdict) pdf_release_obj(font->fontdict); + font->fontdict = NULL; + if (font->descriptor) pdf_release_obj(font->descriptor); + font->descriptor = NULL; + } +} + +void +CIDFont_release (CIDFont *font) +{ + if (font) { + switch(font->subtype) { + case CIDFONT_TYPE0: + CIDFont_type0_release(font); + break; + case CIDFONT_TYPE2: + CIDFont_type2_release(font); + break; + } + if (font->indirect) + ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR); + if (font->fontdict) + ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR); + if (font->descriptor) + ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR); + + if (font->fontname) RELEASE(font->fontname); + if (font->name) RELEASE(font->name); + if (font->ident) RELEASE(font->ident); + if (font->csi) { + if (font->csi->registry) + RELEASE(font->csi->registry); + if (font->csi->ordering) + RELEASE(font->csi->ordering); + RELEASE(font->csi); + } + if (font->options) + release_opt(font->options); + } +} + +#ifdef XETEX +unsigned short * +CIDFont_get_ft_to_gid(CIDFont *font) +{ + ASSERT(font); + return font->ft_to_gid; +} +#endif + +char * +CIDFont_get_fontname (CIDFont *font) +{ + ASSERT(font); + return font->fontname; +} + +char * +CIDFont_get_ident (CIDFont *font) +{ + ASSERT(font); + return font->ident; +} + +int +CIDFont_get_opt_index (CIDFont *font) +{ + int opt_index; + + ASSERT(font); + + if (font->options) + opt_index = font->options->index; + else { + opt_index = 0; + } + + return opt_index; +} + +#ifdef XETEX +FT_Face +CIDFont_get_ft_face(CIDFont *font) +{ + ASSERT(font); + return font->ft_face; +} +#endif + +int +CIDFont_get_subtype (CIDFont *font) +{ + ASSERT(font); + return font->subtype; +} + +int +CIDFont_get_embedding (CIDFont *font) +{ + ASSERT(font); + return font->options->embed; +} + +CIDSysInfo * +CIDFont_get_CIDSysInfo (CIDFont *font) +{ + ASSERT(font); + + return font->csi; +} + +/* + * Returns ID of parent Type0 font + * wmode: 0 for horizontal, 1 for vertical + */ +int +CIDFont_get_parent_id (CIDFont *font, int wmode) +{ + ASSERT(font); + + if (wmode < 0 || wmode > 1) + ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR); + + return (font->parent)[wmode]; +} + +pdf_obj * +CIDFont_get_resource (CIDFont *font) +{ + ASSERT(font); + + if (!font->indirect) + font->indirect = pdf_ref_obj(font->fontdict); + + return pdf_link_obj(font->indirect); +} + +/* + * Set parent Type0 font. + */ +void +CIDFont_attach_parent (CIDFont *font, int parent_id, int wmode) +{ + ASSERT(font); + + if (wmode < 0 || wmode > 1) + ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR); + + if (font->parent[wmode] >= 0) + WARN("%s: CIDFont already have a parent Type1 font.", CIDFONT_DEBUG_STR); + + font->parent[wmode] = parent_id; +} + +int +CIDFont_is_ACCFont (CIDFont *font) +{ + int i; + + ASSERT(font); + + if (!font->csi) + ERROR("%s: CIDSystemInfo undefined.", CIDFONT_DEBUG_STR); + + for (i = ACC_START; i <= ACC_END ; i++) { + if (!strcmp(font->csi->registry, CIDFont_stdcc_def[i].registry) && + !strcmp(font->csi->ordering, CIDFont_stdcc_def[i].ordering)) + return 1; + } + + return 0; +} + +int +CIDFont_is_UCSFont (CIDFont *font) +{ + ASSERT(font); + if (!strcmp(font->csi->ordering, "UCS") || + !strcmp(font->csi->ordering, "UCS2")) + return 1; + return 0; +} + +/* FIXME */ +int +CIDFont_get_flag (CIDFont *font, int mask) +{ + ASSERT(font); + return ((font->flags & mask) ? 1 : 0); +} + +static void +CIDFont_dofont (CIDFont *font) +{ + if (!font || !font->indirect) + return; + + if (__verbose) + MESG(":%s", font->ident); + if (__verbose > 1) { + if (font->fontname) + MESG("[%s]", font->fontname); + } + + switch (font->subtype) { + case CIDFONT_TYPE0: + if(__verbose) + MESG("[CIDFontType0]"); + if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1)) + CIDFont_type0_t1dofont(font); + else if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1C)) + CIDFont_type0_t1cdofont(font); + else + CIDFont_type0_dofont(font); + break; + case CIDFONT_TYPE2: + if(__verbose) + MESG("[CIDFontType2]"); + CIDFont_type2_dofont(font); + break; + default: + ERROR("%s: Unknown CIDFontType %d.", CIDFONT_DEBUG_STR, font->subtype); + break; + } +} + + +/* + * + */ +int +CIDFont_is_BaseFont (CIDFont *font) +{ + ASSERT(font); + return (font->flags & FONT_FLAG_BASEFONT) ? 1 : 0; +} + +#include "pdfparse.h" +#include "cid_basefont.h" + +static int CIDFont_base_open (CIDFont *font, + const char *name, CIDSysInfo *cmap_csi, cid_opt *opt); + +static int +CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, 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 |= 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")); + if (cmap_csi) { /* NULL for accept any */ + if (strcmp(registry, cmap_csi->registry) || + strcmp(ordering, cmap_csi->ordering)) + ERROR("Inconsistent CMap used for CID-keyed font %s.", + cid_basefont[idx].fontname); + else if (supplement < cmap_csi->supplement) { + WARN("CMap has higher supplement number than CIDFont: %s", fontname); + WARN("Some chracters may not be displayed or printed."); + } + } + font->csi = NEW(1, CIDSysInfo); + font->csi->registry = NEW(strlen(registry)+1, char); + font->csi->ordering = NEW(strlen(ordering)+1, char); + strcpy(font->csi->registry, registry); + strcpy(font->csi->ordering, ordering); + font->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 = CIDFONT_TYPE0; + else if (!strcmp(type, "CIDFontType2")) + font->subtype = CIDFONT_TYPE2; + else { + ERROR("Unknown CIDFontType \"%s\"", type); + } + } + + if (cidoptflags & 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->fontdict = fontdict; + font->descriptor = descriptor; + + opt->embed = 0; + + return 0; +} + + + +#define CACHE_ALLOC_SIZE 16u + +struct FontCache { + int num; + int max; + CIDFont **fonts; +}; + +static struct FontCache *__cache = NULL; + +#define CHECK_ID(n) do {\ + if (! __cache)\ + ERROR("%s: CIDFont cache not initialized.", CIDFONT_DEBUG_STR);\ + if ((n) < 0 || (n) >= __cache->num)\ + ERROR("%s: Invalid ID %d", CIDFONT_DEBUG_STR, (n));\ + } while (0) + +void +CIDFont_cache_init (void) +{ + if (__cache) + ERROR("%s: Already initialized.", CIDFONT_DEBUG_STR); + + __cache = NEW(1, struct FontCache); + + __cache->max = CACHE_ALLOC_SIZE; + __cache->fonts = NEW(__cache->max, struct CIDFont *); + __cache->num = 0; +} + +CIDFont * +CIDFont_cache_get (int font_id) +{ + CHECK_ID(font_id); + return __cache->fonts[font_id]; +} + +/* + * cmap_csi is NULL if CMap is Identity. + */ +int +CIDFont_cache_find (const char *map_name, + CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt) +{ + int font_id = -1; + CIDFont *font = NULL; + cid_opt *opt = NULL; + + if (!__cache) + CIDFont_cache_init(); + + opt = NEW(1, cid_opt); + opt->style = fmap_opt->style; + opt->index = fmap_opt->index; + opt->embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1; + opt->name = NULL; + opt->csi = get_cidsysinfo(map_name, fmap_opt); + opt->stemv = fmap_opt->stemv; + + if (!opt->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 = NEW(1, CIDSysInfo); + 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; + } + /* + * 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 < __cache->num; font_id++) { + font = __cache->fonts[font_id]; + if (!strcmp(font->name, map_name) && + font->options->style == opt->style && + font->options->index == opt->index) { + if (font->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 (!opt->csi) { + if (font->subtype == CIDFONT_TYPE2) + continue; + else + break; + } else if (!strcmp(font->csi->registry, opt->csi->registry) && + !strcmp(font->csi->ordering, opt->csi->ordering)) { + if (font->subtype == CIDFONT_TYPE2) + font->csi->supplement = + MAX(opt->csi->supplement, font->csi->supplement); + break; + } + } else if (CIDFont_is_BaseFont(font)) { + opt->embed = 0; + break; + } + } + } + + if (font_id < __cache->num && cmap_csi) { + if (strcmp(font->csi->registry, cmap_csi->registry) || + strcmp(font->csi->ordering, cmap_csi->ordering)) + ERROR("%s: Incompatible CMap for CIDFont \"%s\"", + CIDFONT_DEBUG_STR, map_name); + } + + if (font_id == __cache->num) { + font = CIDFont_new(); +#ifdef XETEX + font->ft_face = fmap_opt->ft_face; +#endif + if (CIDFont_type0_open(font, map_name, cmap_csi, opt) < 0 && + CIDFont_type2_open(font, map_name, cmap_csi, opt) < 0 && + CIDFont_type0_t1open(font, map_name, cmap_csi, opt) < 0 && + CIDFont_type0_t1copen(font, map_name, cmap_csi, opt) < 0 && + CIDFont_base_open (font, map_name, cmap_csi, opt) < 0 + ) { + CIDFont_release(font); + release_opt(opt); + return -1; + } else { + if (__cache->num >= __cache->max) { + __cache->max += CACHE_ALLOC_SIZE; + __cache->fonts = RENEW(__cache->fonts, + __cache->max, struct CIDFont *); + } + font->name = NEW(strlen(map_name)+1, char); + strcpy(font->name, map_name); + font->ident = NEW(strlen(map_name)+1, char); + strcpy(font->ident, map_name); + font->options = opt; + __cache->fonts[font_id] = font; + (__cache->num)++; + } + } else if (opt) { + release_opt(opt); + } + + return font_id; +} + +void +CIDFont_cache_close (void) +{ + int font_id; + + if (__cache) { + for (font_id = 0; + font_id < __cache->num; font_id++) { + CIDFont *font; + + font = __cache->fonts[font_id]; + + if (__verbose) + MESG("(CID"); + + CIDFont_dofont (font); + CIDFont_flush (font); + CIDFont_release(font); + + RELEASE(font); + + if (__verbose) + MESG(")"); + } + RELEASE(__cache->fonts); + RELEASE(__cache); + __cache = NULL; + } +} + +/******************************* OPTIONS *******************************/ + +/* + * FORMAT: + * + * (:int:)?!?string(/string)?(,string)? + */ + +static void +release_opt (cid_opt *opt) +{ + if (opt->csi) { + if (opt->csi->registry) + RELEASE(opt->csi->registry); + if (opt->csi->ordering) + RELEASE(opt->csi->ordering); + RELEASE(opt->csi); + } + RELEASE(opt); +} + +static CIDSysInfo * +get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt) +{ + CIDSysInfo *csi = NULL; + int pdf_ver; + int i, csi_idx = -1, n, m; + + pdf_ver = pdf_get_version(); + + if (!fmap_opt || !fmap_opt->charcoll) + return NULL; + + /* 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 = NEW(1, CIDSysInfo); + 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[pdf_ver]; + } + break; + } + } + if (csi == NULL) { + char *p, *q; + + p = (char *) fmap_opt->charcoll; + csi = NEW(1, CIDSysInfo); + + /* Full REGISTRY-ORDERING-SUPPLEMENT */ + p = strchr(fmap_opt->charcoll, '-'); + if (!p || p[1] == '\0') + ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", + CIDFONT_DEBUG_STR, fmap_opt->charcoll); + p++; + + q = strchr(p, '-'); + if (!q || q[1] == '\0') + ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", + CIDFONT_DEBUG_STR, fmap_opt->charcoll); + q++; + + if (!isdigit(q[0])) + ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", + CIDFONT_DEBUG_STR, 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); + + /* 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[pdf_ver] + && (fmap_opt->flags & FONTMAP_OPT_NOEMBED)) { + WARN("%s: Heighest supplement number supported in PDF-1.%d for %s-%s is %d.", + CIDFONT_DEBUG_STR, pdf_ver, csi->registry, csi->ordering, + CIDFont_stdcc_def[csi_idx].supplement[pdf_ver]); + WARN("%s: Some character may not shown without embedded font (--> %s).", + CIDFONT_DEBUG_STR, map_name); + } + } + + return csi; +} + +void +CIDFont_set_flags (long flags) +{ + CIDFont_type0_set_flags(flags); + CIDFont_type2_set_flags(flags); + cidoptflags |= flags; +} diff --git a/Build/source/texk/dvipdf-x/cid.h b/Build/source/texk/dvipdf-x/cid.h new file mode 100644 index 00000000000..c9a4c00de90 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cid.h @@ -0,0 +1,96 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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_ + +#ifdef XETEX +#include "ft2build.h" +#include FT_FREETYPE_H +#endif + +/* CIDFont types */ +#define CIDFONT_TYPE0 1 +#define CIDFONT_TYPE2 2 + +typedef struct { + char *registry; + char *ordering; + int supplement; +} CIDSysInfo; + +extern CIDSysInfo CSI_IDENTITY; +extern CIDSysInfo CSI_UNICODE; + +typedef struct CIDFont CIDFont; + +extern void CIDFont_set_verbose (void); +#if 0 +extern int CIDFont_require_version (void); +#endif +extern void CIDFont_set_flags (long flags); + +#define CIDFONT_FORCE_FIXEDPITCH (1 << 1) + +#include "pdfobj.h" +#include "type0.h" + +/* FIXME */ +/* Converted from Type 1 */ +#define CIDFONT_FLAG_TYPE1 (1 << 8) +#define CIDFONT_FLAG_TYPE1C (1 << 9) +#define CIDFONT_FLAG_TRUETYPE (1 << 10) + +extern CIDFont *CIDFont_new (void); +extern void CIDFont_release (CIDFont *font); +extern void CIDFont_flush (CIDFont *font); + +extern char *CIDFont_get_fontname (CIDFont *font); + +extern char *CIDFont_get_ident (CIDFont *font); /* FIXME */ +extern int CIDFont_get_opt_index (CIDFont *font); /* FIXME */ +#ifdef XETEX +extern FT_Face CIDFont_get_ft_face (CIDFont *font); +extern unsigned short *CIDFont_get_ft_to_gid(CIDFont *font); +#endif + +extern int CIDFont_get_flag (CIDFont *font, int mask); + +extern int CIDFont_get_subtype (CIDFont *font); +extern int CIDFont_get_embedding (CIDFont *font); +extern pdf_obj *CIDFont_get_resource (CIDFont *font); +extern CIDSysInfo *CIDFont_get_CIDSysInfo (CIDFont *font); + +extern void CIDFont_attach_parent (CIDFont *font, int parent_id, int wmode); +extern int CIDFont_get_parent_id (CIDFont *font, int wmode); + +extern int CIDFont_is_BaseFont (CIDFont *font); +extern int CIDFont_is_ACCFont (CIDFont *font); +extern int CIDFont_is_UCSFont (CIDFont *font); + +#include "fontmap.h" +extern void CIDFont_cache_init (void); +extern int CIDFont_cache_find (const char *map_name, CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt); +extern CIDFont *CIDFont_cache_get (int fnt_id); +extern void CIDFont_cache_close (void); + +#endif /* _CID_H_ */ diff --git a/Build/source/texk/dvipdf-x/cid_basefont.h b/Build/source/texk/dvipdf-x/cid_basefont.h new file mode 100644 index 00000000000..69c2cd0d005 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cid_basefont.h @@ -0,0 +1,489 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 -259 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 857 /CapHeight 857 /Descent -143 /StemV 91 \ +/FontBBox [-250 -143 600 857] \ +/ItalicAngle 0 /Flags 6 /XHeight 599 \ +/Style << /Panose <000000000400000000000000> >> \ +>>" + }, + { + "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 <000001000500000000000000> >> \ +>>" + }, + { + "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 <000002020500000000000000> >> \ +>>" + }, + { + "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/dvipdf-x/cid_p.h b/Build/source/texk/dvipdf-x/cid_p.h new file mode 100644 index 00000000000..c5e940a5f84 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cid_p.h @@ -0,0 +1,74 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_P_H_ +#define _CID_P_H_ + +#define FONT_FLAG_NONE 0 +#define FONT_FLAG_BASEFONT (1 << 0) +#define FONT_FLAG_ACCFONT (1 << 1) +#define FONT_FLAG_UCSFONT (1 << 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 *name; /* Unused */ + CIDSysInfo *csi; + int index; + int style; + int embed; + int stemv; +} cid_opt; + +struct CIDFont +{ + char *ident; /* Map record entry */ + char *name; /* Fontname or filename */ + char *fontname; /* PostScript font name */ +#ifdef XETEX + FT_Face ft_face; + unsigned short *ft_to_gid; +#endif + /* + * CIDFont Specific + */ + int subtype; /* CIDFONT_TYPE0 or CIDFONT_TYPE2 */ + int flags; /* BASEFONT */ + int parent[2]; /* Parent type0 font of this CID-keyed font: H, V */ + CIDSysInfo *csi; /* Character collection */ + cid_opt *options; /* Options from map record */ + /* + * PDF Font Resource + */ + pdf_obj *indirect; /* Indirect reference to CIDFont dictionary */ + pdf_obj *fontdict; /* CIDFont dictionary */ + pdf_obj *descriptor; /* FontDescriptor */ +}; + +#endif /* _CID_P_H_ */ diff --git a/Build/source/texk/dvipdf-x/cidtype0.h b/Build/source/texk/dvipdf-x/cidtype0.h new file mode 100644 index 00000000000..0e8f98f4dcd --- /dev/null +++ b/Build/source/texk/dvipdf-x/cidtype0.h @@ -0,0 +1,47 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 "cid.h" +#include "cid_p.h" +#include "fontmap.h" + +extern void CIDFont_type0_set_verbose (void); +extern void CIDFont_type0_set_flags (long flags); + +extern int CIDFont_type0_open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt); +extern void CIDFont_type0_dofont (CIDFont *font); +extern void CIDFont_type0_release (CIDFont *font); + +/* Type1 --> CFF CIDFont */ +extern int t1_load_UnicodeCMap (const char *font_name, const char *otl_tags, int wmode); +extern int CIDFont_type0_t1open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt); +extern void CIDFont_type0_t1dofont (CIDFont *font); +extern int CIDFont_type0_t1copen (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt); +extern void CIDFont_type0_t1cdofont (CIDFont *font); + +#endif /* _CIDTYPE0_H_ */ diff --git a/Build/source/texk/dvipdf-x/cidtype2.h b/Build/source/texk/dvipdf-x/cidtype2.h new file mode 100644 index 00000000000..528b0aa7142 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cidtype2.h @@ -0,0 +1,37 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 "cid.h" +#include "cid_p.h" + +extern void CIDFont_type2_set_verbose (void); +extern void CIDFont_type2_set_flags (long flags); + +extern int CIDFont_type2_open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt); +extern void CIDFont_type2_dofont (CIDFont *font); +extern void CIDFont_type2_release (CIDFont *font); + +#endif /* _CIDTYPE2_H_ */ diff --git a/Build/source/texk/dvipdf-x/cmap.c b/Build/source/texk/dvipdf-x/cmap.c new file mode 100644 index 00000000000..033431234de --- /dev/null +++ b/Build/source/texk/dvipdf-x/cmap.c @@ -0,0 +1,997 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 ? + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxutil.h" + +#include "cmap_p.h" +#include "cmap.h" + +static int __verbose = 0; +static int __silent = 0; + +void +CMap_set_verbose (void) +{ + __verbose++; +} + +void +CMap_set_silent (int value) +{ + __silent = value ? 1 : 0; +} + +/* Private funcs. */ +static int bytes_consumed (CMap *cmap, const unsigned char *instr, long inbytes); +static void handle_undefined (CMap *cmap, + const unsigned char **inbuf, long *inbytesleft, + unsigned char **outbuf, long *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 = 2; + cmap->profile.maxBytesIn = 2; + cmap->profile.minBytesOut = 2; + cmap->profile.maxBytesOut = 2; + + 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, long *inbytesleft, + unsigned char **outbuf, long *outbytesleft) +{ + long 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, long *inbytesleft, + unsigned char **outbuf, long *outbytesleft) +{ + mapDef *t; + const unsigned char *p, *save; + unsigned char c = 0; + long 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. + */ +long +CMap_decode (CMap *cmap, + const unsigned char **inbuf, long *inbytesleft, + unsigned char **outbuf, long *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. */ +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 c; + 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 (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, long 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 (__verbose) + 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 (__verbose) + 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/dvipdf-x/cmap.h b/Build/source/texk/dvipdf-x/cmap.h new file mode 100644 index 00000000000..f6337282196 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cmap.h @@ -0,0 +1,118 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 + +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_verbose (void); +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 int CMap_match_codespace (CMap *cmap, const unsigned char *c, int dim); + +extern void CMap_decode_char (CMap *cmap, + const unsigned char **inbuf, long *inbytesleft, + unsigned char **outbuf, long *outbytesleft); + +extern long CMap_decode (CMap *cmap, + const unsigned char **inbuf, long *inbytesleft, + unsigned char **outbuf, long *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/dvipdf-x/cmap_p.h b/Build/source/texk/dvipdf-x/cmap_p.h new file mode 100644 index 00000000000..62e94277c36 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cmap_p.h @@ -0,0 +1,104 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 { + long pos; /* Position of next free data segment */ + unsigned char *data; /* CID, Code... MEM_ALLOC_SIZE bytes */ + struct mapData *prev; /* Previous mapData 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/dvipdf-x/cmap_read.c b/Build/source/texk/dvipdf-x/cmap_read.c new file mode 100644 index 00000000000..6128cf5084a --- /dev/null +++ b/Build/source/texk/dvipdf-x/cmap_read.c @@ -0,0 +1,608 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" + +#include "dpxutil.h" +#include "pst.h" + +#include "cmap_p.h" +#include "cmap.h" + +#include "cmap_read.h" + +static int __verbose = 0; + +#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; + long max; + FILE *fp; + long unread; +} ifreader; + +static ifreader *ifreader_create (FILE *fp, long remain, long bufsize); +static long ifreader_read (ifreader *reader, long size); +static void ifreader_destroy (ifreader *reader); + +static ifreader * +ifreader_create (FILE *fp, long size, long 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 long +ifreader_read (ifreader *reader, long size) +{ + long bytesread = 0, bytesrem = 0; + + ASSERT(reader); + bytesrem = (long) reader->endptr - (long) reader->cursor; + if (size > reader->max) { + if (__verbose) + MESG("\nExtending buffer (%ld bytes)...\n", size); + 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; + if (__verbose) + MESG("Reading more %ld bytes (%ld bytes remains in buffer)...\n", bytesread, bytesrem); + } + + *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 + * [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), (int) 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]; + long 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), (int) 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]; + long 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; + long 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), (int) pst_length_of(tok1), + (unsigned char *) pst_data_ptr(tok2), (int) 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; + long 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)) && !memcmp(pst_data_ptr((t)),(n),strlen((n)))) +#define MATCH_OP(t,n) (PST_UNKNOWNTYPE((t)) && !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/dvipdf-x/cmap_read.h b/Build/source/texk/dvipdf-x/cmap_read.h new file mode 100644 index 00000000000..7d63339c3ba --- /dev/null +++ b/Build/source/texk/dvipdf-x/cmap_read.h @@ -0,0 +1,34 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 +#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/dvipdf-x/cmap_write.c b/Build/source/texk/dvipdf-x/cmap_write.c new file mode 100644 index 00000000000..6772d511cf7 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cmap_write.c @@ -0,0 +1,601 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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" + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#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 +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, (long) (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, (long) (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, (long) (wbuf->curptr - wbuf->buf)); + wbuf->curptr = wbuf->buf; + pdf_add_stream(stream, + "endbfrange\n", strlen("endbfrange\n")); + } + + return count; +} + +#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, int flags) /* flags unused */ +{ + 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 { + long 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, 0); + 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 4096 + 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 /%s def\n", cmap->name); + 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, CMAP_CSI_FMT, + csi->registry, csi->ordering, csi->supplement); + pdf_add_stream(stream, wbuf.buf, (long)(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, (long)(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, (long) (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/dvipdf-x/cmap_write.h b/Build/source/texk/dvipdf-x/cmap_write.h new file mode 100644 index 00000000000..9d782931605 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cmap_write.h @@ -0,0 +1,35 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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, int flags); +extern pdf_obj *CMap_ToCode_stream (CMap *cmap, const char *cmap_name, + CIDSysInfo *csi, int cmap_type, + unsigned char *used_slot, int flags); + +#endif /* _CMAP_WRITE_H_ */ diff --git a/Build/source/texk/dvipdf-x/config.h.in b/Build/source/texk/dvipdf-x/config.h.in new file mode 100644 index 00000000000..e43c8606b66 --- /dev/null +++ b/Build/source/texk/dvipdf-x/config.h.in @@ -0,0 +1,272 @@ +/* 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 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 `compress' function. */ +#undef HAVE_COMPRESS + +/* Define to 1 if you have the `compress2' function. */ +#undef HAVE_COMPRESS2 + +/* 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 header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the 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 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 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 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 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 `png_get_image_width' function. */ +#undef HAVE_PNG_GET_IMAGE_WIDTH + +/* Define to 1 if you have the `putenv' function. */ +#undef HAVE_PUTENV + +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* 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 header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define if 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 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 in which 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 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 + +/* 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 , + , or 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 , + , or 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 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to `unsigned int' if 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 diff --git a/Build/source/texk/dvipdf-x/configure b/Build/source/texk/dvipdf-x/configure new file mode 100755 index 00000000000..167d4020465 --- /dev/null +++ b/Build/source/texk/dvipdf-x/configure @@ -0,0 +1,18462 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for dvipdf-x 20130624. +# +# Report bugs to . +# +# +# 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 tex-k@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 &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='dvipdf-x' +PACKAGE_TARNAME='dvipdf-x' +PACKAGE_VERSION='20130624' +PACKAGE_STRING='dvipdf-x 20130624' +PACKAGE_BUGREPORT='tex-k@tug.org' +PACKAGE_URL='' + +ac_unique_file="agl.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +XDVIPDFMX_FALSE +XDVIPDFMX_TRUE +DVIPDFMX_FALSE +DVIPDFMX_TRUE +WIN32_CALL_FALSE +WIN32_CALL_TRUE +WIN32_FALSE +WIN32_TRUE +FREETYPE2_RULE +FREETYPE2_DEPEND +FREETYPE2_LIBS +FREETYPE2_INCLUDES +FT2_CONFIG +LIBPNG_RULE +LIBPNG_DEPEND +LIBPNG_LIBS +LIBPNG_INCLUDES +PKG_CONFIG +ZLIB_RULE +ZLIB_DEPEND +ZLIB_LIBS +ZLIB_INCLUDES +KPATHSEA_RULE +KPATHSEA_DEPEND +KPATHSEA_LIBS +KPATHSEA_INCLUDES +LIBOBJS +CPP +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__quote +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' +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_gnu_ld +with_sysroot +enable_libtool_lock +enable_largefile +enable_dvipdf +enable_xdvipdf +enable_libtool_hack +with_system_kpathsea +with_kpathsea_includes +with_kpathsea_libdir +with_system_zlib +with_zlib_includes +with_zlib_libdir +with_system_libpng +with_system_freetype2 +with_paper +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +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 dvipdf-x 20130624 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/dvipdf-x] + --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 dvipdf-x 20130624:";; + 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 + --disable-dvipdf do not build the dvipdf program + --disable-xdvipdf do not build the xdvipdf program + --enable-libtool-hack ignore libtool dependency_libs + +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-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 + --with-kpathsea-includes=DIR + kpathsea headers installed in DIR + --with-kpathsea-libdir=DIR + kpathsea library installed in DIR + --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-freetype2 use installed freetype2 headers and library + (requires freetype-config) + --with-paper=DIR use paper include/library files from DIR + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + 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 . +_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 +dvipdf-x configure 20130624 +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 declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#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 tex-k@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_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_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_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 +#include +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 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 dvipdf-x $as_me 20130624, 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.14' + +# 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 + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +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}" != 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" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# 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 +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 +#include +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.2' +macro_revision='1.3337' + + + + + + + + + + + + + +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 "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; 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 "$with_gnu_ld" = yes; 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 &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 &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 + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + 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 "$lt_cv_path_NM" != "no"; 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 /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + 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; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # 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"; 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 $i != 17 # 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"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +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 "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; 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 +# which 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. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && 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 + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +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) + 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*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 + ;; +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 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 "$ac_status" -eq 0; 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 "$ac_status" -ne 0; 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 "x$lt_cv_ar_at_file" = xno; 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 + 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 "$host_cpu" = ia64; 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 + +# 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 -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$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 -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/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 + # and D for any global 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};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print 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 con'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* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$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 "$pipe_works" = yes; 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 "$GCC" = yes; 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; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && 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 which ABI we are using. + 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 which ABI we are using. + 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 "$lt_cv_prog_gnu_ld" = yes; 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* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + 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*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|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" + ;; + ppc*-*linux*|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 x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + 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*) + 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 "x$lt_cv_path_mainfest_tool" != xyes; 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 $_lt_result -eq 0; 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 $_lt_result -eq 0 && $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 "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; 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 "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + 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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 +#include +#include +#include + +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 + +_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 + +_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 +#include +#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 + + +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='dvipdf-x' + VERSION='20130624' + + +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: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target. 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: + +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: . + +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 +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.*) : + kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wdeclaration-after-statement" ;; #( + *) : + ;; +esac + case `$CC -dumpversion` in #( + 3.[234].* | 4.*) : + 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.*) : + 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 + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # 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 + + + + + + + + + + + +# 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 "X${COLLECT_NAMES+set}" != Xset; 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 + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# 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 "$GCC" = yes; 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" + # 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 x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; 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 "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + 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' + ;; + + 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 "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + 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' + ;; + + 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) + 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' + ;; + 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 which 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" + # 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 x"$lt_cv_prog_compiler_pic_works" = xyes; 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 x"$lt_cv_prog_compiler_static_works" = xyes; 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 "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; 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 "$hard_links" = no; 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 "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + 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 "$with_gnu_ld" = yes; 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 "$lt_use_gnu_ld_interface" = yes; 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 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 "$host_cpu" != ia64; 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 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 (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 + ;; + + 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 "$host_os" = linux-dietlibc; 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 "$tmp_diet" = no + 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' ;; + 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 "x$supports_anon_versioning" = xyes; 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 + 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 "x$supports_anon_versioning" = xyes; 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 can not +*** 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 "$ld_shlibs" = no; 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 "$GCC" = yes && 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 "$host_cpu" = ia64; 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 AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + 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) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | 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 + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + 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,' + + if test "$GCC" = yes; 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 "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + 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_use_runtimelinking" = yes; 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 "${lt_cv_aix_libpath+set}" = 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 "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; 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 "${lt_cv_aix_libpath+set}" = 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 "$with_gnu_ld" = yes; 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 + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + 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~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $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 "$lt_cv_ld_force_load" = "yes"; 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*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; 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 "$GCC" = yes; 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 $output_objdir/$soname = $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 $output_objdir/$soname = $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 "$GCC" = yes && test "$with_gnu_ld" = no; 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 "$with_gnu_ld" = no; 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 "$GCC" = yes && test "$with_gnu_ld" = no; 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 x"$lt_cv_prog_compiler__b" = xyes; 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 "$with_gnu_ld" = no; 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 "$GCC" = yes; 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 "$lt_cv_irix_exported_symbol" = yes; 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 + ;; + + 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*) + 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; 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 "$GCC" = yes; 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 "$GCC" = yes; 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 "$GCC" = yes; 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 "x$host_vendor" = xsequent; 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 "$GCC" = yes; 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 can NOT 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 "$GCC" = yes; 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 x$host_vendor = xsni; 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 "$ld_shlibs" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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 "$GCC" = yes; 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` + 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" + else + 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 "$host_cpu" = ia64; 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 + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.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}' + else + # 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' + fi + 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%'\''`; test $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} $libname${shared_ext}' + 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 + ;; + +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' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +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=yes + 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 "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + 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 "$lt_cv_prog_gnu_ld" = yes; 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 + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-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 + + # Append ld.so.conf contents 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*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + 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 + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +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 "$with_gnu_ld" = yes; 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=freebsd-elf + 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 "$with_gnu_ld" = yes; 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 "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $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 "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; 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 "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; 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 + + ;; + + *) + 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 "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && 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 "$cross_compiling" = yes; 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 +#endif + +#include + +#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 -fvisbility=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 "x$lt_cv_dlopen_self" = xyes; 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 "$cross_compiling" = yes; 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 +#endif + +#include + +#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 -fvisbility=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 which 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + 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 "$enable_shared" = yes || 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 + /* 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 + /* 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 + /* 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 + /* 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 + /* 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 /* for off_t */ + #include +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 /* for off_t */ + #include +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 +#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 +#include +#include +#include + +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 + +_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 + +_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 +#include +#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 strcasecmp strtol strstr +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 + +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_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 + + + +## Define configure options for dvipdf-x. +# Check whether --enable-dvipdf was given. +if test "${enable_dvipdf+set}" = set; then : + enableval=$enable_dvipdf; +fi + +case enable_dvipdf in #( + yes | no) : + ;; #( + *) : + enable_dvipdf=yes ;; +esac +# Check whether --enable-xdvipdf was given. +if test "${enable_xdvipdf+set}" = set; then : + enableval=$enable_xdvipdf; +fi + +case enable_xdvipdf in #( + yes | no) : + ;; #( + *) : + enable_xdvipdf=yes ;; +esac + +test "x$enable_dvipdf_x:$enable_xdvipdf" = xyes:yes && need_freetype2=yes + + +ac_config_headers="$ac_config_headers config.h" + + +# Check whether --enable-libtool-hack was given. +if test "${enable_libtool_hack+set}" = set; then : + enableval=$enable_libtool_hack; +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 +#include +#include +#include + +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 + +_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 + +_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 +#include +#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 + +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 mkstemp 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 +#include + +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 +#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 +" +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 +#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 + #include + +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 + #include + +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 defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +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 + +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_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 +" +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 +" +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 + +## _KPSE_INIT: Initialize TL infrastructure +kpse_BLD=`(cd "./../../." && pwd)` +kpse_SRC=`(cd "$srcdir/../../." && pwd)` + +## _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 ." + +lt_cl_version="\ +dvipdf-x config.lt 20130624 +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"`' +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_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"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $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"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $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_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +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\\"\\\`\\\\\\"" + ;; + *) + 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 \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which 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' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + +enable_libtool_hack='$enable_libtool_hack' + + +_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 which 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 + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $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. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# 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 +# 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### 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 + +# 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 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 + +# 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 in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# 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 + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# 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 + + 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 "X${COLLECT_NAMES+set}" != Xset; 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) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +## KPSE_LT_HACK: Prevent libtool from linking dependency_libs +if test "x$enable_libtool_hack" = xyes; then + $SED '/# Convert "-framework/i\ + ## KPSE_LT_HACK: ignore dependency_libs\ + test "X$installed" = Xyes && dependency_libs=\ +' "$ofile" >"$cfgfile" + mv "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +fi + +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 "$silent" = yes && + 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" + +## _KPSE_LIB_FLAGS: Setup kpathsea (-lkpathsea) flags + +# Check whether --with-system-kpathsea was given. +if test "${with_system_kpathsea+set}" = set; then : + withval=$with_system_kpathsea; +fi + +# Check whether --with-kpathsea-includes was given. +if test "${with_kpathsea_includes+set}" = set; then : + withval=$with_kpathsea_includes; +fi + +# Check whether --with-kpathsea-libdir was given. +if test "${with_kpathsea_libdir+set}" = set; then : + withval=$with_kpathsea_libdir; +fi +if test "x$with_system_kpathsea" = xyes; then + if test "x$with_kpathsea_includes" != x && test "x$with_kpathsea_includes" != xyes; then + KPATHSEA_INCLUDES="-I$with_kpathsea_includes" +fi +KPATHSEA_LIBS="-lkpathsea" +if test "x$with_kpathsea_libdir" != x && test "x$with_kpathsea_libdir" != xyes; then + KPATHSEA_LIBS="-L$with_kpathsea_libdir $KPATHSEA_LIBS" +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 +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 + +## _KPSE_LIB_FLAGS: Setup zlib (-lz) flags + +# 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 + 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 + +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 + +## _KPSE_LIB_FLAGS: Setup libpng (-lpng) flags + +# 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 + +## _KPSE_LIB_FLAGS: Setup freetype2 (-lfreetype) flags + +# Check whether --with-system-freetype2 was given. +if test "${with_system_freetype2+set}" = set; then : + withval=$with_system_freetype2; +fi +if test "x$with_system_freetype2" = xyes; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}freetype-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}freetype-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_FT2_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$FT2_CONFIG"; then + ac_cv_prog_FT2_CONFIG="$FT2_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_FT2_CONFIG="${ac_tool_prefix}freetype-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 +FT2_CONFIG=$ac_cv_prog_FT2_CONFIG +if test -n "$FT2_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FT2_CONFIG" >&5 +$as_echo "$FT2_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_FT2_CONFIG"; then + ac_ct_FT2_CONFIG=$FT2_CONFIG + # Extract the first word of "freetype-config", so it can be a program name with args. +set dummy freetype-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_FT2_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_FT2_CONFIG"; then + ac_cv_prog_ac_ct_FT2_CONFIG="$ac_ct_FT2_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_FT2_CONFIG="freetype-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_FT2_CONFIG=$ac_cv_prog_ac_ct_FT2_CONFIG +if test -n "$ac_ct_FT2_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FT2_CONFIG" >&5 +$as_echo "$ac_ct_FT2_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_FT2_CONFIG" = x; then + FT2_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 + FT2_CONFIG=$ac_ct_FT2_CONFIG + fi +else + FT2_CONFIG="$ac_cv_prog_FT2_CONFIG" +fi +if $FT2_CONFIG --ftversion >/dev/null 2>&1; then + FREETYPE2_INCLUDES=`$FT2_CONFIG --cflags` + FREETYPE2_LIBS=`$FT2_CONFIG --libs` +elif test "x$need_freetype2:$with_system_freetype2" = xyes:yes; then + as_fn_error $? "did not find freetype-config required for system freetype2 library" "$LINENO" 5 +fi +else + FREETYPE2_INCLUDES="-I$kpse_BLD/libs/freetype2/freetype2 -I$kpse_BLD/libs/freetype2" + FREETYPE2_LIBS="$kpse_BLD/libs/freetype2/libfreetype.la" + FREETYPE2_DEPEND='${top_builddir}/../../libs/freetype2/libfreetype.la' + FREETYPE2_RULE='# Rebuild libfreetype +$(FREETYPE2_DEPEND): ${top_builddir}/../../libs/freetype2/ft2build.h + cd ${top_builddir}/../../libs/freetype2 && $(MAKE) $(AM_MAKEFLAGS) rebuild +${top_builddir}/../../libs/freetype2/ft2build.h: + cd ${top_builddir}/../../libs/freetype2 && $(MAKE) $(AM_MAKEFLAGS) rebuild' +fi + + +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\" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for zlib header files and library" >&5 +$as_echo_n "checking for zlib header files and library... " >&6; } +if ${cho_cv_have_zlib+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +z_stream p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + cho_cv_have_zlib=yes +else + cho_cv_have_zlib=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: $cho_cv_have_zlib" >&5 +$as_echo "$cho_cv_have_zlib" >&6; } +if test "x$cho_cv_have_zlib" = xyes; then : + for ac_func in compress +do : + ac_fn_c_check_func "$LINENO" "compress" "ac_cv_func_compress" +if test "x$ac_cv_func_compress" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_COMPRESS 1 +_ACEOF + +$as_echo "#define HAVE_ZLIB 1" >>confdefs.h + + for ac_func in compress2 +do : + ac_fn_c_check_func "$LINENO" "compress2" "ac_cv_func_compress2" +if test "x$ac_cv_func_compress2" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_COMPRESS2 1 +_ACEOF + +$as_echo "#define HAVE_ZLIB_COMPRESS2 1" >>confdefs.h + +fi +done + +fi +done + +fi + + +eval CPPFLAGS=\"$LIBPNG_INCLUDES \$CPPFLAGS\" +eval LIBS=\"$LIBPNG_LIBS \$LIBS\" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpng header files and library" >&5 +$as_echo_n "checking for libpng header files and library... " >&6; } +if ${cho_cv_have_png+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +png_infop p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + cho_cv_have_png=yes +else + cho_cv_have_png=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: $cho_cv_have_png" >&5 +$as_echo "$cho_cv_have_png" >&6; } +if test "x$cho_cv_have_png" = xyes; then : + for ac_func in png_get_image_width +do : + ac_fn_c_check_func "$LINENO" "png_get_image_width" "ac_cv_func_png_get_image_width" +if test "x$ac_cv_func_png_get_image_width" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PNG_GET_IMAGE_WIDTH 1 +_ACEOF + +$as_echo "#define HAVE_LIBPNG 1" >>confdefs.h + +fi +done + +fi + + +CPPFLAGS=$kpse_save_CPPFLAGS +LIBS=$kpse_save_LIBS + + +echo timestamp >config.force +fi + + +if test "x$enable_texlive_build" != xyes || test ! -d $srcdir/../kpathsea; then + _cppflags=$CPPFLAGS _ldflags=$LDFLAGS + +# Check whether --with-paper was given. +if test "${with_paper+set}" = set; then : + withval=$with_paper; if test -d "$withval"; then + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + fi +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for paper header files" >&5 +$as_echo_n "checking for paper header files... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +struct paper *p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing paperpswidth" >&5 +$as_echo_n "checking for library containing paperpswidth... " >&6; } +if ${ac_cv_search_paperpswidth+:} 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 paperpswidth (); +int +main () +{ +return paperpswidth (); + ; + return 0; +} +_ACEOF +for ac_lib in '' paper; 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_paperpswidth=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_paperpswidth+:} false; then : + break +fi +done +if ${ac_cv_search_paperpswidth+:} false; then : + +else + ac_cv_search_paperpswidth=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_paperpswidth" >&5 +$as_echo "$ac_cv_search_paperpswidth" >&6; } +ac_res=$ac_cv_search_paperpswidth +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_LIBPAPER 1" >>confdefs.h + +fi + +else + CPPFLAGS=$_cppflags + LDDFLAGS=$_ldflags + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi + +{ $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 + + + if test "x$enable_dvipdf" != xno; then + DVIPDFMX_TRUE= + DVIPDFMX_FALSE='#' +else + DVIPDFMX_TRUE='#' + DVIPDFMX_FALSE= +fi + + if test "x$enable_xdvipdf" != xno; then + XDVIPDFMX_TRUE= + XDVIPDFMX_FALSE='#' +else + XDVIPDFMX_TRUE='#' + XDVIPDFMX_FALSE= +fi + + +ac_config_files="$ac_config_files Makefile data/Makefile man/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 +if test -z "${DVIPDFMX_TRUE}" && test -z "${DVIPDFMX_FALSE}"; then + as_fn_error $? "conditional \"DVIPDFMX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${XDVIPDFMX_TRUE}" && test -z "${XDVIPDFMX_FALSE}"; then + as_fn_error $? "conditional \"XDVIPDFMX\" 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 dvipdf-x $as_me 20130624, 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 ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +dvipdf-x config.status 20130624 +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" ac_aux_dir="$ac_aux_dir" + + +# 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"`' +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_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"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $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"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $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_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +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\\"\\\`\\\\\\"" + ;; + *) + 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 \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which 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' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + +enable_libtool_hack='$enable_libtool_hack' +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" ;; + "data/Makefile") CONFIG_FILES="$CONFIG_FILES data/Makefile" ;; + "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/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` +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 +' >$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 +' >$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. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which 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 + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $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. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# 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 +# 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### 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 + +# 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 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 + +# 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 in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# 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 + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# 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 + + 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 "X${COLLECT_NAMES+set}" != Xset; 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) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +## KPSE_LT_HACK: Prevent libtool from linking dependency_libs +if test "x$enable_libtool_hack" = xyes; then + $SED '/# Convert "-framework/i\ + ## KPSE_LT_HACK: ignore dependency_libs\ + test "X$installed" = Xyes && dependency_libs=\ +' "$ofile" >"$cfgfile" + mv "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +fi + ;; + + 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/dvipdf-x/configure.ac b/Build/source/texk/dvipdf-x/configure.ac new file mode 100644 index 00000000000..43533b9d6f0 --- /dev/null +++ b/Build/source/texk/dvipdf-x/configure.ac @@ -0,0 +1,94 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl Copyright (C) 2009-2013 Peter Breitenlohner +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([dvipdf-x], [20130624], [tex-k@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([dvipdf-x]) + +m4_include([ac/dvipdf-x.ac]) + +AC_CONFIG_HEADERS([config.h]) + +KPSE_LT_HACK + +dnl Checks for header files. +AC_HEADER_STDC +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 mkstemp basename]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_STRUCT_TM +AC_STRUCT_TIMEZONE +AC_C_BIGENDIAN +AC_TYPE_UINT32_T + +AC_CHECK_DECL([timezone], + [AC_DEFINE([HAVE_TIMEZONE], 1, + [Define if has timezone as an external variable.])], + [], + [[#include ]]) +AC_CHECK_MEMBER([struct tm.tm_gmtoff], + [AC_DEFINE([HAVE_TM_GMTOFF], 1, + [Define if struct tm has tm_gmtoff as a member.])], + [], + [[#include ]]) + +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_FREETYPE2_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]) +CHO_CHECK_ZLIB + +KPSE_ADD_FLAGS([libpng]) +CHO_CHECK_LIBPNG + +KPSE_RESTORE_FLAGS + +echo timestamp >config.force +fi + +dnl Check for additional libraries. + +if test "x$enable_texlive_build" != xyes || test ! -d $srcdir/../kpathsea; then + CHO_CHECK_LIBPAPER +fi + +KPSE_WIN32_CALL + +AM_CONDITIONAL([DVIPDFMX], [test "x$enable_dvipdf" != xno]) +AM_CONDITIONAL([XDVIPDFMX], [test "x$enable_xdvipdf" != xno]) + +AC_CONFIG_FILES([Makefile + data/Makefile + man/Makefile + ]) + +AC_OUTPUT diff --git a/Build/source/texk/dvipdf-x/cs_type2.c b/Build/source/texk/dvipdf-x/cs_type2.c new file mode 100644 index 00000000000..fcb3edf4805 --- /dev/null +++ b/Build/source/texk/dvipdf-x/cs_type2.c @@ -0,0 +1,807 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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.. + */ + +#include + +/* fabs, sqrt ... */ +#include + +#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; + long ivalue; + value = arg_stack[i]; + /* Nearest integer value */ + ivalue = (long) 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 = (long) floor(value); /* mantissa */ + *(*dest)++ = (ivalue >> 8) & 0xff; + *(*dest)++ = ivalue & 0xff; + ivalue = (long)((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; + break; + 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) +{ + long 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) +{ + long 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, long *len, cff_index *subr_idx, long 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; + long 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, (long) 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, (long) 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... + */ +long +cs_copy_charstring (card8 *dst, long dstlen, + card8 *src, long 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 (long)(dst - save); +} diff --git a/Build/source/texk/dvipdf-x/cs_type2.h b/Build/source/texk/dvipdf-x/cs_type2.h new file mode 100644 index 00000000000..4d23fd8b1aa --- /dev/null +++ b/Build/source/texk/dvipdf-x/cs_type2.h @@ -0,0 +1,45 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 long cs_copy_charstring (card8 *dest, long destlen, + card8 *src, long 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/dvipdf-x/data/EUC-UCS2 b/Build/source/texk/dvipdf-x/data/EUC-UCS2 new file mode 100644 index 00000000000..d7a91685ad5 --- /dev/null +++ b/Build/source/texk/dvipdf-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 +%% +%% 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> + +endcodespacerange + +17 beginbfrange +<00> <5B> <0000> +<5D> <7D> <005D> +<8EA0> <8EDF> + <3008> + + + + <3041> + <30A1> + <0391> + <03A3> + <03B1> + <03C3> + <0410> + <0416> + <0430> + <0436> +endbfrange + +99 beginbfchar +<5C> <00A5> +<7E> <203E> + <3000> + <3001> + <3002> + + + <30FB> + + + + + <309B> + <309C> + <00B4> + + <00A8> + + <203E> + + <30FD> + <30FE> + <309D> + <309E> + <3003> + <4EDD> + <3005> + <3006> + <3007> + <30FC> + <2015> + <2010> + + + + <2016> + + <2026> + <2025> + <2018> + <2019> + <201C> + <201D> + + + <3014> + <3015> + + + + + + + <00B1> + <00D7> + <00F7> + + <2260> + + + <2266> + <2267> + <221E> + <2234> + <2642> + <2640> + <00B0> + <2032> + <2033> + <2103> + + + <00A2> + <00A3> + + + + + + <00A7> + <2606> + <2605> + <25CB> + <25CF> + <25CE> + <25C7> + <25C6> + <25A1> + <25A0> + <25B3> + <25B2> + <25BD> + <25BC> + <203B> + <3012> + <2192> + <2190> + <2191> + <2193> +endbfchar + +100 beginbfchar + <3013> + <2208> + <220B> + <2286> + <2287> + <2282> + <2283> + <222A> + <2229> + <2227> + <2228> + <00AC> + <21D2> + <21D4> + <2200> + <2203> + <2220> + <22A5> + <2312> + <2202> + <2207> + <2261> + <2252> + <226A> + <226B> + <221A> + <223D> + <221D> + <2235> + <222B> + <222C> + <212B> + <2030> + <266F> + <266D> + <266A> + <2020> + <2021> + <00B6> + <25EF> + <0401> + <0451> + <2500> + <2502> + <250C> + <2510> + <2518> + <2514> + <251C> + <252C> + <2524> + <2534> + <253C> + <2501> + <2503> + <250F> + <2513> + <251B> + <2517> + <2523> + <2533> + <252B> + <253B> + <254B> + <2520> + <252F> + <2528> + <2537> + <253F> + <251D> + <2530> + <2525> + <2538> + <2542> + <4E9C> + <5516> + <5A03> + <963F> + <54C0> + <611B> + <6328> + <59F6> + <9022> + <8475> + <831C> + <7A50> + <60AA> + <63E1> + <6E25> + <65ED> + <8466> + <82A6> + <9BF5> + <6893> + <5727> + <65A1> + <6271> + <5B9B> + <59D0> + <867B> +endbfchar + +100 beginbfchar + <98F4> + <7D62> + <7DBE> + <9B8E> + <6216> + <7C9F> + <88B7> + <5B89> + <5EB5> + <6309> + <6697> + <6848> + <95C7> + <978D> + <674F> + <4EE5> + <4F0A> + <4F4D> + <4F9D> + <5049> + <56F2> + <5937> + <59D4> + <5A01> + <5C09> + <60DF> + <610F> + <6170> + <6613> + <6905> + <70BA> + <754F> + <7570> + <79FB> + <7DAD> + <7DEF> + <80C3> + <840E> + <8863> + <8B02> + <9055> + <907A> + <533B> + <4E95> + <4EA5> + <57DF> + <80B2> + <90C1> + <78EF> + <4E00> + <58F1> + <6EA2> + <9038> + <7A32> + <8328> + <828B> + <9C2F> + <5141> + <5370> + <54BD> + <54E1> + <56E0> + <59FB> + <5F15> + <98F2> + <6DEB> + <80E4> + <852D> + <9662> + <9670> + <96A0> + <97FB> + <540B> + <53F3> + <5B87> + <70CF> + <7FBD> + <8FC2> + <96E8> + <536F> + <9D5C> + <7ABA> + <4E11> + <7893> + <81FC> + <6E26> + <5618> + <5504> + <6B1D> + <851A> + <9C3B> + <59E5> + <53A9> + <6D66> + <74DC> + <958F> + <5642> + <4E91> + <904B> + <96F2> +endbfchar + +100 beginbfchar + <834F> + <990C> + <53E1> + <55B6> + <5B30> + <5F71> + <6620> + <66F3> + <6804> + <6C38> + <6CF3> + <6D29> + <745B> + <76C8> + <7A4E> + <9834> + <82F1> + <885B> + <8A60> + <92ED> + <6DB2> + <75AB> + <76CA> + <99C5> + <60A6> + <8B01> + <8D8A> + <95B2> + <698E> + <53AD> + <5186> + <5712> + <5830> + <5944> + <5BB4> + <5EF6> + <6028> + <63A9> + <63F4> + <6CBF> + <6F14> + <708E> + <7114> + <7159> + <71D5> + <733F> + <7E01> + <8276> + <82D1> + <8597> + <9060> + <925B> + <9D1B> + <5869> + <65BC> + <6C5A> + <7525> + <51F9> + <592E> + <5965> + <5F80> + <5FDC> + <62BC> + <65FA> + <6A2A> + <6B27> + <6BB4> + <738B> + <7FC1> + <8956> + <9D2C> + <9D0E> + <9EC4> + <5CA1> + <6C96> + <837B> + <5104> + <5C4B> + <61B6> + <81C6> + <6876> + <7261> + <4E59> + <4FFA> + <5378> + <6069> + <6E29> + <7A4F> + <97F3> + <4E0B> + <5316> + <4EEE> + <4F55> + <4F3D> + <4FA1> + <4F73> + <52A0> + <53EF> + <5609> + <590F> +endbfchar + +100 beginbfchar + <5AC1> + <5BB6> + <5BE1> + <79D1> + <6687> + <679C> + <67B6> + <6B4C> + <6CB3> + <706B> + <73C2> + <798D> + <79BE> + <7A3C> + <7B87> + <82B1> + <82DB> + <8304> + <8377> + <83EF> + <83D3> + <8766> + <8AB2> + <5629> + <8CA8> + <8FE6> + <904E> + <971E> + <868A> + <4FC4> + <5CE8> + <6211> + <7259> + <753B> + <81E5> + <82BD> + <86FE> + <8CC0> + <96C5> + <9913> + <99D5> + <4ECB> + <4F1A> + <89E3> + <56DE> + <584A> + <58CA> + <5EFB> + <5FEB> + <602A> + <6094> + <6062> + <61D0> + <6212> + <62D0> + <6539> + <9B41> + <6666> + <68B0> + <6D77> + <7070> + <754C> + <7686> + <7D75> + <82A5> + <87F9> + <958B> + <968E> + <8C9D> + <51F1> + <52BE> + <5916> + <54B3> + <5BB3> + <5D16> + <6168> + <6982> + <6DAF> + <788D> + <84CB> + <8857> + <8A72> + <93A7> + <9AB8> + <6D6C> + <99A8> + <86D9> + <57A3> + <67FF> + <86CE> + <920E> + <5283> + <5687> + <5404> + <5ED3> + <62E1> + <64B9> + <683C> + <6838> + <6BBB> +endbfchar + +100 beginbfchar + <7372> + <78BA> + <7A6B> + <899A> + <89D2> + <8D6B> + <8F03> + <90ED> + <95A3> + <9694> + <9769> + <5B66> + <5CB3> + <697D> + <984D> + <984E> + <639B> + <7B20> + <6A2B> + <6A7F> + <68B6> + <9C0D> + <6F5F> + <5272> + <559D> + <6070> + <62EC> + <6D3B> + <6E07> + <6ED1> + <845B> + <8910> + <8F44> + <4E14> + <9C39> + <53F6> + <691B> + <6A3A> + <9784> + <682A> + <515C> + <7AC3> + <84B2> + <91DC> + <938C> + <565B> + <9D28> + <6822> + <8305> + <8431> + <7CA5> + <5208> + <82C5> + <74E6> + <4E7E> + <4F83> + <51A0> + <5BD2> + <520A> + <52D8> + <52E7> + <5DFB> + <559A> + <582A> + <59E6> + <5B8C> + <5B98> + <5BDB> + <5E72> + <5E79> + <60A3> + <611F> + <6163> + <61BE> + <63DB> + <6562> + <67D1> + <6853> + <68FA> + <6B3E> + <6B53> + <6C57> + <6F22> + <6F97> + <6F45> + <74B0> + <7518> + <76E3> + <770B> + <7AFF> + <7BA1> + <7C21> + <7DE9> + <7F36> + <7FF0> + <809D> + <8266> + <839E> + <89B3> + <8ACC> +endbfchar + +100 beginbfchar + <8CAB> + <9084> + <9451> + <9593> + <9591> + <95A2> + <9665> + <97D3> + <9928> + <8218> + <4E38> + <542B> + <5CB8> + <5DCC> + <73A9> + <764C> + <773C> + <5CA9> + <7FEB> + <8D0B> + <96C1> + <9811> + <9854> + <9858> + <4F01> + <4F0E> + <5371> + <559C> + <5668> + <57FA> + <5947> + <5B09> + <5BC4> + <5C90> + <5E0C> + <5E7E> + <5FCC> + <63EE> + <673A> + <65D7> + <65E2> + <671F> + <68CB> + <68C4> + <6A5F> + <5E30> + <6BC5> + <6C17> + <6C7D> + <757F> + <7948> + <5B63> + <7A00> + <7D00> + <5FBD> + <898F> + <8A18> + <8CB4> + <8D77> + <8ECC> + <8F1D> + <98E2> + <9A0E> + <9B3C> + <4E80> + <507D> + <5100> + <5993> + <5B9C> + <622F> + <6280> + <64EC> + <6B3A> + <72A0> + <7591> + <7947> + <7FA9> + <87FB> + <8ABC> + <8B70> + <63AC> + <83CA> + <97A0> + <5409> + <5403> + <55AB> + <6854> + <6A58> + <8A70> + <7827> + <6775> + <9ECD> + <5374> + <5BA2> + <811A> + <8650> + <9006> + <4E18> + <4E45> + <4EC7> +endbfchar + +100 beginbfchar + <4F11> + <53CA> + <5438> + <5BAE> + <5F13> + <6025> + <6551> + <673D> + <6C42> + <6C72> + <6CE3> + <7078> + <7403> + <7A76> + <7AAE> + <7B08> + <7D1A> + <7CFE> + <7D66> + <65E7> + <725B> + <53BB> + <5C45> + <5DE8> + <62D2> + <62E0> + <6319> + <6E20> + <865A> + <8A31> + <8DDD> + <92F8> + <6F01> + <79A6> + <9B5A> + <4EA8> + <4EAB> + <4EAC> + <4F9B> + <4FA0> + <50D1> + <5147> + <7AF6> + <5171> + <51F6> + <5354> + <5321> + <537F> + <53EB> + <55AC> + <5883> + <5CE1> + <5F37> + <5F4A> + <602F> + <6050> + <606D> + <631F> + <6559> + <6A4B> + <6CC1> + <72C2> + <72ED> + <77EF> + <80F8> + <8105> + <8208> + <854E> + <90F7> + <93E1> + <97FF> + <9957> + <9A5A> + <4EF0> + <51DD> + <5C2D> + <6681> + <696D> + <5C40> + <66F2> + <6975> + <7389> + <6850> + <7C81> + <50C5> + <52E4> + <5747> + <5DFE> + <9326> + <65A4> + <6B23> + <6B3D> + <7434> + <7981> + <79BD> + <7B4B> + <7DCA> + <82B9> + <83CC> + <887F> +endbfchar + +100 beginbfchar + <895F> + <8B39> + <8FD1> + <91D1> + <541F> + <9280> + <4E5D> + <5036> + <53E5> + <533A> + <72D7> + <7396> + <77E9> + <82E6> + <8EAF> + <99C6> + <99C8> + <99D2> + <5177> + <611A> + <865E> + <55B0> + <7A7A> + <5076> + <5BD3> + <9047> + <9685> + <4E32> + <6ADB> + <91E7> + <5C51> + <5C48> + <6398> + <7A9F> + <6C93> + <9774> + <8F61> + <7AAA> + <718A> + <9688> + <7C82> + <6817> + <7E70> + <6851> + <936C> + <52F2> + <541B> + <85AB> + <8A13> + <7FA4> + <8ECD> + <90E1> + <5366> + <8888> + <7941> + <4FC2> + <50BE> + <5211> + <5144> + <5553> + <572D> + <73EA> + <578B> + <5951> + <5F62> + <5F84> + <6075> + <6176> + <6167> + <61A9> + <63B2> + <643A> + <656C> + <666F> + <6842> + <6E13> + <7566> + <7A3D> + <7CFB> + <7D4C> + <7D99> + <7E4B> + <7F6B> + <830E> + <834A> + <86CD> + <8A08> + <8A63> + <8B66> + <8EFD> + <981A> + <9D8F> + <82B8> + <8FCE> + <9BE8> + <5287> + <621F> + <6483> + <6FC0> + <9699> +endbfchar + +100 beginbfchar + <6841> + <5091> + <6B20> + <6C7A> + <6F54> + <7A74> + <7D50> + <8840> + <8A23> + <6708> + <4EF6> + <5039> + <5026> + <5065> + <517C> + <5238> + <5263> + <55A7> + <570F> + <5805> + <5ACC> + <5EFA> + <61B2> + <61F8> + <62F3> + <6372> + <691C> + <6A29> + <727D> + <72AC> + <732E> + <7814> + <786F> + <7D79> + <770C> + <80A9> + <898B> + <8B19> + <8CE2> + <8ED2> + <9063> + <9375> + <967A> + <9855> + <9A13> + <9E78> + <5143> + <539F> + <53B3> + <5E7B> + <5F26> + <6E1B> + <6E90> + <7384> + <73FE> + <7D43> + <8237> + <8A00> + <8AFA> + <9650> + <4E4E> + <500B> + <53E4> + <547C> + <56FA> + <59D1> + <5B64> + <5DF1> + <5EAB> + <5F27> + <6238> + <6545> + <67AF> + <6E56> + <72D0> + <7CCA> + <88B4> + <80A1> + <80E1> + <83F0> + <864E> + <8A87> + <8DE8> + <9237> + <96C7> + <9867> + <9F13> + <4E94> + <4E92> + <4F0D> + <5348> + <5449> + <543E> + <5A2F> + <5F8C> + <5FA1> + <609F> + <68A7> + <6A8E> + <745A> +endbfchar + +100 beginbfchar + <7881> + <8A9E> + <8AA4> + <8B77> + <9190> + <4E5E> + <9BC9> + <4EA4> + <4F7C> + <4FAF> + <5019> + <5016> + <5149> + <516C> + <529F> + <52B9> + <52FE> + <539A> + <53E3> + <5411> + <540E> + <5589> + <5751> + <57A2> + <597D> + <5B54> + <5B5D> + <5B8F> + <5DE5> + <5DE7> + <5DF7> + <5E78> + <5E83> + <5E9A> + <5EB7> + <5F18> + <6052> + <614C> + <6297> + <62D8> + <63A7> + <653B> + <6602> + <6643> + <66F4> + <676D> + <6821> + <6897> + <69CB> + <6C5F> + <6D2A> + <6D69> + <6E2F> + <6E9D> + <7532> + <7687> + <786C> + <7A3F> + <7CE0> + <7D05> + <7D18> + <7D5E> + <7DB1> + <8015> + <8003> + <80AF> + <80B1> + <8154> + <818F> + <822A> + <8352> + <884C> + <8861> + <8B1B> + <8CA2> + <8CFC> + <90CA> + <9175> + <9271> + <783F> + <92FC> + <95A4> + <964D> + <9805> + <9999> + <9AD8> + <9D3B> + <525B> + <52AB> + <53F7> + <5408> + <58D5> + <62F7> + <6FE0> + <8C6A> + <8F5F> + <9EB9> + <514B> + <523B> + <544A> +endbfchar + +100 beginbfchar + <56FD> + <7A40> + <9177> + <9D60> + <9ED2> + <7344> + <6F09> + <8170> + <7511> + <5FFD> + <60DA> + <9AA8> + <72DB> + <8FBC> + <6B64> + <9803> + <4ECA> + <56F0> + <5764> + <58BE> + <5A5A> + <6068> + <61C7> + <660F> + <6606> + <6839> + <68B1> + <6DF7> + <75D5> + <7D3A> + <826E> + <9B42> + <4E9B> + <4F50> + <53C9> + <5506> + <5D6F> + <5DE6> + <5DEE> + <67FB> + <6C99> + <7473> + <7802> + <8A50> + <9396> + <88DF> + <5750> + <5EA7> + <632B> + <50B5> + <50AC> + <518D> + <6700> + <54C9> + <585E> + <59BB> + <5BB0> + <5F69> + <624D> + <63A1> + <683D> + <6B73> + <6E08> + <707D> + <91C7> + <7280> + <7815> + <7826> + <796D> + <658E> + <7D30> + <83DC> + <88C1> + <8F09> + <969B> + <5264> + <5728> + <6750> + <7F6A> + <8CA1> + <51B4> + <5742> + <962A> + <583A> + <698A> + <80B4> + <54B2> + <5D0E> + <57FC> + <7895> + <9DFA> + <4F5C> + <524A> + <548B> + <643E> + <6628> + <6714> + <67F5> + <7A84> + <7B56> +endbfchar + +100 beginbfchar + <7D22> + <932F> + <685C> + <9BAD> + <7B39> + <5319> + <518A> + <5237> + <5BDF> + <62F6> + <64AE> + <64E6> + <672D> + <6BBA> + <85A9> + <96D1> + <7690> + <9BD6> + <634C> + <9306> + <9BAB> + <76BF> + <6652> + <4E09> + <5098> + <53C2> + <5C71> + <60E8> + <6492> + <6563> + <685F> + <71E6> + <73CA> + <7523> + <7B97> + <7E82> + <8695> + <8B83> + <8CDB> + <9178> + <9910> + <65AC> + <66AB> + <6B8B> + <4ED5> + <4ED4> + <4F3A> + <4F7F> + <523A> + <53F8> + <53F2> + <55E3> + <56DB> + <58EB> + <59CB> + <59C9> + <59FF> + <5B50> + <5C4D> + <5E02> + <5E2B> + <5FD7> + <601D> + <6307> + <652F> + <5B5C> + <65AF> + <65BD> + <65E8> + <679D> + <6B62> + <6B7B> + <6C0F> + <7345> + <7949> + <79C1> + <7CF8> + <7D19> + <7D2B> + <80A2> + <8102> + <81F3> + <8996> + <8A5E> + <8A69> + <8A66> + <8A8C> + <8AEE> + <8CC7> + <8CDC> + <96CC> + <98FC> + <6B6F> + <4E8B> + <4F3C> + <4F8D> + <5150> + <5B57> + <5BFA> + <6148> +endbfchar + +100 beginbfchar + <6301> + <6642> + <6B21> + <6ECB> + <6CBB> + <723E> + <74BD> + <75D4> + <78C1> + <793A> + <800C> + <8033> + <81EA> + <8494> + <8F9E> + <6C50> + <9E7F> + <5F0F> + <8B58> + <9D2B> + <7AFA> + <8EF8> + <5B8D> + <96EB> + <4E03> + <53F1> + <57F7> + <5931> + <5AC9> + <5BA4> + <6089> + <6E7F> + <6F06> + <75BE> + <8CEA> + <5B9F> + <8500> + <7BE0> + <5072> + <67F4> + <829D> + <5C61> + <854A> + <7E1E> + <820E> + <5199> + <5C04> + <6368> + <8D66> + <659C> + <716E> + <793E> + <7D17> + <8005> + <8B1D> + <8ECA> + <906E> + <86C7> + <90AA> + <501F> + <52FA> + <5C3A> + <6753> + <707C> + <7235> + <914C> + <91C8> + <932B> + <82E5> + <5BC2> + <5F31> + <60F9> + <4E3B> + <53D6> + <5B88> + <624B> + <6731> + <6B8A> + <72E9> + <73E0> + <7A2E> + <816B> + <8DA3> + <9152> + <9996> + <5112> + <53D7> + <546A> + <5BFF> + <6388> + <6A39> + <7DAC> + <9700> + <56DA> + <53CE> + <5468> + <5B97> + <5C31> + <5DDE> + <4FEE> +endbfchar + +100 beginbfchar + <6101> + <62FE> + <6D32> + <79C0> + <79CB> + <7D42> + <7E4D> + <7FD2> + <81ED> + <821F> + <8490> + <8846> + <8972> + <8B90> + <8E74> + <8F2F> + <9031> + <914B> + <916C> + <96C6> + <919C> + <4EC0> + <4F4F> + <5145> + <5341> + <5F93> + <620E> + <67D4> + <6C41> + <6E0B> + <7363> + <7E26> + <91CD> + <9283> + <53D4> + <5919> + <5BBF> + <6DD1> + <795D> + <7E2E> + <7C9B> + <587E> + <719F> + <51FA> + <8853> + <8FF0> + <4FCA> + <5CFB> + <6625> + <77AC> + <7AE3> + <821C> + <99FF> + <51C6> + <5FAA> + <65EC> + <696F> + <6B89> + <6DF3> + <6E96> + <6F64> + <76FE> + <7D14> + <5DE1> + <9075> + <9187> + <9806> + <51E6> + <521D> + <6240> + <6691> + <66D9> + <6E1A> + <5EB6> + <7DD2> + <7F72> + <66F8> + <85AF> + <85F7> + <8AF8> + <52A9> + <53D9> + <5973> + <5E8F> + <5F90> + <6055> + <92E4> + <9664> + <50B7> + <511F> + <52DD> + <5320> + <5347> + <53EC> + <54E8> + <5546> + <5531> + <5617> + <5968> + <59BE> +endbfchar + +100 beginbfchar + <5A3C> + <5BB5> + <5C06> + <5C0F> + <5C11> + <5C1A> + <5E84> + <5E8A> + <5EE0> + <5F70> + <627F> + <6284> + <62DB> + <638C> + <6377> + <6607> + <660C> + <662D> + <6676> + <677E> + <68A2> + <6A1F> + <6A35> + <6CBC> + <6D88> + <6E09> + <6E58> + <713C> + <7126> + <7167> + <75C7> + <7701> + <785D> + <7901> + <7965> + <79F0> + <7AE0> + <7B11> + <7CA7> + <7D39> + <8096> + <83D6> + <848B> + <8549> + <885D> + <88F3> + <8A1F> + <8A3C> + <8A54> + <8A73> + <8C61> + <8CDE> + <91A4> + <9266> + <937E> + <9418> + <969C> + <9798> + <4E0A> + <4E08> + <4E1E> + <4E57> + <5197> + <5270> + <57CE> + <5834> + <58CC> + <5B22> + <5E38> + <60C5> + <64FE> + <6761> + <6756> + <6D44> + <72B6> + <7573> + <7A63> + <84B8> + <8B72> + <91B8> + <9320> + <5631> + <57F4> + <98FE> + <62ED> + <690D> + <6B96> + <71ED> + <7E54> + <8077> + <8272> + <89E6> + <98DF> + <8755> + <8FB1> + <5C3B> + <4F38> + <4FE1> + <4FB5> + <5507> +endbfchar + +100 beginbfchar + <5A20> + <5BDD> + <5BE9> + <5FC3> + <614E> + <632F> + <65B0> + <664B> + <68EE> + <699B> + <6D78> + <6DF1> + <7533> + <75B9> + <771F> + <795E> + <79E6> + <7D33> + <81E3> + <82AF> + <85AA> + <89AA> + <8A3A> + <8EAB> + <8F9B> + <9032> + <91DD> + <9707> + <4EBA> + <4EC1> + <5203> + <5875> + <58EC> + <5C0B> + <751A> + <5C3D> + <814E> + <8A0A> + <8FC5> + <9663> + <976D> + <7B25> + <8ACF> + <9808> + <9162> + <56F3> + <53A8> + <9017> + <5439> + <5782> + <5E25> + <63A8> + <6C34> + <708A> + <7761> + <7C8B> + <7FE0> + <8870> + <9042> + <9154> + <9310> + <9318> + <968F> + <745E> + <9AC4> + <5D07> + <5D69> + <6570> + <67A2> + <8DA8> + <96DB> + <636E> + <6749> + <6919> + <83C5> + <9817> + <96C0> + <88FE> + <6F84> + <647A> + <5BF8> + <4E16> + <702C> + <755D> + <662F> + <51C4> + <5236> + <52E2> + <59D3> + <5F81> + <6027> + <6210> + <653F> + <6574> + <661F> + <6674> + <68F2> + <6816> + <6B63> + <6E05> +endbfchar + +100 beginbfchar + <7272> + <751F> + <76DB> + <7CBE> + <8056> + <58F0> + <88FD> + <897F> + <8AA0> + <8A93> + <8ACB> + <901D> + <9192> + <9752> + <9759> + <6589> + <7A0E> + <8106> + <96BB> + <5E2D> + <60DC> + <621A> + <65A5> + <6614> + <6790> + <77F3> + <7A4D> + <7C4D> + <7E3E> + <810A> + <8CAC> + <8D64> + <8DE1> + <8E5F> + <78A9> + <5207> + <62D9> + <63A5> + <6442> + <6298> + <8A2D> + <7A83> + <7BC0> + <8AAC> + <96EA> + <7D76> + <820C> + <8749> + <4ED9> + <5148> + <5343> + <5360> + <5BA3> + <5C02> + <5C16> + <5DDD> + <6226> + <6247> + <64B0> + <6813> + <6834> + <6CC9> + <6D45> + <6D17> + <67D3> + <6F5C> + <714E> + <717D> + <65CB> + <7A7F> + <7BAD> + <7DDA> + <7E4A> + <7FA8> + <817A> + <821B> + <8239> + <85A6> + <8A6E> + <8CCE> + <8DF5> + <9078> + <9077> + <92AD> + <9291> + <9583> + <9BAE> + <524D> + <5584> + <6F38> + <7136> + <5168> + <7985> + <7E55> + <81B3> + <7CCE> + <564C> + <5851> + <5CA8> + <63AA> +endbfchar + +100 beginbfchar + <66FE> + <66FD> + <695A> + <72D9> + <758F> + <758E> + <790E> + <7956> + <79DF> + <7C97> + <7D20> + <7D44> + <8607> + <8A34> + <963B> + <9061> + <9F20> + <50E7> + <5275> + <53CC> + <53E2> + <5009> + <55AA> + <58EE> + <594F> + <723D> + <5B8B> + <5C64> + <531D> + <60E3> + <60F3> + <635C> + <6383> + <633F> + <63BB> + <64CD> + <65E9> + <66F9> + <5DE3> + <69CD> + <69FD> + <6F15> + <71E5> + <4E89> + <75E9> + <76F8> + <7A93> + <7CDF> + <7DCF> + <7D9C> + <8061> + <8349> + <8358> + <846C> + <84BC> + <85FB> + <88C5> + <8D70> + <9001> + <906D> + <9397> + <971C> + <9A12> + <50CF> + <5897> + <618E> + <81D3> + <8535> + <8D08> + <9020> + <4FC3> + <5074> + <5247> + <5373> + <606F> + <6349> + <675F> + <6E2C> + <8DB3> + <901F> + <4FD7> + <5C5E> + <8CCA> + <65CF> + <7D9A> + <5352> + <8896> + <5176> + <63C3> + <5B58> + <5B6B> + <5C0A> + <640D> + <6751> + <905C> + <4ED6> + <591A> + <592A> + <6C70> + <8A51> +endbfchar + +100 beginbfchar + <553E> + <5815> + <59A5> + <60F0> + <6253> + <67C1> + <8235> + <6955> + <9640> + <99C4> + <9A28> + <4F53> + <5806> + <5BFE> + <8010> + <5CB1> + <5E2F> + <5F85> + <6020> + <614B> + <6234> + <66FF> + <6CF0> + <6EDE> + <80CE> + <817F> + <82D4> + <888B> + <8CB8> + <9000> + <902E> + <968A> + <9EDB> + <9BDB> + <4EE3> + <53F0> + <5927> + <7B2C> + <918D> + <984C> + <9DF9> + <6EDD> + <7027> + <5353> + <5544> + <5B85> + <6258> + <629E> + <62D3> + <6CA2> + <6FEF> + <7422> + <8A17> + <9438> + <6FC1> + <8AFE> + <8338> + <51E7> + <86F8> + <53EA> + <53E9> + <4F46> + <9054> + <8FB0> + <596A> + <8131> + <5DFD> + <7AEA> + <8FBF> + <68DA> + <8C37> + <72F8> + <9C48> + <6A3D> + <8AB0> + <4E39> + <5358> + <5606> + <5766> + <62C5> + <63A2> + <65E6> + <6B4E> + <6DE1> + <6E5B> + <70AD> + <77ED> + <7AEF> + <7BAA> + <7DBB> + <803D> + <80C6> + <86CB> + <8A95> + <935B> + <56E3> + <58C7> + <5F3E> + <65AD> + <6696> +endbfchar + +100 beginbfchar + <6A80> + <6BB5> + <7537> + <8AC7> + <5024> + <77E5> + <5730> + <5F1B> + <6065> + <667A> + <6C60> + <75F4> + <7A1A> + <7F6E> + <81F4> + <8718> + <9045> + <99B3> + <7BC9> + <755C> + <7AF9> + <7B51> + <84C4> + <9010> + <79E9> + <7A92> + <8336> + <5AE1> + <7740> + <4E2D> + <4EF2> + <5B99> + <5FE0> + <62BD> + <663C> + <67F1> + <6CE8> + <866B> + <8877> + <8A3B> + <914E> + <92F3> + <99D0> + <6A17> + <7026> + <732A> + <82E7> + <8457> + <8CAF> + <4E01> + <5146> + <51CB> + <558B> + <5BF5> + <5E16> + <5E33> + <5E81> + <5F14> + <5F35> + <5F6B> + <5FB4> + <61F2> + <6311> + <66A2> + <671D> + <6F6E> + <7252> + <753A> + <773A> + <8074> + <8139> + <8178> + <8776> + <8ABF> + <8ADC> + <8D85> + <8DF3> + <929A> + <9577> + <9802> + <9CE5> + <52C5> + <6357> + <76F4> + <6715> + <6C88> + <73CD> + <8CC3> + <93AE> + <9673> + <6D25> + <589C> + <690E> + <69CC> + <8FFD> + <939A> + <75DB> + <901A> + <585A> + <6802> +endbfchar + +100 beginbfchar + <63B4> + <69FB> + <4F43> + <6F2C> + <67D8> + <8FBB> + <8526> + <7DB4> + <9354> + <693F> + <6F70> + <576A> + <58F7> + <5B2C> + <7D2C> + <722A> + <540A> + <91E3> + <9DB4> + <4EAD> + <4F4E> + <505C> + <5075> + <5243> + <8C9E> + <5448> + <5824> + <5B9A> + <5E1D> + <5E95> + <5EAD> + <5EF7> + <5F1F> + <608C> + <62B5> + <633A> + <63D0> + <68AF> + <6C40> + <7887> + <798E> + <7A0B> + <7DE0> + <8247> + <8A02> + <8AE6> + <8E44> + <9013> + <90B8> + <912D> + <91D8> + <9F0E> + <6CE5> + <6458> + <64E2> + <6575> + <6EF4> + <7684> + <7B1B> + <9069> + <93D1> + <6EBA> + <54F2> + <5FB9> + <64A4> + <8F4D> + <8FED> + <9244> + <5178> + <586B> + <5929> + <5C55> + <5E97> + <6DFB> + <7E8F> + <751C> + <8CBC> + <8EE2> + <985B> + <70B9> + <4F1D> + <6BBF> + <6FB1> + <7530> + <96FB> + <514E> + <5410> + <5835> + <5857> + <59AC> + <5C60> + <5F92> + <6597> + <675C> + <6E21> + <767B> + <83DF> + <8CED> + <9014> + <90FD> +endbfchar + +100 beginbfchar + <934D> + <7825> + <783A> + <52AA> + <5EA6> + <571F> + <5974> + <6012> + <5012> + <515A> + <51AC> + <51CD> + <5200> + <5510> + <5854> + <5858> + <5957> + <5B95> + <5CF6> + <5D8B> + <60BC> + <6295> + <642D> + <6771> + <6843> + <68BC> + <68DF> + <76D7> + <6DD8> + <6E6F> + <6D9B> + <706F> + <71C8> + <5F53> + <75D8> + <7977> + <7B49> + <7B54> + <7B52> + <7CD6> + <7D71> + <5230> + <8463> + <8569> + <85E4> + <8A0E> + <8B04> + <8C46> + <8E0F> + <9003> + <900F> + <9419> + <9676> + <982D> + <9A30> + <95D8> + <50CD> + <52D5> + <540C> + <5802> + <5C0E> + <61A7> + <649E> + <6D1E> + <77B3> + <7AE5> + <80F4> + <8404> + <9053> + <9285> + <5CE0> + <9D07> + <533F> + <5F97> + <5FB3> + <6D9C> + <7279> + <7763> + <79BF> + <7BE4> + <6BD2> + <72EC> + <8AAD> + <6803> + <6A61> + <51F8> + <7A81> + <6934> + <5C4A> + <9CF6> + <82EB> + <5BC5> + <9149> + <701E> + <5678> + <5C6F> + <60C7> + <6566> + <6C8C> + <8C5A> +endbfchar + +100 beginbfchar + <9041> + <9813> + <5451> + <66C7> + <920D> + <5948> + <90A3> + <5185> + <4E4D> + <51EA> + <8599> + <8B0E> + <7058> + <637A> + <934B> + <6962> + <99B4> + <7E04> + <7577> + <5357> + <6960> + <8EDF> + <96E3> + <6C5D> + <4E8C> + <5C3C> + <5F10> + <8FE9> + <5302> + <8CD1> + <8089> + <8679> + <5EFF> + <65E5> + <4E73> + <5165> + <5982> + <5C3F> + <97EE> + <4EFB> + <598A> + <5FCD> + <8A8D> + <6FE1> + <79B0> + <7962> + <5BE7> + <8471> + <732B> + <71B1> + <5E74> + <5FF5> + <637B> + <649A> + <71C3> + <7C98> + <4E43> + <5EFC> + <4E4B> + <57DC> + <56A2> + <60A9> + <6FC3> + <7D0D> + <80FD> + <8133> + <81BF> + <8FB2> + <8997> + <86A4> + <5DF4> + <628A> + <64AD> + <8987> + <6777> + <6CE2> + <6D3E> + <7436> + <7834> + <5A46> + <7F75> + <82AD> + <99AC> + <4FF3> + <5EC3> + <62DD> + <6392> + <6557> + <676F> + <76C3> + <724C> + <80CC> + <80BA> + <8F29> + <914D> + <500D> + <57F9> + <5A92> + <6885> + <6973> +endbfchar + +100 beginbfchar + <7164> + <72FD> + <8CB7> + <58F2> + <8CE0> + <966A> + <9019> + <877F> + <79E4> + <77E7> + <8429> + <4F2F> + <5265> + <535A> + <62CD> + <67CF> + <6CCA> + <767D> + <7B94> + <7C95> + <8236> + <8584> + <8FEB> + <66DD> + <6F20> + <7206> + <7E1B> + <83AB> + <99C1> + <9EA6> + <51FD> + <7BB1> + <7872> + <7BB8> + <8087> + <7B48> + <6AE8> + <5E61> + <808C> + <7551> + <7560> + <516B> + <9262> + <6E8C> + <767A> + <9197> + <9AEA> + <4F10> + <7F70> + <629C> + <7B4F> + <95A5> + <9CE9> + <567A> + <5859> + <86E4> + <96BC> + <4F34> + <5224> + <534A> + <53CD> + <53DB> + <5E06> + <642C> + <6591> + <677F> + <6C3E> + <6C4E> + <7248> + <72AF> + <73ED> + <7554> + <7E41> + <822C> + <85E9> + <8CA9> + <7BC4> + <91C6> + <7169> + <9812> + <98EF> + <633D> + <6669> + <756A> + <76E4> + <78D0> + <8543> + <86EE> + <532A> + <5351> + <5426> + <5983> + <5E87> + <5F7C> + <60B2> + <6249> + <6279> + <62AB> + <6590> + <6BD4> +endbfchar + +100 beginbfchar + <6CCC> + <75B2> + <76AE> + <7891> + <79D8> + <7DCB> + <7F77> + <80A5> + <88AB> + <8AB9> + <8CBB> + <907F> + <975E> + <98DB> + <6A0B> + <7C38> + <5099> + <5C3E> + <5FAE> + <6787> + <6BD8> + <7435> + <7709> + <7F8E> + <9F3B> + <67CA> + <7A17> + <5339> + <758B> + <9AED> + <5F66> + <819D> + <83F1> + <8098> + <5F3C> + <5FC5> + <7562> + <7B46> + <903C> + <6867> + <59EB> + <5A9B> + <7D10> + <767E> + <8B2C> + <4FF5> + <5F6A> + <6A19> + <6C37> + <6F02> + <74E2> + <7968> + <8868> + <8A55> + <8C79> + <5EDF> + <63CF> + <75C5> + <79D2> + <82D7> + <9328> + <92F2> + <849C> + <86ED> + <9C2D> + <54C1> + <5F6C> + <658C> + <6D5C> + <7015> + <8CA7> + <8CD3> + <983B> + <654F> + <74F6> + <4E0D> + <4ED8> + <57E0> + <592B> + <5A66> + <5BCC> + <51A8> + <5E03> + <5E9C> + <6016> + <6276> + <6577> + <65A7> + <666E> + <6D6E> + <7236> + <7B26> + <8150> + <819A> + <8299> + <8B5C> + <8CA0> + <8CE6> + <8D74> + <961C> +endbfchar + +100 beginbfchar + <9644> + <4FAE> + <64AB> + <6B66> + <821E> + <8461> + <856A> + <90E8> + <5C01> + <6953> + <98A8> + <847A> + <8557> + <4F0F> + <526F> + <5FA9> + <5E45> + <670D> + <798F> + <8179> + <8907> + <8986> + <6DF5> + <5F17> + <6255> + <6CB8> + <4ECF> + <7269> + <9B92> + <5206> + <543B> + <5674> + <58B3> + <61A4> + <626E> + <711A> + <596E> + <7C89> + <7CDE> + <7D1B> + <96F0> + <6587> + <805E> + <4E19> + <4F75> + <5175> + <5840> + <5E63> + <5E73> + <5F0A> + <67C4> + <4E26> + <853D> + <9589> + <965B> + <7C73> + <9801> + <50FB> + <58C1> + <7656> + <78A7> + <5225> + <77A5> + <8511> + <7B86> + <504F> + <5909> + <7247> + <7BC7> + <7DE8> + <8FBA> + <8FD4> + <904D> + <4FBF> + <52C9> + <5A29> + <5F01> + <97AD> + <4FDD> + <8217> + <92EA> + <5703> + <6355> + <6B69> + <752B> + <88DC> + <8F14> + <7A42> + <52DF> + <5893> + <6155> + <620A> + <66AE> + <6BCD> + <7C3F> + <83E9> + <5023> + <4FF8> + <5305> + <5446> +endbfchar + +100 beginbfchar + <5831> + <5949> + <5B9D> + <5CF0> + <5CEF> + <5D29> + <5E96> + <62B1> + <6367> + <653E> + <65B9> + <670B> + <6CD5> + <6CE1> + <70F9> + <7832> + <7E2B> + <80DE> + <82B3> + <840C> + <84EC> + <8702> + <8912> + <8A2A> + <8C4A> + <90A6> + <92D2> + <98FD> + <9CF3> + <9D6C> + <4E4F> + <4EA1> + <508D> + <5256> + <574A> + <59A8> + <5E3D> + <5FD8> + <5FD9> + <623F> + <66B4> + <671B> + <67D0> + <68D2> + <5192> + <7D21> + <80AA> + <81A8> + <8B00> + <8C8C> + <8CBF> + <927E> + <9632> + <5420> + <982C> + <5317> + <50D5> + <535C> + <58A8> + <64B2> + <6734> + <7267> + <7766> + <7A46> + <91E6> + <52C3> + <6CA1> + <6B86> + <5800> + <5E4C> + <5954> + <672C> + <7FFB> + <51E1> + <76C6> + <6469> + <78E8> + <9B54> + <9EBB> + <57CB> + <59B9> + <6627> + <679A> + <6BCE> + <54E9> + <69D9> + <5E55> + <819C> + <6795> + <9BAA> + <67FE> + <9C52> + <685D> + <4EA6> + <4FE3> + <53C8> + <62B9> + <672B> + <6CAB> + <8FC4> +endbfchar + +100 beginbfchar + <4FAD> + <7E6D> + <9EBF> + <4E07> + <6162> + <6E80> + <6F2B> + <8513> + <5473> + <672A> + <9B45> + <5DF3> + <7B95> + <5CAC> + <5BC6> + <871C> + <6E4A> + <84D1> + <7A14> + <8108> + <5999> + <7C8D> + <6C11> + <7720> + <52D9> + <5922> + <7121> + <725F> + <77DB> + <9727> + <9D61> + <690B> + <5A7F> + <5A18> + <51A5> + <540D> + <547D> + <660E> + <76DF> + <8FF7> + <9298> + <9CF4> + <59EA> + <725D> + <6EC5> + <514D> + <68C9> + <7DBF> + <7DEC> + <9762> + <9EBA> + <6478> + <6A21> + <8302> + <5984> + <5B5F> + <6BDB> + <731B> + <76F2> + <7DB2> + <8017> + <8499> + <5132> + <6728> + <9ED9> + <76EE> + <6762> + <52FF> + <9905> + <5C24> + <623B> + <7C7E> + <8CB0> + <554F> + <60B6> + <7D0B> + <9580> + <5301> + <4E5F> + <51B6> + <591C> + <723A> + <8036> + <91CE> + <5F25> + <77E2> + <5384> + <5F79> + <7D04> + <85AC> + <8A33> + <8E8D> + <9756> + <67F3> + <85AE> + <9453> + <6109> + <6108> + <6CB9> + <7652> +endbfchar + +100 beginbfchar + <8AED> + <8F38> + <552F> + <4F51> + <512A> + <52C7> + <53CB> + <5BA5> + <5E7D> + <60A0> + <6182> + <63D6> + <6709> + <67DA> + <6E67> + <6D8C> + <7336> + <7337> + <7531> + <7950> + <88D5> + <8A98> + <904A> + <9091> + <90F5> + <96C4> + <878D> + <5915> + <4E88> + <4F59> + <4E0E> + <8A89> + <8F3F> + <9810> + <50AD> + <5E7C> + <5996> + <5BB9> + <5EB8> + <63DA> + <63FA> + <64C1> + <66DC> + <694A> + <69D8> + <6D0B> + <6EB6> + <7194> + <7528> + <7AAF> + <7F8A> + <8000> + <8449> + <84C9> + <8981> + <8B21> + <8E0A> + <9065> + <967D> + <990A> + <617E> + <6291> + <6B32> + <6C83> + <6D74> + <7FCC> + <7FFC> + <6DC0> + <7F85> + <87BA> + <88F8> + <6765> + <83B1> + <983C> + <96F7> + <6D1B> + <7D61> + <843D> + <916A> + <4E71> + <5375> + <5D50> + <6B04> + <6FEB> + <85CD> + <862D> + <89A7> + <5229> + <540F> + <5C65> + <674E> + <68A8> + <7406> + <7483> + <75E2> + <88CF> + <88E1> + <91CC> + <96E2> + <9678> +endbfchar + +100 beginbfchar + <5F8B> + <7387> + <7ACB> + <844E> + <63A0> + <7565> + <5289> + <6D41> + <6E9C> + <7409> + <7559> + <786B> + <7C92> + <9686> + <7ADC> + <9F8D> + <4FB6> + <616E> + <65C5> + <865C> + <4E86> + <4EAE> + <50DA> + <4E21> + <51CC> + <5BEE> + <6599> + <6881> + <6DBC> + <731F> + <7642> + <77AD> + <7A1C> + <7CE7> + <826F> + <8AD2> + <907C> + <91CF> + <9675> + <9818> + <529B> + <7DD1> + <502B> + <5398> + <6797> + <6DCB> + <71D0> + <7433> + <81E8> + <8F2A> + <96A3> + <9C57> + <9E9F> + <7460> + <5841> + <6D99> + <7D2F> + <985E> + <4EE4> + <4F36> + <4F8B> + <51B7> + <52B1> + <5DBA> + <601C> + <73B2> + <793C> + <82D3> + <9234> + <96B7> + <96F6> + <970A> + <9E97> + <9F62> + <66A6> + <6B74> + <5217> + <52A3> + <70C8> + <88C2> + <5EC9> + <604B> + <6190> + <6F23> + <7149> + <7C3E> + <7DF4> + <806F> + <84EE> + <9023> + <932C> + <5442> + <9B6F> + <6AD3> + <7089> + <8CC2> + <8DEF> + <9732> + <52B4> + <5A41> +endbfchar + +100 beginbfchar + <5ECA> + <5F04> + <6717> + <697C> + <6994> + <6D6A> + <6F0F> + <7262> + <72FC> + <7BED> + <8001> + <807E> + <874B> + <90CE> + <516D> + <9E93> + <7984> + <808B> + <9332> + <8AD6> + <502D> + <548C> + <8A71> + <6B6A> + <8CC4> + <8107> + <60D1> + <67A0> + <9DF2> + <4E99> + <4E98> + <9C10> + <8A6B> + <85C1> + <8568> + <6900> + <6E7E> + <7897> + <8155> + <5F0C> + <4E10> + <4E15> + <4E2A> + <4E31> + <4E36> + <4E3C> + <4E3F> + <4E42> + <4E56> + <4E58> + <4E82> + <4E85> + <8C6B> + <4E8A> + <8212> + <5F0D> + <4E8E> + <4E9E> + <4E9F> + <4EA0> + <4EA2> + <4EB0> + <4EB3> + <4EB6> + <4ECE> + <4ECD> + <4EC4> + <4EC6> + <4EC2> + <4ED7> + <4EDE> + <4EED> + <4EDF> + <4EF7> + <4F09> + <4F5A> + <4F30> + <4F5B> + <4F5D> + <4F57> + <4F47> + <4F76> + <4F88> + <4F8F> + <4F98> + <4F7B> + <4F69> + <4F70> + <4F91> + <4F6F> + <4F86> + <4F96> + <5118> + <4FD4> + <4FDF> + <4FCE> + <4FD8> + <4FDB> + <4FD1> + <4FDA> +endbfchar + +100 beginbfchar + <4FD0> + <4FE4> + <4FE5> + <501A> + <5028> + <5014> + <502A> + <5025> + <5005> + <4F1C> + <4FF6> + <5021> + <5029> + <502C> + <4FFE> + <4FEF> + <5011> + <5006> + <5043> + <5047> + <6703> + <5055> + <5050> + <5048> + <505A> + <5056> + <506C> + <5078> + <5080> + <509A> + <5085> + <50B4> + <50B2> + <50C9> + <50CA> + <50B3> + <50C2> + <50D6> + <50DE> + <50E5> + <50ED> + <50E3> + <50EE> + <50F9> + <50F5> + <5109> + <5101> + <5102> + <5116> + <5115> + <5114> + <511A> + <5121> + <513A> + <5137> + <513C> + <513B> + <513F> + <5140> + <5152> + <514C> + <5154> + <5162> + <7AF8> + <5169> + <516A> + <516E> + <5180> + <5182> + <56D8> + <518C> + <5189> + <518F> + <5191> + <5193> + <5195> + <5196> + <51A4> + <51A6> + <51A2> + <51A9> + <51AA> + <51AB> + <51B3> + <51B1> + <51B2> + <51B0> + <51B5> + <51BD> + <51C5> + <51C9> + <51DB> + <51E0> + <8655> + <51E9> + <51ED> + <51F0> + <51F5> + <51FE> + <5204> +endbfchar + +100 beginbfchar + <520B> + <5214> + <520E> + <5227> + <522A> + <522E> + <5233> + <5239> + <524F> + <5244> + <524B> + <524C> + <525E> + <5254> + <526A> + <5274> + <5269> + <5273> + <527F> + <527D> + <528D> + <5294> + <5292> + <5271> + <5288> + <5291> + <8FA8> + <8FA7> + <52AC> + <52AD> + <52BC> + <52B5> + <52C1> + <52CD> + <52D7> + <52DE> + <52E3> + <52E6> + <98ED> + <52E0> + <52F3> + <52F5> + <52F8> + <52F9> + <5306> + <5308> + <7538> + <530D> + <5310> + <530F> + <5315> + <531A> + <5323> + <532F> + <5331> + <5333> + <5338> + <5340> + <5346> + <5345> + <4E17> + <5349> + <534D> + <51D6> + <535E> + <5369> + <536E> + <5918> + <537B> + <5377> + <5382> + <5396> + <53A0> + <53A6> + <53A5> + <53AE> + <53B0> + <53B6> + <53C3> + <7C12> + <96D9> + <53DF> + <66FC> + <71EE> + <53EE> + <53E8> + <53ED> + <53FA> + <5401> + <543D> + <5440> + <542C> + <542D> + <543C> + <542E> + <5436> + <5429> + <541D> + <544E> + <548F> +endbfchar + +100 beginbfchar + <5475> + <548E> + <545F> + <5471> + <5477> + <5470> + <5492> + <547B> + <5480> + <5476> + <5484> + <5490> + <5486> + <54C7> + <54A2> + <54B8> + <54A5> + <54AC> + <54C4> + <54C8> + <54A8> + <54AB> + <54C2> + <54A4> + <54BE> + <54BC> + <54D8> + <54E5> + <54E6> + <550F> + <5514> + <54FD> + <54EE> + <54ED> + <54FA> + <54E2> + <5539> + <5540> + <5563> + <554C> + <552E> + <555C> + <5545> + <5556> + <5557> + <5538> + <5533> + <555D> + <5599> + <5580> + <54AF> + <558A> + <559F> + <557B> + <557E> + <5598> + <559E> + <55AE> + <557C> + <5583> + <55A9> + <5587> + <55A8> + <55DA> + <55C5> + <55DF> + <55C4> + <55DC> + <55E4> + <55D4> + <5614> + <55F7> + <5616> + <55FE> + <55FD> + <561B> + <55F9> + <564E> + <5650> + <71DF> + <5634> + <5636> + <5632> + <5638> + <566B> + <5664> + <562F> + <566C> + <566A> + <5686> + <5680> + <568A> + <56A0> + <5694> + <568F> + <56A5> + <56AE> + <56B6> + <56B4> + <56C2> +endbfchar + +100 beginbfchar + <56BC> + <56C1> + <56C3> + <56C0> + <56C8> + <56CE> + <56D1> + <56D3> + <56D7> + <56EE> + <56F9> + <5700> + <56FF> + <5704> + <5709> + <5708> + <570B> + <570D> + <5713> + <5718> + <5716> + <55C7> + <571C> + <5726> + <5737> + <5738> + <574E> + <573B> + <5740> + <574F> + <5769> + <57C0> + <5788> + <5761> + <577F> + <5789> + <5793> + <57A0> + <57B3> + <57A4> + <57AA> + <57B0> + <57C3> + <57C6> + <57D4> + <57D2> + <57D3> + <580A> + <57D6> + <57E3> + <580B> + <5819> + <581D> + <5872> + <5821> + <5862> + <584B> + <5870> + <6BC0> + <5852> + <583D> + <5879> + <5885> + <58B9> + <589F> + <58AB> + <58BA> + <58DE> + <58BB> + <58B8> + <58AE> + <58C5> + <58D3> + <58D1> + <58D7> + <58D9> + <58D8> + <58E5> + <58DC> + <58E4> + <58DF> + <58EF> + <58FA> + <58F9> + <58FB> + <58FC> + <58FD> + <5902> + <590A> + <5910> + <591B> + <68A6> + <5925> + <592C> + <592D> + <5932> + <5938> + <593E> + <7AD2> + <5955> +endbfchar + +100 beginbfchar + <5950> + <594E> + <595A> + <5958> + <5962> + <5960> + <5967> + <596C> + <5969> + <5978> + <5981> + <599D> + <4F5E> + <4FAB> + <59A3> + <59B2> + <59C6> + <59E8> + <59DC> + <598D> + <59D9> + <59DA> + <5A25> + <5A1F> + <5A11> + <5A1C> + <5A09> + <5A1A> + <5A40> + <5A6C> + <5A49> + <5A35> + <5A36> + <5A62> + <5A6A> + <5A9A> + <5ABC> + <5ABE> + <5ACB> + <5AC2> + <5ABD> + <5AE3> + <5AD7> + <5AE6> + <5AE9> + <5AD6> + <5AFA> + <5AFB> + <5B0C> + <5B0B> + <5B16> + <5B32> + <5AD0> + <5B2A> + <5B36> + <5B3E> + <5B43> + <5B45> + <5B40> + <5B51> + <5B55> + <5B5A> + <5B5B> + <5B65> + <5B69> + <5B70> + <5B73> + <5B75> + <5B78> + <6588> + <5B7A> + <5B80> + <5B83> + <5BA6> + <5BB8> + <5BC3> + <5BC7> + <5BC9> + <5BD4> + <5BD0> + <5BE4> + <5BE6> + <5BE2> + <5BDE> + <5BE5> + <5BEB> + <5BF0> + <5BF6> + <5BF3> + <5C05> + <5C07> + <5C08> + <5C0D> + <5C13> + <5C20> + <5C22> + <5C28> + <5C38> + <5C39> + <5C41> +endbfchar + +100 beginbfchar + <5C46> + <5C4E> + <5C53> + <5C50> + <5C4F> + <5B71> + <5C6C> + <5C6E> + <4E62> + <5C76> + <5C79> + <5C8C> + <5C91> + <5C94> + <599B> + <5CAB> + <5CBB> + <5CB6> + <5CBC> + <5CB7> + <5CC5> + <5CBE> + <5CC7> + <5CD9> + <5CE9> + <5CFD> + <5CFA> + <5CED> + <5D8C> + <5CEA> + <5D0B> + <5D15> + <5D17> + <5D5C> + <5D1F> + <5D1B> + <5D11> + <5D14> + <5D22> + <5D1A> + <5D19> + <5D18> + <5D4C> + <5D52> + <5D4E> + <5D4B> + <5D6C> + <5D73> + <5D76> + <5D87> + <5D84> + <5D82> + <5DA2> + <5D9D> + <5DAC> + <5DAE> + <5DBD> + <5D90> + <5DB7> + <5DBC> + <5DC9> + <5DCD> + <5DD3> + <5DD2> + <5DD6> + <5DDB> + <5DEB> + <5DF2> + <5DF5> + <5E0B> + <5E1A> + <5E19> + <5E11> + <5E1B> + <5E36> + <5E37> + <5E44> + <5E43> + <5E40> + <5E4E> + <5E57> + <5E54> + <5E5F> + <5E62> + <5E64> + <5E47> + <5E75> + <5E76> + <5E7A> + <9EBC> + <5E7F> + <5EA0> + <5EC1> + <5EC2> + <5EC8> + <5ED0> + <5ECF> + <5ED6> + <5EE3> + <5EDD> +endbfchar + +100 beginbfchar + <5EDA> + <5EDB> + <5EE2> + <5EE1> + <5EE8> + <5EE9> + <5EEC> + <5EF1> + <5EF3> + <5EF0> + <5EF4> + <5EF8> + <5EFE> + <5F03> + <5F09> + <5F5D> + <5F5C> + <5F0B> + <5F11> + <5F16> + <5F29> + <5F2D> + <5F38> + <5F41> + <5F48> + <5F4C> + <5F4E> + <5F2F> + <5F51> + <5F56> + <5F57> + <5F59> + <5F61> + <5F6D> + <5F73> + <5F77> + <5F83> + <5F82> + <5F7F> + <5F8A> + <5F88> + <5F91> + <5F87> + <5F9E> + <5F99> + <5F98> + <5FA0> + <5FA8> + <5FAD> + <5FBC> + <5FD6> + <5FFB> + <5FE4> + <5FF8> + <5FF1> + <5FDD> + <60B3> + <5FFF> + <6021> + <6060> + <6019> + <6010> + <6029> + <600E> + <6031> + <601B> + <6015> + <602B> + <6026> + <600F> + <603A> + <605A> + <6041> + <606A> + <6077> + <605F> + <604A> + <6046> + <604D> + <6063> + <6043> + <6064> + <6042> + <606C> + <606B> + <6059> + <6081> + <608D> + <60E7> + <6083> + <609A> + <6084> + <609B> + <6096> + <6097> + <6092> + <60A7> + <608B> + <60E1> + <60B8> +endbfchar + +100 beginbfchar + <60E0> + <60D3> + <60B4> + <5FF0> + <60BD> + <60C6> + <60B5> + <60D8> + <614D> + <6115> + <6106> + <60F6> + <60F7> + <6100> + <60F4> + <60FA> + <6103> + <6121> + <60FB> + <60F1> + <610D> + <610E> + <6147> + <613E> + <6128> + <6127> + <614A> + <613F> + <613C> + <612C> + <6134> + <613D> + <6142> + <6144> + <6173> + <6177> + <6158> + <6159> + <615A> + <616B> + <6174> + <616F> + <6165> + <6171> + <615F> + <615D> + <6153> + <6175> + <6199> + <6196> + <6187> + <61AC> + <6194> + <619A> + <618A> + <6191> + <61AB> + <61AE> + <61CC> + <61CA> + <61C9> + <61F7> + <61C8> + <61C3> + <61C6> + <61BA> + <61CB> + <7F79> + <61CD> + <61E6> + <61E3> + <61F6> + <61FA> + <61F4> + <61FF> + <61FD> + <61FC> + <61FE> + <6200> + <6208> + <6209> + <620D> + <620C> + <6214> + <621B> + <621E> + <6221> + <622A> + <622E> + <6230> + <6232> + <6233> + <6241> + <624E> + <625E> + <6263> + <625B> + <6260> + <6268> + <627C> +endbfchar + +100 beginbfchar + <6282> + <6289> + <627E> + <6292> + <6293> + <6296> + <62D4> + <6283> + <6294> + <62D7> + <62D1> + <62BB> + <62CF> + <62FF> + <62C6> + <64D4> + <62C8> + <62DC> + <62CC> + <62CA> + <62C2> + <62C7> + <629B> + <62C9> + <630C> + <62EE> + <62F1> + <6327> + <6302> + <6308> + <62EF> + <62F5> + <6350> + <633E> + <634D> + <641C> + <634F> + <6396> + <638E> + <6380> + <63AB> + <6376> + <63A3> + <638F> + <6389> + <639F> + <63B5> + <636B> + <6369> + <63BE> + <63E9> + <63C0> + <63C6> + <63E3> + <63C9> + <63D2> + <63F6> + <63C4> + <6416> + <6434> + <6406> + <6413> + <6426> + <6436> + <651D> + <6417> + <6428> + <640F> + <6467> + <646F> + <6476> + <644E> + <652A> + <6495> + <6493> + <64A5> + <64A9> + <6488> + <64BC> + <64DA> + <64D2> + <64C5> + <64C7> + <64BB> + <64D8> + <64C2> + <64F1> + <64E7> + <8209> + <64E0> + <64E1> + <62AC> + <64E3> + <64EF> + <652C> + <64F6> + <64F4> + <64F2> + <64FA> + <6500> +endbfchar + +100 beginbfchar + <64FD> + <6518> + <651C> + <6505> + <6524> + <6523> + <652B> + <6534> + <6535> + <6537> + <6536> + <6538> + <754B> + <6548> + <6556> + <6555> + <654D> + <6558> + <655E> + <655D> + <6572> + <6578> + <6582> + <6583> + <8B8A> + <659B> + <659F> + <65AB> + <65B7> + <65C3> + <65C6> + <65C1> + <65C4> + <65CC> + <65D2> + <65DB> + <65D9> + <65E0> + <65E1> + <65F1> + <6772> + <660A> + <6603> + <65FB> + <6773> + <6635> + <6636> + <6634> + <661C> + <664F> + <6644> + <6649> + <6641> + <665E> + <665D> + <6664> + <6667> + <6668> + <665F> + <6662> + <6670> + <6683> + <6688> + <668E> + <6689> + <6684> + <6698> + <669D> + <66C1> + <66B9> + <66C9> + <66BE> + <66BC> + <66C4> + <66B8> + <66D6> + <66DA> + <66E0> + <663F> + <66E6> + <66E9> + <66F0> + <66F5> + <66F7> + <670F> + <6716> + <671E> + <6726> + <6727> + <9738> + <672E> + <673F> + <6736> + <6741> + <6738> + <6737> + <6746> + <675E> + <6760> + <6759> +endbfchar + +100 beginbfchar + <6763> + <6764> + <6789> + <6770> + <67A9> + <677C> + <676A> + <678C> + <678B> + <67A6> + <67A1> + <6785> + <67B7> + <67EF> + <67B4> + <67EC> + <67B3> + <67E9> + <67B8> + <67E4> + <67DE> + <67DD> + <67E2> + <67EE> + <67B9> + <67CE> + <67C6> + <67E7> + <6A9C> + <681E> + <6846> + <6829> + <6840> + <684D> + <6832> + <684E> + <68B3> + <682B> + <6859> + <6863> + <6877> + <687F> + <689F> + <688F> + <68AD> + <6894> + <689D> + <689B> + <6883> + <6AAE> + <68B9> + <6874> + <68B5> + <68A0> + <68BA> + <690F> + <688D> + <687E> + <6901> + <68CA> + <6908> + <68D8> + <6922> + <6926> + <68E1> + <690C> + <68CD> + <68D4> + <68E7> + <68D5> + <6936> + <6912> + <6904> + <68D7> + <68E3> + <6925> + <68F9> + <68E0> + <68EF> + <6928> + <692A> + <691A> + <6923> + <6921> + <68C6> + <6979> + <6977> + <695C> + <6978> + <696B> + <6954> + <697E> + <696E> + <6939> + <6974> + <693D> + <6959> + <6930> + <6961> + <695E> +endbfchar + +100 beginbfchar + <695D> + <6981> + <696A> + <69B2> + <69AE> + <69D0> + <69BF> + <69C1> + <69D3> + <69BE> + <69CE> + <5BE8> + <69CA> + <69DD> + <69BB> + <69C3> + <69A7> + <6A2E> + <6991> + <69A0> + <699C> + <6995> + <69B4> + <69DE> + <69E8> + <6A02> + <6A1B> + <69FF> + <6B0A> + <69F9> + <69F2> + <69E7> + <6A05> + <69B1> + <6A1E> + <69ED> + <6A14> + <69EB> + <6A0A> + <6A12> + <6AC1> + <6A23> + <6A13> + <6A44> + <6A0C> + <6A72> + <6A36> + <6A78> + <6A47> + <6A62> + <6A59> + <6A66> + <6A48> + <6A38> + <6A22> + <6A90> + <6A8D> + <6AA0> + <6A84> + <6AA2> + <6AA3> + <6A97> + <8617> + <6ABB> + <6AC3> + <6AC2> + <6AB8> + <6AB3> + <6AAC> + <6ADE> + <6AD1> + <6ADF> + <6AAA> + <6ADA> + <6AEA> + <6AFB> + <6B05> + <8616> + <6AFA> + <6B12> + <6B16> + <9B31> + <6B1F> + <6B38> + <6B37> + <76DC> + <6B39> + <98EE> + <6B47> + <6B43> + <6B49> + <6B50> + <6B59> + <6B54> + <6B5B> + <6B5F> + <6B61> + <6B78> + <6B79> + <6B7F> +endbfchar + +100 beginbfchar + <6B80> + <6B84> + <6B83> + <6B8D> + <6B98> + <6B95> + <6B9E> + <6BA4> + <6BAA> + <6BAB> + <6BAF> + <6BB2> + <6BB1> + <6BB3> + <6BB7> + <6BBC> + <6BC6> + <6BCB> + <6BD3> + <6BDF> + <6BEC> + <6BEB> + <6BF3> + <6BEF> + <9EBE> + <6C08> + <6C13> + <6C14> + <6C1B> + <6C24> + <6C23> + <6C5E> + <6C55> + <6C62> + <6C6A> + <6C82> + <6C8D> + <6C9A> + <6C81> + <6C9B> + <6C7E> + <6C68> + <6C73> + <6C92> + <6C90> + <6CC4> + <6CF1> + <6CD3> + <6CBD> + <6CD7> + <6CC5> + <6CDD> + <6CAE> + <6CB1> + <6CBE> + <6CBA> + <6CDB> + <6CEF> + <6CD9> + <6CEA> + <6D1F> + <884D> + <6D36> + <6D2B> + <6D3D> + <6D38> + <6D19> + <6D35> + <6D33> + <6D12> + <6D0C> + <6D63> + <6D93> + <6D64> + <6D5A> + <6D79> + <6D59> + <6D8E> + <6D95> + <6FE4> + <6D85> + <6DF9> + <6E15> + <6E0A> + <6DB5> + <6DC7> + <6DE6> + <6DB8> + <6DC6> + <6DEC> + <6DDE> + <6DCC> + <6DE8> + <6DD2> + <6DC5> + <6DFA> + <6DD9> + <6DE4> + <6DD5> + <6DEA> +endbfchar + +100 beginbfchar + <6DEE> + <6E2D> + <6E6E> + <6E2E> + <6E19> + <6E72> + <6E5F> + <6E3E> + <6E23> + <6E6B> + <6E2B> + <6E76> + <6E4D> + <6E1F> + <6E43> + <6E3A> + <6E4E> + <6E24> + <6EFF> + <6E1D> + <6E38> + <6E82> + <6EAA> + <6E98> + <6EC9> + <6EB7> + <6ED3> + <6EBD> + <6EAF> + <6EC4> + <6EB2> + <6ED4> + <6ED5> + <6E8F> + <6EA5> + <6EC2> + <6E9F> + <6F41> + <6F11> + <704C> + <6EEC> + <6EF8> + <6EFE> + <6F3F> + <6EF2> + <6F31> + <6EEF> + <6F32> + <6ECC> + <6F3E> + <6F13> + <6EF7> + <6F86> + <6F7A> + <6F78> + <6F81> + <6F80> + <6F6F> + <6F5B> + <6FF3> + <6F6D> + <6F82> + <6F7C> + <6F58> + <6F8E> + <6F91> + <6FC2> + <6F66> + <6FB3> + <6FA3> + <6FA1> + <6FA4> + <6FB9> + <6FC6> + <6FAA> + <6FDF> + <6FD5> + <6FEC> + <6FD4> + <6FD8> + <6FF1> + <6FEE> + <6FDB> + <7009> + <700B> + <6FFA> + <7011> + <7001> + <700F> + <6FFE> + <701B> + <701A> + <6F74> + <701D> + <7018> + <701F> + <7030> + <703E> + <7032> + <7051> +endbfchar + +100 beginbfchar + <7063> + <7099> + <7092> + <70AF> + <70F1> + <70AC> + <70B8> + <70B3> + <70AE> + <70DF> + <70CB> + <70DD> + <70D9> + <7109> + <70FD> + <711C> + <7119> + <7165> + <7155> + <7188> + <7166> + <7162> + <714C> + <7156> + <716C> + <718F> + <71FB> + <7184> + <7195> + <71A8> + <71AC> + <71D7> + <71B9> + <71BE> + <71D2> + <71C9> + <71D4> + <71CE> + <71E0> + <71EC> + <71E7> + <71F5> + <71FC> + <71F9> + <71FF> + <720D> + <7210> + <721B> + <7228> + <722D> + <722C> + <7230> + <7232> + <723B> + <723C> + <723F> + <7240> + <7246> + <724B> + <7258> + <7274> + <727E> + <7282> + <7281> + <7287> + <7292> + <7296> + <72A2> + <72A7> + <72B9> + <72B2> + <72C3> + <72C6> + <72C4> + <72CE> + <72D2> + <72E2> + <72E0> + <72E1> + <72F9> + <72F7> + <500F> + <7317> + <730A> + <731C> + <7316> + <731D> + <7334> + <732F> + <7329> + <7325> + <733E> + <734E> + <734F> + <9ED8> + <7357> + <736A> + <7368> + <7370> + <7378> +endbfchar + +100 beginbfchar + <7375> + <737B> + <737A> + <73C8> + <73B3> + <73CE> + <73BB> + <73C0> + <73E5> + <73EE> + <73DE> + <74A2> + <7405> + <746F> + <7425> + <73F8> + <7432> + <743A> + <7455> + <743F> + <745F> + <7459> + <7441> + <745C> + <7469> + <7470> + <7463> + <746A> + <7476> + <747E> + <748B> + <749E> + <74A7> + <74CA> + <74CF> + <74D4> + <73F1> + <74E0> + <74E3> + <74E7> + <74E9> + <74EE> + <74F2> + <74F0> + <74F1> + <74F8> + <74F7> + <7504> + <7503> + <7505> + <750C> + <750E> + <750D> + <7515> + <7513> + <751E> + <7526> + <752C> + <753C> + <7544> + <754D> + <754A> + <7549> + <755B> + <7546> + <755A> + <7569> + <7564> + <7567> + <756B> + <756D> + <7578> + <7576> + <7586> + <7587> + <7574> + <758A> + <7589> + <7582> + <7594> + <759A> + <759D> + <75A5> + <75A3> + <75C2> + <75B3> + <75C3> + <75B5> + <75BD> + <75B8> + <75BC> + <75B1> + <75CD> + <75CA> + <75D2> + <75D9> + <75E3> + <75DE> + <75FE> + <75FF> +endbfchar + +100 beginbfchar + <75FC> + <7601> + <75F0> + <75FA> + <75F2> + <75F3> + <760B> + <760D> + <7609> + <761F> + <7627> + <7620> + <7621> + <7622> + <7624> + <7634> + <7630> + <763B> + <7647> + <7648> + <7646> + <765C> + <7658> + <7661> + <7662> + <7668> + <7669> + <766A> + <7667> + <766C> + <7670> + <7672> + <7676> + <7678> + <767C> + <7680> + <7683> + <7688> + <768B> + <768E> + <7696> + <7693> + <7699> + <769A> + <76B0> + <76B4> + <76B8> + <76B9> + <76BA> + <76C2> + <76CD> + <76D6> + <76D2> + <76DE> + <76E1> + <76E5> + <76E7> + <76EA> + <862F> + <76FB> + <7708> + <7707> + <7704> + <7729> + <7724> + <771E> + <7725> + <7726> + <771B> + <7737> + <7738> + <7747> + <775A> + <7768> + <776B> + <775B> + <7765> + <777F> + <777E> + <7779> + <778E> + <778B> + <7791> + <77A0> + <779E> + <77B0> + <77B6> + <77B9> + <77BF> + <77BC> + <77BD> + <77BB> + <77C7> + <77CD> + <77D7> + <77DA> + <77DC> + <77E3> + <77EE> + <77FC> +endbfchar + +100 beginbfchar + <780C> + <7812> + <7926> + <7820> + <792A> + <7845> + <788E> + <7874> + <7886> + <787C> + <789A> + <788C> + <78A3> + <78B5> + <78AA> + <78AF> + <78D1> + <78C6> + <78CB> + <78D4> + <78BE> + <78BC> + <78C5> + <78CA> + <78EC> + <78E7> + <78DA> + <78FD> + <78F4> + <7907> + <7912> + <7911> + <7919> + <792C> + <792B> + <7940> + <7960> + <7957> + <795F> + <795A> + <7955> + <7953> + <797A> + <797F> + <798A> + <799D> + <79A7> + <9F4B> + <79AA> + <79AE> + <79B3> + <79B9> + <79BA> + <79C9> + <79D5> + <79E7> + <79EC> + <79E1> + <79E3> + <7A08> + <7A0D> + <7A18> + <7A19> + <7A20> + <7A1F> + <7980> + <7A31> + <7A3B> + <7A3E> + <7A37> + <7A43> + <7A57> + <7A49> + <7A61> + <7A62> + <7A69> + <9F9D> + <7A70> + <7A79> + <7A7D> + <7A88> + <7A97> + <7A95> + <7A98> + <7A96> + <7AA9> + <7AC8> + <7AB0> + <7AB6> + <7AC5> + <7AC4> + <7ABF> + <9083> + <7AC7> + <7ACA> + <7ACD> + <7ACF> + <7AD5> + <7AD3> + <7AD9> +endbfchar + +100 beginbfchar + <7ADA> + <7ADD> + <7AE1> + <7AE2> + <7AE6> + <7AED> + <7AF0> + <7B02> + <7B0F> + <7B0A> + <7B06> + <7B33> + <7B18> + <7B19> + <7B1E> + <7B35> + <7B28> + <7B36> + <7B50> + <7B7A> + <7B04> + <7B4D> + <7B0B> + <7B4C> + <7B45> + <7B75> + <7B65> + <7B74> + <7B67> + <7B70> + <7B71> + <7B6C> + <7B6E> + <7B9D> + <7B98> + <7B9F> + <7B8D> + <7B9C> + <7B9A> + <7B8B> + <7B92> + <7B8F> + <7B5D> + <7B99> + <7BCB> + <7BC1> + <7BCC> + <7BCF> + <7BB4> + <7BC6> + <7BDD> + <7BE9> + <7C11> + <7C14> + <7BE6> + <7BE5> + <7C60> + <7C00> + <7C07> + <7C13> + <7BF3> + <7BF7> + <7C17> + <7C0D> + <7BF6> + <7C23> + <7C27> + <7C2A> + <7C1F> + <7C37> + <7C2B> + <7C3D> + <7C4C> + <7C43> + <7C54> + <7C4F> + <7C40> + <7C50> + <7C58> + <7C5F> + <7C64> + <7C56> + <7C65> + <7C6C> + <7C75> + <7C83> + <7C90> + <7CA4> + <7CAD> + <7CA2> + <7CAB> + <7CA1> + <7CA8> + <7CB3> + <7CB2> + <7CB1> + <7CAE> + <7CB9> + <7CBD> + <7CC0> +endbfchar + +100 beginbfchar + <7CC5> + <7CC2> + <7CD8> + <7CD2> + <7CDC> + <7CE2> + <9B3B> + <7CEF> + <7CF2> + <7CF4> + <7CF6> + <7CFA> + <7D06> + <7D02> + <7D1C> + <7D15> + <7D0A> + <7D45> + <7D4B> + <7D2E> + <7D32> + <7D3F> + <7D35> + <7D46> + <7D73> + <7D56> + <7D4E> + <7D72> + <7D68> + <7D6E> + <7D4F> + <7D63> + <7D93> + <7D89> + <7D5B> + <7D8F> + <7D7D> + <7D9B> + <7DBA> + <7DAE> + <7DA3> + <7DB5> + <7DC7> + <7DBD> + <7DAB> + <7E3D> + <7DA2> + <7DAF> + <7DDC> + <7DB8> + <7D9F> + <7DB0> + <7DD8> + <7DDD> + <7DE4> + <7DDE> + <7DFB> + <7DF2> + <7DE1> + <7E05> + <7E0A> + <7E23> + <7E21> + <7E12> + <7E31> + <7E1F> + <7E09> + <7E0B> + <7E22> + <7E46> + <7E66> + <7E3B> + <7E35> + <7E39> + <7E43> + <7E37> + <7E32> + <7E3A> + <7E67> + <7E5D> + <7E56> + <7E5E> + <7E59> + <7E5A> + <7E79> + <7E6A> + <7E69> + <7E7C> + <7E7B> + <7E83> + <7DD5> + <7E7D> + <8FAE> + <7E7F> + <7E88> + <7E89> + <7E8C> + <7E92> + <7E90> + <7E93> +endbfchar + +100 beginbfchar + <7E94> + <7E96> + <7E8E> + <7E9B> + <7E9C> + <7F38> + <7F3A> + <7F45> + <7F4C> + <7F4D> + <7F4E> + <7F50> + <7F51> + <7F55> + <7F54> + <7F58> + <7F5F> + <7F60> + <7F68> + <7F69> + <7F67> + <7F78> + <7F82> + <7F86> + <7F83> + <7F88> + <7F87> + <7F8C> + <7F94> + <7F9E> + <7F9D> + <7F9A> + <7FA3> + <7FAF> + <7FB2> + <7FB9> + <7FAE> + <7FB6> + <7FB8> + <8B71> + <7FC5> + <7FC6> + <7FCA> + <7FD5> + <7FD4> + <7FE1> + <7FE6> + <7FE9> + <7FF3> + <7FF9> + <98DC> + <8006> + <8004> + <800B> + <8012> + <8018> + <8019> + <801C> + <8021> + <8028> + <803F> + <803B> + <804A> + <8046> + <8052> + <8058> + <805A> + <805F> + <8062> + <8068> + <8073> + <8072> + <8070> + <8076> + <8079> + <807D> + <807F> + <8084> + <8086> + <8085> + <809B> + <8093> + <809A> + <80AD> + <5190> + <80AC> + <80DB> + <80E5> + <80D9> + <80DD> + <80C4> + <80DA> + <80D6> + <8109> + <80EF> + <80F1> + <811B> + <8129> + <8123> + <812F> +endbfchar + +100 beginbfchar + <814B> + <968B> + <8146> + <813E> + <8153> + <8151> + <80FC> + <8171> + <816E> + <8165> + <8166> + <8174> + <8183> + <8188> + <818A> + <8180> + <8182> + <81A0> + <8195> + <81A4> + <81A3> + <815F> + <8193> + <81A9> + <81B0> + <81B5> + <81BE> + <81B8> + <81BD> + <81C0> + <81C2> + <81BA> + <81C9> + <81CD> + <81D1> + <81D9> + <81D8> + <81C8> + <81DA> + <81DF> + <81E0> + <81E7> + <81FA> + <81FB> + <81FE> + <8201> + <8202> + <8205> + <8207> + <820A> + <820D> + <8210> + <8216> + <8229> + <822B> + <8238> + <8233> + <8240> + <8259> + <8258> + <825D> + <825A> + <825F> + <8264> + <8262> + <8268> + <826A> + <826B> + <822E> + <8271> + <8277> + <8278> + <827E> + <828D> + <8292> + <82AB> + <829F> + <82BB> + <82AC> + <82E1> + <82E3> + <82DF> + <82D2> + <82F4> + <82F3> + <82FA> + <8393> + <8303> + <82FB> + <82F9> + <82DE> + <8306> + <82DC> + <8309> + <82D9> + <8335> + <8334> + <8316> + <8332> + <8331> +endbfchar + +100 beginbfchar + <8340> + <8339> + <8350> + <8345> + <832F> + <832B> + <8317> + <8318> + <8385> + <839A> + <83AA> + <839F> + <83A2> + <8396> + <8323> + <838E> + <8387> + <838A> + <837C> + <83B5> + <8373> + <8375> + <83A0> + <8389> + <83A8> + <83F4> + <8413> + <83EB> + <83CE> + <83FD> + <8403> + <83D8> + <840B> + <83C1> + <83F7> + <8407> + <83E0> + <83F2> + <840D> + <8422> + <8420> + <83BD> + <8438> + <8506> + <83FB> + <846D> + <842A> + <843C> + <855A> + <8484> + <8477> + <846B> + <84AD> + <846E> + <8482> + <8469> + <8446> + <842C> + <846F> + <8479> + <8435> + <84CA> + <8462> + <84B9> + <84BF> + <849F> + <84D9> + <84CD> + <84BB> + <84DA> + <84D0> + <84C1> + <84C6> + <84D6> + <84A1> + <8521> + <84FF> + <84F4> + <8517> + <8518> + <852C> + <851F> + <8515> + <8514> + <84FC> + <8540> + <8563> + <8558> + <8548> + <8541> + <8602> + <854B> + <8555> + <8580> + <85A4> + <8588> + <8591> + <858A> + <85A8> + <856D> +endbfchar + +100 beginbfchar + <8594> + <859B> + <85EA> + <8587> + <859C> + <8577> + <857E> + <8590> + <85C9> + <85BA> + <85CF> + <85B9> + <85D0> + <85D5> + <85DD> + <85E5> + <85DC> + <85F9> + <860A> + <8613> + <860B> + <85FE> + <85FA> + <8606> + <8622> + <861A> + <8630> + <863F> + <864D> + <4E55> + <8654> + <865F> + <8667> + <8671> + <8693> + <86A3> + <86A9> + <86AA> + <868B> + <868C> + <86B6> + <86AF> + <86C4> + <86C6> + <86B0> + <86C9> + <8823> + <86AB> + <86D4> + <86DE> + <86E9> + <86EC> + <86DF> + <86DB> + <86EF> + <8712> + <8706> + <8708> + <8700> + <8703> + <86FB> + <8711> + <8709> + <870D> + <86F9> + <870A> + <8734> + <873F> + <8737> + <873B> + <8725> + <8729> + <871A> + <8760> + <875F> + <8778> + <874C> + <874E> + <8774> + <8757> + <8768> + <876E> + <8759> + <8753> + <8763> + <876A> + <8805> + <87A2> + <879F> + <8782> + <87AF> + <87CB> + <87BD> + <87C0> + <87D0> + <96D6> + <87AB> + <87C4> + <87B3> + <87C7> +endbfchar + +100 beginbfchar + <87C6> + <87BB> + <87EF> + <87F2> + <87E0> + <880F> + <880D> + <87FE> + <87F6> + <87F7> + <880E> + <87D2> + <8811> + <8816> + <8815> + <8822> + <8821> + <8831> + <8836> + <8839> + <8827> + <883B> + <8844> + <8842> + <8852> + <8859> + <885E> + <8862> + <886B> + <8881> + <887E> + <889E> + <8875> + <887D> + <88B5> + <8872> + <8882> + <8897> + <8892> + <88AE> + <8899> + <88A2> + <888D> + <88A4> + <88B0> + <88BF> + <88B1> + <88C3> + <88C4> + <88D4> + <88D8> + <88D9> + <88DD> + <88F9> + <8902> + <88FC> + <88F4> + <88E8> + <88F2> + <8904> + <890C> + <890A> + <8913> + <8943> + <891E> + <8925> + <892A> + <892B> + <8941> + <8944> + <893B> + <8936> + <8938> + <894C> + <891D> + <8960> + <895E> + <8966> + <8964> + <896D> + <896A> + <896F> + <8974> + <8977> + <897E> + <8983> + <8988> + <898A> + <8993> + <8998> + <89A1> + <89A9> + <89A6> + <89AC> + <89AF> + <89B2> + <89BA> + <89BD> + <89BF> + <89C0> +endbfchar + +100 beginbfchar + <89DA> + <89DC> + <89DD> + <89E7> + <89F4> + <89F8> + <8A03> + <8A16> + <8A10> + <8A0C> + <8A1B> + <8A1D> + <8A25> + <8A36> + <8A41> + <8A5B> + <8A52> + <8A46> + <8A48> + <8A7C> + <8A6D> + <8A6C> + <8A62> + <8A85> + <8A82> + <8A84> + <8AA8> + <8AA1> + <8A91> + <8AA5> + <8AA6> + <8A9A> + <8AA3> + <8AC4> + <8ACD> + <8AC2> + <8ADA> + <8AEB> + <8AF3> + <8AE7> + <8AE4> + <8AF1> + <8B14> + <8AE0> + <8AE2> + <8AF7> + <8ADE> + <8ADB> + <8B0C> + <8B07> + <8B1A> + <8AE1> + <8B16> + <8B10> + <8B17> + <8B20> + <8B33> + <97AB> + <8B26> + <8B2B> + <8B3E> + <8B28> + <8B41> + <8B4C> + <8B4F> + <8B4E> + <8B49> + <8B56> + <8B5B> + <8B5A> + <8B6B> + <8B5F> + <8B6C> + <8B6F> + <8B74> + <8B7D> + <8B80> + <8B8C> + <8B8E> + <8B92> + <8B93> + <8B96> + <8B99> + <8B9A> + <8C3A> + <8C41> + <8C3F> + <8C48> + <8C4C> + <8C4E> + <8C50> + <8C55> + <8C62> + <8C6C> + <8C78> + <8C7A> + <8C82> + <8C89> + <8C85> + <8C8A> +endbfchar + +100 beginbfchar + <8C8D> + <8C8E> + <8C94> + <8C7C> + <8C98> + <621D> + <8CAD> + <8CAA> + <8CBD> + <8CB2> + <8CB3> + <8CAE> + <8CB6> + <8CC8> + <8CC1> + <8CE4> + <8CE3> + <8CDA> + <8CFD> + <8CFA> + <8CFB> + <8D04> + <8D05> + <8D0A> + <8D07> + <8D0F> + <8D0D> + <8D10> + <9F4E> + <8D13> + <8CCD> + <8D14> + <8D16> + <8D67> + <8D6D> + <8D71> + <8D73> + <8D81> + <8D99> + <8DC2> + <8DBE> + <8DBA> + <8DCF> + <8DDA> + <8DD6> + <8DCC> + <8DDB> + <8DCB> + <8DEA> + <8DEB> + <8DDF> + <8DE3> + <8DFC> + <8E08> + <8E09> + <8DFF> + <8E1D> + <8E1E> + <8E10> + <8E1F> + <8E42> + <8E35> + <8E30> + <8E34> + <8E4A> + <8E47> + <8E49> + <8E4C> + <8E50> + <8E48> + <8E59> + <8E64> + <8E60> + <8E2A> + <8E63> + <8E55> + <8E76> + <8E72> + <8E7C> + <8E81> + <8E87> + <8E85> + <8E84> + <8E8B> + <8E8A> + <8E93> + <8E91> + <8E94> + <8E99> + <8EAA> + <8EA1> + <8EAC> + <8EB0> + <8EC6> + <8EB1> + <8EBE> + <8EC5> + <8EC8> + <8ECB> + <8EDB> +endbfchar + +100 beginbfchar + <8EE3> + <8EFC> + <8EFB> + <8EEB> + <8EFE> + <8F0A> + <8F05> + <8F15> + <8F12> + <8F19> + <8F13> + <8F1C> + <8F1F> + <8F1B> + <8F0C> + <8F26> + <8F33> + <8F3B> + <8F39> + <8F45> + <8F42> + <8F3E> + <8F4C> + <8F49> + <8F46> + <8F4E> + <8F57> + <8F5C> + <8F62> + <8F63> + <8F64> + <8F9C> + <8F9F> + <8FA3> + <8FAD> + <8FAF> + <8FB7> + <8FDA> + <8FE5> + <8FE2> + <8FEA> + <8FEF> + <9087> + <8FF4> + <9005> + <8FF9> + <8FFA> + <9011> + <9015> + <9021> + <900D> + <901E> + <9016> + <900B> + <9027> + <9036> + <9035> + <9039> + <8FF8> + <904F> + <9050> + <9051> + <9052> + <900E> + <9049> + <903E> + <9056> + <9058> + <905E> + <9068> + <906F> + <9076> + <96A8> + <9072> + <9082> + <907D> + <9081> + <9080> + <908A> + <9089> + <908F> + <90A8> + <90AF> + <90B1> + <90B5> + <90E2> + <90E4> + <6248> + <90DB> + <9102> + <9112> + <9119> + <9132> + <9130> + <914A> + <9156> + <9158> + <9163> + <9165> + <9169> +endbfchar + +100 beginbfchar + <9173> + <9172> + <918B> + <9189> + <9182> + <91A2> + <91AB> + <91AF> + <91AA> + <91B5> + <91B4> + <91BA> + <91C0> + <91C1> + <91C9> + <91CB> + <91D0> + <91D6> + <91DF> + <91E1> + <91DB> + <91FC> + <91F5> + <91F6> + <921E> + <91FF> + <9214> + <922C> + <9215> + <9211> + <925E> + <9257> + <9245> + <9249> + <9264> + <9248> + <9295> + <923F> + <924B> + <9250> + <929C> + <9296> + <9293> + <929B> + <925A> + <92CF> + <92B9> + <92B7> + <92E9> + <930F> + <92FA> + <9344> + <932E> + <9319> + <9322> + <931A> + <9323> + <933A> + <9335> + <933B> + <935C> + <9360> + <937C> + <936E> + <9356> + <93B0> + <93AC> + <93AD> + <9394> + <93B9> + <93D6> + <93D7> + <93E8> + <93E5> + <93D8> + <93C3> + <93DD> + <93D0> + <93C8> + <93E4> + <941A> + <9414> + <9413> + <9403> + <9407> + <9410> + <9436> + <942B> + <9435> + <9421> + <943A> + <9441> + <9452> + <9444> + <945B> + <9460> + <9462> + <945E> + <946A> + <9229> +endbfchar + +100 beginbfchar + <9470> + <9475> + <9477> + <947D> + <945A> + <947C> + <947E> + <9481> + <947F> + <9582> + <9587> + <958A> + <9594> + <9596> + <9598> + <9599> + <95A0> + <95A8> + <95A7> + <95AD> + <95BC> + <95BB> + <95B9> + <95BE> + <95CA> + <6FF6> + <95C3> + <95CD> + <95CC> + <95D5> + <95D4> + <95D6> + <95DC> + <95E1> + <95E5> + <95E2> + <9621> + <9628> + <962E> + <962F> + <9642> + <964C> + <964F> + <964B> + <9677> + <965C> + <965E> + <965D> + <965F> + <9666> + <9672> + <966C> + <968D> + <9698> + <9695> + <9697> + <96AA> + <96A7> + <96B1> + <96B2> + <96B0> + <96B4> + <96B6> + <96B8> + <96B9> + <96CE> + <96CB> + <96C9> + <96CD> + <894D> + <96DC> + <970D> + <96D5> + <96F9> + <9704> + <9706> + <9708> + <9713> + <970E> + <9711> + <970F> + <9716> + <9719> + <9724> + <972A> + <9730> + <9739> + <973D> + <973E> + <9744> + <9746> + <9748> + <9742> + <9749> + <975C> + <9760> + <9764> + <9766> + <9768> + <52D2> +endbfchar + +100 beginbfchar + <976B> + <9771> + <9779> + <9785> + <977C> + <9781> + <977A> + <9786> + <978B> + <978F> + <9790> + <979C> + <97A8> + <97A6> + <97A3> + <97B3> + <97B4> + <97C3> + <97C6> + <97C8> + <97CB> + <97DC> + <97ED> + <9F4F> + <97F2> + <7ADF> + <97F6> + <97F5> + <980F> + <980C> + <9838> + <9824> + <9821> + <9837> + <983D> + <9846> + <984F> + <984B> + <986B> + <986F> + <9870> + <9871> + <9874> + <9873> + <98AA> + <98AF> + <98B1> + <98B6> + <98C4> + <98C3> + <98C6> + <98E9> + <98EB> + <9903> + <9909> + <9912> + <9914> + <9918> + <9921> + <991D> + <991E> + <9924> + <9920> + <992C> + <992E> + <993D> + <993E> + <9942> + <9949> + <9945> + <9950> + <994B> + <9951> + <9952> + <994C> + <9955> + <9997> + <9998> + <99A5> + <99AD> + <99AE> + <99BC> + <99DF> + <99DB> + <99DD> + <99D8> + <99D1> + <99ED> + <99EE> + <99F1> + <99F2> + <99FB> + <99F8> + <9A01> + <9A0F> + <9A05> + <99E2> + <9A19> + <9A2B> + <9A37> +endbfchar + +100 beginbfchar + <9A45> + <9A42> + <9A40> + <9A43> + <9A3E> + <9A55> + <9A4D> + <9A5B> + <9A57> + <9A5F> + <9A62> + <9A65> + <9A64> + <9A69> + <9A6B> + <9A6A> + <9AAD> + <9AB0> + <9ABC> + <9AC0> + <9ACF> + <9AD1> + <9AD3> + <9AD4> + <9ADE> + <9ADF> + <9AE2> + <9AE3> + <9AE6> + <9AEF> + <9AEB> + <9AEE> + <9AF4> + <9AF1> + <9AF7> + <9AFB> + <9B06> + <9B18> + <9B1A> + <9B1F> + <9B22> + <9B23> + <9B25> + <9B27> + <9B28> + <9B29> + <9B2A> + <9B2E> + <9B2F> + <9B32> + <9B44> + <9B43> + <9B4F> + <9B4D> + <9B4E> + <9B51> + <9B58> + <9B74> + <9B93> + <9B83> + <9B91> + <9B96> + <9B97> + <9B9F> + <9BA0> + <9BA8> + <9BB4> + <9BC0> + <9BCA> + <9BB9> + <9BC6> + <9BCF> + <9BD1> + <9BD2> + <9BE3> + <9BE2> + <9BE4> + <9BD4> + <9BE1> + <9C3A> + <9BF2> + <9BF1> + <9BF0> + <9C15> + <9C14> + <9C09> + <9C13> + <9C0C> + <9C06> + <9C08> + <9C12> + <9C0A> + <9C04> + <9C2E> + <9C1B> + <9C25> + <9C24> + <9C21> + <9C30> + <9C47> +endbfchar + +100 beginbfchar + <9C32> + <9C46> + <9C3E> + <9C5A> + <9C60> + <9C67> + <9C76> + <9C78> + <9CE7> + <9CEC> + <9CF0> + <9D09> + <9D08> + <9CEB> + <9D03> + <9D06> + <9D2A> + <9D26> + <9DAF> + <9D23> + <9D1F> + <9D44> + <9D15> + <9D12> + <9D41> + <9D3F> + <9D3E> + <9D46> + <9D48> + <9D5D> + <9D5E> + <9D64> + <9D51> + <9D50> + <9D59> + <9D72> + <9D89> + <9D87> + <9DAB> + <9D6F> + <9D7A> + <9D9A> + <9DA4> + <9DA9> + <9DB2> + <9DC4> + <9DC1> + <9DBB> + <9DB8> + <9DBA> + <9DC6> + <9DCF> + <9DC2> + <9DD9> + <9DD3> + <9DF8> + <9DE6> + <9DED> + <9DEF> + <9DFD> + <9E1A> + <9E1B> + <9E1E> + <9E75> + <9E79> + <9E7D> + <9E81> + <9E88> + <9E8B> + <9E8C> + <9E92> + <9E95> + <9E91> + <9E9D> + <9EA5> + <9EA9> + <9EB8> + <9EAA> + <9EAD> + <9761> + <9ECC> + <9ECE> + <9ECF> + <9ED0> + <9ED4> + <9EDC> + <9EDE> + <9EDD> + <9EE0> + <9EE5> + <9EE8> + <9EEF> + <9EF4> + <9EF6> + <9EF7> + <9EF9> + <9EFB> + <9EFC> + <9EFD> + <9F07> +endbfchar + +29 beginbfchar + <9F08> + <76B7> + <9F15> + <9F21> + <9F2C> + <9F3E> + <9F4A> + <9F52> + <9F54> + <9F63> + <9F5F> + <9F60> + <9F61> + <9F66> + <9F67> + <9F6C> + <9F6A> + <9F77> + <9F72> + <9F76> + <9F95> + <9F9C> + <9FA0> + <582F> + <69C7> + <9059> + <7464> + <51DC> + <7199> +endbfchar + +endcmap +CMapName currentdict /CMap defineresource pop +end +end + +%%EndResource +%%EOF diff --git a/Build/source/texk/dvipdf-x/data/Makefile.am b/Build/source/texk/dvipdf-x/data/Makefile.am new file mode 100644 index 00000000000..1a9cbe259e9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/data/Makefile.am @@ -0,0 +1,11 @@ +configdatadir = $(datarootdir)/texmf-dist/dvipdfmx +dist_configdata_DATA = dvipdfmx.cfg + +glyphlistdatadir = $(datarootdir)/texmf-dist/fonts/map/glyphlist +dist_glyphlistdata_DATA = glyphlist.txt pdfglyphlist.txt + +mapdatadir = $(datarootdir)/texmf-dist/fonts/map/dvipdfmx +dist_mapdata_DATA = cid-x.map + +cmapdatadir = $(datarootdir)/texmf-dist/fonts/cmap/dvipdfmx +dist_cmapdata_DATA = EUC-UCS2 diff --git a/Build/source/texk/dvipdf-x/data/Makefile.in b/Build/source/texk/dvipdf-x/data/Makefile.in new file mode 100644 index 00000000000..e9b08e88636 --- /dev/null +++ b/Build/source/texk/dvipdf-x/data/Makefile.in @@ -0,0 +1,586 @@ +# Makefile.in generated by automake 1.14 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +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@ +subdir = data +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(dist_cmapdata_DATA) $(dist_configdata_DATA) \ + $(dist_glyphlistdata_DATA) $(dist_mapdata_DATA) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../m4/cho-libs.m4 \ + $(top_srcdir)/../../m4/kpse-common.m4 \ + $(top_srcdir)/../../m4/kpse-freetype2-flags.m4 \ + $(top_srcdir)/../../m4/kpse-kpathsea-flags.m4 \ + $(top_srcdir)/../../m4/kpse-libpng-flags.m4 \ + $(top_srcdir)/../../m4/kpse-lt-hack.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)/ac/dvipdf-x.ac $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +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 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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; }; \ + } +am__installdirs = "$(DESTDIR)$(cmapdatadir)" \ + "$(DESTDIR)$(configdatadir)" "$(DESTDIR)$(glyphlistdatadir)" \ + "$(DESTDIR)$(mapdatadir)" +DATA = $(dist_cmapdata_DATA) $(dist_configdata_DATA) \ + $(dist_glyphlistdata_DATA) $(dist_mapdata_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +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@ +FREETYPE2_DEPEND = @FREETYPE2_DEPEND@ +FREETYPE2_INCLUDES = @FREETYPE2_INCLUDES@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +FT2_CONFIG = @FT2_CONFIG@ +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@ +LIBPNG_DEPEND = @LIBPNG_DEPEND@ +LIBPNG_INCLUDES = @LIBPNG_INCLUDES@ +LIBPNG_LIBS = @LIBPNG_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +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@ +configdatadir = $(datarootdir)/texmf-dist/dvipdfmx +dist_configdata_DATA = dvipdfmx.cfg +glyphlistdatadir = $(datarootdir)/texmf-dist/fonts/map/glyphlist +dist_glyphlistdata_DATA = glyphlist.txt pdfglyphlist.txt +mapdatadir = $(datarootdir)/texmf-dist/fonts/map/dvipdfmx +dist_mapdata_DATA = cid-x.map +cmapdatadir = $(datarootdir)/texmf-dist/fonts/cmap/dvipdfmx +dist_cmapdata_DATA = EUC-UCS2 +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign data/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign data/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @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 +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(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: + +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) + +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-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +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-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +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 Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_cmapdataDATA \ + uninstall-dist_configdataDATA uninstall-dist_glyphlistdataDATA \ + uninstall-dist_mapdataDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-dist_cmapdataDATA install-dist_configdataDATA \ + install-dist_glyphlistdataDATA install-dist_mapdataDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags-am uninstall uninstall-am \ + uninstall-dist_cmapdataDATA uninstall-dist_configdataDATA \ + uninstall-dist_glyphlistdataDATA uninstall-dist_mapdataDATA + + +# 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/dvipdf-x/data/cid-x.map b/Build/source/texk/dvipdf-x/data/cid-x.map new file mode 100644 index 00000000000..40f45d540ff --- /dev/null +++ b/Build/source/texk/dvipdf-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/dvipdf-x/data/dvipdfmx.cfg b/Build/source/texk/dvipdf-x/data/dvipdfmx.cfg new file mode 100644 index 00000000000..1832f5a9a85 --- /dev/null +++ b/Build/source/texk/dvipdf-x/data/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 diff --git a/Build/source/texk/dvipdf-x/data/glyphlist.txt b/Build/source/texk/dvipdf-x/data/glyphlist.txt new file mode 100644 index 00000000000..0304ffc6674 --- /dev/null +++ b/Build/source/texk/dvipdf-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/dvipdf-x/data/pdfglyphlist.txt b/Build/source/texk/dvipdf-x/data/pdfglyphlist.txt new file mode 100644 index 00000000000..25596f152dd --- /dev/null +++ b/Build/source/texk/dvipdf-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/dvipdf-x/dpxconf.c b/Build/source/texk/dvipdf-x/dpxconf.c new file mode 100644 index 00000000000..6c6e0e19160 --- /dev/null +++ b/Build/source/texk/dvipdf-x/dpxconf.c @@ -0,0 +1,112 @@ +/* + + This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dpxconf.h" + +#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 */ + +#if 0 +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); + } +} +#endif diff --git a/Build/source/texk/dvipdf-x/dpxconf.h b/Build/source/texk/dvipdf-x/dpxconf.h new file mode 100644 index 00000000000..167257bf477 --- /dev/null +++ b/Build/source/texk/dvipdf-x/dpxconf.h @@ -0,0 +1,62 @@ +/* + + This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +#ifdef HAVE_LIBPAPER +#include +#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 */ + +#if 0 +extern void dumppaperinfo (void); +#endif + +#endif /* _DPXCONF_H_ */ diff --git a/Build/source/texk/dvipdf-x/dpxcrypt.c b/Build/source/texk/dvipdf-x/dpxcrypt.c new file mode 100644 index 00000000000..cc61cd55dc8 --- /dev/null +++ b/Build/source/texk/dvipdf-x/dpxcrypt.c @@ -0,0 +1,375 @@ +/* + + This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks. + + Copyright (C) 2003-2012 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#include +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif + +#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))) ) + +/* + * 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 , 1995. + * heavily modified for GnuPG by Werner Koch + */ + +void MD5_init (MD5_CONTEXT *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + 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]; + register uint32_t A = ctx->A; + register uint32_t B = ctx->B; + register uint32_t C = ctx->C; + register 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 long 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) +{ + unsigned long 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; + hd->buf[57] = lsb >> 8; + hd->buf[58] = lsb >> 16; + hd->buf[59] = lsb >> 24; + hd->buf[60] = msb; + hd->buf[61] = msb >> 8; + hd->buf[62] = msb >> 16; + hd->buf[63] = msb >> 24; + 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 { *(unsigned long *)p = (*hd).a ; p += 4; } while (0) +#endif + X(A); + X(B); + X(C); + X(D); +#undef X +} + +/* + * 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 , 1995. + * heavily modified for GnuPG by Werner Koch + */ + +static void do_encrypt_stream (ARC4_KEY *ctx, unsigned char *outbuf, const unsigned char *inbuf, unsigned long len) +{ + register int i = ctx->idx_i; + register int j = ctx->idx_j; + register unsigned char *sbox = ctx->sbox; + register 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_KEY *ctx, unsigned long 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_KEY *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_KEY *ctx, unsigned int keylen, const unsigned char *key) +{ + do_arcfour_setkey(ctx, key, keylen); + _gcry_burn_stack(300); +} diff --git a/Build/source/texk/dvipdf-x/dpxcrypt.h b/Build/source/texk/dvipdf-x/dpxcrypt.h new file mode 100644 index 00000000000..d2613043cf8 --- /dev/null +++ b/Build/source/texk/dvipdf-x/dpxcrypt.h @@ -0,0 +1,49 @@ +/* + + This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks. + + Copyright (C) 2003-2012 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 + +/* libgcrypt md5 */ +typedef struct { + unsigned long A,B,C,D; /* chaining variables */ + unsigned long 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 long inlen); +void MD5_final (unsigned char *outbuf, MD5_CONTEXT *ctx); + +/* libgcrypt arcfour */ +typedef struct { + int idx_i, idx_j; + unsigned char sbox[256]; +} ARC4_KEY; + +void ARC4 (ARC4_KEY *ctx, unsigned long len, const unsigned char *inbuf, unsigned char *outbuf); +void ARC4_set_key (ARC4_KEY *ctx, unsigned int keylen, const unsigned char *key); + +#endif /* _DPXCRYPT_H_ */ diff --git a/Build/source/texk/dvipdf-x/dvicodes.h b/Build/source/texk/dvipdf-x/dvicodes.h new file mode 100644 index 00000000000..964da579b15 --- /dev/null +++ b/Build/source/texk/dvipdf-x/dvicodes.h @@ -0,0 +1,131 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 unsigned 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 */ +#ifdef XETEX +#define XDVI_ID 5 /* XeTeX ".xdv" output that uses XDV opcodes below */ +#endif +#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 PTEXDIR 255 /* Ascii pTeX DIR command */ + +#ifdef XETEX +#define XDV_PIC_FILE 251 /* include graphic or PDF file */ +#define XDV_NATIVE_FONT_DEF 252 /* fontdef for native platform font */ +#define XDV_GLYPH_ARRAY 253 /* string of glyph IDs with X and Y positions */ +#define XDV_GLYPH_STRING 254 /* string of glyph IDs with X-positions only */ +#endif + +#endif /* _DVICODES_H_ */ diff --git a/Build/source/texk/dvipdf-x/dvipdfm-ann.test b/Build/source/texk/dvipdf-x/dvipdfm-ann.test new file mode 100755 index 00000000000..f574bd4da81 --- /dev/null +++ b/Build/source/texk/dvipdf-x/dvipdfm-ann.test @@ -0,0 +1,25 @@ +#! /bin/sh + +# Copyright (C) 2013 Peter Breitenlohner +# You may freely use, modify and/or distribute this file. + +# Not really a test, just making sure the program executes. + +TEXMFCNF=${srcdir}/../kpathsea +TEXFONTS=${srcdir}/tests:${srcdir}/data +DVIPDFMXINPUTS=${srcdir}/tests:${srcdir}/data +TEXPICTS=${srcdir}/tests +export TEXMFCNF TEXFONTS DVIPDFMXINPUTS TEXPICTS + +failed= + +echo "*** dvipdfmx -v -o grahn1.pdf grahn" && echo \ + && ./dvipdfmx -v -o grahn1.pdf ${srcdir}/tests/grahn \ + && echo && echo "dvipdfmx-ann tests OK" && echo \ + || failed="$failed dvipdfmx-ann" + +test -z "$failed" && exit 0 +echo +echo "failed tests:$failed" +exit 1 + diff --git a/Build/source/texk/dvipdf-x/dvipdfmx.h b/Build/source/texk/dvipdf-x/dvipdfmx.h new file mode 100644 index 00000000000..0736e061988 --- /dev/null +++ b/Build/source/texk/dvipdf-x/dvipdfmx.h @@ -0,0 +1,28 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2009-2012 by Jin-Hwan Cho, Matthias Franz, 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 _DVIPDFMX_H_ +#define _DVIPDFMX_H_ + +extern int compat_mode; + +#endif /* _DVIPDFMX_H_ */ diff --git a/Build/source/texk/dvipdf-x/dvipdfmx.test b/Build/source/texk/dvipdf-x/dvipdfmx.test new file mode 100755 index 00000000000..4fb17db507c --- /dev/null +++ b/Build/source/texk/dvipdf-x/dvipdfmx.test @@ -0,0 +1,33 @@ +#! /bin/sh + +# Copyright (C) 2013 Peter Breitenlohner +# You may freely use, modify and/or distribute this file. + +TEXMFCNF=${srcdir}/../kpathsea +TEXFONTS=${srcdir}/tests:${srcdir}/data +DVIPDFMXINPUTS=${srcdir}/tests:${srcdir}/data +TEXPICTS=${srcdir}/tests +export TEXMFCNF TEXFONTS DVIPDFMXINPUTS TEXPICTS + +failed= + +echo "*** dvipdfmx --version" \ + && ./dvipdfmx --version \ + && echo && echo "dvipdfmx-version tests OK" && echo \ + || failed="$failed dvipdfmx-version" + +echo "*** dvipdfmx --help" \ + && ./dvipdfmx --help \ + && echo && echo "dvipdfmx-help tests OK" && echo \ + || failed="$failed dvipdfmx-help" + +echo "*** dvipdfmx -v -o image1.pdf image" && echo \ + && ./dvipdfmx -v -o image1.pdf ${srcdir}/tests/image \ + && echo && echo "dvipdfmx-image tests OK" && echo \ + || failed="$failed dvipdfmx-image" + +test -z "$failed" && exit 0 +echo +echo "failed tests:$failed" +exit 1 + diff --git a/Build/source/texk/dvipdf-x/dvipdft b/Build/source/texk/dvipdf-x/dvipdft new file mode 100755 index 00000000000..3bcd0027db1 --- /dev/null +++ b/Build/source/texk/dvipdf-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/dvipdf-x/man/Makefile.am b/Build/source/texk/dvipdf-x/man/Makefile.am new file mode 100644 index 00000000000..dcd610d22ea --- /dev/null +++ b/Build/source/texk/dvipdf-x/man/Makefile.am @@ -0,0 +1,12 @@ +# Note: dvipdft.1 used here needs to be updated +# and dvipdfm.1 be replaced by dvipdfmx.1 with a link to dvipdfm.1 +dist_man1_MANS = dvipdfm.1 dvipdft.1 extractbb.1 + +man1_links = extractbb:ebb + +include $(top_srcdir)/../../am/man1_links.am + +install-data-hook: install-man1-links + +uninstall-hook: uninstall-man1-links + diff --git a/Build/source/texk/dvipdf-x/man/Makefile.in b/Build/source/texk/dvipdf-x/man/Makefile.in new file mode 100644 index 00000000000..68f6eb367a9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/man/Makefile.in @@ -0,0 +1,557 @@ +# Makefile.in generated by automake 1.14 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +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@ +DIST_COMMON = $(top_srcdir)/../../am/man1_links.am \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am $(dist_man1_MANS) +subdir = man +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../m4/cho-libs.m4 \ + $(top_srcdir)/../../m4/kpse-common.m4 \ + $(top_srcdir)/../../m4/kpse-freetype2-flags.m4 \ + $(top_srcdir)/../../m4/kpse-kpathsea-flags.m4 \ + $(top_srcdir)/../../m4/kpse-libpng-flags.m4 \ + $(top_srcdir)/../../m4/kpse-lt-hack.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)/ac/dvipdf-x.ac $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +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 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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; }; \ + } +man1dir = $(mandir)/man1 +am__installdirs = "$(DESTDIR)$(man1dir)" +NROFF = nroff +MANS = $(dist_man1_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +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@ +FREETYPE2_DEPEND = @FREETYPE2_DEPEND@ +FREETYPE2_INCLUDES = @FREETYPE2_INCLUDES@ +FREETYPE2_LIBS = @FREETYPE2_LIBS@ +FT2_CONFIG = @FT2_CONFIG@ +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@ +LIBPNG_DEPEND = @LIBPNG_DEPEND@ +LIBPNG_INCLUDES = @LIBPNG_INCLUDES@ +LIBPNG_LIBS = @LIBPNG_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +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@ + +# Note: dvipdft.1 used here needs to be updated +# and dvipdfm.1 be replaced by dvipdfmx.1 with a link to dvipdfm.1 +dist_man1_MANS = dvipdfm.1 dvipdft.1 extractbb.1 +man1_links = extractbb:ebb +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/../../am/man1_links.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign man/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; +$(top_srcdir)/../../am/man1_links.am: + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @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 +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man1dir)"; 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: + +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) + +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-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +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 Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +uninstall-man: uninstall-man1 + +.MAKE: install-am install-data-am install-strip uninstall-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am 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-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-hook uninstall-man uninstall-man1 + +.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-data-hook: install-man1-links + +uninstall-hook: uninstall-man1-links + +# 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/dvipdf-x/man/dvipdfm.1 b/Build/source/texk/dvipdf-x/man/dvipdfm.1 new file mode 100644 index 00000000000..b72633f76ae --- /dev/null +++ b/Build/source/texk/dvipdf-x/man/dvipdfm.1 @@ -0,0 +1,358 @@ +.de EX +.sp +.in +5 +.nf +.ft CW +.. +.de EE +.in -5 +.ft R +.sp +.fi +.. +.TH "DVIPDFM" "1" "28 April 2011" "20120420" "DVIPDFMx" +.SH NAME +dvipdfm \- produce PDF files directly from DVI files + +.SH SYNOPSIS +.B dvipdfm +.RI [ options ] +.I file\c +.RB [ .dvi ] + +.SH DESCRIPTION +In TeX Live, +.B dvipdfm +is another incarnation of +.B dvipdfmx +rather than a separate program. Compatibility is attempted as best as +possible. (The change was made due to duplicated security and +configuration issues arising repeatedly.) Please report problems with +this +.B dvipdfm +to the +.B dvipdfmx +maintainers at dvipdfmx (at) ktug.or.kr. + +The program +.B dvipdfm +generates a +.SM PDF +file from a +.SM DVI +file. +.SM DVI +files are the output format +produced by TeX. +Output from +.B groff +can be converted to +.SM DVI +format +using +.BR grodvi . + +The program +.B dvipdfm +recognizes several commonly used +.BR \especial +commands, which are extensions to the +.SM 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 +so that many +macro packages produced for use with +.B dvips +will work with +.B dvipdfm. +Dvipdfm understands its own specific +.B \especial +commands to allow access to PDF features +such as annotations and bookmarks. + +For issues related to bounding boxes (and hence image sizes), please see +.BR extractbb (1). + +.SH OPTIONS + +.TP 5 +.B \-\^c +Ignore color +.BR \especials . +The +.B \-\^c +toggles a flag that disables color +.B \especial +processing. +Unless changed in the configuration file, +that flag is off, and color +.BR \especial "s" +are interpreted normally. +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 \-\^d +Remove thumbnail images after including them. +(See the +.B \-\^t +option for more information.) + +.TP 5 +.B \-\^e +Toggle partial font embedding flag. If partial +font embedding is off, embedded fonts are +.I fully +embedded. +The default, if not changed in the configuration file, +is to embed only those glyphs actually used in the document. + +.TP 5 +.B \-\^f map_file +Set the name of the font map file to +.IR map_file . +The format of the font map file +is documented in the +.IR "Dvipdfm User's Manual" . + +.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 " name" +Generate PDF output file having the name +.IR name . +By default, the name of the output +file 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 \-\^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. + +.TP 5 +.B \-\^s " page_specifications" +Select the pages of the +.SM DVI +file to be converted. +The +.I page_specifications +consists of a comma separated list of +.I 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 implied to be the first page of the +.SM DVI +file. +An empty +.I last_page +is treated as the last page of the +.SM 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 +.SM DVI +file; +and +.TP 5 +.B "\-\^s 1\-10" +includes the first ten pages of the +.SM 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. +They must have the same base name +as the +.SM DVI +file and they must have the page number as the extension +to the file name. Dvipdfm does not +generate the thumbnails itself, but it is distributed with a wrapper +program named +.B dvipdft +that does so. + +.TP 5 +.B \-\^v +Increase verbosity. +Results of the +.B \-\^v +option are cumulative (e.g., +.B \-\^vv +) increases the verbosity by two increments. + +.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 bpt ", " 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 compression_level +Set the compression level to +.IR compression_level . +Compressions levels range from 0 (no compression) to +9 (maximum compression) and correspond to the values understood by zlib. + +.SH "IMAGE BOUNDING BOXES" + +When including images with +.BR dvipdfm , +their bounding boxes should be generated by running +.BR ebb , +or extractbb -m. +The result will be in an +.B .bb +file. + +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 Dvipdfm +uses the +.B kpathsea +library for locating the files that it opens. Hence, +the environment variables documented in the +.I Kpathsea library +documentation influence +.B dvipdfm. + +Dvipdfm also reads the following environment variables: + +.TP 5 +TMP +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=dvipdfm \-format='other text files' config +.fi + +.TP 5 +.I config +Startup options + +.TP 5 +.I t1fonts.map +The default font map file (this name 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" +.BR dvipdft "(1), " +.BR tex "(1), " dvips "(1), " groff "(1), " grodvi "(1), " pic "(1), " +.BR extractbb "(1), " +and the +.I "Kpathsea library" +info documentation. + +.SH AUTHOR +Mark A. Wicks. But for the version in TeX Live, all bugs and other +reports should go to the +.B dvipdfmx +maintainers at dvipdfmx (at) ktug.or.kr. diff --git a/Build/source/texk/dvipdf-x/man/dvipdft.1 b/Build/source/texk/dvipdf-x/man/dvipdft.1 new file mode 100644 index 00000000000..50646022ef0 --- /dev/null +++ b/Build/source/texk/dvipdf-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 , +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/dvipdf-x/man/extractbb.1 b/Build/source/texk/dvipdf-x/man/extractbb.1 new file mode 100644 index 00000000000..34b6d348580 --- /dev/null +++ b/Build/source/texk/dvipdf-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 +, 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 +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/dvipdf-x/mem.c b/Build/source/texk/dvipdf-x/mem.c new file mode 100644 index 00000000000..39f87193976 --- /dev/null +++ b/Build/source/texk/dvipdf-x/mem.c @@ -0,0 +1,55 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" + +void *new (size_t size) +{ + void *result = malloc (size); + if (!result) { + ERROR("Out of memory - asked for %lu bytes\n", (unsigned long) size); + } + + return result; +} + +void *renew (void *mem, size_t size) +{ + if (size) { + void *result = realloc (mem, size); + if (!result) { + ERROR("Out of memory - asked for %lu bytes\n", (unsigned long) size); + } + return result; + } else { + /* realloc may not return NULL if size == 0 */ + free(mem); + return NULL; + } +} diff --git a/Build/source/texk/dvipdf-x/mem.h b/Build/source/texk/dvipdf-x/mem.h new file mode 100644 index 00000000000..7db9073a403 --- /dev/null +++ b/Build/source/texk/dvipdf-x/mem.h @@ -0,0 +1,37 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +extern void *new (size_t size); +extern void *renew (void *p, size_t size); + +#define NEW(n,type) (type *) new(((size_t)(n))*sizeof(type)) +#define RENEW(p,n,type) (type *) renew(p,(n)*sizeof(type)) +#define RELEASE(p) free(p) + +#endif /* _MEM_H_ */ diff --git a/Build/source/texk/dvipdf-x/mfileio.c b/Build/source/texk/dvipdf-x/mfileio.c new file mode 100644 index 00000000000..df83b932f83 --- /dev/null +++ b/Build/source/texk/dvipdf-x/mfileio.c @@ -0,0 +1,127 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include +#include "system.h" +#include "mfileio.h" +#include "error.h" + +#ifdef IODEBUG +static FILE *iodebug_file = NULL; +static long 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(); + tmp = fopen (name, mode); + event += 1; + fprintf(iodebug_file, "%p %07ld [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 %07ld [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, long pos) +{ + if (fseek(file, pos, SEEK_SET)) { + os_error(); + } +} + +void seek_relative (FILE *file, long pos) +{ + if (fseek(file, pos, SEEK_CUR)) { + os_error(); + } +} + + +void seek_end (FILE *file) +{ + if (fseek(file, 0L, SEEK_END)) { + os_error(); + } +} + +long tell_position (FILE *file) +{ + long size; + if ((size = ftell (file)) < 0) { + os_error(); + } + return size; +} + +long file_size (FILE *file) +{ + long size; + /* Seek to end */ + seek_end (file); + size = tell_position (file); + rewind (file); + return (size); +} + +/* Unlike fgets, mfgets works with \r, \n, or \r\n end of lines. */ +char *mfgets (char *buffer, unsigned long 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; +} + +char work_buffer[WORK_BUFFER_SIZE]; diff --git a/Build/source/texk/dvipdf-x/mfileio.h b/Build/source/texk/dvipdf-x/mfileio.h new file mode 100644 index 00000000000..a749b589fc5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/mfileio.h @@ -0,0 +1,61 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 +#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 +#define MFOPEN(name,mode) fopen((name),(mode)) +#define MFCLOSE(file) fclose(file) +#endif + +extern UNSIGNED_BYTE read_byte (FILE *); + +extern void seek_absolute (FILE *file, long pos); +extern void seek_relative (FILE *file, long pos); + +extern void seek_end (FILE *file); + +extern long tell_position (FILE *file); + +extern long file_size (FILE *file); + +extern char *mfgets (char *buffer, unsigned long size, FILE *file); + +extern char work_buffer[]; + +#define WORK_BUFFER_SIZE 1024 + +#endif /* _MFILEIO_H_ */ diff --git a/Build/source/texk/dvipdf-x/mpost.h b/Build/source/texk/dvipdf-x/mpost.h new file mode 100644 index 00000000000..d3a01110f57 --- /dev/null +++ b/Build/source/texk/dvipdf-x/mpost.h @@ -0,0 +1,47 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 int check_for_mp (FILE *fp); + +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/dvipdf-x/numbers.c b/Build/source/texk/dvipdf-x/numbers.c new file mode 100644 index 00000000000..56da780a305 --- /dev/null +++ b/Build/source/texk/dvipdf-x/numbers.c @@ -0,0 +1,228 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include "system.h" +#include "error.h" +#include "mfileio.h" +#include "numbers.h" + +UNSIGNED_BYTE get_unsigned_byte (FILE *file) +{ + int ch; + if ((ch = fgetc (file)) < 0) + ERROR ("File ended prematurely\n"); + return (UNSIGNED_BYTE) ch; +} + +#if 0 +UNSIGNED_BYTE sget_unsigned_byte (char *s) +{ + return *((unsigned char *) s); +} +#endif + +SIGNED_BYTE get_signed_byte (FILE *file) +{ + int byte; + byte = get_unsigned_byte(file); + if (byte >= 0x80) + byte -= 0x100; + return (SIGNED_BYTE) byte; +} + +UNSIGNED_PAIR get_unsigned_pair (FILE *file) +{ + int i; + UNSIGNED_BYTE byte; + UNSIGNED_PAIR pair = 0; + for (i=0; i<2; i++) { + byte = get_unsigned_byte(file); + pair = pair*0x100u + byte; + } + return pair; +} + +UNSIGNED_PAIR sget_unsigned_pair (unsigned char *s) +{ + int i; + UNSIGNED_BYTE byte; + UNSIGNED_PAIR pair = 0; + for (i=0; i<2; i++) { + byte = *(s++); + pair = pair*0x100u + byte; + } + return pair; +} + +SIGNED_PAIR get_signed_pair (FILE *file) +{ + int i; + long pair = 0; + for (i=0; i<2; i++) { + pair = pair*0x100 + get_unsigned_byte(file); + } + if (pair >= 0x8000) { + pair -= 0x10000l; + } + return (SIGNED_PAIR) pair; +} + + +UNSIGNED_TRIPLE get_unsigned_triple(FILE *file) +{ + int i; + long triple = 0; + for (i=0; i<3; i++) { + triple = triple*0x100u + get_unsigned_byte(file); + } + return (UNSIGNED_TRIPLE) triple; +} + +SIGNED_TRIPLE get_signed_triple(FILE *file) +{ + int i; + long triple = 0; + for (i=0; i<3; i++) { + triple = triple*0x100 + get_unsigned_byte(file); + } + if (triple >= 0x800000l) + triple -= 0x1000000l; + return (SIGNED_TRIPLE) triple; +} + +SIGNED_QUAD get_signed_quad(FILE *file) +{ + int byte, i; + long quad = 0; + + /* Check sign on first byte before reading others */ + byte = get_unsigned_byte(file); + quad = byte; + if (quad >= 0x80) + quad = byte - 0x100; + for (i=0; i<3; i++) { + quad = quad*0x100 + get_unsigned_byte(file); + } + return (SIGNED_QUAD) quad; +} + +UNSIGNED_QUAD get_unsigned_quad(FILE *file) +{ + int i; + unsigned long quad = 0; + for (i=0; i<4; i++) { + quad = quad*0x100u + get_unsigned_byte(file); + } + return (UNSIGNED_QUAD) quad; +} + +SIGNED_QUAD sqxfw (SIGNED_QUAD sq, fixword fw) +{ + int sign = 1; + unsigned long a, b, c, d, ad, bd, bc, ac; + unsigned long e, f, g, h, i, j, k; + unsigned long result; + /* Make positive. */ + if (sq < 0) { + sign = -sign; + sq = -sq; + } + if (fw < 0) { + sign = -sign; + fw = -fw; + } + a = ((unsigned long) sq) >> 16u; + b = ((unsigned long) sq) & 0xffffu; + c = ((unsigned long) fw) >> 16u; + d = ((unsigned long) fw) & 0xffffu; + ad = a*d; bd = b*d; bc = b*c; ac = a*c; + e = bd >> 16u; + f = ad >> 16u; + g = ad & 0xffffu; + h = bc >> 16u; + i = bc & 0xffffu; + j = ac >> 16u; + k = ac & 0xffffu; + result = (e+g+i + (1<<3)) >> 4u; /* 1<<3 is for rounding */ + result += (f+h+k) << 12u; + result += j << 28u; + return (sign > 0) ? result : result * -1L; +} + +#if 0 +SIGNED_QUAD axboverc (SIGNED_QUAD n1, SIGNED_QUAD n2, SIGNED_QUAD divide) +{ + int sign = 1; + unsigned long a, b, c, d, ad, bd, bc, ac, e, f, g, h, i, j, o; + unsigned long high, low; + SIGNED_QUAD result = 0; + /* Make positive. */ + if (n1 < 0) { + sign = -sign; + n1 = -n1; + } + if (n2 < 0) { + sign = -sign; + n2 = -n2; + } + if (divide < 0) { + sign = -sign; + divide = -divide; + } + a = ((unsigned long) n1) >> 16u; + b = ((unsigned long) n1) & 0xffffu; + c = ((unsigned long) n2) >> 16u; + d = ((unsigned long) n2) & 0xffffu; + ad = a*d; bd = b*d; bc = b*c; ac = a*c; + e = bd >> 16u; f = bd & 0xffffu; + g = ad >> 16u; h = ad & 0xffffu; + i = bc >> 16u; j = bc & 0xffffu; + o = e+h+j; + high = g+i+(o>>16u)+ac; o &= 0xffffu; + low = (o << 16) + f; + if (high >= divide) + ERROR ("Overflow in axboc"); + { + int k; + for (k=0; k<32; k++) { + high *= 2; + result *= 2; + if (low >= 0x80000000) { + low -= 0x80000000; + high += 1; + } + low *= 2; + if (high > divide) { + high -= divide; + result += 1; + } + } + } + high *= 2; + if (high >= divide) + result += 1; + return (sign>0)?result:-result; +} +#endif + diff --git a/Build/source/texk/dvipdf-x/numbers.h b/Build/source/texk/dvipdf-x/numbers.h new file mode 100644 index 00000000000..0b3da63dd44 --- /dev/null +++ b/Build/source/texk/dvipdf-x/numbers.h @@ -0,0 +1,86 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 +#include + +typedef unsigned char Ubyte; +typedef int UNSIGNED_BYTE, SIGNED_BYTE, SIGNED_PAIR; +typedef unsigned UNSIGNED_PAIR; +typedef long UNSIGNED_TRIPLE, SIGNED_TRIPLE, SIGNED_QUAD; +typedef unsigned long UNSIGNED_QUAD; + +extern UNSIGNED_BYTE get_unsigned_byte (FILE *); +#if 0 +extern UNSIGNED_BYTE sget_unsigned_byte (char *); +#endif +extern SIGNED_BYTE get_signed_byte (FILE *); +extern UNSIGNED_PAIR get_unsigned_pair (FILE *); +extern UNSIGNED_PAIR sget_unsigned_pair (unsigned char *); +extern SIGNED_PAIR get_signed_pair (FILE *); +extern UNSIGNED_TRIPLE get_unsigned_triple (FILE *); +extern SIGNED_TRIPLE get_signed_triple (FILE *); +extern SIGNED_QUAD get_signed_quad (FILE *); +extern UNSIGNED_QUAD get_unsigned_quad (FILE *); + +typedef signed long fixword; + +extern SIGNED_QUAD sqxfw (SIGNED_QUAD sq, fixword fw); +#if 0 +extern SIGNED_QUAD axboverc (SIGNED_QUAD n1, SIGNED_QUAD n2, SIGNED_QUAD divide); +#endif + +#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/dvipdf-x/otl_conf.c b/Build/source/texk/dvipdf-x/otl_conf.c new file mode 100644 index 00000000000..cffbe505645 --- /dev/null +++ b/Build/source/texk/dvipdf-x/otl_conf.c @@ -0,0 +1,641 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 /* _HAVE_CONFIG_H */ + +#include "system.h" +#include "error.h" +#include "mem.h" +#include "dpxfile.h" +#include "dpxutil.h" + +#include "pdfobj.h" +#include "pdfparse.h" + +#include "agl.h" + +#include "otl_conf.h" + +#define VERBOSE_LEVEL_MIN 0 +static int verbose = 0; +void +otl_conf_set_verbose (void) +{ + verbose++; +} + +static pdf_obj * +parse_uc_coverage (pdf_obj *gclass, const char **pp, const char *endptr) +{ + pdf_obj *coverage; + pdf_obj *value; + long ucv = 0; + char *glyphname, *glyphclass; + + if (*pp + 1 >= endptr) + return NULL; + + if (**pp == '[') + (*pp)++; + + coverage = pdf_new_array(); + + while (*pp < endptr) { + skip_white(pp, endptr); + switch (**pp) { + case ']': case ';': + (*pp)++; + return coverage; + break; + case ',': + (*pp)++; + break; + case '@': + { + pdf_obj *cvalues; + int i, size; + + (*pp)++; + glyphclass = parse_c_ident(pp, endptr); + cvalues = pdf_lookup_dict(gclass, glyphclass); + if (!cvalues) + ERROR("%s not defined...", glyphclass); + size = pdf_array_length(cvalues); + for (i = 0; i < size; i++) { + pdf_add_array(coverage, + pdf_link_obj(pdf_get_array(cvalues, i))); + } + } + break; + default: + glyphname = parse_c_ident(pp, endptr); + if (!glyphname) + ERROR("Invalid Unicode character specified."); + + skip_white(pp, endptr); + if (*pp + 1 < endptr && **pp == '-') { + value = pdf_new_array(); + + if (agl_get_unicodes(glyphname, &ucv, 1) != 1) + ERROR("Invalid Unicode char: %s", glyphname); + pdf_add_array(value, pdf_new_number(ucv)); + RELEASE(glyphname); + + (*pp)++; skip_white(pp, endptr); + glyphname = parse_c_ident(pp, endptr); + if (!glyphname) + ERROR("Invalid Unicode char: %s", glyphname); + if (agl_get_unicodes(glyphname, &ucv, 1) != 1) + ERROR("Invalid Unicode char: %s", glyphname); + pdf_add_array(value, pdf_new_number(ucv)); + RELEASE(glyphname); + + } else { + if (agl_get_unicodes(glyphname, &ucv, 1) != 1) + ERROR("Invalid Unicode char: %s", glyphname); + value = pdf_new_number(ucv); + RELEASE(glyphname); + } + pdf_add_array(coverage, value); + break; + } + skip_white(pp, endptr); + } + + return coverage; +} + +static pdf_obj *parse_block (pdf_obj *gclass, const char **pp, const char *endptr); + +static void +add_rule (pdf_obj *rule, pdf_obj *gclass, + char *first, char *second, char *suffix) +{ + pdf_obj *glyph1, *glyph2; +#define MAX_UNICODES 16 + long unicodes[MAX_UNICODES]; + int i, n_unicodes; + + if (first[0] == '@') { + glyph1 = pdf_lookup_dict(gclass, &first[1]); + if (!glyph1) { + WARN("No glyph class \"%s\" found.", &first[1]); + return; + } + pdf_link_obj(glyph1); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_conf>> Output glyph sequence: %s\n", first); + } + + } else { + n_unicodes = agl_get_unicodes(first, unicodes, MAX_UNICODES); + if (n_unicodes < 1) { + WARN("Failed to convert glyph \"%s\" to Unicode sequence.", + first); + return; + } + glyph1 = pdf_new_array(); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_conf>> Output glyph sequence: %s ->", first); + } + + for (i = 0; i < n_unicodes; i++) { + pdf_add_array(glyph1, pdf_new_number(unicodes[i])); + + if (verbose > VERBOSE_LEVEL_MIN) { + if (unicodes[i] < 0x10000) { + MESG(" U+%04X", unicodes[i]); + } else { + MESG(" U+%06X", unicodes[i]); + } + } + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + } + } + + if (second[0] == '@') { + glyph2 = pdf_lookup_dict(gclass, &second[1]); + if (!glyph2) { + WARN("No glyph class \"%s\" found.", &second[1]); + return; + } + pdf_link_obj(glyph2); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_conf>> Input glyph sequence: %s (%s)\n", second, suffix); + } + + } else { + n_unicodes = agl_get_unicodes(second, unicodes, 16); + if (n_unicodes < 1) { + WARN("Failed to convert glyph \"%s\" to Unicode sequence.", + second); + return; + } + + if (verbose > VERBOSE_LEVEL_MIN) { + if (suffix) + MESG("otl_conf>> Input glyph sequence: %s.%s ->", second, suffix); + else + MESG("otl_conf>> Input glyph sequence: %s ->", second); + } + + glyph2 = pdf_new_array(); + for (i = 0; i < n_unicodes; i++) { + pdf_add_array(glyph2, pdf_new_number(unicodes[i])); + + if (verbose > VERBOSE_LEVEL_MIN) { + if (unicodes[i] < 0x10000) { + MESG(" U+%04X", unicodes[i]); + } else { + MESG(" U+%06X", unicodes[i]); + } + } + } + if (verbose > VERBOSE_LEVEL_MIN) { + MESG(" (%s)\n", suffix); + } + } + + /* OK */ + if (suffix) { + pdf_add_array(rule, pdf_new_string(suffix, strlen(suffix))); + } else { + pdf_add_array(rule, pdf_new_null()); + } + pdf_add_array(rule, glyph1); + pdf_add_array(rule, glyph2); +} + +static pdf_obj * +parse_substrule (pdf_obj *gclass, const char **pp, const char *endptr) +{ + pdf_obj *substrule; + char *token; + + skip_white(pp, endptr); + if (*pp < endptr && **pp == '{') + (*pp)++; + + skip_white(pp, endptr); + if (*pp >= endptr) + return NULL; + + substrule = pdf_new_array(); + while (*pp < endptr && **pp != '}') { + skip_white(pp, endptr); + if (*pp >= endptr) + break; + + if (**pp == '#') { + while (*pp < endptr) { + if (**pp == '\r' || **pp == '\n') { + (*pp)++; + break; + } + (*pp)++; + } + continue; + } else if (**pp == ';') { + (*pp)++; + continue; + } + + skip_white(pp, endptr); + token = parse_c_ident(pp, endptr); + if (!token) + break; + + if (!strcmp(token, "assign") || !strcmp(token, "substitute")) { + char *tmp, *first, *second, *suffix; + + skip_white(pp, endptr); + + first = parse_c_ident(pp, endptr); + if (!first) + ERROR("Syntax error (1)"); + + skip_white(pp, endptr); + tmp = parse_c_ident(pp, endptr); + if (strcmp(tmp, "by") && strcmp(tmp, "to")) + ERROR("Syntax error (2): %s", *pp); + + skip_white(pp, endptr); + second = parse_c_ident(pp, endptr); /* allows @ */ + if (!second) + ERROR("Syntax error (3)"); + + /* (assign|substitute) tag dst src */ + pdf_add_array(substrule, pdf_new_name(token)); + if (*pp + 1 < endptr && **pp == '.') { + (*pp)++; + suffix = parse_c_ident(pp, endptr); + } else { + suffix = NULL; + } + add_rule(substrule, gclass, first, second, suffix); + + RELEASE(first); + RELEASE(tmp); + RELEASE(second); + if (suffix) + RELEASE(suffix); + } else { + ERROR("Unkown command %s.", token); + } + RELEASE(token); + skip_white(pp, endptr); + } + + if (*pp < endptr && **pp == '}') + (*pp)++; + return substrule; +} + +static pdf_obj * +parse_block (pdf_obj *gclass, const char **pp, const char *endptr) +{ + pdf_obj *rule; + char *token, *tmp; + + skip_white(pp, endptr); + if (*pp < endptr && **pp == '{') + (*pp)++; + + skip_white(pp, endptr); + if (*pp >= endptr) + return NULL; + + rule = pdf_new_dict(); + while (*pp < endptr && **pp != '}') { + skip_white(pp, endptr); + if (*pp >= endptr) + break; + if (**pp == '#') { + while (*pp < endptr) { + if (**pp == '\r' || **pp == '\n') { + (*pp)++; + break; + } + (*pp)++; + } + continue; + } else if (**pp == ';') { + (*pp)++; + continue; + } + + skip_white(pp, endptr); + token = parse_c_ident(pp, endptr); + if (!token) + break; + + if (!strcmp(token, "script") || + !strcmp(token, "language")) { + int i, len; + + skip_white(pp, endptr); + len = 0; + while (*pp + len < endptr && *(*pp + len) != ';') { + len++; + } + if (len > 0) { + tmp = NEW(len+1, char); + memset(tmp, 0, len+1); + for (i = 0; i < len; i++) { + if (!isspace(**pp)) + tmp[i] = **pp; + (*pp)++; + } + pdf_add_dict(rule, + pdf_new_name(token), + pdf_new_string(tmp, strlen(tmp))); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_conf>> Current %s set to \"%s\"\n", token, tmp); + } + + RELEASE(tmp); + } + } else if (!strcmp(token, "option")) { + pdf_obj *opt_dict, *opt_rule; + + opt_dict = pdf_lookup_dict(rule, "option"); + if (!opt_dict) { + opt_dict = pdf_new_dict(); + pdf_add_dict(rule, + pdf_new_name("option"), opt_dict); + } + + skip_white(pp, endptr); + tmp = parse_c_ident(pp, endptr); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_conf>> Reading option \"%s\"\n", tmp); + } + + skip_white(pp, endptr); + opt_rule = parse_block(gclass, pp, endptr); + pdf_add_dict(opt_dict, pdf_new_name(tmp), opt_rule); + + RELEASE(tmp); + } else if (!strcmp(token, "prefered") || + !strcmp(token, "required") || + !strcmp(token, "optional")) { + pdf_obj *subst, *rule_block; + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_conf>> Reading block (%s)\n", token); + } + + skip_white(pp, endptr); + if (*pp >= endptr || **pp != '{') + ERROR("Syntax error (1)"); + + rule_block = parse_substrule(gclass, pp, endptr); + subst = pdf_lookup_dict(rule, "rule"); + if (!subst) { + subst = pdf_new_array(); + pdf_add_dict(rule, pdf_new_name("rule"), subst); + } + pdf_add_array(subst, pdf_new_number(token[0])); + pdf_add_array(subst, rule_block); + } else if (token[0] == '@') { + pdf_obj *coverage; + + skip_white(pp, endptr); + (*pp)++; /* = */ + skip_white(pp, endptr); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_conf>> Glyph class \"%s\"\n", token); + } + + coverage = parse_uc_coverage(gclass, pp, endptr); + if (!coverage) + ERROR("No valid Unicode characters..."); + + pdf_add_dict(gclass, + pdf_new_name(&token[1]), coverage); + } + RELEASE(token); + skip_white(pp, endptr); + } + + if (*pp < endptr && **pp == '}') + (*pp)++; + return rule; +} + + +static pdf_obj * +otl_read_conf (const char *conf_name) +{ + pdf_obj *rule; + pdf_obj *gclass; + FILE *fp; + char *filename, *wbuf, *p, *endptr; + const char *pp; + long size, len; + + filename = NEW(strlen(conf_name)+strlen(".otl")+1, char); + strcpy(filename, conf_name); + strcat(filename, ".otl"); + + fp = DPXFOPEN(filename, DPX_RES_TYPE_TEXT); + if (!fp) { + RELEASE(filename); + return NULL; + } + + size = file_size(fp); + rewind(fp); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otl_conf>> Layout config. \"%s\" found: file=\"%s\" (%ld bytes)\n", + conf_name, filename, size); + } + RELEASE(filename); + if (size < 1) + return NULL; + + wbuf = NEW(size, char); + p = wbuf; endptr = p + size; + while (size > 0 && p < endptr) { + len = fread(p, sizeof(char), size, fp); + p += len; + size -= len; + } + + pp = wbuf; + gclass = pdf_new_dict(); + rule = parse_block(gclass, &pp, endptr); + pdf_release_obj(gclass); + + RELEASE(wbuf); + + return rule; +} + +static pdf_obj *otl_confs = NULL; + +pdf_obj * +otl_find_conf (const char *conf_name) +{ + pdf_obj *rule; + pdf_obj *script, *language; + pdf_obj *options; + + return NULL; + + if (otl_confs) + rule = pdf_lookup_dict(otl_confs, conf_name); + else { + otl_confs = pdf_new_dict(); + rule = NULL; + } + + if (!rule) { + rule = otl_read_conf(conf_name); + if (rule) { + pdf_add_dict(otl_confs, + pdf_new_name(conf_name), rule); + script = pdf_lookup_dict(rule, "script"); + language = pdf_lookup_dict(rule, "language"); + options = pdf_lookup_dict(rule, "option"); + if (!script) { + script = pdf_new_string("*", 1); + pdf_add_dict(rule, + pdf_new_name("script"), + script); + WARN("Script unspecified in \"%s\"...", conf_name); + } + if (!language) { + language = pdf_new_string("dflt", 4); + pdf_add_dict(rule, + pdf_new_name("language"), + language); + WARN("Language unspecified in \"%s\"...", conf_name); + } + + if (options) { + pdf_obj *optkeys, *opt, *key; + long i, num_opts; + + optkeys = pdf_dict_keys(options); + num_opts = pdf_array_length(optkeys); + for (i = 0; i < num_opts; i++) { + key = pdf_get_array(optkeys, i); + opt = pdf_lookup_dict(options, pdf_name_value(key)); + if (!pdf_lookup_dict(opt, "script")) + pdf_add_dict(opt, + pdf_new_name("script"), + pdf_link_obj(script)); + if (!pdf_lookup_dict(opt, "language")) + pdf_add_dict(opt, + pdf_new_name("language"), + pdf_link_obj(language)); + } + pdf_release_obj(optkeys); + } + + } + } + + return rule; +} + + +char * +otl_conf_get_script (pdf_obj *conf) +{ + pdf_obj *script; + + ASSERT(conf); + + script = pdf_lookup_dict(conf, "script"); + + return pdf_string_value(script); +} + +char * +otl_conf_get_language (pdf_obj *conf) +{ + pdf_obj *language; + + ASSERT(conf); + + language = pdf_lookup_dict(conf, "language"); + + return pdf_string_value(language); +} + +pdf_obj * +otl_conf_get_rule (pdf_obj *conf) +{ + ASSERT(conf); + return pdf_lookup_dict(conf, "rule"); +} + +pdf_obj * +otl_conf_find_opt (pdf_obj *conf, const char *opt_tag) +{ + pdf_obj *opt_conf = NULL; + pdf_obj *options; + + ASSERT(conf); + + options = pdf_lookup_dict(conf, "option"); + if (options && opt_tag) + opt_conf = pdf_lookup_dict(options, opt_tag); + else + opt_conf = NULL; + + return opt_conf; +} + +void +otl_init_conf (void) +{ + if (otl_confs) + pdf_release_obj(otl_confs); + otl_confs = pdf_new_dict(); + + if (verbose > VERBOSE_LEVEL_MIN + 10) { + pdf_release_obj(pdf_ref_obj(otl_confs)); + } +} + +void +otl_close_conf (void) +{ + pdf_release_obj(otl_confs); + otl_confs = NULL; +} diff --git a/Build/source/texk/dvipdf-x/otl_conf.h b/Build/source/texk/dvipdf-x/otl_conf.h new file mode 100644 index 00000000000..16a3734cdcd --- /dev/null +++ b/Build/source/texk/dvipdf-x/otl_conf.h @@ -0,0 +1,39 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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_CONF_H_ +#define _OTL_CONF_H_ + +extern void otl_conf_set_verbose (void); + +extern pdf_obj *otl_find_conf (const char *conf_name); +extern void otl_init_conf (void); +extern void otl_close_conf (void); + +extern pdf_obj *otl_conf_get_class (pdf_obj *conf, const char *ident); + +extern char *otl_conf_get_script (pdf_obj *conf); +extern char *otl_conf_get_language (pdf_obj *conf); +extern pdf_obj *otl_conf_get_rule (pdf_obj *conf); +extern pdf_obj *otl_conf_find_opt (pdf_obj *conf, const char *opt_tag); + +#endif /* _OTL_CONF_H_ */ diff --git a/Build/source/texk/dvipdf-x/otl_opt.c b/Build/source/texk/dvipdf-x/otl_opt.c new file mode 100644 index 00000000000..cc26113eaa3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/otl_opt.c @@ -0,0 +1,343 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 /* _HAVE_CONFIG_H */ + +#include +#include +#include + +#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; + break; + 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(**pp) || isdigit(**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 +{ + long start, end; +}; + +struct uc_coverage +{ + long count; + struct lv_range *ranges; +}; + +static int CDECL +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 int CDECL +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; + long 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/dvipdf-x/otl_opt.h b/Build/source/texk/dvipdf-x/otl_opt.h new file mode 100644 index 00000000000..d79fc9a8052 --- /dev/null +++ b/Build/source/texk/dvipdf-x/otl_opt.h @@ -0,0 +1,37 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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/dvipdf-x/pdfencoding.c b/Build/source/texk/dvipdf-x/pdfencoding.c new file mode 100644 index 00000000000..539a575748e --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdfencoding.c @@ -0,0 +1,1080 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.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 unsigned char verbose = 0; + +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 + +void +pdf_encoding_set_verbose (void) +{ + verbose++; +} + +/* + * 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 int CDECL +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 (verbose) { + 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] == '%') { + 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 (verbose > 1) + MESG("[%s]", pdf_name_value(enc_name)); + pdf_release_obj(enc_name); + } + pdf_release_obj(encoding_array); + + if (verbose) 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_get_version() >= 4; + 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. + */ +pdf_obj * +pdf_create_ToUnicode_CMap (const char *enc_name, + char **enc_vec, const char *is_used) +{ + pdf_obj *stream; + CMap *cmap; + int code, all_predef; + char *cmap_name; + unsigned char *p, *endptr; + + ASSERT(enc_name && enc_vec); + + 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); + + all_predef = 1; + for (code = 0; code <= 0xff; code++) { + if (is_used && !is_used[code]) + continue; + + if (enc_vec[code]) { + long len; + int fail_count = 0; + agl_name *agln = agl_lookup_list(enc_vec[code]); + /* Adobe glyph naming conventions are not used by viewers, + * hence even ligatures (e.g, "f_i") must be explicitly defined + */ + if (pdf_get_version() < 5 || !agln || !agln->is_predef) { + 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) { + CMap_add_bfchar(cmap, wbuf, 1, wbuf + 1, len); + all_predef &= agln && agln->is_predef; + } + } + } + } + + stream = all_predef ? NULL : CMap_create_stream(cmap, 0); + + 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 (verbose) { + MESG("(CMap:%s)", ident); + } + stream = CMap_create_stream(cmap, 0); + 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/dvipdf-x/pdfencoding.h b/Build/source/texk/dvipdf-x/pdfencoding.h new file mode 100644 index 00000000000..1fadbd364b9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdfencoding.h @@ -0,0 +1,80 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_encoding_set_verbose (void); + +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/dvipdf-x/pdfencrypt.h b/Build/source/texk/dvipdf-x/pdfencrypt.h new file mode 100644 index 00000000000..6823e7718d5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdfencrypt.h @@ -0,0 +1,39 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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" + +#define MAX_PWD_LEN 128 + +extern void pdf_enc_set_verbose (void); +extern pdf_obj *pdf_enc_id_array (void); +extern void pdf_enc_compute_id_string (char *dviname, char *pdfname); +extern void pdf_enc_set_label (unsigned long label); +extern void pdf_enc_set_generation (unsigned generation); +extern void pdf_enc_set_passwd (unsigned size, unsigned perm, const char *owner, const char *user); +extern void pdf_encrypt_data (unsigned char *data, unsigned long len); +extern pdf_obj *pdf_encrypt_obj (void); + +#endif /* _PDFENCRYPT_H_ */ diff --git a/Build/source/texk/dvipdf-x/pdffont.c b/Build/source/texk/dvipdf-x/pdffont.c new file mode 100644 index 00000000000..e9ba84acac5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdffont.c @@ -0,0 +1,1012 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dpxfile.h" +#include "dpxutil.h" + +#include "pdfobj.h" + +#include "pdfencoding.h" +#include "cmap.h" +#include "unicode.h" + +#include "type1.h" +#include "type1c.h" +#include "truetype.h" + +#include "pkfont.h" + +#include "type0.h" +#include "tt_cmap.h" +#include "cidtype0.h" +#include "otl_conf.h" + +#include "pdffont.h" + +static int __verbose = 0; + +#define MREC_HAS_TOUNICODE(m) ((m) && (m)->opt.tounicode) + +void +pdf_font_set_verbose (void) +{ + __verbose++; + CMap_set_verbose(); + Type0Font_set_verbose(); + CIDFont_set_verbose (); + pdf_encoding_set_verbose(); + UC_set_verbose (); + agl_set_verbose(); + otl_conf_set_verbose(); + otf_cmap_set_verbose (); +} + +int +pdf_font_get_verbose (void) +{ + return __verbose; +} + +void +pdf_font_set_dpi (int font_dpi) +{ + PKFont_set_dpi(font_dpi); +} + +void +pdf_font_make_uniqueTag (char *tag) +{ + int i; + char ch; + static char first = 1; + + if (first) { + srand(time(NULL)); + first = 0; + } + + for (i = 0; i < 6; i++) { + ch = rand() % 26; + tag[i] = ch + 'A'; + } + tag[6] = '\0'; +} + + +struct pdf_font +{ +#ifdef XETEX + FT_Face ft_face; + unsigned short *ft_to_gid; +#endif + + char *ident; + int subtype; + + char *map_name; + + int encoding_id; /* encoding or CMap */ + + /* + * If subtype is Type0, it simply points font_id + * of Type0 font. Type0 and simple font is not + * unified yet. + */ + int font_id; + + /* For simple font */ + int 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; +}; + +static void +pdf_init_font_struct (pdf_font *font) +{ + ASSERT(font); + +#ifdef XETEX + font->ft_face = NULL; +#endif + + font->ident = NULL; + font->map_name = NULL; + font->subtype = -1; + font->font_id = -1; /* Type0 ID */ + 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; + + return; +} + +static void +pdf_flush_font (pdf_font *font) +{ + char *fontname, *uniqueTag; + + if (!font) { + return; + } + + if (font->resource && font->reference) { + if (font->subtype != PDF_FONT_FONTTYPE_TYPE3) { + if (pdf_font_get_flag(font, 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 { + if (!font->fontname) { + ERROR("Undefined in fontname... (%s)", font->ident); + } + 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) { + if (font->ident) + RELEASE(font->ident); + if (font->map_name) + RELEASE(font->map_name); + if (font->fontname) + RELEASE(font->fontname); + if (font->usedchars) + RELEASE(font->usedchars); + + if (font->reference) + ERROR("pdf_font>> Object not flushed."); + if (font->resource) + ERROR("pdf_font> Object not flushed."); + if (font->descriptor) + ERROR("pdf_font>> Object not flushed."); + + font->ident = NULL; + font->map_name = NULL; + font->fontname = NULL; + font->usedchars = 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(); + otl_init_conf(); + + CMap_cache_init(); + pdf_init_encodings(); + + Type0Font_cache_init(); + + font_cache.count = 0; + font_cache.capacity = CACHE_ALLOC_SIZE; + font_cache.fonts = NEW(font_cache.capacity, pdf_font); +} + +#define CHECK_ID(n) do {\ + if ((n) < 0 || (n) >= font_cache.count) {\ + ERROR("Invalid font ID: %d", (n));\ + }\ +} while (0) +#define GET_FONT(n) (&(font_cache.fonts[(n)])) + + +pdf_obj * +pdf_get_font_reference (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = GET_FONT(font_id); + if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) { + Type0Font *t0font; + + t0font = Type0Font_cache_get(font->font_id); + return Type0Font_get_resource(t0font); + } else { + if (!font->reference) { + font->reference = pdf_ref_obj(pdf_font_get_resource(font)); + } + } + + return pdf_link_obj(font->reference); +} + +char * +pdf_get_font_usedchars (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = GET_FONT(font_id); + if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) { + Type0Font *t0font; + + t0font = Type0Font_cache_get(font->font_id); + return Type0Font_get_usedchars(t0font); + } else { + 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->subtype == PDF_FONT_FONTTYPE_TYPE0) { + Type0Font *t0font; + + t0font = Type0Font_cache_get(font->font_id); + return Type0Font_get_wmode(t0font); + } else { + return 0; + } +} + +int +pdf_get_font_subtype (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = GET_FONT(font_id); + + return font->subtype; +} + +#if 0 +char * +pdf_get_font_fontname (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = GET_FONT(font_id); + + return font->fontname; +} +#endif /* 0 */ + +int +pdf_get_font_encoding (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = GET_FONT(font_id); + + return font->encoding_id; +} + +/* 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 *fontdict; + pdf_obj *tounicode; + const char *cmap_name = NULL; + fontmap_rec *mrec; /* 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->map_name); + + mrec = pdf_lookup_fontmap_record(font->map_name); + if (MREC_HAS_TOUNICODE(mrec)) + cmap_name = mrec->opt.tounicode; + else { + cmap_name = font->map_name; + } + + fontdict = pdf_font_get_resource(font); + tounicode = pdf_load_ToUnicode_stream(cmap_name); + if (!tounicode && MREC_HAS_TOUNICODE(mrec)) + WARN("Failed to read ToUnicode mapping \"%s\"...", mrec->opt.tounicode); + else if (tounicode) { + 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_add_dict(fontdict, + pdf_new_name("ToUnicode"), + pdf_ref_obj (tounicode)); /* _FIXME_ */ + if (__verbose) + MESG("pdf_font>> ToUnicode CMap \"%s\" attached to font id=\"%s\".\n", + cmap_name, font->map_name); + } + 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 = GET_FONT(font_id); + + if (__verbose) { + if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) { + MESG("(%s", pdf_font_get_ident(font)); + if (__verbose > 2 && + !pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) { + MESG("[%s+%s]", + pdf_font_get_uniqueTag(font), + pdf_font_get_fontname(font)); + } else if (__verbose > 1) { + MESG("[%s]", + pdf_font_get_fontname(font)); + } + if (__verbose > 1) { + if (pdf_font_get_encoding(font) >= 0) { + MESG("[%s]", + pdf_encoding_get_name(pdf_font_get_encoding(font))); + } else { + MESG("[built-in]"); + } + } + + } + } + + /* Must come before load_xxx */ + try_load_ToUnicode_CMap(font); + + /* Type 0 is handled separately... */ + switch (font->subtype) { + case PDF_FONT_FONTTYPE_TYPE1: + if (__verbose) + MESG("[Type1]"); + if (!pdf_font_get_flag(font, PDF_FONT_FLAG_BASEFONT)) + pdf_font_load_type1(font); + break; + case PDF_FONT_FONTTYPE_TYPE1C: + if (__verbose) + MESG("[Type1C]"); + pdf_font_load_type1c(font); + break; + case PDF_FONT_FONTTYPE_TRUETYPE: + if (__verbose) + MESG("[TrueType]"); + pdf_font_load_truetype(font); + break; + case PDF_FONT_FONTTYPE_TYPE3: + if (__verbose) + MESG("[Type3/PK]"); + pdf_font_load_pkfont (font); + break; + case PDF_FONT_FONTTYPE_TYPE0: + break; + default: + ERROR("Unknown font type: %d", font->subtype); + break; + } + + if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0) + pdf_encoding_add_usedchars(font->encoding_id, font->usedchars); + + if (__verbose) { + if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) + MESG(")"); + } + } + + pdf_encoding_complete(); + + for (font_id = 0; font_id < font_cache.count; font_id++) { + pdf_font *font = GET_FONT(font_id); + + if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0) { + 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) + pdf_add_dict(font->resource, + pdf_new_name("Encoding"), + PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj)); + + if (!pdf_lookup_dict(font->resource, "ToUnicode") + && (tounicode = pdf_encoding_get_tounicode(font->encoding_id))) + 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; + + Type0Font_cache_close(); + + CMap_cache_close(); + pdf_close_encodings(); + + otl_close_conf(); + agl_close_map (); /* After encoding */ + + return; +} + +int +pdf_font_findresource (const char *tex_name, + double font_scale, 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 : tex_name; + if (mrec && mrec->enc_name) { +#define MAYBE_CMAP(s) (!strstr((s), ".enc") || strstr((s), ".cmap")) + if (MAYBE_CMAP(mrec->enc_name)) { + cmap_id = CMap_cache_find(mrec->enc_name); + if (cmap_id >= 0) { + CMap *cmap; + int cmap_type, minbytes; + + cmap = CMap_cache_get(cmap_id); + cmap_type = CMap_get_type (cmap); + minbytes = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN); + /* + * Check for output encoding. + */ + if (cmap_type != CMAP_TYPE_IDENTITY && + cmap_type != CMAP_TYPE_CODE_TO_CID && + cmap_type != CMAP_TYPE_TO_UNICODE) { + WARN("Only 16-bit encoding supported for output encoding."); + } + /* + * Turn on map option. + */ + if (minbytes == 2 && mrec->opt.mapc < 0) { + if (__verbose) { + MESG("\n"); + MESG("pdf_font>> Input encoding \"%s\" requires at least 2 bytes.\n", + CMap_get_name(cmap)); + MESG("pdf_font>> The -m <00> option will be assumed for \"%s\".\n", mrec->font_name); + } + mrec->opt.mapc = 0; /* _FIXME_ */ + } + } else 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)); + } + if (cmap_id < 0) + ERROR("Failed to read UCS2/UCS4 TrueType cmap..."); + } + } + if (cmap_id < 0) { + encoding_id = pdf_encoding_findresource(mrec->enc_name); + if (encoding_id < 0) + ERROR("Could not find encoding file \"%s\".", mrec->enc_name); + } + } + + if (mrec && cmap_id >= 0) { + /* + * Composite Font + */ + int type0_id, found = 0; + + type0_id = pdf_font_findfont0(mrec->font_name, cmap_id, &mrec->opt); + if (type0_id < 0) { + return -1; + } + + for (font_id = 0; + font_id < font_cache.count; font_id++) { + font = GET_FONT(font_id); + if (font->subtype == PDF_FONT_FONTTYPE_TYPE0 && + font->font_id == type0_id && + font->encoding_id == cmap_id) { + found = 1; + if (__verbose) { + MESG("\npdf_font>> Type0 font \"%s\" (cmap_id=%d) found at font_id=%d.\n", + mrec->font_name, cmap_id, font_id); + } + break; + } + } + + if (!found) { + 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 = GET_FONT(font_id); + pdf_init_font_struct(font); + +#ifdef XETEX + font->ft_to_gid = Type0Font_get_ft_to_gid(type0_id); + font->ft_face = mrec->opt.ft_face; +#endif + + font->font_id = type0_id; + font->subtype = PDF_FONT_FONTTYPE_TYPE0; + font->encoding_id = cmap_id; + + font_cache.count++; + + if (__verbose) { + MESG("\npdf_font>> Type0 font \"%s\"", fontname); + MESG(" cmap_id=<%s,%d>", mrec->enc_name, font->encoding_id); + MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id); + } + + } + } else { + /* + * Simple Font - always embed. + */ + int found = 0; + + for (font_id = 0; + font_id < font_cache.count; font_id++) { + font = GET_FONT(font_id); + 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->ident) && + encoding_id == font->encoding_id) { + if (mrec && mrec->opt.index == font->index) + 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(fontname, font->ident) && + font_scale == font->point_size) { + found = 1; + } + break; + case PDF_FONT_FONTTYPE_TYPE0: + break; + default: + ERROR("Unknown font type: %d", font->subtype); + break; + } + + if (found) { + if (__verbose) { + MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", + fontname, encoding_id, font_id); + } + break; + } + } + + + if (!found) { + 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 = GET_FONT(font_id); + + pdf_init_font_struct(font); + +#ifdef XETEX + font->ft_face = mrec ? mrec->opt.ft_face : NULL; +#endif + + font->point_size = font_scale; + font->encoding_id = encoding_id; + font->ident = NEW(strlen(fontname) + 1, char); + strcpy(font->ident, fontname); + font->map_name = NEW(strlen(tex_name) + 1, char); + strcpy(font->map_name, tex_name); + font->index = (mrec && mrec->opt.index) ? mrec->opt.index : 0; + + if (pdf_font_open_type1(font) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TYPE1; + } else if (pdf_font_open_type1c(font) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TYPE1C; + } else if (pdf_font_open_truetype(font) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TRUETYPE; + } else if (pdf_font_open_pkfont(font) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TYPE3; + } else { + pdf_clean_font_struct(font); + return -1; + } + + font_cache.count++; + + if (__verbose) { + MESG("\npdf_font>> Simple font \"%s\"", fontname); + MESG(" enc_id=<%s,%d>", + (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id); + MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id); + } + } + } + + return font_id; +} + +int +pdf_font_is_in_use (pdf_font *font) +{ + ASSERT(font); + + return ((font->reference) ? 1 : 0); +} + +#ifdef XETEX +FT_Face +pdf_font_get_ft_face (pdf_font *font) +{ + ASSERT(font); + + return font->ft_face; +} + +unsigned short * +pdf_get_font_ft_to_gid (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = GET_FONT(font_id); + + return font->ft_to_gid; +} +#endif + +int +pdf_font_get_index (pdf_font *font) +{ + ASSERT(font); + + return font->index; +} + +char * +pdf_font_get_ident (pdf_font *font) +{ + ASSERT(font); + + return font->ident; +} + +char * +pdf_font_get_mapname (pdf_font *font) +{ + ASSERT(font); + + return font->map_name; +} + +char * +pdf_font_get_fontname (pdf_font *font) +{ + ASSERT(font); + + return font->fontname; +} + +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->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_usedchars (pdf_font *font) +{ + ASSERT(font); + + return font->usedchars; +} + +int +pdf_font_get_encoding (pdf_font *font) +{ + ASSERT(font); + + return font->encoding_id; +} + +int +pdf_font_get_flag (pdf_font *font, int mask) +{ + ASSERT(font); + + return ((font->flags & mask) ? 1 : 0); +} + +#if 0 +int +pdf_font_get_flags (pdf_font *font) +{ + ASSERT(font); + + return font->flags; +} +#endif /* 0 */ + +double +pdf_font_get_param (pdf_font *font, int param_type) +{ + double param = 0.0; + + ASSERT(font); + + switch (param_type) { + case PDF_FONT_PARAM_DESIGN_SIZE: + param = font->design_size; + break; + case PDF_FONT_PARAM_POINT_SIZE: + param = font->point_size; + break; + default: + break; + } + + return param; +} + +char * +pdf_font_get_uniqueTag (pdf_font *font) +{ + ASSERT(font); + + if (font->uniqueID[0] == '\0') { + pdf_font_make_uniqueTag(font->uniqueID); + } + + return font->uniqueID; +} + +int +pdf_font_set_fontname (pdf_font *font, const char *fontname) +{ + ASSERT(font && fontname); + + if (strlen(fontname) > PDF_NAME_LEN_MAX) { + ERROR("Unexpected error..."); + return -1; + } + if (font->fontname) { + RELEASE(font->fontname); + } + font->fontname = NEW(strlen(fontname)+1, char); + strcpy(font->fontname, fontname); + + return 0; +} + +int +pdf_font_set_subtype (pdf_font *font, int subtype) +{ + ASSERT(font); + + font->subtype = subtype; + + return 0; +} + +int +pdf_font_set_flags (pdf_font *font, int flags) +{ + ASSERT(font); + + font->flags |= flags; + + return 0; +} + diff --git a/Build/source/texk/dvipdf-x/pdffont.h b/Build/source/texk/dvipdf-x/pdffont.h new file mode 100644 index 00000000000..f4a9a3c19fa --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdffont.h @@ -0,0 +1,110 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +extern void pdf_font_set_verbose (void); +extern int pdf_font_get_verbose (void); + +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_PARAM_DESIGN_SIZE 1 +#define PDF_FONT_PARAM_POINT_SIZE 2 + +typedef struct pdf_font pdf_font; + +/* pdf_open_document() call them. */ +extern void pdf_init_fonts (void); +extern void pdf_close_fonts (void); + +/* font_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 *font_name, + double font_scale, fontmap_rec *mrec); + +extern int pdf_get_font_subtype (int font_id); +extern pdf_obj *pdf_get_font_reference (int font_id); +extern char *pdf_get_font_usedchars (int font_id); + +#if 0 +extern char *pdf_get_font_fontname (int font_id); /* without unique tag */ +#endif /* 0 */ +extern int pdf_get_font_encoding (int font_id); +extern int pdf_get_font_wmode (int font_id); +#ifdef XETEX +extern unsigned short *pdf_get_font_ft_to_gid (int font_id); +#endif + +/* Each font drivers use the followings. */ +extern int pdf_font_is_in_use (pdf_font *font); + +#ifdef XETEX +extern FT_Face pdf_font_get_ft_face (pdf_font *font); +#endif + +extern char *pdf_font_get_ident (pdf_font *font); +extern char *pdf_font_get_mapname (pdf_font *font); +extern char *pdf_font_get_fontname (pdf_font *font); /* without unique tag */ +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 char *pdf_font_get_usedchars (pdf_font *font); +extern int pdf_font_get_encoding (pdf_font *font); + +extern int pdf_font_get_flag (pdf_font *font, int mask); +#if 0 +extern int pdf_font_get_flags (pdf_font *font); +#endif /* 0 */ +extern double pdf_font_get_param (pdf_font *font, int type); + +extern int pdf_font_get_index (pdf_font *font); + +extern int pdf_font_set_fontname (pdf_font *font, const char *fontname); +extern int pdf_font_set_flags (pdf_font *font, int flags); +extern int pdf_font_set_subtype (pdf_font *font, int subtype); + +extern void pdf_font_make_uniqueTag (char *tag); + +#endif /* _PDFFONT_H_ */ diff --git a/Build/source/texk/dvipdf-x/pdflimits.h b/Build/source/texk/dvipdf-x/pdflimits.h new file mode 100644 index 00000000000..e2bd3828a68 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdflimits.h @@ -0,0 +1,43 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 3 +#define PDF_VERSION_MAX 7 +#define PDF_VERSION_DEFAULT 4 + +/* + * 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 + +#endif /* _PDFLIMITS_H_ */ diff --git a/Build/source/texk/dvipdf-x/pdfparse.h b/Build/source/texk/dvipdf-x/pdfparse.h new file mode 100644 index 00000000000..cb253608df9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdfparse.h @@ -0,0 +1,55 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 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_tainted_dict (const char **pp, const char *endptr); + +#endif /* _PDFPARSE_H_ */ diff --git a/Build/source/texk/dvipdf-x/pdfresource.c b/Build/source/texk/dvipdf-x/pdfresource.c new file mode 100644 index 00000000000..ac53e28f581 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdfresource.c @@ -0,0 +1,377 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. + */ + +#if 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; +} + +long +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 (long) ((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 (long) ((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 + +long +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 (long) (cat_id << 16|res_id); + } + } + + return -1; +} + +pdf_obj * +pdf_get_resource_reference (long 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 (long 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/dvipdf-x/pdfresource.h b/Build/source/texk/dvipdf-x/pdfresource.h new file mode 100644 index 00000000000..fd5336e8c2c --- /dev/null +++ b/Build/source/texk/dvipdf-x/pdfresource.h @@ -0,0 +1,47 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 long pdf_defineresource (const char *category, + const char *resname, pdf_obj *object, int flags); +extern long 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 (long res_id); +#if 0 +extern pdf_obj *pdf_get_resource (long res_id); +#endif + +#endif /* _PDF_RESOURCE_H_ */ diff --git a/Build/source/texk/dvipdf-x/pkfont.c b/Build/source/texk/dvipdf-x/pkfont.c new file mode 100644 index 00000000000..12ba5b76fae --- /dev/null +++ b/Build/source/texk/dvipdf-x/pkfont.c @@ -0,0 +1,794 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if 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) +{ + FILE *fp; + char *fqpn; + kpse_glyph_file_type kpse_file_info; + + fqpn = kpse_find_glyph(ident, dpi, kpse_pk_format, &kpse_file_info); + if (!fqpn) + return NULL; + fp = MFOPEN(fqpn, FOPEN_RBIN_MODE); + RELEASE(fqpn); + + return fp; +} + + +int +pdf_font_open_pkfont (pdf_font *font) +{ + char *ident; + double point_size; + int encoding_id; + unsigned dpi; + FILE *fp; + + ident = pdf_font_get_ident(font); + point_size = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE); + encoding_id = pdf_font_get_encoding(font); + + if (!ident || point_size <= 0.0) + return -1; + + dpi = truedpi(ident, point_size, base_dpi); + fp = dpx_open_pk_font_at(ident, dpi); + if (!fp) + return -1; + MFCLOSE(fp); + + /* Type 3 fonts doesn't have FontName. + * FontFamily is recommended for PDF 1.5. + */ + pdf_font_set_fontname(font, ident); + + 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 long +fill_black_run (unsigned char *dp, long left, long run_count) +{ + const static unsigned char mask[8] = { + 127u, 191u, 223u, 239u, 247u, 251u, 253u, 254u + }; + long 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 long +fill_white_run (unsigned char *dp, long left, long run_count) +{ + return run_count; +} + +static long +pk_packed_num (long *np, int dyn_f, unsigned char *dp, long pl) +{ + long 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; +} + + +#if DEBUG == 2 +static void +send_out (unsigned char *rowptr, long rowbytes, long wd, pdf_obj *stream) +#else +static void +send_out (unsigned char *rowptr, long rowbytes, pdf_obj *stream) +#endif +{ + pdf_add_stream(stream, (void *)rowptr, rowbytes); +#if DEBUG == 2 + { + long i, n, len = (wd + 7) / 8; + int c; + fputc('|', stderr); + for (n = 0; n < len; n++) { + c = rowptr[n]; + for (i = 0; i < 8; i++) { + if (n * 8 + i == wd) + break; + if (c & 1 << (7 - i)) + fputc(' ', stderr); + else + fputc('*', stderr); + } + } + fputc('|', stderr); + fputc('\n', stderr); + } +#endif /* DEBUG2 */ +} + +static int +pk_decode_packed (pdf_obj *stream, long wd, long ht, + int dyn_f, int run_color, unsigned char *dp, long pl) +{ + unsigned char *rowptr; + long rowbytes; + long i, np = 0; + long 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. + */ +#ifdef DEBUG + MESG("\npkfont>> wd: %ld, ht: %ld, dyn_f: %d\n", wd, ht, dyn_f); +#endif + for (np = 0, i = 0; i < ht; i++) { + long 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(rowptr, 0, 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 DEBUG == 3 + MESG("\npk_nyb: %d", nyb); +#endif + 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); +#if DEBUG == 3 + MESG(" --> rep: %ld\n", repeat_count); +#endif + } else if (nyb == 15) { + if (repeat_count != 0) + WARN("Second repeat count for this row!"); + np++; /* Consume this nybble */ + repeat_count = 1; +#if DEBUG == 3 + MESG(" --> rep: %ld\n", repeat_count); +#endif + } else { /* run_count */ + /* Interprete current nybble as packed number */ + run_count = pk_packed_num(&np, dyn_f, dp, pl); +#if DEBUG == 3 + MESG(" --> run: %ld (%d)\n", run_count, run_color); +#endif + 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(rowptr, wd - rowbits_left, nbits); + break; + } + } + } + /* We got bitmap row data. */ +#if DEBUG == 2 + send_out(rowptr, rowbytes, wd, stream); +#else + send_out(rowptr, rowbytes, stream); +#endif + for ( ; i < ht && repeat_count > 0; repeat_count--, i++) +#if DEBUG == 2 + send_out(rowptr, rowbytes, wd, stream); +#else + send_out(rowptr, rowbytes, stream); +#endif + } + RELEASE(rowptr); + + return 0; +} + +static int +pk_decode_bitmap (pdf_obj *stream, long wd, long ht, + int dyn_f, int run_color, unsigned char *dp, long pl) +{ + unsigned char *rowptr, c; + long 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) { +#if DEBUG == 2 + send_out(rowptr, rowbytes, wd, stream); +#else + send_out(rowptr, rowbytes, stream); +#endif + memset(rowptr, 0, rowbytes); + j = 0; + } + } + + return 0; +} + + +/* Read PK font file */ +static void +do_skip (FILE *fp, unsigned long length) +{ + while (length-- > 0) + fgetc(fp); +} + +static void +do_preamble (FILE *fp) +{ + /* Check for id byte */ + if (fgetc(fp) == 89) { + /* Skip comment */ + do_skip(fp, get_unsigned_byte(fp)); + /* Skip other header info. It's normally used for verifying this + is the file wethink it is */ + do_skip(fp, 16); + } else { + ERROR("embed_pk_font: PK ID byte is incorrect. Are you sure this is a PK file?"); + } + return; +} + +struct pk_header_ +{ + unsigned long pkt_len; + SIGNED_QUAD chrcode; + SIGNED_QUAD wd, dx, dy; + SIGNED_QUAD bm_wd, bm_ht, 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) * 0x100U + 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 = 0L; + 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_unsigned_quad(fp); + 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_signed_quad(fp); + h->bm_ht = get_signed_quad(fp); + 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) * 0x10000UL + 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 = 0x0L; + 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 (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, long pkt_len) +{ + pdf_obj *stream; /* charproc */ + long 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 %ld %ld %ld %ld 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%ld 0 0 %ld %ld %ld cm\n", pkh->bm_wd, pkh->bm_ht, llx, lly); + pdf_add_stream(stream, work_buffer, len); + len = sprintf (work_buffer, "BI\n/W %ld\n/H %ld\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) +{ + 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 (!pdf_font_is_in_use(font)) { + return 0; + } + + ident = pdf_font_get_ident(font); + point_size = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE); + usedchars = pdf_font_get_usedchars(font); +#if ENABLE_GLYPHENC + encoding_id = pdf_font_get_encoding(font); + 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); + if (!fp) { + ERROR("Could not find/open PK font file: %s (at %udpi)", ident, dpi); + } + + 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]) + do_skip(fp, pkh.pkt_len); + 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, pkh.bm_voff - pkh.bm_ht); + bbox.urx = MAX(bbox.urx, pkh.bm_wd - 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: do_skip(fp, get_unsigned_byte(fp)); break; + case PK_XXX2: do_skip(fp, get_unsigned_pair(fp)); break; + case PK_XXX3: do_skip(fp, get_unsigned_triple(fp)); break; + case PK_XXX4: do_skip(fp, get_unsigned_quad(fp)); break; + case PK_YYY: do_skip(fp, 4); 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/dvipdf-x/pkfont.h b/Build/source/texk/dvipdf-x/pkfont.h new file mode 100644 index 00000000000..2fb39f27e4e --- /dev/null +++ b/Build/source/texk/dvipdf-x/pkfont.h @@ -0,0 +1,35 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); +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/dvipdf-x/pst.c b/Build/source/texk/dvipdf-x/pst.c new file mode 100644 index 00000000000..fd3dab66678 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pst.c @@ -0,0 +1,182 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include + +#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 long 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 long 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/dvipdf-x/pst.h b/Build/source/texk/dvipdf-x/pst.h new file mode 100644 index 00000000000..4b23ae9cd8d --- /dev/null +++ b/Build/source/texk/dvipdf-x/pst.h @@ -0,0 +1,74 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +#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 long pst_length_of (pst_obj *obj); + +extern long 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/dvipdf-x/pst_obj.c b/Build/source/texk/dvipdf-x/pst_obj.c new file mode 100644 index 00000000000..1534f522c43 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pst_obj.c @@ -0,0 +1,901 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include +#include + +#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 { long value; } pst_integer; +typedef struct { double value; } pst_real; +typedef struct { char *value; } pst_name; +typedef struct +{ + long length; + unsigned char *value; +} pst_string; + + +/* BOOLEAN */ +static pst_boolean *pst_boolean_new (char value) ; +static void pst_boolean_release (pst_boolean *obj); +static long pst_boolean_IV (pst_boolean *obj); +static double pst_boolean_RV (pst_boolean *obj); +static unsigned char *pst_boolean_SV (pst_boolean *obj); +static long pst_boolean_length (pst_boolean *obj); +static void *pst_boolean_data_ptr(pst_boolean *obj); + +/* NUMBERS */ +static pst_integer *pst_integer_new (long value) ; +static void pst_integer_release (pst_integer *obj); +static long 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 (pst_integer *obj); +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 long 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 (pst_real *obj); + +/* NAME */ +static pst_name *pst_name_new (const char *name) ; +static void pst_name_release (pst_name *obj); +static long pst_name_IV (pst_name *obj); +static double pst_name_RV (pst_name *obj); +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 long 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; +} + +long +pst_length_of (pst_obj *obj) +{ + long len = 0; + + ASSERT(obj); + switch (obj->type) { + case PST_TYPE_BOOLEAN: len = pst_boolean_length(obj->data); break; + case PST_TYPE_INTEGER: len = pst_integer_length(obj->data); break; + case PST_TYPE_REAL: len = pst_real_length(obj->data); 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; +} + +long +pst_getIV (pst_obj *obj) +{ + long 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(obj->data); 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(obj->data); 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: + { + long 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 long +pst_boolean_IV (pst_boolean *obj) +{ + ASSERT(obj); + return (long) 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 long +pst_boolean_length (pst_boolean *obj) +{ + 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 (long 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 long +pst_integer_IV (pst_integer *obj) +{ + ASSERT(obj); + return (long) 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, "%ld", obj->value); + + value = NEW(len, 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 (pst_integer *obj) +{ + 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 long +pst_real_IV (pst_real *obj) +{ + ASSERT(obj); + return (long) 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 (pst_real *obj) +{ + 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; + long 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 +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; +} + +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 + +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 long +pst_name_IV (pst_name *obj) +{ + TYPE_ERROR(); + return 0; +} + +static double +pst_name_RV (pst_name *obj) +{ + 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; +} + +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; + long 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 long 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 long +pst_string_IV (pst_string *obj) +{ + return (long) 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/dvipdf-x/pst_obj.h b/Build/source/texk/dvipdf-x/pst_obj.h new file mode 100644 index 00000000000..463c2b411e9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/pst_obj.h @@ -0,0 +1,41 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); + +#if 0 +extern int pst_name_is_valid (const char *name); +extern char *pst_name_encode (const char *name); +#endif + +#endif /* _PST_OBJ_H_ */ diff --git a/Build/source/texk/dvipdf-x/sfnt.h b/Build/source/texk/dvipdf-x/sfnt.h new file mode 100644 index 00000000000..29ffeeec98b --- /dev/null +++ b/Build/source/texk/dvipdf-x/sfnt.h @@ -0,0 +1,161 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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_ + +#if HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H_ */ + +#include "mfileio.h" +#include "numbers.h" +#include "pdfobj.h" + +#ifdef XETEX +#include "ft2build.h" +#include FT_FREETYPE_H +#include FT_TRUETYPE_TABLES_H +#endif + +/* Acoid conflict with CHAR from . */ +#define CHAR SFNT_CHAR + +/* 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 unsigned long ULONG; +typedef signed long LONG; +typedef unsigned long Fixed; /* 16.16-bit signed fixed-point number */ +typedef short FWord; +typedef unsigned short uFWord; +typedef short F2Dot14; /* 16-bit signed fixed number with the low + 14 bits representing fraction. */ + +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; +#ifdef XETEX + FT_Face ft_face; + long loc; +#else + FILE *stream; +#endif + ULONG offset; +} sfnt; + +/* Convert sfnt "fixed" type to double */ +#define fixed(a) ((double)((a)%0x10000L)/(double)(0x10000L) + \ + (a)/0x10000L - (((a)/0x10000L > 0x7fffL) ? 0x10000L : 0)) + +#ifdef XETEX +UNSIGNED_BYTE ft_unsigned_byte(sfnt* f); +SIGNED_BYTE ft_signed_byte(sfnt* f); +UNSIGNED_PAIR ft_unsigned_pair(sfnt* f); +SIGNED_PAIR ft_signed_pair(sfnt* f); +UNSIGNED_QUAD ft_unsigned_quad(sfnt* f); +unsigned long ft_read(unsigned char* buf, unsigned long len, sfnt* f); + +#define sfnt_get_byte(s) ((BYTE) ft_unsigned_byte(s)) +#define sfnt_get_char(s) ((CHAR) ft_signed_byte (s)) +#define sfnt_get_ushort(s) ((USHORT) ft_unsigned_pair(s)) +#define sfnt_get_short(s) ((SHORT) ft_signed_pair (s)) +#define sfnt_get_ulong(s) ((ULONG) ft_unsigned_quad(s)) +#define sfnt_get_long(s) ((LONG) ft_signed_quad (s)) + +#define sfnt_seek_set(s,o) (s)->loc = (o) +#define sfnt_read(b,l,s) ft_read((b), (l), (s)) +#else +/* 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) +#endif + +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); + +#ifdef XETEX +extern sfnt *sfnt_open (FT_Face face, int accept_types); +#else +extern sfnt *sfnt_open (FILE *fp); +extern sfnt *dfont_open (FILE *fp, int index); +#endif +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/dvipdf-x/spc_color.h b/Build/source/texk/dvipdf-x/spc_color.h new file mode 100644 index 00000000000..4af9ac8d21e --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_color.h @@ -0,0 +1,32 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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, long 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/dvipdf-x/spc_dvips.h b/Build/source/texk/dvipdf-x/spc_dvips.h new file mode 100644 index 00000000000..74b50ffa733 --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_dvips.h @@ -0,0 +1,41 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +#ifdef XETEX +extern int spc_dvips_at_begin_document (void); +extern int spc_dvips_at_end_document (void); +extern int spc_dvips_at_begin_page (void); +#endif +extern int spc_dvips_at_end_page (void); + +extern int spc_dvips_check_special (const char *buffer, long 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/dvipdf-x/spc_html.h b/Build/source/texk/dvipdf-x/spc_html.h new file mode 100644 index 00000000000..0f435900c5f --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_html.h @@ -0,0 +1,39 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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, long 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/dvipdf-x/spc_misc.c b/Build/source/texk/dvipdf-x/spc_misc.c new file mode 100644 index 00000000000..ae8ee12e421 --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_misc.c @@ -0,0 +1,210 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" + +#include "mfileio.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" + +static int +spc_handler_postscriptbox (struct spc_env *spe, struct spc_arg *ap) +{ + int form_id, len; + transform_info ti; + 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_findresource(filename, 0, NULL); + if (form_id < 0) { + spc_warn(spe, "Failed to load image file: %s", filename); + return -1; + } + + pdf_dev_put_image(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}, + {"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, long size) +{ + const char *p, *endptr; + int i; + + p = buffer; + endptr = p + size; + + skip_white(&p, endptr); + size = (long) (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(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/dvipdf-x/spc_misc.h b/Build/source/texk/dvipdf-x/spc_misc.h new file mode 100644 index 00000000000..7774f30018b --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_misc.h @@ -0,0 +1,34 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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, long size); +extern int spc_misc_setup_handler (struct spc_handler *handle, + struct spc_env *spe, struct spc_arg *args); + +#endif /* _SPC_MISC_H_ */ diff --git a/Build/source/texk/dvipdf-x/spc_pdfm.h b/Build/source/texk/dvipdf-x/spc_pdfm.h new file mode 100644 index 00000000000..5cbfa8c596b --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_pdfm.h @@ -0,0 +1,37 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_check_special (const char *buffer, long 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/dvipdf-x/spc_tpic.h b/Build/source/texk/dvipdf-x/spc_tpic.h new file mode 100644 index 00000000000..51f51687f9e --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_tpic.h @@ -0,0 +1,41 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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, long 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/dvipdf-x/spc_xtx.c b/Build/source/texk/dvipdf-x/spc_xtx.c new file mode 100644 index 00000000000..a039c36371c --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_xtx.c @@ -0,0 +1,457 @@ +/* + This is xdvipdfmx, an extended version of dvipdfmx, + an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (c) 2006 SIL International + 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, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#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 (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); + pdf_dev_get_fixed_point(&pt); + pdf_dev_set_fixed_point(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, spe, args) < 2) { + return -1; + } + args->curptr = args->endptr; + + return spc_handler_xtx_do_transform(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, spe, 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->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->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, spe, args) < 1) { + return -1; + } + args->curptr = args->endptr; + + return spc_handler_xtx_do_transform (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(); + + return 0; +} + +int +spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args) +{ + pdf_dev_grestore(); + + /* + * 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(); + pdf_dev_reset_color(); + + 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 */ +static int +spc_handler_xtx_fontmapline (struct spc_env *spe, struct spc_arg *ap) +{ + fontmap_rec *mrec; + char *map_name, opchr; + int error = 0; + + 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; + case '+': + mrec = NEW(1, fontmap_rec); + pdf_init_fontmap_record(mrec); + error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr), + is_pdfm_mapline(ap->curptr)); + if (error) + spc_warn(spe, "Invalid fontmap line."); + else { + pdf_append_fontmap_record(mrec->map_name, mrec); + } + pdf_clear_fontmap_record(mrec); + RELEASE(mrec); + break; + default: + mrec = NEW(1, fontmap_rec); + pdf_init_fontmap_record(mrec); + error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr), + is_pdfm_mapline(ap->curptr)); + if (error) + spc_warn(spe, "Invalid fontmap line."); + 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, spe, 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, long 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/dvipdf-x/spc_xtx.h b/Build/source/texk/dvipdf-x/spc_xtx.h new file mode 100644 index 00000000000..b4f75f4abb3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/spc_xtx.h @@ -0,0 +1,40 @@ +/* + This is xdvipdfmx, an extended version of dvipdfmx, + an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (c) 2006 SIL International + 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 + + 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, long 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 (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/dvipdf-x/specials.h b/Build/source/texk/dvipdf-x/specials.h new file mode 100644 index 00000000000..0616f4b8c15 --- /dev/null +++ b/Build/source/texk/dvipdf-x/specials.h @@ -0,0 +1,78 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +struct spc_env { + double x_user, y_user; + double mag; + long pg; /* current page in PDF */ +}; + +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; +}; + +/* This should not use pdf_. */ +extern void spc_set_verbose (void); + +#include +extern void spc_warn (struct spc_env *spe, const char *fmt, ...); + +#include "pdfobj.h" +/* PDF parser shouldn't depend on this... + */ +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 void spc_push_object (const char *key, pdf_obj *value); +extern void spc_flush_object (const char *key); +extern void spc_clear_objects (void); + +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, long size, + double x_user, double y_user, double mag); + +#endif /* _SPECIALS_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/bmpimage.c b/Build/source/texk/dvipdf-x/src/bmpimage.c new file mode 100644 index 00000000000..ef23e70a3a4 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/bmpimage.c @@ -0,0 +1,460 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * BMP SUPPORT: + */ + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "pdfobj.h" + +#include "bmpimage.h" + +#define DIB_FILE_HEADER_SIZE 14 +#define DIB_CORE_HEADER_SIZE 14 +#define DIB_INFO_HEADER_SIZE 40 + +#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_SIZE) + +static long read_raster_rle8 (unsigned char *data_ptr, + long width, long height, FILE *fp); +static long read_raster_rle4 (unsigned char *data_ptr, + long width, long 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; + else + return 1; + + return 0; +} + +int +bmp_include_image (pdf_ximage *ximage, FILE *fp) +{ + pdf_obj *stream, *stream_dict, *colorspace; + ximage_info info; + unsigned char buf[DIB_HEADER_SIZE_MAX+4]; + unsigned char *p; + long offset, hsize, compression; + long psize; /* Bytes per palette color: 3 for OS2, 4 for Win */ + unsigned short bit_count; /* Bits per pix */ + int num_palette, flip; + int i; + + pdf_ximage_init_image_info(&info); + + stream = stream_dict = colorspace = NULL; + p = buf; + + rewind(fp); + if (fread(buf, 1, DIB_FILE_HEADER_SIZE + 4, fp) + != DIB_FILE_HEADER_SIZE + 4) { + WARN("Could not read BMP file header..."); + } + + 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; + offset = ULONG_LE(p); p += 4; + + /* info header */ + hsize = ULONG_LE(p); p += 4; + if (fread(p, sizeof(char), hsize - 4, fp) != hsize - 4) { + WARN("Could not read BMP file header..."); + return -1; + } + flip = 1; + if (hsize == DIB_CORE_HEADER_SIZE) { + info.width = USHORT_LE(p); p += 2; + info.height = USHORT_LE(p); p += 2; + if (USHORT_LE(p) != 1) { + WARN("Unknown bcPlanes value in BMP COREHEADER."); + return -1; + } + p += 2; + bit_count = USHORT_LE(p); p += 2; + compression = DIB_COMPRESS_NONE; + psize = 3; + } else if (hsize == DIB_INFO_HEADER_SIZE) { + info.width = ULONG_LE(p); p += 4; + info.height = ULONG_LE(p); p += 4; + if (USHORT_LE(p) != 1) { + WARN("Unknown biPlanes value in BMP INFOHEADER."); + return -1; + } + p += 2; + bit_count = USHORT_LE(p); p += 2; + compression = ULONG_LE(p); p += 4; + if (info.height < 0) { + info.height = -info.height; + flip = 0; + } + psize = 4; + } else { + WARN("Unknown BMP header type."); + return -1; + } + + if (bit_count < 24) { + if (bit_count != 1 && + bit_count != 4 && bit_count != 8) { + WARN("Unsupported palette size: %ld", bit_count); + return -1; + } + num_palette = (offset - hsize - DIB_FILE_HEADER_SIZE) / psize; + info.bits_per_component = bit_count; + info.num_components = 1; + } else if (bit_count == 24) { /* full color */ + num_palette = 1; /* dummy */ + info.bits_per_component = 8; + info.num_components = 3; + } else { + WARN("Unkown BMP bitCount: %ld", 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; + } + + stream = pdf_new_stream(STREAM_COMPRESS); + stream_dict = pdf_stream_dict(stream); + + if (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, psize, fp) != 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. */ + { + long rowbytes, n; + unsigned char *stream_data_ptr = NULL; + + rowbytes = (info.width * bit_count + 7) / 8; + + seek_absolute(fp, offset); + if (compression == DIB_COMPRESS_NONE) { + long 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 (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 (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 { + pdf_release_obj(stream); + return -1; + } + + /* gbr --> rgb */ + if (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); + } + + pdf_ximage_set_image(ximage, &info, stream); + + return 0; +} + +static long +read_raster_rle8 (unsigned char *data_ptr, + long width, long height, FILE *fp) +{ + long count = 0; + unsigned char *p, b0, b1; + long 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 long +read_raster_rle4 (unsigned char *data_ptr, + long width, long height, FILE *fp) +{ + long count = 0; + unsigned char *p, b0, b1, b; + long 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/dvipdf-x/src/cff.c b/Build/source/texk/dvipdf-x/src/cff.c new file mode 100644 index 00000000000..7e280732123 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/cff.c @@ -0,0 +1,1470 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. +*/ + +#include +#include + +#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 long get_unsigned (FILE *stream, int n) +{ + unsigned long v = 0; + + while (n-- > 0) + v = v*0x100u + get_unsigned_byte(stream); + + return v; +} + +#define get_offset(s, n) get_unsigned((s), (n)) +#define get_card8(s) get_unsigned_byte((s)) +#define get_card16(s) get_unsigned_pair((s)) + +/* + * Read Header, Name INDEX, Top DICT INDEX, and String INDEX. + */ +cff_font *cff_open(FILE *stream, long 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->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_seek_set(cff, 0); + cff->header.major = get_card8(cff->stream); + cff->header.minor = get_card8(cff->stream); + cff->header.hdr_size = get_card8(cff->stream); + cff->header.offsize = get_card8(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 = (long) cff_dict_get(cff->topdict, "CharStrings", 0); + cff_seek_set(cff, offset); + cff->num_glyphs = get_card16(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 = (long) 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 = (long) 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;inum_fds;i++) { + if (cff->fdarray[i]) cff_release_dict(cff->fdarray[i]); + } + RELEASE(cff->fdarray); + } + if (cff->private) { + for (i=0;inum_fds;i++) { + if (cff->private[i]) cff_release_dict(cff->private[i]); + } + RELEASE(cff->private); + } + if (cff->subrs) { + for (i=0;inum_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; +} + +long +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); +} + +long +cff_put_header (cff_font *cff, card8 *dest, long 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_card16(cff->stream); + if (count > 0) { + idx->offsize = get_card8(cff->stream); + if (idx->offsize < 1 || idx->offsize > 4) + ERROR("invalid offsize data"); + + idx->offset = NEW(count+1, l_offset); + for (i=0;ioffset)[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; + long length, nb_read, offset; + + idx = NEW(1, cff_index); + + idx->count = count = get_card16(cff->stream); + if (count > 0) { + idx->offsize = get_card8(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 = fread(idx->data + offset, 1, length, cff->stream); + offset += nb_read; + length -= nb_read; + } + } else { + idx->offsize = 0; + idx->offset = NULL; + idx->data = NULL; + } + + return idx; +} + +long +cff_pack_index (cff_index *idx, card8 *dest, long destlen) +{ + long len = 0; + long 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; +} + +long +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; + long 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; +} + +long 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; +} + +long 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; +} + +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; + long 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. + */ +long cff_read_encoding (cff_font *cff) +{ + cff_encoding *encoding; + long 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 = (long) 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_card8(cff->stream); + length = 1; + + switch (encoding->format & (~0x80)) { + case 0: + encoding->num_entries = get_card8(cff->stream); + (encoding->data).codes = NEW(encoding->num_entries, card8); + for (i=0;i<(encoding->num_entries);i++) { + (encoding->data).codes[i] = get_card8(cff->stream); + } + length += encoding->num_entries + 1; + break; + case 1: + { + cff_range1 *ranges; + encoding->num_entries = get_card8(cff->stream); + encoding->data.range1 = ranges + = NEW(encoding->num_entries, cff_range1); + for (i=0;i<(encoding->num_entries);i++) { + ranges[i].first = get_card8(cff->stream); + ranges[i].n_left = get_card8(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_card8(cff->stream); + encoding->supp = map = NEW(encoding->num_supps, cff_map); + for (i=0;i<(encoding->num_supps);i++) { + map[i].code = get_card8(cff->stream); + map[i].glyph = get_card16(cff->stream); /* SID */ + } + length += (encoding->num_supps) * 3 + 1; + } else { + encoding->num_supps = 0; + encoding->supp = NULL; + } + + return length; +} + +long cff_pack_encoding (cff_font *cff, card8 *dest, long destlen) +{ + long 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); + } +} + +long cff_read_charsets (cff_font *cff) +{ + cff_charsets *charset; + long 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 = (long) 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_card8(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_card16(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_card16(cff->stream); + ranges[charset->num_entries].n_left = get_card8(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_card16(cff->stream); + ranges[charset->num_entries].n_left = get_card16(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; +} + +long cff_pack_charsets (cff_font *cff, card8 *dest, long destlen) +{ + long 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; +} + +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 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) +{ + card16 gid = 0; + cff_charsets *charset; + card16 i; + + 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 (cid == 0) { + return 0; /* GID 0 (.notdef) */ + } + + charset = cff->charsets; + + gid = 0; + switch (charset->format) { + case 0: + for (i = 0; i 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) +{ + card16 sid = 0; + cff_charsets *charset; + card16 i; + + 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 */ + } + + charset = cff->charsets; + + sid = 0; + 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 */ +long cff_read_fdselect (cff_font *cff) +{ + cff_fdselect *fdsel; + long offset, length; + card16 i; + + if (cff->topdict == NULL) + ERROR("Top DICT not available"); + + if (!(cff->flag & FONTTYPE_CIDFONT)) + return 0; + + offset = (long) cff_dict_get(cff->topdict, "FDSelect", 0); + cff_seek_set(cff, offset); + cff->fdselect = fdsel = NEW(1, cff_fdselect); + fdsel->format = get_card8(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_card8(cff->stream); + } + length += fdsel->num_entries; + break; + case 3: + { + cff_range3 *ranges; + fdsel->num_entries = get_card16(cff->stream); + fdsel->data.ranges = ranges = NEW(fdsel->num_entries, cff_range3); + for (i=0;i<(fdsel->num_entries);i++) { + ranges[i].first = get_card16(cff->stream); + ranges[i].fd = get_card8(cff->stream); + } + if (ranges[0].first != 0) + ERROR("Range not starting with 0."); + if (cff->num_glyphs != get_card16(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; +} + +long cff_pack_fdselect (cff_font *cff, card8 *dest, long destlen) +{ + cff_fdselect *fdsel; + long 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;inum_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; +} + +long cff_read_subrs (cff_font *cff) +{ + long len = 0; + long 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;inum_fds;i++) { + if (cff->private[i] == NULL || + !cff_dict_known(cff->private[i], "Subrs")) { + (cff->subrs)[i] = NULL; + } else { + offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); + offset += (long) 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 = (long) cff_dict_get(cff->topdict, "Private", 1); + offset += (long) 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; +} + +long cff_read_fdarray (cff_font *cff) +{ + long len = 0; + cff_index *idx; + long 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 = (long) 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;icount;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; +} + +long cff_read_private (cff_font *cff) +{ + long len = 0; + card8 *data; + long 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;inum_fds;i++) { + if (cff->fdarray[i] != NULL && + cff_dict_known(cff->fdarray[i], "Private") && + (size = (long) cff_dict_get(cff->fdarray[i], "Private", 0)) + > 0) { + offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); + cff_seek_set(cff, offset); + data = NEW(size, card8); + if (fread(data, 1, size, cff->stream) != 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 = (long) cff_dict_get(cff->topdict, "Private", 0)) > 0) { + offset = (long) cff_dict_get(cff->topdict, "Private", 1); + cff_seek_set(cff, offset); + data = NEW(size, card8); + if (fread(data, 1, size, cff->stream) != 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/dvipdf-x/src/cff.h b/Build/source/texk/dvipdf-x/src/cff.h new file mode 100644 index 00000000000..685defb9d72 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/cff.h @@ -0,0 +1,146 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 */ +} cff_font; + +extern cff_font *cff_open (FILE *file, long offset, int idx); +extern void cff_close (cff_font *cff); + +#define cff_seek_set(c, p) seek_absolute (((c)->stream), ((c)->offset) + (p)); + +/* CFF Header */ +extern long cff_put_header (cff_font *cff, card8 *dest, long 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 long cff_index_size (cff_index *idx); +extern long cff_pack_index (cff_index *idx, card8 *dest, long destlen); + +/* Name INDEX */ +extern char *cff_get_name (cff_font *cff); +extern long cff_set_name (cff_font *cff, char *name); + +/* Global and Local Subrs INDEX */ +extern long cff_read_subrs (cff_font *cff); + +/* Encoding */ +extern long cff_read_encoding (cff_font *cff); +extern long cff_pack_encoding (cff_font *cff, card8 *dest, long destlen); +extern card16 cff_encoding_lookup (cff_font *cff, card8 code); +extern void cff_release_encoding (cff_encoding *encoding); + +/* Charsets */ +extern long cff_read_charsets (cff_font *cff); +extern long cff_pack_charsets (cff_font *cff, card8 *dest, long destlen); + +/* Returns GID of PS name "glyph" */ +extern card16 cff_glyph_lookup (cff_font *cff, const char *glyph); +/* Returns GID of glyph with SID/CID "cid" */ +extern card16 cff_charsets_lookup (cff_font *cff, 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); + +/* FDSelect */ +extern long cff_read_fdselect (cff_font *cff); +extern long cff_pack_fdselect (cff_font *cff, card8 *dest, long destlen); +extern card8 cff_fdselect_lookup (cff_font *cff, card16 gid); +extern void cff_release_fdselect (cff_fdselect *fdselect); + +/* Font DICT(s) */ +extern long cff_read_fdarray (cff_font *cff); + +/* Private DICT(s) */ +extern long cff_read_private (cff_font *cff); + +/* String */ +extern int cff_match_string (cff_font *cff, const char *str, s_SID sid); +extern char *cff_get_string (cff_font *cff, s_SID id); +extern long cff_get_sid (cff_font *cff, const char *str); +extern long 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); + +#define cff_is_stdstr(s) (cff_get_sid(NULL, (s)) >= 0) + +#endif /* _CFF_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/cff_dict.c b/Build/source/texk/dvipdf-x/src/cff_dict.c new file mode 100644 index 00000000000..c2e20250299 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/cff_dict.c @@ -0,0 +1,713 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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" + */ + +#include +#include +#include + +#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;icount;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) +{ + long 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) { + *status = CFF_ERROR_PARSE_ERROR; + return; + } else if (stack_top < 1) { + *status = CFF_ERROR_STACK_UNDERFLOW; + 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) { + 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]; + } else { + (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 long pack_integer (card8 *dest, long destlen, long value) +{ + long 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 long pack_real (card8 *dest, long 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 long cff_dict_put_number (double value, + card8 *dest, long destlen, + int type) +{ + long len = 0; + double nearint; + + nearint = floor(value+0.5); + /* set offset to longint */ + if (type == CFF_TYPE_OFFSET) { + long lvalue; + + lvalue = (long) 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, (long) nearint); + } + + return len; +} + +static long +put_dict_entry (cff_dict_entry *de, + card8 *dest, long destlen) +{ + long 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; +} + +long cff_dict_pack (cff_dict *dict, card8 *dest, long destlen) +{ + long 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;idcount;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/dvipdf-x/src/cidtype0.c b/Build/source/texk/dvipdf-x/src/cidtype0.c new file mode 100644 index 00000000000..f2a2afaed00 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/cidtype0.c @@ -0,0 +1,2047 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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. + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "numbers.h" +#include "mem.h" +#include "error.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 "cid_p.h" +#include "cidtype0.h" + +static int verbose = 0; +static long opt_flags = 0; + +void +CIDFont_type0_set_verbose (void) +{ + verbose++; +} + +void +CIDFont_type0_set_flags (long flags) +{ + opt_flags = flags; +} + +/* + * 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; + long cid, start = 0, prev = 0; + double defaultAdvanceWidth; + int empty = 1; + + 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; + long cid; +#if 0 + long 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 long +write_fontfile (CIDFont *font, cff_font *cffont) +{ + cff_index *topdict, *fdarray, *private; + unsigned char *dest; + long destlen = 0, i, size; + long 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; +} + +void +CIDFont_type0_dofont (CIDFont *font) +{ + sfnt *sfont; + cff_font *cffont; + FILE *fp = NULL; + cff_index *charstrings, *idx; + cff_charsets *charset = NULL; + cff_fdselect *fdselect = NULL; + long charstring_len, max_len; + long destlen = 0; + long size, offset = 0; + card8 *data; + card16 num_glyphs, gid; + long cid, cid_count; + card16 cs_count, last_cid; + int fd, prev_fd, parent_id; + char *used_chars; + unsigned char *CIDToGIDMap = NULL; + + ASSERT(font); + + if (!font->indirect) + return; + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), + pdf_ref_obj (font->descriptor)); + + if (CIDFont_is_BaseFont(font)) + return; + else if (!CIDFont_get_embedding(font) && + (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) { + /* No metrics needed. */ + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + return; + } + + if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && + (parent_id = CIDFont_get_parent_id(font, 1)) < 0) + ERROR("No parent Type 0 font !"); + + used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + if (!used_chars) + ERROR("Unexpected error: Font not actually used???"); + + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT); + if (!fp) + ERROR("Could not open OpenType font file: %s", font->ident); + sfont = sfnt_open(fp); + if (!sfont) + ERROR("Could not open OpenType font file: %s", font->ident); + + if (sfnt_read_table_directory(sfont, 0) < 0 || + sfont->type != SFNT_TYPE_POSTSCRIPT) + ERROR("Not a CFF/OpenType font ?"); + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset == 0) + ERROR("Not a CFF/OpenType font ?"); + + cffont = cff_open(fp, offset, font->options->index); + if (!cffont) + ERROR("Could not open CFF font."); + if (!(cffont->flag & FONTTYPE_CIDFONT)) + ERROR("Not a CIDFont."); + + if (cff_dict_known(cffont->topdict, "CIDCount")) { + cid_count = (long) cff_dict_get(cffont->topdict, "CIDCount", 0); + } else { + cid_count = CID_MAX + 1; + } + + cff_read_charsets(cffont); + CIDToGIDMap = NEW(2*cid_count, unsigned char); + memset(CIDToGIDMap, 0, 2*cid_count); + add_to_used_chars2(used_chars, 0); /* .notdef */ + cid = 0; last_cid = 0; num_glyphs = 0; + 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->ident); + 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_FORCE_FIXEDPITCH) { + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + } else { + add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid, + ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1)); + } + + if (!CIDFont_get_embedding(font)) { + RELEASE(CIDToGIDMap); + cff_close(cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return; + } + + /* + * Embed font subset. + */ + cff_read_fdselect(cffont); + cff_read_fdarray(cffont); + cff_read_private(cffont); + + cff_read_subrs(cffont); + + offset = (long) 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 = ftell(cffont->stream); + + if ((cs_count = idx->count) < 2) { + ERROR("No valid charstring data found."); + } + + /* 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) + ERROR("Charstring too long: gid=%u", gid_org); + 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; + seek_absolute(cffont->stream, offset + (idx->offset)[gid_org] - 1); + fread(data, 1, size, cffont->stream); + 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) + ERROR("Unexpeced error: ?????"); + 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); + if (fp) + DPXFCLOSE(fp); + + if (verbose > 1) + MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen); + + /* + * 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); + } + + return; +} + +int +CIDFont_type0_open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + CIDSysInfo *csi; + char *fontname; + sfnt *sfont; + cff_font *cffont; + FILE *fp = NULL; + unsigned long offset = 0; + + ASSERT(font); + + fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT); + if (!fp) + return -1; + + sfont = sfnt_open(fp); + if (!sfont) { + ERROR("Not a CFF/OpenType font?"); + } + if (sfont->type != SFNT_TYPE_POSTSCRIPT || + sfnt_read_table_directory(sfont, 0) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + ERROR("Not a CFF/OpenType font?"); + } + + cffont = cff_open(sfont->stream, offset, opt->index); + if (!cffont) { + ERROR("Cannot read CFF font data"); + } + + if (!(cffont->flag & FONTTYPE_CIDFONT)) { + cff_close(cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + } + + csi = NEW(1, CIDSysInfo); + 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); + + if (cmap_csi) { + if (strcmp(csi->registry, cmap_csi->registry) != 0 || + strcmp(csi->ordering, cmap_csi->ordering) != 0) { + MESG("\nCharacter collection mismatched:\n"); + MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement); + MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); + ERROR("Inconsistent CMap specified for this font."); + } + if (csi->supplement < cmap_csi->supplement) { + WARN("CMap have higher supplmement number."); + WARN("Some characters may not be displayed or printed."); + } + } + + { + char *shortname; + + shortname = cff_get_name(cffont); + if (!shortname) + ERROR("No valid FontName found."); + /* + * Mangled name requires more 7 bytes. + * Style requires more 11 bytes. + */ + fontname = NEW(strlen(shortname)+19, char); + memset(fontname, 0, strlen(shortname)+19); + strcpy(fontname, shortname); + RELEASE(shortname); + } + 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; + } + + font->fontname = fontname; + font->subtype = CIDFONT_TYPE0; + font->csi = csi; + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); + + /* getting font info. from TrueType tables */ + if ((font->descriptor + = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL) + ERROR("Could not obtain necessary font info."); + + if (opt->embed) { + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + } + + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(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->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict); + } + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), + pdf_new_number(1000)); /* not sure */ + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return 0; +} + +void +CIDFont_type0_t1cdofont (CIDFont *font) +{ + sfnt *sfont; + cff_font *cffont; + cff_index *charstrings, *idx; + long charstring_len, max_len; + long destlen = 0; + long size, offset = 0; + card8 *data; + card16 num_glyphs, gid, last_cid; + long i, cid; + int parent_id; + char *used_chars; + double default_width, nominal_width; + FILE *fp = NULL; + + ASSERT(font); + + if (!font->indirect) + return; + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), + pdf_ref_obj (font->descriptor)); + + if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && + (parent_id = CIDFont_get_parent_id(font, 1)) < 0) + ERROR("No parent Type 0 font !"); + + used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + if (!used_chars) + ERROR("Unexpected error: Font not actually used???"); + + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT); + if (!fp) + ERROR("Could not open OpenType font file: %s", font->ident); + + sfont = sfnt_open(fp); + if (!sfont) + ERROR("Could not open OpenType font file: %s", font->ident); + + if (sfnt_read_table_directory(sfont, 0) < 0 || + sfont->type != SFNT_TYPE_POSTSCRIPT) + ERROR("Not a CFF/OpenType font ?"); + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset == 0) + ERROR("Not a CFF/OpenType font ?"); + + cffont = cff_open(fp, offset, font->options->index); + if (!cffont) + ERROR("Could not open CFF font."); + if (cffont->flag & FONTTYPE_CIDFONT) + ERROR("This is CIDFont..."); + + 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 = (long) 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 = ftell(cffont->stream); + + if (idx->count < 2) + ERROR("No valid charstring data found."); + + /* 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) + ERROR("Charstring too long: gid=%u", cid); + 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; + seek_absolute(cffont->stream, offset + (idx->offset)[cid] - 1); + fread(data, 1, size, cffont->stream); + 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) + ERROR("Unexpeced error: ?????"); + 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); + + cff_close(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->fontdict, CIDToGIDMap, last_cid, + ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1)); + RELEASE(CIDToGIDMap); + } + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + if (verbose > 1) + MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen); + + /* + * 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); + } + + return; +} + +int +CIDFont_type0_t1copen (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + CIDSysInfo *csi; + char *fontname; + sfnt *sfont; + cff_font *cffont; + unsigned long offset = 0; + FILE *fp = NULL; + + ASSERT(font); + + fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT); + if (!fp) + return -1; + + sfont = sfnt_open(fp); + if (!sfont) { + ERROR("Not a CFF/OpenType font?"); + } + if (sfont->type != SFNT_TYPE_POSTSCRIPT || + sfnt_read_table_directory(sfont, 0) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + ERROR("Not a CFF/OpenType font?"); + } + + cffont = cff_open(fp, offset, opt->index); + if (!cffont) { + ERROR("Cannot read CFF font data"); + } + + if (cffont->flag & FONTTYPE_CIDFONT) { + cff_close(cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return -1; + } + + csi = NEW(1, CIDSysInfo); + 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 (cmap_csi) { + if (strcmp(csi->registry, cmap_csi->registry) != 0 || + strcmp(csi->ordering, cmap_csi->ordering) != 0) { + MESG("\nCharacter collection mismatched:\n"); + MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement); + MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); + ERROR("Inconsistent CMap specified for this font."); + } + if (csi->supplement < cmap_csi->supplement) { + WARN("CMap have higher supplmement number."); + WARN("Some characters may not be displayed or printed."); + } + } + + { + char *shortname; + + shortname = cff_get_name(cffont); + if (!shortname) + ERROR("No valid FontName found."); + /* Mangled name requires more 7 bytes. */ + + fontname = NEW(strlen(shortname) + 8, char); + memset(fontname, 0, strlen(shortname) + 8); + strcpy(fontname, shortname); + RELEASE(shortname); + } + cff_close(cffont); + + opt->embed = 1; + + font->fontname = fontname; + font->subtype = CIDFONT_TYPE0; + font->csi = csi; + font->flags |= CIDFONT_FLAG_TYPE1C; + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); + + /* getting font info. from TrueType tables */ + if ((font->descriptor + = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL) + ERROR("Could not obtain necessary font info."); + + if (opt->embed) { + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + } + + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(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->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict); + } + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return 0; +} + + +/* 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" + +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++) { + long 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) { + ERROR("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; + long 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; + long 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, 0); + } + CMap_release(cmap); + + return stream; +} + + +int +CIDFont_type0_t1open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + FILE *fp; + char *fontname, *shortname; + cff_font *cffont; + + ASSERT(font); + + if (cmap_csi && + (strcmp(cmap_csi->registry, "Adobe") != 0 || + strcmp(cmap_csi->ordering, "Identity") != 0)) { + return -1; + } + fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT); + if (!fp) + return -1; + + cffont = t1_load_font(NULL, 1, fp); + if (!cffont) { + DPXFCLOSE(fp); + return -1; + } + DPXFCLOSE(fp); + + shortname = cff_get_name(cffont); + if (!shortname) + ERROR("No valid FontName found."); + fontname = NEW(strlen(shortname) + 8, char); + memset(fontname, 0, strlen(shortname) + 8); + strcpy(fontname, shortname); + RELEASE(shortname); + + cff_close(cffont); + + 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 = CIDFONT_TYPE0; + font->csi = NEW(1, CIDSysInfo); + font->csi->registry = NEW(strlen("Adobe")+1, char); + strcpy(font->csi->registry, "Adobe"); + font->csi->ordering = NEW(strlen("Identity")+1, char); + strcpy(font->csi->ordering, "Identity"); + font->csi->supplement = 0; + font->flags |= CIDFONT_FLAG_TYPE1; + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); + + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + + font->descriptor = pdf_new_dict(); + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(fontname)); + { + pdf_obj *csi_dict; + + csi_dict = pdf_new_dict(); + pdf_add_dict(csi_dict, + pdf_new_name("Registry"), + pdf_new_string("Adobe", strlen("Adobe"))); + pdf_add_dict(csi_dict, + pdf_new_name("Ordering"), + pdf_new_string("Identity", strlen("Identity"))); + pdf_add_dict(csi_dict, + pdf_new_name("Supplement"), + pdf_new_number(0.0)); + pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict); + } + + + return 0; +} + +/* 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 */ + +/* pdf_font --> CIDFont */ +static void +get_font_attr (CIDFont *font, cff_font *cffont) +{ + double capheight, ascent, descent; + double italicangle, stemv; + double defaultwidth, nominalwidth; + long flags = 0; + long 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 (CIDFont *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, parent_id; + + /* + * 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?"); + } + 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); + + if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && + (parent_id = CIDFont_get_parent_id(font, 1)) < 0) + ERROR("No parent Type 0 font !"); + + used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + if (!used_chars) { + ERROR("Unexpected error: Font not actually used???"); + } + + /* 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->fontdict, + pdf_new_name("DW"), pdf_new_number(default_width)); + if (pdf_array_length(tmp) > 0) { + pdf_add_dict(font->fontdict, pdf_new_name("W"), pdf_ref_obj(tmp)); + } + pdf_release_obj(tmp); +} + +void +CIDFont_type0_t1dofont (CIDFont *font) +{ + cff_font *cffont; + double defaultwidth, nominalwidth; + long num_glyphs = 0; + FILE *fp; + long i, offset; + char *used_chars = NULL; + card16 last_cid, gid, cid; + unsigned char *CIDToGIDMap; + + ASSERT(font); + + if (!font->indirect) { + return; + } + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), + pdf_ref_obj (font->descriptor)); + + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_T1FONT); + if (!fp) { + ERROR("Type1: Could not open Type1 font."); + } + + cffont = t1_load_font(NULL, 0, fp); + if (!cffont) + ERROR("Could not read Type 1 font..."); + DPXFCLOSE(fp); + + if (!font->fontname) + ERROR("Fontname undefined..."); + + { + Type0Font *hparent, *vparent; + pdf_obj *tounicode; + int vparent_id, hparent_id; + + hparent_id = CIDFont_get_parent_id(font, 0); + vparent_id = CIDFont_get_parent_id(font, 1); + if (hparent_id < 0 && vparent_id < 0) + ERROR("No parent Type 0 font !"); + + /* usedchars is same for h and v */ + if (hparent_id < 0) + hparent = NULL; + else { + hparent = Type0Font_cache_get(hparent_id); + used_chars = Type0Font_get_usedchars(hparent); + } + if (vparent_id < 0) + vparent = NULL; + else { + vparent = Type0Font_cache_get(vparent_id); + used_chars = Type0Font_get_usedchars(vparent); + } + if (!used_chars) + ERROR("Unexpected error: Font not actually used???"); + + tounicode = create_ToUnicode_stream(cffont, font->fontname, used_chars); + + if (hparent) + Type0Font_set_ToUnicode(hparent, pdf_ref_obj(tounicode)); + if (vparent) + Type0Font_set_ToUnicode(vparent, pdf_ref_obj(tounicode)); + pdf_release_obj(tounicode); + } + + 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; + long 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) { + ERROR("This font using the \"seac\" command for accented characters..."); + } + 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); + + { + 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); + } + + + return; +} + +void +CIDFont_type0_release(CIDFont *font) +{ + return; +} diff --git a/Build/source/texk/dvipdf-x/src/cidtype2.c b/Build/source/texk/dvipdf-x/src/cidtype2.c new file mode 100644 index 00000000000..dcf74c6abec --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/cidtype2.c @@ -0,0 +1,1105 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "numbers.h" +#include "mem.h" +#include "error.h" +#include "dpxfile.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 "cid_p.h" +#include "cidtype2.h" + +static int verbose = 0; +static int opt_flags = 0; + +void +CIDFont_type2_set_verbose (void) +{ + verbose++; +} + +void +CIDFont_type2_set_flags (long flags) +{ + opt_flags = flags; +} + +/* + * 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 void +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) { + ERROR("No valid character found in fontname string."); + } +} + +/* + * 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) + ERROR("Character set unknown."); + + if (!strcmp(ord, "UCS") && + select <= WIN_UCS_INDEX_MAX) + 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."); + ERROR("Cannot continue..."); + } + + 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) +{ + long 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 char *cidtogidmap, unsigned short last_cid) +{ + pdf_obj *w2_array, *an_array = NULL; + long cid; +#if 0 + long 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 long +cid_to_code (CMap *cmap, CID cid) +{ + unsigned char inbuf[2], outbuf[32]; + long 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 0; + else if (outbytesleft == 31) + return (long) outbuf[0]; + else if (outbytesleft == 30) + return (long) (outbuf[0] << 8|outbuf[1]); + else if (outbytesleft == 28) { /* We assume the output encoding is UTF-16. */ + CID hi, lo; + hi = outbuf[0] << 8|outbuf[1]; + lo = outbuf[2] << 8|outbuf[3]; + if (hi >= 0xd800 && hi <= 0xdbff && lo >= 0xdc00 && lo <= 0xdfff) + return (long) ((hi - 0xd800) * 0x400 + 0x10000 + lo - 0xdc00); + else + return (long) (hi << 16|lo); + } + + return 0; +} + +/* #define NO_GHOSTSCRIPT_BUG 1 */ + +void +CIDFont_type2_dofont (CIDFont *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; + unsigned long offset = 0; + CID cid, last_cid; + unsigned char *cidtogidmap; + USHORT num_glyphs; + int i, glyph_ordering = 0, unicode_cmap = 0; + FILE *fp = NULL; + + if (!font->indirect) + return; + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor)); + + if (CIDFont_is_BaseFont(font)) + return; + + /* + * 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->csi->registry, strlen(font->csi->registry))); + pdf_add_dict(tmp, + pdf_new_name("Ordering"), + pdf_new_string(font->csi->ordering, strlen(font->csi->ordering))); + pdf_add_dict(tmp, + pdf_new_name("Supplement"), + pdf_new_number(font->csi->supplement)); + pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), tmp); + } + + /* Quick exit for non-embedded & fixed-pitch font. */ + if (!CIDFont_get_embedding(font) && + (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) { + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + return; + } + + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_TTFONT); + if (!fp) { + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_DFONT); + if (!fp) ERROR("Could not open TTF/dfont file: %s", font->ident); + sfont = dfont_open(fp, font->options->index); + } else { + sfont = sfnt_open(fp); + } + + if (!sfont) { + ERROR("Could not open TTF file: %s", font->ident); + } + + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, font->options->index); + if (offset == 0) + ERROR("Invalid TTC index in %s.", font->ident); + break; + case SFNT_TYPE_TRUETYPE: + if (font->options->index > 0) + ERROR("Found TrueType font file while expecting TTC file (%s).", font->ident); + offset = 0; + break; + case SFNT_TYPE_DFONT: + offset = sfont->offset; + break; + default: + ERROR("Not a TrueType/TTC font (%s)?", font->ident); + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) + ERROR("Could not read TrueType table directory (%s).", font->ident); + + /* + * Adobe-Identity means font's internal glyph ordering here. + */ + if (!strcmp(font->csi->registry, "Adobe") && + !strcmp(font->csi->ordering, "Identity")) { + glyph_ordering = 1; + } else { + glyph_ordering = 0; + } + + /* + * Select TrueType cmap table, find ToCode CMap for each TrueType encodings. + */ + if (glyph_ordering) { + ttcmap = NULL; + cmap = NULL; + } else { + /* + * 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->ident); + WARN("CID character collection for this font is set to \"%s-%s\"", + font->csi->registry, font->csi->ordering); + ERROR("Cannot continue without this..."); + } else if (i <= WIN_UCS_INDEX_MAX) { + unicode_cmap = 1; + } else { + unicode_cmap = 0; + } + + /* + * NULL is returned if CMap is Identity CMap. + */ + cmap = find_tocode_cmap(font->csi->registry, + font->csi->ordering, i); + } + + glyphs = tt_build_init(); + + last_cid = 0; + num_glyphs = 1; /* .notdef */ + used_chars = h_used_chars = v_used_chars = NULL; + { + Type0Font *parent; + int parent_id, c; + + if ((parent_id = CIDFont_get_parent_id(font, 0)) >= 0) { + parent = Type0Font_cache_get(parent_id); + h_used_chars = Type0Font_get_usedchars(parent); + } + if ((parent_id = CIDFont_get_parent_id(font, 1)) >= 0) { + parent = Type0Font_cache_get(parent_id); + v_used_chars = Type0Font_get_usedchars(parent); + } + if (!h_used_chars && !v_used_chars) + ERROR("Unexpected error."); + + /* + * 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; + } + if (v_used_chars && v_used_chars[i] != 0) { + last_cid = i * 8 + 7; + c = v_used_chars[i]; + break; + } + } + if (last_cid > 0) { + for (i = 0; i < 8; i++) { + if ((c >> i) & 1) + break; + last_cid--; + } + } + if (last_cid >= 0xFFFFu) { + ERROR("CID count > 65535"); + } + } + +#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++) { + long code; + unsigned short gid; + + if (!is_used_char2(h_used_chars, cid)) + continue; + + if (glyph_ordering) { + gid = cid; + code = cid; + } else { + code = cid_to_code(cmap, cid); + gid = tt_cmap_lookup(ttcmap, code); +#ifdef FIX_CJK_UNIOCDE_SYMBOLS + if (gid == 0 && unicode_cmap) { + long 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 */ + } + + if (gid == 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 (glyph_ordering) { + 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++) { + long code; + unsigned short gid; + + 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; + } + + if (glyph_ordering) { + gid = cid; + code = cid; + } else { + code = cid_to_code(cmap, cid); + gid = tt_cmap_lookup(ttcmap, code); +#ifdef FIX_CJK_UNIOCDE_SYMBOLS + if (gid == 0 && unicode_cmap) { + long 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 */ + } + if (gid == 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; + } + + if (!used_chars) + ERROR("Unexpected error."); + + tt_cmap_release(ttcmap); + + if (CIDFont_get_embedding(font)) { + if (tt_build_tables(sfont, glyphs) < 0) + ERROR("Could not created FontFile stream."); + if (verbose > 1) + MESG("[%u glyphs (Max CID: %u)]", glyphs->num_glyphs, last_cid); + } else { + if (tt_get_metrics(sfont, glyphs) < 0) + ERROR("Reading glyph metrics failed..."); + } + + /* + * DW, W, DW2, and W2 + */ + if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + } else { + add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); + if (v_used_chars) + add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); + } + + tt_build_finish(glyphs); + + /* Finish here if not embedded. */ + if (!CIDFont_get_embedding(font)) { + if (cidtogidmap) + RELEASE(cidtogidmap); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return; + } + + /* 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) { + ERROR("Some required TrueType table (%s) does not exist.", required_table[i].name); + } + } + + /* + * FontFile2 + */ + fontfile = sfnt_create_FontFile_stream(sfont); + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + if (!fontfile) + ERROR("Could not created FontFile stream for \"%s\".", font->ident); + + if (verbose > 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); + + /* + * CIDSet + */ + { + 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); + } + + /* + * CIDToGIDMap + */ + if (cidtogidmap) { + pdf_obj *c2gmstream; + + c2gmstream = pdf_new_stream(STREAM_COMPRESS); + pdf_add_stream(c2gmstream, cidtogidmap, (last_cid + 1) * 2); + pdf_add_dict(font->fontdict, + pdf_new_name("CIDToGIDMap"), + pdf_ref_obj (c2gmstream)); + pdf_release_obj(c2gmstream); + RELEASE(cidtogidmap); + } + + return; +} + +int +CIDFont_type2_open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + char *fontname; + sfnt *sfont; + unsigned long 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, opt->index); + } else { + sfont = sfnt_open(fp); + } + + if (!sfont) { + DPXFCLOSE(fp); + return -1; + } + + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, opt->index); + break; + case SFNT_TYPE_TRUETYPE: + if (opt->index > 0) { + ERROR("Invalid TTC index (not TTC font): %s", name); + } else { + offset = 0; + } + break; + case SFNT_TYPE_DFONT: + offset = sfont->offset; + break; + default: + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) { + ERROR("Reading TrueType table directory failed."); + } + + { + char *shortname; + long 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); + } + validate_name(shortname, namelen); /* for SJIS, UTF-16, ... string */ + /* + * 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 = CIDFONT_TYPE2; + font->csi = NEW(1, CIDSysInfo); + if (opt->csi) { + if (cmap_csi) { + if (strcmp(opt->csi->registry, cmap_csi->registry) || + strcmp(opt->csi->ordering, cmap_csi->ordering)) { + WARN("CID character collection mismatched:\n"); + MESG("\tFont: %s-%s-%d\n", + opt->csi->registry, opt->csi->ordering, opt->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 (opt->csi->supplement < cmap_csi->supplement) { + WARN("Supplmement value in CIDSystemInfo increased."); + WARN("Some characters may not shown."); + opt->csi->supplement = cmap_csi->supplement; + } + } + font->csi->registry = NEW(strlen(opt->csi->registry)+1, char); + strcpy(font->csi->registry, opt->csi->registry); + font->csi->ordering = NEW(strlen(opt->csi->ordering)+1, char); + strcpy(font->csi->ordering, opt->csi->ordering); + font->csi->supplement = opt->csi->supplement; + } else if (cmap_csi) { + font->csi->registry = NEW(strlen(cmap_csi->registry)+1, char); + strcpy(font->csi->registry, cmap_csi->registry); + font->csi->ordering = NEW(strlen(cmap_csi->ordering)+1, char); + strcpy(font->csi->ordering, cmap_csi->ordering); + font->csi->supplement = cmap_csi->supplement; + } else { /* This means font's internal glyph ordering. */ + font->csi->registry = NEW(strlen("Adobe")+1, char); + strcpy(font->csi->registry, "Adobe"); + font->csi->ordering = NEW(strlen("Identity")+1, char); + strcpy(font->csi->ordering, "Identity"); + font->csi->supplement = 0; + } + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType2")); + + font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0); + if (!font->descriptor) { + ERROR("Could not obtain necessary font info."); + } + + if (opt->embed) { + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + } + + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(fontname)); + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + /* + * Don't write fontdict here. + * /Supplement in /CIDSystemInfo may change. + */ + + return 0; +} + +void +CIDFont_type2_release (CIDFont *font) +{ + return; +} diff --git a/Build/source/texk/dvipdf-x/src/dpxfile.c b/Build/source/texk/dvipdf-x/src/dpxfile.c new file mode 100644 index 00000000000..d6390641ed0 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/dpxfile.c @@ -0,0 +1,1153 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _MSC_VER +#include +#endif + +#include + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dpxutil.h" +#include "mfileio.h" + +#include "dpxfile.h" +#include "dpxcrypt.h" +#define MAX_KEY_LEN 16 + +#include +#include +#ifdef WIN32 +#include +#include +#else +#if HAVE_SYS_WAIT_H +#include +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(val) ((unsigned)(val) >> 8) +#endif +#ifndef WIFEXITED +#define WIFEXITED(val) (((val) & 255) == 0) +#endif +#endif + +static int verbose = 0; +int keep_cache = 0; + +void +dpx_file_set_verbose (void) +{ + verbose++; +} + + +/* Kpathsea library does not check file type. */ +static int qcheck_filetype (const char *fqpn, int type); + +/* For testing MIKTEX enabled compilation */ +#if defined(TESTCOMPILE) && !defined(MIKTEX) +# define MIKTEX 1 +# define PATH_SEP_CHR '/' +# define _MAX_PATH 256 + +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) > _MAX_PATH) + 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(PACKAGE); + + if (!fqpn) + return 0; + if (strlen(fqpn) > _MAX_PATH) + 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) > _MAX_PATH) + r = 0; + else { + strcpy(buf, fqpn); + r = 1; + } + RELEASE(fqpn); + + return r; +} + +#endif /* TESTCOMPILE */ + +#ifdef MIKTEX +#ifndef PATH_SEP_CHR +# define PATH_SEP_CHR '\\' +#endif +static char _tmpbuf[_MAX_PATH+1]; +#endif /* MIKTEX */ + +static int exec_spawn (char *cmd) +{ + char **cmdv, **qv; + char *p, *pp; + char buf[1024]; + int i, ret = -1; + + 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 + 2, sizeof (char *)); + p = cmd; + qv = cmdv; + while (*p) { + pp = buf; + if (*p == '"') { + p++; + while (*p != '"') { + if (*p == '\0') { + goto done; + } + *pp++ = *p++; + } + p++; + } else if (*p == '\'') { + p++; + while (*p != '\'') { + if (*p == '\0') { + goto done; + } + *pp++ = *p++; + } + p++; + } else { + while (*p != ' ' && *p != '\t' && *p) { + if (*p == '\'') { + p++; + while (*p != '\'') { + if (*p == '\0') { + goto done; + } + *pp++ = *p++; + } + p++; + } else { + *pp++ = *p++; + } + } + } + *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++; + } +#ifdef WIN32 + ret = spawnvp (_P_WAIT, *cmdv, (const char* const*) cmdv); +#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 +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(PACKAGE, q, _tmpbuf); + if (!r && strcmp(q, filename)) + r = miktex_find_app_input_file(PACKAGE, 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) +{ + kpse_format_info_type *fif; + kpse_format_info_type *fir; + if (verbose < 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."); +} + +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(PACKAGE); + + 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_opentype_file (const char *filename); +static char *dpx_find_truetype_file (const char *filename); +static char *dpx_find_type1_file (const char *filename); +static char *dpx_find_iccp_file (const char *filename); +static char *dpx_find_dfont_file (const char *filename); + +FILE * +dpx_open_file (const char *filename, int type) +{ + FILE *fp = NULL; + char *fqpn = NULL; + + switch (type) { + case DPX_RES_TYPE_FONTMAP: + fqpn = dpx_find_fontmap_file(filename); + 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; + default: + ERROR("Unknown resource type: %d", type); + 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 + 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, PACKAGE, + 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 + 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, PACKAGE, + 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) + /* Find in Acrobat's Resource/CMap dir */ + { + char _acrodir[_MAX_PATH+1]; + char *q; + int r; + + memset(_acrodir, 0, _MAX_PATH+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, _MAX_PATH+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 + 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 + 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 + 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 + 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 + if (fqpn) + insistupdate(filename, fqpn, fools[i], + kpse_program_text_format, kpse_enc_format); +#endif + } + RELEASE(q); + + return fqpn; +} + + +static char * +dpx_find_type1_file (const char *filename) +{ + char *fqpn = NULL; + + fqpn = kpse_find_file(filename, kpse_type1_format, 0); + if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_T1FONT)) { + RELEASE(fqpn); + fqpn = NULL; + } + + return fqpn; +} + + +static char * +dpx_find_truetype_file (const char *filename) +{ + char *fqpn = NULL; + + fqpn = kpse_find_file(filename, kpse_truetype_format, 0); + if (fqpn && !qcheck_filetype(fqpn, DPX_RES_TYPE_TTFONT)) { + RELEASE(fqpn); + fqpn = NULL; + } + + return fqpn; +} + + +static char * +dpx_find_opentype_file (const char *filename) +{ + char *fqpn = NULL; + char *q; + + q = ensuresuffix(filename, ".otf"); +#ifndef MIKTEX + fqpn = kpse_find_file(q, kpse_opentype_format, 0); + if (!fqpn) { +#endif + fqpn = dpx_foolsearch(PACKAGE, q, 0); +#ifndef MIKTEX + if (fqpn) + insistupdate(filename, fqpn, PACKAGE, + 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; +} + + +static 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 const char * +dpx_get_tmpdir (void) +{ +# ifdef WIN32 +# define __TMPDIR "." +# else /* WIN32 */ +# define __TMPDIR "/tmp" +#endif /* WIN32 */ + 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 */ + return _tmpd; +} + +#ifdef HAVE_MKSTEMP +# include +#endif + +#ifdef XETEX +char * +dpx_create_temp_file (void) +{ + char *tmp = NULL; + +#if defined(MIKTEX) + { + tmp = NEW(_MAX_PATH + 1, char); + miktex_create_temp_file_name(tmp); /* FIXME_FIXME */ + } +#elif defined(HAVE_MKSTEMP) +# define TEMPLATE "/dvipdfmx.XXXXXX" + { + const char *_tmpd; + int _fd = -1; + _tmpd = dpx_get_tmpdir(); + tmp = NEW(strlen(_tmpd) + strlen(TEMPLATE) + 1, char); + strcpy(tmp, _tmpd); + strcat(tmp, TEMPLATE); + _fd = mkstemp(tmp); + if (_fd != -1) +#ifdef WIN32 + _close(_fd); +#else + close(_fd); +#endif /* WIN32 */ + else { + RELEASE(tmp); + tmp = NULL; + } + } +#else /* use _tempnam or tmpnam */ + { +# ifdef WIN32 + const char *_tmpd; + char *p; + _tmpd = dpx_get_tmpdir(); + tmp = _tempnam (_tmpd, "dvipdfmx."); + 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; +} +#endif /* XETEX */ + +char * +dpx_create_fix_temp_file (const char *filename) +{ +#define PREFIX "dvipdfmx." + static const 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; id_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) +{ + const char *dir; + char *pathname; + DIR *dp; + struct dirent *de; + time_t limit; + + if (life == -2) { + 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) 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); + stat(pathname, &sb); + if (sb.st_mtime < limit) { + remove(pathname); + /* printf("remove: %s\n", pathname); */ + } + } + } + closedir(dp); + } + RELEASE(pathname); +} + +void +dpx_delete_temp_file (char *tmp, int force) +{ + if (!tmp) + return; + if (force || 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, + unsigned char 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); + } + case 'v': /* Version number, e.g. 1.4 */ { + char buf[16]; + sprintf(buf, "1.%hu", (unsigned short) version); + 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(*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; + unsigned long 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, int type) +{ + int r = 1; + FILE *fp; + + if (!fqpn) + 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; + } + MFCLOSE(fp); + + return r; +} + diff --git a/Build/source/texk/dvipdf-x/src/dpxfile.h b/Build/source/texk/dvipdf-x/src/dpxfile.h new file mode 100644 index 00000000000..df95b8c5411 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/dpxfile.h @@ -0,0 +1,65 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +#define DPX_RES_TYPE_FONTMAP 0x00 + +#define DPX_RES_TYPE_T1FONT 0x10 +#define DPX_RES_TYPE_TTFONT 0x11 +#define DPX_RES_TYPE_OTFONT 0x12 +#define DPX_RES_TYPE_PKFONT 0x13 +#define DPX_RES_TYPE_DFONT 0x14 + +#define DPX_RES_TYPE_ENC 0x20 +#define DPX_RES_TYPE_CMAP 0x21 +#define DPX_RES_TYPE_SFD 0x22 +#define DPX_RES_TYPE_AGL 0x23 + +#define DPX_RES_TYPE_ICCPROFILE 0x30 + +#define DPX_RES_TYPE_BINARY 0x40 +#define DPX_RES_TYPE_TEXT 0x41 + +#include "mfileio.h" +extern FILE *dpx_open_file (const char *filename, int type); + +#define DPXFOPEN(n,t) dpx_open_file((const char *)(n),(t)) +#define DPXFCLOSE(f) MFCLOSE((f)) + +extern void dpx_file_set_verbose (void); + +extern int dpx_file_apply_filter (const char *cmdtmpl, + const char *input, const char *output, + unsigned char 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 */ + +extern int keep_cache; +#endif /* _DPXFILE_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/dpxutil.c b/Build/source/texk/dvipdf-x/src/dpxutil.c new file mode 100644 index 00000000000..05e1b1b1485 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/dpxutil.c @@ -0,0 +1,639 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include +#include +#include +#include + +#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; +} + +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; +} + +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); +} + +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; +} + +/* Overflowed value is set to invalid char. */ +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; +} + +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; +} + +void +skip_white_spaces (unsigned char **s, unsigned char *endptr) +{ + while (*s < endptr) + if (!is_space(**s)) + break; + else + (*s)++; +} + +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; +} + +long 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; +} + +void +ht_modify_table (struct ht_table *ht, + const void *key, int keylen, void *value, int mode) +{ + 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) { + switch (mode) { + case HT_NEW: + ASSERT(0); /* duplicates not allowed in this mode */ + break; + case HT_REPLACE: { + if (hent->value && ht->hval_free_fn) + ht->hval_free_fn(hent->value); + hent->value = value; + break; + } + case HT_KEEP: + ht->hval_free_fn(value); + break; + } + } 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++; + } +} + +int +ht_set_iter (struct ht_table *ht, struct ht_iter *iter) +{ + int i; + + ASSERT(ht && ht->table && 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(p[0]); + i++, p++) + c = (c << 4) + + (isdigit(p[0]) ? + p[0] - '0' : + (islower(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/dvipdf-x/src/dpxutil.h b/Build/source/texk/dvipdf-x/src/dpxutil.h new file mode 100644 index 00000000000..46273759836 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/dpxutil.h @@ -0,0 +1,113 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +#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)) + +#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) == '%') +#endif + +extern void skip_white_spaces (unsigned char **s, unsigned char *endptr); +extern int xtoi (char c); +extern int getxpair (unsigned char **str); +extern int putxpair (unsigned char c, char **str); +extern int sputx (unsigned char c, char **buf, char *endptr); + +extern unsigned char ostrtouc (unsigned char **inbuf, + unsigned char *inbufend, unsigned char *valid); +extern unsigned char esctouc (unsigned char **inbuf, + unsigned char *inbufend, unsigned char *valid); + +#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 { + long count; + hval_free_func hval_free_fn; + struct ht_entry *table[HASH_TABLE_SIZE]; +}; + +#define HT_NEW 0 +#define HT_REPLACE 1 +#define HT_KEEP 2 + +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 long ht_table_size (struct ht_table *ht); +extern void *ht_lookup_table (struct ht_table *ht, + const void *key, int keylen); +extern void ht_modify_table (struct ht_table *ht, + const void *key, int keylen, + void *value, int mode); +#define ht_append_table(ht, key, keylen, value) \ + ht_modify_table(ht, key, keylen, value, HT_NEW) +#define ht_insert_table(ht, key, keylen, value) \ + ht_modify_table(ht, key, keylen, value, HT_REPLACE) +extern int ht_remove_table (struct ht_table *ht, + const void *key, int keylen); + +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/dvipdf-x/src/dvi.c b/Build/source/texk/dvipdf-x/src/dvi.c new file mode 100644 index 00000000000..62a315f4831 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/dvi.c @@ -0,0 +1,1967 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "numbers.h" + +#include "pdfdev.h" +#include "pdfdoc.h" +#include "pdfparse.h" +#include "pdfencrypt.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" + +#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 unsigned long *page_loc = NULL; +static UNSIGNED_PAIR num_pages = 0; + +static unsigned long dvi_file_size = 0; + +static struct dvi_header +{ + UNSIGNED_QUAD unit_num; + UNSIGNED_QUAD unit_den; + UNSIGNED_QUAD mag; + UNSIGNED_QUAD media_width, media_height; + UNSIGNED_PAIR 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; + +#define PHYSICAL 1 +#define VIRTUAL 2 +#define SUBFONT 3 +#define DVI 1 +#define VF 2 + +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 */ +} *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 +{ + long 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; +} *def_fonts = NULL; + +static int num_def_fonts = 0, max_def_fonts = 0; +static int compute_boxes = 0, link_annot = 1; +static int verbose = 0; + +void +dvi_set_verbose (void) +{ + verbose++; + subfont_set_verbose(); + tfm_set_verbose(); + vf_set_verbose (); + spc_set_verbose(); +} + +unsigned +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 long +find_post (void) +{ + long current; + int ch; + + /* First find end of file */ + dvi_file_size = file_size(dvi_file); + current = dvi_file_size; + + /* Scan backwards through PADDING */ + do { + current--; + seek_absolute(dvi_file, current); + } 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)) { + MESG("DVI ID = %d\n", ch); + ERROR(invalid_signature); + } + + /* Make sure post_post is really there */ + current = current - 5; + seek_absolute(dvi_file, current); + 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); + seek_absolute(dvi_file, current); + if ((ch = fgetc(dvi_file)) != POST) { + MESG("Found %d where post_post opcode should be\n", ch); + ERROR(invalid_signature); + } + + return current; +} + +static void +get_page_info (long post_location) +{ + int i; + + seek_absolute(dvi_file, post_location + 27); + num_pages = get_unsigned_pair(dvi_file); + if (num_pages == 0) { + ERROR("Page count is 0!"); + } + if (verbose > 2) { + MESG("Page count:\t %4d\n", num_pages); + } + + page_loc = NEW(num_pages, unsigned long); + + seek_absolute(dvi_file, post_location + 1); + 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--) { + seek_absolute(dvi_file, page_loc[i+1] + 41); + 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 (long post_location) +{ + seek_absolute(dvi_file, post_location + 5); + + 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 (verbose > 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); + } +} + +const char * +dvi_comment (void) +{ + return dvi_info.comment; +} + +static void +read_font_record (SIGNED_QUAD tex_id) +{ + UNSIGNED_BYTE dir_length, name_length; + UNSIGNED_QUAD 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); + } + get_unsigned_quad(dvi_file); + point_size = get_unsigned_quad(dvi_file); + design_size = get_unsigned_quad(dvi_file); + 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'; + 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; + num_def_fonts++; + + return; +} + +static void +get_dvi_fonts (long post_location) +{ + UNSIGNED_BYTE code; + SIGNED_QUAD tex_id = 0; + + seek_absolute(dvi_file, post_location + 29); + while ((code = get_unsigned_byte(dvi_file)) != POST_POST) { + switch (code) { + case FNT_DEF1: + tex_id = get_unsigned_byte(dvi_file); + break; + case FNT_DEF2: + tex_id = get_unsigned_pair(dvi_file); + break; + case FNT_DEF3: + tex_id = get_unsigned_triple(dvi_file); + break; + case FNT_DEF4: + tex_id = get_signed_quad(dvi_file); + break; + default: + MESG("Unexpected op code: %3d\n", code); + ERROR(invalid_signature); + } + read_font_record(tex_id); + } + if (verbose > 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=%5ld, ", + 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) +{ + UNSIGNED_BYTE length; + + seek_absolute(dvi_file, 14); + 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 (verbose) { + 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 +{ + SIGNED_QUAD h, v, w, x, y, z, 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 */ + 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; +} + +void +dvi_do_special (const void *buffer, UNSIGNED_QUAD size) +{ + double x_user, y_user, mag; + const char *p; + + if (size > 0x7fffffffUL) { + WARN("Special more than %ul bytes???", size); + return; + } + + 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, (long) size, x_user, y_user, mag) < 0) { + if (verbose) { + dump(p, p + size); + } + } + + return; +} + +#if 0 +double +dvi_unit_size (void) +{ + return dvi2pts; +} +#endif + + +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 (verbose) + 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); + } + + /* 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 (verbose) + 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 (verbose) + 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) { + 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..."); + } + loaded_fonts[cur_id].type = PHYSICAL; + loaded_fonts[cur_id].font_id = font_id; + + if (verbose) + 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 (SIGNED_QUAD x, SIGNED_QUAD y) +{ + dvi_state.h = x; + dvi_state.v = y; +} + +void dvi_right (SIGNED_QUAD x) +{ + 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; + } +} + +void dvi_down (SIGNED_QUAD y) +{ + 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; + } +} + +/* Please remove this. + * Optimization for 8-bit encodings. + */ +static void +do_string (unsigned char *s, int len) +{ + struct loaded_font *font; + spt_t width, height, depth; + int i; + + if (current_font < 0) + ERROR("No font selected!"); + + font = &loaded_fonts[current_font]; + + width = tfm_string_width(font->tfm_id, s, len); + width = sqxfw(font->size, width); + + switch (font->type) { + case PHYSICAL: + if (font->subfont_id < 0) { + pdf_dev_set_string(dvi_state.h, -dvi_state.v, s, len, + width, font->font_id, 1); + if (compute_boxes && link_annot && + marked_depth >= tagged_depth) { + pdf_rect rect; + + height = tfm_string_height(font->tfm_id, s, len); + depth = tfm_string_depth (font->tfm_id, s, len); + height = sqxfw(font->size, height); + depth = sqxfw(font->size, depth); + + pdf_dev_set_rect (&rect, dvi_state.h, -dvi_state.v, + width, height, depth); + pdf_doc_expand_box(&rect); + } + } else { /* Subfonts */ + dvi_push(); + for (i = 0; i < len; i++) { + dvi_set(s[i]); + } + dvi_pop(); + } + break; + case VIRTUAL: + dvi_push(); + for (i = 0; i < len; i++) { + dvi_set(s[i]); + } + dvi_pop(); + } + switch (dvi_state.d) { + case 0: + dvi_state.h += width; break; + case 1: + dvi_state.v += width; break; + case 3: + dvi_state.v -= width; 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 (SIGNED_QUAD ch) +{ + struct loaded_font *font; + spt_t width, height, depth; + unsigned char wbuf[4]; + + 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]; + + width = tfm_get_fw_width(font->tfm_id, ch); + width = sqxfw(font->size, width); + + switch (font->type) { + case PHYSICAL: + if (ch > 65535) { /* _FIXME_ */ + wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff; + wbuf[1] = UTF32toUTF16HS(ch) & 0xff; + wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff; + wbuf[3] = UTF32toUTF16LS(ch) & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4, + width, font->font_id, 2); + } else if (ch > 255) { /* _FIXME_ */ + wbuf[0] = (ch >> 8) & 0xff; + wbuf[1] = ch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else if (font->subfont_id >= 0) { + unsigned short uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch); + wbuf[0] = (uch >> 8) & 0xff; + wbuf[1] = uch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else { + wbuf[0] = (unsigned char) ch; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1, + width, font->font_id, 1); + } + if (compute_boxes && link_annot && + marked_depth >= tagged_depth) { + 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); + + pdf_dev_set_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; + } + switch (dvi_state.d) { + case 0: + dvi_state.h += width; break; + case 1: + dvi_state.v += width; break; + case 3: + dvi_state.v -= width; break; + } +} + +void +dvi_put (SIGNED_QUAD ch) +{ + struct loaded_font *font; + spt_t width, height, depth; + unsigned char wbuf[4]; + + if (current_font < 0) { + ERROR("No font selected!"); + } + + font = &loaded_fonts[current_font]; + + 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_ */ + wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff; + wbuf[1] = UTF32toUTF16HS(ch) & 0xff; + wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff; + wbuf[3] = UTF32toUTF16LS(ch) & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4, + width, font->font_id, 2); + } else if (ch > 255) { /* _FIXME_ */ + wbuf[0] = (ch >> 8) & 0xff; + wbuf[1] = ch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else if (font->subfont_id >= 0) { + unsigned int uch; + + uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch); + wbuf[0] = (uch >> 8) & 0xff; + wbuf[1] = uch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else { + wbuf[0] = (unsigned char) ch; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1, + width, font->font_id, 1); + } + if (compute_boxes && link_annot && + marked_depth >= tagged_depth) { + 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); + + pdf_dev_set_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 (SIGNED_QUAD width, SIGNED_QUAD height) +{ + do_moveto(dvi_state.h, dvi_state.v); + + switch (dvi_state.d) { + case 0: + pdf_dev_set_rule(dvi_state.h, -dvi_state.v, width, height); + break; + case 1: + pdf_dev_set_rule(dvi_state.h, -dvi_state.v - width, height, width); + break; + case 3: + pdf_dev_set_rule(dvi_state.h - height, -dvi_state.v , height, width); + break; + } +} + +void +dvi_dir (UNSIGNED_BYTE dir) /* how? */ +{ + fprintf(stderr, " > dvi_dir %d\n", dir); + dvi_state.d = dir; + pdf_dev_set_dirmode(dvi_state.d); /* 0: horizontal, 1: vertical */ +} + +static void +do_set1 (void) +{ + dvi_set(get_unsigned_byte(dvi_file)); +} + +static void +do_set2 (void) +{ + dvi_set(get_unsigned_pair(dvi_file)); +} + +static void +do_set3 (void) +{ + dvi_set(get_unsigned_triple(dvi_file)); +} + +static void +do_setrule (void) +{ + SIGNED_QUAD width, height; + + height = get_signed_quad(dvi_file); + width = get_signed_quad(dvi_file); + if (width > 0 && height > 0) { + dvi_rule(width, height); + } + dvi_right(width); +} + +static void +do_putrule (void) +{ + SIGNED_QUAD width, height; + + height = get_signed_quad (dvi_file); + width = get_signed_quad (dvi_file); + if (width > 0 && height > 0) { + dvi_rule(width, height); + } +} + +static void +do_put1 (void) +{ + dvi_put(get_unsigned_byte(dvi_file)); +} + +static void +do_put2 (void) +{ + dvi_put(get_unsigned_pair(dvi_file)); +} + +static void +do_put3 (void) +{ + dvi_put(get_unsigned_triple(dvi_file)); +} + +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: vertical */ +} + + +static void +do_right1 (void) +{ + dvi_right(get_signed_byte(dvi_file)); +} + +static void +do_right2 (void) +{ + dvi_right(get_signed_pair(dvi_file)); +} + +static void +do_right3 (void) +{ + dvi_right(get_signed_triple(dvi_file)); +} + +static void +do_right4 (void) +{ + dvi_right(get_signed_quad(dvi_file)); +} + +void +dvi_w (SIGNED_QUAD ch) +{ + dvi_state.w = ch; + dvi_right(ch); +} + +void +dvi_w0 (void) +{ + dvi_right(dvi_state.w); +} + +static void +do_w1 (void) +{ + dvi_w(get_signed_byte(dvi_file)); +} + +static void +do_w2 (void) +{ + dvi_w(get_signed_pair(dvi_file)); +} + +static void +do_w3 (void) +{ + dvi_w(get_signed_triple(dvi_file)); +} + +static void +do_w4 (void) +{ + dvi_w(get_signed_quad(dvi_file)); +} + +void +dvi_x (SIGNED_QUAD ch) +{ + dvi_state.x = ch; + dvi_right(ch); +} + +void +dvi_x0 (void) +{ + dvi_right(dvi_state.x); +} + +static void +do_x1 (void) +{ + dvi_x(get_signed_byte(dvi_file)); +} + +static void +do_x2 (void) +{ + dvi_x(get_signed_pair(dvi_file)); +} + +static void +do_x3 (void) +{ + dvi_x(get_signed_triple(dvi_file)); +} + +static void +do_x4 (void) +{ + dvi_x(get_signed_quad(dvi_file)); +} + +static void +do_down1 (void) +{ + dvi_down(get_signed_byte(dvi_file)); +} + +static void +do_down2 (void) +{ + dvi_down(get_signed_pair(dvi_file)); +} + +static void +do_down3 (void) +{ + dvi_down(get_signed_triple(dvi_file)); +} + +static void +do_down4 (void) +{ + dvi_down(get_signed_quad(dvi_file)); +} + +void +dvi_y (SIGNED_QUAD ch) +{ + dvi_state.y = ch; + dvi_down(ch); +} + +void +dvi_y0 (void) +{ + dvi_down(dvi_state.y); +} + +static +void do_y1 (void) +{ + dvi_y(get_signed_byte(dvi_file)); +} + +static +void do_y2 (void) +{ + dvi_y(get_signed_pair(dvi_file)); +} + +static +void do_y3 (void) +{ + dvi_y(get_signed_triple(dvi_file)); +} + +static +void do_y4 (void) +{ + dvi_y(get_signed_quad(dvi_file)); +} + +void +dvi_z (SIGNED_QUAD ch) +{ + dvi_state.z = ch; + dvi_down(ch); +} + +void +dvi_z0 (void) +{ + dvi_down(dvi_state.z); +} + +static void +do_z1 (void) +{ + dvi_z(get_signed_byte(dvi_file)); +} + +static void +do_z2 (void) +{ + dvi_z(get_signed_pair(dvi_file)); +} + +static void +do_z3 (void) +{ + dvi_z(get_signed_triple(dvi_file)); +} + +static void +do_z4 (void) +{ + dvi_z(get_signed_quad(dvi_file)); +} + +static void +do_fntdef (void) +{ + int area_len, name_len, i; + + get_signed_quad(dvi_file); + get_signed_quad(dvi_file); + get_signed_quad(dvi_file); + area_len = get_unsigned_byte(dvi_file); + name_len = get_unsigned_byte(dvi_file); + for (i = 0; i < area_len + name_len; i++) { + get_unsigned_byte(dvi_file); + } +} + +static void +do_fntdef1 (void) +{ + get_unsigned_byte(dvi_file); + do_fntdef(); +} + +static void +do_fntdef2 (void) +{ + get_unsigned_pair(dvi_file); + do_fntdef(); +} + +static void +do_fntdef3 (void) +{ + get_unsigned_triple(dvi_file); + do_fntdef(); +} + +static void +do_fntdef4 (void) +{ + get_signed_quad(dvi_file); + do_fntdef(); +} + +void +dvi_set_font (int font_id) +{ + current_font = font_id; +} + +static void +do_fnt (SIGNED_QUAD 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=%ld", tex_id); + } + + if (!def_fonts[i].used) { + int font_id; + + font_id = dvi_locate_font(def_fonts[i].font_name, def_fonts[i].point_size); + 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_fnt1 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_unsigned_byte(dvi_file); + do_fnt(tex_id); +} + +static void +do_fnt2 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_unsigned_pair(dvi_file); + do_fnt(tex_id); +} + +static void +do_fnt3 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_unsigned_triple(dvi_file); + do_fnt(tex_id); +} + +static void +do_fnt4 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_signed_quad(dvi_file); + do_fnt(tex_id); +} + +static void +do_xxx (UNSIGNED_QUAD size) +{ + UNSIGNED_QUAD i; + Ubyte *buffer; + + buffer = NEW(size+1, Ubyte); + for (i = 0; i < size; i++) { + buffer[i] = get_unsigned_byte(dvi_file); + } + dvi_do_special(buffer, size); + RELEASE(buffer); +} + +static void +do_xxx1 (void) +{ + SIGNED_QUAD size; + + size = get_unsigned_byte(dvi_file); + do_xxx(size); +} + +static void +do_xxx2 (void) +{ + SIGNED_QUAD size; + + size = get_unsigned_pair(dvi_file); + do_xxx(size); +} + +static void +do_xxx3 (void) +{ + SIGNED_QUAD size; + + size = get_unsigned_triple(dvi_file); + do_xxx(size); +} + +static void +do_xxx4 (void) +{ + SIGNED_QUAD size; + + size = get_unsigned_quad(dvi_file); + do_xxx(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++) { + get_signed_quad(dvi_file); + } + /* Ignore previous page pointer since we have already + * saved this information + */ + get_signed_quad(dvi_file); + 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_unsigned_byte(dvi_file); + pdf_dev_set_dirmode(dvi_state.d); /* 0: horizontal, 1: vertical */ +} + +/* Note to be absolutely certain that the string escape buffer doesn't + * hit its limit, FORMAT_BUF_SIZE should set to 4 times S_BUFFER_SIZE + * in pdfobj.c. Is there any application that genenerate words with + * 1k characters? + */ + +#define SBUF_SIZE 1024 + +/* Most of the work of actually interpreting + * the dvi file is here. + */ +void +dvi_do_page (unsigned n, + double paper_width, double paper_height, + double hmargin, double vmargin) +{ + unsigned char opcode; + unsigned char sbuf[SBUF_SIZE]; + unsigned int slen = 0; + + if (!page_loc || n >= num_pages) + ERROR("Tried to process non-existent page: %ld", n); + + /* DVI coordinate */ + dev_origin_x = hmargin; + dev_origin_y = paper_height - vmargin; + + seek_absolute(dvi_file, page_loc[n]); + + dvi_stack_depth = 0; + for (;;) { + /* The most likely opcodes are individual setchars. + * These are buffered for speed. */ + slen = 0; + while ((opcode = fgetc(dvi_file)) <= SET_CHAR_127 && + slen < SBUF_SIZE) { + sbuf[slen++] = opcode; + } + if (slen > 0) { + do_string(sbuf, slen); + } + if (slen == SBUF_SIZE) + 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: do_set1(); break; + case SET2: do_set2(); break; + case SET3: do_set3(); break; + case SET4: + ERROR("Multibyte (>24 bits) character not supported!"); + break; + + case SET_RULE: + do_setrule(); + break; + + case PUT1: do_put1(); break; + case PUT2: do_put2(); break; + case PUT3: do_put3(); break; + case PUT4: + ERROR ("Multibyte character (>24 bits) not supported!"); + break; + + case PUT_RULE: + do_putrule(); + break; + + case NOP: + break; + + case BOP: + do_bop(); + break; + case EOP: + do_eop(); + return; + break; + + case PUSH: + dvi_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(); + /* Above explanation holds for following line too */ + dvi_mark_depth(); + break; + + case RIGHT1: do_right1(); break; + case RIGHT2: do_right2(); break; + case RIGHT3: do_right3(); break; + case RIGHT4: do_right4(); break; + + case W0: dvi_w0(); break; + case W1: do_w1 (); break; + case W2: do_w2 (); break; + case W3: do_w3 (); break; + case W4: do_w4 (); break; + + case X0: dvi_x0(); break; + case X1: do_x1 (); break; + case X2: do_x2 (); break; + case X3: do_x3 (); break; + case X4: do_x4 (); break; + + case DOWN1: do_down1(); break; + case DOWN2: do_down2(); break; + case DOWN3: do_down3(); break; + case DOWN4: do_down4(); break; + + case Y0: dvi_y0(); break; + case Y1: do_y1 (); break; + case Y2: do_y2 (); break; + case Y3: do_y3 (); break; + case Y4: do_y4 (); break; + + case Z0: dvi_z0(); break; + case Z1: do_z1 (); break; + case Z2: do_z2 (); break; + case Z3: do_z3 (); break; + case Z4: do_z4 (); break; + + case FNT1: do_fnt1(); break; + case FNT2: do_fnt2(); break; + case FNT3: do_fnt3(); break; + case FNT4: do_fnt4(); break; + + /* Specials */ + case XXX1: do_xxx1(); break; + case XXX2: do_xxx2(); break; + case XXX3: do_xxx3(); break; + case XXX4: do_xxx4(); break; + + /* Font definition - skipped. */ + case FNT_DEF1: do_fntdef1(); break; + case FNT_DEF2: do_fntdef2(); break; + case FNT_DEF3: do_fntdef3(); break; + case FNT_DEF4: do_fntdef4(); break; + + /* pTeX extension */ + case PTEXDIR: + do_dir(); + break; + + case PRE: case POST: case POST_POST: + ERROR("Unexpected preamble or postamble in dvi file"); + break; + default: + ERROR("Unexpected opcode or DVI file ended prematurely"); + } + } +} + +double +dvi_init (const char *dvi_filename, double mag) +{ + long post_location; + + dvi_file = MFOPEN(dvi_filename, FOPEN_RBIN_MODE); + if (!dvi_file) { + ERROR("Could not open specified DVI 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(); + + return dvi2pts; +} + +void +dvi_close (void) +{ + int i; + + /* 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; + + if (loaded_fonts) + RELEASE(loaded_fonts); + loaded_fonts = NULL; + num_loaded_fonts = 0; + + vf_close_all_fonts(); + tfm_close_all (); +} + +/* 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" + +/* This need to allow 'true' prefix for unit and + * length value must be divided by current magnification. + */ +static int +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 + "pt", "in", "cm", "mm", "bp", + 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); + + q = parse_c_ident(&p, endptr); + if (q) { + char *qq = q; + if (strlen(q) > strlen("true") && + !memcmp(q, "true", strlen("true"))) { + u /= mag != 0.0 ? mag : 1.0; /* inverse magnify */ + q += strlen("true"); + } + 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; + default: + WARN("Unknown unit of measure: %s", qq); + error = -1; + break; + } + RELEASE(qq); + } + + *vp = v * u; *pp = p; + return error; +} + + +static int +scan_special (double *wd, double *ht, double *xo, double *yo, char *lm, + unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw, + const char *buf, UNSIGNED_QUAD size) +{ + char *q; + const char *p = buf, *endptr; + int ns_pdf = 0, error = 0; + + 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; + } + } + 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 = read_length(wd, dvi_tell_mag(), &p, endptr); + if (!error) + *wd *= dvi_tell_mag(); + } else if (!strcmp(kp, "height")) { + error = read_length(ht, dvi_tell_mag(), &p, endptr); + if (!error) + *ht *= dvi_tell_mag(); + } else if (!strcmp(kp, "xoffset")) { + error = read_length(xo, dvi_tell_mag(), &p, endptr); + if (!error) + *xo *= dvi_tell_mag(); + } else if (!strcmp(kp, "yoffset")) { + error = read_length(yo, dvi_tell_mag(), &p, endptr); + if (!error) + *yo *= dvi_tell_mag(); + } + 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 = read_length(wd, 1.0, &p, endptr); + if (!error) { + skip_white(&p, endptr); + if (p < endptr && *p == ',') { + p++; skip_white(&p, endptr); + } + error = read_length(ht, 1.0, &p, endptr); + skip_white(&p, endptr); + } + if (!error && qchr) { /* Check if properly quoted */ + if (p >= endptr || *p != qchr) + error = -1; + } + } 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 = (unsigned)strtol(kv, NULL, 10); + RELEASE(kv); + } + } else if (ns_pdf && !strcmp(q, "encrypt") && do_enc) { + *do_enc = 1; + *owner_pw = *user_pw = 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))) { + strncpy(owner_pw, pdf_string_value(obj), MAX_PWD_LEN); + pdf_release_obj(obj); + } else + error = -1; + } else if (!strcmp(kp, "userpw")) { + if ((obj = parse_pdf_string(&p, endptr))) { + strncpy(user_pw, pdf_string_value(obj), MAX_PWD_LEN); + 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); + } + } + RELEASE(q); + } + + return error; +} + + +void +dvi_scan_specials (unsigned page_no, + double *page_width, double *page_height, + double *x_offset, double *y_offset, char *landscape, + unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw) +{ + FILE *fp = dvi_file; + long offset; + unsigned char opcode; + + if (page_no >= num_pages) + ERROR("Invalid page number: %u", page_no); + offset = page_loc[page_no]; + + seek_absolute(fp, offset); + while ((opcode = fgetc(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) { + UNSIGNED_QUAD size = 0UL; + char buf[1024]; + switch (opcode) { + case XXX1: size = get_unsigned_byte(fp); break; + case XXX2: size = get_unsigned_pair(fp); break; + case XXX3: size = get_unsigned_triple(fp); break; + case XXX4: size = get_unsigned_quad(fp); break; + } + size = MIN(size, 1024); + 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, + minorversion, do_enc, key_bits, permission, owner_pw, user_pw, buf, size)) + WARN("Reading special command failed: \"%.*s\"", size, buf); + continue; + } + + /* Skipping... */ + switch (opcode) { + case BOP: + seek_relative(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_unsigned_byte(fp); + break; + + case SET2: case PUT2: case RIGHT2: case DOWN2: + case W2: case X2: case Y2: case Z2: case FNT2: + get_signed_pair(fp); + break; + + case SET3: case PUT3: case RIGHT3: case DOWN3: + case W3: case X3: case Y3: case Z3: case FNT3: + get_signed_triple(fp); + break; + + case SET4: case PUT4: case RIGHT4: case DOWN4: + case W4: case X4: case Y4: case Z4: case FNT4: + get_signed_quad(fp); + break; + + case SET_RULE: case PUT_RULE: + seek_relative(fp, 8); + break; + + case FNT_DEF1: do_fntdef1(); break; + case FNT_DEF2: do_fntdef2(); break; + case FNT_DEF3: do_fntdef3(); break; + case FNT_DEF4: do_fntdef4(); break; + + case PTEXDIR: + get_unsigned_byte(fp); + break; + + default: /* case PRE: case POST: case POST_POST: and others */ + ERROR("Unexpected opcode %d at pos=0x%x", opcode, tell_position(fp)); + break; + } + } + + return; +} + diff --git a/Build/source/texk/dvipdf-x/src/dvi.h b/Build/source/texk/dvipdf-x/src/dvi.h new file mode 100644 index 00000000000..1e9636f8195 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/dvi.h @@ -0,0 +1,96 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +extern void dvi_set_verbose (void); + +/* returns scale (dvi2pts) */ +extern double dvi_init (const char *dvi_filename, double mag); +extern void dvi_close (void); /* Closes data structures created by dvi_open */ + +extern double dvi_tell_mag (void); +#if 0 +extern double dvi_unit_size (void); +#endif +extern double dvi_dev_xpos (void); +extern double dvi_dev_ypos (void); +extern unsigned 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 (SIGNED_QUAD ch); +extern void dvi_rule (SIGNED_QUAD width, SIGNED_QUAD height); + +extern void dvi_right (SIGNED_QUAD x); +extern void dvi_put (SIGNED_QUAD ch); +extern void dvi_push (void); +extern void dvi_pop (void); +extern void dvi_w0 (void); +extern void dvi_w (SIGNED_QUAD ch); +extern void dvi_x0 (void); +extern void dvi_x (SIGNED_QUAD ch); +extern void dvi_down (SIGNED_QUAD y); +extern void dvi_y (SIGNED_QUAD ch); +extern void dvi_y0 (void); +extern void dvi_z (SIGNED_QUAD ch); +extern void dvi_z0 (void); +extern void dvi_dir (UNSIGNED_BYTE dir); + +extern void dvi_do_page (unsigned page_no, + double paper_width, double paper_height, + double x_offset, double y_offset); +extern void dvi_scan_specials (unsigned page_no, + double *width, double *height, + double *x_offset, double *y_offset, + char *landscape, unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw); +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); +/* 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, UNSIGNED_QUAD size); + +#endif /* _DVI_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/dvipdfmx.c b/Build/source/texk/dvipdf-x/src/dvipdfmx.c new file mode 100644 index 00000000000..cde17f051a6 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/dvipdfmx.c @@ -0,0 +1,1026 @@ +/* + + This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks. + + Copyright (C) 2009-2013 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "system.h" +#include "mem.h" + +#include "dpxconf.h" +#include "dpxfile.h" +#include "dpxutil.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 "xbb.h" + +#include "error.h" + +int compat_mode = 0; /* 0 = dvipdfmx, 1 = dvipdfm */ + +static int verbose = 0; + +static int mp_mode = 0; + +static long 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) + +static char ignore_colors = 0; +static double annot_grow = 0.0; +static int bookmark_open = 0; +static double mag = 1.0; +static int font_dpi = 600; +static int really_quiet = 0; +/* + * Precision is essentially limited to 0.01pt. + * See, dev_set_string() in pdfdev.c. + */ +static int pdfdecimaldigits = 2; + +/* 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; + +/* Encryption */ +static int do_encryption = 0; +static unsigned key_bits = 40; +static unsigned permission = 0x003C; + +/* Page device */ +static double paper_width = 595.0; +static double paper_height = 842.0; +static double x_offset = 72.0; +static double y_offset = 72.0; +static char landscape_mode = 0; + + +char *dvi_filename = NULL, *pdf_filename = NULL; + +static void +read_config_file (const char *config); + +#ifdef WIN32 +#define STRN_CMP strncasecmp +#else +#define STRN_CMP strncmp +#endif + +static void +set_default_pdf_filename(void) +{ + const char *dvi_base; + + dvi_base = xbasename(dvi_filename); + if (mp_mode && + strlen(dvi_base) > 4 && + !STRN_CMP(".mps", dvi_base + strlen(dvi_base) - 4, 4)) { + pdf_filename = NEW(strlen(dvi_base)+1, char); + strncpy(pdf_filename, dvi_base, strlen(dvi_base) - 4); + pdf_filename[strlen(dvi_base)-4] = '\0'; + } else if (strlen(dvi_base) > 4 && + !STRN_CMP(".dvi", dvi_base+strlen(dvi_base)-4, 4)) { + pdf_filename = NEW(strlen(dvi_base)+1, char); + strncpy(pdf_filename, dvi_base, strlen(dvi_base)-4); + pdf_filename[strlen(dvi_base)-4] = '\0'; + } else { + pdf_filename = NEW(strlen(dvi_base)+5, char); + strcpy(pdf_filename, dvi_base); + } + + strcat (pdf_filename, ".pdf"); +} + +static void +show_version (void) +{ + fprintf(stdout, "\nThis is %s-%s by the DVIPDFMx project team,\n", PACKAGE, VERSION); + fprintf(stdout, "modified for TeX Live,\n"); + fprintf(stdout, "an extended version of dvipdfm-0.13.2c developed by Mark A. Wicks.\n"); + fprintf(stdout, "\nCopyright (C) 2002-2013 by the DVIPDFMx project team\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) +{ + fprintf(stdout, "\nUsage: dvipdfmx [options] dvifile\n"); + fprintf(stdout, "-c \t\tIgnore color specials (for B&W printing)\n"); + fprintf(stdout, "-d number\tSet PDF decimal digits (0-5) [2]\n"); + fprintf(stdout, "-f filename\tSet font map file name [cid-x.map]\n"); + fprintf(stdout, "-g dimension\tAnnotation \"grow\" amount [0.0in]\n"); + fprintf(stdout, "-l \t\tLandscape mode\n"); + fprintf(stdout, "-m number\tSet additional magnification\n"); + fprintf(stdout, "-o filename\tSet output file name [dvifile.pdf]\n"); + fprintf(stdout, "-p papersize\tSet papersize [a4]\n"); + fprintf(stdout, "-q \t\tBe quiet\n"); + fprintf(stdout, "-r resolution\tSet resolution (in DPI) for raster fonts [600]\n"); + fprintf(stdout, "-s pages\tSelect page ranges (-)\n"); + fprintf(stdout, "-t \t\tEmbed thumbnail images of PNG format [dvifile.1] \n"); + fprintf(stdout, "-x dimension\tSet horizontal offset [1.0in]\n"); + fprintf(stdout, "-y dimension\tSet vertical offset [1.0in]\n"); + fprintf(stdout, "-z number \tSet zlib compression level (0-9) [9]\n"); + + fprintf(stdout, "-v \t\tBe verbose\n"); + fprintf(stdout, "-vv\t\tBe more verbose\n"); + fprintf(stdout, "-C number\tSpecify miscellaneous option flags [0]:\n"); + fprintf(stdout, "\t\t 0x0001 reserved\n"); + fprintf(stdout, "\t\t 0x0002 Use semi-transparent filling for tpic shading command,\n"); + fprintf(stdout, "\t\t\t instead of opaque gray color. (requires PDF 1.4)\n"); + fprintf(stdout, "\t\t 0x0004 Treat all CIDFont as fixed-pitch font.\n"); + fprintf(stdout, "\t\t 0x0008 Do not replace duplicate fontmap entries.\n"); + fprintf(stdout, "\t\t 0x0010 Do not optimize PDF destinations.\n"); + fprintf(stdout, "\t\tPositive values are always ORed with previously given flags.\n"); + fprintf(stdout, "\t\tAnd negative values replace old values.\n"); + fprintf(stdout, "-D template\tPS->PDF conversion command line template [none]\n"); + fprintf(stdout, "-E \t\tEnable DVIPDFM emulation mode\n"); + fprintf(stdout, "-I number\tImage cache life in hours [-2]\n"); + fprintf(stdout, " \t 0: erase all old images and leave new images\n"); + fprintf(stdout, " \t-1: erase all old images and also erase new images\n"); + fprintf(stdout, " \t-2: ignore image cache\n"); + fprintf(stdout, "-K number\tEncryption key length [40]\n"); + fprintf(stdout, "-O number\tSet maximum depth of open bookmark items [0]\n"); + fprintf(stdout, "-P number\tSet permission flags for PDF encryption [0x003C]\n"); + fprintf(stdout, "-S \t\tEnable PDF encryption\n"); + fprintf(stdout, "-V number\tSet PDF minor version [4]\n"); + fprintf(stdout, "\nAll dimensions entered on the command line are \"true\" TeX dimensions.\n"); + fprintf(stdout, "Argument of \"-s\" lists physical page ranges separated by commas, e.g., \"-s 1-3,5-6\"\n"); + fprintf(stdout, "Papersize is specified by paper format (e.g., \"a4\") or by w,h (e.g., \"20cm,30cm\").\n"); +} + +static void +usage (void) +{ + if (really_quiet) + return; + fprintf(stdout, "\nTry \"dvipdfmx --help\" for more information.\n"); + exit(1); +} + + +static int +read_length (double *vp, 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 + "pt", "in", "cm", "mm", "bp", + 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); + + q = parse_c_ident(&p, endptr); + if (q) { + if (strlen(q) > strlen("true") && + !memcmp(q, "true", strlen("true"))) { + q += strlen("true"); /* just skip "true" */ + } + 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; + default: + WARN("Unknown unit of measure: %s", q); + error = -1; + break; + } + RELEASE(q); + } + + *vp = v * u; *pp = p; + return error; +} + +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 = read_length(&paper_width, &p, comma); + p = comma + 1; + error = read_length(&paper_height, &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 +{ + long 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(*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(*p); p++); + + if (*p == '-') { + for (++p; *p && isspace(*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(*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(*p); p++); + if (*p) + ERROR("Bad page range specification: %s", p); + } + } + return; +} + +#define POP_ARG() {argv += 1; argc -= 1;} +/* It doesn't work as expected (due to dvi filename). */ +#define CHECK_ARG(n,m) if (argc < (n) + 1) {\ + if (!really_quiet)\ + fprintf(stderr, "\nMissing %s after \"-%c\".\n", (m), *flag);\ + usage();\ +} + +static void +set_verbose (int argc, char *argv[]) +{ + while (argc > 0) { + if(*argv[0] == '-') { + char *flag; + + for (flag = argv[0] + 1; *flag != 0; flag++) { + if (*flag == '-') + break; + if (*flag == 'q') + really_quiet = 1; + if (*flag == 'v') + verbose++; + } + } + POP_ARG(); + } + + if (!really_quiet) { + int i; + + for (i = 0; i < verbose; i++) { + dvi_set_verbose(); + pdf_dev_set_verbose(); + pdf_doc_set_verbose(); + pdf_enc_set_verbose(); + pdf_obj_set_verbose(); + pdf_fontmap_set_verbose(); + dpx_file_set_verbose(); + } + } +} + + +static void +do_args (int argc, char *argv[]) +{ + while (argc > 0 && *argv[0] == '-') { + char *flag, *nextptr; + const char *nnextptr; + + for (flag = argv[0] + 1; *flag != 0; flag++) { + switch (*flag) { + case '-': + if (++flag) { + if (!strcmp(flag, "help")) { + show_version(); + show_usage(); + exit(0); + } else if (!strcmp(flag, "version")) { + show_version(); + exit(0); + } + } + if (!really_quiet) + fprintf(stderr, "Unknown option in \"--%s\"", flag); + usage(); + break; + case 'D': + CHECK_ARG(1, "PS->PDF conversion command line template"); + set_distiller_template(argv[1]); + POP_ARG(); + break; + case 'r': + CHECK_ARG(1, "bitmap font dpi"); + font_dpi = atoi(argv[1]); + if (font_dpi <= 0) + ERROR("Invalid bitmap font dpi specified: %s", argv[1]); + POP_ARG(); + break; + case 'm': + CHECK_ARG(1, "magnification value"); + mag = strtod(argv[1], &nextptr); + if (mag < 0.0 || nextptr == argv[1]) + ERROR("Invalid magnification specifiied: %s", argv[1]); + POP_ARG(); + break; + case 'g': + CHECK_ARG(1, "annotation \"grow\" amount"); + nnextptr = nextptr = argv[1]; + read_length(&annot_grow, &nnextptr, nextptr + strlen(nextptr)); + POP_ARG(); + break; + case 'x': + CHECK_ARG(1, "horizontal offset value"); + nnextptr = nextptr = argv[1]; + read_length(&x_offset, &nnextptr, nextptr + strlen(nextptr)); + POP_ARG(); + break; + case 'y': + CHECK_ARG(1, "vertical offset value"); + nnextptr = nextptr = argv[1]; + read_length(&y_offset, &nnextptr, nextptr + strlen(nextptr)); + POP_ARG(); + break; + case 'o': + CHECK_ARG(1, "output file name"); + pdf_filename = NEW (strlen(argv[1])+1,char); + strcpy(pdf_filename, argv[1]); + POP_ARG(); + break; + case 's': + CHECK_ARG(1, "page selection specification"); + select_pages(argv[1]); + POP_ARG(); + break; + case 't': + pdf_doc_enable_manual_thumbnails(); + break; + case 'p': + CHECK_ARG(1, "paper format/size"); + select_paper(argv[1]); + POP_ARG(); + break; + case 'c': + ignore_colors = 1; + break; + case 'l': + landscape_mode = 1; + break; + case 'f': + CHECK_ARG(1, "fontmap file name"); + if (opt_flags & OPT_FONTMAP_FIRST_MATCH) + pdf_load_fontmap_file(argv[1], FONTMAP_RMODE_APPEND); + else + pdf_load_fontmap_file(argv[1], FONTMAP_RMODE_REPLACE); + POP_ARG(); + break; + case 'q': case 'v': + break; + case 'V': + { + int ver_minor; + + if (isdigit(*(flag+1))) { + flag++; + ver_minor = atoi(flag); + } else { + CHECK_ARG(1, "PDF minor version number"); + ver_minor = atoi(argv[1]); + POP_ARG(); + } + if (ver_minor < PDF_VERSION_MIN) { + WARN("PDF version 1.%d not supported. Using PDF 1.%d instead.", + ver_minor, PDF_VERSION_MIN); + ver_minor = PDF_VERSION_MIN; + } else if (ver_minor > PDF_VERSION_MAX) { + WARN("PDF version 1.%d not supported. Using PDF 1.%d instead.", + ver_minor, PDF_VERSION_MAX); + ver_minor = PDF_VERSION_MAX; + } + pdf_set_version((unsigned) ver_minor); + } + break; + case 'z': + { + int level; + + if (isdigit(*(flag+1))) { + flag++; + level = atoi(flag); + } else { + CHECK_ARG(1, "compression level"); + level = atoi(argv[1]); + POP_ARG(); + } + pdf_set_compression(level); + } + break; + case 'd': + if (compat_mode) { + WARN("dvipdfm \"-d\" option not supported."); + break; + } + if (isdigit(*(flag+1))) { + flag++; + pdfdecimaldigits = atoi(flag); + } else { + CHECK_ARG(1, "number of fractional digits"); + pdfdecimaldigits = atoi(argv[1]); + POP_ARG(); + } + break; + case 'I': + CHECK_ARG(1, "image cache life in hours"); + image_cache_life = atoi(argv[1]); + POP_ARG(); + break; + case 'S': + do_encryption = 1; + break; + case 'K': + CHECK_ARG(1, "encryption key length"); + key_bits = (unsigned) atoi(argv[1]); + if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7)) + ERROR("Invalid encryption key length specified: %s", argv[1]); + POP_ARG(); + break; + case 'P': + CHECK_ARG(1, "encryption permission flag"); + permission = (unsigned) strtoul(argv[1], &nextptr, 0); + if (nextptr == argv[1]) + ERROR("Invalid encryption permission flag: %s", argv[1]); + POP_ARG(); + break; + case 'O': + /* Bookmark open level */ + CHECK_ARG(1, "bookmark open level"); + bookmark_open = atoi(argv[1]); + POP_ARG(); + break; + case 'M': + mp_mode = 1; + break; + case 'C': + CHECK_ARG(1, "a number"); + { + long flags; + + flags = (unsigned) strtol(argv[1], &nextptr, 0); + if (nextptr == argv[1]) + ERROR("Invalid flag: %s", argv[1]); + if (flags < 0) + opt_flags = -flags; + else + opt_flags |= flags; + } + POP_ARG(); + break; + case 'E': + compat_mode = 1; + break; + case 'i': + CHECK_ARG(1, "subsidiary config file"); + read_config_file(argv[1]); + POP_ARG(); + break; + case 'e': + if (compat_mode) { + WARN("dvipdfm \"-e\" option not supported."); + break; + } /* else fall through */ + default: + if (!really_quiet) + fprintf(stderr, "Unknown option in \"-%s\"", flag); + usage(); + break; + } + } + POP_ARG(); + } + + if (argc > 1) { + if (!really_quiet) + fprintf(stderr, "Multiple dvi filenames?"); + usage(); + } else if (argc > 0) { + /* + * The only legitimate way to have argc == 0 here is + * do_args was called from config file. In that case, there is + * no dvi file name. Check for that case . + */ + if (!mp_mode && STRN_CMP(".dvi", argv[0] + strlen(argv[0]) - 4, 4)) { + dvi_filename = NEW(strlen(argv[0]) + 5, char); + strcpy(dvi_filename, argv[0]); + strcat(dvi_filename, ".dvi"); + } else { + dvi_filename = NEW(strlen(argv[0]) + 1, char); + strcpy(dvi_filename, argv[0]); + } + } +} + +static void +cleanup (void) +{ + if (dvi_filename) + RELEASE(dvi_filename); + if (pdf_filename) + RELEASE(pdf_filename); + if (page_ranges) + RELEASE(page_ranges); +} + +static void +read_config_file (const char *config) +{ + const char *start, *end; + char *option; + FILE *fp; + + fp = DPXFOPEN(config, DPX_RES_TYPE_TEXT); + if (!fp) { + WARN("Could not open config file \"%s\".", config); + return; + } + while ((start = mfgets (work_buffer, WORK_BUFFER_SIZE, fp)) != NULL) { + char *argv[2]; + int argc; + + argc = 0; + 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 = 1; + argv[0] = NEW (strlen(option)+2, char); + strcpy (argv[0]+1, option); + RELEASE (option); + *argv[0] = '-'; + skip_white (&start, end); + if (start < end) { + argc += 1; + if (*start == '"') { + argv[1] = parse_c_string (&start, end); + } + else + argv[1] = parse_ident (&start, end); + } + } + do_args (argc, argv); + while (argc > 0) { + RELEASE (argv[--argc]); + } + } + if (fp) + MFCLOSE(fp); +} + +static void +system_default (void) +{ + if (systempapername() != NULL) { + select_paper(systempapername()); + } else if (defaultpapername() != NULL) { + select_paper(defaultpapername()); + } +} + +void +error_cleanup (void) +{ + pdf_close_images(); /* delete temporary files */ + pdf_error_cleanup(); + if (pdf_filename) { + remove(pdf_filename); + if (!really_quiet) + fprintf(stderr, "\nOutput file removed.\n"); + } +} + +#define SWAP(v1,v2) do {\ + double _tmp = (v1);\ + (v1) = (v2);\ + (v2) = _tmp;\ + } while (0) + +static void +do_dvi_pages (void) +{ + long page_no, page_count, i, step; + double page_width, page_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; + } + + page_width = paper_width; + 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; 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; + for (;;) { + if (page_no < dvi_npages()) { + double w, h, xo, yo; + char lm; + + MESG("[%d", page_no+1); + /* Users want to change page size even after page is started! */ + 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, NULL, NULL, NULL, NULL, NULL, NULL); + if (lm != landscape_mode) { + SWAP(w, h); + landscape_mode = lm; + } + 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 != paper_width || + page_height != 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_no, + page_width, 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++) { + if (page_ranges[i].last < 0) + ERROR("Invalid page number for MPS input: -1"); + + step = (page_ranges[i].first <= page_ranges[i].last) ? 1 : -1; + page_no = page_ranges[i].first; + for (;;) { + sprintf(filename, "%s.%d", dvi_filename, page_no + 1); + fp = MFOPEN(filename, FOPEN_RBIN_MODE); + if (fp) { + MESG("[%d<%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); + } +} + + +/* TODO: MetaPost mode */ +#if defined(MIKTEX) +# define main Main +#endif +int CDECL +main (int argc, char *argv[]) +{ + double dvi2pts; + + { + const char *base = xbasename(argv[0]); + + if (STRN_CMP(base, "dvipdfmx", 8) != 0 && + (STRN_CMP(base, "dvipdfm",7) == 0 || STRN_CMP(base, "ebb", 3) == 0)) + compat_mode = 1; + + if (STRN_CMP(base, "extractbb", 9) == 0 || + STRN_CMP(base, "xbb", 3) == 0 || + STRN_CMP(base, "ebb", 3) == 0) + return extractbb(argc, argv); + } + + if (argc < 2) { + if (!really_quiet) + fprintf(stderr, "No dvi filename specified."); + usage(); + return 1; + } + +#ifdef MIKTEX + miktex_initialize(); +#else + kpse_set_program_name(argv[0], PACKAGE); +#endif + + paperinit(); + system_default(); + + argv+=1; + argc-=1; + + set_verbose(argc, argv); + /* quiet mode cannot be set in config file */ + if (really_quiet) + shut_up(); + + pdf_init_fontmaps(); /* This must come before parsing options... */ + + read_config_file(DPX_CONFIG_FILE); + + do_args (argc, argv); + +#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); + dpx_delete_old_cache(image_cache_life); + + if (!dvi_filename) { + WARN("No dvi filename specified."); + usage(); + return 1; + } + + /* Check for ".dvi" at end of argument name */ + if (pdf_filename == NULL) + set_default_pdf_filename(); + + MESG("%s -> %s\n", dvi_filename, pdf_filename); + + pdf_enc_compute_id_string(dvi_filename, pdf_filename); + if (do_encryption) { + if (key_bits > 40 && pdf_get_version() < 4) + ERROR("Chosen key length requires at least PDF 1.4. " + "Use \"-V 4\" to change."); + pdf_enc_set_passwd(key_bits, permission, NULL, NULL); + } + + if (mp_mode) { + x_offset = 0.0; + y_offset = 0.0; + dvi2pts = 0.01; /* dvi2pts controls accuracy. */ + } else { + unsigned ver_minor = 0; + char owner_pw[MAX_PWD_LEN], user_pw[MAX_PWD_LEN]; + /* Dependency between DVI and PDF side is rather complicated... */ + dvi2pts = dvi_init(dvi_filename, mag); + if (dvi2pts == 0.0) + ERROR("dvi_init() failed!"); + + pdf_doc_set_creator(dvi_comment()); + + if (do_encryption) + /* command line takes precedence */ + dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, + &ver_minor, NULL, NULL, NULL, NULL, NULL); + else { + dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, + &ver_minor, &do_encryption, &key_bits, &permission, owner_pw, user_pw); + if (do_encryption) { + if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7)) + ERROR("Invalid encryption key length specified: %u", key_bits); + else if (key_bits > 40 && pdf_get_version() < 4) + ERROR("Chosen key length requires at least PDF 1.4. " + "Use \"-V 4\" to change."); + do_encryption = 1; + pdf_enc_set_passwd(key_bits, permission, owner_pw, user_pw); + } + } + if (ver_minor >= PDF_VERSION_MIN && ver_minor <= PDF_VERSION_MAX) { + pdf_set_version(ver_minor); + } + if (landscape_mode) { + SWAP(paper_width, paper_height); + } + } + + pdf_files_init(); + + /* 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. + */ + pdf_open_document(pdf_filename, do_encryption, + paper_width, paper_height, annot_grow, bookmark_open, + !(opt_flags & OPT_PDFDOC_NO_DEST_REMOVE)); + + /* Ignore_colors placed here since + * they are considered as device's capacity. + */ + pdf_init_device(dvi2pts, pdfdecimaldigits, ignore_colors); + + 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 (mp_mode) { + do_mps_pages(); + } else { + do_dvi_pages(); + } + + pdf_files_close(); + + /* Order of close... */ + pdf_close_device (); + /* pdf_close_document flushes XObject (image) and other resources. */ + pdf_close_document(); + + pdf_close_fontmaps(); /* pdf_font may depend on fontmap. */ + + if (!mp_mode) + dvi_close(); + + MESG("\n"); + cleanup(); + + paperdone(); +#ifdef MIKTEX + miktex_uninitialize (); +#endif + + return 0; +} diff --git a/Build/source/texk/dvipdf-x/src/epdf.c b/Build/source/texk/dvipdf-x/src/epdf.c new file mode 100644 index 00000000000..17fdcf3ee26 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/epdf.c @@ -0,0 +1,208 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 ... + */ + +#if 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 "pdfximage.h" + +#include "epdf.h" + +int +pdf_include_page (pdf_ximage *ximage, FILE *image_file, const char *filename) +{ + pdf_file *pf; + xform_info info; + pdf_obj *contents = NULL, *catalog; + pdf_obj *page = NULL, *resources = NULL, *markinfo = NULL; + + pf = pdf_open(filename, image_file); + if (!pf) + return -1; + + if (pdf_file_get_version(pf) > pdf_get_version()) + goto too_recent; + + pdf_ximage_init_form_info(&info); + + page = pdf_doc_get_page(pf, pdf_ximage_get_page(ximage), NULL, + &info.bbox, &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("File contains tagged PDF. Ignoring tags."); + pdf_release_obj(tmp); + } + + contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents")); + pdf_release_obj(page); + + /* + * Handle page content stream. + */ + { + pdf_obj *content_new; + + if (!contents) { + /* + * Empty page + */ + content_new = pdf_new_stream(0); + /* TODO: better don't include anything if the page is empty */ + } else if (PDF_OBJ_STREAMTYPE(contents)) { + /* + * We must import the stream because its dictionary + * may contain indirect references. + */ + content_new = pdf_import_object(contents); + } else if (PDF_OBJ_ARRAYTYPE(contents)) { + /* + * Concatenate all content streams. + */ + int idx, len = pdf_array_length(contents); + content_new = pdf_new_stream(STREAM_COMPRESS); + for (idx = 0; idx < len; idx++) { + pdf_obj *content_seg = pdf_deref_obj(pdf_get_array(contents, idx)); + if (!PDF_OBJ_STREAMTYPE(content_seg) || + pdf_concat_stream(content_new, content_seg) < 0) { + pdf_release_obj(content_seg); + pdf_release_obj(content_new); + goto error; + } + pdf_release_obj(content_seg); + } + } else + goto error; + + if (contents) + pdf_release_obj(contents); + contents = content_new; + } + + /* + * 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(1.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(1.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + + 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; + + too_recent: + pdf_close(pf); + WARN("PDF version of input file more recent than in output file."); + if (compat_mode) { + WARN("Converting. Use \"-V\" switch to change output PDF version."); + return 1; + } else { + WARN("Use \"-V\" switch to change output PDF version."); + return -1; + } +} diff --git a/Build/source/texk/dvipdf-x/src/epdf.h b/Build/source/texk/dvipdf-x/src/epdf.h new file mode 100644 index 00000000000..885a6135f6a --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/epdf.h @@ -0,0 +1,34 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +extern int pdf_include_page (pdf_ximage *ximage, FILE *file, + const char *filename); + +#endif /* _EPDF_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/error.c b/Build/source/texk/dvipdf-x/src/error.c new file mode 100644 index 00000000000..c4d2d3d7cac --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/error.c @@ -0,0 +1,92 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include + +#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 (void) +{ + really_quiet = 1; +} + +void +MESG (const char *fmt, ...) +{ + va_list argp; + + if (!really_quiet) { + 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) { + if (WANT_NEWLINE()) + fprintf(stderr, "\n"); + fprintf(stderr, "** WARNING ** "); + 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) { + if (WANT_NEWLINE()) + fprintf(stderr, "\n"); + fprintf(stderr, "** ERROR ** "); + va_start(argp, fmt); + vfprintf(stderr, fmt, argp); + va_end(argp); + fprintf(stderr, "\n"); + } + error_cleanup(); + exit( 1 ); +} diff --git a/Build/source/texk/dvipdf-x/src/error.h b/Build/source/texk/dvipdf-x/src/error.h new file mode 100644 index 00000000000..25103e0d4e0 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/error.h @@ -0,0 +1,46 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); + +#define FATAL_ERROR -1 +#define NO_ERROR 0 + +#include +#include + +extern void shut_up (void); + +extern void ERROR (const char *fmt, ...); +extern void MESG (const char *fmt, ...); +extern void WARN (const char *fmt, ...); + +#define ASSERT(e) assert(e) + +#endif /* _ERROR_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/fontmap.c b/Build/source/texk/dvipdf-x/src/fontmap.c new file mode 100644 index 00000000000..c2151278f12 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/fontmap.c @@ -0,0 +1,1572 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "error.h" + +#include "dpxfile.h" +#include "dpxutil.h" + +#include "subfont.h" + +#include "fontmap.h" + +#ifdef XETEX +#include "ft2build.h" +#include FT_FREETYPE_H +#if 0 && defined(XETEX_MAC) +#include +#include +#include FT_MAC_H +#endif +#endif + +/* CIDFont */ +static char *strip_options (const char *map_name, fontmap_opt *opt); + +static int verbose = 0; +void +pdf_fontmap_set_verbose (void) +{ + verbose++; +} + + +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; /* deactivated */ + mrec->opt.index = 0; + mrec->opt.charcoll = NULL; + mrec->opt.style = FONTMAP_STYLE_NONE; + mrec->opt.stemv = -1; /* not given explicitly by an option */ + +#ifdef XETEX + mrec->opt.ft_face = NULL; + mrec->opt.glyph_widths = NULL; +#endif +} + +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); +#ifdef XETEX + if (mrec->opt.glyph_widths) + RELEASE(mrec->opt.glyph_widths); +#endif + 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; + +#ifdef XETEX + dst->opt.ft_face = src->opt.ft_face; + dst->opt.glyph_widths = src->opt.glyph_widths; +#endif +} + + +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(*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]; + long 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 = atoi(q); + if (mrec->opt.index < 0) { + WARN("Invalid TTC index number: %s", q); + return -1; + } + 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; + + /* 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(*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; + break; + } + 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 (++p < endptr && *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; + break; + } + 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 (verbose > 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 (verbose > 3) + MESG("\n"); + + return 0; +} + +int +pdf_remove_fontmap_record (const char *kp) +{ + char *fnt_name, *sfd_name = NULL; + + if (!kp) + return -1; + + if (verbose > 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 (verbose > 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 (verbose > 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 (verbose > 3) + MESG("\n"); + + return 0; +} + +int +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 -1; + } + + if (verbose > 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); + return -1; + } + if (verbose > 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 (verbose > 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 (verbose > 3) + MESG("\n"); + + return 0; +} + + +int +pdf_read_fontmap_line (fontmap_rec *mrec, const char *mline, long 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; + long llen, lpos = 0; + int error = 0, format = 0; + + ASSERT(filename); + ASSERT(fontmap) ; + + if (verbose) + MESG(" 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 (verbose) + MESG(">"); + + return error; +} + +#ifdef XETEX +static int +pdf_insert_native_fontmap_record (const char *name, const char *path, int index, FT_Face face, + int layout_dir, int extend, int slant, int embolden) +{ + char *fontmap_key; + fontmap_rec *mrec; + + ASSERT(name); + ASSERT(path || face); + + fontmap_key = malloc(strlen(name) + 40); // CHECK + sprintf(fontmap_key, "%s/%c/%d/%d/%d", name, layout_dir == 0 ? 'H' : 'V', extend, slant, embolden); + + if (verbose) + MESG("map_name = fontmap_key; + mrec->enc_name = mstrdup(layout_dir == 0 ? "Identity-H" : "Identity-V"); + mrec->font_name = (path != NULL) ? mstrdup(path) : NULL; + mrec->opt.index = index; + mrec->opt.ft_face = face; + mrec->opt.glyph_widths = NULL; + 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; + + pdf_insert_fontmap_record(mrec->map_name, mrec); + pdf_clear_fontmap_record(mrec); + RELEASE(mrec); + + if (verbose) + MESG(">"); + + return 0; +} + +static FT_Library ftLib; + +static int +pdf_load_native_font_from_path(const char *ps_name, int layout_dir, int extend, int slant, int embolden) +{ + const char *p; + char *filename = NEW(strlen(ps_name), char); + char *q = filename; + int index = 0; + FT_Face face = NULL; + int error = -1; + +#ifdef WIN32 + for (p = ps_name + 1; *p && *p != ']'; ++p) { + if (*p == ':') { + if (p == ps_name+2 && isalpha(*(p-1)) && (*(p+1) == '/' || *(p+1) == '\\')) + *q++ = *p; + else + break; + } + else + *q++ = *p; + } +#else + for (p = ps_name + 1; *p && *p != ':' && *p != ']'; ++p) + *q++ = *p; +#endif + *q = 0; + if (*p == ':') { + ++p; + while (*p && *p != ']') + index = index * 10 + *p++ - '0'; + } + + /* try loading the filename directly */ + error = FT_New_Face(ftLib, filename, index, &face); + + /* if failed, try locating the file in the TEXMF tree */ + if ( error && + ( (q = dpx_find_opentype_file(filename)) != NULL + || (q = dpx_find_truetype_file(filename)) != NULL + || (q = dpx_find_type1_file(filename)) != NULL + || (q = dpx_find_dfont_file(filename)) != NULL) ) { + error = FT_New_Face(ftLib, q, index, &face); + RELEASE(q); + } + + if (error == 0) + error = pdf_insert_native_fontmap_record(ps_name, filename, index, face, + layout_dir, extend, slant, embolden); + RELEASE(filename); + return error; +} + +int +pdf_load_native_font (const char *ps_name, + const char *fam_name, const char *sty_name, + int layout_dir, int extend, int slant, int embolden) +{ + static int sInitialized = 0; + int error = -1; + + if (!sInitialized) { + if (FT_Init_FreeType(&ftLib) != 0) { + WARN("FreeType initialization failed."); + return error; + } + sInitialized = 1; + } + + if (ps_name[0] == '[') { + error = pdf_load_native_font_from_path(ps_name, layout_dir, extend, slant, embolden); + } + else { +/* re-enable this if we decided not to ship XeTeX 0.9999 in TeX Live 2013 */ +#if 0 && defined(XETEX_MAC) + CFStringRef theName = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, + ps_name, kCFStringEncodingASCII, kCFAllocatorNull); + ATSFontRef fontRef = ATSFontFindFromPostScriptName(theName, kATSOptionFlagsDefault); + CFRelease(theName); + if (fontRef != 0) { + CFStringRef atsName = NULL; + OSStatus status = ATSFontGetName(fontRef, kATSOptionFlagsDefault, &atsName); + if (status == noErr) { + int bufferSize = CFStringGetLength(atsName) * 4 + 1; + char* fontName = NEW(bufferSize, char); + if (CFStringGetCString(atsName, fontName, bufferSize, kCFStringEncodingUTF8)) { + FT_Long index; + UInt8 path[PATH_MAX + 1]; + FT_Error ftErr = FT_GetFilePath_From_Mac_ATS_Name(fontName, path, PATH_MAX, &index); + if (ftErr == 0) { + FT_Face face; + ftErr = FT_New_Face(ftLib, (char*)path, index, &face); + if (ftErr == 0) { + error = pdf_insert_native_fontmap_record(ps_name, NULL, index, face, + layout_dir, extend, slant, embolden); + } + } + } + RELEASE(fontName); + } + if (atsName != NULL) + CFRelease(atsName); + } +#else + ERROR("Loading fonts by font name is not supported: %s", ps_name); +#endif /* XETEX_MAC */ + } + + return error; +} +#endif /* XETEX */ + +#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 +#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(*(p+1))) { + opt->index = (int) 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, " \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, "\n"); + fprintf(stdout, "\n"); + fprintf(stdout, "\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, "\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/dvipdf-x/src/fontmap.h b/Build/source/texk/dvipdf-x/src/fontmap.h new file mode 100644 index 00000000000..2624e856c5d --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/fontmap.h @@ -0,0 +1,111 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +#ifdef XETEX +#include "ft2build.h" +#include FT_FREETYPE_H +#endif + +/* Options */ +typedef struct fontmap_opt { + /* Synthetic font */ + double slant, extend, bold; + /* comaptibility and other flags */ + long mapc, flags; + + char *otl_tags; /* currently unused */ + char *tounicode; /* not implemented yet */ + + double design_size; /* unused */ + + char *charcoll; /* Adobe-Japan1-4, etc. */ + int index; /* TTC index */ + int style; /* ,Bold, etc. */ + int stemv; /* StemV value especially for CJK fonts */ +#ifdef XETEX + FT_Face ft_face; + unsigned short *glyph_widths; +#endif +} 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_fontmap_set_verbose (void); + +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, long 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 int 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); + +#ifdef XETEX +extern int pdf_load_native_font (const char *ps_name, + const char *fam_name, const char *sty_name, + int layout_dir, int extend, int slant, int embolden); +#endif + +#endif /* _FONTMAP_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/jpegimage.c b/Build/source/texk/dvipdf-x/src/jpegimage.c new file mode 100644 index 00000000000..b21d6c34e94 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/jpegimage.c @@ -0,0 +1,792 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + + +#if 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 "dvipdfmx.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 +#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_APP2 = 0xe2, + JM_APP14 = 0xee, + JM_APP15 = 0xef, + + JM_COM = 0xfe +} JPEG_marker; + +typedef enum { + JS_APPn_JFIF, + JS_APPn_ADOBE, + JS_APPn_ICC +} JPEG_APPn_sig; + +struct JPEG_APPn_JFIF /* APP0 */ +{ + unsigned short version; + unsigned char units; /* 0: only aspect ratio + * 1: dots per inch + * 2: dots per cm + */ + unsigned short Xdensity; + unsigned short Ydensity; + unsigned char Xthumbnail; + unsigned char Ythumbnail; + unsigned char *thumbnail; /* Thumbnail data. */ +}; + +struct JPEG_APPn_ICC /* APP2 */ +{ + unsigned char seq_id; + unsigned char num_chunks; + unsigned char *chunk; + + /* Length of ICC profile data in this chunk. */ + unsigned short length; +}; + +struct JPEG_APPn_Adobe /* APP14 */ +{ + unsigned short version; + unsigned short flag0; + unsigned short flag1; + unsigned char transform; /* color transform code */ +}; + +struct JPEG_ext +{ + JPEG_marker marker; + JPEG_APPn_sig app_sig; + void *app_data; +}; + +#define MAX_COUNT 1024 +struct JPEG_info +{ + unsigned short height; + unsigned short width; + + unsigned char bits_per_component; + unsigned char num_components; + + /* 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) + +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, int flags); /* flags unused yet */ + +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_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")); + + colorspace = NULL; + if (j_info.flags & HAVE_APPn_ICC) { + pdf_obj *icc_stream, *intent; + + icc_stream = JPEG_get_iccp(&j_info); + + if (!icc_stream) + colorspace = NULL; + else { + int cspc_id; + + 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, 0); + + 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; +} + +#define IS_JFIF(j) ((j)->flags & HAVE_APPn_JFIF) + +static void +jpeg_get_density (struct JPEG_info *j_info, + double *xdensity, double *ydensity) +{ + if (compat_mode) { + *xdensity = *ydensity = 72.0 / 100.0; + return; + } + + *xdensity = *ydensity = 1.0; + + if (IS_JFIF(j_info)) { + struct JPEG_APPn_JFIF *app_data; + int i; + for (i = 0; i < j_info->num_appn; i++) { + if (j_info->appn[i].marker == JM_APP0 || + j_info->appn[i].app_sig == JS_APPn_JFIF) + break; + } + if (i < j_info->num_appn) { + app_data = (struct JPEG_APPn_JFIF *)j_info->appn[i].app_data; + switch (app_data->units) { + case 1: /* pixels per inch */ + *xdensity = 72.0 / app_data->Xdensity; + *ydensity = 72.0 / app_data->Ydensity; + break; + case 2: /* pixels per centimeter */ + *xdensity = 72.0 / 2.54 / app_data->Xdensity; + *ydensity = 72.0 / 2.54 / app_data->Ydensity; + break; + default: + break; + } + } + } +} + +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->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); + } +} + +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 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; + } + } + + return -1; +} + +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, unsigned short length) +{ + 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; +} + +static unsigned short +read_APP0_JFIF (struct JPEG_info *j_info, FILE *fp, unsigned short length) +{ + struct JPEG_APPn_JFIF *app_data; + unsigned short 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); + + return (9 + thumb_data_len); +} + +static unsigned short +read_APP0_JFXX (struct JPEG_info *j_info, FILE *fp, unsigned short 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 unsigned short +read_APP2_ICC (struct JPEG_info *j_info, FILE *fp, unsigned short 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, int flags) /* flags unused yet */ +{ + JPEG_marker marker; + long length, nb_read; + int found_SOFn, count; + + rewind(fp); + count = 0; + found_SOFn = 0; + while (!found_SOFn && + count < MAX_COUNT && + (marker = JPEG_get_marker(fp)) >= 0) { + 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); + count++; + continue; + } + 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); + while (length > 0) { + nb_read = fread(work_buffer, sizeof(char), + MIN(length, WORK_BUFFER_SIZE), fp); + if (nb_read > 0) + pdf_add_stream(stream, work_buffer, nb_read); + length -= nb_read; + } + found_SOFn = 1; + break; + default: + if (j_info->skipbits[count / 8] & (1 << (7 - (count % 8)))) { + /* skip */ + while (length > 0) { + nb_read = fread(work_buffer, sizeof(char), + MIN(length, WORK_BUFFER_SIZE), fp); + length -= nb_read; + } + } 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); + while (length > 0) { + nb_read = fread(work_buffer, sizeof(char), + MIN(length, WORK_BUFFER_SIZE), fp); + if (nb_read > 0) + pdf_add_stream(stream, work_buffer, nb_read); + length -= nb_read; + } + } + } + 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); +} + +static int +JPEG_scan_file (struct JPEG_info *j_info, FILE *fp) +{ + JPEG_marker marker; + unsigned short length; + int found_SOFn, count; + char app_sig[128]; + + rewind(fp); + count = 0; + found_SOFn = 0; + while (!found_SOFn && + (marker = JPEG_get_marker(fp)) >= 0) { + if (marker == JM_SOI || + (marker >= JM_RST0 && marker <= JM_RST7)) { + count++; + continue; + } + 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)) { + j_info->flags |= HAVE_APPn_JFIF; + length -= read_APP0_JFIF(j_info, fp, length); + } else if (!memcmp(app_sig, "JFXX", 5)) { + length -= read_APP0_JFXX(j_info, fp, length); + } + } + 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); + if (count < MAX_COUNT) { + j_info->skipbits[count / 8] |= (1 << (7 - (count % 8))); + } + } + } + seek_relative(fp, length); + 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)) { + j_info->flags |= HAVE_APPn_ADOBE; + length -= read_APP14_Adobe(j_info, fp, length); + } else { + if (count < MAX_COUNT) { + j_info->skipbits[count/8] |= (1 << (7 - (count % 8))); + } + } + } + seek_relative(fp, length); + break; + default: + seek_relative(fp, length); + if (marker >= JM_APP0 && + marker <= JM_APP15) { + if (count < MAX_COUNT) { + j_info->skipbits[count / 8] |= (1 << (7 - (count % 8))); + } + } + break; + } + count++; + } + + return (found_SOFn ? 0 : -1); +} + +int +jpeg_get_bbox (FILE *fp, long *width, long *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/dvipdf-x/src/jpegimage.h b/Build/source/texk/dvipdf-x/src/jpegimage.h new file mode 100644 index 00000000000..437f01d6af3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/jpegimage.h @@ -0,0 +1,38 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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, long *width, long *height, + double *xdensity, double *ydensity); + +#endif /* _JPEGIMAGE_H_ */ + + diff --git a/Build/source/texk/dvipdf-x/src/mpost.c b/Build/source/texk/dvipdf-x/src/mpost.c new file mode 100644 index 00000000000..2d610d1f158 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/mpost.c @@ -0,0 +1,1674 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "numbers.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" + +/* + * 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 + * + * gsave grestore ... + * + * can't be translated to PDF code + * + * q 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 = -1; + +#define CURRENT_FONT() ((currentfont < 0) ? NULL : &font_stack[currentfont]) + +/* 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(); + + if (font) { + if (!strcmp(font->font_name, font_name) && + font->pt_size == pt_size) + return 0; + } else { /* No currentfont */ +/* ***TODO*** Here some problem exists! */ + font = &font_stack[0]; + font->font_name = NULL; + currentfont = 0; + } + + 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; + + if (currentfont < 0) { + font_stack[0].font_name = NEW(strlen("Courier") + 1, char); + strcpy(font_stack[0].font_name, "Courier"); + font_stack[0].pt_size = 1; + font_stack[0].tfm_id = 0; + font_stack[0].subfont_id = 0; + currentfont = 0; + } + + current = &font_stack[currentfont++]; + next = &font_stack[currentfont ]; + next->font_name = NEW(strlen(current->font_name)+1, char); + strcpy(next->font_name, current->font_name); + next->pt_size = current->pt_size; + + next->subfont_id = current->subfont_id; + next->tfm_id = current->tfm_id; +} + +static void +restore_font (void) +{ + struct mp_font *current; + + current = CURRENT_FONT(); + if (current) { + if (current->font_name) + RELEASE(current->font_name); + current->font_name = NULL; + } else { + ERROR("No currentfont..."); + } + + currentfont--; +} + +static void +clear_fonts (void) +{ + while (currentfont >= 0) { + if (font_stack[currentfont].font_name) + RELEASE(font_stack[currentfont].font_name); + 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(**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 { + bbox->llx = values[0]; + bbox->lly = values[1]; + bbox->urx = values[2]; + bbox->ury = values[3]; + + return 0; + } + } + skip_line (pp, endptr); + while (*pp < endptr && isspace(**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; + skip_line(start, end); + break; + } else if (!strncmp(*start, "%%Page:", 7)) { + skip_line(start, end); + break; + } + skip_line(start, end); + } + if (!found_prolog) { + *start = save; + } + + return; +} + +/* PostScript Operators */ + +#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) { + 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) { + 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, 0); + 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, 0); + } + + 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); + 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(**start) || + (*start < end - 1 && + (**start == '+' || **start == '-' || **start == '.' ))) { + double value; + char *next; + + value = strtod(*start, &next); + if (next < end && !strchr("<([{/%", *next) && !isspace(*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; + long 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, 0.0, 0.0, &(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; + long 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, 0.0, 0.0); /* 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); +} + +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); +} diff --git a/Build/source/texk/dvipdf-x/src/pdfcolor.c b/Build/source/texk/dvipdf-x/src/pdfcolor.c new file mode 100644 index 00000000000..4aff0dd589b --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfcolor.c @@ -0,0 +1,1515 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 "dpxfile.h" + +#include "pdfdoc.h" +#include "pdfdraw.h" + +#include "pdfcolor.h" + + +static int verbose = 0; +void +pdf_color_set_verbose (void) +{ + verbose++; +} + +/* This function returns PDF_COLORSPACE_TYPE_GRAY, + * PDF_COLORSPACE_TYPE_RGB or PDF_COLORSPACE_TYPE_CMYK. + */ +int +pdf_color_type (const pdf_color *color) +{ + ASSERT(color); + + return -color->num_components; +} + +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->num_components = 3; + + 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->num_components = 4; + + 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->num_components = 1; + + 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 (f == 1.0) { + pdf_color_white(dst); + } else { + double f0, f1; + int n; + + n = dst->num_components = 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; + } +} + +int +pdf_color_is_white (const pdf_color *color) +{ + int n; + double f; + + ASSERT(color); + + n = color->num_components; + f = n == 4 ? 0.0 : 1.0; /* n == 4 is CMYK, others are RGB and Gray */ + + while (n--) + if (color->values[n] != f) + return 0; + + return 1; +} + +int +pdf_color_to_string (const pdf_color *color, char *buffer) +{ + int i, len = 0; + + for (i = 0; i < color->num_components; i++) { + len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001)); + } + return len; +} + +pdf_color current_fill = { + 1, + {0.0, 0.0, 0.0, 0.0} +}; + +pdf_color current_stroke = { + 1, + {0.0, 0.0, 0.0, 0.0} +}; + +/* + * This routine is not a real color matching. + */ +int +pdf_color_compare (const pdf_color *color1, const pdf_color *color2) +{ + int n = color1->num_components; + + if (n != color2->num_components) + return -1; + + while (n--) + if (color1->values[n] != color2->values[n]) + return -1; + + return 0; +} + +int +pdf_color_is_valid (const pdf_color *color) +{ + int n; + + n = color->num_components; + if (n != 1 && n != 3 && n != 4) + return 0; + + while (n--) + if (color->values[n] < 0.0 || color->values[n] > 1.0) + return 0; + + return 1; +} + +/* Dvipdfm special */ +#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; + +void +pdf_color_clear_stack (void) +{ + if (color_stack.current > 0) { + WARN("You've mistakenly made a global color change within nested colors."); + } + 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(0); +} + +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(0); + } + 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; +} + +/***************************** COLOR SPACE *****************************/ + +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); + +#if 0 +struct calgray_cdata +{ + double white_point[3]; /* required, second component must + * be equal to 1.0 + */ + double black_point[3]; /* optional, default: [0 0 0] */ + double gamma; /* optional, default: 1.0 */ +}; + +struct calrgb_cdata +{ + double white_point[3]; /* required, second component must + * be equal to 1.0 + */ + double black_point[3]; /* optional, default: [0 0 0] */ + double gamma[3]; /* optional, default: [1 1 1] */ + double matrix[9]; /* optional, default: identity + * [1 0 0 0 1 0 0 0 1] + */ +}; + +static void +release_calrgb (void *cdata) +{ + struct calrgb_cdata *calrgb; + + if (cdata) { + calrgb = (struct calrgb_cdata *) cdata; + RELEASE(calrgb); + } +} + +static int +compare_calrgb (const char *ident1, const void *cdata1, + const char *ident2, const void *cdata2) +{ + struct calrgb_cdata *calrgb1; + struct calrgb_cdata *calrgb2; + + if (ident1 && ident2 && + !strcmp(ident1, ident2)) { + return 0; + } +} + +static void +init_calrgb (struct calrgb_cdata *calrgb) +{ + ASSERT(calrgb); + + calrgb->white_point[0] = 1.0; + calrgb->white_point[1] = 1.0; + calrgb->white_point[2] = 1.0; + + calrgb->black_point[0] = 0.0; + calrgb->black_point[1] = 0.0; + calrgb->black_point[2] = 0.0; + + calrgb->gamma[0] = 1.0; + calrgb->gamma[1] = 1.0; + calrgb->gamma[2] = 1.0; + + calrgb->matrix[0] = 1.0; + calrgb->matrix[1] = 0.0; + calrgb->matrix[2] = 0.0; + + calrgb->matrix[3] = 0.0; + calrgb->matrix[4] = 1.0; + calrgb->matrix[5] = 0.0; + + calrgb->matrix[6] = 0.0; + calrgb->matrix[7] = 0.0; + calrgb->matrix[8] = 1.0; +} + +static int +valid_calrgb (struct calrgb_cdata *calrgb) +{ + if (calrgb->white_point[1] != 1.0 || + calrgb->white_point[0] <= 0.0 || + calrgb->white_point[2] <= 0.0) + return 0; + + if (calrgb->black_point[0] < 0.0 || + calrgb->black_point[1] < 0.0 || + calrgb->black_point[2] < 0.0) + return 0; + + if (calrgb->gamma[0] < 0.0 || + calrgb->gamma[1] < 0.0 || + calrgb->gamma[2] < 0.0) + return 0; + + /* matrix should be invertible? */ + + return 1; +} + +static pdf_obj * +pdf_color_make_calrgb_resource (struct calrgb_cdata *calrgb) +{ + pdf_obj *colorspace; + pdf_obj *calparams, *tmp_array; + + ASSERT(calrgb); + + if (!valid_calrgb(calrgb)) + return NULL; + + colorspace = pdf_new_array(); + calparams = pdf_new_dict(); + + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->white_point[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(1.0)); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->white_point[2], 0.001))); + pdf_add_dict(calparams, pdf_new_name("WhitePoint"), tmp_array); + + if (calrgb->black_point[0] != 0.0 || + calrgb->black_point[1] != 0.0 || + calrgb->black_point[2] != 0.0) { + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[1], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[2], 0.001))); + pdf_add_dict(calparams, pdf_new_name("BlackPoint"), tmp_array); + } + + if (calrgb->gamma[0] != 1.0 || + calrgb->gamma[1] != 1.0 || + calrgb->gamma[2] != 1.0) { + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[1], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[2], 0.001))); + pdf_add_dict(calparams, pdf_new_name("Gamma"), tmp_array); + } + + if (calrgb->matrix[0] != 1.0 || + calrgb->matrix[1] != 0.0 || + calrgb->matrix[2] != 0.0 || + calrgb->matrix[3] != 0.0 || + calrgb->matrix[4] != 1.0 || + calrgb->matrix[5] != 0.0 || + calrgb->matrix[6] != 0.0 || + calrgb->matrix[7] != 0.0 || + calrgb->matrix[8] != 1.0) { + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[1], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[2], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[3], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[4], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[5], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[6], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[7], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[8], 0.001))); + pdf_add_dict(calparams, pdf_new_name("Matrix"), tmp_array); + } + + pdf_add_array(colorspace, pdf_new_name("CalRGB")); + pdf_add_array(colorspace, calparams); + + return colorspace; +} +#endif + +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 */ +}; + +static int +iccp_version_supported (int major, int minor) +{ + int pdf_ver; + + pdf_ver = pdf_get_version(); + if (pdf_ver < 6) { + if (icc_versions[pdf_ver].major < major) + return 0; + else if (icc_versions[pdf_ver].major == major && + icc_versions[pdf_ver].minor < minor) + return 0; + else { + return 1; + } + } + + return 0; +} + +typedef unsigned long 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 +{ + long X, Y, Z; /* s15Fixed16Numeber */ +} iccXYZNumber; + +typedef struct +{ + long size; + iccSig CMMType; + long 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]; + long 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 +{ + long 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_CIELAB: + 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, long 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; + break; + } + + return 0; +} + +pdf_obj * +iccp_get_rendering_intent (const void *profile, long proflen) +{ + pdf_obj *ri = NULL; + const unsigned char *p; + long 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) ((long) ((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, long 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 %ld in ICC profile header.)", + *p, 128 - ((long) (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, long 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, long 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 (verbose) + MESG("(ICCP:[id=%d])", cspc_id); + release_iccbased_cdata(cdata); + return cspc_id; + } + if (verbose > 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, long length, FILE *fp) +{ + pdf_obj *stream; + MD5_CONTEXT md5; + long 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; + long 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 (verbose) + MESG("(ICCP:[id=%d])", cspc_id); + release_iccbased_cdata(cdata); + pdf_release_obj(stream); + return cspc_id; + } + if (verbose > 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 (verbose) { + MESG("(ColorSpace:%s", ident); + if (verbose > 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/dvipdf-x/src/pdfcolor.h b/Build/source/texk/dvipdf-x/src/pdfcolor.h new file mode 100644 index 00000000000..65d897e7c66 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfcolor.h @@ -0,0 +1,105 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_DEVICECMYK -4 +#define PDF_COLORSPACE_TYPE_DEVICERGB -3 +#define PDF_COLORSPACE_TYPE_DEVICEGRAY -1 +#define PDF_COLORSPACE_TYPE_INVALID 0 +#define PDF_COLORSPACE_TYPE_CALGRAY 1 +#define PDF_COLORSPACE_TYPE_CIELAB 2 +#define PDF_COLORSPACE_TYPE_CALRGB 3 +#define PDF_COLORSPACE_TYPE_ICCBASED 4 + +#define PDF_COLORSPACE_TYPE_CMYK PDF_COLORSPACE_TYPE_DEVICECMYK +#define PDF_COLORSPACE_TYPE_RGB PDF_COLORSPACE_TYPE_DEVICERGB +#define PDF_COLORSPACE_TYPE_GRAY PDF_COLORSPACE_TYPE_DEVICEGRAY + + +#define PDF_COLOR_COMPONENT_MAX 4 + +typedef struct +{ + int num_components; + double values[PDF_COLOR_COMPONENT_MAX]; +} pdf_color; + +extern void pdf_color_set_verbose (void); + +extern int pdf_color_type (const pdf_color *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); +#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_copycolor (pdf_color *color1, const pdf_color *color2); +extern void pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f); + +extern int pdf_color_compare (const pdf_color *color1, const pdf_color *color2); + +extern int pdf_color_is_white (const pdf_color *color); +extern int pdf_color_is_valid (const pdf_color *color); + +extern int pdf_color_to_string (const pdf_color *color, char *buffer); + +/* Not check size */ +extern pdf_obj *iccp_get_rendering_intent (const void *profile, long proflen); +extern int iccp_check_colorspace (int colortype, + const void *profile, long proflen); + +/* returns colorspace ID */ +extern int iccp_load_profile (const char *ident, + const void *profile, long 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 specials & color stack + * 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); + +extern void pdf_color_clear_stack (void); +extern void pdf_color_get_current (pdf_color **sc, pdf_color **fc); + +#endif /* _PDF_COLOR_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/pdfdev.c b/Build/source/texk/dvipdf-x/src/pdfdev.c new file mode 100644 index 00000000000..79351aec34c --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfdev.c @@ -0,0 +1,1839 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.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" + +static int verbose = 0; + +void +pdf_dev_set_verbose (void) +{ + verbose++; +} + +/* Not working yet... */ +double +pdf_dev_scale (void) +{ + return 1.0; +} + +/* + * Unit conversion, formatting and others. + */ + +#define TEX_ONE_HUNDRED_BP 6578176 +static struct { + double dvi2pts; + long min_bp_val; /* Shortest resolvable distance in the output PDF. */ + int precision; /* Number of decimal digits (in fractional part) kept. */ +} dev_unit = { + 0.0, + 658, + 2 +}; + + +double +dev_unit_dviunit (void) +{ + return (1.0/dev_unit.dvi2pts); +} + +#define DEV_PRECISION_MAX 8 +static unsigned long ten_pow[10] = { + 1ul, 10ul, 100ul, 1000ul, 10000ul, 100000ul, 1000000ul, 10000000ul, 100000000ul, 1000000000ul +}; + +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(b) ( (spt_t) round( (b) / dev_unit.dvi2pts ) ) +#define spt2bpt(s) ( (s) * dev_unit.dvi2pts ) +#define dround_at(v,p) (ROUND( (v), ten_pow_inv[(p)] )) + +static int +p_itoa (long 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); +} + +/* ... */ +static int +p_dtoa (double value, int prec, char *buf) +{ + const long p[10] = { 1, 10, 100, 1000, 10000, + 100000, 1000000, 10000000, 100000000, 1000000000 }; + long i, f; + char *c = buf; + int n; + + if (value < 0) { + value = -value; + *c++ = '-'; + n = 1; + } else + n = 0; + + i = (long) value; + f = (long) ((value-i)*p[prec] + 0.5); + + if (f == p[prec]) { + f = 0; + i++; + } + + if (i) { + int m = p_itoa(i, c); + c += m; + n += m; + } else if (!f) { + *(c = buf) = '0'; + n = 1; + } + + if (f) { + int j = prec; + + *c++ = '.'; + + while (j--) { + c[j] = (f % 10) + '0'; + f /= 10; + } + c += prec-1; + n += 1+prec; + + while (*c == '0') { + c--; + n--; + } + } + + *(++c) = 0; + + return n; +} + +static int +dev_sprint_bp (char *buf, spt_t value, spt_t *error) +{ + double value_in_bp; + double error_in_bp; + int prec = dev_unit.precision; + + value_in_bp = spt2bpt(value); + if (error) { + error_in_bp = value_in_bp - dround_at(value_in_bp, prec); + *error = bpt2spt(error_in_bp); + } + + return p_dtoa(value_in_bp, prec, buf); +} + +/* They are affected by precision (set at device initialization). */ +int +pdf_sprint_matrix (char *buf, const pdf_tmatrix *M) +{ + int len; + int prec2 = MIN(dev_unit.precision + 2, DEV_PRECISION_MAX); + int prec0 = MAX(dev_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; +} + +int +pdf_sprint_rect (char *buf, const pdf_rect *rect) +{ + int len; + + len = p_dtoa(rect->llx, dev_unit.precision, buf); + buf[len++] = ' '; + len += p_dtoa(rect->lly, dev_unit.precision, buf+len); + buf[len++] = ' '; + len += p_dtoa(rect->urx, dev_unit.precision, buf+len); + buf[len++] = ' '; + len += p_dtoa(rect->ury, dev_unit.precision, buf+len); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + +int +pdf_sprint_coord (char *buf, const pdf_coord *p) +{ + int len; + + len = p_dtoa(p->x, dev_unit.precision, buf); + buf[len++] = ' '; + len += p_dtoa(p->y, dev_unit.precision, buf+len); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + +int +pdf_sprint_length (char *buf, double value) +{ + int len; + + len = p_dtoa(value, dev_unit.precision, buf); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + + +int +pdf_sprint_number (char *buf, double value) +{ + int len; + + len = p_dtoa(value, DEV_PRECISION_MAX, buf); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + + +static struct +{ + /* 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; + +} dev_param = { + 1, /* autorotate */ + 1, /* 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 + +static int motion_state = GRAPHICS_MODE; + +#define FORMAT_BUF_SIZE 4096 +static char format_buffer[FORMAT_BUF_SIZE]; + +/* + * 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) + +static struct { + + /* 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; +} text_state = { + -1, /* font */ + 0, /* offset */ + 0, 0, /* ref_x, ref_y */ + 0, 0, /* raise, leading */ + {0.0, 1.0, 0}, + + 0.0, /* Experimental boldness param */ + + 0, /* dir_mode */ + + /* internal */ + 0, /* force_reset */ + 0 /* 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[7]; /* 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 */ + + /* Compatibility */ + int mapc; /* Nasty workaround for Omega */ + + /* There are no font metric format supporting four-bytes + * charcter code. So we should provide an option to specify + * UCS group and plane. + */ + int ucs_group; + int ucs_plane; + + int is_unicode; +}; +static struct dev_font *dev_fonts = NULL; + +static int num_dev_fonts = 0; +static int max_dev_fonts = 0; +static int num_phys_fonts = 0; + +#define CURRENTFONT() ((text_state.font_id < 0) ? NULL : &(dev_fonts[text_state.font_id])) +#define GET_FONT(n) (&(dev_fonts[(n)])) + + +static void +dev_set_text_matrix (spt_t xpos, spt_t ypos, double slant, double extend, int rotate) +{ + pdf_tmatrix tm; + int len = 0; + + /* 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 * dev_unit.dvi2pts; + tm.f = ypos * dev_unit.dvi2pts; + + format_buffer[len++] = ' '; + len += pdf_sprint_matrix(format_buffer+len, &tm); + format_buffer[len++] = ' '; + format_buffer[len++] = 'T'; + format_buffer[len++] = 'm'; + + pdf_doc_add_page_content(format_buffer, len); /* op: Tm */ + + text_state.ref_x = xpos; + text_state.ref_y = ypos; + text_state.matrix.slant = slant; + text_state.matrix.extend = extend; + 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 (void) +{ + /* + * We need to reset the line matrix to handle slanted fonts. + */ + pdf_doc_add_page_content(" 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 (text_state.force_reset || + text_state.matrix.slant != 0.0 || + text_state.matrix.extend != 1.0 || + ROTATE_TEXT(text_state.matrix.rotate)) { + dev_set_text_matrix(0, 0, + text_state.matrix.slant, + text_state.matrix.extend, + text_state.matrix.rotate); + } + text_state.ref_x = 0; + text_state.ref_y = 0; + text_state.offset = 0; + text_state.force_reset = 0; +} + +static void +text_mode (void) +{ + switch (motion_state) { + case TEXT_MODE: + break; + case STRING_MODE: + pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */ + break; + case GRAPHICS_MODE: + reset_text_state(); + break; + } + motion_state = TEXT_MODE; + text_state.offset = 0; +} + +void +graphics_mode (void) +{ + switch (motion_state) { + case GRAPHICS_MODE: + break; + case STRING_MODE: + pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */ + /* continue */ + case TEXT_MODE: + pdf_doc_add_page_content(" ET", 3); /* op: ET */ + text_state.force_reset = 0; + text_state.font_id = -1; + break; + } + motion_state = GRAPHICS_MODE; +} + +static void +start_string (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; + + delx = xpos - text_state.ref_x; + dely = ypos - 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. + */ + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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) + */ + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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; + + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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); + + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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; + + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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); + + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx); + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_dely, &error_dely); + error_delx = -error_delx; + error_dely = -error_dely; + break; + } + pdf_doc_add_page_content(format_buffer, len); /* op: */ + /* + * dvipdfm wrongly using "TD" in place of "Td". + * The TD operator set leading, but we are not using T* etc. + */ + pdf_doc_add_page_content(text_state.is_mb ? " Td[<" : " Td[(", 5); /* op: Td */ + + /* Error correction */ + text_state.ref_x = xpos - error_delx; + text_state.ref_y = ypos - error_dely; + + text_state.offset = 0; +} + +static void +string_mode (spt_t xpos, spt_t ypos, double slant, double extend, int rotate) +{ + switch (motion_state) { + case STRING_MODE: + break; + case GRAPHICS_MODE: + reset_text_state(); + /* continue */ + case TEXT_MODE: + if (text_state.force_reset) { + dev_set_text_matrix(xpos, ypos, slant, extend, rotate); + pdf_doc_add_page_content(text_state.is_mb ? "[<" : "[(", 2); /* op: */ + text_state.force_reset = 0; + } else { + start_string(xpos, ypos, slant, extend, rotate); + } + break; + } + 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 +dev_set_font (int font_id) +{ + struct dev_font *font; + int text_rotate; + double font_scale; + int len; + int vert_dir, vert_font; + + /* text_mode() must come before text_state.is_mb is changed. */ + text_mode(); + + font = GET_FONT(font_id); + ASSERT(font); /* Caller should check font_id. */ + + text_state.is_mb = (font->format == PDF_FONTTYPE_COMPOSITE) ? 1 : 0; + + vert_font = font->wmode ? 1 : 0; + if (dev_param.autorotate) { + vert_dir = text_state.dir_mode; + } else { + vert_dir = vert_font; + } + text_rotate = (vert_font << 2)|vert_dir; + + if (font->slant != text_state.matrix.slant || + font->extend != text_state.matrix.extend || + ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) { + text_state.force_reset = 1; + } + text_state.matrix.slant = font->slant; + text_state.matrix.extend = font->extend; + 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 * dev_unit.dvi2pts; + len = sprintf(format_buffer, " /%s", font->short_name); /* space not necessary. */ + format_buffer[len++] = ' '; + len += p_dtoa(font_scale, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), format_buffer+len); + format_buffer[len++] = ' '; + format_buffer[len++] = 'T'; + format_buffer[len++] = 'f'; + pdf_doc_add_page_content(format_buffer, len); /* op: Tf */ + + if (font->bold > 0.0 || font->bold != text_state.bold_param) { + if (font->bold <= 0.0) + len = sprintf(format_buffer, " 0 Tr"); + else + len = sprintf(format_buffer, " 2 Tr %.2f w", font->bold); /* _FIXME_ */ + pdf_doc_add_page_content(format_buffer, len); /* op: Tr w */ + } + text_state.bold_param = font->bold; + + text_state.font_id = font_id; + + return 0; +} + + +/* Access text state parameters. + */ +#if 0 +int +pdf_dev_currentfont (void) +{ + return text_state.font_id; +} + +double +pdf_dev_get_font_ptsize (int font_id) +{ + struct dev_font *font; + + font = GET_FONT(font_id); + if (font) { + return font->sptsize * dev_unit.dvi2pts; + } + + return 1.0; +} +#endif + +int +pdf_dev_get_font_wmode (int font_id) +{ + struct dev_font *font; + + font = GET_FONT(font_id); + if (font) { + return font->wmode; + } + + return 0; +} + +static unsigned char sbuf0[FORMAT_BUF_SIZE]; +static unsigned char sbuf1[FORMAT_BUF_SIZE]; + +static int +handle_multibyte_string (struct dev_font *font, + const unsigned char **str_ptr, int *str_len, int ctype) +{ + const unsigned char *p; + int i, length; + + p = *str_ptr; + length = *str_len; + + /* _FIXME_ */ + if (font->is_unicode) { /* UCS-4 */ + if (ctype == 1) { + if (length * 4 >= FORMAT_BUF_SIZE) { + WARN("Too long string..."); + return -1; + } + for (i = 0; i < length; i++) { + sbuf1[i*4 ] = font->ucs_group; + sbuf1[i*4+1] = font->ucs_plane; + sbuf1[i*4+2] = '\0'; + sbuf1[i*4+3] = p[i]; + } + length *= 4; + } else if (ctype == 2) { + int len = 0; + + if (length * 2 >= FORMAT_BUF_SIZE) { + WARN("Too long string..."); + return -1; + } + for (i = 0; i < length; i += 2, len += 4) { + sbuf1[len ] = font->ucs_group; + if ((p[i] & 0xf8) == 0xd8) { + int c; + /* Check for valid surrogate pair. */ + if ((p[i] & 0xfc) != 0xd8 || i + 2 >= length || (p[i+2] & 0xfc) != 0xdc) { + WARN("Invalid surrogate p[%d]=%02X...", i, p[i]); + return -1; + } + c = (((p[i] & 0x03) << 10) | (p[i+1] << 2) | (p[i+2] & 0x03)) + 0x100; + sbuf1[len+1] = (c >> 8) & 0xff; + sbuf1[len+2] = c & 0xff; + i += 2; + } else { + sbuf1[len+1] = font->ucs_plane; + sbuf1[len+2] = p[i]; + } + sbuf1[len+3] = p[i+1]; + } + length = len; + } + p = sbuf1; + } else if (ctype == 1 && font->mapc >= 0) { + /* Omega workaround... + * Translate single-byte chars to double byte code space. + */ + if (length * 2 >= FORMAT_BUF_SIZE) { + WARN("Too long string..."); + return -1; + } + for (i = 0; i < length; i++) { + sbuf1[i*2 ] = (font->mapc & 0xff); + sbuf1[i*2+1] = p[i]; + } + length *= 2; + p = sbuf1; + } + + /* + * 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; + long 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; +} + + +static pdf_coord *dev_coords = NULL; +static int num_dev_coords = 0; +static int max_dev_coords = 0; + +void pdf_dev_get_coord(double *xpos, double *ypos) +{ + if (num_dev_coords > 0) { + *xpos = dev_coords[num_dev_coords-1].x; + *ypos = dev_coords[num_dev_coords-1].y; + } else { + *xpos = *ypos = 0.0; + } +} + +void pdf_dev_push_coord(double xpos, double ypos) +{ + if (num_dev_coords >= max_dev_coords) { + max_dev_coords += 4; + dev_coords = RENEW(dev_coords, max_dev_coords, pdf_coord); + } + dev_coords[num_dev_coords].x = xpos; + dev_coords[num_dev_coords].y = ypos; + num_dev_coords++; +} + +void pdf_dev_pop_coord(void) +{ + if (num_dev_coords > 0) num_dev_coords--; +} + +/* + * ctype: + * 0 byte-width of char can be variable and input string + * is properly encoded. + * n Single character cosumes n bytes in input string. + * + * _FIXME_ + * --> + * selectfont(font_name, point_size) and show_string(pos, string) + */ +void +pdf_dev_set_string (spt_t xpos, spt_t ypos, + const void *instr_ptr, int instr_len, + spt_t width, + int font_id, int ctype) +{ + 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 >= num_dev_fonts) { + ERROR("Invalid font: %d (%d)", font_id, num_dev_fonts); + return; + } + if (font_id != text_state.font_id) { + dev_set_font(font_id); + } + + font = CURRENTFONT(); + if (!font) { + ERROR("Currentfont not set."); + return; + } + + text_xorigin = text_state.ref_x; + text_yorigin = 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, ctype) < 0) { + ERROR("Error in converting input string..."); + return; + } + if (font->used_chars != NULL) { + for (i = 0; i < length; i += 2) + add_to_used_chars2(font->used_chars, + (unsigned short) (str_ptr[i] << 8)|str_ptr[i+1]); + } + } else { + if (font->used_chars != NULL) { + for (i = 0; i < length; i++) + font->used_chars[str_ptr[i]] = 1; + } + } + + if (num_dev_coords > 0) { + xpos -= bpt2spt(dev_coords[num_dev_coords-1].x); + ypos -= bpt2spt(dev_coords[num_dev_coords-1].y); + } + + /* + * 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 (text_state.dir_mode==0) { + /* Left-to-right */ + delh = text_xorigin + text_state.offset - xpos; + delv = ypos - text_yorigin; + } else if (text_state.dir_mode==1) { + /* Top-to-bottom */ + delh = ypos - text_yorigin + text_state.offset; + delv = xpos - text_xorigin; + } else { + /* Bottom-to-top */ + delh = ypos + text_yorigin + 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 (text_state.force_reset || + labs(delv) > dev_unit.min_bp_val || + labs(delh) > WORD_SPACE_MAX(font)) { + text_mode(); + 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 (motion_state != STRING_MODE) + string_mode(xpos, ypos, + font->slant, font->extend, 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(). + */ + text_state.offset -= + (spt_t) (kern * font->extend * (font->sptsize / 1000.0)); + format_buffer[len++] = text_state.is_mb ? '>' : ')'; + if (font->wmode) + len += p_itoa(-kern, format_buffer + len); + else { + len += p_itoa( kern, format_buffer + len); + } + format_buffer[len++] = text_state.is_mb ? '<' : '('; + pdf_doc_add_page_content(format_buffer, len); /* op: */ + len = 0; + } + + if (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; + format_buffer[len++] = ((first >= 10) ? first + 'W' : first + '0'); + format_buffer[len++] = ((second >= 10) ? second + 'W' : second + '0'); + } + } else { + len += pdfobj_escape_str(format_buffer + len, + FORMAT_BUF_SIZE - len, str_ptr, length); + } + /* I think if you really care about speed, you should avoid memcopy here. */ + pdf_doc_add_page_content(format_buffer, len); /* op: */ + + text_state.offset += width; +} + +void +pdf_init_device (double dvi2pts, int precision, int black_and_white) +{ + if (precision < 0 || + precision > DEV_PRECISION_MAX) + WARN("Number of decimal digits out of range [0-%d].", + DEV_PRECISION_MAX); + + if (precision < 0) { + dev_unit.precision = 0; + } else if (precision > DEV_PRECISION_MAX) { + dev_unit.precision = DEV_PRECISION_MAX; + } else { + dev_unit.precision = precision; + } + dev_unit.dvi2pts = dvi2pts; + dev_unit.min_bp_val = (long) ROUND(1.0/(ten_pow[dev_unit.precision]*dvi2pts), 1); + if (dev_unit.min_bp_val < 0) + dev_unit.min_bp_val = -dev_unit.min_bp_val; + + dev_param.colormode = (black_and_white ? 0 : 1); + + graphics_mode(); + pdf_color_clear_stack(); + pdf_dev_init_gstates(); + + num_dev_fonts = max_dev_fonts = 0; + dev_fonts = NULL; + num_dev_coords = max_dev_coords = 0; + dev_coords = NULL; +} + +void +pdf_close_device (void) +{ + if (dev_fonts) { + int i; + + for (i = 0; i < num_dev_fonts; i++) { + if (dev_fonts[i].tex_name) + RELEASE(dev_fonts[i].tex_name); + if (dev_fonts[i].resource) + pdf_release_obj(dev_fonts[i].resource); + dev_fonts[i].tex_name = NULL; + dev_fonts[i].resource = NULL; + } + RELEASE(dev_fonts); + } + if (dev_coords) RELEASE(dev_coords); + 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 (void) +{ + int i; + + for (i = 0; i < num_dev_fonts; i++) { + dev_fonts[i].used_on_this_page = 0; + } + + text_state.font_id = -1; + + text_state.matrix.slant = 0.0; + text_state.matrix.extend = 1.0; + text_state.matrix.rotate = TEXT_WMODE_HH; + + text_state.bold_param = 0.0; + + text_state.is_mb = 0; +} + +#if 0 +/* Not working */ +void +pdf_dev_set_origin (double phys_x, double phys_y) +{ + pdf_tmatrix M0, M1; + + pdf_dev_currentmatrix(&M0); + pdf_dev_currentmatrix(&M1); + pdf_invertmatrix(&M1); + M0.e = phys_x; M0.f = phys_y; + pdf_concatmatrix(&M1, &M0); + + pdf_dev_concat(&M1); +} +#endif + +void +pdf_dev_bop (const pdf_tmatrix *M) +{ + graphics_mode(); + + text_state.force_reset = 0; + + pdf_dev_gsave(); + pdf_dev_concat(M); + + pdf_dev_reset_fonts(); + pdf_dev_reset_color(0); +} + +void +pdf_dev_eop (void) +{ + int depth; + + graphics_mode(); + + 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. + * This may assign different resource name for same font at different + * point size even for scalable fonts. + */ +int +pdf_dev_locate_font (const char *font_name, spt_t ptsize) +{ + 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 < num_dev_fonts; i++) { + if (!strcmp(font_name, dev_fonts[i].tex_name) && ptsize == dev_fonts[i].sptsize) { + return i; + } + } + + /* + * Make sure we have room for a new one, even though we may not + * actually create one. + */ + if (num_dev_fonts >= max_dev_fonts) { + max_dev_fonts += 16; + dev_fonts = RENEW(dev_fonts, max_dev_fonts, struct dev_font); + } + + font = &dev_fonts[num_dev_fonts]; + + /* New font */ + mrec = pdf_lookup_fontmap_record(font_name); + + if (verbose > 1) + print_fontmap(font_name, mrec); + + font->font_id = pdf_font_findresource(font_name, ptsize * dev_unit.dvi2pts, mrec); + if (font->font_id < 0) + return -1; + + /* We found device font here. */ + font->short_name[0] = 'F'; + p_itoa(num_phys_fonts + 1, &font->short_name[1]); /* NULL terminated here */ + num_phys_fonts++; + + 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; + font->mapc = -1; + font->is_unicode = 0; + font->ucs_group = 0; + font->ucs_plane = 0; + + if (mrec) { + font->extend = mrec->opt.extend; + font->slant = mrec->opt.slant; + font->bold = mrec->opt.bold; + if (mrec->opt.mapc >= 0) + font->mapc = (mrec->opt.mapc >> 8) & 0xff; + else { + font->mapc = -1; + } + if (mrec->enc_name && + !strcmp(mrec->enc_name, "unicode")) { + font->is_unicode = 1; + if (mrec->opt.mapc >= 0) { + font->ucs_group = (mrec->opt.mapc >> 24) & 0xff; + font->ucs_plane = (mrec->opt.mapc >> 16) & 0xff; + } else { + font->ucs_group = 0; + font->ucs_plane = 0; + } + } else { + font->is_unicode = 0; + } + } + + return num_dev_fonts++; +} + + +/* This does not remember current stroking width. */ +static int +dev_sprint_line (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 * dev_unit.dvi2pts; + + len += p_dtoa(w, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), buf+len); + buf[len++] = ' '; + buf[len++] = 'w'; + buf[len++] = ' '; + len += dev_sprint_bp(buf+len, p0_x, NULL); + buf[len++] = ' '; + len += dev_sprint_bp(buf+len, p0_y, NULL); + buf[len++] = ' '; + buf[len++] = 'm'; + buf[len++] = ' '; + len += dev_sprint_bp(buf+len, p1_x, NULL); + buf[len++] = ' '; + len += dev_sprint_bp(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) +{ + int len = 0; + double width_in_bp; + + if (num_dev_coords > 0) { + xpos -= bpt2spt(dev_coords[num_dev_coords-1].x); + ypos -= bpt2spt(dev_coords[num_dev_coords-1].y); + } + + graphics_mode(); + + format_buffer[len++] = ' '; + format_buffer[len++] = 'q'; + format_buffer[len++] = ' '; + /* Don't use too thick line. */ + width_in_bp = ((width < height) ? width : height) * dev_unit.dvi2pts; + if (width_in_bp < 0.0 || /* Shouldn't happen */ + width_in_bp > PDF_LINE_THICKNESS_MAX) { + pdf_rect rect; + + rect.llx = dev_unit.dvi2pts * xpos; + rect.lly = dev_unit.dvi2pts * ypos; + rect.urx = dev_unit.dvi2pts * width; + rect.ury = dev_unit.dvi2pts * height; + len += pdf_sprint_rect(format_buffer+len, &rect); + format_buffer[len++] = ' '; + format_buffer[len++] = 'r'; + format_buffer[len++] = 'e'; + format_buffer[len++] = ' '; + 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 < dev_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(format_buffer+len, + height, + xpos, + ypos + height/2, + xpos + width, + ypos + height/2); + } else { + if (width < dev_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(format_buffer+len, + width, + xpos + width/2, + ypos, + xpos + width/2, + ypos + height); + } + } + format_buffer[len++] = ' '; + format_buffer[len++] = 'Q'; + pdf_doc_add_page_content(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) +{ + double dev_x, dev_y; + pdf_coord p0, p1, p2, p3; + double min_x, min_y, max_x, max_y; + + dev_x = x_user * dev_unit.dvi2pts; + dev_y = y_user * dev_unit.dvi2pts; + if (text_state.dir_mode) { + p0.x = dev_x - dev_unit.dvi2pts * depth; + p0.y = dev_y - dev_unit.dvi2pts * width; + p1.x = dev_x + dev_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 - dev_unit.dvi2pts * depth; + p1.x = dev_x + dev_unit.dvi2pts * width; + p1.y = p0.y; + p2.x = p1.x; + p2.y = dev_y + dev_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) +{ + return text_state.dir_mode; +} + +void +pdf_dev_set_dirmode (int text_dir) +{ + struct dev_font *font; + int text_rotate; + int vert_dir, vert_font; + + font = CURRENTFONT(); + + vert_font = (font && font->wmode) ? 1 : 0; + if (dev_param.autorotate) { + vert_dir = text_dir; + } else { + vert_dir = vert_font; + } + text_rotate = (vert_font << 2)|vert_dir; + + if (font && + ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) { + text_state.force_reset = 1; + } + + text_state.matrix.rotate = text_rotate; + text_state.dir_mode = text_dir; +} + +static void +dev_set_param_autorotate (int auto_rotate) +{ + struct dev_font *font; + int text_rotate, vert_font, vert_dir; + + font = CURRENTFONT(); + + vert_font = (font && font->wmode) ? 1 : 0; + if (auto_rotate) { + vert_dir = text_state.dir_mode; + } else { + vert_dir = vert_font; + } + text_rotate = (vert_font << 2)|vert_dir; + + if (ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) { + text_state.force_reset = 1; + } + text_state.matrix.rotate = text_rotate; + dev_param.autorotate = auto_rotate; +} + +int +pdf_dev_get_param (int param_type) +{ + int value = 0; + + switch (param_type) { + case PDF_DEV_PARAM_AUTOROTATE: + value = dev_param.autorotate; + break; + case PDF_DEV_PARAM_COLORMODE: + value = dev_param.colormode; + break; + default: + ERROR("Unknown device parameter: %d", param_type); + } + + return value; +} + +void +pdf_dev_set_param (int param_type, int value) +{ + switch (param_type) { + case PDF_DEV_PARAM_AUTOROTATE: + dev_set_param_autorotate(value); + break; + case PDF_DEV_PARAM_COLORMODE: + dev_param.colormode = value; /* 0 for B&W */ + break; + default: + ERROR("Unknown device parameter: %d", param_type); + } + + return; +} + + +int +pdf_dev_put_image (int id, + transform_info *p, + double ref_x, + double ref_y) +{ + char *res_name; + pdf_tmatrix M, M1; + pdf_rect r; + int len = 0; + + if (num_dev_coords > 0) { + ref_x -= dev_coords[num_dev_coords-1].x; + ref_y -= dev_coords[num_dev_coords-1].y; + } + + pdf_copymatrix(&M, &(p->matrix)); + M.e += ref_x; M.f += ref_y; + /* Just rotate by -90, but not tested yet. Any problem if M has scaling? */ + if (dev_param.autorotate && + 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; + } + + graphics_mode(); + pdf_dev_gsave(); + + pdf_ximage_scale_image(id, &M1, &r, p); + pdf_concatmatrix(&M, &M1); + pdf_dev_concat(&M); + + /* Clip */ + if (p->flags & INFO_DO_CLIP) { +#if 0 + pdf_dev_newpath(); + pdf_dev_moveto(r.llx, r.lly); + pdf_dev_lineto(r.urx, r.lly); + pdf_dev_lineto(r.urx, r.ury); + pdf_dev_lineto(r.llx, r.ury); + pdf_dev_closepath(); + pdf_dev_clip(); + pdf_dev_newpath(); +#else + pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly); +#endif + } + + res_name = pdf_ximage_get_resname(id); + len = sprintf(work_buffer, " /%s Do", res_name); + pdf_doc_add_page_content(work_buffer, len); /* op: Do */ + + 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; +} diff --git a/Build/source/texk/dvipdf-x/src/pdfdev.h b/Build/source/texk/dvipdf-x/src/pdfdev.h new file mode 100644 index 00000000000..705e603e114 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfdev.h @@ -0,0 +1,228 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 signed long 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); + + +extern void pdf_dev_set_verbose (void); + +/* 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); + +#if 0 +/* DVI interpreter knows text positioning in relative motion. + * However, pdf_dev_set_string() recieves text string with placement + * in absolute position in user space, and it convert absolute + * positioning back to relative positioning. It is quite wasteful. + * + * TeX using DVI register stack operation to do CR and then use down + * command for LF. DVI interpreter knows hint for current leading + * and others (raised or lowered), but they are mostly lost in + * pdf_dev_set_string(). + */ + +typedef struct +{ + int argc; + + struct { + int is_kern; /* kern or string */ + + spt_t kern; /* negative kern means space */ + + int offset; /* offset to sbuf */ + int length; /* length of string */ + } args[]; + + unsigned char sbuf[PDF_STRING_LEN_MAX]; + +} pdf_text_string; + +/* Something for handling raise, leading, etc. here. */ + +#endif + +/* 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, int ctype); +extern void pdf_dev_set_rule (spt_t xpos, spt_t ypos, + spt_t width, spt_t height); + +/* Place XObject */ +extern int pdf_dev_put_image (int xobj_id, + transform_info *p, double ref_x, double ref_y); + +/* The design_size and ptsize required by PK font support... + */ +extern int pdf_dev_locate_font (const char *font_name, spt_t ptsize); + +extern int pdf_dev_setfont (const char *font_name, spt_t ptsize); + +/* The following two routines are NOT WORKING. + * Dvipdfmx doesn't manage gstate well.. + */ +#if 0 +/* pdf_dev_translate() or pdf_dev_concat() should be used. */ +extern void pdf_dev_set_origin (double orig_x, double orig_y); +#endif +/* Always returns 1.0, please rename this. */ +extern double pdf_dev_scale (void); + +/* Access text state parameters. */ +#if 0 +extern int pdf_dev_currentfont (void); /* returns font_id */ +extern double pdf_dev_get_font_ptsize (int font_id); +#endif +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)) +#define pdf_dev_set_colormode(v) pdf_dev_set_param(PDF_DEV_PARAM_COLORMODE, (v)) + +/* + * For pdf_doc, pdf_draw and others. + */ + +/* Force reselecting font: + * XFrom (content grabbing) and Metapost support want them. + */ +extern void pdf_dev_reset_fonts (void); + +/* 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_get_coord(double *xpos, double *ypos); +extern void pdf_dev_push_coord(double xpos, double ypos); +extern void pdf_dev_pop_coord(void); + +#endif /* _PDFDEV_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/pdfdoc.c b/Build/source/texk/dvipdf-x/src/pdfdoc.c new file mode 100644 index 00000000000..862789ec714 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfdoc.c @@ -0,0 +1,2738 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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)... + */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" + +#include "numbers.h" + +#include "pdfobj.h" +#include "pdfparse.h" +#include "pdfnames.h" + +#include "pdfencrypt.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 int verbose = 0; + +static char manual_thumb_enabled = 0; +static char *thumb_basename = NULL; + +void +pdf_doc_enable_manual_thumbnails (void) +{ +#if HAVE_LIBPNG + manual_thumb_enabled = 1; +#else + WARN("Manual thumbnail is not supported without the libpng library."); +#endif +} + +static pdf_obj * +read_thumbnail (const char *thumb_filename) +{ + pdf_obj *image_ref; + int xobj_id; + FILE *fp; + + 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_findresource(thumb_filename, 0, NULL); + 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; +} + +void +pdf_doc_set_verbose (void) +{ + verbose++; + pdf_font_set_verbose(); + pdf_color_set_verbose(); + pdf_ximage_set_verbose(); +} + +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; + long page_no; + pdf_rect rect; +} pdf_bead; + +typedef struct pdf_article +{ + char *id; + pdf_obj *info; + long num_beads; + long 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; + + long num_entries; /* This is not actually total number of pages. */ + long max_entries; + pdf_page *entries; + } pages; + + struct { + pdf_olitem *first; + pdf_olitem *current; + int current_depth; + } outlines; + + struct { + long num_entries; + long max_entries; + pdf_article *entries; + } articles; + + struct name_dict *names; + + int check_gotos; + struct ht_table gotos; + + struct { + int outline_open_depth; + double annot_grow; + } opt; + + struct form_list_node *pending_forms; + +} 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, long size) +{ + if (size > MAXPAGES(p)) { + long 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 long 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; +} + +#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 long +compute_timezone_offset() +{ + const time_t now = time(NULL); + struct tm tm; + struct tm local; + time_t gmtoff; + + localtime_r(&now, &local); + gmtime_r(&now, &tm); + return (mktime(&local) - mktime(&tm)); +} + +#endif /* HAVE_TIMEZONE */ +#endif /* HAVE_TM_GMTOFF */ + +/* + * Docinfo + */ +static long +asn_date (char *date_string) +{ + long tz_offset; + time_t current_time; + struct tm *bd_time; + + time(¤t_time); + bd_time = localtime(¤t_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 */ + + sprintf(date_string, "D:%04d%02d%02d%02d%02d%02d%c%02ld'%02ld'", + 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) ? '+' : '-', labs(tz_offset) / 3600, + (labs(tz_offset) / 60) % 60); + + return strlen(date_string); +} + +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; + char *banner; + 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]); + } + } + } + + banner = NEW(strlen(PACKAGE)+strlen(VERSION)+4, char); + sprintf(banner, "%s (%s)", PACKAGE, 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]; + + asn_date(now); + 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); + } + + 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; + + if (!PDF_OBJ_INDIRECTTYPE(resource_ref)) { + WARN("Passed non indirect reference..."); + resource_ref = pdf_ref_obj(resource_ref); /* leak */ + } + resources = pdf_doc_get_page_resources(p, category); + duplicate = pdf_lookup_dict(resources, resource_name); + if (duplicate && pdf_compare_reference(duplicate, resource_ref)) { + WARN("Conflicting page resource found (page: %ld, category: %s, name: %s).", + pdf_doc_current_page_number(), category, resource_name); + WARN("Ignoring..."); + pdf_release_obj(resource_ref); + } 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, long num_pages, + pdf_obj *parent_ref) +{ + pdf_obj *self, *self_ref, *kids; + long 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++) { + long 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; + long 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; +} + +/* + * 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. + */ + +pdf_obj * +pdf_doc_get_page (pdf_file *pf, long page_no, long *count_p, + pdf_rect *bbox, pdf_obj **resources_p) { + pdf_obj *page_tree = NULL; + pdf_obj *resources = NULL, *box = NULL, *rotate = 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)) + goto error; + + { + long 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; + } + count = pdf_number_value(tmp); + pdf_release_obj(tmp); + if (count_p) + *count_p = count; + 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 *media_box = NULL, *crop_box = NULL, *kids, *tmp; + int depth = PDF_OBJ_MAX_DEPTH; + long 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, "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; + } + kids_length = pdf_array_length(kids); + + for (i = 0; i < kids_length; i++) { + long count; + + pdf_release_obj(page_tree); + page_tree = pdf_deref_obj(pdf_get_array(kids, i)); + if (!PDF_OBJ_DICTTYPE(page_tree)) + goto error; + + 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; + } + + if (page_idx < count) + break; + + page_idx -= count; + } + + pdf_release_obj(kids); + } + + if (!depth || kids_length == i) { + if (media_box) + pdf_release_obj(media_box); + if (crop_box) + pdf_release_obj(crop_box); + goto error; + } + + if (crop_box) + box = crop_box; + else + if (!(box = pdf_deref_obj(pdf_lookup_dict(page_tree, "ArtBox"))) && + !(box = pdf_deref_obj(pdf_lookup_dict(page_tree, "TrimBox"))) && + !(box = pdf_deref_obj(pdf_lookup_dict(page_tree, "BleedBox"))) && + media_box) { + box = media_box; + media_box = NULL; + } + if (media_box) + pdf_release_obj(media_box); + } + + if (!PDF_OBJ_ARRAYTYPE(box) || pdf_array_length(box) != 4 || + !PDF_OBJ_DICTTYPE(resources)) + goto error; + + if (PDF_OBJ_NUMBERTYPE(rotate)) { + if (pdf_number_value(rotate)) + WARN("<< /Rotate %d >> found. (Not supported yet)", + (int) pdf_number_value(rotate)); + pdf_release_obj(rotate); + rotate = NULL; + } else if (rotate) + goto error; + + { + 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); + goto error; + } + 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); + } + } + + pdf_release_obj(box); + + if (resources_p) + *resources_p = resources; + else if (resources) + pdf_release_obj(resources); + + return page_tree; + + error: + WARN("Cannot parse document. Broken PDF file?"); + error_silent: + if (box) + pdf_release_obj(box); + if (rotate) + pdf_release_obj(rotate); + if (resources) + pdf_release_obj(resources); + if (page_tree) + pdf_release_obj(page_tree); + + return NULL; +} + +#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->opt.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 "" + 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)->opt.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; + + 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); +#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, strlen(dest)); + 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, "%lx", ht_table_size(&pdoc.gotos)); + D_new = pdf_new_string(buf, strlen(buf)); + ht_append_table(&pdoc.gotos, dest, strlen(dest), 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; + long 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 (verbose && 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; +} + + +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; + double annot_grow = p->opt.annot_grow; + double xpos, ypos; + pdf_rect mediabox, annbox; + + page = doc_get_page_entry(p, page_no); + if (!page->annots) + page->annots = pdf_new_array(); + + pdf_doc_get_mediabox(page_no, &mediabox); + pdf_dev_get_coord(&xpos, &ypos); + annbox.llx = rect->llx - xpos; annbox.lly = rect->lly - ypos; + annbox.urx = rect->urx - xpos; annbox.ury = rect->ury - ypos; + + if (annbox.llx < mediabox.llx || annbox.urx > mediabox.urx || + annbox.lly < mediabox.lly || annbox.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]", + annbox.llx, annbox.lly, annbox.urx, annbox.ury); + WARN("Maybe incorrect paper size specified."); + } + if (annbox.llx > annbox.urx || annbox.lly > annbox.ury) { + WARN("Rectangle with negative width/height: [%g %g %g %g]", + annbox.llx, annbox.lly, annbox.urx, annbox.ury); + } + + rect_array = pdf_new_array(); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.llx - annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.lly - annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.urx + annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.ury + annot_grow, 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; +} + +#if 0 +void +pdf_doc_end_article (const char *article_id) +{ + return; /* no-op */ +} +#endif + +static pdf_bead * +find_bead (pdf_article *article, const char *bead_id) +{ + pdf_bead *bead; + long 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, long page_no, const pdf_rect *rect) +{ + pdf_doc *p = &pdoc; + pdf_article *article; + pdf_bead *bead; + long 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; + long 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) { + long 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; +} + +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; +} + +long +pdf_doc_current_page_number (void) +{ + pdf_doc *p = &pdoc; + + return (long) (PAGECOUNT(p) + 1); +} + +pdf_obj * +pdf_doc_ref_page (unsigned long 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; + long 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 (manual_thumb_enabled) { + char *thumb_filename; + pdf_obj *thumb_ref; + + thumb_filename = NEW(strlen(thumb_basename)+7, char); + sprintf(thumb_filename, "%s.%ld", + 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; + +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; +} + +static char *doccreator = NULL; /* Ugh */ + +void +pdf_open_document (const char *filename, + int do_encryption, + double media_width, double media_height, + double annot_grow_amount, int bookmark_open_depth, + int check_gotos) +{ + pdf_doc *p = &pdoc; + + pdf_out_init(filename, do_encryption); + + pdf_doc_init_catalog(p); + + p->opt.annot_grow = annot_grow_amount; + p->opt.outline_open_depth = bookmark_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 (doccreator) { + pdf_add_dict(p->info, + pdf_new_name("Creator"), + pdf_new_string(doccreator, strlen(doccreator))); + RELEASE(doccreator); doccreator = NULL; + } + + pdf_doc_init_bookmarks(p, bookmark_open_depth); + pdf_doc_init_articles (p); + pdf_doc_init_names (p, check_gotos); + pdf_doc_init_page_tree(p, media_width, media_height); + + pdf_doc_set_bgcolor(NULL); + + if (do_encryption) { + pdf_obj *encrypt = pdf_encrypt_obj(); + pdf_set_encrypt(encrypt); + pdf_release_obj(encrypt); + } + pdf_set_id(pdf_enc_id_array()); + + /* Create a default name for thumbnail image files */ + if (manual_thumb_enabled) { + if (strlen(filename) > 4 && + !strncmp(".pdf", filename + strlen(filename) - 4, 4)) { + thumb_basename = NEW(strlen(filename)-4+1, char); + strncpy(thumb_basename, filename, strlen(filename)-4); + thumb_basename[strlen(filename)-4] = 0; + } else { + thumb_basename = NEW(strlen(filename)+1, char); + strcpy(thumb_basename, filename); + } + } + + p->pending_forms = NULL; + + return; +} + +void +pdf_doc_set_creator (const char *creator) +{ + if (!creator || + creator[0] == '\0') + return; + + doccreator = NEW(strlen(creator)+1, char); + strcpy(doccreator, creator); /* Ugh */ +} + + +void +pdf_close_document (void) +{ + pdf_doc *p = &pdoc; + + /* + * 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_out_flush(); + + if (thumb_basename) + RELEASE(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. */ + xobj_id = pdf_ximage_defineresource(ident, + PDF_XOBJECT_TYPE_FORM, + &info, pdf_ref_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(); + pdf_dev_reset_color(1); /* force color operators to be added to stream */ + + 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(); + pdf_dev_reset_color(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(); + breaking_state.annot_dict = NULL; +} + +void +pdf_doc_break_annot (void) +{ + if (breaking_state.dirty) { + pdf_obj *annot_dict; + + /* Copy dict */ + annot_dict = pdf_new_dict(); + pdf_merge_dict(annot_dict, breaking_state.annot_dict); + pdf_doc_add_annot(pdf_doc_current_page_number(), &(breaking_state.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 (long pg_start, + const char *type, + const void *prefix, int prfx_len, long 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/dvipdf-x/src/pdfdoc.h b/Build/source/texk/dvipdf-x/src/pdfdoc.h new file mode 100644 index 00000000000..2281f036fd2 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfdoc.h @@ -0,0 +1,143 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +#define PDF_DOC_GRABBING_NEST_MAX 4 + +extern void pdf_doc_set_verbose (void); + +extern void pdf_open_document (const char *filename, + int do_encryption, + double media_width, double media_height, + double annot_grow_amount, int bookmark_open_depth, + int check_gotos); +extern void pdf_close_document (void); + + +/* PDF document metadata */ +extern void pdf_doc_set_creator (const char *creator); + + +/* 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 pdf_obj *pdf_doc_get_page (pdf_file *pf, long page_no, long *count_p, + pdf_rect *bbox, pdf_obj **resources_p); + +extern long pdf_doc_current_page_number (void); +extern pdf_obj *pdf_doc_current_page_resources (void); + +extern pdf_obj *pdf_doc_ref_page (unsigned long 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_get_mediabox (unsigned page_no, 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); +#if 0 +extern void pdf_doc_end_article (const char *article_id); /* Do nothing... */ +#endif +extern void pdf_doc_make_article (const char *article_id, + const char **bead_order, int num_beads); +extern void pdf_doc_add_bead (const char *article_id, + const char *bead_id, + long 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 dest_is_new); + +/* 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 (long page_start, + const char *type, + const void *prefix, int pfrx_len, + long counter_start); +#endif + +/* Similar to bop_content */ +#include "pdfcolor.h" +extern void pdf_doc_set_bgcolor (const pdf_color *color); + +#endif /* _PDFDOC_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/pdfdraw.c b/Build/source/texk/dvipdf-x/src/pdfdraw.c new file mode 100644 index 00000000000..de5b4dc7f11 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfdraw.c @@ -0,0 +1,1811 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +#include "system.h" +#include "error.h" +#include "mem.h" +#include "mfileio.h" +#include "dpxutil.h" +#include "numbers.h" + +#include "pdfdoc.h" +#include "pdfdev.h" +#include "pdfcolor.h" + +#include "pdfdraw.h" + +#if 1 +typedef void pdf_dev; +#endif + + +/* + * 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) < 1.e-8) { +#if 1 + WARN("Inverting matrix with zero determinant..."); +#endif + 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); + + 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; +} + +#if 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; +} +#endif + +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) < 1.e-8) { + 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); + } + + 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) + + +static char fmt_buf[1024]; /* FIXME */ +#define FORMAT_BUFF_PTR(p) fmt_buf +#define FORMAT_BUFF_LEN(p) 1024 + +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) < 1.e-8 || + fabs(r_y) < 1.e-8) + 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) < 1.e-8) + 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)) < 1.e-8) { + 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 (pdf_dev *P, + const pdf_rect *r, + const pdf_tmatrix *M, + char opchr + ) +{ + char *buf = FORMAT_BUFF_PTR(P); + 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(); + + buf[len++] = ' '; + if (!isclip) { + buf[len++] = 'q'; + if (M) { + buf[len++] = ' '; + len += pdf_sprint_matrix(buf + len, M); + buf[len++] = ' '; + buf[len++] = 'c'; buf[len++] = 'm'; + } + buf[len++] = ' '; + } + buf[len++] = 'n'; + + 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; + + buf[len++] = ' '; + buf[len++] = isclip ? 'n' : 'Q'; + + pdf_doc_add_page_content(buf, len); /* op: q cm n re Q */ + + return 0; +} + +/* FIXME */ +static int +pdf_dev__flushpath (pdf_dev *P, + pdf_path *pa, + char opchr, + int rule, + int ignore_rule) +{ + pa_elem *pe, *pe1; + char *b = FORMAT_BUFF_PTR(P); + long b_len = FORMAT_BUFF_LEN(P); + 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; +} + + +/* 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; + long flags; +} pdf_gstate; + + +typedef struct m_stack_elem +{ + void *data; + struct m_stack_elem *prev; +} m_stack_elem; + +typedef struct m_stack +{ + int size; + m_stack_elem *top; + m_stack_elem *bottom; +} m_stack; + +static void +m_stack_init (m_stack *stack) +{ + ASSERT(stack); + + stack->size = 0; + stack->top = NULL; + stack->bottom = NULL; + + return; +} + +static void +m_stack_push (m_stack *stack, void *data) +{ + m_stack_elem *elem; + + ASSERT(stack); + + elem = NEW(1, m_stack_elem); + elem->prev = stack->top; + elem->data = data; + + stack->top = elem; + if (stack->size == 0) + stack->bottom = elem; + + stack->size++; + + return; +} + +static void * +m_stack_pop (m_stack *stack) +{ + m_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; +} + +static void * +m_stack_top (m_stack *stack) +{ + void *data; + + ASSERT(stack); + + if (stack->size == 0) + return NULL; + + data = stack->top->data; + + return data; +} + +#define m_stack_depth(s) ((s)->size) + +static m_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); + + return; +} + +static void +clear_a_gstate (pdf_gstate *gs) +{ + clear_a_path(&gs->path); + 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); + + return; +} + +void +pdf_dev_init_gstates (void) +{ + pdf_gstate *gs; + + m_stack_init(&gs_stack); + + gs = NEW(1, pdf_gstate); + init_a_gstate(gs); + + m_stack_push(&gs_stack, gs); /* Initial state */ + + return; +} + +void +pdf_dev_clear_gstates (void) +{ + pdf_gstate *gs; + + if (m_stack_depth(&gs_stack) > 1) /* at least 1 elem. */ + WARN("GS stack depth is not zero at the end of the document."); + + while ((gs = m_stack_pop(&gs_stack)) != NULL) { + clear_a_gstate(gs); + RELEASE(gs); + } + return; +} + +int +pdf_dev_gsave (void) +{ + pdf_gstate *gs0, *gs1; + + gs0 = m_stack_top(&gs_stack); + gs1 = NEW(1, pdf_gstate); + init_a_gstate(gs1); + copy_a_gstate(gs1, gs0); + m_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 (m_stack_depth(&gs_stack) <= 1) { /* Initial state at bottom */ + WARN("Too many grestores."); + return -1; + } + + gs = m_stack_pop(&gs_stack); + clear_a_gstate(gs); + RELEASE(gs); + + pdf_doc_add_page_content(" Q", 2); /* op: Q */ + + pdf_dev_reset_fonts(); + + return 0; +} + + +int +pdf_dev_push_gstate (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs0; + + gs0 = NEW(1, pdf_gstate); + + init_a_gstate(gs0); + + m_stack_push(gss, gs0); + + return 0; +} + + +int +pdf_dev_pop_gstate (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs; + + if (m_stack_depth(gss) <= 1) { /* Initial state at bottom */ + WARN("Too many grestores."); + return -1; + } + + gs = m_stack_pop(gss); + clear_a_gstate(gs); + RELEASE(gs); + + return 0; +} + + +int +pdf_dev_current_depth (void) +{ + return (m_stack_depth(&gs_stack) - 1); /* 0 means initial state */ +} + +void +pdf_dev_grestore_to (int depth) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs; + + ASSERT(depth >= 0); + + if (m_stack_depth(gss) > depth + 1) { + WARN("Closing pending transformations at end of page/XObject."); + } + + while (m_stack_depth(gss) > depth + 1) { + pdf_doc_add_page_content(" Q", 2); /* op: Q */ + gs = m_stack_pop(gss); + clear_a_gstate(gs); + RELEASE(gs); + } + pdf_dev_reset_fonts(); + + return; +} + +int +pdf_dev_currentpoint (pdf_coord *p) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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 */ + +/* + * 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 = m_stack_top(&gs_stack); + pdf_color *current = mask ? &gs->fillcolor : &gs->strokecolor; + + ASSERT(pdf_color_is_valid(color)); + + 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_to_string(color, fmt_buf); + fmt_buf[len++] = ' '; + switch (pdf_color_type(color)) { + case PDF_COLORSPACE_TYPE_RGB: + fmt_buf[len++] = 'R' | mask; + fmt_buf[len++] = 'G' | mask; + break; + case PDF_COLORSPACE_TYPE_CMYK: + fmt_buf[len++] = 'K' | mask; + break; + case PDF_COLORSPACE_TYPE_GRAY: + fmt_buf[len++] = 'G' | mask; + break; + default: /* already verified the given color */ + break; + } + pdf_doc_add_page_content(fmt_buf, len); /* op: RG K G rg k g */ + + pdf_color_copycolor(current, color); +} + +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); +} + +int +pdf_dev_concat (const pdf_tmatrix *M) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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 = FORMAT_BUFF_PTR(NULL); + int len = 0; + + ASSERT(M); + + /* Adobe Reader erases page content if there are + * non invertible transformation. + */ + if (fabs(detP(M)) < 1.0e-8) { + 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; + } + + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_path *cpa = &gs->path; + + return pdf_dev__flushpath(NULL, cpa, 'W', PDF_FILL_RULE_NONZERO, 0); +} + +int +pdf_dev_eoclip (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_path *cpa = &gs->path; + + return pdf_dev__flushpath(NULL, cpa, 'W', PDF_FILL_RULE_EVENODD, 0); +} + +int +pdf_dev_flushpath (char p_op, int fill_rule) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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(NULL, cpa, p_op, fill_rule, 1); + pdf_path__clearpath(cpa); + + gs->flags &= ~GS_FLAG_CURRENTPOINT_SET; + + return error; +} + +int +pdf_dev_newpath (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_tmatrix *CTM = &gs->matrix; + + ASSERT(p); + + pdf_coord__transform(p, (M ? M : CTM)); + + return; +} + +#if 0 +void +pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_tmatrix *CTM = &gs->matrix; + + ASSERT(p); + + pdf_coord__itransform(p, (M ? M : CTM)); + + return; +} +#endif + +int +pdf_dev_arc (double c_x , double c_y, double r, + double a_0 , double a_1) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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); +} + + +#if 0 +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(NULL, &r, M, 'S'); +} +#endif + +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(NULL, &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(NULL, &r, NULL, 'W'); +} diff --git a/Build/source/texk/dvipdf-x/src/pdfdraw.h b/Build/source/texk/dvipdf-x/src/pdfdraw.h new file mode 100644 index 00000000000..a2b8638a742 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfdraw.h @@ -0,0 +1,167 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); + + +#if 0 +extern int pdf_dev_rectstroke (double x, double y, + double w, double h, + const pdf_tmatrix *M /* optional */ + ); +#endif +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); + +#define pdf_dev_fill() pdf_dev_flushpath('f', PDF_FILL_RULE_NONZERO) +#define pdf_dev_eofill() pdf_dev_flushpath('f', PDF_FILL_RULE_EVENODD) +#define pdf_dev_stroke() pdf_dev_flushpath('S', PDF_FILL_RULE_NONZERO) +#define pdf_dev_fillstroke() pdf_dev_flushpath('B', PDF_FILL_RULE_NONZERO) + +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); +#if 0 +extern void pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M); +#endif + +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); +#define pdf_dev_grestoreall() pdf_dev_grestore_to(0); + +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_reset_color (int force); + +#endif /* _PDF_DRAW_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/pdfencrypt.c b/Build/source/texk/dvipdf-x/src/pdfencrypt.c new file mode 100644 index 00000000000..bd610d7a69b --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfencrypt.c @@ -0,0 +1,537 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#ifdef WIN32 +#include +#define getch _getch +#else /* !WIN32 */ +#include +#endif /* WIN32 */ + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "pdfobj.h" +#include "dpxcrypt.h" + +#include "pdfencrypt.h" + +#define MAX_KEY_LEN 16 +#define MAX_STR_LEN 32 + +static unsigned char algorithm, revision, key_size; +static long permission; + +static unsigned char key_data[MAX_KEY_LEN], id_string[MAX_KEY_LEN]; +static unsigned char opwd_string[MAX_STR_LEN], upwd_string[MAX_STR_LEN]; + +static unsigned long current_label = 0; +static unsigned current_generation = 0; + +static ARC4_KEY key; +static MD5_CONTEXT md5_ctx; + +static unsigned char md5_buf[MAX_KEY_LEN], key_buf[MAX_KEY_LEN]; +static unsigned char in_buf[MAX_STR_LEN], out_buf[MAX_STR_LEN]; + +static const unsigned char padding_string[MAX_STR_LEN] = { + 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 +}; + +static char owner_passwd[MAX_PWD_LEN], user_passwd[MAX_PWD_LEN]; + +static unsigned char verbose = 0; + +void pdf_enc_set_verbose (void) +{ + if (verbose < 255) verbose++; +} + +#define PRODUCER "%s-%s, Copyright \251 2002-2010 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata" +void pdf_enc_compute_id_string (char *dviname, char *pdfname) +{ + char *date_string, *producer; + time_t current_time; + struct tm *bd_time; + + MD5_init(&md5_ctx); + + date_string = NEW (15, char); + time(¤t_time); + bd_time = localtime(¤t_time); + sprintf (date_string, "%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); + MD5_write(&md5_ctx, (unsigned char *)date_string, strlen(date_string)); + RELEASE (date_string); + + producer = NEW (strlen(PRODUCER)+strlen(PACKAGE)+strlen(VERSION), char); + sprintf(producer, PRODUCER, PACKAGE, VERSION); + MD5_write(&md5_ctx, (unsigned char *)producer, strlen(producer)); + RELEASE (producer); + + MD5_write(&md5_ctx, (unsigned char *)dviname, strlen(dviname)); + MD5_write(&md5_ctx, (unsigned char *)pdfname, strlen(pdfname)); + MD5_final(id_string, &md5_ctx); +} + +static void passwd_padding (unsigned char *src, unsigned char *dst) +{ + register int len = strlen((char *)src); + + if (len > MAX_STR_LEN) + len = MAX_STR_LEN; + + memcpy(dst, src, len); + memcpy(dst+len, padding_string, MAX_STR_LEN-len); +} + +static void compute_owner_password (void) +{ + register unsigned char i, j; + /* + * Algorithm 3.3 Computing the encryption dictionary's O (owner password) + * value + * + * 1. Pad or truncate the owner password string as described in step 1 + * of Algorithm 3.2. If there is no owner password, use the user + * password instead. (See implementation note 17 in Appendix H.) + */ + passwd_padding((unsigned char *)(strlen(owner_passwd) > 0 ? owner_passwd : user_passwd), in_buf); + /* + * 2. Initialize the MD5 hash function and pass the result of step 1 + * as input to this function. + */ + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, in_buf, MAX_STR_LEN); + MD5_final(md5_buf, &md5_ctx); + /* + * 3. (Revision 3 only) Do the following 50 times: Take the output + * from the previous MD5 hash and pass it as input into a new + * MD5 hash. + */ + if (revision == 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_ctx); + MD5_write(&md5_ctx, md5_buf, key_size); + MD5_final(md5_buf, &md5_ctx); + } + /* + * 4. Create an RC4 encryption key using the first n bytes of the output + * from the final MD5 hash, where n is always 5 for revision 2 but + * for revision 3 depends on the value of the encryption dictionary's + * Length entry. + */ + ARC4_set_key(&key, key_size, md5_buf); + /* + * 5. Pad or truncate the user password string as described in step 1 + * of Algorithm 3.2. + */ + passwd_padding((unsigned char *)user_passwd, in_buf); + /* + * 6. Encrypt the result of step 5, using an RC4 encryption function + * with the encryption key obtained in step 4. + */ + ARC4(&key, MAX_STR_LEN, in_buf, out_buf); + /* + * 7. (Revision 3 only) Do the following 19 times: Take the output + * from the previous invocation of the RC4 function and pass it + * as input to a new invocation of the function; use an encryption + * key generated by taking each byte of the encryption key obtained + * in step 4 and performing an XOR (exclusive or) operation between + * that byte and the single-byte value of the iteration counter + * (from 1 to 19). + */ + if (revision == 3) + for (i = 1; i <= 19; i++) { + memcpy(in_buf, out_buf, MAX_STR_LEN); + for (j = 0; j < key_size; j++) + key_buf[j] = md5_buf[j] ^ i; + ARC4_set_key(&key, key_size, key_buf); + ARC4(&key, MAX_STR_LEN, in_buf, out_buf); + } + /* + * 8. Store the output from the final invocation of the RC4 function + * as the value of the O entry in the encryption dictionary. + */ + memcpy(opwd_string, out_buf, MAX_STR_LEN); +} + +static void compute_encryption_key (unsigned char *pwd) +{ + register unsigned char i; + /* + * Algorithm 3.2 Computing an encryption key + * + * 1. Pad or truncate the password string to exactly 32 bytes. If the + * password string is more than 32 bytes long, use only its first + * 32 bytes; if it is less than 32 bytes long, pad it by appending + * the required number of additional bytes from the beginning of + * the following padding string: + * + * < 28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08 + * 2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A > + * + * That is, if the password string is n bytes long, append the + * first 32 - n bytes of the padding string to the end of the + * password string. If the password string is empty (zero-length), + * meaning there is no user password, substitute the entire + * padding string in its place. + */ + passwd_padding(pwd, in_buf); + /* + * 2. Initialize the MD5 hash function and pass the result of step 1 + * as input to this fuction. + */ + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, in_buf, MAX_STR_LEN); + /* + * 3. Pass the value of the encryption dictionary's O entry to the + * MD5 hash function. (Algorithm 3.3 shows how the O value is + * computed.) + */ + MD5_write(&md5_ctx, opwd_string, MAX_STR_LEN); + /* + * 4. Treat the value of the P entry as an unsigned 4-byte integer + * and pass these bytes to the MD5 hash function, low-order byte + * first. + */ + in_buf[0] = (unsigned char)(permission) & 0xFF; + in_buf[1] = (unsigned char)(permission >> 8) & 0xFF; + in_buf[2] = (unsigned char)(permission >> 16) & 0xFF; + in_buf[3] = (unsigned char)(permission >> 24) & 0xFF; + MD5_write(&md5_ctx, in_buf, 4); + /* + * 5. Pass the first element of the file's file identifier array + * (the value of the ID entry in the document's trailer dictionary; + * see Table 3.12 on page 68) to the MD5 hash function and + * finish the hash. + */ + MD5_write(&md5_ctx, id_string, MAX_KEY_LEN); + MD5_final(md5_buf, &md5_ctx); + /* + * 6. (Revision 3 only) Do the following 50 times; Take the output from + * the previous MD5 hash and pass it as input into a new MD5 hash. + */ + if (revision == 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_ctx); + MD5_write(&md5_ctx, md5_buf, key_size); + MD5_final(md5_buf, &md5_ctx); + } + /* + * 7. Set the encryption key to the first n bytes of the output from + * the final MD5 hash, where n is always 5 for revision 2 but for + * revision 3 depends on the value of the encryption dictionary's + * Length entry. + */ + memcpy(key_data, md5_buf, key_size); +} + +static void compute_user_password (void) +{ + register unsigned char i, j; + /* + * Algorithm 3.4 Computing the encryption dictionary's U (user password) + * value (Revision 2) + * + * 1. Create an encryption key based on the user password string, as + * described in Algorithm 3.2. + * + * 2. Encrypt the 32-byte padding string shown in step 1 of Algorithm + * 3.2, using an RC4 encryption fuction with the encryption key from + * the preceeding step. + * + * 3. Store the result of step 2 as the value of the U entry in the + * encryption dictionary. + */ + /* + * Algorithm 3.5 Computing the encryption dictionary's U (user password) + * value (Revision 3) + * + * 1. Create an encryption key based on the user password string, as + * described in Algorithm 3.2. + * + * 2. Initialize the MD5 hash function and pass the 32-byte padding + * string shown in step 1 of Algorithm 3.2 as input to this function. + * + * 3. Pass the first element of the file's file identifier array (the + * value of the ID entry in the document's trailer dictionary; see + * Table 3.12 on page 68) to the hash function and finish the hash. + * + * 4. Encrypt the 16-byte result of the hash, using an RC4 encryption + * function with the encryption key from step 1. + * + * 5. Do the following 19 times: Take the output from the previous + * invocation of the RC4 function and pass it as input to a new + * invocation of the function; use an encryption key generated by + * taking each byte of the original encryption key (obtained in + * step 1) and performing an XOR (exclusive or) operation between + * that byte and the single-byte value of the iteration counter + * (from 1 to 19). + * + * 6. Append 16 bytes of arbitrary padding to the output from the + * final invocation of the RC4 function and store the 32-byte + * result as the value of the U entry in the encryption dictionary. + */ + compute_encryption_key((unsigned char *)user_passwd); + + switch (revision) { + case 2: + ARC4_set_key(&key, key_size, key_data); + ARC4(&key, MAX_STR_LEN, padding_string, out_buf); + break; + case 3: + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, padding_string, MAX_STR_LEN); + + MD5_write(&md5_ctx, id_string, MAX_KEY_LEN); + MD5_final(md5_buf, &md5_ctx); + + ARC4_set_key(&key, key_size, key_data); + ARC4(&key, MAX_KEY_LEN, md5_buf, out_buf); + + for (i = 1; i <= 19; i++) { + memcpy(in_buf, out_buf, MAX_KEY_LEN); + for (j = 0; j < key_size; j++) + key_buf[j] = key_data[j] ^ i; + ARC4_set_key(&key, key_size, key_buf); + ARC4(&key, MAX_KEY_LEN, in_buf, out_buf); + } + break; + default: + ERROR("Invalid revision number.\n"); + } + + memcpy(upwd_string, out_buf, MAX_STR_LEN); +} + +#ifdef WIN32 +static char *getpass (const char *prompt) +{ + static char pwd_buf[128]; + 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') + break; + fputs("*", stderr); + fflush(stderr); + } + pwd_buf[i] = '\0'; + fputs("\n", stderr); + return pwd_buf; +} +#endif + +void pdf_enc_set_passwd (unsigned bits, unsigned perm, const char *owner_pw, const char *user_pw) +{ + char *retry_passwd; + + if (owner_pw) { + strncpy(owner_passwd, owner_pw, MAX_PWD_LEN); + } else + while (1) { + strncpy(owner_passwd, getpass("Owner password: "), MAX_PWD_LEN); + retry_passwd = getpass("Re-enter owner password: "); + if (!strncmp(owner_passwd, retry_passwd, MAX_PWD_LEN)) + break; + fputs("Password is not identical.\nTry again.\n", stderr); + fflush(stderr); + } + + if (user_pw) { + strncpy(user_passwd, user_pw, MAX_PWD_LEN); + } else + while (1) { + strncpy(user_passwd, getpass("User password: "), MAX_PWD_LEN); + retry_passwd = getpass("Re-enter user password: "); + if (!strncmp(user_passwd, retry_passwd, MAX_PWD_LEN)) + break; + fputs("Password is not identical.\nTry again.\n", stderr); + fflush(stderr); + } + + key_size = (unsigned char)(bits / 8); + algorithm = (key_size == 5 ? 1 : 2); + permission = (long) (perm | 0xC0U); + revision = ((algorithm == 1 && permission < 0x100L) ? 2 : 3); + if (revision == 3) + permission |= ~0xFFFL; + + compute_owner_password(); + compute_user_password(); +} + +void pdf_encrypt_data (unsigned char *data, unsigned long len) +{ + unsigned char *result; + + memcpy(in_buf, key_data, key_size); + in_buf[key_size] = (unsigned char)(current_label) & 0xFF; + in_buf[key_size+1] = (unsigned char)(current_label >> 8) & 0xFF; + in_buf[key_size+2] = (unsigned char)(current_label >> 16) & 0xFF; + in_buf[key_size+3] = (unsigned char)(current_generation) & 0xFF; + in_buf[key_size+4] = (unsigned char)(current_generation >> 8) & 0xFF; + + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, in_buf, key_size+5); + MD5_final(md5_buf, &md5_ctx); + + result = NEW (len, unsigned char); + ARC4_set_key(&key, (key_size > 10 ? MAX_KEY_LEN : key_size+5), md5_buf); + ARC4(&key, len, data, result); + memcpy(data, result, len); + RELEASE (result); +} + +pdf_obj *pdf_encrypt_obj (void) +{ + pdf_obj *doc_encrypt; + +#ifdef DEBUG + fprintf (stderr, "(pdf_encrypt_obj)"); +#endif + + doc_encrypt = pdf_new_dict (); + + /* KEY : Filter + * TYPE : name + * VALUE: (Required) The name of the security handler for this document; + * see below. Default value: Standard, for the built-in security + * handler. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("Filter"), + pdf_new_name ("Standard")); + /* KEY : V + * TYPE : number + * VALUE: (Optional but strongly recommended) A code specifying the + * algorithm to be used in encrypting and decrypting the document: + * 0 An algorithm that is undocumented and no longer supported, + * and whose use is strongly discouraged. + * 1 Algorithm 3.1 on page 73, with an encryption key length + * of 40 bits; see below. + * 2 (PDF 1.4) Algorithm 3.1 on page 73, but allowing encryption + * key lengths greater than 40 bits. + * 3 (PDF 1.4) An unpublished algorithm allowing encryption key + * lengths ranging from 40 to 128 bits. (This algorithm is + * unpublished as an export requirement of the U.S. Department + * of Commerce.) + * The default value if this entry is omitted is 0, but a value + * of 1 or greater is strongly recommended. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("V"), + pdf_new_number (algorithm)); + /* KEY : Length + * TYPE : integer + * VALUE: (Optional; PDF 1.4; only if V is 2 or 3) The length of the + * encryption key, in bits. The value must be a multiple of 8, + * in the range 40 to 128. Default value: 40. + */ + if (algorithm > 1) + pdf_add_dict (doc_encrypt, + pdf_new_name ("Length"), + pdf_new_number (key_size * 8)); + /* KEY : R + * TYPE : number + * VALUE: (Required) A number specifying which revision of the standard + * security handler should be used to interpret this dictionary. + * The revison number should be 2 if the document is encrypted + * with a V value less than 2; otherwise this value should be 3. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("R"), + pdf_new_number (revision)); + /* KEY : O + * TYPE : string + * VALUE: (Required) A 32-byte string, based on both the owner and + * user passwords, that is used in computing the encryption + * key and in determining whether a valid owner password was + * entered. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("O"), + pdf_new_string (opwd_string, 32)); + /* KEY : U + * TYPE : string + * VALUE: (Required) A 32-byte string, based on the user password, + * that is used in determining whether to prompt the user + * for a password and, if so, whether a valid user or owner + * password was entered. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("U"), + pdf_new_string (upwd_string, 32)); + /* KEY : P + * TYPE : (signed 32 bit) integer + * VALUE: (Required) A set of flags specifying which operations are + * permitted when the document is opened with user access. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("P"), + pdf_new_number (permission)); + + return doc_encrypt; +} + +pdf_obj *pdf_enc_id_array (void) +{ + pdf_obj *id = pdf_new_array(); + pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN)); + pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN)); + return id; +} + +void pdf_enc_set_label (unsigned long label) +{ + current_label = label; +} + +void pdf_enc_set_generation (unsigned generation) +{ + current_generation = generation; +} diff --git a/Build/source/texk/dvipdf-x/src/pdfnames.c b/Build/source/texk/dvipdf-x/src/pdfnames.c new file mode 100644 index 00000000000..28082c8b9a9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfnames.c @@ -0,0 +1,425 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "numbers.h" + +/* Hash */ +#include "dpxutil.h" + +#include "pdfobj.h" + +#include "pdfnames.h" + +struct obj_data +{ + pdf_obj *object; + int closed; /* 1 if object is closed */ +}; + +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(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 void CDECL +hval_free (void *hval) +{ + struct obj_data *value; + + value = (struct obj_data *) hval; + + 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); + ASSERT(value->object); + 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->closed = 0; + ht_append_table(names, key, keylen, value); + } else { + ASSERT(value->object); + if (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; +} + +/* + * 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 *object; + + ASSERT(names); + + value = ht_lookup_table(names, key, keylen); + if (value) { + object = value->object; + } 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. + */ + object = pdf_new_undefined(); + pdf_names_add_object(names, key, keylen, object); + } + ASSERT(object); + + return pdf_ref_obj(object); +} + +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; + ASSERT(value->object); + + 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; + } + + value->closed = 1; + + return 0; +} + +struct named_object +{ + char *key; + int keylen; + pdf_obj *value; +}; + +static int CDECL +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, long 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)); + break; + 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; + long 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, long *num_entries, + struct ht_table *filter) +{ + struct named_object *objects; + struct ht_iter iter; + long 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, long *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/dvipdf-x/src/pdfnames.h b/Build/source/texk/dvipdf-x/src/pdfnames.h new file mode 100644 index 00000000000..bcf3aec9d98 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfnames.h @@ -0,0 +1,52 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); + +/* Really create name tree... */ +extern pdf_obj *pdf_names_create_tree (struct ht_table *names, + long *count, + struct ht_table *filter); + +extern char *printable_key (const char *key, int keylen); + +#endif /* _PDF_NAMES_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/pdfobj.c b/Build/source/texk/dvipdf-x/src/pdfobj.c new file mode 100644 index 00000000000..ba431d9be9a --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfobj.c @@ -0,0 +1,3163 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "dpxutil.h" +#include "pdflimits.h" +#include "pdfencrypt.h" +#include "pdfparse.h" + +#ifdef HAVE_ZLIB +#include +#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; + + unsigned long label; /* Only used for indirect objects + all other "label" to zero */ + unsigned short generation; /* Only used if "label" is used */ + unsigned refcount; /* Number of links to this object */ + int flags; + void *data; +}; + +struct pdf_boolean +{ + char value; +}; + +struct pdf_number +{ + double value; +}; + +struct pdf_string +{ + unsigned char *string; + unsigned short length; +}; + +struct pdf_name +{ + char *name; +}; + +struct pdf_array +{ + unsigned long max; + unsigned long size; + struct pdf_obj **values; +}; + +struct pdf_dict +{ + struct pdf_obj *key; + struct pdf_obj *value; + struct pdf_dict *next; +}; + +struct pdf_stream +{ + struct pdf_obj *dict; + unsigned char *stream; + long *objstm_data; /* used for object streams */ + unsigned long stream_length; + unsigned long max_length; + unsigned char _flags; +}; + +struct pdf_indirect +{ + pdf_file *pf; + unsigned long label; + unsigned short 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; + +static FILE *pdf_output_file = NULL; + +static long pdf_output_file_position = 0; +static long pdf_output_line_position = 0; +static long compression_saved = 0; + +#define FORMAT_BUF_SIZE 4096 +static char format_buffer[FORMAT_BUF_SIZE]; + +typedef struct xref_entry +{ + unsigned char type; /* object storage type */ + unsigned long field2; /* offset in file or object stream */ + unsigned short field3; /* generation or index */ + pdf_obj *direct; /* used for imported objects */ + pdf_obj *indirect; /* used for imported objects */ +} xref_entry; + +static xref_entry *output_xref; + +static unsigned long pdf_max_ind_objects; +static unsigned long next_label; + +static unsigned long startxref; + +struct pdf_file +{ + FILE *file; + pdf_obj *trailer; + xref_entry *xref_table; + pdf_obj *catalog; + long num_obj; + long file_size; + int version; +}; + +static pdf_obj *output_stream; + +#define OBJSTM_MAX_OBJS 200 +/* the limit is only 100 for linearized PDF */ + +static int enc_mode; +static int doc_enc_mode; + +static pdf_obj *trailer_dict; +static pdf_obj *xref_stream; + +/* Internal static routines */ + +static int check_for_pdf_version (FILE *file); + +static void pdf_flush_obj (pdf_obj *object, FILE *file); +static void pdf_label_obj (pdf_obj *object); +static void pdf_write_obj (pdf_obj *object, FILE *file); + +static void set_objstm_data (pdf_obj *objstm, long *data); +static long *get_objstm_data (pdf_obj *objstm); +static void release_objstm (pdf_obj *objstm); + +static void pdf_out_char (FILE *file, char c); +static void pdf_out (FILE *file, const void *buffer, long length); + +static void release_indirect (pdf_indirect *data); +static void write_indirect (pdf_indirect *indirect, FILE *file); + +static void release_boolean (pdf_obj *data); +static void write_boolean (pdf_boolean *data, FILE *file); + +static void release_null (pdf_null *data); +static void write_null (pdf_null *data, FILE *file); + +static void release_number (pdf_number *number); +static void write_number (pdf_number *number, FILE *file); + +static void write_string (pdf_string *str, FILE *file); +static void release_string (pdf_string *str); + +static void write_name (pdf_name *name, FILE *file); +static void release_name (pdf_name *name); + +static void write_array (pdf_array *array, FILE *file); +static void release_array (pdf_array *array); + +static void write_dict (pdf_dict *dict, FILE *file); +static void release_dict (pdf_dict *dict); + +static void write_stream (pdf_stream *stream, FILE *file); +static void release_stream (pdf_stream *stream); + +static int verbose = 0; +static char compression_level = 9; + +void +pdf_set_compression (int level) +{ +#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) + compression_level = level; + else { + ERROR("set_compression: invalid compression level: %d", level); + } +#endif /* !HAVE_ZLIB */ + + return; +} + +static unsigned pdf_version = PDF_VERSION_DEFAULT; + +void +pdf_set_version (unsigned version) +{ + /* Don't forget to update CIDFont_stdcc_def[] in cid.c too! */ + if (version >= PDF_VERSION_MIN && version <= PDF_VERSION_MAX) { + pdf_version = version; + } +} + +unsigned +pdf_get_version (void) +{ + return pdf_version; +} + +int +pdf_obj_get_verbose(void) +{ + return verbose; +} + +void +pdf_obj_set_verbose(void) +{ + verbose++; +} + +static pdf_obj *current_objstm = NULL; +static int do_objstm; + +static void +add_xref_entry (unsigned long label, unsigned char type, unsigned long field2, unsigned short field3) +{ + if (label >= pdf_max_ind_objects) { + pdf_max_ind_objects = (label/IND_OBJECTS_ALLOC_SIZE+1)*IND_OBJECTS_ALLOC_SIZE; + output_xref = RENEW(output_xref, pdf_max_ind_objects, xref_entry); + } + + output_xref[label].type = type; + output_xref[label].field2 = field2; + output_xref[label].field3 = field3; + output_xref[label].direct = NULL; + output_xref[label].indirect = NULL; +} + +#define BINARY_MARKER "%\344\360\355\370\n" +void +pdf_out_init (const char *filename, int do_encryption) +{ + char v; + + output_xref = NULL; + pdf_max_ind_objects = 0; + add_xref_entry(0, 0, 0, 0xffff); + next_label = 1; + + if (pdf_version >= 5) { + xref_stream = pdf_new_stream(STREAM_COMPRESS); + xref_stream->flags |= OBJ_NO_ENCRYPT; + trailer_dict = pdf_stream_dict(xref_stream); + pdf_add_dict(trailer_dict, pdf_new_name("Type"), pdf_new_name("XRef")); + do_objstm = 1; + } else { + xref_stream = NULL; + trailer_dict = pdf_new_dict(); + do_objstm = 0; + } + + output_stream = NULL; + + pdf_output_file = MFOPEN(filename, FOPEN_WBIN_MODE); + if (!pdf_output_file) { + if (strlen(filename) < 128) + ERROR("Unable to open \"%s\".", filename); + else + ERROR("Unable to open file."); + } + pdf_out(pdf_output_file, "%PDF-1.", strlen("%PDF-1.")); + v = '0' + pdf_version; + pdf_out(pdf_output_file, &v, 1); + pdf_out(pdf_output_file, "\n", 1); + pdf_out(pdf_output_file, BINARY_MARKER, strlen(BINARY_MARKER)); + + enc_mode = 0; + doc_enc_mode = do_encryption; +} + +static void +dump_xref_table (void) +{ + long length; + unsigned long i; + + pdf_out(pdf_output_file, "xref\n", 5); + + length = sprintf(format_buffer, "%d %lu\n", 0, next_label); + pdf_out(pdf_output_file, format_buffer, 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 < next_label; i++) { + unsigned char type = output_xref[i].type; + if (type > 1) + ERROR("object type %hu not allowed in xref table", type); + length = sprintf(format_buffer, "%010lu %05hu %c \n", + output_xref[i].field2, output_xref[i].field3, + type ? 'n' : 'f'); + pdf_out(pdf_output_file, format_buffer, length); + } +} + +static void +dump_trailer_dict (void) +{ + pdf_out(pdf_output_file, "trailer\n", 8); + enc_mode = 0; + write_dict(trailer_dict->data, pdf_output_file); + pdf_release_obj(trailer_dict); + pdf_out_char(pdf_output_file, '\n'); +} + +/* + * output a PDF 1.5 cross-reference stream; + * contributed by Matthias Franz (March 21, 2007) + */ +static void +dump_xref_stream (void) +{ + unsigned long pos, i; + unsigned poslen; + unsigned char buf[7] = {0, 0, 0, 0, 0}; + + pdf_obj *w; + + /* determine the necessary size of the offset field */ + pos = 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(trailer_dict, pdf_new_name("W"), w); + + /* We need the xref entry for the xref stream right now */ + add_xref_entry(next_label-1, 1, startxref, 0); + + for (i = 0; i < next_label; i++) { + unsigned j; + unsigned short f3; + buf[0] = output_xref[i].type; + pos = output_xref[i].field2; + for (j = poslen; j--; ) { + buf[1+j] = (unsigned char) pos; + pos >>= 8; + } + f3 = output_xref[i].field3; + buf[poslen+1] = (unsigned char) (f3 >> 8); + buf[poslen+2] = (unsigned char) (f3); + pdf_add_stream(xref_stream, &buf, poslen+3); + } + + pdf_release_obj(xref_stream); +} + +void +pdf_out_flush (void) +{ + if (pdf_output_file) { + long length; + + /* Flush current object stream */ + if (current_objstm) { + release_objstm(current_objstm); + 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 (xref_stream) + pdf_label_obj(xref_stream); + + /* Record where this xref is for trailer */ + startxref = pdf_output_file_position; + + pdf_add_dict(trailer_dict, pdf_new_name("Size"), + pdf_new_number(next_label)); + + if (xref_stream) + dump_xref_stream(); + else { + dump_xref_table(); + dump_trailer_dict(); + } + + /* Done with xref table */ + RELEASE(output_xref); + + pdf_out(pdf_output_file, "startxref\n", 10); + length = sprintf(format_buffer, "%lu\n", startxref); + pdf_out(pdf_output_file, format_buffer, length); + pdf_out(pdf_output_file, "%%EOF\n", 6); + + MESG("\n"); + if (verbose) { + if (compression_level > 0) { + MESG("Compression saved %ld bytes%s\n", compression_saved, + pdf_version < 5 ? ". Try \"-V 5\" for better compression" : ""); + } + } + MESG("%ld bytes written", pdf_output_file_position); + + MFCLOSE(pdf_output_file); + } +} + +void +pdf_error_cleanup (void) +{ + /* + * This routine is the cleanup required for an abnormal exit. + * For now, simply close the file. + */ + if (pdf_output_file) + MFCLOSE(pdf_output_file); +} + + +void +pdf_set_root (pdf_obj *object) +{ + if (pdf_add_dict(trailer_dict, pdf_new_name("Root"), pdf_ref_obj(object))) { + ERROR("Root object already set!"); + } + /* 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 (doc_enc_mode) + object->flags |= OBJ_NO_OBJSTM; +} + +void +pdf_set_info (pdf_obj *object) +{ + if (pdf_add_dict(trailer_dict, pdf_new_name("Info"), pdf_ref_obj(object))) { + ERROR ("Info object already set!"); + } +} + +void +pdf_set_id (pdf_obj *id) +{ + if (pdf_add_dict(trailer_dict, pdf_new_name("ID"), id)) { + ERROR ("ID already set!"); + } +} + +void +pdf_set_encrypt (pdf_obj *encrypt) +{ + if (pdf_add_dict(trailer_dict, pdf_new_name("Encrypt"), pdf_ref_obj(encrypt))) { + ERROR("Encrypt object already set!"); + } + encrypt->flags |= OBJ_NO_ENCRYPT; +} + +static +void pdf_out_char (FILE *file, char c) +{ + if (output_stream && file == pdf_output_file) + pdf_add_stream(output_stream, &c, 1); + else { + fputc(c, file); + /* Keep tallys for xref table *only* if writing a pdf file. */ + if (file == pdf_output_file) { + pdf_output_file_position += 1; + if (c == '\n') + pdf_output_line_position = 0; + else + pdf_output_line_position += 1; + } + } +} + +static char xchar[] = "0123456789abcdef"; + +#define pdf_out_xchar(f,c) do {\ + pdf_out_char((f), xchar[((c) >> 4) & 0x0f]);\ + pdf_out_char((f), xchar[(c) & 0x0f]);\ +} while (0) + +static +void pdf_out (FILE *file, const void *buffer, long length) +{ + if (output_stream && file == pdf_output_file) + pdf_add_stream(output_stream, buffer, length); + else { + fwrite(buffer, 1, length, file); + /* Keep tallys for xref table *only* if writing a pdf file */ + if (file == pdf_output_file) { + pdf_output_file_position += length; + pdf_output_line_position += length; + /* "foo\nbar\n "... */ + if (length > 0 && + ((const char *)buffer)[length-1] == '\n') + pdf_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 (FILE *file) +{ + if (file == pdf_output_file && pdf_output_line_position >= 80) { + pdf_out_char(file, '\n'); + } else { + pdf_out_char(file, ' '); + } +} + +#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; + + result = NEW(1, pdf_obj); + result->type = type; + result->data = NULL; + result->label = 0; + result->generation = 0; + result->refcount = 1; + result->flags = 0; + + if (INVALIDOBJ(result)) + ERROR("Invalid object type: %d", type); + + 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_obj *object) +{ + 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) { + object->label = 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) +{ + if (INVALIDOBJ(object)) + ERROR("pdf_ref_obj(): passed invalid object."); + + if (object->refcount == 0) { + MESG("\nTrying to refer already released object!!!\n"); + pdf_write_obj(object, stderr); + ERROR("Cannot continue..."); + } + + if (PDF_OBJ_INDIRECTTYPE(object)) { + return pdf_link_obj(object); + } else { + if (object->label == 0) { + pdf_label_obj(object); + } + return pdf_new_indirect(NULL, object->label, object->generation); + } +} + +static void +release_indirect (pdf_indirect *data) +{ + RELEASE(data); +} + +static void +write_indirect (pdf_indirect *indirect, FILE *file) +{ + long length; + + ASSERT(!indirect->pf); + + length = sprintf(format_buffer, "%lu %hu R", indirect->label, indirect->generation); + pdf_out(file, format_buffer, 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 +release_null (pdf_null *obj) +{ + return; +} + +static void +write_null (pdf_null *obj, FILE *file) +{ + pdf_out(file, "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_boolean *data, FILE *file) +{ + if (data->value) { + pdf_out(file, "true", 4); + } else { + pdf_out(file, "false", 5); + } +} + +#if 0 +void +pdf_set_boolean (pdf_obj *object, char value) +{ + pdf_boolean *data; + + TYPECHECK(object, PDF_BOOLEAN); + + data = object->data; + data->value = value; +} +#endif + +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_number *number, FILE *file) +{ + int count; + + count = pdf_sprint_number(format_buffer, number->value); + + pdf_out(file, format_buffer, 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; + data->string = NEW(length+1, unsigned char); + memcpy(data->string, str, length); + /* Shouldn't assume NULL terminated. */ + data->string[length] = '\0'; + + 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) +{ + int result = 0; + int 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 result; +} + +static void +write_string (pdf_string *str, FILE *file) +{ + unsigned char *s; + char wbuf[FORMAT_BUF_SIZE]; /* Shouldn't use format_buffer[]. */ + int nescc = 0, i, count; + + s = str->string; + + if (enc_mode) + pdf_encrypt_data(s, str->length); + + /* + * Count all ASCII non-printable characters. + */ + for (i = 0; i < str->length; i++) { + if (!isprint(s[i])) + nescc++; + } + /* + * If the string contains much escaped chars, then we write it as + * ASCII hex string. + */ + if (nescc > str->length / 3) { + pdf_out_char(file, '<'); + for (i = 0; i < str->length; i++) { + pdf_out_xchar(file, s[i]); + } + pdf_out_char(file, '>'); + } else { + pdf_out_char(file, '('); + /* + * 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 < str->length; i++) { + count = pdfobj_escape_str(wbuf, FORMAT_BUF_SIZE, &(s[i]), 1); + pdf_out(file, wbuf, count); + } + pdf_out_char(file, ')'); + } +} + +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; + unsigned 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_name *name, FILE *file) +{ + char *s; + int i, length; + + 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) == '%') +#endif + pdf_out_char(file, '/'); + for (i = 0; i < length; i++) { + if (s[i] < '!' || s[i] > '~' || s[i] == '#' || is_delim(s[i])) { + /* ^ "space" is here. */ + pdf_out_char (file, '#'); + pdf_out_xchar(file, s[i]); + } else { + pdf_out_char (file, s[i]); + } + } +} + +static void +release_name (pdf_name *data) +{ + if (data->name != NULL) { + RELEASE(data->name); + data->name = NULL; + } + RELEASE(data); +} + +#if 0 +void +pdf_set_name (pdf_obj *object, const char *name) +{ + pdf_name *data; + unsigned length; + + TYPECHECK(object, PDF_NAME); + + length = strlen(name); + data = object->data; + if (data->name != NULL) { + RELEASE(data->name); + } + if (length != 0) { + data->name = NEW(length+1, char); + memcpy(data->name, name, length); + data->name[length] = 0; + } else { + data->name = NULL; + } +} +#endif + +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_array *array, FILE *file) +{ + pdf_out_char(file, '['); + if (array->size > 0) { + unsigned long 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(file); + type1 = type2; + pdf_write_obj(array->values[i], file); + } else + WARN("PDF array element #ld undefined.", i); + } + } + pdf_out_char(file, ']'); +} + +pdf_obj * +pdf_get_array (pdf_obj *array, long 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 int +pdf_array_length (pdf_obj *array) +{ + pdf_array *data; + + TYPECHECK(array, PDF_ARRAY); + + data = (pdf_array *) array->data; + + return (unsigned int) data->size; +} + +static void +release_array (pdf_array *data) +{ + unsigned long 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, unsigned idx, pdf_obj *object) +{ + pdf_array *data; + long 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) { + int 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 */ +void +pdf_unshift_array (pdf_obj *array, pdf_obj *object) +{ + pdf_array *data; + int i; + + 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 *); + } + for (i = 0; i < data->size; i++) + data->values[i+1] = data->values[i]; + 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_dict *dict, FILE *file) +{ +#if 0 + pdf_out (file, "<<\n", 3); /* dropping \n saves few kb. */ +#else + pdf_out (file, "<<", 2); +#endif + while (dict->key != NULL) { + pdf_write_obj(dict->key, file); + if (pdf_need_white(PDF_NAME, (dict->value)->type)) { + pdf_out_white(file); + } + pdf_write_obj(dict->value, file); +#if 0 + pdf_out_char (file, '\n'); /* removing this saves few kb. */ +#endif + dict = dict->next; + } + pdf_out(file, ">>", 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; + + result->data = data; + result->flags |= OBJ_NO_OBJSTM; + + return result; +} + +static void +write_stream (pdf_stream *stream, FILE *file) +{ + unsigned char *filtered; + unsigned long filtered_length; + unsigned long buffer_length; + unsigned char *buffer; + + /* + * 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; + +#if 0 + if (stream->stream_length < 10) + stream->_flags &= ^STREAM_COMPRESS; +#endif + +#ifdef HAVE_ZLIB + /* Apply compression filter if requested */ + if (stream->stream_length > 0 && + (stream->_flags & STREAM_COMPRESS) && + compression_level > 0) { + + pdf_obj *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, compression_level)) { + ERROR("Zlib error"); + } +#else + if (compress(buffer, &buffer_length, filtered, + filtered_length)) { + ERROR ("Zlib error"); + } +#endif /* HAVE_ZLIB_COMPRESS2 */ + RELEASE(filtered); + compression_saved += filtered_length - buffer_length + - (filters ? strlen("/FlateDecode "): strlen("/Filter/FlateDecode\n")); + + filtered = buffer; + filtered_length = buffer_length; + } +#endif /* HAVE_ZLIB */ + +#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(stream->dict, file); + + pdf_out(file, "\nstream\n", 8); + + if (enc_mode) + pdf_encrypt_data(filtered, filtered_length); + + if (filtered_length > 0) { + pdf_out(file, 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(file, "\n", 1); + pdf_out(file, "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; +} + +long +pdf_stream_length (pdf_obj *stream) +{ + pdf_stream *data; + + TYPECHECK(stream, PDF_STREAM); + + data = stream->data; + + return (long) data->stream_length; +} + +static void +set_objstm_data (pdf_obj *objstm, long *data) { + TYPECHECK(objstm, PDF_STREAM); + + ((pdf_stream *) objstm->data)->objstm_data = data; +} + +static long * +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, long 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 +int +pdf_add_stream_flate (pdf_obj *dst, const void *data, long len) +{ + z_stream z; + Bytef wbuf[WBUF_SIZE]; + + z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; + + z.next_in = (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 -1; + } + + for (;;) { + int status; + status = inflate(&z, Z_NO_FLUSH); + if (status == Z_STREAM_END) + break; + else if (status != Z_OK) { + WARN("inflate() failed. Broken PDF file?"); + inflateEnd(&z); + return -1; + } + + if (z.avail_out == 0) { + pdf_add_stream(dst, wbuf, WBUF_SIZE); + z.next_out = wbuf; + z.avail_out = WBUF_SIZE; + } + } + + if (WBUF_SIZE - z.avail_out > 0) + pdf_add_stream(dst, wbuf, WBUF_SIZE - z.avail_out); + + return (inflateEnd(&z) == Z_OK ? 0 : -1); +} +#endif + + +int +pdf_concat_stream (pdf_obj *dst, pdf_obj *src) +{ + const char *stream_data; + long stream_length; + pdf_obj *stream_dict; + pdf_obj *filter; + + if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src)) + ERROR("Invalid type."); + + stream_data = pdf_stream_dataptr(src); + stream_length = pdf_stream_length (src); + stream_dict = pdf_stream_dict (src); + + if (pdf_lookup_dict(stream_dict, "DecodeParms")) { + WARN("Streams with DecodeParams not supported."); + return -1; + } + + filter = pdf_lookup_dict(stream_dict, "Filter"); + if (!filter) { + pdf_add_stream(dst, stream_data, stream_length); + return 0; +#if HAVE_ZLIB + } else { + char *filter_name; + if (PDF_OBJ_NAMETYPE(filter)) { + filter_name = pdf_name_value(filter); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return pdf_add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } else if (PDF_OBJ_ARRAYTYPE(filter)) { + if (pdf_array_length(filter) > 1) { + WARN("Multiple DecodeFilter not supported."); + return -1; + } else { + filter_name = pdf_name_value(pdf_get_array(filter, 0)); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return pdf_add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } + } else + ERROR("Broken PDF file?"); +#endif /* HAVE_ZLIB */ + } + + return -1; +} + +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_obj *object, FILE *file) +{ + if (object == NULL) { + write_null(NULL, file); + return; + } + + if (INVALIDOBJ(object) || PDF_OBJ_UNDEFINED(object)) + ERROR("pdf_write_obj: Invalid object, type = %d\n", object->type); + + if (file == stderr) + fprintf(stderr, "{%d}", object->refcount); + + switch (object->type) { + case PDF_BOOLEAN: + write_boolean(object->data, file); + break; + case PDF_NUMBER: + write_number (object->data, file); + break; + case PDF_STRING: + write_string (object->data, file); + break; + case PDF_NAME: + write_name(object->data, file); + break; + case PDF_ARRAY: + write_array(object->data, file); + break; + case PDF_DICT: + write_dict (object->data, file); + break; + case PDF_STREAM: + write_stream(object->data, file); + break; + case PDF_NULL: + write_null(NULL, file); + break; + case PDF_INDIRECT: + write_indirect(object->data, file); + break; + } +} + +/* Write the object to the file */ +static void +pdf_flush_obj (pdf_obj *object, FILE *file) +{ + long length; + + /* + * Record file position + */ + add_xref_entry(object->label, 1, + pdf_output_file_position, object->generation); + length = sprintf(format_buffer, "%lu %hu obj\n", object->label, object->generation); + enc_mode = doc_enc_mode && !(object->flags & OBJ_NO_ENCRYPT); + pdf_enc_set_label(object->label); + pdf_enc_set_generation(object->generation); + pdf_out(file, format_buffer, length); + pdf_write_obj(object, file); + pdf_out(file, "\nendobj\n", 8); +} + +static long +pdf_add_objstm (pdf_obj *objstm, pdf_obj *object) +{ + long *data, pos; + + TYPECHECK(objstm, PDF_STREAM); + + data = get_objstm_data(objstm); + pos = ++data[0]; + + data[2*pos] = object->label; + data[2*pos+1] = pdf_stream_length(objstm); + + add_xref_entry(object->label, 2, objstm->label, pos-1); + + /* redirect output into objstm */ + output_stream = objstm; + enc_mode = 0; + pdf_write_obj(object, pdf_output_file); + pdf_out_char(pdf_output_file, '\n'); + output_stream = NULL; + + return pos; +} + +static void +release_objstm (pdf_obj *objstm) +{ + long *data = get_objstm_data(objstm); + long pos = data[0]; + pdf_obj *dict; + pdf_stream *stream; + unsigned char *old_buf; + unsigned long 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; + + { + long i = 2*pos, *val = data+2; + while (i--) { + long length = sprintf(format_buffer, "%ld ", *(val++)); + pdf_add_stream(objstm, format_buffer, 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); +} + +void +pdf_release_obj (pdf_obj *object) +{ + 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); + pdf_write_obj(object, stderr); + ERROR("pdf_release_obj: Called with invalid object."); + } + object->refcount -= 1; + if (object->refcount == 0) { + /* + * 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 && pdf_output_file != NULL) { + if (!do_objstm || object->flags & OBJ_NO_OBJSTM + || (doc_enc_mode && object->flags & OBJ_NO_ENCRYPT) + || object->generation) + pdf_flush_obj(object, pdf_output_file); + else { + if (!current_objstm) { + long *data = NEW(2*OBJSTM_MAX_OBJS+2, long); + data[0] = data[1] = 0; + current_objstm = pdf_new_stream(STREAM_COMPRESS); + set_objstm_data(current_objstm, data); + pdf_label_obj(current_objstm); + } + if (pdf_add_objstm(current_objstm, object) == OBJSTM_MAX_OBJS) { + release_objstm(current_objstm); + current_objstm = NULL; + } + } + } + switch (object->type) { + case PDF_BOOLEAN: + release_boolean(object->data); + break; + case PDF_NULL: + release_null(object->data); + 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); + } +} + +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 long +find_xref (FILE *pdf_input_file) +{ + long xref_pos; + int tries = 10; + + do { + long 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 */ + mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file); + + { + const char *start, *end; + char *number; + + start = work_buffer; + end = start + strlen(work_buffer); + skip_white(&start, end); + number = parse_number(&start, end); + xref_pos = (long) 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 long +next_object_offset (pdf_file *pf, unsigned long obj_num) +{ + long next = pf->file_size; /* Worst case */ + long i, 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, unsigned long obj_num, unsigned short obj_gen) +{ + pdf_obj *result; + pdf_indirect *indirect; + + indirect = NEW(1, pdf_indirect); + indirect->pf = pf; + 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 (unsigned long obj_num, unsigned short obj_gen, + pdf_file *pf, long offset, long limit) +{ + long length; + char *buffer; + const char *p, *endptr; + pdf_obj *result; + + 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; + unsigned long 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, unsigned long num) +{ + unsigned long offset = pf->xref_table[num].field2; + unsigned short gen = pf->xref_table[num].field3; + long limit = next_object_offset(pf, num), 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 = (long) pdf_number_value(n_obj); + + first_obj = pdf_lookup_dict(dict, "First"); + if (!PDF_OBJ_NUMBERTYPE(first_obj)) + goto error; + first = (long) pdf_number_value(first_obj); + /* reject object streams without object data */ + if (first >= pdf_stream_length(objstm)) + goto error; + + header = NEW(2*(n+1), long); + 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, unsigned long obj_num, unsigned short 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 */ + unsigned long offset; + long 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 */ + unsigned long objstm_num = pf->xref_table[obj_num].field2; + unsigned short index = pf->xref_table[obj_num].field3; + pdf_obj *objstm; + long *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_NUM(o) (((pdf_indirect *)((o)->data))->label) +#define OBJ_GEN(o) (((pdf_indirect *)((o)->data))->generation) + +/* 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); + unsigned long obj_num = OBJ_NUM(obj); + unsigned short obj_gen = OBJ_GEN(obj); + ASSERT(pf); + pdf_release_obj(obj); + obj = pdf_get_object(pf, obj_num, obj_gen); + } + + 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, long new_size) +{ + unsigned long 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; +} + +static int +parse_xref_table (pdf_file *pf, long xref_pos) +{ + FILE *pdf_input_file = pf->file; + unsigned long first, size; + unsigned long i, offset; + unsigned int obj_gen; + char flag; + int r; + + /* + * 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); + + mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file); + if (memcmp(work_buffer, "xref", strlen("xref"))) { + /* Might be an xref stream and not an xref table */ + return 0; + } + /* Next line in file has first item and size of table */ + for (;;) { + unsigned long current_pos; + + current_pos = tell_position(pdf_input_file); + if (mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file) == NULL) { + WARN("Premature end of PDF file while parsing xref table."); + return -1; + } + if (!strncmp(work_buffer, "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. + */ + seek_absolute(pdf_input_file, current_pos); + break; + } + sscanf(work_buffer, "%lu %lu", &first, &size); + if (pf->num_obj < first + size) { + extend_xref(pf, first + size); + } + + for (i = first; i < first + size; i++) { + fread(work_buffer, sizeof(char), 20, pdf_input_file); + /* + * 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. + */ + work_buffer[19] = 0; + offset = 0UL; obj_gen = 0; flag = 0; + r = sscanf(work_buffer, "%010lu %05u %c", &offset, &obj_gen, &flag); + if ( r != 3 || + ((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; + } + 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; + } + } + } + + return 1; +} + +static unsigned long +parse_xrefstm_field (const char **p, int length, unsigned long def) +{ + unsigned long 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, long *length, + int *W, int wsum, + long first, long 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--) { + unsigned char type; + unsigned long field2; + unsigned short field3; + + type = (unsigned char) parse_xrefstm_field(p, W[0], 1); + if (type > 2) + WARN("Unknown cross-reference stream entry type."); + else if (!W[1] || (type != 1 && !W[2])) + return -1; + + field2 = (unsigned long) parse_xrefstm_field(p, W[1], 0); + field3 = (unsigned short) 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, long xref_pos, pdf_obj **trailer) +{ + pdf_obj *xrefstm, *size_obj, *W_obj, *index_obj; + unsigned long size; + long 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 = (unsigned long) 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) { + unsigned int 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, + (long) pdf_number_value(first), + (long) 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; +} + +static pdf_obj * +read_xref (pdf_file *pf) +{ + pdf_obj *trailer = NULL, *main_trailer = NULL; + long 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, (long) 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 = (long) 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) +{ + unsigned long 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); + pf->trailer = NULL; + } + if (pf->catalog) { + pdf_release_obj(pf->catalog); + pf->catalog = NULL; + } + + 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; +} + +#if 0 +pdf_obj * +pdf_file_get_trailer (pdf_file *pf) +{ + ASSERT(pf); + return pf->trailer; +} +#endif + +pdf_obj * +pdf_file_get_catalog (pdf_file *pf) +{ + ASSERT(pf); + return pf->catalog; +} + +pdf_file * +pdf_open (const char *ident, FILE *file) +{ + pdf_file *pf; + + ASSERT(pdf_files); + + pf = (pdf_file *) ht_lookup_table(pdf_files, ident, strlen(ident)); + + if (pf) { + pf->file = file; + } else { + int version; + pdf_obj *new_version; + + version = check_for_pdf_version(file); + if (version < 0) { + WARN("Not a PDF file."); + return NULL; + } + + 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 minor; + + if (!PDF_OBJ_NAMETYPE(new_version) || + sscanf(pdf_name_value(new_version), "1.%u", &minor) != 1) { + pdf_release_obj(new_version); + WARN("Illegal Version entry in document catalog. Broken PDF file?"); + goto error; + } + + if (pf->version < minor) + pf->version = minor; + + pdf_release_obj(new_version); + } + + 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 minor; + + rewind(file); + + return (ungetc(fgetc(file), file) == '%' && + fscanf(file, "%%PDF-1.%u", &minor) == 1) ? minor : -1; +} + +int +check_for_pdf (FILE *file) +{ + return (check_for_pdf_version(file) >= 0); +} + +static int CDECL +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 loop_marker = { PDF_OBJ_INVALID, 0, 0, 0, 0, NULL }; + +static pdf_obj * +pdf_import_indirect (pdf_obj *object) +{ + pdf_file *pf = OBJ_FILE(object); + unsigned long obj_num = OBJ_NUM(object); + unsigned short 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(); + } + + if ((ref = pf->xref_table[obj_num].indirect)) { + if (ref == &loop_marker) + ERROR("Loop in object hierarchy detected. Broken PDF file?"); + return pdf_link_obj(ref); + } else { + pdf_obj *obj, *tmp; + + obj = pdf_get_object(pf, obj_num, obj_gen); + + /* We mark the reference to be able to detect loops */ + pf->xref_table[obj_num].indirect = &loop_marker; + + tmp = pdf_import_object(obj); + + pf->xref_table[obj_num].indirect = ref = pdf_ref_obj(tmp); + + pdf_release_obj(tmp); + 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; + int 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; +} diff --git a/Build/source/texk/dvipdf-x/src/pdfobj.h b/Build/source/texk/dvipdf-x/src/pdfobj.h new file mode 100644 index 00000000000..85d78870506 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfobj.h @@ -0,0 +1,210 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +/* 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) + +/* 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 int pdf_obj_get_verbose (void); +extern void pdf_obj_set_verbose (void); +extern void pdf_error_cleanup (void); + +extern void pdf_out_init (const char *filename, int do_encryption); +extern void pdf_out_flush (void); +extern void pdf_set_version (unsigned version); +extern unsigned pdf_get_version (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); +#if 0 +extern void pdf_set_boolean (pdf_obj *object, char value); +#endif +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); +#if 0 +extern void pdf_set_name (pdf_obj *object, const char *name); +#endif +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, long idx); +extern unsigned pdf_array_length (pdf_obj *array); + +extern void pdf_unshift_array (pdf_obj *array, pdf_obj *object); +#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, + long stream_data_len); +#if HAVE_ZLIB +extern int pdf_add_stream_flate (pdf_obj *stream, + const void *stream_data_ptr, + long stream_data_len); +#endif +extern int pdf_concat_stream (pdf_obj *dst, pdf_obj *src); +extern pdf_obj *pdf_stream_dict (pdf_obj *stream); +extern long 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); + +#if 0 +extern int pdf_stream_pop_filter (pdf_obj *stream); +#endif + +/* Compare label of two indirect reference object. + */ +extern int pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2); + +/* The following routines are not appropriate for pdfobj. + */ + +extern void pdf_set_compression (int level); + +extern void pdf_set_info (pdf_obj *obj); +extern void pdf_set_id (pdf_obj *id); +extern void pdf_set_root (pdf_obj *obj); +extern void pdf_set_encrypt (pdf_obj *encrypt); + +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); +#if 0 +extern pdf_obj *pdf_file_get_trailer (pdf_file *pf); +#endif +extern int pdf_file_get_version (pdf_file *pf); +extern pdf_obj *pdf_file_get_catalog (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, unsigned long label, unsigned short generation); + +#endif /* _PDFOBJ_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/pdfparse.c b/Build/source/texk/dvipdf-x/src/pdfparse.c new file mode 100644 index 00000000000..78c3fdd3455 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfparse.c @@ -0,0 +1,1044 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#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) == '%') +#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); + +static const char *save = NULL; + +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"); +} + +#define SAVE(s,e) do {\ + save = (s);\ + } while (0) +#define DUMP_RESTORE(s,e) do {\ + dump(save, end);\ + (s) = save;\ + } while (0) + +void +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 == '%') + 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(*p)) + p++; + if (p < end && *p == '.') { + p++; + while (p < end && isdigit(*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(*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; +} + +#define DDIGITS_MAX 10 +pdf_obj * +parse_pdf_number (const char **pp, const char *endptr) +{ + const char *p; + unsigned long ipart = 0, dpart = 0; + int nddigits = 0, sign = 1; + int has_dot = 0; + static double ipot[DDIGITS_MAX+1] = { + 1.0, + 0.1, + 0.01, + 0.001, + 0.0001, + 0.00001, + 0.000001, + 0.0000001, + 0.00000001, + 0.000000001, + 0.0000000001 + }; + + p = *pp; + skip_white(&p, endptr); + if (p >= endptr || + (!isdigit(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(p[0])) { + if (has_dot) { + if (nddigits == DDIGITS_MAX && pdf_obj_get_verbose() > 1) { + WARN("Number with more than %d fractional digits.", DDIGITS_MAX); + } else if (nddigits < DDIGITS_MAX) { + dpart = dpart * 10 + p[0] - '0'; + nddigits++; + } /* Ignore decimal digits more than DDIGITS_MAX */ + } else { + ipart = ipart * 10 + p[0] - '0'; + } + } else { + WARN("Could not find a numeric object."); + return NULL; + } + p++; + } + + *pp = p; + return pdf_new_number((double) sign * (((double ) ipart) + dpart * ipot[nddigits])); +} + +/* + * 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(p[1]) || !isxdigit(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; + long 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(*(*pp + 1)))) { + return parse_pdf_hex_string(pp, endptr); + } + } + + WARN("Could not find a string object."); + + return NULL; +} + +#ifndef PDF_PARSE_STRICT +pdf_obj * +parse_pdf_tainted_dict (const char **pp, const char *endptr) +{ + pdf_obj *result; + + parser_state.tainted = 1; + result = parse_pdf_dict(pp, endptr, NULL); + parser_state.tainted = 0; + + return result; +} +#else /* PDF_PARSE_STRICT */ +pdf_obj * +parse_pdf_tainted_dict (const char **pp, const char *endptr) +{ + return parse_pdf_dict(pp, endptr, NULL); +} +#endif /* !PDF_PARSE_STRICT */ + +pdf_obj * +parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf) +{ + 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(&p, endptr, pf); + 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; +} + +pdf_obj * +parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf) +{ + 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(&p, endptr, pf); + 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_file *pf) +{ + pdf_obj *result = NULL; + const char *p; + pdf_obj *stream_dict; + long 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 = (long) 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; +} + +#ifndef PDF_PARSE_STRICT + +/* PLEASE REMOVE THIS */ +#include "specials.h" + +/* This is not PDF indirect reference. */ +static pdf_obj * +parse_pdf_reference (const char **start, const char *end) +{ + pdf_obj *result = NULL; + char *name; + + SAVE(*start, end); + + 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); + DUMP_RESTORE(*start, end); + } + RELEASE(name); + } else { + WARN("Could not find a reference name."); + DUMP_RESTORE(*start, end); + result = NULL; + } + + return result; +} +#endif /* !PDF_PARSE_STRICT */ + +static pdf_obj * +try_pdf_reference (const char *start, const char *end, const char **endptr, pdf_file *pf) +{ + unsigned long id = 0; + unsigned short gen = 0; + + ASSERT(pf); + + if (endptr) + *endptr = start; + + skip_white(&start, end); + if (start > end - 5 || !isdigit(*start)) { + return NULL; + } + while (!is_space(*start)) { + if (start >= end || !isdigit(*start)) { + return NULL; + } + id = id * 10 + (*start - '0'); + start++; + } + + skip_white(&start, end); + if (start >= end || !isdigit(*start)) + return NULL; + while (!is_space(*start)) { + if (start >= end || !isdigit(*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 (const char **pp, const char *endptr, pdf_file *pf) +/* 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(pp, endptr, pf); + skip_white(pp, endptr); + if ( result && + *pp <= endptr - 15 && + !memcmp(*pp, "stream", 6)) { + dict = result; + result = parse_pdf_stream(pp, endptr, dict, pf); + pdf_release_obj(dict); + } + } + + break; + case '(': + result = parse_pdf_string(pp, endptr); + break; + case '[': + result = parse_pdf_array(pp, endptr, pf); + 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; + + case '@': + +#ifndef PDF_PARSE_STRICT + result = parse_pdf_reference(pp, endptr); +#endif /* !PDF_PARSE_STRICT */ + break; + + default: + WARN("Unknown PDF object type."); + result = NULL; + } + + return result; +} + diff --git a/Build/source/texk/dvipdf-x/src/pdfximage.c b/Build/source/texk/dvipdf-x/src/pdfximage.c new file mode 100644 index 00000000000..ff81ac697fb --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfximage.c @@ -0,0 +1,940 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dpxfile.h" + +#include "pdfobj.h" + +#include "pdfdoc.h" +#include "pdfdev.h" +#include "pdfdraw.h" + +#include "epdf.h" +#include "mpost.h" +#include "pngimage.h" +#include "jpegimage.h" +#include "bmpimage.h" + +#include "pdfximage.h" + +/* From psimage.h */ +static int check_for_ps (FILE *fp); +static int ps_include_page (pdf_ximage *ximage); + + +#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 + + +struct attr_ +{ + long width, height; + double xdensity, ydensity; + pdf_rect bbox; +}; + +struct pdf_ximage_ +{ + char *ident; + char res_name[16]; + long page_no; + + int subtype; + + struct attr_ attr; + + char *filename; + pdf_obj *reference; + pdf_obj *resource; + pdf_obj *attr_dict; + + char tempfile; +}; + + +/* verbose, verbose, verbose... */ +struct opt_ +{ + int verbose; + char *cmdtmpl; +}; + +static struct opt_ _opts = { + 0, NULL +}; + +void pdf_ximage_set_verbose (void) { _opts.verbose++; } + + +struct ic_ +{ + int count, capacity; + pdf_ximage *ximages; +}; + +static struct ic_ _ic = { + 0, 0, NULL +}; + +static void +pdf_init_ximage_struct (pdf_ximage *I, + const char *ident, const char *filename, + long page_no, pdf_obj *dict) +{ + if (ident) { + I->ident = NEW(strlen(ident)+1, char); + strcpy(I->ident, ident); + } else + I ->ident = NULL; + I->page_no = page_no; + if (filename) { + I->filename = NEW(strlen(filename)+1, char); + strcpy(I->filename, filename); + } else + I->filename = NULL; + I->subtype = -1; + memset(I->res_name, 0, 16); + I->reference = NULL; + I->resource = NULL; + I->attr_dict = dict; + + 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->tempfile = 0; +} + +static void +pdf_set_ximage_tempfile (pdf_ximage *I, const char *filename) +{ + if (I->filename) + RELEASE(I->filename); + I->filename = NEW(strlen(filename)+1, char); + strcpy(I->filename, filename); + I->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->reference) + pdf_release_obj(I->reference); + if (I->resource) + pdf_release_obj(I->resource); + if (I->attr_dict) + pdf_release_obj(I->attr_dict); + pdf_init_ximage_struct(I, NULL, NULL, 0, NULL); +} + + +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->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 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 (_opts.verbose > 1 && keep_cache != 1) + MESG("pdf_image>> deleting temporary file \"%s\"\n", I->filename); + dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */ + I->filename = 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; + } +#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 *fullname, int format, FILE *fp, + long page_no, pdf_obj *dict) +{ + struct ic_ *ic = &_ic; + int id = -1; /* ret */ + pdf_ximage *I; + + 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, ident, fullname, page_no, dict); + + switch (format) { + case IMAGE_TYPE_JPEG: + if (_opts.verbose) + MESG("[JPEG]"); + if (jpeg_include_image(I, fp) < 0) + goto error; + I->subtype = PDF_XOBJECT_TYPE_IMAGE; + break; +#ifdef HAVE_LIBPNG + case IMAGE_TYPE_PNG: + if (_opts.verbose) + MESG("[PNG]"); + if (png_include_image(I, fp) < 0) + goto error; + I->subtype = PDF_XOBJECT_TYPE_IMAGE; + break; +#endif + case IMAGE_TYPE_BMP: + if (_opts.verbose) + MESG("[BMP]"); + if (bmp_include_image(I, fp) < 0) + goto error; + I->subtype = PDF_XOBJECT_TYPE_IMAGE; + break; + case IMAGE_TYPE_PDF: + if (_opts.verbose) + MESG("[PDF]"); + { + int result = pdf_include_page(I, fp, fullname); + if (result > 0) + /* PDF version too recent */ + result = ps_include_page(I); + if (result < 0) + goto error; + } + if (_opts.verbose) + MESG(",Page:%ld", I->page_no); + I->subtype = PDF_XOBJECT_TYPE_FORM; + break; + // case IMAGE_TYPE_EPS: + default: + if (_opts.verbose) + MESG(format == IMAGE_TYPE_EPS ? "[PS]" : "[UNKNOWN]"); + if (ps_include_page(I) < 0) + goto error; + if (_opts.verbose) + MESG(",Page:%ld", I->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; + } + + ic->count++; + + 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))) + +int +pdf_ximage_findresource (const char *ident, long page_no, pdf_obj *dict) +{ + struct ic_ *ic = &_ic; + int id = -1; + pdf_ximage *I; + char *fullname, *f = NULL; + int format; + FILE *fp; + + for (id = 0; id < ic->count; id++) { + I = &ic->ximages[id]; + if (I->ident && !strcmp(ident, I->ident)) { + f = I->filename; + if (I->page_no == page_no && I->attr_dict == dict) { + return id; + } + } + } + + 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 */ + fullname = dpx_find_file(ident, "_pic_", ""); + if (!fullname) { + WARN("Error locating image file \"%s\"", ident); + return -1; + } + } + + fp = dpx_fopen(fullname, FOPEN_RBIN_MODE); + if (!fp) { + WARN("Error opening image file \"%s\"", fullname); + RELEASE(fullname); + return -1; + } + if (_opts.verbose) { + MESG("(Image:%s", ident); + if (_opts.verbose > 1) + MESG("[%s]", fullname); + } + + format = source_image_type(fp); + switch (format) { + case IMAGE_TYPE_MPS: + if (_opts.verbose) + MESG("[MPS]"); + id = mps_include_page(ident, fp); + if (id < 0) { + WARN("Try again with the distiller."); + format = IMAGE_TYPE_EPS; + rewind(fp); + } else + break; + default: + id = load_image(ident, fullname, format, fp, page_no, dict); + break; + } + dpx_fclose(fp); + + RELEASE(fullname); + + if (_opts.verbose) + MESG(")"); + + if (id < 0) + WARN("pdf: image inclusion failed for \"%s\".", ident); + + return id; +} + +/* 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; + + I->reference = pdf_ref_obj(resource); + + 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)); + 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); + + 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; + + I->subtype = PDF_XOBJECT_TYPE_FORM; + + I->attr.bbox.llx = info->bbox.llx; + I->attr.bbox.lly = info->bbox.lly; + I->attr.bbox.urx = info->bbox.urx; + I->attr.bbox.ury = info->bbox.ury; + + I->reference = pdf_ref_obj(resource); + + pdf_release_obj(resource); /* Caller don't know we are using reference. */ + I->resource = NULL; +} + +long +pdf_ximage_get_page (pdf_ximage *I) +{ + return I->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->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; + pdf_ximage *I; + + 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, ident, NULL, 0, NULL); + + 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); + } + 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, long width, long 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; + } + + 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; +} + +static int +ps_include_page (pdf_ximage *ximage) +{ + char *distiller_template = _opts.cmdtmpl; + char *filename = ximage->filename; + 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; + } + + if (keep_cache != -1 && stat(temp, &stat_t)==0 && stat(filename, &stat_o)==0 + && stat_t.st_mtime > stat_o.st_mtime) { + /* cache exist */ + /*printf("\nLast file modification: %s", ctime(&stat_o.st_mtime)); + printf("Last file modification: %s", ctime(&stat_t.st_mtime));*/ + ; + } else { + if (_opts.verbose > 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, + (unsigned char) 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); + 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; +} diff --git a/Build/source/texk/dvipdf-x/src/pdfximage.h b/Build/source/texk/dvipdf-x/src/pdfximage.h new file mode 100644 index 00000000000..a919742594d --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pdfximage.h @@ -0,0 +1,94 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +#define PDF_XOBJECT_TYPE_FORM 0 +#define PDF_XOBJECT_TYPE_IMAGE 1 + +typedef struct { + int flags; + + long width; + long height; + + int bits_per_component; + int num_components; + + long 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 pdf_ximage_ pdf_ximage; + +extern void pdf_ximage_set_verbose (void); + +extern void pdf_init_images (void); +extern void pdf_close_images (void); + +extern char *pdf_ximage_get_resname (int xobj_id); +extern int pdf_ximage_get_subtype (int xobj_id); +extern pdf_obj *pdf_ximage_get_reference (int xobj_id); + + +extern int pdf_ximage_findresource (const char *ident, long page_no, + pdf_obj *dict); +extern int pdf_ximage_defineresource (const char *ident, int subtype, + void *cdata, pdf_obj *resource); + +/* 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 long pdf_ximage_get_page (pdf_ximage *I); + +/* from psimage.h */ +extern void set_distiller_template (char *s); + +extern int +pdf_ximage_scale_image (int id, + pdf_tmatrix *M, /* ret */ + pdf_rect *r, /* ret */ + transform_info *p /* arg */ + ); + +/* from dvipdfmx.c */ +extern void pdf_ximage_disable_ebb (void); + +/* from spc_pdfm.c */ +extern int pdf_ximage_get_subtype (int xobj_id); +extern void pdf_ximage_set_attr (int xobj_id, long width, long height, double xdensity, double ydensity, double llx, double lly, double urx, double ury); +#endif /* _PDFXIMAGE_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/pngimage.c b/Build/source/texk/dvipdf-x/src/pngimage.c new file mode 100644 index 00000000000..2a835ae49f9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pngimage.c @@ -0,0 +1,1064 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * PNG SUPPORT + * + * All bitdepth less than 16 is supported. + * Supported color types are: PALETTE, RGB, GRAY, RGB_ALPHA, GRAY_ALPHA. + * Supported ancillary chunks: tRNS, cHRM + gAMA, (sRGB), (iCCP) + * + * gAMA support is available only when cHRM exists. cHRM support is not + * tested well. CalRGB/CalGray colorspace is used for PNG images that + * have cHRM chunk (but not sRGB). + * + * LIMITATIONS + * + * Recent version of PDF (>= 1.5) support 16 bpc, but 16 bit bitdepth PNG + * images are automatically converted to 8 bit bitpedth image. + * + * TODO + * + * sBIT ? iTXT, tEXT and tIME as MetaData ?, pHYS (see below) + * 16 bpc support for PDF-1.5. JBIG compression for monochrome image. + * Predictor for deflate ? + */ + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dvipdfmx.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 +#if 0 +/* 16_TO_8 required. */ +#define PNG_NO_READ_TRANSFORMS +#endif + +#include +#include "pngimage.h" + +#include "pdfximage.h" + +#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 + * + * We ignore gAMA if cHRM is not found. + */ +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_infop info_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; +} + +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, xppm, yppm; + + 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, NULL); + 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); + 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); + xppm = png_get_x_pixels_per_meter(png_ptr, png_info_ptr); + yppm = png_get_y_pixels_per_meter(png_ptr, png_info_ptr); + + /* We do not need 16-bpc color. Ask libpng to convert down to 8-bpc. */ + if (bpc > 8) { + png_set_strip_16(png_ptr); + bpc = 8; + } + + 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 (compat_mode) + info.xdensity = info.ydensity = 72.0 / 100.0; + else { + 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, png_info_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; + } + 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: + if (color_type != PNG_COLOR_TYPE_RGB) + ERROR("Unexpected error in png_include_image()."); + mask = create_ckey_mask(png_ptr, png_info_ptr); + break; + /* rowbytes changes 4 to 3 at here */ + case PDF_TRANS_TYPE_ALPHA: + if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) + ERROR("Unexpected error in png_include_image()."); + 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: + if (color_type != PNG_COLOR_TYPE_GRAY) + ERROR("Unexpected error in png_include_image()."); + mask = create_ckey_mask(png_ptr, png_info_ptr); + break; + case PDF_TRANS_TYPE_ALPHA: + if (color_type != PNG_COLOR_TYPE_GRAY_ALPHA) + ERROR("Unexpected error in png_include_image()."); + 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) { + pdf_add_dict(stream_dict, pdf_new_name("SMask"), pdf_ref_obj(mask)); + pdf_release_obj(mask); + } else { + WARN("%s: You found a bug in pngimage.c.", PNG_DEBUG_STR); + pdf_release_obj(mask); + } + } + + 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); + + 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; + unsigned pdf_version; + png_byte color_type; + png_color_16p trans_values; + png_bytep trans; + int num_trans; + + pdf_version = pdf_get_version(); + 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_version < 3 && trans_type != PDF_TRANS_TYPE_NONE ) || + ( pdf_version < 4 && 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_version < 3) + WARN("%s: Please use -V 3 option to enable binary transparency support.", PNG_DEBUG_STR); + if (pdf_version < 4) + 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: %g", PNG_DEBUG_STR, G); + return NULL; + } + G = 1.0 / G; /* Gamma is inverted. */ + } else { + G = 1.0; + } + + 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: %g", PNG_DEBUG_STR, G); + return NULL; + } + G = 1.0 / G; /* Gamma is inverted. */ + } else { + G = 1.0; + } + + 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: %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; +} + +/* + * pHYs: no support + * + * pngimage.c is not responsible for adjusting image size. + * Higher layer must do something for this. + */ + +/* + * 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; + + 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; + } + + 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("XObjcect")); + 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++) { + png_byte idx = image_data_ptr[i]; + 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; + png_bytep smask_data_ptr; + png_uint_32 i; + + color_type = png_get_color_type(png_ptr, info_ptr); + + if (color_type & PNG_COLOR_MASK_COLOR) { + if (*rowbytes_ptr != 4*width*sizeof(png_byte)) { /* Something wrong */ + WARN("%s: Inconsistent rowbytes value.", PNG_DEBUG_STR); + return NULL; + } + } else { + if (*rowbytes_ptr != 2*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("XObjcect")); + 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)); + + smask_data_ptr = (png_bytep) NEW(width*height, png_byte); + + switch (color_type) { + case PNG_COLOR_TYPE_RGB_ALPHA: + 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); + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + 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); + 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, width*height); + RELEASE(smask_data_ptr); + + return smask; +} + +static void +read_image_data (png_structp png_ptr, png_infop info_ptr, /* info_ptr unused */ + 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, long *width, long *height, + double *xdensity, double *ydensity) +{ + png_structp png_ptr; + png_infop png_info_ptr; + png_uint_32 xppm, yppm; + + rewind (png_file); + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + 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); + xppm = png_get_x_pixels_per_meter(png_ptr, png_info_ptr); + yppm = png_get_y_pixels_per_meter(png_ptr, png_info_ptr); + + /* 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 (compat_mode) + *xdensity = *ydensity = 72.0 / 100.0; + else { + *xdensity = xppm ? 72.0 / 0.0254 / xppm : 1.0; + *ydensity = yppm ? 72.0 / 0.0254 / yppm : 1.0; + } + + return 0; +} + +#endif /* HAVE_LIBPNG */ diff --git a/Build/source/texk/dvipdf-x/src/pngimage.h b/Build/source/texk/dvipdf-x/src/pngimage.h new file mode 100644 index 00000000000..04b4e478a71 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/pngimage.h @@ -0,0 +1,45 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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, long *width, long *height, + double *xdensity, double *ydensity); + +#endif + +#endif /* _PNGIMAGE_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/sfnt.c b/Build/source/texk/dvipdf-x/src/sfnt.c new file mode 100644 index 00000000000..7f40f9e49d5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/sfnt.c @@ -0,0 +1,529 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 /* HAVE_CONFIG_H */ + +#include + +#include "system.h" + +#include "error.h" +#include "mem.h" +#include "mfileio.h" + +#include "sfnt.h" + + +sfnt * +sfnt_open (FILE *fp) +{ + sfnt *sfont; + ULONG type; + + ASSERT(fp); + + rewind(fp); + + sfont = NEW(1, sfnt); + + sfont->stream = fp; + +/* + * 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_OPENTYPE 0x00010000UL +#define SFNT_POSTSCRIPT 0x4f54544fUL +#define SFNT_TTC 0x74746366UL + + type = sfnt_get_ulong(sfont); + + if (type == SFNT_TRUETYPE) { + 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) +{ + long 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, unsigned long 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; + unsigned long i, u_tag; + + ASSERT(sfont && sfont->stream); + + sfnt_seek_set(sfont, offset); + + if (sfont->directory) + release_directory(sfont->directory); + + sfont->directory = td = NEW (1, struct sfnt_table_directory); + + 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; + long 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/dvipdf-x/src/spc_color.c b/Build/source/texk/dvipdf-x/src/spc_color.c new file mode 100644 index 00000000000..6031948e1ab --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/spc_color.c @@ -0,0 +1,191 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if 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); + 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); + 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); + 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, long 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/dvipdf-x/src/spc_dvips.c b/Build/source/texk/dvipdf-x/src/spc_dvips.c new file mode 100644 index 00000000000..07ea009172e --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/spc_dvips.c @@ -0,0 +1,434 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "error.h" + +#include "dpxfile.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" + + +static int block_pending = 0; +static double pending_x = 0.0; +static double pending_y = 0.0; +static int position_set = 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; + + 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, NULL, 1) < 0) { + RELEASE(filename); + return -1; + } + + form_id = pdf_ximage_findresource(filename, 1, NULL); + if (form_id < 0) { + spc_warn(spe, "Failed to read image file: %s", filename); + RELEASE(filename); + return -1; + } + RELEASE(filename); + + pdf_dev_put_image(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; + + 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_findresource(filename, 1, NULL); + 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 + pdf_dev_put_image(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; + + ASSERT(spe && args && args->curptr <= args->endptr); + + if (args->curptr + strlen(":[begin]") <= args->endptr && + !strncmp(args->curptr, ":[begin]", strlen(":[begin]"))) { + block_pending++; + position_set = 1; + + x_user = pending_x = spe->x_user; + y_user = pending_y = spe->y_user; + 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 : spe->x_user; + y_user = position_set ? pending_y : spe->y_user; + args->curptr++; + } else { + position_set = 1; + x_user = pending_x = spe->x_user; + y_user = pending_y = spe->y_user; + } + + 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 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; + M.a = M.d = 1.0; M.b = M.c = 0.0; M.e = spe->x_user; M.f = spe->y_user; + pdf_dev_concat(&M); + error = mps_exec_inline(&args->curptr, + args->endptr, + spe->x_user, spe->y_user); + M.e = -spe->x_user; M.f = -spe->y_user; + 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[] = { + {"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}, + {"\" ", spc_handler_ps_default} +}; + +#ifdef XETEX +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; +} +#endif + +int +spc_dvips_at_end_page (void) +{ + mps_eop_cleanup(); +#ifdef XETEX + if (!temporary_defs) { + dpx_delete_temp_file(temporary_defs, true); + temporary_defs = 0; + } +#endif + return 0; +} + +int +spc_dvips_check_special (const char *buf, long len) +{ + const char *p, *endptr; + int i; + + p = buf; + endptr = p + len; + + skip_white(&p, endptr); + if (p >= endptr) + return 0; + + len = (long) (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(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; +} + diff --git a/Build/source/texk/dvipdf-x/src/spc_html.c b/Build/source/texk/dvipdf-x/src/spc_html.c new file mode 100644 index 00000000000..c7a4d535b8e --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/spc_html.c @@ -0,0 +1,943 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 { + long 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(*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(*p); p++); + if (p >= endptr || *p != '<') + return -1; + + *type = HTML_TAG_TYPE_OPEN; + for (++p; p < endptr && isspace(*p); p++); + if (p < endptr && *p == '/') { + *type = HTML_TAG_TYPE_CLOSE; + for (++p; p < endptr && isspace(*p); p++); + } + +#define ISDELIM(c) ((c) == '>' || (c) == '/' || isspace(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(*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(*p); p++); + } + if (error) { + *pp = p; + return error; + } + + if (p < endptr && *p == '/') { + *type = HTML_TAG_TYPE_EMPTY; + for (++p; p < endptr && isspace(*p); p++); + } + if (p == endptr || *p != '>') { + *pp = p; + return -1; + } + p++; + + downcasify(name); + *pp = p; + return 0; +} + + +static int +spc_handler_html__init (struct spc_env *spe, struct spc_arg *ap, 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, struct spc_arg *ap, 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, struct spc_arg *ap, 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, struct spc_arg *ap, 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, 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, pdf_obj *attr, 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 + "pt", "in", "cm", "mm", "bp", +#define K_UNIT__PX 5 + "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__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 /* 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; +} +#endif /* ENABLE_HTML_SVG_OPACITY */ + +static int +spc_html__img_empty (struct spc_env *spe, pdf_obj *attr, struct spc_html_ *sd) +{ + pdf_obj *src, *obj; + transform_info ti; + int id, error = 0; +#ifdef ENABLE_HTML_SVG_OPACITY + double alpha = 1.0; /* meaning fully opaque */ +#endif /* ENABLE_HTML_SVG_OPACITY */ +#ifdef ENABLE_HTML_SVG_TRANSFORM + pdf_tmatrix M, M1; + + pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user, spe->y_user); +#endif /* ENABLE_HTML_SVG_TRANSFORM */ + + 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(*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(&M, &N); + for ( ; *p && isspace(*p); p++); + if (*p == ',') + for (++p; *p && isspace(*p); p++); + } + } + } +#endif /* ENABLE_HTML_SVG_TRANSFORM */ + + if (error) { + spc_warn(spe, "Error in html \"img\" tag attribute."); + return error; + } + + id = pdf_ximage_findresource(pdf_string_value(src), 0, NULL); + if (id < 0) { + spc_warn(spe, "Could not find/load image: %s", pdf_string_value(src)); + error = -1; + } else { +#if defined(ENABLE_HTML_SVG_TRANSFORM) || defined(ENABLE_HTML_SVG_OPACITY) + { + char *res_name; + pdf_rect r; + + graphics_mode(); + + pdf_dev_gsave(); + +#ifdef ENABLE_HTML_SVG_OPACITY + { + pdf_obj *dict; + int a = round(100.0 * alpha); + if (a != 0) { + res_name = NEW(strlen("_Tps_a100_") + 1, char); + sprintf(res_name, "_Tps_a%03d_", a); /* Not Tps prefix but... */ + if (!check_resourcestatus("ExtGState", res_name)) { + dict = create_xgstate(round_at(0.01 * a, 0.01), 0); + pdf_doc_add_page_resource("ExtGState", + res_name, pdf_ref_obj(dict)); + pdf_release_obj(dict); + } + pdf_doc_add_page_content(" /", 2); /* op: */ + pdf_doc_add_page_content(res_name, strlen(res_name)); /* op: */ + pdf_doc_add_page_content(" gs", 3); /* op: gs */ + RELEASE(res_name); + } + } +#endif /* ENABLE_HTML_SVG_OPACITY */ + + pdf_ximage_scale_image(id, &M1, &r, &ti); + pdf_concatmatrix(&M, &M1); + pdf_dev_concat(&M); + + pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly); + + res_name = pdf_ximage_get_resname(id); + pdf_doc_add_page_content(" /", 2); /* op: */ + pdf_doc_add_page_content(res_name, strlen(res_name)); /* op: */ + pdf_doc_add_page_content(" Do", 3); /* op: Do */ + + pdf_dev_grestore(); + + pdf_doc_add_page_resource("XObject", + res_name, + pdf_ximage_get_reference(id)); + } +#else + pdf_dev_put_image(id, &ti, spe->x_user, spe->y_user); +#endif /* ENABLE_HTML_SVG_XXX */ + } + + return error; +} +#else +static int +spc_html__img_empty (struct spc_env *spe, pdf_obj *attr, struct spc_html_ *sd) +{ + 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, attr, 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, sd); + } + } + pdf_release_obj(attr); + + for ( ; ap->curptr < ap->endptr && isspace(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(*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(*p); p++); + if (*p != '(' || *(p + 1) == 0) + return -1; + for (++p; *p && isspace(*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(*p); p++); + if (*p == ',') + for (++p; *p && isspace(*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(NULL, NULL, sd); +} + +int +spc_html_at_begin_page (void) +{ + struct spc_html_ *sd = &_html_state; + return spc_handler_html__bophook(NULL, NULL, sd); +} + +int +spc_html_at_end_page (void) +{ + struct spc_html_ *sd = &_html_state; + return spc_handler_html__eophook(NULL, NULL, sd); +} + +int +spc_html_at_end_document (void) +{ + struct spc_html_ *sd = &_html_state; + return spc_handler_html__clean(NULL, NULL, sd); +} + + +int +spc_html_check_special (const char *buffer, long size) +{ + const char *p, *endptr; + + p = buffer; + endptr = p + size; + + for ( ; p < endptr && isspace(*p); p++); + size = (long) (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(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(ap->curptr[0]); ap->curptr++); + + return 0; +} + diff --git a/Build/source/texk/dvipdf-x/src/spc_pdfm.c b/Build/source/texk/dvipdf-x/src/spc_pdfm.c new file mode 100644 index 00000000000..6ae6a94fded --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/spc_pdfm.c @@ -0,0 +1,2021 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#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 "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 ENABLE_TOUNICODE 1 + + +/* PLEASE REMOVE THIS */ +struct resource_map { + int type; + int res_id; +}; + +#ifdef ENABLE_TOUNICODE +struct tounicode { + int cmap_id; + int unescape_backslash; + pdf_obj *taintkeys; /* An array of PDF names. */ +}; +#endif /* ENABLE_TOUNICODE */ + +struct spc_pdf_ +{ + pdf_obj *annot_dict; /* pending annotation dict */ + int lowest_level; /* current min level of outlines */ + struct ht_table *resourcemap; /* see remark below (somewhere) */ +#ifdef ENABLE_TOUNICODE + struct tounicode cd; /* For to-UTF16-BE conversion :( */ +#endif /* ENABLE_TOUNICODE */ +}; + +#if 1 +static struct spc_pdf_ _pdf_stat = { + NULL, + 255, + NULL, +#ifdef ENABLE_TOUNICODE + { -1, 0, NULL } +#endif /* ENABLE_TOUNICODE */ +}; +#endif + +/* PLEASE REMOVE THIS */ +static void +hval_free (void *vp) +{ + RELEASE(vp); +} + + +static int +addresource (struct spc_pdf_ *sd, const char *ident, int res_id) +{ + struct resource_map *r; + + if (!ident || res_id < 0) + return -1; + + r = NEW(1, struct resource_map); + r->type = 0; /* unused */ + r->res_id = res_id; + + ht_append_table(sd->resourcemap, ident, strlen(ident), r); + spc_push_object(ident, pdf_ximage_get_reference(res_id)); + + return 0; +} + +static int +findresource (struct spc_pdf_ *sd, const char *ident) +{ + struct resource_map *r; + + if (!ident) + return -1; + + r = ht_lookup_table(sd->resourcemap, ident, strlen(ident)); + + return (r ? r->res_id : -1); +} + + +static int +spc_handler_pdfm__init (struct spc_env *spe, struct spc_arg *ap, void *dp) +{ + struct spc_pdf_ *sd = dp; +#ifdef ENABLE_TOUNICODE + static const char *default_taintkeys[] = { + "Title", "Author", "Subject", "Keywords", + "Creator", "Producer", "Contents", "Subj", + "TU", "T", "TM", NULL /* EOD */ + }; + int i; +#endif /* ENABLE_TOUNICODE */ + + sd->annot_dict = NULL; + sd->lowest_level = 255; + sd->resourcemap = NEW(1, struct ht_table); + ht_init_table(sd->resourcemap, hval_free); + +#ifdef ENABLE_TOUNICODE + 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])); + } +#endif /* ENABLE_TOUNICODE */ + + return 0; +} + +static int +spc_handler_pdfm__clean (struct spc_env *spe, struct spc_arg *ap, 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->resourcemap) { + ht_clear_table(sd->resourcemap); + RELEASE(sd->resourcemap); + } + sd->resourcemap = NULL; + +#ifdef ENABLE_TOUNICODE + if (sd->cd.taintkeys) + pdf_release_obj(sd->cd.taintkeys); + sd->cd.taintkeys = NULL; +#endif /* ENABLE_TOUNICODE */ + + return 0; +} + + +int +spc_pdfm_at_begin_document (void) +{ + struct spc_pdf_ *sd = &_pdf_stat; + return spc_handler_pdfm__init(NULL, NULL, sd); +} + +int +spc_pdfm_at_end_document (void) +{ + struct spc_pdf_ *sd = &_pdf_stat; + return spc_handler_pdfm__clean(NULL, NULL, sd); +} + + +/* 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, + (long) (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, + (long) (args->endptr - args->curptr)); + } + + args->curptr = args->endptr; + + return 0; +} + +#define streamfiltered(o) \ + (pdf_lookup_dict(pdf_stream_dict((o)), "Filter") ? 1 : 0) + +/* 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; +} + +#ifndef pdf_obj_isaref +#define pdf_obj_isaref(o) (pdf_obj_typeof((o)) == PDF_INDIRECT) +#endif + +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); + + if (pdf_obj_isaref(vp)) { + 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; +} + + +/* 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(&ap->curptr, ap->endptr, NULL); + 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(&ap->curptr, ap->endptr, NULL); + 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; +} + + +#ifdef ENABLE_TOUNICODE + +/* For pdf:tounicode support + * This feature is provided for convenience. TeX can't do + * input encoding conversion. + */ +#include "cmap.h" + +static int +reencodestring (CMap *cmap, pdf_obj *instring) +{ +#define WBUF_SIZE 4096 + unsigned char wbuf[WBUF_SIZE]; + unsigned char *obufcur; + const unsigned char *inbufcur; + long inbufleft, obufleft; + + if (!cmap || !instring) + return 0; + + inbufleft = pdf_string_length(instring); + inbufcur = pdf_string_value (instring); + + wbuf[0] = 0xfe; + wbuf[1] = 0xff; + obufcur = wbuf + 2; + obufleft = WBUF_SIZE - 2; + + CMap_decode(cmap, + &inbufcur, &inbufleft, + &obufcur, &obufleft); + + if (inbufleft > 0) { + return -1; + } + + pdf_set_string(instring, wbuf, WBUF_SIZE - obufleft); + + return 0; +} + +static int +needreencode (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 modstrings (pdf_obj *key, pdf_obj *value, void *pdata); + +static int +modstrings (pdf_obj *kp, pdf_obj *vp, void *dp) +{ + int r = 0; /* continue */ + CMap *cmap; + struct tounicode *cd = dp; + + ASSERT( pdf_obj_typeof(kp) == PDF_NAME ); + + if (!cd || cd->cmap_id < 0 || !cd->taintkeys) + return -1; + + switch (pdf_obj_typeof(vp)) { + case PDF_STRING: + cmap = CMap_cache_get(cd->cmap_id); + if (needreencode(kp, vp, cd)) { + r = reencodestring(cmap, vp); + if (r < 0) /* error occured... */ + WARN("Failed to convert input string to UTF16..."); + } + break; + case PDF_DICT: + r = pdf_foreach_dict(vp, modstrings, dp); + break; + case PDF_STREAM: + r = pdf_foreach_dict(pdf_stream_dict(vp), modstrings, dp); + break; + } + + return r; +} + +static pdf_obj * +my_parse_pdf_dict (const char **pp, const char *endptr, struct tounicode *cd) +{ + pdf_obj *dict; + + if (cd->cmap_id < 0) + return parse_pdf_dict(pp, endptr, NULL); + + /* :( */ + if (cd->unescape_backslash) + dict = parse_pdf_tainted_dict(pp, endptr); + else { + dict = parse_pdf_dict(pp, endptr, NULL); + } + if (dict) + pdf_foreach_dict(dict, modstrings, cd); + + return dict; +} + +#endif /* ENABLE_TOUNICODE */ + + +static int +spc_handler_pdfm_annot (struct spc_env *spe, struct spc_arg *args) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *annot_dict; + pdf_rect rect; + char *ident = NULL; + pdf_coord cp; + 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, NULL, 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; + } + +#ifdef ENABLE_TOUNICODE + annot_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + annot_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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; + } + + cp.x = spe->x_user; cp.y = spe->y_user; + pdf_dev_transform(&cp, NULL); + if (ti.flags & INFO_HAS_USER_BBOX) { + rect.llx = ti.bbox.llx + cp.x; + rect.lly = ti.bbox.lly + cp.y; + rect.urx = ti.bbox.urx + cp.x; + rect.ury = ti.bbox.ury + cp.y; + } else { + rect.llx = cp.x; + rect.lly = cp.y - spe->mag * ti.depth; + rect.urx = cp.x + spe->mag * ti.width; + rect.ury = cp.y + spe->mag * ti.height; + } + + /* Order is important... */ + if (ident) + spc_push_object(ident, pdf_link_obj(annot_dict)); + /* This add reference. */ + pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict, 1); + + if (ident) { + spc_flush_object(ident); + RELEASE(ident); + } + pdf_release_obj(annot_dict); + + return 0; +} + +/* NOTE: This can't have ident. See "Dvipdfm User's Manual". */ +static int +spc_handler_pdfm_bann (struct spc_env *spe, struct spc_arg *args) +{ + struct spc_pdf_ *sd = &_pdf_stat; + 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); + +#ifdef ENABLE_TOUNICODE + sd->annot_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + sd->annot_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + if (!sd->annot_dict) { + spc_warn(spe, "Ignoring annotation with invalid dictionary."); + 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; + return -1; + } + + error = spc_begin_annot(spe, sd->annot_dict); + + 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; +} + + +/* Color:.... */ +static int +spc_handler_pdfm_bcolor (struct spc_env *spe, struct spc_arg *ap) +{ + int error; + pdf_color fc, sc; + pdf_color *pfc, *psc; + + pdf_color_get_current(&psc, &pfc); + 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_push(&sc, &fc); + } + + 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; + pdf_color fc, sc; + pdf_color *pfc, *psc; + + pdf_color_get_current(&psc, &pfc); + 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; + transform_info ti; + + transform_info_clear(&ti); + if (spc_util_read_dimtrns(spe, &ti, args, NULL, 0) < 0) { + return -1; + } + + /* Create transformation matrix */ + pdf_copymatrix(&M, &(ti.matrix)); + M.e += ((1.0 - M.a) * spe->x_user - M.c * spe->y_user); + M.f += ((1.0 - M.d) * spe->y_user - M.b * spe->x_user); + + 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); + + 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; + +#ifdef ENABLE_TOUNICODE + item_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + item_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + 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; + } + +#ifdef ENABLE_TOUNICODE + info_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + info_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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(ident, info_dict); + RELEASE(ident); + + return 0; +} + +static int +spc_handler_pdfm_bead (struct spc_env *spe, struct spc_arg *args) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *article; + pdf_obj *article_info; + char *article_name; + pdf_rect rect; + long page_no; + transform_info ti; + pdf_coord cp; + + 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, NULL, 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; + } + + cp.x = spe->x_user; cp.y = spe->y_user; + pdf_dev_transform(&cp, NULL); + if (ti.flags & INFO_HAS_USER_BBOX) { + rect.llx = ti.bbox.llx + cp.x; + rect.lly = ti.bbox.lly + cp.y; + rect.urx = ti.bbox.urx + cp.x; + rect.ury = ti.bbox.ury + cp.y; + } else { + rect.llx = cp.x; + rect.lly = cp.y - spe->mag * ti.depth; + rect.urx = cp.x + spe->mag * ti.width; + rect.ury = cp.y + spe->mag * ti.height; + } + + skip_white(&args->curptr, args->endptr); + if (args->curptr[0] != '<') { + article_info = pdf_new_dict(); + } else { +#ifdef ENABLE_TOUNICODE + article_info = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + article_info = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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(article_name, article_info); + } + page_no = pdf_doc_current_page_number(); + 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) +{ + struct spc_pdf_ *sd = &_pdf_stat; + int xobj_id; + char *ident = NULL; + pdf_obj *fspec, *attr = NULL; + transform_info ti; + long page_no; + + skip_white(&args->curptr, args->endptr); + if (args->curptr[0] == '@') { + ident = parse_opt_ident(&args->curptr, args->endptr); + xobj_id = findresource(sd, ident); + if (xobj_id >= 0) { + spc_warn(spe, "Object reference name for image \"%s\" already used.", ident); + RELEASE(ident); + return -1; + } + } + + transform_info_clear(&ti); + page_no = 1; + if (spc_util_read_dimtrns(spe, &ti, args, &page_no, 0) < 0) { + 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) { + attr = parse_pdf_object(&args->curptr, args->endptr, NULL); + if (!attr || !PDF_OBJ_DICTTYPE(attr)) { + spc_warn(spe, "Ignore invalid attribute dictionary."); + if (attr) pdf_release_obj(attr); + } + } + + xobj_id = pdf_ximage_findresource(pdf_string_value(fspec), page_no, attr); + 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)) + pdf_dev_put_image(xobj_id, &ti, spe->x_user, spe->y_user); + + if (ident) { + if (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); + addresource(sd, ident, xobj_id); + 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; + } + + array = parse_pdf_object(&args->curptr, args->endptr, NULL); + if (!array) { + spc_warn(spe, "No destination not 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(&args->curptr, args->endptr, NULL); + 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(&args->curptr, args->endptr, NULL); + 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) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *docinfo, *dict; + +#ifdef ENABLE_TOUNICODE + dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *catalog, *dict; + pdf_obj *pref_old, *pref_add; + +#ifdef ENABLE_TOUNICODE + dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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(ident); + RELEASE(ident); + } else { /* Close all? */ + spc_clear_objects(); + } + + 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(&args->curptr, args->endptr, NULL); + if (!object) { + spc_warn(spe, "Could not find an object definition for \"%s\".", ident); + RELEASE(ident); + return -1; + } else { + spc_push_object(ident, object); + } + RELEASE(ident); + + return 0; +} + +static int +spc_handler_pdfm_content (struct spc_env *spe, struct spc_arg *args) +{ + long len = 0; + + skip_white(&args->curptr, args->endptr); + if (args->curptr < args->endptr) { + pdf_tmatrix M; + + pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user, spe->y_user); + 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 = (long) (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; + if (!direct) { + M.a = M.d = 1.0; M.b = M.c = 0.0; + M.e = spe->x_user; M.f = spe->y_user; + pdf_dev_concat(&M); + } + pdf_doc_add_page_content(" ", 1); /* op: */ + pdf_doc_add_page_content(args->curptr, (long) (args->endptr - args->curptr)); /* op: ANY */ + if (!direct) { + M.e = -spe->x_user; M.f = -spe->y_user; + 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(); + pdf_dev_get_coord(&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); + pdf_dev_push_coord(spe->x_user, spe->y_user); + return 0; +} + +static int +spc_handler_pdfm_econtent (struct spc_env *spe, struct spc_arg *args) +{ + pdf_dev_pop_coord(); + pdf_dev_grestore(); + pdf_dev_reset_color(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, (long) (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; + long 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); + if (instring) + pdf_add_stream(fstream, instring, strlen(instring)); + 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_dict(&args->curptr, args->endptr, NULL); + if (!tmp) { + spc_warn(spe, "Parsing dictionary failed."); + pdf_release_obj(fstream); + 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(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 xobj_id; + char *ident; + pdf_rect cropbox; + 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, NULL, 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; + } + + xobj_id = pdf_doc_begin_grabbing(ident, spe->x_user, spe->y_user, &cropbox); + + if (xobj_id < 0) { + RELEASE(ident); + spc_warn(spe, "Couldn't start form object."); + return -1; + } + + spc_push_object(ident, pdf_ximage_get_reference(xobj_id)); + RELEASE(ident); + + return 0; +} + +/* 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) +{ + pdf_obj *attrib = NULL; + + skip_white(&args->curptr, args->endptr); + + if (args->curptr < args->endptr) { + attrib = parse_pdf_dict(&args->curptr, args->endptr, NULL); + if (attrib && !PDF_OBJ_DICTTYPE(attrib)) { + pdf_release_obj(attrib); + attrib = NULL; + } + } + pdf_doc_end_grabbing(attrib); + + return 0; +} + +/* 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) +{ + struct spc_pdf_ *sd = &_pdf_stat; + 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, NULL, 0) < 0) { + RELEASE(ident); + return -1; + } + } + + /* Dvipdfmx was suddenly changed to use file name to identify + * external images. We can't use ident to find image resource + * here. + */ + xobj_id = findresource(sd, ident); + if (xobj_id < 0) { + xobj_id = pdf_ximage_findresource(ident, 0, NULL); + if (xobj_id < 0) { + spc_warn(spe, "Specified (image) object doesn't exist: %s", ident); + RELEASE(ident); + return -1; + } + } + + pdf_dev_put_image(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; +} + +static int +spc_handler_pdfm_mapline (struct spc_env *spe, struct spc_arg *ap) +{ + fontmap_rec *mrec; + char *map_name, opchr; + int error = 0; + + 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; + case '+': + mrec = NEW(1, fontmap_rec); + pdf_init_fontmap_record(mrec); + error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr), is_pdfm_mapline(ap->curptr)); + if (error) + spc_warn(spe, "Invalid fontmap line."); + else { + pdf_append_fontmap_record(mrec->map_name, mrec); + } + pdf_clear_fontmap_record(mrec); + RELEASE(mrec); + break; + default: + mrec = NEW(1, fontmap_rec); + pdf_init_fontmap_record(mrec); + error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr), is_pdfm_mapline(ap->curptr)); + if (error) + spc_warn(spe, "Invalid fontmap line."); + 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; +} + + +#ifdef ENABLE_TOUNICODE +static int +spc_handler_pdfm_tounicode (struct spc_env *spe, struct spc_arg *args) +{ + struct spc_pdf_ *sd = &_pdf_stat; + char *cmap_name; + + /* 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); + return 0; +} +#endif /* ENABLE_TOUNICODE */ + + +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}, + +#ifdef ENABLE_TOUNICODE + {"tounicode", spc_handler_pdfm_tounicode}, +#endif /* ENABLE_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}, + {"encrypt", spc_handler_pdfm_do_nothing}, +}; + +int +spc_pdfm_check_special (const char *buf, long 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) { + 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/dvipdf-x/src/spc_tpic.c b/Build/source/texk/dvipdf-x/src/spc_tpic.c new file mode 100644 index 00000000000..d0a6e91c0f4 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/spc_tpic.c @@ -0,0 +1,1114 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if 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[32]; + 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); + + 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, long *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; + long 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; + long 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; + long 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; + long 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; + long 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; + long 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; + long 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, + struct spc_arg *ap, 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_get_version() < 4) { + 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 (struct spc_env *spe, + struct spc_arg *ap, void *dp) +{ + struct spc_tpic_ *tp = dp; + + ASSERT(tp); + + tpic__clear(tp); + + return 0; +} + +static int +spc_handler_tpic__eophook (struct spc_env *spe, + struct spc_arg *ap, 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, + struct spc_arg *ap, 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(NULL, NULL, tp); +} + +int +spc_tpic_at_end_page (void) +{ + struct spc_tpic_ *tp = &_tpic_state; + return spc_handler_tpic__eophook(NULL, NULL, tp); +} + + +int +spc_tpic_at_begin_document (void) +{ + struct spc_tpic_ *tp = &_tpic_state; + return spc_handler_tpic__init(NULL, NULL, tp); +} + +int +spc_tpic_at_end_document (void) +{ + struct spc_tpic_ *tp = &_tpic_state; + return spc_handler_tpic__clean(NULL, NULL, tp); +} + + +#if DEBUG +#include "pdfparse.h" /* parse_val_ident :( */ + +static pdf_obj * +spc_parse_kvpairs (struct spc_env *spe, 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 ) /* , void *dp) */ +{ + struct spc_tpic_ *tp = &_tpic_state; + pdf_obj *dict; + int error = 0; + + dict = spc_parse_kvpairs(spe, 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_get_version() < 4) { + 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, long 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/dvipdf-x/src/spc_util.c b/Build/source/texk/dvipdf-x/src/spc_util.c new file mode 100644 index 00000000000..83fc0651377 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/spc_util.c @@ -0,0 +1,791 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxutil.h" + +#include "pdfdev.h" +#include "pdfparse.h" +#include "pdfcolor.h" +#include "pdfdraw.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); + +static int +spc_util_read_numbers (double *values, int num_values, + struct spc_env *spe, 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, spe, 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, spe, 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, spe, 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, "hsb")) { + nc = spc_util_read_numbers(cv, 3, spe, 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; +} + +/* Argumaent 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[4]; /* at most four */ + int nc, isarry = 0; + int error = 0; + char *q; + + skip_blank(&ap->curptr, ap->endptr); + + if (ap->curptr[0] == '[') { + ap->curptr++; skip_blank(&ap->curptr, ap->endptr); + isarry = 1; + } + + nc = spc_util_read_numbers(cv, 4, spe, 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) { + error = pdf_color_namedcolor(colorspec, q); + if (error) + spc_warn(spe, "Unrecognized color name: %s, keep the current color", q); + RELEASE(q); + } else { + error = -1; + } + 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) +{ + ASSERT(colorspec && spe && ap); + + skip_blank(&ap->curptr, ap->endptr); + if (ap->curptr >= ap->endptr) { + return -1; + } + return spc_read_color_color(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. + */ +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 + "pt", "in", "cm", "mm", "bp", NULL + }; + int k, error = 0; + + q = parse_float_decimal(&ap->curptr, ap->endptr); + if (!q) + return -1; + + v = atof(q); + RELEASE(q); + + q = parse_c_ident(&ap->curptr, ap->endptr); + if (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"); + } + 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; + default: + spc_warn(spe, "Unknown unit of measure: %s", q); + error = -1; + break; + } + RELEASE(q); + } + + *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; +} + + +static int +spc_read_dimtrns_pdfm (struct spc_env *spe, transform_info *p, struct spc_arg *ap, long *page_no) +{ + 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", +#define K_TRN__MATRIX 8 + "matrix", +#undef K__CLIP +#define K__CLIP 9 + "clip", +#define K__PAGE 10 + "page", +#define K__HIDE 11 + "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, spe, 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, spe, 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, spe, ap) == 1) + *page_no = (long) page; + else + error = -1; + } + 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, long *page_no, int syntax) +{ + ASSERT(ti && spe && args); + + if (syntax) { + ASSERT(!page_no); + return spc_read_dimtrns_dvips(spe, ti, args); + } else { + return spc_read_dimtrns_pdfm (spe, ti, args, page_no); + } + + return -1; +} + + +/* Color names */ +#ifdef rgb +#undef rgb +#endif +#ifdef cmyk +#undef cmyk +#endif +#define gray(g) {1, {g}} +#define rgb8(r,g,b) {3, {((r)/255.0), ((g)/255.0), ((b)/255.0), 0.0}} +#define cmyk(c,m,y,k) {4, {(c), (m), (y), (k)}} + +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/dvipdf-x/src/spc_util.h b/Build/source/texk/dvipdf-x/src/spc_util.h new file mode 100644 index 00000000000..c7251069210 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/spc_util.h @@ -0,0 +1,43 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 "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); +extern int spc_util_read_pdfcolor (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *args, pdf_color *defaultcolor); +extern int spc_util_read_dimtrns (struct spc_env *spe, transform_info *dimtrns, struct spc_arg *args, long *page, int syntax); +extern int spc_util_read_length (struct spc_env *spe, double *length, struct spc_arg *ap); + +#endif /* _SPC_UTIL_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/specials.c b/Build/source/texk/dvipdf-x/src/specials.c new file mode 100644 index 00000000000..dc5bf600028 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/specials.c @@ -0,0 +1,600 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "numbers.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" +#ifdef XETEX +#include "spc_xtx.h" +#endif + +#include "specials.h" + +static int verbose = 0; +void +spc_set_verbose (void) +{ + verbose++; +} + + +void +spc_warn (struct spc_env *spe, const char *fmt, ...) +{ + va_list ap; + static char buf[1024]; + + va_start(ap, fmt); + + vsprintf(buf, 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; +} + + + +static struct ht_table *named_objects = NULL; + +/* 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; + + ASSERT(named_objects); + + 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 = 0.0; + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.x, .01)); + break; + case K_OBJ__YPOS: + cp.x = 0.0; 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(named_objects, 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; + + ASSERT(named_objects); + + 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 = 0.0; + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.x, .01)); + break; + case K_OBJ__YPOS: + cp.x = 0.0; 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(named_objects, 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 (const char *key, pdf_obj *value) +{ + ASSERT(named_objects); + + if (!key || !value) + return; + + pdf_names_add_object(named_objects, key, strlen(key), value); +} + +void +spc_flush_object (const char *key) +{ + pdf_names_close_object(named_objects, key, strlen(key)); +} + +void +spc_clear_objects (void) +{ + pdf_delete_name_tree(&named_objects); + named_objects = pdf_new_name_tree(); +} + + +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, long 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_ */ + + 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) (); + int (*eodhk_func) (); + int (*bophk_func) (); + int (*eophk_func) (); + int (*check_func) (const char *, long); + 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, + NULL, + spc_pdfm_check_special, + spc_pdfm_setup_handler + }, + +#ifdef XETEX + {"x:", + NULL, + NULL, + NULL, + NULL, + spc_xtx_check_special, + spc_xtx_setup_handler + }, +#endif + + {"ps:", +#ifdef XETEX + spc_dvips_at_begin_document, + spc_dvips_at_end_document, + spc_dvips_at_begin_page, +#else + NULL, + NULL, + NULL, +#endif + spc_dvips_at_end_page, + spc_dvips_check_special, + spc_dvips_setup_handler + }, + + {"color", + 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, + 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, + spc_html_check_special, + spc_html_setup_handler + }, + + {"unknown", + NULL, + NULL, + NULL, + NULL, + spc_misc_check_special, + spc_misc_setup_handler + }, + + {NULL} /* end */ +}; + +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; + + ASSERT(!named_objects); + + named_objects = pdf_new_name_tree(); + + for (i = 0; known_specials[i].key != NULL; i++) { + if (known_specials[i].bodhk_func) { + error = known_specials[i].bodhk_func(); + } + } + + return error; +} + +int +spc_exec_at_end_document (void) +{ + int error = 0; + int i; + + for (i = 0; known_specials[i].key != NULL; i++) { + if (known_specials[i].eodhk_func) { + error = known_specials[i].eodhk_func(); + } + } + + if (named_objects) { + pdf_delete_name_tree(&named_objects); + } + + 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; + long 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(*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(*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, long size, + double x_user, double y_user, double mag) +{ + int error = -1; + int i, found; + struct spc_env spe; + struct spc_arg args; + struct spc_handler special; + + if (verbose > 3) { + 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); + } + break; + } + } + + check_garbage(&args); + + return error; +} + diff --git a/Build/source/texk/dvipdf-x/src/tfm.c b/Build/source/texk/dvipdf-x/src/tfm.c new file mode 100644 index 00000000000..a296b8848de --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tfm.c @@ -0,0 +1,1216 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "mfileio.h" +#include "error.h" + +#include "numbers.h" +#include "dpxutil.h" + +#include "tfm.h" + +#define TFM_FORMAT 1 +#define OFM_FORMAT 2 + +#define FWBASE ((double) (1<<20)) + +static int verbose = 0; + + +#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) +#endif /* !WITHOUT_ASCII_PTEX */ + +#if !defined(WITHOUT_ASCII_PTEX) +#define CHARACTER_INDEX(i) ((i>0xFFFFul ? 0x10000ul : 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 + UNSIGNED_BYTE id; + UNSIGNED_BYTE nt; +#endif /* !WITHOUT_ASCII_PTEX */ +#ifndef WITHOUT_OMEGA + SIGNED_QUAD level; +#endif /* !WITHOUT_OMEGA */ + UNSIGNED_QUAD wlenfile; + UNSIGNED_QUAD wlenheader; + UNSIGNED_QUAD bc, ec; + UNSIGNED_QUAD nwidths, nheights, ndepths; + UNSIGNED_QUAD nitcor, nlig, nkern, nextens; + UNSIGNED_QUAD nfonparm; +#ifndef WITHOUT_OMEGA + UNSIGNED_QUAD fontdir; + UNSIGNED_QUAD nco, ncw, npc; +#endif /* !WITHOUT_OMEGA */ + SIGNED_QUAD *header; +#ifndef WITHOUT_ASCII_PTEX + UNSIGNED_PAIR *chartypes; +#endif /* !WITHOUT_ASCII_PTEX */ + UNSIGNED_QUAD *char_info; + UNSIGNED_PAIR *width_index; + UNSIGNED_BYTE *height_index; + UNSIGNED_BYTE *depth_index; + SIGNED_QUAD *width; + SIGNED_QUAD *height; + SIGNED_QUAD *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 +{ + long first_char; + long 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; + unsigned short *indices; +}; + +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 long +lookup_char (const struct char_map *map, long 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; + + return -1; +} + +static long +lookup_range (const struct range_map *map, long charcode) +{ + long 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; + long 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); + } +} + +void +tfm_set_verbose (void) +{ + verbose++; +} + + +static long +fread_fwords (SIGNED_QUAD *words, SIGNED_QUAD nmemb, FILE *fp) +{ + long i; + + for (i = 0; i < nmemb; i++) + words[i] = get_signed_quad(fp); + + return nmemb*4; +} + +static long +fread_uquads (UNSIGNED_QUAD *quads, SIGNED_QUAD nmemb, FILE *fp) +{ + long 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, SIGNED_QUAD tfm_file_size) +{ + UNSIGNED_QUAD 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 (tfm_file_size < 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 %ld bytes but it says it is %ld bytes!", + expected_size * 4, tfm->wlenfile * 4); + if (tfm_file_size > expected_size *4) { + WARN("Proceeding nervously..."); + } else { + ERROR("Can't proceed..."); + } + } +} + +static void +tfm_get_sizes (FILE *tfm_file, SIGNED_QUAD tfm_file_size, struct tfm_font *tfm) +{ +#ifndef WITHOUT_ASCII_PTEX + { + UNSIGNED_PAIR 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 void +jfm_do_char_type_array (FILE *tfm_file, struct tfm_font *tfm) +{ + UNSIGNED_PAIR charcode; + UNSIGNED_PAIR chartype; + long i; + + tfm->chartypes = NEW(65536, UNSIGNED_PAIR); + for (i = 0; i < 65536; i++) { + tfm->chartypes[i] = 0; + } + for (i = 0; i < tfm->nt; i++) { + charcode = get_unsigned_pair(tfm_file); + chartype = get_unsigned_pair(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; + long code; + + fm->charmap.type = MAPTYPE_CHAR; + fm->charmap.data = map = NEW(1, struct char_map); + map->coverage.first_char = 0; + map->coverage.num_chars = 0x10FFFFu; + map->indices = NEW(0x10001ul, unsigned short); + + for (code = 0; code <= 0xFFFFu; code++) { + map->indices[code] = tfm->chartypes[code]; + } + map->indices[0x10000ul] = tfm->chartypes[0]; + } 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; + map->coverages[0].num_chars = 0x10FFFFu; + 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) +{ + UNSIGNED_QUAD charinfo; + UNSIGNED_PAIR width_index, 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 / 16777216ul); + height_index = (charinfo / 0x100000ul) & 0xf; + depth_index = (charinfo / 0x10000ul) & 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, SIGNED_QUAD 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, SIGNED_QUAD ofm_file_size) +{ + UNSIGNED_QUAD 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, UNSIGNED_QUAD ofm_file_size, struct tfm_font *tfm) +{ + tfm->level = get_signed_quad(ofm_file); + + tfm->wlenfile = get_signed_quad(ofm_file); + tfm->wlenheader = get_signed_quad(ofm_file); + tfm->bc = get_signed_quad(ofm_file); + tfm->ec = get_signed_quad(ofm_file); + if (tfm->ec < tfm->bc) { + ERROR("OFM file error: ec(%u) < bc(%u) ???", tfm->ec, tfm->bc); + } + tfm->nwidths = get_signed_quad(ofm_file); + tfm->nheights = get_signed_quad(ofm_file); + tfm->ndepths = get_signed_quad(ofm_file); + tfm->nitcor = get_signed_quad(ofm_file); + tfm->nlig = get_signed_quad(ofm_file); + tfm->nkern = get_signed_quad(ofm_file); + tfm->nextens = get_signed_quad(ofm_file); + tfm->nfonparm = get_signed_quad(ofm_file); + tfm->fontdir = get_signed_quad(ofm_file); + 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_signed_quad(ofm_file); + tfm->ncw = get_signed_quad(ofm_file); + tfm->npc = get_signed_quad(ofm_file); + seek_absolute(ofm_file, 4*(tfm->nco - tfm->wlenheader)); + } 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) +{ + UNSIGNED_QUAD num_chars; + + num_chars = tfm->ec - tfm->bc + 1; + if (num_chars != 0) { + UNSIGNED_QUAD i; + + tfm->width_index = NEW(num_chars, UNSIGNED_PAIR); + tfm->height_index = NEW(num_chars, UNSIGNED_BYTE); + tfm->depth_index = NEW(num_chars, UNSIGNED_BYTE); + 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 */ + get_unsigned_quad(tfm_file); + } + } +} + +static void +ofm_do_char_info_one (FILE *tfm_file, struct tfm_font *tfm) +{ + UNSIGNED_QUAD num_char_infos; + UNSIGNED_QUAD num_chars; + + num_char_infos = tfm->ncw / (3 + (tfm->npc / 2)); + num_chars = tfm->ec - tfm ->bc + 1; + + if (num_chars != 0) { + UNSIGNED_QUAD i; + UNSIGNED_QUAD char_infos_read; + + tfm->width_index = NEW(num_chars, UNSIGNED_PAIR); + tfm->height_index = NEW(num_chars, UNSIGNED_BYTE); + tfm->depth_index = NEW(num_chars, UNSIGNED_BYTE); + 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 */ + get_unsigned_quad(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, UNSIGNED_QUAD num_chars) +{ + long 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, UNSIGNED_QUAD 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, UNSIGNED_QUAD 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, UNSIGNED_QUAD); + 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; + UNSIGNED_QUAD 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 (verbose) { + if (format == TFM_FORMAT) + MESG("(TFM:%s", tfm_name); + else if (format == OFM_FORMAT) + MESG("(OFM:%s", tfm_name); + if (verbose > 1) + MESG("[%s]", file_name); + } + + RELEASE(file_name); + + tfm_file_size = file_size(tfm_file); + 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 (verbose) + 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, SIGNED_QUAD ch) +{ + struct font_metric *fm; + long 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, SIGNED_QUAD ch) +{ + struct font_metric *fm; + long 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, SIGNED_QUAD ch) +{ + struct font_metric *fm; + long 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, SIGNED_QUAD ch) +{ + return ((double) tfm_get_fw_width(font_id, ch)/FWBASE); +} + +#if 0 +double +tfm_get_height (int font_id, SIGNED_QUAD ch) +{ + return ((double) tfm_get_fw_height(font_id, ch)/FWBASE); +} + +double +tfm_get_depth (int font_id, SIGNED_QUAD 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++) { + SIGNED_QUAD 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; +} + +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++) { + SIGNED_QUAD 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++) { + SIGNED_QUAD 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; +} + +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 + +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/dvipdf-x/src/truetype.c b/Build/source/texk/dvipdf-x/src/truetype.c new file mode 100644 index 00000000000..41d06e65b78 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/truetype.c @@ -0,0 +1,1002 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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. +*/ + + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" + +#include "numbers.h" +#include "error.h" +#include "mem.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" + +#include "tfm.h" + +/* Modifying this has no effect :P */ +#ifdef ENABLE_NOEMBED +# undef ENABLE_NOEMBED +#endif + +int +pdf_font_open_truetype (pdf_font *font) +{ + char *ident; + int index, encoding_id; + pdf_obj *fontdict, *descriptor; + sfnt *sfont; + int embedding = 1; /* Must be embedded. */ + FILE *fp = NULL; + int length, error = 0; + + ASSERT( font ); + + ident = pdf_font_get_ident(font); + index = pdf_font_get_index(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) { + unsigned long 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) { + 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. + */ + encoding_id = pdf_font_get_encoding(font); + fontdict = pdf_font_get_resource(font); + descriptor = pdf_font_get_descriptor(font); +#ifdef ENABLE_NOEMBED + embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; +#endif /* ENABLE_NOEMBED */ + + ASSERT( fontdict && descriptor ); + + { + pdf_obj *tmp; + tmp = tt_get_fontdesc(sfont, &embedding, -1, 1); + if (!tmp) { + ERROR("Could not obtain necessary font info."); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + } + ASSERT(pdf_obj_typeof(tmp) == PDF_DICT); + + pdf_merge_dict(descriptor, tmp); + pdf_release_obj(tmp); + } + + if (!embedding) { + if (encoding_id >= 0 && + !pdf_encoding_is_predefined(encoding_id)) { + ERROR("Custom encoding not allowed for non-embedded TrueType font."); + sfnt_close(sfont); + return -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; + long flags; + +#ifndef ENABLE_NOEMBED + ERROR("Font file=\"%s\" can't be embedded due to liscence restrictions.", ident); +#endif /* ENABLE_NOEMBED */ + pdf_font_set_flags(font, PDF_FONT_FLAG_NOEMBED); + tmp = pdf_lookup_dict(descriptor, "Flags"); + if (tmp && pdf_obj_typeof(tmp) == PDF_NUMBER) { + flags = (long) 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)); + } + } + } + + { + char fontname[256]; + int n; + + memset(fontname, 0, 256); + length = tt_get_ps_fontname(sfont, fontname, 255); + if (length < 1) { + length = MIN(strlen(ident), 255); + strncpy(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) + ERROR("Can't find valid fontname for \"%s\".", ident); + pdf_font_set_fontname(font, fontname); + } + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + pdf_add_dict(fontdict, + pdf_new_name("Type"), pdf_new_name("Font")); + pdf_add_dict(fontdict, + pdf_new_name("Subtype"), pdf_new_name("TrueType")); + + return 0; +} + +/* + * 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 *tmparray; + int code, firstchar, lastchar, tfm_id; + char *usedchars; + + fontdict = pdf_font_get_resource (font); + usedchars = pdf_font_get_usedchars (font); + + tmparray = pdf_new_array(); + 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???"); + pdf_release_obj(tmparray); + return; + } + tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + for (code = firstchar; code <= lastchar; code++) { + if (usedchars[code]) { + double width; + if (tfm_id < 0) /* tfm is not found */ + width = widths[code]; + else + width = 1000. * tfm_get_width(tfm_id, code); + pdf_add_array(tmparray, + pdf_new_number(ROUND(width, 0.1))); + } else { + pdf_add_array(tmparray, pdf_new_number(0.0)); + } + } + + if (pdf_array_length(tmparray) > 0) { + pdf_add_dict(fontdict, + pdf_new_name("Widths"), pdf_ref_obj(tmparray)); + } + pdf_release_obj(tmparray); + + 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 verbose = 0; + +#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 (verbose > 2) + MESG("[glyphs:/.notdef"); + + count = 1; /* .notdef */ + for (code = 0; code < 256; code++) { + if (!usedchars[code]) + continue; + + if (verbose > 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, pdf_font_get_ident(font)); + 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 (verbose > 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 (verbose > 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 (verbose > 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 (long *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 (verbose > 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 (verbose >= 0) /* give warning */ + WARN("Glyph \"%s\" looks like a composite glyph...", + agln->name); + error = composeuchar(agln->unicodes, agln->n_components, NULL, gm, &idx); + if (verbose >= 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+%06lX", agln->unicodes[_i]); + else + _n += sprintf(_p+_n, "U+%04lX", 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; + long 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", + pdf_font_get_ident(font)); + 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, pdf_font_get_ident(font)); + 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], pdf_font_get_ident(font)); + } else { + if (verbose > 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 (verbose > 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 = pdf_font_get_descriptor(font); + char *ident = pdf_font_get_ident(font); + int encoding_id = pdf_font_get_encoding(font); + char *usedchars = pdf_font_get_usedchars(font); +#ifdef ENABLE_NOEMBED + int embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; +#endif /* ENABLE_NOEMBED */ + int index = pdf_font_get_index(font); + char **enc_vec; + pdf_obj *fontfile; + FILE *fp = NULL; + sfnt *sfont; + int i, error = 0; + + if (!pdf_font_is_in_use(font)) + return 0; + + verbose = pdf_font_get_verbose(); + + 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) { + unsigned long offset; + offset = ttc_read_offset(sfont, index); + if (offset == 0) ERROR("Invalid TTC index in %s.", ident); + error = sfnt_read_table_directory(sfont, ttc_read_offset(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 (verbose > 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/dvipdf-x/src/tt_aux.c b/Build/source/texk/dvipdf-x/src/tt_aux.c new file mode 100644 index 00000000000..fc19300f431 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tt_aux.c @@ -0,0 +1,271 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 /* HAVE_CONFIG_H */ + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "numbers.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, int 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 < 0 || 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) +{ + 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) { + RELEASE(os2); + RELEASE(head); + return NULL; + } + + descriptor = pdf_new_dict(); + pdf_add_dict (descriptor, + pdf_new_name ("Type"), + pdf_new_name ("FontDescriptor")); + + if (*embed) { + /* + 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 + */ + if (os2->fsType == 0x0000 || (os2->fsType & 0x0008)) { + /* the least restrictive license granted takes precedence. */ + *embed = 1; + } else if (os2->fsType & 0x0004) { + fprintf(stderr, + "\n** NOTICE: This document contains `Preview & Print' only"); + fprintf(stderr, " licensed font **\n"); + *embed = 1; + } else { + fprintf(stderr, + "\n*** Embedding disabled due to licensing restriction ***\n"); + *embed = 0; + } + } + + 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->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) { /* 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); + RELEASE(os2); + tt_release_post_table(post); + + return descriptor; +} + diff --git a/Build/source/texk/dvipdf-x/src/tt_aux.h b/Build/source/texk/dvipdf-x/src/tt_aux.h new file mode 100644 index 00000000000..fafef4e196a --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tt_aux.h @@ -0,0 +1,35 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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, int ttc_idx); + +/* FontDescriptor */ +extern pdf_obj *tt_get_fontdesc (sfnt *sfont, int *embed, int stemv, int type); + +#endif /* _TT_AUX_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/tt_cmap.c b/Build/source/texk/dvipdf-x/src/tt_cmap.c new file mode 100644 index 00000000000..6fad1352ded --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tt_cmap.c @@ -0,0 +1,1879 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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 "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 "unicode.h" +#include "agl.h" +#include "pdfparse.h" +#include "pdfresource.h" +#include "otl_conf.h" + +#include "dpxfile.h" + +/* Hash */ +#include "dpxutil.h" + +#include "tt_cmap.h" + +#define VERBOSE_LEVEL_MIN 0 +static int verbose = 0; +void +otf_cmap_set_verbose (void) +{ + otl_gsub_set_verbose(); + verbose++; +} + +/* 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) + ERROR("invalid cmap subtable"); + + 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) + ERROR("invalid cmap subtable"); + + 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 */ + + 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) + ERROR("invalid cmap subtable"); + + 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 { + 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) + ERROR("invalid cmap subtable"); + + 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]; + else + return 0; + + 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) + ERROR("invalid cmap subtable"); + + 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; + ULONG 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 TrueType cmap format."); + tt_cmap_release(cmap); + return NULL; + } + + 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: + ERROR("Unrecognized TrueType cmap format."); + } + } + RELEASE(cmap); + } + + return; +} + + +USHORT +tt_cmap_lookup (tt_cmap *cmap, long cc) +{ + USHORT gid = 0; + + ASSERT(cmap); + + if (cc > 0xffffL && cmap->format < 12) { + WARN("Four bytes charcode not supported in 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: + ERROR("Unrecognized TrueType cmap subtable format"); + break; + } + + return gid; +} + +/* Sorry for placing this here. + * We need to rewrite TrueType font support code... + */ + +#define WBUF_SIZE 1024 +static unsigned char wbuf[WBUF_SIZE]; + +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}; + +static void +load_cmap4 (struct cmap4 *map, + unsigned char *GIDToCIDMap, CMap *cmap) +{ + USHORT c0, c1, gid, cid; + USHORT j, d, segCount; + USHORT ch; + long i; + + 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 { + gid = (map->glyphIndexArray[j+d] + + map->idDelta[i]) & 0xffff; + } + if (gid != 0 && gid != 0xffff) { + if (GIDToCIDMap) { + cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); + if (cid == 0) + WARN("GID %u does not have corresponding CID %u.", + gid, cid); + } else { + cid = gid; + } + wbuf[0] = 0; + wbuf[1] = 0; + wbuf[2] = (ch >> 8) & 0xff; + wbuf[3] = ch & 0xff; + CMap_add_cidchar(cmap, wbuf, 4, cid); + } + } + } + + return; +} + +static void +load_cmap12 (struct cmap12 *map, + unsigned char *GIDToCIDMap, CMap *cmap) +{ + ULONG i, ch; /* LONG ? */ + USHORT gid, cid; + + for (i = 0; i < map->nGroups; i++) { + for (ch = map->groups[i].startCharCode; + ch <= map->groups[i].endCharCode; + ch++) { + long d = ch - map->groups[i].startCharCode; + gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); + if (GIDToCIDMap) { + cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); + if (cid == 0) + WARN("GID %u does not have corresponding CID %u.", gid, cid); + } else { + cid = gid; + } + wbuf[0] = (ch >> 24) & 0xff; + wbuf[1] = (ch >> 16) & 0xff; + wbuf[2] = (ch >> 8) & 0xff; + wbuf[3] = ch & 0xff; + CMap_add_cidchar(cmap, wbuf, 4, cid); + } + } + + return; +} + +/* 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" + +static int +handle_CIDFont (sfnt *sfont, + unsigned char **GIDToCIDMap, CIDSysInfo *csi) +{ + cff_font *cffont; + long offset, i; + card16 num_glyphs, gid; + cff_charsets *charset; + unsigned char *map; + struct tt_maxp_table *maxp; + + ASSERT(csi); + + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset == 0) { + csi->registry = NULL; + csi->ordering = NULL; + *GIDToCIDMap = NULL; + return 0; + } + + maxp = tt_read_maxp_table(sfont); + num_glyphs = (card16) maxp->numGlyphs; + RELEASE(maxp); + if (num_glyphs < 1) + ERROR("No glyph contained in this font..."); + + cffont = cff_open(sfont->stream, offset, 0); + if (!cffont) + ERROR("Could not open CFF font..."); + + + if (!(cffont->flag & FONTTYPE_CIDFONT)) { + cff_close(cffont); + csi->registry = NULL; + csi->ordering = NULL; + *GIDToCIDMap = NULL; + return 0; + } + + if (!cff_dict_known(cffont->topdict, "ROS")) { + ERROR("No CIDSystemInfo???"); + } 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); + charset = cffont->charsets; + if (!charset) { + ERROR("No CFF charset data???"); + } + + map = NEW(num_glyphs * 2, unsigned char); + memset(map, 0, num_glyphs * 2); + switch (charset->format) { + case 0: + { + s_SID *cids; /* CID... */ + + cids = charset->data.glyphs; + for (gid = 1, i = 0; + i < charset->num_entries; i++) { + map[2*gid ] = (cids[i] >> 8) & 0xff; + map[2*gid+1] = cids[i] & 0xff; + 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) { + map[2*gid ] = (cid >> 8) & 0xff; + map[2*gid + 1] = cid & 0xff; + gid++; + } + } + } + break; + case 2: + { + cff_range2 *ranges; + card16 cid, count; + + ranges = charset->data.range2; + if (charset->num_entries == 1 && + ranges[0].first == 1) { + /* "Complete" CIDFont */ + RELEASE(map); map = NULL; + } 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) { + map[gid] = (cid >> 8) & 0xff; + map[gid] = cid & 0xff; + gid++; + } + } + + } + } + break; + default: + RELEASE(map); map = NULL; + ERROR("Unknown CFF charset format...: %d", charset->format); + break; + } + cff_close(cffont); + + *GIDToCIDMap = map; + return 1; +} + +/* + * 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 USHORT +handle_subst_glyphs (CMap *cmap, + CMap *cmap_add, const char *used_glyphs) +{ + USHORT count; + USHORT i, gid; + + for (count = 0, i = 0; i < 8192; i++) { + int j; + long len, inbytesleft, outbytesleft; + const unsigned char *inbuf; + unsigned char *outbuf; + + if (used_glyphs[i] == 0) + continue; + + for (j = 0; j < 8; j++) { + gid = 8 * i + j; + + if (!is_used_char2(used_glyphs, gid)) + continue; + + if (!cmap_add) + WARN("No Unicode mapping available: GID=%u", gid); + else { + wbuf[0] = (gid >> 8) & 0xff; + wbuf[1] = gid & 0xff; + inbuf = wbuf; + inbytesleft = 2; + outbuf = wbuf + 2; + outbytesleft = WBUF_SIZE - 2; + CMap_decode(cmap_add, + &inbuf , &inbytesleft, + &outbuf, &outbytesleft); + if (inbytesleft != 0) { + WARN("CMap conversion failed..."); + } else { + len = WBUF_SIZE - 2 - outbytesleft; + CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len); + count++; + + if (verbose > VERBOSE_LEVEL_MIN) { + long _i; + + MESG("otf_cmap>> Additional ToUnicode mapping: <%04X> <", gid); + for (_i = 0; _i < len; _i++) { + MESG("%02X", wbuf[2 + _i]); + } + MESG(">\n"); + } + + } + } + + } + } + + return count; +} + +static pdf_obj * +create_ToUnicode_cmap4 (struct cmap4 *map, + const char *cmap_name, CMap *cmap_add, + const char *used_glyphs) +{ + pdf_obj *stream = NULL; + CMap *cmap; + USHORT c0, c1, gid, count, ch; + USHORT i, j, d, segCount; + char used_glyphs_copy[8192]; + + 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); + + memcpy(used_glyphs_copy, used_glyphs, 8192); + + segCount = map->segCountX2 / 2; + for (count = 0, i = 0; i < segCount; 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 { + gid = (map->glyphIndexArray[j+d] + + map->idDelta[i]) & 0xffff; + } + if (is_used_char2(used_glyphs_copy, gid)) { + count++; + + wbuf[0] = (gid >> 8) & 0xff; + wbuf[1] = (gid & 0xff); + + wbuf[2] = (ch >> 8) & 0xff; + wbuf[3] = ch & 0xff; + + CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, 2); + + /* Avoid duplicate entry + * There are problem when two Unicode code is mapped to + * single glyph... + */ + used_glyphs_copy[gid/8] &= ~(1 << (7 - (gid % 8))); + count++; + } + } + } + + count += handle_subst_glyphs(cmap, cmap_add, used_glyphs_copy); + + if (count < 1) + stream = NULL; + else { + stream = CMap_create_stream(cmap, 0); + } + CMap_release(cmap); + + return stream; +} + + +static pdf_obj * +create_ToUnicode_cmap12 (struct cmap12 *map, + const char *cmap_name, CMap *cmap_add, + const char *used_glyphs) +{ + pdf_obj *stream = NULL; + CMap *cmap; + ULONG i, ch; + USHORT gid, count; + char used_glyphs_copy[8192]; + + 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); + + memcpy(used_glyphs_copy, used_glyphs, 8192); + for (count = 0, i = 0; i < map->nGroups; i++) { + for (ch = map->groups[i].startCharCode; + ch <= map->groups[i].endCharCode; ch++) { + unsigned char *p; + int len; + long d; + + p = wbuf + 2; + d = ch - map->groups[i].startCharCode; + gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); + if (is_used_char2(used_glyphs_copy, gid)) { + count++; + wbuf[0] = (gid >> 8) & 0xff; + wbuf[1] = (gid & 0xff); + len = UC_sput_UTF16BE((long)ch, &p, wbuf+WBUF_SIZE); + + used_glyphs_copy[gid/8] &= ~(1 << (7 - (gid % 8))); + CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, len); + } + } + } + + count += handle_subst_glyphs(cmap, cmap_add, used_glyphs_copy); + + if (count < 1) + stream = NULL; + else { + stream = CMap_create_stream(cmap, 0); + } + CMap_release(cmap); + + return stream; +} + +pdf_obj * +otf_create_ToUnicode_stream (const char *font_name, + int ttc_index, /* 0 for non-TTC */ + const char *used_glyphs) +{ + pdf_obj *cmap_ref = NULL; + long res_id; + pdf_obj *cmap_obj = NULL; + CMap *cmap_add; + int cmap_add_id; + tt_cmap *ttcmap; + char *normalized_font_name; + char *cmap_name; + FILE *fp = NULL; + sfnt *sfont; + long offset = 0; + int i; + + + /* replace slash in map name with dash to make the output cmap name valid, + * happens when XeTeX embeds full font path + * https://sourceforge.net/p/xetex/bugs/52/ + */ + normalized_font_name = NEW(strlen(font_name)+1, char); + strcpy(normalized_font_name, font_name); + for (i = 0; i < strlen(font_name); ++i) { + if (normalized_font_name[i] == '/') + normalized_font_name[i] = '-'; + } + + cmap_name = NEW(strlen(font_name)+strlen("-UTF16")+5, char); + sprintf(cmap_name, "%s,%03d-UTF16", normalized_font_name, ttc_index); + + res_id = pdf_findresource("CMap", cmap_name); + if (res_id >= 0) { + RELEASE(cmap_name); + cmap_ref = pdf_get_resource_reference(res_id); + return cmap_ref; + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otf_cmap>> Creating ToUnicode CMap for \"%s\"...\n", font_name); + } + + fp = DPXFOPEN(font_name, DPX_RES_TYPE_TTFONT); + if (!fp) { + fp = DPXFOPEN(font_name, DPX_RES_TYPE_OTFONT); + } + + if (!fp) { + RELEASE(cmap_name); + return NULL; + } + + sfont = sfnt_open(fp); + if (!sfont) { + ERROR("Could not open TrueType font file \"%s\"", font_name); + } + + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { + ERROR("Invalid TTC index"); + } + break; + default: + offset = 0; + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) { + ERROR("Could not read TrueType table directory."); + } + + cmap_add_id = CMap_cache_find(cmap_name); + if (cmap_add_id < 0) { + cmap_add = NULL; + } else { + cmap_add = CMap_cache_get(cmap_add_id); + } + + CMap_set_silent(1); /* many warnings without this... */ + ttcmap = tt_cmap_read(sfont, 3, 10); /* Microsoft UCS4 */ + if (ttcmap && + ttcmap->format == 12) { + WARN("Format 12 cmap table ... untested"); + cmap_obj = create_ToUnicode_cmap12(ttcmap->map, + cmap_name, cmap_add, used_glyphs); + } else { + ttcmap = tt_cmap_read(sfont, 3, 1); /* Microsoft UCS2 */ + if (ttcmap && + ttcmap->format == 4) { + cmap_obj = create_ToUnicode_cmap4(ttcmap->map, + cmap_name, cmap_add, used_glyphs); + } else { + ttcmap = tt_cmap_read(sfont, 0, 3); /* Unicode 2.0 or later */ + if (ttcmap && + ttcmap->format == 4) { + cmap_obj = create_ToUnicode_cmap4(ttcmap->map, + cmap_name, cmap_add, used_glyphs); + } else { + ERROR("Unable to read OpenType/TrueType Unicode cmap table."); + } + } + } + tt_cmap_release(ttcmap); + CMap_set_silent(0); + + if (cmap_obj) { + res_id = pdf_defineresource("CMap", cmap_name, + cmap_obj, PDF_RES_FLUSH_IMMEDIATE); + cmap_ref = pdf_get_resource_reference(res_id); + } else { + cmap_ref = NULL; + } + RELEASE(cmap_name); + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return cmap_ref; +} + +/* Must be smaller than (WBUF_SIZE-2)/8 */ +#define MAX_UNICODES 16 + +struct gent +{ + USHORT gid; + long ucv; /* assigned PUA unicode */ + + int num_unicodes; + long unicodes[MAX_UNICODES]; +}; + +static void +create_cmaps (CMap *cmap, CMap *tounicode, + struct ht_table *unencoded, unsigned char *GIDToCIDMap) +{ + struct ht_iter iter; + + ASSERT(cmap && unencoded); + + if (ht_set_iter(unencoded, &iter) < 0) + return; + + CMap_set_silent(1); /* many warnings without this... */ + + do { + struct gent *glyph; + unsigned char *ucv; + int i, len; + unsigned char *p, *endptr; + CID cid; + + glyph = (struct gent *) ht_iter_getval(&iter); + ucv = (unsigned char *) ht_iter_getkey(&iter, &len); + + if (GIDToCIDMap) { + cid = ((GIDToCIDMap[2 * glyph->gid] << 8)|GIDToCIDMap[2 * glyph->gid + 1]); + if (cid == 0) + WARN("Glyph gid=%u does not have corresponding CID.", glyph->gid); + } else { + cid = glyph->gid; + } + + CMap_add_cidchar(cmap, ucv, 4, cid); + + if (tounicode) { + wbuf[0] = (cid >> 8) & 0xff; + wbuf[1] = cid & 0xff; + p = wbuf + 2; + endptr = wbuf + WBUF_SIZE; + len = 0; + for (i = 0; i < glyph->num_unicodes; i++) { + len += UC_sput_UTF16BE(glyph->unicodes[i], &p, endptr); + } + CMap_add_bfchar(tounicode, wbuf, 2, wbuf + 2, len); + } + } while (ht_iter_next(&iter) >= 0); + + CMap_set_silent(0); + + ht_clear_iter(&iter); +} + +static void +add_glyph (struct ht_table *unencoded, + USHORT gid, long ucv, int num_unicodes, long *unicodes) +{ + struct gent *glyph; + int i; + + ASSERT(unencoded); + + if (gid == 0 || num_unicodes < 1) { + return; + } + + wbuf[0] = (ucv >> 24) & 0xff; + wbuf[1] = (ucv >> 16) & 0xff; + wbuf[2] = (ucv >> 8) & 0xff; + wbuf[3] = ucv & 0xff; + + glyph = NEW(1, struct gent); + glyph->gid = gid; + glyph->num_unicodes = num_unicodes; + for (i = 0; + i < num_unicodes && i < MAX_UNICODES; i++) { + glyph->unicodes[i] = unicodes[i]; + } + + ht_append_table(unencoded, wbuf, 4, glyph); +} + +/* This seriously affects speed... */ +static struct gent * +find_glyph (struct ht_table *unencoded, long ucv) +{ + ASSERT(unencoded); + + wbuf[0] = (ucv >> 24) & 0xff; + wbuf[1] = (ucv >> 16) & 0xff; + wbuf[2] = (ucv >> 8) & 0xff; + wbuf[3] = ucv & 0xff; + + return (struct gent *) ht_lookup_table(unencoded, wbuf, 4); +} + +static void +handle_subst (pdf_obj *dst_obj, pdf_obj *src_obj, int flag, + otl_gsub *gsub_list, tt_cmap *ttcmap, + struct ht_table *unencoded) +{ + pdf_obj *tmp; + long i, j, src_size, dst_size; + long src, dst; + long src_start, src_end, dst_start, dst_end; + + src_size = pdf_array_length(src_obj); + dst_size = pdf_array_length(dst_obj); + + dst_start = dst_end = -1; dst = 0; + src_start = src_end = -1; src = 0; + for (i = 0, j = 0; + i < src_size && j < dst_size; i++) { + USHORT gid; + int rv; + struct gent *glyph; + + tmp = pdf_get_array(src_obj, i); + if (PDF_OBJ_ARRAYTYPE(tmp)) { + src_start = (long) pdf_number_value(pdf_get_array(tmp, 0)); + src_end = (long) pdf_number_value(pdf_get_array(tmp, 1)); + } else { + src_start = src_end = (long) pdf_number_value(tmp); + } + for (src = src_start; src <= src_end; src++) { + glyph = find_glyph(unencoded, src); + if (glyph) + gid = glyph->gid; + else { + gid = tt_cmap_lookup(ttcmap, src); + } + dst++; + if (dst > dst_end) { + tmp = pdf_get_array(dst_obj, j++); + if (PDF_OBJ_ARRAYTYPE(tmp)) { + dst_start = (long) pdf_number_value(pdf_get_array(tmp, 0)); + dst_end = (long) pdf_number_value(pdf_get_array(tmp, 1)); + } else { + dst_start = dst_end = (long) pdf_number_value(tmp); + } + dst = dst_start; + } + if (gid == 0) { + if (flag == 'r' || flag == 'p') { + if (src < 0x10000) { + WARN("Font does not have glyph for U+%04X.", src); + } else { + WARN("Font does not have glyph for U+%06X.", src); + } + } + if (flag == 'r') { + ERROR("Missing glyph found..."); + } + continue; + } + rv = otl_gsub_apply(gsub_list, &gid); + if (rv < 0) { + if (flag == 'p' || flag == 'r') { + if (src < 0x10000) { + WARN("No substituted glyph for U+%04X.", src); + } else { + WARN("No substituted glyph for U+%06X.", src); + } + } + if (flag == 'r') { + ERROR("Missing glyph found..."); + } + continue; + } + + if (glyph) { + glyph->gid = gid; + } else { + add_glyph(unencoded, gid, dst, 1, &src); + } + + if (verbose > VERBOSE_LEVEL_MIN) { + if (dst < 0x10000) { + MESG("otf_cmap>> Substituted glyph gid=%u assigned to U+%04X\n", + gid, dst); + } else { + MESG("otf_cmap>> Substituted glyph gid=%u assigned to U+%06X\n", + gid, dst); + } + } + + } + } + + if (dst < dst_end || src < src_end || + i < src_size || j < dst_size) { + WARN("Number of glyphs in left-side and right-side not equal..."); + WARN("Please check .otl file..."); + } +} + +static void +handle_assign (pdf_obj *dst, pdf_obj *src, int flag, + otl_gsub *gsub_list, tt_cmap *ttcmap, + struct ht_table *unencoded) +{ + long unicodes[MAX_UNICODES], ucv; + int i, n_unicodes, rv; + USHORT gid_in[MAX_UNICODES], lig; + + n_unicodes = pdf_array_length(src); /* FIXME */ + ucv = (long) pdf_number_value(pdf_get_array(dst, 0)); /* FIXME */ + if (!UC_is_valid(ucv)) { + if (flag == 'r' || flag == 'p') { + if (ucv < 0x10000) { + WARN("Invalid Unicode in: %04X", ucv); + } else { + WARN("Invalid Unicode in: %06X", ucv); + } + } + if (flag == 'r') { + ERROR("Invalid Unicode code specified.", ucv); + } + return; + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Ligature component:"); + } + + for (i = 0; i < n_unicodes; i++) { + unicodes[i] = + (long) pdf_number_value(pdf_get_array(src, i)); + gid_in[i] = tt_cmap_lookup(ttcmap, unicodes[i]); + + if (verbose > VERBOSE_LEVEL_MIN) { + if (unicodes[i] < 0x10000) { + MESG(" U+%04X (gid=%u)", unicodes[i], gid_in[i]); + } else { + MESG(" U+%06X (gid=%u)", unicodes[i], gid_in[i]); + } + } + + if (gid_in[i] == 0) { + if (flag == 'r' || flag == 'p') { + if (unicodes[i] < 0x10000) { + WARN("Unicode char U+%04X not exist in font...", unicodes[i]); + } else { + WARN("Unicode char U+%06X not exist in font...", unicodes[i]); + } + } + if (flag == 'r') { + ERROR("Missing glyph found..."); + } + return; + } + + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + } + + rv = otl_gsub_apply_lig(gsub_list, + gid_in, (USHORT)n_unicodes, &lig); + if (rv < 0) { + if (flag == 'p') + WARN("No ligature found..."); + else if (flag == 'r') + ERROR("No ligature found..."); + return; + } + + add_glyph(unencoded, lig, ucv, n_unicodes, unicodes); + + if (verbose > VERBOSE_LEVEL_MIN) { + if (ucv < 0x10000) { + MESG("otf_cmap>> Ligature glyph gid=%u assigned to U+%04X\n", lig, ucv); + } else { + MESG("otf_cmap>> Ligature glyph gid=%u assigned to U+%06X\n", lig, ucv); + } + } + + return; +} + +static int +load_base_CMap (const char *cmap_name, int wmode, + CIDSysInfo *csi, unsigned char *GIDToCIDMap, + tt_cmap *ttcmap) +{ + int cmap_id; + + cmap_id = CMap_cache_find(cmap_name); + if (cmap_id < 0) { + CMap *cmap; + + 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); + + if (csi) { /* CID */ + CMap_set_CIDSysInfo(cmap, csi); + } else { + CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY); + } + + if (ttcmap->format == 12) { + load_cmap12(ttcmap->map, GIDToCIDMap, cmap); + } else if (ttcmap->format == 4) { + load_cmap4(ttcmap->map, GIDToCIDMap, cmap); + } + + cmap_id = CMap_cache_add(cmap); + } + + return cmap_id; +} + +static void +load_gsub (pdf_obj *conf, otl_gsub *gsub_list, sfnt *sfont) +{ + pdf_obj *rule; + char *script, *language, *feature; + long i, size; + + rule = otl_conf_get_rule(conf); + if (!rule) + return; + + script = otl_conf_get_script (conf); + language = otl_conf_get_language(conf); + + size = pdf_array_length(rule); + for (i = 0; i < size; i += 2) { + pdf_obj *tmp, *commands; + int flag; + long j, num_comms; + + tmp = pdf_get_array(rule, i); + flag = (int) pdf_number_value(tmp); + + commands = pdf_get_array(rule, i+1); + num_comms = pdf_array_length(commands); + + /* (assign|substitute) tag dst src */ + for (j = 0 ; j < num_comms; j += 4) { + tmp = pdf_get_array(commands, 1); + if (PDF_OBJ_STRINGTYPE(tmp)) { + feature = pdf_string_value(tmp); + if (otl_gsub_add_feat(gsub_list, + script, language, feature, sfont) < 0) { + if (flag == 'p') + WARN("No OTL feature matches \"%s.%s.%s\" found.", + script, language, feature); + else if (flag == 'r') + ERROR("No OTL feature matches \"%s.%s.%s\" found.", + script, language, feature); + } + } + + } + } + +} + +static void +handle_gsub (pdf_obj *conf, + tt_cmap *ttcmap, otl_gsub *gsub_list, + struct ht_table *unencoded) +{ + pdf_obj *rule; + char *script, *language, *feature; + long i, size; + + if (!conf) + return; + + rule = otl_conf_get_rule(conf); + if (!rule) { + return; + } + + if (!PDF_OBJ_ARRAYTYPE(rule)) { + WARN("Not arraytype?"); + return; + } + script = otl_conf_get_script (conf); + language = otl_conf_get_language(conf); + + size = pdf_array_length(rule); + for (i = 0; i < size; i += 2) { + pdf_obj *tmp, *commands; + long j, num_comms; + int flag; + + tmp = pdf_get_array(rule, i); + flag = (int) pdf_number_value(tmp); + + commands = pdf_get_array (rule, i+1); + num_comms = pdf_array_length(commands); + + for (j = 0; j < num_comms; j += 4) { + pdf_obj *operator; + pdf_obj *src, *dst, *feat; + int rv; + + /* (assing|substitute) tag dst src */ + operator = pdf_get_array(commands, j); + + feat = pdf_get_array(commands, j+1); + if (PDF_OBJ_STRINGTYPE(feat)) + feature = pdf_string_value(feat); + else + feature = NULL; + + dst = pdf_get_array(commands, j+2); + src = pdf_get_array(commands, j+3); + + rv = otl_gsub_select(gsub_list, script, language, feature); + if (rv < 0) { + if (flag == 'p') { + WARN("No GSUB feature %s.%s.%s loaded...", + script, language, feature); + } else if (flag == 'r') { + ERROR("No GSUB feature %s.%s.%s loaded...", + script, language, feature); + } + } else { + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> %s:\n", pdf_name_value(operator)); + } + + if (!strcmp(pdf_name_value(operator), "assign")) { + handle_assign(dst, src, flag, + gsub_list, ttcmap, unencoded); + } else if (!strcmp(pdf_name_value(operator), "substitute")) { + handle_subst(dst, src, flag, + gsub_list, ttcmap, unencoded); + } + } + + } + + } + +} + +static void CDECL +hval_free (void *hval) +{ + RELEASE(hval); +} + +int +otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC font */ + const char *otl_tags, int wmode) +{ + int cmap_id = -1; + int tounicode_id = -1, is_cidfont = 0; + sfnt *sfont; + unsigned long offset = 0; + char *base_name = NULL, *cmap_name = NULL; + char *tounicode_name = NULL; + FILE *fp = NULL; + otl_gsub *gsub_list = NULL; + tt_cmap *ttcmap; + CMap *cmap, *base, *tounicode = NULL; + CIDSysInfo csi = {NULL, NULL, 0}; + unsigned char *GIDToCIDMap = NULL; + + if (!map_name) + return -1; + + if (ttc_index > 999 || ttc_index < 0) { + return -1; /* Sorry for this... */ + } + + 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) return -1; + sfont = dfont_open(fp, ttc_index); + } else { + sfont = sfnt_open(fp); + } + + if (!sfont) { + ERROR("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name); + } + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { + ERROR("Invalid TTC index"); + } + break; + case SFNT_TYPE_TRUETYPE: + case SFNT_TYPE_POSTSCRIPT: + offset = 0; + break; + case SFNT_TYPE_DFONT: + offset = sfont->offset; + break; + default: + ERROR("Not a OpenType/TrueType/TTC font?: %s", map_name); + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) + ERROR("Could not read OpenType/TrueType table directory."); + + base_name = NEW(strlen(map_name)+strlen("-UCS4-H")+5, char); + if (wmode) + sprintf(base_name, "%s,%03d-UCS4-V", map_name, ttc_index); + else { + sprintf(base_name, "%s,%03d-UCS4-H", map_name, ttc_index); + } + + if (otl_tags) { + cmap_name = NEW(strlen(map_name)+strlen(otl_tags)+strlen("-UCS4-H")+6, char); + if (wmode) + sprintf(cmap_name, "%s,%03d,%s-UCS4-V", map_name, ttc_index, otl_tags); + else + sprintf(cmap_name, "%s,%03d,%s-UCS4-H", map_name, ttc_index, otl_tags); + } else { + cmap_name = NEW(strlen(base_name)+1, char); + strcpy(cmap_name, base_name); + } + + if (sfont->type == SFNT_TYPE_POSTSCRIPT) { + is_cidfont = handle_CIDFont(sfont, &GIDToCIDMap, &csi); + } else { + is_cidfont = 0; + } + + if (is_cidfont) { + tounicode_name = NULL; + } else { + tounicode_name = NEW(strlen(map_name)+strlen("-UTF16")+5, char); + sprintf(tounicode_name, "%s,%03d-UTF16", map_name, ttc_index); + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otf_cmap>> Unicode charmap for font=\"%s\" layout=\"%s\"\n", + map_name, (otl_tags ? otl_tags : "none")); + } + + cmap_id = CMap_cache_find(cmap_name); + if (cmap_id >= 0) { + RELEASE(cmap_name); + RELEASE(base_name); + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (tounicode_name) + RELEASE(tounicode_name); + + sfnt_close(sfont); + DPXFCLOSE(fp); + + if (verbose > VERBOSE_LEVEL_MIN) + MESG("otf_cmap>> Found at cmap_id=%d.\n", cmap_id); + + return cmap_id; + } + + 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) { + ERROR("Unable to read OpenType/TrueType Unicode cmap table."); + } + } + } + cmap_id = load_base_CMap(base_name, wmode, + (is_cidfont ? &csi : NULL), + GIDToCIDMap, ttcmap); + if (cmap_id < 0) + ERROR("Failed to read OpenType/TrueType cmap table."); + + if (!otl_tags) { + RELEASE(cmap_name); + RELEASE(base_name); + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (tounicode_name) + RELEASE(tounicode_name); + if (is_cidfont) { + if (csi.registry) + RELEASE(csi.registry); + if (csi.ordering) + RELEASE(csi.ordering); + } + tt_cmap_release(ttcmap); + sfnt_close(sfont); + DPXFCLOSE(fp); + + return cmap_id; + } + + base = CMap_cache_get(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, lrange_min, lrange_max, 4); */ + CMap_set_usecmap(cmap, base); + CMap_add_cidchar(cmap, lrange_max, 4, 0); /* FIXME */ + + if (is_cidfont) { + CMap_set_CIDSysInfo(cmap, &csi); + if (csi.registry) + RELEASE(csi.registry); + if (csi.ordering) + RELEASE(csi.ordering); + } else { + CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY); + } + + gsub_list = otl_gsub_new(); + + { + struct ht_table unencoded; + char *conf_name, *opt_tag; + pdf_obj *conf, *opt_conf; + + conf_name = NEW(strlen(otl_tags)+1, char); + memset (conf_name, 0, strlen(otl_tags)+1); + opt_tag = strchr(otl_tags, ':'); + if (opt_tag) { + opt_tag++; + strncpy(conf_name, otl_tags, + strlen(otl_tags) - strlen(opt_tag) - 1); + } else { + strcpy(conf_name, otl_tags); + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Read layout config. \"%s\"\n", conf_name); + } + + conf = otl_find_conf(conf_name); + if (!conf) + ERROR("Layout file \"%s\" not found...", conf_name); + + load_gsub(conf, gsub_list, sfont); + if (opt_tag) { + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Layout option \"%s\" enabled\n", opt_tag); + } + opt_conf = otl_conf_find_opt(conf, opt_tag); + if (!opt_conf) + ERROR("There is no option \"%s\" in \"%s\".", + opt_tag, conf_name); + load_gsub(opt_conf, gsub_list, sfont); + } + + ht_init_table(&unencoded, hval_free); + + handle_gsub(conf, ttcmap, gsub_list, &unencoded); + if (opt_tag) { + opt_conf = otl_conf_find_opt(conf, opt_tag); + if (!opt_conf) + ERROR("There is no option \"%s\" in \"%s\".", + opt_tag, conf_name); + handle_gsub(opt_conf, ttcmap, gsub_list, &unencoded); + } + if (is_cidfont) { + tounicode_id = -1; + tounicode = NULL; + } else { + 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); + /* FIXME */ + CMap_add_bfchar(tounicode, srange_min, 2, srange_max, 2); + } + } + create_cmaps(cmap, tounicode, &unencoded, GIDToCIDMap); + + ht_clear_table(&unencoded); + RELEASE(conf_name); + } + + cmap_id = CMap_cache_add(cmap); + if (!is_cidfont && tounicode_id < 0) /* New */ + CMap_cache_add(tounicode); + + tt_cmap_release(ttcmap); + if (gsub_list) + otl_gsub_release(gsub_list); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Overwrite CMap \"%s\" by \"%s\" with usecmap\n", + base_name, cmap_name); + } + + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (base_name) + RELEASE(base_name); + if (cmap_name) + RELEASE(cmap_name); + if (tounicode_name) + RELEASE(tounicode_name); + + sfnt_close(sfont); + DPXFCLOSE(fp); + + return cmap_id; +} diff --git a/Build/source/texk/dvipdf-x/src/tt_cmap.h b/Build/source/texk/dvipdf-x/src/tt_cmap.h new file mode 100644 index 00000000000..4f937ad7fbe --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tt_cmap.h @@ -0,0 +1,79 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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" + +extern void otf_cmap_set_verbose (void); + +/* 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, long 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, + int ttc_index, + const char *used_glyphs); +/* CMap ID */ +extern int otf_load_Unicode_CMap (const char *map_name, + int ttc_index, + const char *otl_opts, int wmode); + +#endif /* _TT_CMAP_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/tt_glyf.c b/Build/source/texk/dvipdf-x/src/tt_glyf.c new file mode 100644 index 00000000000..661ed8693ee --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tt_glyf.c @@ -0,0 +1,668 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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, ... + * + */ + +#include "config.h" + +#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 int CDECL +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; + long i; + USHORT *w_stat; /* Estimate most frequently appeared width */ + + ASSERT(g); + + if (sfont == NULL || +#ifdef XETEX + sfont->ft_face == NULL +#else + sfont->stream == NULL +#endif + ) + 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); + 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++) { + long gap, j; + gap = (long) 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); + 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; + long i; + USHORT *w_stat; + + ASSERT(g); + + if (sfont == NULL || +#ifdef XETEX + sfont->ft_face == NULL +#else + sfont->stream == NULL +#endif + ) + 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/dvipdf-x/src/tt_post.c b/Build/source/texk/dvipdf-x/src/tt_post.c new file mode 100644 index 00000000000..46adba1afcf --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tt_post.c @@ -0,0 +1,271 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. +*/ + +#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 (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; + } + } + 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; + post->count = 0; + post->names = NULL; + } else if (post->Version == 0x00025000UL) { + WARN("TrueType 'post' version 2.5 found (deprecated)"); + post->numberOfGlyphs = 0; /* wrong */ + post->glyphNamePtr = NULL; + post->count = 0; + post->names = NULL; + } else if (post->Version == 0x00020000UL) { + if (read_v2_post_names(post, sfont) < 0) { + WARN("Invalid TrueType 'post' table..."); + tt_release_post_table(post); + post = NULL; + } + } else if (post->Version == 0x00030000UL) { + post->numberOfGlyphs = 0; /* wrong */ + post->glyphNamePtr = NULL; + post->count = 0; + post->names = NULL; + } else { + WARN("Unknown 'post' version: %08X", post->Version); + tt_release_post_table(post); + post = NULL; + } + + 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->count; gid++) { + if (post->glyphNamePtr[gid] && + !strcmp(glyphname, post->glyphNamePtr[gid])) { + return gid; + } + } + + return 0; +} + +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/dvipdf-x/src/tt_table.c b/Build/source/texk/dvipdf-x/src/tt_table.c new file mode 100644 index 00000000000..c14573d62b2 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/tt_table.c @@ -0,0 +1,492 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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. +*/ + +#include + +#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 = NULL; + + sfnt_locate_table(sfont, "head"); + + table = NEW(1, struct tt_head_table); + 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 = NULL; + + sfnt_locate_table(sfont, "maxp"); + + table = NEW(1, struct tt_maxp_table); + 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 = NULL; + + sfnt_locate_table(sfont, "hhea"); + + table = NEW(1, struct tt_hhea_table); + 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 = NULL; + + sfnt_locate_table(sfont, "vhea"); + + table = NEW(1, struct tt_vhea_table); + 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); + 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); + table->ulCodePageRange1 = sfnt_get_ulong(sfont); + table->ulCodePageRange2 = sfnt_get_ulong(sfont); + if (table->version == 0x0002) { + 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; +} + +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; + + name_offset = sfnt_locate_table (sfont, "name"); + + if (sfnt_get_ushort(sfont)) + ERROR ("Expecting zero"); + + num_names = sfnt_get_ushort(sfont); + string_offset = sfnt_get_ushort(sfont); + for (i=0;i destlen - 1) { + fprintf(stderr, "\n** Notice: Name string too long. Truncating **\n"); + length = destlen - 1; + } + sfnt_seek_set (sfont, name_offset+string_offset+offset); + sfnt_read(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; + + fprintf(stderr, "\n** Warning: No valid PostScript name available **\n"); + /* + Wrokaround 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/dvipdf-x/src/type0.c b/Build/source/texk/dvipdf-x/src/type0.c new file mode 100644 index 00000000000..0882175708d --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/type0.c @@ -0,0 +1,677 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxfile.h" + +#include "pdfobj.h" +#include "fontmap.h" + +#include "cmap.h" +#include "cid.h" + +#include "type0.h" + + +#define TYPE0FONT_DEBUG_STR "Type0" +#define TYPE0FONT_DEBUG 3 + +static int __verbose = 0; + +static pdf_obj *pdf_read_ToUnicode_file (const char *cmap_name); + +void +Type0Font_set_verbose(void) +{ + __verbose++; +} + +/* + * used_chars: + * + * Single bit is used for each CIDs since used_chars can be reused as a + * stream content of CIDSet by doing so. See, cid.h for add_to_used() and + * is_used(). + */ + +static char * +new_used_chars2(void) +{ + char *used_chars; + + used_chars = NEW(8192, char); + memset(used_chars, 0, 8192); + + return used_chars; +} + +#define FLAG_NONE 0 +#define FLAG_USED_CHARS_SHARED (1 << 0) + +struct Type0Font { + char *fontname; /* BaseFont */ + char *encoding; /* "Identity-H" or "Identity-V" (not ID) */ + char *used_chars; /* Used chars (CIDs) */ + + /* + * Type0 only + */ + CIDFont *descendant; /* Only single descendant is allowed. */ + int flags; + int wmode; + + /* + * PDF Font Resource + */ + pdf_obj *indirect; + pdf_obj *fontdict; + pdf_obj *descriptor; /* MUST BE NULL */ +}; + +static void +Type0Font_init_font_struct (Type0Font *font) +{ + ASSERT(font); + + font->fontname = NULL; + font->fontdict = NULL; + font->indirect = NULL; + font->descriptor = NULL; + font->encoding = NULL; + font->used_chars = NULL; + font->descendant = NULL; + font->wmode = -1; + font->flags = FLAG_NONE; + + return; +} + +static void +Type0Font_clean (Type0Font *font) +{ + if (font) { + if (font->fontdict) + ERROR("%s: Object not flushed.", TYPE0FONT_DEBUG_STR); + if (font->indirect) + ERROR("%s: Object not flushed.", TYPE0FONT_DEBUG_STR); + if (font->descriptor) + ERROR("%s: FontDescriptor unexpected for Type0 font.", TYPE0FONT_DEBUG_STR); + if (!(font->flags & FLAG_USED_CHARS_SHARED) && font->used_chars) + RELEASE(font->used_chars); + if (font->encoding) + RELEASE(font->encoding); + if (font->fontname) + RELEASE(font->fontname); + font->fontdict = NULL; + font->indirect = NULL; + font->descriptor = NULL; + font->used_chars = NULL; + font->encoding = NULL; + font->fontname = NULL; + } +} + +/* PLEASE FIX THIS */ +#include "tt_cmap.h" + +static void +add_ToUnicode (Type0Font *font) +{ + pdf_obj *tounicode; + CIDFont *cidfont; + CIDSysInfo *csi; + char *cmap_name, *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. + */ + + cidfont = font->descendant; + if (!cidfont) { + ERROR("%s: No descendant CID-keyed font.", TYPE0FONT_DEBUG_STR); + return; + } + + 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. + */ + tounicode = pdf_read_ToUnicode_file("Adobe-Identity-UCS2"); + if (!tounicode) { /* This should work */ + tounicode = pdf_new_name("Identity-H"); + } + pdf_add_dict(font->fontdict, pdf_new_name("ToUnicode"), tounicode); + return; + } + + tounicode = NULL; + csi = CIDFont_get_CIDSysInfo(cidfont); + fontname = CIDFont_get_fontname(cidfont); + if (CIDFont_get_embedding(cidfont)) { + fontname += 7; /* FIXME */ + } + + if (!strcmp(csi->registry, "Adobe") && + !strcmp(csi->ordering, "Identity")) { + switch (CIDFont_get_subtype(cidfont)) { + case CIDFONT_TYPE2: + /* PLEASE FIX THIS */ + tounicode = otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), + CIDFont_get_opt_index(cidfont), + Type0Font_get_usedchars(font)); + break; + default: + if (CIDFont_get_flag(cidfont, CIDFONT_FLAG_TYPE1C)) { /* FIXME */ + tounicode = otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), + CIDFont_get_opt_index(cidfont), + Type0Font_get_usedchars(font)); + } else if (CIDFont_get_flag(cidfont, CIDFONT_FLAG_TYPE1)) { /* FIXME */ + /* Font loader will create ToUnicode and set. */ + return; + } else { + cmap_name = NEW(strlen(fontname) + 7, char); + sprintf(cmap_name, "%s-UTF16", fontname); + tounicode = pdf_read_ToUnicode_file(cmap_name); + if (!tounicode) { + sprintf(cmap_name, "%s-UCS2", fontname); + tounicode = pdf_read_ToUnicode_file(cmap_name); + } + RELEASE(cmap_name); + } + break; + } + } else { + cmap_name = NEW(strlen(csi->registry)+strlen(csi->ordering)+8, char); + sprintf(cmap_name, "%s-%s-UTF16", csi->registry, csi->ordering); + tounicode = pdf_read_ToUnicode_file(cmap_name); + if (!tounicode) { + sprintf(cmap_name, "%s-%s-UCS2", csi->registry, csi->ordering); + tounicode = pdf_read_ToUnicode_file(cmap_name); + } + RELEASE(cmap_name); + } + + if (tounicode) { + pdf_add_dict(font->fontdict, + pdf_new_name("ToUnicode"), tounicode); + } else { + WARN("Failed to load ToUnicode CMap for font \"%s\"", fontname); + } + + return; +} + +void +Type0Font_set_ToUnicode (Type0Font *font, pdf_obj *cmap_ref) +{ + ASSERT(font); + + pdf_add_dict(font->fontdict, + pdf_new_name("ToUnicode"), cmap_ref); +} + +static void +Type0Font_dofont (Type0Font *font) +{ + if (!font || !font->indirect) + return; + + if (!pdf_lookup_dict(font->fontdict, "ToUnicode")) { /* FIXME */ + add_ToUnicode(font); + } +} + +static void +Type0Font_flush (Type0Font *font) +{ + if (font) { + if (font->fontdict) + pdf_release_obj(font->fontdict); + font->fontdict = NULL; + if (font->indirect) + pdf_release_obj(font->indirect); + font->indirect = NULL; + if (font->descriptor) + ERROR("%s: FontDescriptor unexpected for Type0 font.", TYPE0FONT_DEBUG_STR); + font->descriptor = NULL; + } +} + +int +Type0Font_get_wmode (Type0Font *font) +{ + ASSERT(font); + + return font->wmode; +} + +#if 0 +char * +Type0Font_get_encoding (Type0Font *font) +{ + ASSERT(font); + + return font->encoding; +} +#endif + +char * +Type0Font_get_usedchars (Type0Font *font) +{ + ASSERT(font); + + return font->used_chars; +} + +pdf_obj * +Type0Font_get_resource (Type0Font *font) +{ + ASSERT(font); + + /* + * This looks somewhat strange. + */ + if (!font->indirect) { + pdf_obj *array; + + array = pdf_new_array(); + pdf_add_array(array, CIDFont_get_resource(font->descendant)); + pdf_add_dict(font->fontdict, pdf_new_name("DescendantFonts"), array); + font->indirect = pdf_ref_obj(font->fontdict); + } + + return pdf_link_obj(font->indirect); +} + +/******************************** CACHE ********************************/ + +#define CHECK_ID(n) do {\ + if ((n) < 0 || (n) >= __cache.count)\ + ERROR("%s: Invalid ID %d", TYPE0FONT_DEBUG_STR, (n));\ +} while (0) + +#define CACHE_ALLOC_SIZE 16u + +static struct font_cache { + int count; + int capacity; + Type0Font *fonts; +} __cache = { + 0, 0, NULL +}; + +void +Type0Font_cache_init (void) +{ + if (__cache.fonts) + ERROR("%s: Already initialized.", TYPE0FONT_DEBUG_STR); + __cache.count = 0; + __cache.capacity = 0; + __cache.fonts = NULL; +} + +Type0Font * +Type0Font_cache_get (int id) +{ + CHECK_ID(id); + + return &__cache.fonts[id]; +} + +int +Type0Font_cache_find (const char *map_name, int cmap_id, fontmap_opt *fmap_opt) +{ + int font_id = -1; + Type0Font *font; + CIDFont *cidfont; + CMap *cmap; + CIDSysInfo *csi; + char *fontname = NULL; + int cid_id = -1, parent_id = -1, wmode = 0; + int pdf_ver; + + pdf_ver = pdf_get_version(); + if (!map_name || cmap_id < 0 || pdf_ver < 2) + return -1; + + /* + * Encoding is Identity-H or Identity-V according as thier WMode value. + * + * We do not use match against the map_name since fonts (TrueType) covers + * characters across multiple character collection (eg, Adobe-Japan1 and + * Adobe-Japan2) must be splited into multiple CID-keyed fonts. + */ + + cmap = CMap_cache_get(cmap_id); + csi = (CMap_is_Identity(cmap)) ? NULL : CMap_get_CIDSysInfo(cmap) ; + + cid_id = CIDFont_cache_find(map_name, csi, fmap_opt); + + if (cid_id < 0) + return -1; + + /* + * The descendant CID-keyed font has already been registerd. + * If CID-keyed font with ID = cid_id is new font, then create new parent + * Type 0 font. Otherwise, there already exists parent Type 0 font and + * then we find him and return his ID. We must check against their WMode. + */ + + cidfont = CIDFont_cache_get(cid_id); + wmode = CMap_get_wmode(cmap); + + /* Does CID-keyed font already have parent ? */ + parent_id = CIDFont_get_parent_id(cidfont, wmode); + if (parent_id >= 0) + return parent_id; /* If so, we don't need new one. */ + + /* + * CIDFont does not have parent or his parent's WMode does not matched with + * wmode. Create new Type0 font. + */ + + if (__cache.count >= __cache.capacity) { + __cache.capacity += CACHE_ALLOC_SIZE; + __cache.fonts = RENEW(__cache.fonts, __cache.capacity, struct Type0Font); + } + font_id = __cache.count; + font = &__cache.fonts[font_id]; + + Type0Font_init_font_struct(font); + + /* + * All CJK double-byte characters are mapped so that resulting + * character codes coincide with CIDs of given character collection. + * So, the Encoding is always Identity-H for horizontal fonts or + * Identity-V for vertical fonts. + */ + if (wmode) { + font->encoding = NEW(strlen("Identity-V")+1, char); + strcpy(font->encoding, "Identity-V"); + } else { + font->encoding = NEW(strlen("Identity-H")+1, char); + strcpy(font->encoding, "Identity-H"); + } + font->wmode = wmode; + + /* + * Now we start font dictionary. + */ + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, pdf_new_name ("Type"), pdf_new_name ("Font")); + pdf_add_dict(font->fontdict, pdf_new_name ("Subtype"), pdf_new_name ("Type0")); + + /* + * Type0 font does not have FontDescriptor because it is not a simple font. + * Instead, DescendantFonts appears here. + * + * Up to PDF version 1.5, Type0 font must have single descendant font which + * is a CID-keyed font. Future PDF spec. will allow multiple desecendant + * fonts. + */ + font->descendant = cidfont; + CIDFont_attach_parent(cidfont, font_id, wmode); + + /* + * PostScript Font name: + * + * Type0 font's fontname is usually descendant CID-keyed font's font name + * appended by -ENCODING. + */ + fontname = CIDFont_get_fontname(cidfont); + + if (__verbose) { + if (CIDFont_get_embedding(cidfont) && strlen(fontname) > 7) + MESG("(CID:%s)", fontname+7); /* skip XXXXXX+ */ + else + MESG("(CID:%s)", fontname); + } + + /* + * The difference between CID-keyed font and TrueType font appears here. + * + * Glyph substitution for vertical writing is done in CMap mapping process + * for CID-keyed fonts. But we must rely on OpenType layout table in the + * case of TrueType fonts. So, we must use different used_chars for each + * horizontal and vertical fonts in that case. + * + * In most PDF file, encoding name is not appended to fontname for Type0 + * fonts having CIDFontType 2 font as their descendant. + */ + + font->used_chars = NULL; + font->flags = FLAG_NONE; + + switch (CIDFont_get_subtype(cidfont)) { + case CIDFONT_TYPE0: + font->fontname = NEW(strlen(fontname)+strlen(font->encoding)+2, char); + sprintf(font->fontname, "%s-%s", fontname, font->encoding); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), pdf_new_name(font->fontname)); + /* + * Need used_chars to write W, W2. + */ + if ((parent_id = CIDFont_get_parent_id(cidfont, wmode ? 0 : 1)) < 0) + font->used_chars = new_used_chars2(); + else { + /* Don't allocate new one. */ + font->used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + font->flags |= FLAG_USED_CHARS_SHARED; + } + break; + case CIDFONT_TYPE2: + /* + * TrueType: + * + * Use different used_chars for H and V. + */ + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), pdf_new_name(fontname)); + font->used_chars = new_used_chars2(); + break; + default: + ERROR("Unrecognized CIDFont Type"); + break; + } + + pdf_add_dict(font->fontdict, + pdf_new_name("Encoding"), pdf_new_name(font->encoding)); + + __cache.count++; + + return font_id; +} + +void +Type0Font_cache_close (void) +{ + int font_id; + + /* + * This need to be fixed. + * + * CIDFont_cache_close() before Type0Font_release because of used_chars. + * ToUnicode support want descendant CIDFont's CSI and fontname. + */ + if (__cache.fonts) { + for (font_id = 0; font_id < __cache.count; font_id++) + Type0Font_dofont(&__cache.fonts[font_id]); + } + CIDFont_cache_close(); + if (__cache.fonts) { + for (font_id = 0; font_id < __cache.count; font_id++) { + Type0Font_flush(&__cache.fonts[font_id]); + Type0Font_clean(&__cache.fonts[font_id]); + } + RELEASE(__cache.fonts); + } + __cache.fonts = NULL; + __cache.count = 0; + __cache.capacity = 0; +} + + +/************************************************************************/ + +int +pdf_font_findfont0 (const char *font_name, int cmap_id, fontmap_opt *fmap_opt) +{ + return Type0Font_cache_find(font_name, cmap_id, fmap_opt); +} + +/******************************** 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> \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; + long 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/dvipdf-x/src/type0.h b/Build/source/texk/dvipdf-x/src/type0.h new file mode 100644 index 00000000000..da22c8085d7 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/type0.h @@ -0,0 +1,56 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 "pdfobj.h" + +#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)))) + +typedef struct Type0Font Type0Font; + +extern void Type0Font_set_verbose (void); + +extern int Type0Font_get_wmode (Type0Font *font); +#if 0 +extern char *Type0Font_get_encoding (Type0Font *font); +#endif +extern char *Type0Font_get_usedchars (Type0Font *font); + +extern pdf_obj *Type0Font_get_resource (Type0Font *font); + +extern void Type0Font_set_ToUnicode (Type0Font *font, pdf_obj *cmap_ref); + +#include "fontmap.h" +extern int pdf_font_findfont0 (const char *font_name, + int cmap_id, fontmap_opt *fmap_opt); + +/******************************** CACHE ********************************/ + +extern void Type0Font_cache_init (void); +extern Type0Font *Type0Font_cache_get (int id); +extern int Type0Font_cache_find (const char *map_name, int cmap_id, fontmap_opt *fmap_opt); +extern void Type0Font_cache_close (void); + +#endif /* _TYPE0_H_ */ diff --git a/Build/source/texk/dvipdf-x/src/type1.c b/Build/source/texk/dvipdf-x/src/type1.c new file mode 100644 index 00000000000..fff0e44cab5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/type1.c @@ -0,0 +1,806 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.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" + +#include "tfm.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) +{ + char *ident; + FILE *fp; + char fontname[PDF_NAME_LEN_MAX+1]; + + ASSERT(font); + + ident = pdf_font_get_ident(font); + + if (is_basefont(ident)) { + pdf_font_set_fontname(font, ident); + pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1); + pdf_font_set_flags (font, + (PDF_FONT_FLAG_NOEMBED|PDF_FONT_FLAG_BASEFONT)); + } else { + fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT); + if (!fp) + return -1; + + 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); + + pdf_font_set_fontname(font, fontname); + pdf_font_set_subtype (font, 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; + long 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 = pdf_font_get_fontname (font); + 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, long num_glyphs) +{ + pdf_obj *fontdict, *descriptor; + pdf_obj *tmp_array; + int code, firstchar, lastchar; + double val; + int i, tfm_id; + char *usedchars; + double scaling; + + fontdict = pdf_font_get_resource (font); + descriptor = pdf_font_get_descriptor(font); + usedchars = pdf_font_get_usedchars (font); + + /* + * 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; + + tmp_array = pdf_new_array(); + for (i = 0; i < 4; i++) { + val = cff_dict_get(cffont->topdict, "FontBBox", i); + pdf_add_array(tmp_array, pdf_new_number(ROUND(val, 1.0))); + } + pdf_add_dict(descriptor, pdf_new_name("FontBBox"), tmp_array); + + tmp_array = pdf_new_array(); + if (num_glyphs <= 1) { /* This must be an error. */ + firstchar = lastchar = 0; + pdf_add_array(tmp_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; + } + } + if (firstchar > lastchar) { + WARN("No glyphs actually used???"); + pdf_release_obj(tmp_array); + return; + } + tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + for (code = firstchar; code <= lastchar; code++) { + if (usedchars[code]) { + double width; + if (tfm_id < 0) /* tfm is not found */ + width = scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])]; + else + width = 1000. * tfm_get_width(tfm_id, code); + pdf_add_array(tmp_array, + pdf_new_number(ROUND(width, 0.1))); + } else { + pdf_add_array(tmp_array, pdf_new_number(0.0)); + } + } + } + + if (pdf_array_length(tmp_array) > 0) { + pdf_add_dict(fontdict, + pdf_new_name("Widths"), pdf_ref_obj(tmp_array)); + } + pdf_release_obj(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; +} + + +static long +write_fontfile (pdf_font *font, cff_font *cffont, long num_glyphs) +{ + pdf_obj *descriptor; + pdf_obj *fontfile, *stream_dict; + cff_index *topdict; + long private_size, stream_data_len, charstring_len; + long 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); + + RELEASE(stream_data_ptr); + + return offset; +} + + +int +pdf_font_load_type1 (pdf_font *font) +{ + pdf_obj *fontdict; + 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; + long offset; + int code, verbose; + + ASSERT(font); + + if (!pdf_font_is_in_use(font)) { + return 0; + } + + verbose = pdf_font_get_verbose(); + + encoding_id = pdf_font_get_encoding (font); + fontdict = pdf_font_get_resource (font); + + pdf_font_get_descriptor(font); + usedchars = pdf_font_get_usedchars (font); + ident = pdf_font_get_ident (font); + fontname = pdf_font_get_fontname (font); + uniqueTag = pdf_font_get_uniqueTag (font); + if (!usedchars || !ident || !fontname) { + ERROR("Type1: Unexpected error."); + } + + 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); + { + int prev, duplicate; + long 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 (verbose > 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 (verbose > 2) { + MESG("/%s", glyph); + } + + } + } + 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; + long 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) { + long 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 (verbose > 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; + } + + for (i = 0; i < num_glyphs; i++) { + if (GIDMap[i] == bchar_gid) + break; + } + if (i == num_glyphs) { + if (verbose > 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; + } + } + 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 (verbose > 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); + + offset = write_fontfile(font, cffont, num_glyphs); + if (verbose > 1) + MESG("[%u glyphs][%ld bytes]", num_glyphs, offset); + + 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); + + /* + * Maybe writing Charset is recommended for subsetted font. + */ + + return 0; +} diff --git a/Build/source/texk/dvipdf-x/src/type1c.c b/Build/source/texk/dvipdf-x/src/type1c.c new file mode 100644 index 00000000000..1c61ce24eaa --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/type1c.c @@ -0,0 +1,740 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.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" + +#include "tfm.h" + +int +pdf_font_open_type1c (pdf_font *font) +{ + char *ident, *fontname; + FILE *fp = NULL; + sfnt *sfont; + cff_font *cffont; + pdf_obj *descriptor, *tmp; + unsigned long offset = 0; + int encoding_id, embedding; + + ASSERT(font); + + ident = pdf_font_get_ident (font); + encoding_id = pdf_font_get_encoding(font); + + fp = DPXFOPEN(ident, DPX_RES_TYPE_OTFONT); + if (!fp) + return -1; + + sfont = sfnt_open(fp); + if (!sfont || + sfont->type != SFNT_TYPE_POSTSCRIPT || + sfnt_read_table_directory(sfont, 0) < 0) { + ERROR("Not a CFF/OpenType font?"); + } + + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset < 1) { + ERROR("No \"CFF \" table found. Not a CFF/OpenType font?"); + } + + cffont = cff_open(sfont->stream, offset, 0); + if (!cffont) { + ERROR("Could not read CFF font data"); + } + + if (cffont->flag & FONTTYPE_CIDFONT) { + cff_close (cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + } + + fontname = cff_get_name(cffont); + if (!fontname) { + ERROR("No valid FontName found in CFF/OpenType font."); + } + pdf_font_set_fontname(font, fontname); + RELEASE(fontname); + + cff_close(cffont); + + /* + * 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."); + } + pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1C); + + embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; + 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); + 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 */ + pdf_font_set_flags(font, PDF_FONT_FLAG_NOEMBED); + } + + 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, tfm_id; + char *usedchars; + pdf_obj *tmp_array; + double scaling; + + fontdict = pdf_font_get_resource(font); + usedchars = pdf_font_get_usedchars(font); + + /* 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; + + tmp_array = pdf_new_array(); + if (num_glyphs <= 1) { + /* This should be error. */ + firstchar = lastchar = 0; + pdf_add_array(tmp_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; + } + } + if (firstchar > lastchar) { + ERROR("No glyphs used at all!"); + pdf_release_obj(tmp_array); + return; + } + tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + for (code = firstchar; code <= lastchar; code++) { + if (usedchars[code]) { + double width; + if (tfm_id < 0) /* tfm is not found */ + width = scaling * widths[code]; + else + width = 1000. * tfm_get_width(tfm_id, code); + pdf_add_array(tmp_array, + pdf_new_number(ROUND(width, 0.1))); + } else { + pdf_add_array(tmp_array, pdf_new_number(0.0)); + } + } + } + + if (pdf_array_length(tmp_array) > 0) { + pdf_add_dict(fontdict, + pdf_new_name("Widths"), pdf_ref_obj(tmp_array)); + } + pdf_release_obj(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; +} + +int +pdf_font_load_type1c (pdf_font *font) +{ + pdf_obj *fontdict, *descriptor; + 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; + long topdict_offset, private_size; + long charstring_len, max_len; + long size, offset = 0; + long 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]; + int verbose; + + ASSERT(font); + + verbose = pdf_font_get_verbose(); + + if (!pdf_font_is_in_use(font)) { + return 0; + } + + if (pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) { + ERROR("Only embedded font supported for CFF/OpenType font."); + } + + usedchars = pdf_font_get_usedchars (font); + fontname = pdf_font_get_fontname (font); + ident = pdf_font_get_ident (font); + uniqueTag = pdf_font_get_uniqueTag (font); + if (!usedchars || + !fontname || !ident) { + ERROR("Unexpected error...."); + } + + fontdict = pdf_font_get_resource (font); + descriptor = pdf_font_get_descriptor(font); + encoding_id = pdf_font_get_encoding (font); + + 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 ?"); + } + + 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 = (long) 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 = ftell(cffont->stream); + 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 (verbose > 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; + seek_absolute(cffont->stream, offset + cs_idx->offset[0] - 1); + fread(data, 1, size, cffont->stream); + 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; + 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; + } + if (verbose > 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; + seek_absolute(cffont->stream, offset + cs_idx->offset[gid] - 1); + fread(data, sizeof(char), size, cffont->stream); + 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 (verbose > 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 (verbose > 1) { + MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, offset); + } + + /* + * CharSet might be recommended for subsetted font, but it is meaningful + * only for Type 1 font... + */ + + /* + * 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/dvipdf-x/src/vf.c b/Build/source/texk/dvipdf-x/src/vf.c new file mode 100644 index 00000000000..1d7f9e753f4 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/vf.c @@ -0,0 +1,1058 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "numbers.h" +#include "error.h" +#include "mem.h" + +#include "dpxfile.h" +/* pdfdev... */ +#include "pdfdev.h" + +#include "tfm.h" +#include "dvi.h" +#include "vf.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))) + +static unsigned char verbose = 0; + +void vf_set_verbose(void) +{ + if (verbose < 255) verbose++; +} + +struct font_def { + signed long font_id /* id used internally in vf file */; + unsigned long 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; + unsigned long design_size; /* A fixword-pts quantity */ + int num_dev_fonts, max_dev_fonts; + struct font_def *dev_fonts; + unsigned char **ch_pkt; + unsigned long *pkt_len; + unsigned num_chars; +}; + +struct vf *vf_fonts = NULL; +int num_vf_fonts = 0, max_vf_fonts = 0; + +static int read_header(FILE *vf_file, int thisfont) +{ + int i, result = 1, ch; + + /* Check for usual signature */ + if ((ch = get_unsigned_byte (vf_file)) == PRE && + (ch = get_unsigned_byte (vf_file)) == VF_ID) { + + /* If here, assume it's a legitimate vf file */ + ch = get_unsigned_byte (vf_file); + + /* skip comment */ + for (i=0; i max_vf_fonts) { + vf_fonts = RENEW (vf_fonts, size, struct vf); + for (i=max_vf_fonts; i (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, unsigned long); + for (i=a_vf->num_chars; ich_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, unsigned long pkt_len, + unsigned ch) +{ + unsigned char *pkt; +#ifdef DEBUG + fprintf (stderr, "read_a_char_def: len=%ld, ch=%d\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, signed long font_id, int thisfont) +{ + struct font_def *dev_font; + int dir_length, name_length; +#ifdef DEBUG + fprintf (stderr, "read_a_font_def: font_id = %ld\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_unsigned_quad (vf_file); + dev_font -> design_size = get_unsigned_quad (vf_file); + 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; + unsigned long font_id; + while (!eof) { + code = get_unsigned_byte (vf_file); + switch (code) { + case FNT_DEF1: + font_id = get_unsigned_byte (vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + case FNT_DEF2: + font_id = get_unsigned_pair (vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + case FNT_DEF3: + font_id = get_unsigned_triple(vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + case FNT_DEF4: + font_id = get_signed_quad(vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + default: + if (code < 242) { + long ch; + /* For a short packet, code is the pkt_len */ + ch = get_unsigned_byte (vf_file); + /* Skip over TFM width since we already know it */ + get_unsigned_triple (vf_file); + read_a_char_def (vf_file, thisfont, code, ch); + break; + } + if (code == 242) { + unsigned long pkt_len, ch; + pkt_len = get_unsigned_quad(vf_file); + ch = get_unsigned_quad (vf_file); + /* Skip over TFM width since we already know it */ + get_unsigned_quad (vf_file); + if (ch < 0x1000000L) + read_a_char_def (vf_file, thisfont, pkt_len, ch); + else { + fprintf (stderr, "char=%ld\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 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 (verbose) + fprintf (stderr, ")"); + MFCLOSE (vf_file); + } + if (full_vf_file_name) + RELEASE(full_vf_file_name); + } + return thisfont; +} + +#define next_byte() (*((*start)++)) +static UNSIGNED_BYTE unsigned_byte (unsigned char **start, unsigned char *end) +{ + UNSIGNED_BYTE byte = 0; + if (*start < end) + byte = next_byte(); + else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return byte; +} + +static SIGNED_BYTE signed_byte (unsigned char **start, unsigned char *end) +{ + int byte = 0; + if (*start < end) { + byte = next_byte(); + if (byte >= 0x80) + byte -= 0x100; + } + else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_BYTE) byte; +} + +static UNSIGNED_PAIR unsigned_pair (unsigned char **start, unsigned char *end) +{ + int i; + UNSIGNED_BYTE byte; + UNSIGNED_PAIR pair = 0; + if (end-*start > 1) { + for (i=0; i<2; i++) { + byte = next_byte(); + pair = pair*0x100u + byte; + } + } + else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return pair; +} + +static SIGNED_PAIR signed_pair (unsigned char **start, unsigned char *end) +{ + int i; + long pair = 0; + if (end - *start > 1) { + for (i=0; i<2; i++) { + pair = pair*0x100 + next_byte(); + } + if (pair >= 0x8000) { + pair -= 0x10000l; + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_PAIR) pair; +} + +static UNSIGNED_TRIPLE unsigned_triple(unsigned char **start, unsigned + char *end) +{ + int i; + long triple = 0; + if (end-*start > 2) { + for (i=0; i<3; i++) { + triple = triple*0x100u + next_byte(); + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (UNSIGNED_TRIPLE) triple; +} + +static SIGNED_TRIPLE signed_triple(unsigned char **start, unsigned char *end) +{ + int i; + long triple = 0; + if (end-*start > 2) { + for (i=0; i<3; i++) { + triple = triple*0x100 + next_byte(); + } + if (triple >= 0x800000l) + triple -= 0x1000000l; + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_TRIPLE) triple; +} + +static SIGNED_QUAD signed_quad(unsigned char **start, unsigned char *end) +{ + int byte, i; + long quad = 0; + /* Check sign on first byte before reading others */ + if (end-*start > 3) { + byte = next_byte(); + quad = byte; + if (quad >= 0x80) + quad = byte - 0x100; + for (i=0; i<3; i++) { + quad = quad*0x100 + next_byte(); + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_QUAD) quad; +} + +static UNSIGNED_QUAD unsigned_quad(unsigned char **start, unsigned char *end) +{ + int i; + unsigned long quad = 0; + if (end-*start > 3) { + for (i=0; i<4; i++) { + quad = quad*0x100u + next_byte(); + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (UNSIGNED_QUAD) quad; +} + +static void vf_set (SIGNED_QUAD ch) +{ + /* Defer to the dvi_set() defined in dvi.c */ + dvi_set (ch); + return; +} + +static void vf_set1(unsigned char **start, unsigned char *end) +{ + vf_set (unsigned_byte(start, end)); + return; +} + +static void vf_set2(unsigned char **start, unsigned char *end) +{ + vf_set (unsigned_pair(start, end)); + return; +} + +static void vf_set3(unsigned char **start, unsigned char *end) +{ + vf_set (unsigned_triple(start, end)); + return; +} + +static void vf_putrule(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + SIGNED_QUAD width, height; + height = signed_quad (start, end); + width = signed_quad (start, end); + if (width > 0 && height > 0) { + dvi_rule (sqxfw(ptsize,width), sqxfw(ptsize, height)); + } + return; +} + +static void vf_setrule(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + SIGNED_QUAD width, height, s_width; + height = signed_quad (start, end); + width = signed_quad (start, end); + s_width = sqxfw(ptsize, width); + if (width > 0 && height > 0) { + dvi_rule (s_width, sqxfw(ptsize, height)); + } + dvi_right (s_width); + return; +} + +static void vf_put1(unsigned char **start, unsigned char *end) +{ + dvi_put (unsigned_byte(start, end)); + return; +} + +static void vf_put2(unsigned char **start, unsigned char *end) +{ + dvi_put (unsigned_pair(start, end)); + return; +} + +static void vf_put3(unsigned char **start, unsigned char *end) +{ + dvi_put (unsigned_triple(start, end)); + return; +} + +static void vf_push(void) +{ + dvi_push(); + return; +} + +static void vf_pop(void) +{ + dvi_pop(); + return; +} + +static void vf_right (SIGNED_QUAD x, spt_t ptsize) +{ + dvi_right ((SIGNED_QUAD) (sqxfw(ptsize, x))); + return; +} + + +static void vf_right1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_byte (start, end), ptsize); + return; +} + +static void vf_right2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_pair (start, end), ptsize); + return; +} + +static void vf_right3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_triple (start, end), ptsize); + return; +} + +static void vf_right4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_quad (start, end), ptsize); + return; +} + +static void vf_w0(void) +{ + dvi_w0(); + return; +} + +static void vf_w (SIGNED_QUAD w, spt_t ptsize) +{ + dvi_w ((SIGNED_QUAD) (sqxfw(ptsize, w))); + return; +} + +static void vf_w1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_byte(start, end), ptsize); + return; +} + +static void vf_w2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_pair(start, end), ptsize); + return; +} + +static void vf_w3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_triple(start, end), ptsize); + return; +} + +static void vf_w4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_quad(start, end), ptsize); + return; +} + +static void vf_x0(void) +{ + dvi_x0(); + return; +} + +static void vf_x (SIGNED_QUAD x, spt_t ptsize) +{ + dvi_x ((SIGNED_QUAD) (sqxfw(ptsize, x))); + return; +} + +static void vf_x1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_byte(start, end), ptsize); + return; +} + +static void vf_x2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_pair(start, end), ptsize); + return; +} + +static void vf_x3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_triple(start, end), ptsize); + return; +} + +static void vf_x4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_quad(start, end), ptsize); + return; +} + +static void vf_down (SIGNED_QUAD y, spt_t ptsize) +{ + dvi_down ((SIGNED_QUAD) (sqxfw(ptsize, y))); + return; +} + +static void vf_down1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_byte(start, end), ptsize); + return; +} + +static void vf_down2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_pair(start, end), ptsize); + return; +} + +static void vf_down3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_triple(start, end), ptsize); + return; +} + +static void vf_down4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_quad(start, end), ptsize); + return; +} + +static void vf_y0(void) +{ + dvi_y0(); + return; +} + +static void vf_y (SIGNED_QUAD y, spt_t ptsize) +{ + dvi_y ((SIGNED_QUAD) (sqxfw(ptsize, y))); + return; +} + + +static void vf_y1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_byte(start, end), ptsize); + return; +} + +static void vf_y2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_pair(start, end), ptsize); + return; +} + +static void vf_y3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_triple(start, end), ptsize); + return; +} + +static void vf_y4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_quad(start, end), ptsize); + return; +} + +static void vf_z0(void) +{ + dvi_z0(); + return; +} + +static void vf_z (SIGNED_QUAD z, spt_t ptsize) +{ + dvi_z ((SIGNED_QUAD) (sqxfw(ptsize, z))); + return; +} + +static void vf_z1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_byte(start, end), ptsize); + return; +} + +static void vf_z2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_pair(start, end), ptsize); + return; +} + +static void vf_z3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_triple(start, end), ptsize); + return; +} + +static void vf_z4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_quad(start, end), ptsize); + return; +} + +static void vf_fnt (SIGNED_QUAD font_id, unsigned long vf_font) +{ + int i; + for (i=0; i 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])) { + fprintf (stderr, "\nchar=0x%lx(%ld)\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: + vf_set1(&start, end); + break; + case SET2: + vf_set2(&start, end); + break; + case SET3: + vf_set3(&start, end); + 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: + vf_put1(&start, end); + break; + case PUT2: + vf_put2(&start, end); + break; + case PUT3: + vf_put3(&start, end); + 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: + vf_push(); + break; + case POP: + vf_pop(); + break; + case RIGHT1: + vf_right1(&start, end, ptsize); + break; + case RIGHT2: + vf_right2(&start, end, ptsize); + break; + case RIGHT3: + vf_right3(&start, end, ptsize); + break; + case RIGHT4: + vf_right4(&start, end, ptsize); + break; + case W0: + vf_w0(); + break; + case W1: + vf_w1(&start, end, ptsize); + break; + case W2: + vf_w2(&start, end, ptsize); + break; + case W3: + vf_w3(&start, end, ptsize); + break; + case W4: + vf_w4(&start, end, ptsize); + break; + case X0: + vf_x0(); + break; + case X1: + vf_x1(&start, end, ptsize); + break; + case X2: + vf_x2(&start, end, ptsize); + break; + case X3: + vf_x3(&start, end, ptsize); + break; + case X4: + vf_x4(&start, end, ptsize); + break; + case DOWN1: + vf_down1(&start, end, ptsize); + break; + case DOWN2: + vf_down2(&start, end, ptsize); + break; + case DOWN3: + vf_down3(&start, end, ptsize); + break; + case DOWN4: + vf_down4(&start, end, ptsize); + break; + case Y0: + vf_y0(); + break; + case Y1: + vf_y1(&start, end, ptsize); + break; + case Y2: + vf_y2(&start, end, ptsize); + break; + case Y3: + vf_y3(&start, end, ptsize); + break; + case Y4: + vf_y4(&start, end, ptsize); + break; + case Z0: + vf_z0(); + break; + case Z1: + vf_z1(&start, end, ptsize); + break; + case Z2: + vf_z2(&start, end, ptsize); + break; + case Z3: + vf_z3(&start, end, ptsize); + break; + case Z4: + vf_z4(&start, end, ptsize); + break; + case FNT1: + vf_fnt1(&start, end, vf_font); + break; + case FNT2: + vf_fnt2(&start, end, vf_font); + break; + case FNT3: + vf_fnt3(&start, end, vf_font); + break; + case FNT4: + vf_fnt4(&start, end, vf_font); + break; + case XXX1: + vf_xxx1(&start, end); + break; + case XXX2: + vf_xxx2(&start, end); + break; + case XXX3: + vf_xxx3(&start, end); + break; + case XXX4: + vf_xxx4(&start, end); + break; + case PTEXDIR: + vf_dir(&start, end); + break; + default: + if (opcode <= SET_CHAR_127) { + vf_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) +{ + unsigned long i; + int j; + struct font_def *one_font; + for (i=0; i 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; +} diff --git a/Build/source/texk/dvipdf-x/src/xbb.c b/Build/source/texk/dvipdf-x/src/xbb.c new file mode 100644 index 00000000000..c5fd0f22094 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/xbb.c @@ -0,0 +1,343 @@ +/* + + This is extractbb, a bounding box extraction program. + + Copyright (C) 2009-2012 by Jin-Hwan Cho and Matthias Franz + + 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 +*/ + +#include +#include +#include + +#include "numbers.h" +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "pdfobj.h" +#include "pdfdev.h" +#include "pdfdoc.h" +#include "pdfparse.h" + +#include "config.h" + +#include "jpegimage.h" +#include "pngimage.h" + +#include "dvipdfmx.h" +#include "xbb.h" + +#define XBB_PROGRAM "extractbb" +#define XBB_VERSION VERSION + +static int really_quiet = 0; + +static void show_version(void) +{ + if (really_quiet) return; + + fprintf(stdout, "%s, version %s, Copyright (C) 2009 by Jin-Hwan Cho and Matthias Franz\n", XBB_PROGRAM, XBB_VERSION); + fprintf(stdout, "A bounding box extraction utility from PDF, PNG, and JPEG.\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) +{ + if (really_quiet) return; + + fprintf(stdout, "\nUsage: %s [-v|-q] [-O] [-m|-x] [files]\n", XBB_PROGRAM); + fprintf(stdout, "\t-v\tBe verbose\n"); + fprintf(stdout, "\t-q\tBe quiet\n"); + fprintf(stdout, "\t-O\tWrite output to stdout\n"); + if(compat_mode) { + fprintf(stdout, "\t-m\tOutput .bb file used in DVIPDFM (default)\n"); + fprintf(stdout, "\t-x\tOutput .xbb file used in DVIPDFMx\n"); + } else { + fprintf(stdout, "\t-m\tOutput .bb file used in DVIPDFM\n"); + fprintf(stdout, "\t-x\tOutput .xbb file used in DVIPDFMx (default)\n"); + } +} + +static void usage(void) +{ + if (really_quiet) return; + + fprintf(stdout, "\nTry \"%s --help\" for more information.\n", XBB_PROGRAM); + exit(1); +} + +static char verbose = 0; + +static void do_time(FILE *file) +{ + time_t current_time; + struct tm *bd_time; + + time(¤t_time); + bd_time = localtime(¤t_time); + fprintf(file, "%%%%CreationDate: %s\n", asctime(bd_time)); +} + +const char *extensions[] = { + ".jpeg", ".JPEG", ".jpg", ".JPG", ".pdf", ".PDF", ".png", ".PNG" +}; + +static int xbb_to_file = 1; + +static char *make_xbb_filename(const char *name) +{ + int i; + char *result; + + 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)+5, char); /* 5 = ".xbb" + trailing 0 */ + strcpy(result, name); + } else { /* Remove extension */ + result = NEW(strlen(name)-strlen(extensions[i])+5, char); /* 5 = ".xbb" + trailing 0 */ + strncpy(result, name, strlen(name)-strlen(extensions[i])); + result[strlen(name)-strlen(extensions[i])] = 0; + } + strcat(result, (!compat_mode ? ".xbb" : ".bb")); + return result; +} + +static void write_xbb(char *fname, + double bbllx_f, double bblly_f, + double bburx_f, double bbury_f, + int pdf_version, long pagecount) +{ + char *outname = NULL; + FILE *fp; + + long bbllx = ROUND(bbllx_f, 1.0), bblly = ROUND(bblly_f, 1.0); + long bburx = ROUND(bburx_f, 1.0), bbury = ROUND(bbury_f, 1.0); + + if (xbb_to_file) { + outname = make_xbb_filename(fname); + if ((fp = MFOPEN(outname, FOPEN_W_MODE)) == NULL) { + ERROR("Unable to open output file: %s\n", outname); + } + } else { + fp = stdout; +#ifdef WIN32 + setmode(fileno(fp), _O_BINARY); +#endif + } + + if (verbose) { + 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: %s %s\n", XBB_PROGRAM, XBB_VERSION); + fprintf(fp, "%%%%BoundingBox: %ld %ld %ld %ld\n", bbllx, bblly, bburx, bbury); + + if (!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: 1.%d\n", pdf_version); + fprintf(fp, "%%%%Pages: %ld\n", pagecount); + } + } + + do_time(fp); + + if (xbb_to_file) { + RELEASE(outname); + MFCLOSE(fp); + } +} + +static void do_jpeg (FILE *fp, char *filename) +{ + long 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; +} + +#ifdef HAVE_LIBPNG + +static void do_png (FILE *fp, char *filename) +{ + long 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; + long page_no = 1; + long count; + pdf_rect bbox; + + pf = pdf_open(filename, fp); + if (!pf) { + WARN("%s does not look like a PDF file...\n", filename); + return; + } + + page = pdf_doc_get_page(pf, page_no, &count, &bbox, NULL); + + pdf_close(pf); + + if (!page) + return; + + pdf_release_obj(page); + write_xbb(filename, bbox.llx, bbox.lly, bbox.urx, bbox.ury, + pdf_file_get_version(pf), count); +} + +int extractbb (int argc, char *argv[]) +{ + pdf_files_init(); + + pdf_set_version(5); + + kpse_set_program_name(argv[0], NULL); + + argc -= 1; argv += 1; + if (argc == 0) + usage(); + + while (argc > 0 && *argv[0] == '-') { + char *flag = argv[0] + 1; + switch (*flag) { + case '-': + if (++flag) { + if (!strcmp(flag, "help")) { + show_version(); + show_usage(); + exit(0); + } else if (!strcmp(flag, "version")) { + show_version(); + exit(0); + } + } + if (!really_quiet) + fprintf(stderr, "Unknown option in \"--%s\"", flag); + usage(); + break; + case 'O': + xbb_to_file = 0; + argc -= 1; argv += 1; + break; + case 'm': + compat_mode = 1; + argc -= 1; argv += 1; + break; + case 'x': + compat_mode = 0; + argc -= 1; argv += 1; + break; + case 'v': + verbose = 1; + argc -= 1; argv += 1; + break; + case 'h': + usage(); + argc -= 1; argv += 1; + break; + case 'q': + really_quiet = 1; + shut_up(); + argc -= 1; argv += 1; + break; + case 'b': + if (compat_mode) { + /* ignore obsolete "binary mode" option */ + argc -= 1; argv += 1; + break; + } + /* else fall through */ + default: + if (!really_quiet) + fprintf(stderr, "Unknown option in \"-%s\"", flag); + usage(); + } + } + + for (; argc > 0; argc--, argv++) { + FILE *infile = NULL; + char *kpse_file_name; + if (!(kpse_file_name = kpse_find_pict(argv[0])) || + (infile = MFOPEN(kpse_file_name, FOPEN_RBIN_MODE)) == NULL) { + WARN("Can't find file (%s)...skipping\n", argv[0]); + goto cont; + } + if (check_for_jpeg(infile)) { + do_jpeg(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[0]); + cont: + if (kpse_file_name) + RELEASE(kpse_file_name); + if (infile) + MFCLOSE(infile); + } + + pdf_files_close(); + + return 0; +} diff --git a/Build/source/texk/dvipdf-x/src/xbb.h b/Build/source/texk/dvipdf-x/src/xbb.h new file mode 100644 index 00000000000..c4390e1cb09 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/xbb.h @@ -0,0 +1,31 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, 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 _XBB_H_ +#define _XBB_H_ + +#define EBB_OUTPUT 0 +#define XBB_OUTPUT 1 + +extern int extractbb(int argc, char *argv[]); + +#endif /* _XBB_H_ */ diff --git a/Build/source/texk/dvipdf-x/subfont.c b/Build/source/texk/dvipdf-x/subfont.c new file mode 100644 index 00000000000..001dec358d3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/subfont.c @@ -0,0 +1,657 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. +*/ + +#include + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxfile.h" + +#include "subfont.h" + +static int verbose = 0; +void +subfont_set_verbose (void) +{ + verbose++; +} + +/* 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 + * 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; + long c, v1 = 0, v2 = 0; + int curpos = 0; + int error = 0; + +#define IS_TOKSEP(c) ((c) == '\0' || isspace((c))) + for ( ; *p && isspace(*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(*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 (verbose > 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(*p); p++); + if (*p == 0) + continue; /* empty */ + + /* Saw non-wsp here */ + for (n = 0, q = p; *p && !isspace(*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 (verbose > 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 (verbose > 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 (verbose > 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(*p); p++); + if (*p == 0) + continue; /* empty line */ + + /* q = parse_ident(&p, p + strlen(p)); */ + for (q = p; *p && !isspace(*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 (verbose > 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 +#else +typedef int iconv_t; +#endif +#include + +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, " \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, " ", i); + else { + fprintf(stdout, " > 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 (verbose) { + 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, " \n"); + return; +} + +#define subfontDefinition_DTD "\ +\n\ +\n\ +\n\ +\n\ +\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, "\n"); + fprintf(stdout, "\n", + subfontDefinition_DTD); + fprintf(stdout, "\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, "\n"); + +#ifdef HAVE_ICONV + if (cd != (iconv_t) -1) + iconv_close(cd); +#endif + + return 0; +} + +#endif /* DPXTEST */ diff --git a/Build/source/texk/dvipdf-x/subfont.h b/Build/source/texk/dvipdf-x/subfont.h new file mode 100644 index 00000000000..15c448135c9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/subfont.h @@ -0,0 +1,35 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 subfont_set_verbose (void); + +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/dvipdf-x/system.h b/Build/source/texk/dvipdf-x/system.h new file mode 100644 index 00000000000..b3a4d16b217 --- /dev/null +++ b/Build/source/texk/dvipdf-x/system.h @@ -0,0 +1,53 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 +#include "gnu-miktex.h" +#include +#else +#include +#include +#endif + +#ifdef WIN32 +# undef ERROR +# undef NO_ERROR +# undef RGB +# undef CMYK +# undef SETLINECAP +# undef SETLINEJOIN +# undef SETMITERLIMIT +# pragma warning(disable : 4101 4018) +#else +# ifndef __cdecl +# define __cdecl +# endif +# define CDECL +#endif /* WIN32 */ + +#endif /* _SYSTEM_H_ */ diff --git a/Build/source/texk/dvipdf-x/t1_char.c b/Build/source/texk/dvipdf-x/t1_char.c new file mode 100644 index 00000000000..7b6788870bd --- /dev/null +++ b/Build/source/texk/dvipdf-x/t1_char.c @@ -0,0 +1,1590 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#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 int CDECL +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 *endptr) +{ + 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 (t1_chardesc *cd) +{ + 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 (t1_chardesc *cd) +{ + /* 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(cd) ; break; + case 2: do_othersubr2(cd) ; break; + case 3: do_othersubr3(cd) ; break; + case 12: do_othersubr12(cd); 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 (__verbose > 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; + long ivalue; + value = argv[i]; + /* Nearest integer value */ + ivalue = (long) 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 = (long) floor(value); /* mantissa */ + *(*dest)++ = (ivalue >> 8) & 0xff; + *(*dest)++ = ivalue & 0xff; + ivalue = (long)((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) +{ + long 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) +{ + long 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; + long 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, 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) { + if (!(*data == endptr - 1 && **data == cs_return)) + WARN("Garbage after endchar. (%ld bytes)", (long) (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, long 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 long +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) { + 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) { + 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 (long) (dst - save); +} + +long +t1char_convert_charstring (card8 *dst, long dstlen, + card8 *src, long srclen, cff_index *subrs, + double default_width, double nominal_width, + t1_ginfo *ginfo) +{ + long 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/dvipdf-x/t1_char.h b/Build/source/texk/dvipdf-x/t1_char.h new file mode 100644 index 00000000000..5240a3a39cc --- /dev/null +++ b/Build/source/texk/dvipdf-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, long srclen, + cff_index *subrs, t1_ginfo *ginfo); +extern long t1char_convert_charstring (card8 *dst, long dstlen, + card8 *src, long srclen, + cff_index *subrs, + double default_width, double nominal_width, + t1_ginfo *ginfo); + +#endif /* _T1_CSTR_H_ */ diff --git a/Build/source/texk/dvipdf-x/t1_load.c b/Build/source/texk/dvipdf-x/t1_load.c new file mode 100644 index 00000000000..c3dc14297bc --- /dev/null +++ b/Build/source/texk/dvipdf-x/t1_load.c @@ -0,0 +1,1226 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#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, + long skip, long 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) ((t) && PST_NAMETYPE((t)) && !strncmp(pst_data_ptr((t)),(n),strlen((n)))) +#define MATCH_OP(t,n) ((t) && PST_UNKNOWNTYPE((t)) && !strncmp(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" +}; + +static int +parse_encoding (char **enc_vec, unsigned char **start, unsigned char *end, int mode) +{ + 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); + + tok = pst_get_token(start, end); + 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; + long i, count, offset, max_size; + long *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, long); + lengths = NEW(count, long); + memset(offsets, 0, sizeof(long)*count); + memset(lengths, 0, sizeof(long)*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;) { + long 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; + long i, count, have_notdef; + long 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)); + +#ifdef XETEX + font->ft_to_gid = NEW(count, unsigned short); +#endif + + offset = 0; + have_notdef = 0; /* .notdef must be at gid = 0 in CFF */ + + seek_operator(start, end, "begin"); + for (i = 0; i < count; i++) { + char *glyph_name; + long 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 (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; + } +#ifdef XETEX + font->ft_to_gid[i] = gid; +#endif + + 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) { + long 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 long +parse_part1 (cff_font *font, char **enc_vec, + unsigned char **start, unsigned char *end, int mode) +{ + 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, mode) < 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; + } + + 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, long *length) +{ + unsigned char *buffer; + long 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; + } + { + long 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; + long 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) +{ +#ifdef XETEX + cff->sfont = NULL; +#else + cff->stream = NULL; +#endif + 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); + +#ifdef XETEX + cff->ft_to_gid = NULL; +#endif +} + +cff_font * +t1_load_font (char **enc_vec, int mode, FILE *fp) +{ + long 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, mode) < 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/dvipdf-x/t1_load.h b/Build/source/texk/dvipdf-x/t1_load.h new file mode 100644 index 00000000000..95683612fbf --- /dev/null +++ b/Build/source/texk/dvipdf-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/dvipdf-x/tests/cmr10.pfb b/Build/source/texk/dvipdf-x/tests/cmr10.pfb new file mode 100644 index 00000000000..337b4b58c45 Binary files /dev/null and b/Build/source/texk/dvipdf-x/tests/cmr10.pfb differ diff --git a/Build/source/texk/dvipdf-x/tests/cmr10.tfm b/Build/source/texk/dvipdf-x/tests/cmr10.tfm new file mode 100644 index 00000000000..6594c9c4a7f Binary files /dev/null and b/Build/source/texk/dvipdf-x/tests/cmr10.tfm differ diff --git a/Build/source/texk/dvipdf-x/tests/dvipdfmx.cfg b/Build/source/texk/dvipdf-x/tests/dvipdfmx.cfg new file mode 100644 index 00000000000..c3a2843b66a --- /dev/null +++ b/Build/source/texk/dvipdf-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 diff --git a/Build/source/texk/dvipdf-x/tests/grahn.dvi b/Build/source/texk/dvipdf-x/tests/grahn.dvi new file mode 100644 index 00000000000..39cbb802741 Binary files /dev/null and b/Build/source/texk/dvipdf-x/tests/grahn.dvi differ diff --git a/Build/source/texk/dvipdf-x/tests/grahn.tex b/Build/source/texk/dvipdf-x/tests/grahn.tex new file mode 100644 index 00000000000..eda2974a6fb --- /dev/null +++ b/Build/source/texk/dvipdf-x/tests/grahn.tex @@ -0,0 +1,8 @@ +% +\special{pdf:obj @tug <>} + +\special{pdf:bann <>}% +TUG on the web +\special{pdf:eann}% + +\bye diff --git a/Build/source/texk/dvipdf-x/tests/image.dvi b/Build/source/texk/dvipdf-x/tests/image.dvi new file mode 100644 index 00000000000..5fa697608d1 Binary files /dev/null and b/Build/source/texk/dvipdf-x/tests/image.dvi differ diff --git a/Build/source/texk/dvipdf-x/tests/image.jpeg b/Build/source/texk/dvipdf-x/tests/image.jpeg new file mode 100644 index 00000000000..5312aab5fc4 Binary files /dev/null and b/Build/source/texk/dvipdf-x/tests/image.jpeg differ diff --git a/Build/source/texk/dvipdf-x/tests/image.pdf b/Build/source/texk/dvipdf-x/tests/image.pdf new file mode 100644 index 00000000000..12c4576b56f Binary files /dev/null and b/Build/source/texk/dvipdf-x/tests/image.pdf differ diff --git a/Build/source/texk/dvipdf-x/tests/image.png b/Build/source/texk/dvipdf-x/tests/image.png new file mode 100644 index 00000000000..9b225237c0f Binary files /dev/null and b/Build/source/texk/dvipdf-x/tests/image.png differ diff --git a/Build/source/texk/dvipdf-x/tests/image.tex b/Build/source/texk/dvipdf-x/tests/image.tex new file mode 100644 index 00000000000..e0514f46b2b --- /dev/null +++ b/Build/source/texk/dvipdf-x/tests/image.tex @@ -0,0 +1,23 @@ +% +\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 @pngpic (image.png)} +\special{pdf:uxobj @pngpic} +} +\advance\count0 by 1 +% +\shipout\vbox{ +\vbox to5cm{} +\special{pdf:image @pdfpic (image.pdf)} +\special{pdf:uxobj @pdfpic} +} +\advance\count0 by 1 +% +\bye diff --git a/Build/source/texk/dvipdf-x/tests/psfonts.map b/Build/source/texk/dvipdf-x/tests/psfonts.map new file mode 100644 index 00000000000..2a799870993 --- /dev/null +++ b/Build/source/texk/dvipdf-x/tests/psfonts.map @@ -0,0 +1 @@ +cmr10 CMR10 + + 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 void tfm_set_verbose (void); + +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, SIGNED_QUAD ch); +#if 0 +extern double tfm_get_height (int font_id, SIGNED_QUAD ch); +extern double tfm_get_depth (int font_id, SIGNED_QUAD ch); +#endif + +extern fixword tfm_get_fw_width (int font_id, SIGNED_QUAD ch); +extern fixword tfm_get_fw_height (int font_id, SIGNED_QUAD ch); +extern fixword tfm_get_fw_depth (int font_id, SIGNED_QUAD ch); + +extern fixword tfm_string_width (int font_id, const unsigned char *s, unsigned len); +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); + +extern double tfm_get_space (int font_id); + +/* 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_exists (const char *tfm_name); + +#endif /* _TFM_H_ */ diff --git a/Build/source/texk/dvipdf-x/truetype.h b/Build/source/texk/dvipdf-x/truetype.h new file mode 100644 index 00000000000..a12c28d9517 --- /dev/null +++ b/Build/source/texk/dvipdf-x/truetype.h @@ -0,0 +1,33 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); +extern int pdf_font_load_truetype (pdf_font *font); + +#endif /* _TRUETYPE_H_ */ diff --git a/Build/source/texk/dvipdf-x/tt_glyf.h b/Build/source/texk/dvipdf-x/tt_glyf.h new file mode 100644 index 00000000000..1b00611dc9c --- /dev/null +++ b/Build/source/texk/dvipdf-x/tt_glyf.h @@ -0,0 +1,60 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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/dvipdf-x/tt_gsub.c b/Build/source/texk/dvipdf-x/tt_gsub.c new file mode 100644 index 00000000000..ea31da94e3e --- /dev/null +++ b/Build/source/texk/dvipdf-x/tt_gsub.c @@ -0,0 +1,1666 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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) + */ + +#include "system.h" + +#include "error.h" +#include "mem.h" +#include "mfileio.h" + +#include "sfnt.h" + +#include "otl_opt.h" +#include "tt_gsub.h" + +#define VERBOSE_LEVEL_MIN 0 +static int verbose = 0; +void +otl_gsub_set_verbose (void) +{ + verbose++; +} + +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 long +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 long +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 long +clt_read_record_list (struct clt_record_list *list, sfnt *sfont) +{ + long 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 long +clt_read_number_list (struct clt_number_list *list, sfnt *sfont) +{ + long 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 long +clt_read_script_table (struct clt_script_table *tab, sfnt *sfont) +{ + long 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 long +clt_read_langsys_table (struct clt_langsys_table *tab, sfnt *sfont) +{ + long 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 long +clt_read_feature_table (struct clt_feature_table *tab, sfnt *sfont) +{ + long 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 long +clt_read_lookup_table (struct clt_lookup_table *tab, sfnt *sfont) +{ + long 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 long +clt_read_coverage (struct clt_coverage *cov, sfnt *sfont) +{ + long 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 long +clt_lookup_coverage (struct clt_coverage *cov, USHORT gid) +{ + long 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 long +otl_gsub_read_single (struct otl_gsub_subtab *subtab, sfnt *sfont) +{ + long len; + ULONG offset; /* not Offset which is USHORT */ + Offset cov_offset; /* subtable offset, offset to Coverage table */ + + ASSERT(subtab && sfont); + +#ifdef XETEX + offset = sfont->loc; +#else + offset = tell_position(sfont->stream); +#endif + + 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 long +otl_gsub_read_alternate (struct otl_gsub_subtab *subtab, sfnt *sfont) +{ + long 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); + +#ifdef XETEX + offset = sfont->loc; +#else + offset = tell_position(sfont->stream); +#endif + + 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; + data->coverage.count = 0; + data->coverage.format = 0; + data->coverage.list = NULL; + return len; + } + 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; + break; + } + 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 long +otl_gsub_read_ligature (struct otl_gsub_subtab *subtab, sfnt *sfont) +{ + long 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); + +#ifdef XETEX + offset = sfont->loc; +#else + offset = tell_position(sfont->stream); +#endif + + 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; + data->coverage.count = 0; + data->coverage.format = 0; + data->coverage.list = NULL; + return len; + } + 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; + break; + } + 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; + break; + } + 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 long +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) +{ + long 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; + long 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(verbose > 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(verbose > 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(verbose > 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; + long i; + + if(verbose > 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 (feature_table.FeatureParams != 0) { + ERROR("unrecognized FeatureParams"); + } + + /* Lookup table */ + for (i = 0; i < feature_table.LookupListIndex.count; i++) { + struct clt_lookup_table lookup_table; + long 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 (verbose > 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(verbose > 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(verbose > 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(verbose > 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(verbose > 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(verbose > 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(verbose > 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(verbose > 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) +{ + long 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) +{ + long 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) +{ + long 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 otl_gsub +{ + int num_gsubs; + int select; + 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; + + return (otl_gsub *) gsub_list; +} + +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(verbose > 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(verbose > VERBOSE_LEVEL_MIN) { + MESG("otl_gsub>> Failed\n"); + } + RELEASE(gsub->script); + RELEASE(gsub->language); + RELEASE(gsub->feature); + } + + return retval; +} + +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); + } + + 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; +} + +int +otl_gsub_select (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)) { + gsub_list->select = i; + return i; + } + } + + gsub_list->select = -1; + + return -1; +} + +#if 0 +static int +otl_gsub_dump_single (struct otl_gsub_subtab *subtab) +{ + long gid, idx; + + ASSERT(subtab); + + if (subtab->SubstFormat == 1) { + struct otl_gsub_single1 *data; + + data = (subtab->table).single1; + for (gid = 0; gid < 0x10000; gid++) { + idx = clt_lookup_coverage(&data->coverage, gid); + if (idx >= 0) { + fprintf(stdout, "substitute \\%u by \\%u;\n", + (USHORT) gid, (USHORT) (gid + data->DeltaGlyphID)); + } + } + } else if (subtab->SubstFormat == 2) { + struct otl_gsub_single2 *data; + + data = (subtab->table).single2; + for (gid = 0; gid < 0x10000; gid++) { + idx = clt_lookup_coverage(&data->coverage, gid); + if (idx >= 0 && + idx < data->GlyphCount) { + fprintf(stdout, "substitute \\%u by \\%u;\n", + (USHORT) gid, (data->Substitute)[idx]); + } + } + } + + return 0; +} + +static int +otl_gsub_dump_alternate (struct otl_gsub_subtab *subtab) +{ + long gid, idx; + + ASSERT(subtab); + + if (subtab->SubstFormat == 1) { + struct otl_gsub_alternate1 *data; + + data = subtab->table.alternate1; + for (gid = 0; gid < 0x10000; gid++) { + idx = clt_lookup_coverage(&data->coverage, gid); + if (idx >= 0 && idx < data->AlternateSetCount) { + struct otl_gsub_altset *altset; + USHORT i; + altset = &(data->AlternateSet[idx]); + if (altset->GlyphCount == 0) + continue; + fprintf(stdout, "substitute \\%u from [", (USHORT) gid); + for (i = 0; i < altset->GlyphCount; i++) { + fprintf(stdout, " \\%u", altset->Alternate[i]); + } + fprintf(stdout, " ];\n"); + } + } + } + + return 0; +} + +static int +otl_gsub_dump_ligature (struct otl_gsub_subtab *subtab) +{ + long gid, idx; + + ASSERT(subtab); + + if (subtab->SubstFormat == 1) { + struct otl_gsub_ligature1 *data; + + data = subtab->table.ligature1; + for (gid = 0; gid < 0x10000; gid++) { + idx = clt_lookup_coverage(&data->coverage, gid); + 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++) { + fprintf(stdout, "substitute \\%u", (USHORT) gid); + for (i = 0; i < ligset->Ligature[j].CompCount - 1; i++) { + fprintf(stdout, " \\%u", ligset->Ligature[j].Component[i]); + } + fprintf(stdout, " by \\%u;\n", ligset->Ligature[j].LigGlyph); + } + } + } + } + + return 0; +} + +int +otl_gsub_dump (otl_gsub *gsub_list, + const char *script, const char *language, const char *feature) +{ + int error = -1; + struct otl_gsub_tab *gsub; + struct otl_gsub_subtab *subtab; + int sel, i, j; + + if (!gsub_list) + return -1; + + sel = gsub_list->select; + error = otl_gsub_select(gsub_list, script, language, feature); + if (error < 0) { + ERROR("GSUB feature %s.%s.%s not found.", script, language, feature); + } + + 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; + !error && + j < gsub->num_subtables; j++) { + subtab = &(gsub->subtables[j]); + switch ((int) subtab->LookupType){ + case OTL_GSUB_TYPE_SINGLE: + error = otl_gsub_dump_single(subtab); + break; + case OTL_GSUB_TYPE_ALTERNATE: + error = otl_gsub_dump_alternate(subtab); + break; + case OTL_GSUB_TYPE_LIGATURE: + error = otl_gsub_dump_ligature(subtab); + break; + } + } + gsub_list->select = sel; + + return error; +} +#endif diff --git a/Build/source/texk/dvipdf-x/tt_gsub.h b/Build/source/texk/dvipdf-x/tt_gsub.h new file mode 100644 index 00000000000..43e5aae02ae --- /dev/null +++ b/Build/source/texk/dvipdf-x/tt_gsub.h @@ -0,0 +1,67 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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" + +extern void otl_gsub_set_verbose (void); + +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); + +#if 0 +extern int otl_gsub_dump (otl_gsub *gsub_list, + const char *script, + const char *language, + const char *feature); +#endif + +#endif /* _TT_GSUB_H_ */ diff --git a/Build/source/texk/dvipdf-x/tt_post.h b/Build/source/texk/dvipdf-x/tt_post.h new file mode 100644 index 00000000000..89a5684f162 --- /dev/null +++ b/Build/source/texk/dvipdf-x/tt_post.h @@ -0,0 +1,53 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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); + +#endif /* _TT_POST_H_ */ diff --git a/Build/source/texk/dvipdf-x/tt_table.h b/Build/source/texk/dvipdf-x/tt_table.h new file mode 100644 index 00000000000..ddf9dce3c0a --- /dev/null +++ b/Build/source/texk/dvipdf-x/tt_table.h @@ -0,0 +1,199 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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_name (sfnt *sfont, char *dest, USHORT destlen, + USHORT plat_id, USHORT enco_id, + USHORT lang_id, USHORT name_id); +extern USHORT tt_get_ps_fontname (sfnt *sfont, char *dest, USHORT destlen); + +#endif /* _TT_TABLE_H_ */ diff --git a/Build/source/texk/dvipdf-x/type1.h b/Build/source/texk/dvipdf-x/type1.h new file mode 100644 index 00000000000..27aac87552e --- /dev/null +++ b/Build/source/texk/dvipdf-x/type1.h @@ -0,0 +1,33 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); +extern int pdf_font_load_type1 (pdf_font *font); + +#endif /* _TYPE1_H_ */ diff --git a/Build/source/texk/dvipdf-x/type1c.h b/Build/source/texk/dvipdf-x/type1c.h new file mode 100644 index 00000000000..27e929c6176 --- /dev/null +++ b/Build/source/texk/dvipdf-x/type1c.h @@ -0,0 +1,33 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); +extern int pdf_font_load_type1c (pdf_font *font); + +#endif /* _TYPE1C_H_ */ diff --git a/Build/source/texk/dvipdf-x/unicode.c b/Build/source/texk/dvipdf-x/unicode.c new file mode 100644 index 00000000000..ddf7380b53a --- /dev/null +++ b/Build/source/texk/dvipdf-x/unicode.c @@ -0,0 +1,113 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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? + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxutil.h" + +#include "pdfobj.h" +#include "pdfresource.h" + +#include "pdfencoding.h" +#include "agl.h" +#include "unicode.h" + +static int __verbose = 0; + +#define UC_DEBUG 3 +#define UC_DEBUG_STR "UC" + +void +UC_set_verbose (void) +{ + __verbose++; +} + +#define UC_REPLACEMENT_CHAR 0x0000FFFDL + +#define UC_SUR_SHIFT 10 +#define UC_SUR_MASK 0x3FFUL +#define UC_SUR_LOW_START 0xDC00UL +#define UC_SUR_HIGH_START 0xD800UL + +int +UC_sput_UTF16BE (long ucv, unsigned char **pp, unsigned char *limptr) +{ + int count = 0; + unsigned char *p = *pp; + + if (ucv >= 0 && ucv <= 0xFFFF) { + if (p + 2 >= limptr) + ERROR("Not enough space available..."); + p[0] = (ucv >> 8) & 0xff; + p[1] = ucv & 0xff; + count = 2; + } else if (ucv >= 0x010000L && ucv <= 0x10FFFFL) { + unsigned short high, low; + + if (p + 4 >= limptr) + ERROR("Not enough space available..."); + ucv -= 0x00010000L; + 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 >= limptr) + ERROR("Not enough space available..."); + p[0] = (UC_REPLACEMENT_CHAR >> 8) & 0xff; + p[1] = (UC_REPLACEMENT_CHAR & 0xff); + count = 2; + } + + *pp += count; + return count; +} + +int +UC_is_valid (long ucv) +{ + if (ucv < 0 || (ucv >= 0x0000D800L && ucv <= 0x0000DFFFL)) + return 0; + return 1; +} + diff --git a/Build/source/texk/dvipdf-x/unicode.h b/Build/source/texk/dvipdf-x/unicode.h new file mode 100644 index 00000000000..b1d00837c33 --- /dev/null +++ b/Build/source/texk/dvipdf-x/unicode.h @@ -0,0 +1,36 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +#include "pdfobj.h" +#include "agl.h" + +extern void UC_set_verbose (void); + +extern int UC_sput_UTF16BE (long ucv, unsigned char **dstpp, unsigned char *endptr); +extern int UC_is_valid (long ucv); + +#endif /* _UNICODE_H_ */ diff --git a/Build/source/texk/dvipdf-x/vf.h b/Build/source/texk/dvipdf-x/vf.h new file mode 100644 index 00000000000..8c8a923438d --- /dev/null +++ b/Build/source/texk/dvipdf-x/vf.h @@ -0,0 +1,35 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 void vf_set_verbose (void); +extern int vf_locate_font (const char *tex_name, spt_t ptsize); +extern void vf_set_char (SIGNED_QUAD ch, int vf_font); +extern void vf_close_all_fonts(void); + +#endif /* _VF_H_ */ diff --git a/Build/source/texk/dvipdf-x/xdvipdfm-ann.test b/Build/source/texk/dvipdf-x/xdvipdfm-ann.test new file mode 100755 index 00000000000..bdb35cad5f3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xdvipdfm-ann.test @@ -0,0 +1,25 @@ +#! /bin/sh + +# Copyright (C) 2013 Peter Breitenlohner +# You may freely use, modify and/or distribute this file. + +# Not really a test, just making sure the program executes. + +TEXMFCNF=${srcdir}/../kpathsea +TEXFONTS=${srcdir}/tests:${srcdir}/data +DVIPDFMXINPUTS=${srcdir}/tests:${srcdir}/data +TEXPICTS=${srcdir}/tests +export TEXMFCNF TEXFONTS DVIPDFMXINPUTS TEXPICTS + +failed= + +echo "*** xdvipdfmx -v -o grahn2.pdf grahn" && echo \ + && ./xdvipdfmx -v -o grahn2.pdf ${srcdir}/tests/grahn \ + && 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/dvipdf-x/xdvipdfmx.test b/Build/source/texk/dvipdf-x/xdvipdfmx.test new file mode 100755 index 00000000000..21a4c5a9af9 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xdvipdfmx.test @@ -0,0 +1,37 @@ +#! /bin/sh + +# Copyright (C) 2013 Peter Breitenlohner +# You may freely use, modify and/or distribute this file. + +TEXMFCNF=${srcdir}/../kpathsea +TEXFONTS=${srcdir}/tests:${srcdir}/data +DVIPDFMXINPUTS=${srcdir}/tests:${srcdir}/data +TEXPICTS=${srcdir}/tests +export TEXMFCNF TEXFONTS DVIPDFMXINPUTS TEXPICTS + +failed= + +if false; then + +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" + +fi + +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" + +test -z "$failed" && exit 0 +echo +echo "failed tests:$failed" +exit 1 + diff --git a/Build/source/texk/dvipdf-x/xsrc/bmpimage.c b/Build/source/texk/dvipdf-x/xsrc/bmpimage.c new file mode 100644 index 00000000000..e09e37b238c --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/bmpimage.c @@ -0,0 +1,466 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * BMP SUPPORT: + */ + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "pdfobj.h" + +#include "bmpimage.h" + +#define DIB_FILE_HEADER_SIZE 14 +#define DIB_CORE_HEADER_SIZE 14 +#define DIB_INFO_HEADER_SIZE 40 + +#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_SIZE) + +static long read_raster_rle8 (unsigned char *data_ptr, + long width, long height, FILE *fp); +static long read_raster_rle4 (unsigned char *data_ptr, + long width, long 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; + else + return 1; + + return 0; +} + +int +bmp_include_image (pdf_ximage *ximage, FILE *fp) +{ + pdf_obj *stream, *stream_dict, *colorspace; + ximage_info info; + unsigned char buf[DIB_HEADER_SIZE_MAX+4]; + unsigned char *p; + long offset, hsize, compression; + long psize; /* Bytes per palette color: 3 for OS2, 4 for Win */ + unsigned short bit_count; /* Bits per pix */ + int num_palette, flip; + int i; + unsigned long biXPelsPerMeter, biYPelsPerMeter; + + pdf_ximage_init_image_info(&info); + + stream = stream_dict = colorspace = NULL; + p = buf; + + rewind(fp); + if (fread(buf, 1, DIB_FILE_HEADER_SIZE + 4, fp) + != DIB_FILE_HEADER_SIZE + 4) { + WARN("Could not read BMP file header..."); + } + + 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; + offset = ULONG_LE(p); p += 4; + + /* info header */ + hsize = ULONG_LE(p); p += 4; + if (fread(p, sizeof(char), hsize - 4, fp) != hsize - 4) { + WARN("Could not read BMP file header..."); + return -1; + } + flip = 1; + if (hsize == DIB_CORE_HEADER_SIZE) { + info.width = USHORT_LE(p); p += 2; + info.height = USHORT_LE(p); p += 2; + if (USHORT_LE(p) != 1) { + WARN("Unknown bcPlanes value in BMP COREHEADER."); + return -1; + } + p += 2; + bit_count = USHORT_LE(p); p += 2; + compression = DIB_COMPRESS_NONE; + psize = 3; + } else if (hsize == DIB_INFO_HEADER_SIZE) { + info.width = ULONG_LE(p); p += 4; + info.height = ULONG_LE(p); p += 4; + if (USHORT_LE(p) != 1) { + WARN("Unknown biPlanes value in BMP INFOHEADER."); + return -1; + } + p += 2; + bit_count = USHORT_LE(p); p += 2; + compression = ULONG_LE(p); p += 4; + /* ignore biSizeImage */ p += 4; + biXPelsPerMeter = ULONG_LE(p); p += 4; + biYPelsPerMeter = ULONG_LE(p); p += 4; + info.xdensity = 72.0 / (biXPelsPerMeter * 0.0254); + info.ydensity = 72.0 / (biYPelsPerMeter * 0.0254); + if (info.height < 0) { + info.height = -info.height; + flip = 0; + } + psize = 4; + } else { + WARN("Unknown BMP header type."); + return -1; + } + + if (bit_count < 24) { + if (bit_count != 1 && + bit_count != 4 && bit_count != 8) { + WARN("Unsupported palette size: %ld", bit_count); + return -1; + } + num_palette = (offset - hsize - DIB_FILE_HEADER_SIZE) / psize; + info.bits_per_component = bit_count; + info.num_components = 1; + } else if (bit_count == 24) { /* full color */ + num_palette = 1; /* dummy */ + info.bits_per_component = 8; + info.num_components = 3; + } else { + WARN("Unkown BMP bitCount: %ld", 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; + } + + stream = pdf_new_stream(STREAM_COMPRESS); + stream_dict = pdf_stream_dict(stream); + + if (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, psize, fp) != 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. */ + { + long rowbytes, n; + unsigned char *stream_data_ptr = NULL; + + rowbytes = (info.width * bit_count + 7) / 8; + + seek_absolute(fp, offset); + if (compression == DIB_COMPRESS_NONE) { + long 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 (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 (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 { + pdf_release_obj(stream); + return -1; + } + + /* gbr --> rgb */ + if (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); + } + + pdf_ximage_set_image(ximage, &info, stream); + + return 0; +} + +static long +read_raster_rle8 (unsigned char *data_ptr, + long width, long height, FILE *fp) +{ + long count = 0; + unsigned char *p, b0, b1; + long 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 long +read_raster_rle4 (unsigned char *data_ptr, + long width, long height, FILE *fp) +{ + long count = 0; + unsigned char *p, b0, b1, b; + long 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/dvipdf-x/xsrc/cff.c b/Build/source/texk/dvipdf-x/xsrc/cff.c new file mode 100644 index 00000000000..5e98b6e097d --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/cff.c @@ -0,0 +1,1484 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. +*/ + +#include +#include + +#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 long get_unsigned (sfnt *sfont, int n) +{ + unsigned long v = 0; + + while (n-- > 0) + v = v*0x100u + sfnt_get_byte(sfont); + + return v; +} + +#define get_offset(s, n) get_unsigned((s), (n)) +#define get_card8(s) sfnt_get_byte((s)) +#define get_card16(s) sfnt_get_ushort((s)) + +/* + * Read Header, Name INDEX, Top DICT INDEX, and String INDEX. + */ +cff_font *cff_open(sfnt *sfont, long offset, int n) +{ + cff_font *cff; + cff_index *idx; + + cff = NEW(1, cff_font); + + cff->fontname = NULL; + cff->index = n; + cff->sfont = sfont; + cff->offset = offset; + cff->filter = 0; /* not used */ + cff->flag = 0; + + cff->name = 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_seek_set(cff, 0); + cff->header.major = get_card8(cff->sfont); + cff->header.minor = get_card8(cff->sfont); + cff->header.hdr_size = get_card8(cff->sfont); + cff->header.offsize = get_card8(cff->sfont); + 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 = cff->sfont->loc - offset; + + /* Number of glyphs */ + offset = (long) cff_dict_get(cff->topdict, "CharStrings", 0); + cff_seek_set(cff, offset); + cff->num_glyphs = get_card16(cff->sfont); + + /* 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 = (long) 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 = (long) 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 */ + +#ifdef XETEX + cff->ft_to_gid = NULL; +#endif + + 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;inum_fds;i++) { + if (cff->fdarray[i]) cff_release_dict(cff->fdarray[i]); + } + RELEASE(cff->fdarray); + } + if (cff->private) { + for (i=0;inum_fds;i++) { + if (cff->private[i]) cff_release_dict(cff->private[i]); + } + RELEASE(cff->private); + } + if (cff->subrs) { + for (i=0;inum_fds;i++) { + if (cff->subrs[i]) cff_release_index(cff->subrs[i]); + } + RELEASE(cff->subrs); + } + if (cff->_string) + cff_release_index(cff->_string); +#ifdef XETEX + if (cff->ft_to_gid) RELEASE(cff->ft_to_gid); +#endif + 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; +} + +long +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); +} + +long +cff_put_header (cff_font *cff, card8 *dest, long 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_card16(cff->sfont); + if (count > 0) { + idx->offsize = get_card8(cff->sfont); + if (idx->offsize < 1 || idx->offsize > 4) + ERROR("invalid offsize data"); + + idx->offset = NEW(count+1, l_offset); + for (i=0;ioffset)[i] = get_offset(cff->sfont, 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; + long length, nb_read, offset; + + idx = NEW(1, cff_index); + + idx->count = count = get_card16(cff->sfont); + if (count > 0) { + idx->offsize = get_card8(cff->sfont); + 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->sfont, 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 = sfnt_read(idx->data + offset, length, cff->sfont); + offset += nb_read; + length -= nb_read; + } + } else { + idx->offsize = 0; + idx->offset = NULL; + idx->data = NULL; + } + + return idx; +} + +long +cff_pack_index (cff_index *idx, card8 *dest, long destlen) +{ + long len = 0; + long 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; +} + +long +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; + long 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; +} + +long 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; +} + +long 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; +} + +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; + long 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. + */ +long cff_read_encoding (cff_font *cff) +{ + cff_encoding *encoding; + long 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 = (long) 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_card8(cff->sfont); + length = 1; + + switch (encoding->format & (~0x80)) { + case 0: + encoding->num_entries = get_card8(cff->sfont); + (encoding->data).codes = NEW(encoding->num_entries, card8); + for (i=0;i<(encoding->num_entries);i++) { + (encoding->data).codes[i] = get_card8(cff->sfont); + } + length += encoding->num_entries + 1; + break; + case 1: + { + cff_range1 *ranges; + encoding->num_entries = get_card8(cff->sfont); + encoding->data.range1 = ranges + = NEW(encoding->num_entries, cff_range1); + for (i=0;i<(encoding->num_entries);i++) { + ranges[i].first = get_card8(cff->sfont); + ranges[i].n_left = get_card8(cff->sfont); + } + 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_card8(cff->sfont); + encoding->supp = map = NEW(encoding->num_supps, cff_map); + for (i=0;i<(encoding->num_supps);i++) { + map[i].code = get_card8(cff->sfont); + map[i].glyph = get_card16(cff->sfont); /* SID */ + } + length += (encoding->num_supps) * 3 + 1; + } else { + encoding->num_supps = 0; + encoding->supp = NULL; + } + + return length; +} + +long cff_pack_encoding (cff_font *cff, card8 *dest, long destlen) +{ + long 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); + } +} + +long cff_read_charsets (cff_font *cff) +{ + cff_charsets *charset; + long 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 = (long) 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_card8(cff->sfont); + 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_card16(cff->sfont); + } + 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_card16(cff->sfont); + ranges[charset->num_entries].n_left = get_card8(cff->sfont); + 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_card16(cff->sfont); + ranges[charset->num_entries].n_left = get_card16(cff->sfont); + 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; +} + +long cff_pack_charsets (cff_font *cff, card8 *dest, long destlen) +{ + long 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; +} + +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 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) +{ + card16 gid = 0; + cff_charsets *charset; + card16 i; + + 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 (cid == 0) { + return 0; /* GID 0 (.notdef) */ + } + + charset = cff->charsets; + + gid = 0; + switch (charset->format) { + case 0: + for (i = 0; i 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) +{ + card16 sid = 0; + cff_charsets *charset; + card16 i; + + 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 */ + } + + charset = cff->charsets; + + sid = 0; + 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 */ +long cff_read_fdselect (cff_font *cff) +{ + cff_fdselect *fdsel; + long offset, length; + card16 i; + + if (cff->topdict == NULL) + ERROR("Top DICT not available"); + + if (!(cff->flag & FONTTYPE_CIDFONT)) + return 0; + + offset = (long) cff_dict_get(cff->topdict, "FDSelect", 0); + cff_seek_set(cff, offset); + cff->fdselect = fdsel = NEW(1, cff_fdselect); + fdsel->format = get_card8(cff->sfont); + + 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_card8(cff->sfont); + } + length += fdsel->num_entries; + break; + case 3: + { + cff_range3 *ranges; + fdsel->num_entries = get_card16(cff->sfont); + fdsel->data.ranges = ranges = NEW(fdsel->num_entries, cff_range3); + for (i=0;i<(fdsel->num_entries);i++) { + ranges[i].first = get_card16(cff->sfont); + ranges[i].fd = get_card8(cff->sfont); + } + if (ranges[0].first != 0) + ERROR("Range not starting with 0."); + if (cff->num_glyphs != get_card16(cff->sfont)) + 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; +} + +long cff_pack_fdselect (cff_font *cff, card8 *dest, long destlen) +{ + cff_fdselect *fdsel; + long 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;inum_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; +} + +long cff_read_subrs (cff_font *cff) +{ + long len = 0; + long 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;inum_fds;i++) { + if (cff->private[i] == NULL || + !cff_dict_known(cff->private[i], "Subrs")) { + (cff->subrs)[i] = NULL; + } else { + offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); + offset += (long) 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 = (long) cff_dict_get(cff->topdict, "Private", 1); + offset += (long) 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; +} + +long cff_read_fdarray (cff_font *cff) +{ + long len = 0; + cff_index *idx; + long 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 = (long) 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;icount;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; +} + +long cff_read_private (cff_font *cff) +{ + long len = 0; + card8 *data; + long 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;inum_fds;i++) { + if (cff->fdarray[i] != NULL && + cff_dict_known(cff->fdarray[i], "Private") && + (size = (long) cff_dict_get(cff->fdarray[i], "Private", 0)) + > 0) { + offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); + cff_seek_set(cff, offset); + data = NEW(size, card8); + if (sfnt_read(data, size, cff->sfont) != 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 = (long) cff_dict_get(cff->topdict, "Private", 0)) > 0) { + offset = (long) cff_dict_get(cff->topdict, "Private", 1); + cff_seek_set(cff, offset); + data = NEW(size, card8); + if (sfnt_read(data, size, cff->sfont) != 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; +} + +#ifdef XETEX +unsigned short* cff_get_ft_to_gid(cff_font *cff) +{ + return cff->ft_to_gid; +} +#endif diff --git a/Build/source/texk/dvipdf-x/xsrc/cff.h b/Build/source/texk/dvipdf-x/xsrc/cff.h new file mode 100644 index 00000000000..9772d6d2a31 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/cff.h @@ -0,0 +1,156 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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" + +#include "sfnt.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; + +#ifdef XETEX + unsigned short *ft_to_gid; +#endif + + sfnt *sfont; + int filter; /* not used, ASCII Hex filter if needed */ + + int index; /* CFF fontset index */ + int flag; /* Flag: see above */ +} cff_font; + +extern cff_font *cff_open (sfnt *sfont, long offset, int idx); +extern void cff_close (cff_font *cff); + +#define cff_seek_set(c, p) sfnt_seek_set (((c)->sfont), ((c)->offset) + (p)); + +/* CFF Header */ +extern long cff_put_header (cff_font *cff, card8 *dest, long 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 long cff_index_size (cff_index *idx); +extern long cff_pack_index (cff_index *idx, card8 *dest, long destlen); + +/* Name INDEX */ +extern char *cff_get_name (cff_font *cff); +extern long cff_set_name (cff_font *cff, char *name); + +/* Global and Local Subrs INDEX */ +extern long cff_read_subrs (cff_font *cff); + +/* Encoding */ +extern long cff_read_encoding (cff_font *cff); +extern long cff_pack_encoding (cff_font *cff, card8 *dest, long destlen); +extern card16 cff_encoding_lookup (cff_font *cff, card8 code); +extern void cff_release_encoding (cff_encoding *encoding); + +/* Charsets */ +extern long cff_read_charsets (cff_font *cff); +extern long cff_pack_charsets (cff_font *cff, card8 *dest, long destlen); + +/* Returns GID of PS name "glyph" */ +extern card16 cff_glyph_lookup (cff_font *cff, const char *glyph); +/* Returns GID of glyph with SID/CID "cid" */ +extern card16 cff_charsets_lookup (cff_font *cff, 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); + +/* FDSelect */ +extern long cff_read_fdselect (cff_font *cff); +extern long cff_pack_fdselect (cff_font *cff, card8 *dest, long destlen); +extern card8 cff_fdselect_lookup (cff_font *cff, card16 gid); +extern void cff_release_fdselect (cff_fdselect *fdselect); + +/* Font DICT(s) */ +extern long cff_read_fdarray (cff_font *cff); + +/* Private DICT(s) */ +extern long cff_read_private (cff_font *cff); + +#ifdef XETEX +extern unsigned short* cff_get_ft_to_gid(cff_font *cff); +#endif + +/* String */ +extern int cff_match_string (cff_font *cff, const char *str, s_SID sid); +extern char *cff_get_string (cff_font *cff, s_SID id); +extern long cff_get_sid (cff_font *cff, const char *str); +extern long 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); + +#define cff_is_stdstr(s) (cff_get_sid(NULL, (s)) >= 0) + +#endif /* _CFF_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/cff_dict.c b/Build/source/texk/dvipdf-x/xsrc/cff_dict.c new file mode 100644 index 00000000000..96b30ef5d55 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/cff_dict.c @@ -0,0 +1,720 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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" + */ + +#include +#include +#include + +#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;icount;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) +{ + long 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) { + *status = CFF_ERROR_PARSE_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 long pack_integer (card8 *dest, long destlen, long value) +{ + long 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 long pack_real (card8 *dest, long 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 long cff_dict_put_number (double value, + card8 *dest, long destlen, + int type) +{ + long len = 0; + double nearint; + + nearint = floor(value+0.5); + /* set offset to longint */ + if (type == CFF_TYPE_OFFSET) { + long lvalue; + + lvalue = (long) 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, (long) nearint); + } + + return len; +} + +static long +put_dict_entry (cff_dict_entry *de, + card8 *dest, long destlen) +{ + long 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; +} + +long cff_dict_pack (cff_dict *dict, card8 *dest, long destlen) +{ + long 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;idcount;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/dvipdf-x/xsrc/cidtype0.c b/Build/source/texk/dvipdf-x/xsrc/cidtype0.c new file mode 100644 index 00000000000..316f5c68073 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/cidtype0.c @@ -0,0 +1,2075 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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. + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "numbers.h" +#include "mem.h" +#include "error.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 "cid_p.h" +#include "cidtype0.h" + +static int verbose = 0; +static long opt_flags = 0; + +void +CIDFont_type0_set_verbose (void) +{ + verbose++; +} + +void +CIDFont_type0_set_flags (long flags) +{ + opt_flags = flags; +} + +/* + * 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; + long cid, start = 0, prev = 0; + double defaultAdvanceWidth; + int empty = 1; + + 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; + long cid; +#if 0 + long 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 long +write_fontfile (CIDFont *font, cff_font *cffont) +{ + cff_index *topdict, *fdarray, *private; + unsigned char *dest; + long destlen = 0, i, size; + long 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; +} + +void +CIDFont_type0_dofont (CIDFont *font) +{ + sfnt *sfont; + cff_font *cffont; + FILE *fp = NULL; + cff_index *charstrings, *idx; + cff_charsets *charset = NULL; + cff_fdselect *fdselect = NULL; + long charstring_len, max_len; + long destlen = 0; + long size, offset = 0; + card8 *data; + card16 num_glyphs, gid; + long cid, cid_count; + card16 cs_count, last_cid; + int fd, prev_fd, parent_id; + char *used_chars; + unsigned char *CIDToGIDMap = NULL; + + ASSERT(font); + + if (!font->indirect) + return; + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), + pdf_ref_obj (font->descriptor)); + + if (CIDFont_is_BaseFont(font)) + return; + else if (!CIDFont_get_embedding(font) && + (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) { + /* No metrics needed. */ + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + return; + } + + if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && + (parent_id = CIDFont_get_parent_id(font, 1)) < 0) + ERROR("No parent Type 0 font !"); + + used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + if (!used_chars) + ERROR("Unexpected error: Font not actually used???"); + +#ifdef XETEX + sfont = sfnt_open(font->ft_face, SFNT_TYPE_POSTSCRIPT); +#else + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT); + if (!fp) + ERROR("Could not open OpenType font file: %s", font->ident); + sfont = sfnt_open(fp); +#endif + if (!sfont) + ERROR("Could not open OpenType font file: %s", font->ident); + + if (sfnt_read_table_directory(sfont, 0) < 0 || + sfont->type != SFNT_TYPE_POSTSCRIPT) + ERROR("Not a CFF/OpenType font ?"); + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset == 0) + ERROR("Not a CFF/OpenType font ?"); + + cffont = cff_open(sfont, offset, font->options->index); + if (!cffont) + ERROR("Could not open CFF font."); + if (!(cffont->flag & FONTTYPE_CIDFONT)) + ERROR("Not a CIDFont."); + + if (cff_dict_known(cffont->topdict, "CIDCount")) { + cid_count = (long) cff_dict_get(cffont->topdict, "CIDCount", 0); + } else { + cid_count = CID_MAX + 1; + } + + cff_read_charsets(cffont); + CIDToGIDMap = NEW(2*cid_count, unsigned char); + memset(CIDToGIDMap, 0, 2*cid_count); + add_to_used_chars2(used_chars, 0); /* .notdef */ + cid = 0; last_cid = 0; num_glyphs = 0; + 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->ident); + 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_FORCE_FIXEDPITCH) { + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + } else { + add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid, + ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1)); + } + + if (!CIDFont_get_embedding(font)) { + RELEASE(CIDToGIDMap); + cff_close(cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return; + } + + /* + * Embed font subset. + */ + cff_read_fdselect(cffont); + cff_read_fdarray(cffont); + cff_read_private(cffont); + + cff_read_subrs(cffont); + + offset = (long) 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 = cffont->sfont->loc; + + if ((cs_count = idx->count) < 2) { + ERROR("No valid charstring data found."); + } + + /* 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) + ERROR("Charstring too long: gid=%u", gid_org); + 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; + sfnt_seek_set(cffont->sfont, offset + (idx->offset)[gid_org] - 1); + sfnt_read(data, size, cffont->sfont); + 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) + ERROR("Unexpeced error: ?????"); + 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); + if (fp) + DPXFCLOSE(fp); + + if (verbose > 1) + MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen); + + /* + * 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); + } + + return; +} + +int +CIDFont_type0_open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + CIDSysInfo *csi; + char *fontname; + sfnt *sfont; + cff_font *cffont; + FILE *fp = NULL; + unsigned long offset = 0; + + ASSERT(font); + +#ifdef XETEX + sfont = sfnt_open(font->ft_face, SFNT_TYPE_POSTSCRIPT); + if (!sfont) + return -1; +#else + fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT); + if (!fp) + return -1; + + sfont = sfnt_open(fp); + if (!sfont) { + ERROR("Not a CFF/OpenType font?"); + } +#endif + if (sfont->type != SFNT_TYPE_POSTSCRIPT || + sfnt_read_table_directory(sfont, 0) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + ERROR("Not a CFF/OpenType font?"); + } + + cffont = cff_open(sfont, offset, opt->index); + if (!cffont) { + ERROR("Cannot read CFF font data"); + } + + if (!(cffont->flag & FONTTYPE_CIDFONT)) { + cff_close(cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + } + + csi = NEW(1, CIDSysInfo); + 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); + + if (cmap_csi) { + if (strcmp(csi->registry, cmap_csi->registry) != 0 || + strcmp(csi->ordering, cmap_csi->ordering) != 0) { + MESG("\nCharacter collection mismatched:\n"); + MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement); + MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); + ERROR("Inconsistent CMap specified for this font."); + } + if (csi->supplement < cmap_csi->supplement) { + WARN("CMap have higher supplmement number."); + WARN("Some characters may not be displayed or printed."); + } + } + + { + char *shortname; + + shortname = cff_get_name(cffont); + if (!shortname) + ERROR("No valid FontName found."); + /* + * Mangled name requires more 7 bytes. + * Style requires more 11 bytes. + */ + fontname = NEW(strlen(shortname)+19, char); + memset(fontname, 0, strlen(shortname)+19); + strcpy(fontname, shortname); + RELEASE(shortname); + } + 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; + } + + font->fontname = fontname; + font->subtype = CIDFONT_TYPE0; + font->csi = csi; + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); + + /* getting font info. from TrueType tables */ + if ((font->descriptor + = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name)) == NULL) + ERROR("Could not obtain necessary font info."); + + if (opt->embed) { + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + } + + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(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->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict); + } + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), + pdf_new_number(1000)); /* not sure */ + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return 0; +} + +void +CIDFont_type0_t1cdofont (CIDFont *font) +{ + sfnt *sfont; + cff_font *cffont; + cff_index *charstrings, *idx; + long charstring_len, max_len; + long destlen = 0; + long size, offset = 0; + card8 *data; + card16 num_glyphs, gid, last_cid; + long i, cid; + int parent_id; + char *used_chars; + double default_width, nominal_width; + FILE *fp = NULL; + + ASSERT(font); + + if (!font->indirect) + return; + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), + pdf_ref_obj (font->descriptor)); + + if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && + (parent_id = CIDFont_get_parent_id(font, 1)) < 0) + ERROR("No parent Type 0 font !"); + + used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + if (!used_chars) + ERROR("Unexpected error: Font not actually used???"); + +#ifdef XETEX + sfont = sfnt_open(font->ft_face, SFNT_TYPE_POSTSCRIPT); +#else + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT); + if (!fp) + ERROR("Could not open OpenType font file: %s", font->ident); + + sfont = sfnt_open(fp); +#endif + if (!sfont) + ERROR("Could not open OpenType font file: %s", font->ident); + + if (sfnt_read_table_directory(sfont, 0) < 0 || + sfont->type != SFNT_TYPE_POSTSCRIPT) + ERROR("Not a CFF/OpenType font ?"); + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset == 0) + ERROR("Not a CFF/OpenType font ?"); + + cffont = cff_open(sfont, offset, font->options->index); + if (!cffont) + ERROR("Could not open CFF font."); + if (cffont->flag & FONTTYPE_CIDFONT) + ERROR("This is CIDFont..."); + + 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 = (long) 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 = cffont->sfont->loc; + + if (idx->count < 2) + ERROR("No valid charstring data found."); + + /* 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) + ERROR("Charstring too long: gid=%u", cid); + 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; + sfnt_seek_set(cffont->sfont, offset + (idx->offset)[cid] - 1); + sfnt_read(data, size, cffont->sfont); + 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) + ERROR("Unexpeced error: ?????"); + 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); + + cff_close(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->fontdict, CIDToGIDMap, last_cid, + ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1)); + RELEASE(CIDToGIDMap); + } + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + if (verbose > 1) + MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen); + + /* + * 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); + } + + return; +} + +int +CIDFont_type0_t1copen (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + CIDSysInfo *csi; + char *fontname; + sfnt *sfont; + cff_font *cffont; + unsigned long offset = 0; + FILE *fp = NULL; + + ASSERT(font); + +#ifdef XETEX + sfont = sfnt_open(font->ft_face, SFNT_TYPE_POSTSCRIPT); + if (!sfont) + return -1; +#else + fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT); + if (!fp) + return -1; + + sfont = sfnt_open(fp); +#endif + if (!sfont) { + ERROR("Not a CFF/OpenType font?"); + } + if (sfont->type != SFNT_TYPE_POSTSCRIPT || + sfnt_read_table_directory(sfont, 0) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + ERROR("Not a CFF/OpenType font?"); + } + + cffont = cff_open(sfont, offset, opt->index); + if (!cffont) { + ERROR("Cannot read CFF font data"); + } + + if (cffont->flag & FONTTYPE_CIDFONT) { + cff_close(cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return -1; + } + + csi = NEW(1, CIDSysInfo); + 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 (cmap_csi) { + if (strcmp(csi->registry, cmap_csi->registry) != 0 || + strcmp(csi->ordering, cmap_csi->ordering) != 0) { + MESG("\nCharacter collection mismatched:\n"); + MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement); + MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); + ERROR("Inconsistent CMap specified for this font."); + } + if (csi->supplement < cmap_csi->supplement) { + WARN("CMap have higher supplmement number."); + WARN("Some characters may not be displayed or printed."); + } + } + + { + char *shortname; + + shortname = cff_get_name(cffont); + if (!shortname) + ERROR("No valid FontName found."); + /* Mangled name requires more 7 bytes. */ + + fontname = NEW(strlen(shortname) + 8, char); + memset(fontname, 0, strlen(shortname) + 8); + strcpy(fontname, shortname); + RELEASE(shortname); + } + cff_close(cffont); + + opt->embed = 1; + + font->fontname = fontname; + font->subtype = CIDFONT_TYPE0; + font->csi = csi; + font->flags |= CIDFONT_FLAG_TYPE1C; + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); + + /* getting font info. from TrueType tables */ + if ((font->descriptor + = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name)) == NULL) + ERROR("Could not obtain necessary font info."); + + if (opt->embed) { + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + } + + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(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->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict); + } + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return 0; +} + + +/* 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" + +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++) { + long 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) { + ERROR("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; + long 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; + long 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, 0); + } + CMap_release(cmap); + + return stream; +} + + +int +CIDFont_type0_t1open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + FILE *fp; + char *fontname, *shortname; + cff_font *cffont; + + ASSERT(font); + + if (cmap_csi && + (strcmp(cmap_csi->registry, "Adobe") != 0 || + strcmp(cmap_csi->ordering, "Identity") != 0)) { + return -1; + } + fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT); + if (!fp) + return -1; + + cffont = t1_load_font(NULL, 1, fp); + if (!cffont) { + DPXFCLOSE(fp); + return -1; + } + DPXFCLOSE(fp); + + shortname = cff_get_name(cffont); + if (!shortname) + ERROR("No valid FontName found."); + fontname = NEW(strlen(shortname) + 8, char); + memset(fontname, 0, strlen(shortname) + 8); + strcpy(fontname, shortname); + RELEASE(shortname); + +#ifdef XETEX + font->ft_to_gid = cff_get_ft_to_gid(cffont); + cffont->ft_to_gid = NULL; +#endif + + cff_close(cffont); + + 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 = CIDFONT_TYPE0; + font->csi = NEW(1, CIDSysInfo); + font->csi->registry = NEW(strlen("Adobe")+1, char); + strcpy(font->csi->registry, "Adobe"); + font->csi->ordering = NEW(strlen("Identity")+1, char); + strcpy(font->csi->ordering, "Identity"); + font->csi->supplement = 0; + font->flags |= CIDFONT_FLAG_TYPE1; + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); + + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + + font->descriptor = pdf_new_dict(); + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(fontname)); + { + pdf_obj *csi_dict; + + csi_dict = pdf_new_dict(); + pdf_add_dict(csi_dict, + pdf_new_name("Registry"), + pdf_new_string("Adobe", strlen("Adobe"))); + pdf_add_dict(csi_dict, + pdf_new_name("Ordering"), + pdf_new_string("Identity", strlen("Identity"))); + pdf_add_dict(csi_dict, + pdf_new_name("Supplement"), + pdf_new_number(0.0)); + pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict); + } + + + return 0; +} + +/* 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 */ + +/* pdf_font --> CIDFont */ +static void +get_font_attr (CIDFont *font, cff_font *cffont) +{ + double capheight, ascent, descent; + double italicangle, stemv; + double defaultwidth, nominalwidth; + long flags = 0; + long 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 (CIDFont *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, parent_id; + + /* + * 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?"); + } + 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); + + if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && + (parent_id = CIDFont_get_parent_id(font, 1)) < 0) + ERROR("No parent Type 0 font !"); + + used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + if (!used_chars) { + ERROR("Unexpected error: Font not actually used???"); + } + + /* 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->fontdict, + pdf_new_name("DW"), pdf_new_number(default_width)); + if (pdf_array_length(tmp) > 0) { + pdf_add_dict(font->fontdict, pdf_new_name("W"), pdf_ref_obj(tmp)); + } + pdf_release_obj(tmp); +} + +void +CIDFont_type0_t1dofont (CIDFont *font) +{ + cff_font *cffont; + double defaultwidth, nominalwidth; + long num_glyphs = 0; + FILE *fp; + long i, offset; + char *used_chars = NULL; + card16 last_cid, gid, cid; + unsigned char *CIDToGIDMap; + + ASSERT(font); + + if (!font->indirect) { + return; + } + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), + pdf_ref_obj (font->descriptor)); + + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_T1FONT); + if (!fp) { + ERROR("Type1: Could not open Type1 font."); + } + + cffont = t1_load_font(NULL, 0, fp); + if (!cffont) + ERROR("Could not read Type 1 font..."); + DPXFCLOSE(fp); + + if (!font->fontname) + ERROR("Fontname undefined..."); + + { + Type0Font *hparent, *vparent; + pdf_obj *tounicode; + int vparent_id, hparent_id; + + hparent_id = CIDFont_get_parent_id(font, 0); + vparent_id = CIDFont_get_parent_id(font, 1); + if (hparent_id < 0 && vparent_id < 0) + ERROR("No parent Type 0 font !"); + + /* usedchars is same for h and v */ + if (hparent_id < 0) + hparent = NULL; + else { + hparent = Type0Font_cache_get(hparent_id); + used_chars = Type0Font_get_usedchars(hparent); + } + if (vparent_id < 0) + vparent = NULL; + else { + vparent = Type0Font_cache_get(vparent_id); + used_chars = Type0Font_get_usedchars(vparent); + } + if (!used_chars) + ERROR("Unexpected error: Font not actually used???"); + + tounicode = create_ToUnicode_stream(cffont, font->fontname, used_chars); + + if (hparent) + Type0Font_set_ToUnicode(hparent, pdf_ref_obj(tounicode)); + if (vparent) + Type0Font_set_ToUnicode(vparent, pdf_ref_obj(tounicode)); + pdf_release_obj(tounicode); + } + + 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; + long 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) { + ERROR("This font using the \"seac\" command for accented characters..."); + } + 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); + + { + 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); + } + + + return; +} + +void +CIDFont_type0_release(CIDFont *font) +{ +#ifdef XETEX + if (font->ft_to_gid) RELEASE(font->ft_to_gid); +#endif + return; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/cidtype2.c b/Build/source/texk/dvipdf-x/xsrc/cidtype2.c new file mode 100644 index 00000000000..0059a1c89ea --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/cidtype2.c @@ -0,0 +1,1126 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "numbers.h" +#include "mem.h" +#include "error.h" +#include "dpxfile.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 "cid_p.h" +#include "cidtype2.h" + +static int verbose = 0; +static int opt_flags = 0; + +void +CIDFont_type2_set_verbose (void) +{ + verbose++; +} + +void +CIDFont_type2_set_flags (long flags) +{ + opt_flags = flags; +} + +/* + * 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 void +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) { + ERROR("No valid character found in fontname string."); + } +} + +/* + * 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) + ERROR("Character set unknown."); + + if (!strcmp(ord, "UCS") && + select <= WIN_UCS_INDEX_MAX) + 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."); + ERROR("Cannot continue..."); + } + + 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) +{ + long 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 char *cidtogidmap, unsigned short last_cid) +{ + pdf_obj *w2_array, *an_array = NULL; + long cid; +#if 0 + long 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 long +cid_to_code (CMap *cmap, CID cid) +{ + unsigned char inbuf[2], outbuf[32]; + long 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 0; + else if (outbytesleft == 31) + return (long) outbuf[0]; + else if (outbytesleft == 30) + return (long) (outbuf[0] << 8|outbuf[1]); + else if (outbytesleft == 28) { /* We assume the output encoding is UTF-16. */ + CID hi, lo; + hi = outbuf[0] << 8|outbuf[1]; + lo = outbuf[2] << 8|outbuf[3]; + if (hi >= 0xd800 && hi <= 0xdbff && lo >= 0xdc00 && lo <= 0xdfff) + return (long) ((hi - 0xd800) * 0x400 + 0x10000 + lo - 0xdc00); + else + return (long) (hi << 16|lo); + } + + return 0; +} + +/* #define NO_GHOSTSCRIPT_BUG 1 */ + +void +CIDFont_type2_dofont (CIDFont *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; + unsigned long offset = 0; + CID cid, last_cid; + unsigned char *cidtogidmap; + USHORT num_glyphs; + int i, glyph_ordering = 0, unicode_cmap = 0; + FILE *fp = NULL; + + if (!font->indirect) + return; + + pdf_add_dict(font->fontdict, + pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor)); + + if (CIDFont_is_BaseFont(font)) + return; + + /* + * 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->csi->registry, strlen(font->csi->registry))); + pdf_add_dict(tmp, + pdf_new_name("Ordering"), + pdf_new_string(font->csi->ordering, strlen(font->csi->ordering))); + pdf_add_dict(tmp, + pdf_new_name("Supplement"), + pdf_new_number(font->csi->supplement)); + pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), tmp); + } + + /* Quick exit for non-embedded & fixed-pitch font. */ + if (!CIDFont_get_embedding(font) && + (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) { + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + return; + } + +#ifdef XETEX + sfont = sfnt_open(font->ft_face, SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE); +#else + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_TTFONT); + if (!fp) { + fp = DPXFOPEN(font->ident, DPX_RES_TYPE_DFONT); + if (!fp) ERROR("Could not open TTF/dfont file: %s", font->ident); + sfont = dfont_open(fp, font->options->index); + } else { + sfont = sfnt_open(fp); + } +#endif + + if (!sfont) { + ERROR("Could not open TTF file: %s", font->ident); + } + + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, font->options->index); + if (offset == 0) + ERROR("Invalid TTC index in %s.", font->ident); + break; + case SFNT_TYPE_TRUETYPE: +#ifndef XETEX + /* disable the check here becuase sfnt_open() does not distinguish dfont + * from regular trutype */ + if (font->options->index > 0) + ERROR("Found TrueType font file while expecting TTC file (%s).", font->ident); +#endif + offset = 0; + break; + case SFNT_TYPE_DFONT: + offset = sfont->offset; + break; + default: + ERROR("Not a TrueType/TTC font (%s)?", font->ident); + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) + ERROR("Could not read TrueType table directory (%s).", font->ident); + + /* + * Adobe-Identity means font's internal glyph ordering here. + */ + if (!strcmp(font->csi->registry, "Adobe") && + !strcmp(font->csi->ordering, "Identity")) { + glyph_ordering = 1; + } else { + glyph_ordering = 0; + } + + /* + * Select TrueType cmap table, find ToCode CMap for each TrueType encodings. + */ + if (glyph_ordering) { + ttcmap = NULL; + cmap = NULL; + } else { + /* + * 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->ident); + WARN("CID character collection for this font is set to \"%s-%s\"", + font->csi->registry, font->csi->ordering); + ERROR("Cannot continue without this..."); + } else if (i <= WIN_UCS_INDEX_MAX) { + unicode_cmap = 1; + } else { + unicode_cmap = 0; + } + + /* + * NULL is returned if CMap is Identity CMap. + */ + cmap = find_tocode_cmap(font->csi->registry, + font->csi->ordering, i); + } + + glyphs = tt_build_init(); + + last_cid = 0; + num_glyphs = 1; /* .notdef */ + used_chars = h_used_chars = v_used_chars = NULL; + { + Type0Font *parent; + int parent_id, c; + + if ((parent_id = CIDFont_get_parent_id(font, 0)) >= 0) { + parent = Type0Font_cache_get(parent_id); + h_used_chars = Type0Font_get_usedchars(parent); + } + if ((parent_id = CIDFont_get_parent_id(font, 1)) >= 0) { + parent = Type0Font_cache_get(parent_id); + v_used_chars = Type0Font_get_usedchars(parent); + } + if (!h_used_chars && !v_used_chars) + ERROR("Unexpected error."); + + /* + * 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; + } + if (v_used_chars && v_used_chars[i] != 0) { + last_cid = i * 8 + 7; + c = v_used_chars[i]; + break; + } + } + if (last_cid > 0) { + for (i = 0; i < 8; i++) { + if ((c >> i) & 1) + break; + last_cid--; + } + } + if (last_cid >= 0xFFFFu) { + ERROR("CID count > 65535"); + } + } + +#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++) { + long code; + unsigned short gid; + + if (!is_used_char2(h_used_chars, cid)) + continue; + + if (glyph_ordering) { + gid = cid; + code = cid; + } else { + code = cid_to_code(cmap, cid); + gid = tt_cmap_lookup(ttcmap, code); +#ifdef FIX_CJK_UNIOCDE_SYMBOLS + if (gid == 0 && unicode_cmap) { + long 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 */ + } + + if (gid == 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 (glyph_ordering) { + 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++) { + long code; + unsigned short gid; + + 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; + } + + if (glyph_ordering) { + gid = cid; + code = cid; + } else { + code = cid_to_code(cmap, cid); + gid = tt_cmap_lookup(ttcmap, code); +#ifdef FIX_CJK_UNIOCDE_SYMBOLS + if (gid == 0 && unicode_cmap) { + long 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 */ + } + if (gid == 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; + } + + if (!used_chars) + ERROR("Unexpected error."); + + tt_cmap_release(ttcmap); + + if (CIDFont_get_embedding(font)) { + if (tt_build_tables(sfont, glyphs) < 0) + ERROR("Could not created FontFile stream."); + if (verbose > 1) + MESG("[%u glyphs (Max CID: %u)]", glyphs->num_glyphs, last_cid); + } else { + if (tt_get_metrics(sfont, glyphs) < 0) + ERROR("Reading glyph metrics failed..."); + } + + /* + * DW, W, DW2, and W2 + */ + if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { + pdf_add_dict(font->fontdict, + pdf_new_name("DW"), pdf_new_number(1000.0)); + } else { + add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); + if (v_used_chars) + add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); + } + + tt_build_finish(glyphs); + + /* Finish here if not embedded. */ + if (!CIDFont_get_embedding(font)) { + if (cidtogidmap) + RELEASE(cidtogidmap); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return; + } + + /* 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) { + ERROR("Some required TrueType table (%s) does not exist.", required_table[i].name); + } + } + + /* + * FontFile2 + */ + fontfile = sfnt_create_FontFile_stream(sfont); + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + if (!fontfile) + ERROR("Could not created FontFile stream for \"%s\".", font->ident); + + if (verbose > 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); + + /* + * CIDSet + */ + { + 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); + } + + /* + * CIDToGIDMap + */ + if (cidtogidmap) { + pdf_obj *c2gmstream; + + c2gmstream = pdf_new_stream(STREAM_COMPRESS); + pdf_add_stream(c2gmstream, cidtogidmap, (last_cid + 1) * 2); + pdf_add_dict(font->fontdict, + pdf_new_name("CIDToGIDMap"), + pdf_ref_obj (c2gmstream)); + pdf_release_obj(c2gmstream); + RELEASE(cidtogidmap); + } + + return; +} + +int +CIDFont_type2_open (CIDFont *font, const char *name, + CIDSysInfo *cmap_csi, cid_opt *opt) +{ + char *fontname; + sfnt *sfont; + unsigned long offset = 0; + FILE *fp = NULL; + + ASSERT(font && opt); + +#ifdef XETEX + sfont = sfnt_open(font->ft_face, SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE); + if (!sfont) + return -1; +#else + fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT); + if (!fp) { + fp = DPXFOPEN(name, DPX_RES_TYPE_DFONT); + if (!fp) return -1; + sfont = dfont_open(fp, opt->index); + } else { + sfont = sfnt_open(fp); + } + + if (!sfont) { + DPXFCLOSE(fp); + return -1; + } +#endif + + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, opt->index); + break; + case SFNT_TYPE_TRUETYPE: +#ifdef XETEX + /* disable the check here becuase sfnt_open() does not distinguish dfont + * from regular trutype */ + offset = 0; +#else + assert (opt->index == 0); + if (opt->index > 0) { + ERROR("Invalid TTC index (not TTC font): %s", name); + } else { + offset = 0; + } +#endif + break; + case SFNT_TYPE_DFONT: + offset = sfont->offset; + break; + default: + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) { + ERROR("Reading TrueType table directory failed."); + } + + { + char *shortname; + long 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); + } + validate_name(shortname, namelen); /* for SJIS, UTF-16, ... string */ + /* + * 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 = CIDFONT_TYPE2; + font->csi = NEW(1, CIDSysInfo); + if (opt->csi) { + if (cmap_csi) { + if (strcmp(opt->csi->registry, cmap_csi->registry) || + strcmp(opt->csi->ordering, cmap_csi->ordering)) { + WARN("CID character collection mismatched:\n"); + MESG("\tFont: %s-%s-%d\n", + opt->csi->registry, opt->csi->ordering, opt->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 (opt->csi->supplement < cmap_csi->supplement) { + WARN("Supplmement value in CIDSystemInfo increased."); + WARN("Some characters may not shown."); + opt->csi->supplement = cmap_csi->supplement; + } + } + font->csi->registry = NEW(strlen(opt->csi->registry)+1, char); + strcpy(font->csi->registry, opt->csi->registry); + font->csi->ordering = NEW(strlen(opt->csi->ordering)+1, char); + strcpy(font->csi->ordering, opt->csi->ordering); + font->csi->supplement = opt->csi->supplement; + } else if (cmap_csi) { + font->csi->registry = NEW(strlen(cmap_csi->registry)+1, char); + strcpy(font->csi->registry, cmap_csi->registry); + font->csi->ordering = NEW(strlen(cmap_csi->ordering)+1, char); + strcpy(font->csi->ordering, cmap_csi->ordering); + font->csi->supplement = cmap_csi->supplement; + } else { /* This means font's internal glyph ordering. */ + font->csi->registry = NEW(strlen("Adobe")+1, char); + strcpy(font->csi->registry, "Adobe"); + font->csi->ordering = NEW(strlen("Identity")+1, char); + strcpy(font->csi->ordering, "Identity"); + font->csi->supplement = 0; + } + + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->fontdict, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType2")); + + font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name); + if (!font->descriptor) { + ERROR("Could not obtain necessary font info."); + } + + if (opt->embed) { + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; + } + + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), + pdf_new_name(fontname)); + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + /* + * Don't write fontdict here. + * /Supplement in /CIDSystemInfo may change. + */ + + return 0; +} + +void +CIDFont_type2_release (CIDFont *font) +{ + return; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/dpxfile.c b/Build/source/texk/dvipdf-x/xsrc/dpxfile.c new file mode 100644 index 00000000000..a0b124c722e --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/dpxfile.c @@ -0,0 +1,1175 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _MSC_VER +#include +#endif + +#include + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dpxutil.h" +#include "mfileio.h" + +#include "dpxfile.h" +#include "dpxcrypt.h" +#define MAX_KEY_LEN 16 + +#include +#include +#ifdef WIN32 +#include +#include +#else +#if HAVE_SYS_WAIT_H +#include +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(val) ((unsigned)(val) >> 8) +#endif +#ifndef WIFEXITED +#define WIFEXITED(val) (((val) & 255) == 0) +#endif +#endif + +static int verbose = 0; +int keep_cache = 0; + +void +dpx_file_set_verbose (void) +{ + verbose++; +} + + +/* Kpathsea library does not check file type. */ +static int qcheck_filetype (const char *fqpn, int type); + +/* For testing MIKTEX enabled compilation */ +#if defined(TESTCOMPILE) && !defined(MIKTEX) +# define MIKTEX 1 +# define PATH_SEP_CHR '/' +# define _MAX_PATH 256 + +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) > _MAX_PATH) + 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(PACKAGE); + + if (!fqpn) + return 0; + if (strlen(fqpn) > _MAX_PATH) + 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) > _MAX_PATH) + r = 0; + else { + strcpy(buf, fqpn); + r = 1; + } + RELEASE(fqpn); + + return r; +} + +#endif /* TESTCOMPILE */ + +#ifdef MIKTEX +#ifndef PATH_SEP_CHR +# define PATH_SEP_CHR '\\' +#endif +static char _tmpbuf[_MAX_PATH+1]; +#endif /* MIKTEX */ + +static int exec_spawn (char *cmd) +{ + char **cmdv, **qv; + char *p, *pp; + char buf[1024]; + int i, ret = -1; + + 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 + 2, sizeof (char *)); + p = cmd; + qv = cmdv; + while (*p) { + pp = buf; + if (*p == '"') { + p++; + while (*p != '"') { + if (*p == '\0') { + goto done; + } + *pp++ = *p++; + } + p++; + } else if (*p == '\'') { + p++; + while (*p != '\'') { + if (*p == '\0') { + goto done; + } + *pp++ = *p++; + } + p++; + } else { + while (*p != ' ' && *p != '\t' && *p) { + if (*p == '\'') { + p++; + while (*p != '\'') { + if (*p == '\0') { + goto done; + } + *pp++ = *p++; + } + p++; + } else { + *pp++ = *p++; + } + } + } + *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++; + } +#ifdef WIN32 + ret = spawnvp (_P_WAIT, *cmdv, (const char* const*) cmdv); +#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 +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(PACKAGE, q, _tmpbuf); + if (!r && strcmp(q, filename)) + r = miktex_find_app_input_file(PACKAGE, 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) +{ + kpse_format_info_type *fif; + kpse_format_info_type *fir; + if (verbose < 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."); +} + +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(PACKAGE); + + 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, int type) +{ + FILE *fp = NULL; + char *fqpn = NULL; + + switch (type) { + case DPX_RES_TYPE_FONTMAP: + fqpn = dpx_find_fontmap_file(filename); + 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; + default: + ERROR("Unknown resource type: %d", type); + 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 + 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, PACKAGE, + 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 + 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, PACKAGE, + 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) + /* Find in Acrobat's Resource/CMap dir */ + { + char _acrodir[_MAX_PATH+1]; + char *q; + int r; + + memset(_acrodir, 0, _MAX_PATH+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, _MAX_PATH+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 + 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 + 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 + 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 + 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 + 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 + if (is_absolute_path(q)) + fqpn = xstrdup(q); + else + fqpn = kpse_find_file(q, kpse_opentype_format, 0); + if (!fqpn) { +#endif + fqpn = dpx_foolsearch(PACKAGE, q, 0); +#ifndef MIKTEX + if (fqpn) + insistupdate(filename, fqpn, PACKAGE, + 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 const char * +dpx_get_tmpdir (void) +{ +# ifdef WIN32 +# define __TMPDIR "." +# else /* WIN32 */ +# define __TMPDIR "/tmp" +#endif /* WIN32 */ + 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 */ + return _tmpd; +} + +#ifdef HAVE_MKSTEMP +# include +#endif + +#ifdef XETEX +char * +dpx_create_temp_file (void) +{ + char *tmp = NULL; + +#if defined(MIKTEX) + { + tmp = NEW(_MAX_PATH + 1, char); + miktex_create_temp_file_name(tmp); /* FIXME_FIXME */ + } +#elif defined(HAVE_MKSTEMP) +# define TEMPLATE "/dvipdfmx.XXXXXXXX" + { + const char *_tmpd; + int _fd = -1; + _tmpd = dpx_get_tmpdir(); + tmp = NEW(strlen(_tmpd) + strlen(TEMPLATE) + 1, char); + strcpy(tmp, _tmpd); + strcat(tmp, TEMPLATE); + _fd = mkstemp(tmp); + if (_fd != -1) +#ifdef WIN32 + _close(_fd); +#else + close(_fd); +#endif /* WIN32 */ + else { + RELEASE(tmp); + tmp = NULL; + } + } +#else /* use _tempnam or tmpnam */ + { +# ifdef WIN32 + const char *_tmpd; + char *p; + _tmpd = dpx_get_tmpdir(); + tmp = _tempnam (_tmpd, "dvipdfmx."); + 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; +} +#endif /* XETEX */ + +char * +dpx_create_fix_temp_file (const char *filename) +{ +#define PREFIX "xdvipdfmx." + static const 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; id_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) +{ + const char *dir; + char *pathname; + DIR *dp; + struct dirent *de; + time_t limit; + + if (life == -2) { + 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) 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); + stat(pathname, &sb); + if (sb.st_mtime < limit) { + remove(pathname); + /* printf("remove: %s\n", pathname); */ + } + } + } + closedir(dp); + } + RELEASE(pathname); +} + +void +dpx_delete_temp_file (char *tmp, int force) +{ + if (!tmp) + return; + if (force || 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, + unsigned char 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); + } + case 'v': /* Version number, e.g. 1.4 */ { + char buf[6]; + sprintf(buf, "1.%hu", (unsigned short) version); + 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(*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; + unsigned long 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, int type) +{ + int r = 1; + FILE *fp; + + if (!fqpn) + 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; + } + MFCLOSE(fp); + + return r; +} + diff --git a/Build/source/texk/dvipdf-x/xsrc/dpxfile.h b/Build/source/texk/dvipdf-x/xsrc/dpxfile.h new file mode 100644 index 00000000000..e4ae4c0a679 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/dpxfile.h @@ -0,0 +1,70 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +#define DPX_RES_TYPE_FONTMAP 0x00 + +#define DPX_RES_TYPE_T1FONT 0x10 +#define DPX_RES_TYPE_TTFONT 0x11 +#define DPX_RES_TYPE_OTFONT 0x12 +#define DPX_RES_TYPE_PKFONT 0x13 +#define DPX_RES_TYPE_DFONT 0x14 + +#define DPX_RES_TYPE_ENC 0x20 +#define DPX_RES_TYPE_CMAP 0x21 +#define DPX_RES_TYPE_SFD 0x22 +#define DPX_RES_TYPE_AGL 0x23 + +#define DPX_RES_TYPE_ICCPROFILE 0x30 + +#define DPX_RES_TYPE_BINARY 0x40 +#define DPX_RES_TYPE_TEXT 0x41 + +#include "mfileio.h" +extern FILE *dpx_open_file (const char *filename, int 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 void dpx_file_set_verbose (void); + +extern int dpx_file_apply_filter (const char *cmdtmpl, + const char *input, const char *output, + unsigned char 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 */ + +extern int keep_cache; +#endif /* _DPXFILE_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/dpxutil.c b/Build/source/texk/dvipdf-x/xsrc/dpxutil.c new file mode 100644 index 00000000000..98ba7cde9d4 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/dpxutil.c @@ -0,0 +1,651 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include +#include +#include +#include + +#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; +} + +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; +} + +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); +} + +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; +} + +/* Overflowed value is set to invalid char. */ +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; +} + +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; +} + +void +skip_white_spaces (unsigned char **s, unsigned char *endptr) +{ + while (*s < endptr) + if (!is_space(**s)) + break; + else + (*s)++; +} + +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; +} + +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 && ht->table && 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(p[0]); + i++, p++) + c = (c << 4) + + (isdigit(p[0]) ? + p[0] - '0' : + (islower(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/dvipdf-x/xsrc/dpxutil.h b/Build/source/texk/dvipdf-x/xsrc/dpxutil.h new file mode 100644 index 00000000000..f902bb1f2aa --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/dpxutil.h @@ -0,0 +1,105 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +#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)) + +#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) == '%') +#endif + +extern void skip_white_spaces (unsigned char **s, unsigned char *endptr); +extern int xtoi (char c); +extern int getxpair (unsigned char **str); +extern int putxpair (unsigned char c, char **str); +extern int sputx (unsigned char c, char **buf, char *endptr); + +extern unsigned char ostrtouc (unsigned char **inbuf, + unsigned char *inbufend, unsigned char *valid); +extern unsigned char esctouc (unsigned char **inbuf, + unsigned char *inbufend, unsigned char *valid); + +#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 { + long 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 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/dvipdf-x/xsrc/dvi.c b/Build/source/texk/dvipdf-x/xsrc/dvi.c new file mode 100644 index 00000000000..5bb8d9aad5e --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/dvi.c @@ -0,0 +1,2737 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#endif + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "numbers.h" + +#include "pdfdev.h" +#include "pdfdoc.h" +#include "pdfparse.h" +#include "pdfencrypt.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" + +#ifdef XETEX +#include "pdfximage.h" +#include FT_ADVANCES_H +#endif + +#define DVI_STACK_DEPTH_MAX 256u +#define TEX_FONTS_ALLOC_SIZE 16u +#define VF_NESTING_MAX 16u + +/* Interal Variables */ +static FILE *dvi_file = NULL; +static char linear = 0; /* set to 1 for strict linear processing of the input */ + +static unsigned long *page_loc = NULL; +static unsigned long num_pages = 0; + +static unsigned long dvi_file_size = 0; + +static struct dvi_header +{ + UNSIGNED_QUAD unit_num; + UNSIGNED_QUAD unit_den; + UNSIGNED_QUAD mag; + UNSIGNED_QUAD media_width, media_height; + UNSIGNED_PAIR 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 PHYSICAL 1 +#define VIRTUAL 2 +#define SUBFONT 3 +#ifdef XETEX +#define NATIVE 4 +#endif +#define DVI 1 +#define VF 2 + +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 */ +#ifdef XETEX + unsigned long rgba_color; + FT_Face ft_face; + int layout_dir; + float extend; + float slant; + float embolden; +#endif +} *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 +{ + long 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; +#ifdef XETEX + int native; /* boolean */ + unsigned long rgba_color; /* only used for native fonts in XeTeX */ + int layout_dir; /* 1 = vertical, 0 = horizontal */ + int extend; + int slant; + int embolden; +#endif +} *def_fonts = NULL; + +#ifdef XETEX +#define XDV_FLAG_VERTICAL 0x0100 +#define XDV_FLAG_COLORED 0x0200 +#define XDV_FLAG_FEATURES 0x0400 +#define XDV_FLAG_VARIATIONS 0x0800 +#define XDV_FLAG_EXTEND 0x1000 +#define XDV_FLAG_SLANT 0x2000 +#define XDV_FLAG_EMBOLDEN 0x4000 +#endif + +static int num_def_fonts = 0, max_def_fonts = 0; +static int compute_boxes = 0, link_annot = 1; +static int verbose = 0; + +#define DVI_PAGE_BUF_CHUNK 0x10000UL /* 64K should be plenty for most pages */ + +static unsigned char* dvi_page_buffer; +static unsigned long dvi_page_buf_size; +static unsigned long dvi_page_buf_index; + +/* functions to read numbers from the dvi file and store them in dvi_page_buffer */ +static UNSIGNED_BYTE 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 (UNSIGNED_BYTE) ch; +} + +#if 0 +/* Not used */ +static SIGNED_BYTE get_and_buffer_signed_byte (FILE *file) +{ + int byte; + byte = get_and_buffer_unsigned_byte(file); + if (byte >= 0x80) + byte -= 0x100; + return (SIGNED_BYTE) byte; +} +#endif + +static UNSIGNED_PAIR get_and_buffer_unsigned_pair (FILE *file) +{ + int i; + UNSIGNED_BYTE byte; + UNSIGNED_PAIR pair = 0; + for (i=0; i<2; i++) { + byte = get_and_buffer_unsigned_byte(file); + pair = pair*0x100u + byte; + } + return pair; +} + +static SIGNED_PAIR get_and_buffer_signed_pair (FILE *file) +{ + int i; + long pair = 0; + for (i=0; i<2; i++) { + pair = pair*0x100 + get_and_buffer_unsigned_byte(file); + } + if (pair >= 0x8000) { + pair -= 0x10000l; + } + return (SIGNED_PAIR) pair; +} + +static UNSIGNED_TRIPLE get_and_buffer_unsigned_triple(FILE *file) +{ + int i; + long triple = 0; + for (i=0; i<3; i++) { + triple = triple*0x100u + get_and_buffer_unsigned_byte(file); + } + return (UNSIGNED_TRIPLE) triple; +} + +static SIGNED_TRIPLE get_and_buffer_signed_triple(FILE *file) +{ + int i; + long triple = 0; + for (i=0; i<3; i++) { + triple = triple*0x100 + get_and_buffer_unsigned_byte(file); + } + if (triple >= 0x800000l) + triple -= 0x1000000l; + return (SIGNED_TRIPLE) triple; +} + +static SIGNED_QUAD get_and_buffer_signed_quad(FILE *file) +{ + int byte, i; + long quad = 0; + + /* Check sign on first byte before reading others */ + byte = get_and_buffer_unsigned_byte(file); + quad = byte; + if (quad >= 0x80) + quad = byte - 0x100; + for (i=0; i<3; i++) { + quad = quad*0x100 + get_and_buffer_unsigned_byte(file); + } + return (SIGNED_QUAD) quad; +} + +static UNSIGNED_QUAD get_and_buffer_unsigned_quad(FILE *file) +{ + int i; + unsigned long quad = 0; + for (i=0; i<4; i++) { + quad = quad*0x100u + get_and_buffer_unsigned_byte(file); + } + return (UNSIGNED_QUAD) quad; +} + +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 UNSIGNED_BYTE get_buffered_unsigned_byte (void) +{ + return dvi_page_buffer[dvi_page_buf_index++]; +} + +static SIGNED_BYTE get_buffered_signed_byte (void) +{ + int byte; + byte = dvi_page_buffer[dvi_page_buf_index++]; + if (byte >= 0x80) + byte -= 0x100; + return (SIGNED_BYTE) byte; +} + +static UNSIGNED_PAIR get_buffered_unsigned_pair (void) +{ + int i; + UNSIGNED_BYTE byte; + UNSIGNED_PAIR pair = 0; + for (i=0; i<2; i++) { + byte = dvi_page_buffer[dvi_page_buf_index++]; + pair = pair*0x100u + byte; + } + return pair; +} + +static SIGNED_PAIR get_buffered_signed_pair (void) +{ + int i; + long pair = 0; + for (i=0; i<2; i++) { + pair = pair*0x100 + dvi_page_buffer[dvi_page_buf_index++]; + } + if (pair >= 0x8000) { + pair -= 0x10000l; + } + return (SIGNED_PAIR) pair; +} + +static UNSIGNED_TRIPLE get_buffered_unsigned_triple(void) +{ + int i; + long triple = 0; + for (i=0; i<3; i++) { + triple = triple*0x100u + dvi_page_buffer[dvi_page_buf_index++]; + } + return (UNSIGNED_TRIPLE) triple; +} + +static SIGNED_TRIPLE get_buffered_signed_triple(void) +{ + int i; + long triple = 0; + for (i=0; i<3; i++) { + triple = triple*0x100 + dvi_page_buffer[dvi_page_buf_index++]; + } + if (triple >= 0x800000l) + triple -= 0x1000000l; + return (SIGNED_TRIPLE) triple; +} + +static SIGNED_QUAD get_buffered_signed_quad(void) +{ + int byte, i; + long quad = 0; + + /* Check sign on first byte before reading others */ + byte = dvi_page_buffer[dvi_page_buf_index++]; + quad = byte; + if (quad >= 0x80) + quad = byte - 0x100; + for (i=0; i<3; i++) { + quad = quad*0x100 + dvi_page_buffer[dvi_page_buf_index++]; + } + return (SIGNED_QUAD) quad; +} + +static UNSIGNED_QUAD get_buffered_unsigned_quad(void) +{ + int i; + unsigned long quad = 0; + for (i=0; i<4; i++) { + quad = quad*0x100u + dvi_page_buffer[dvi_page_buf_index++]; + } + return (UNSIGNED_QUAD) quad; +} + + + +void +dvi_set_verbose (void) +{ + verbose++; + subfont_set_verbose(); + tfm_set_verbose(); + vf_set_verbose (); + spc_set_verbose(); +} + +unsigned +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 long +find_post (void) +{ + long current; + int ch; + + /* First find end of file */ + dvi_file_size = file_size(dvi_file); + current = dvi_file_size; + + /* Scan backwards through PADDING */ + do { + current--; + seek_absolute(dvi_file, current); + } 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 || +#ifdef XETEX + !(ch == DVI_ID || ch == DVIV_ID || ch == XDVI_ID)) { +#else + !(ch == DVI_ID || ch == DVIV_ID)) { +#endif + MESG("DVI ID = %d\n", ch); + ERROR(invalid_signature); + } + + /* Make sure post_post is really there */ + current = current - 5; + seek_absolute(dvi_file, current); + 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); + seek_absolute(dvi_file, current); + if ((ch = fgetc(dvi_file)) != POST) { + MESG("Found %d where post_post opcode should be\n", ch); + ERROR(invalid_signature); + } + + return current; +} + +static void +get_page_info (long post_location) +{ + int i; + + seek_absolute(dvi_file, post_location + 27); + num_pages = get_unsigned_pair(dvi_file); + if (num_pages == 0) { + ERROR("Page count is 0!"); + } + if (verbose > 2) { + MESG("Page count:\t %4d\n", num_pages); + } + + page_loc = NEW(num_pages, unsigned long); + + seek_absolute(dvi_file, post_location + 1); + 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--) { + seek_absolute(dvi_file, page_loc[i+1] + 41); + 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 (long post_location) +{ + seek_absolute(dvi_file, post_location + 5); + + 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 (verbose > 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) +{ + UNSIGNED_BYTE ch; + + ch = get_unsigned_byte(dvi_file); + if (ch != PRE) { + MESG("Found %d where PRE was expected\n", ch); + ERROR(invalid_signature); + } + + ch = get_unsigned_byte(dvi_file); +#ifdef XETEX + if (!(ch == DVI_ID || ch == DVIV_ID || ch == XDVI_ID)) { +#else + if (!(ch == DVI_ID || ch == DVIV_ID)) { +#endif + MESG("DVI ID = %d\n", ch); + ERROR(invalid_signature); + } + + 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); + + 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 (verbose > 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 (verbose) { + MESG("DVI Comment: %s\n", dvi_info.comment); + } + + num_pages = 0x7FFFFFFUL; /* for linear processing: we just keep going! */ +} + +const char * +dvi_comment (void) +{ + return dvi_info.comment; +} + +static void +read_font_record (SIGNED_QUAD tex_id) +{ + UNSIGNED_BYTE dir_length, name_length; + UNSIGNED_QUAD 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); + } + get_unsigned_quad(dvi_file); + point_size = get_unsigned_quad(dvi_file); + design_size = get_unsigned_quad(dvi_file); + 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'; + 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; +#ifdef XETEX + def_fonts[num_def_fonts].native = 0; + def_fonts[num_def_fonts].rgba_color = 0xffffffff; + 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; +#endif + num_def_fonts++; + + return; +} + +#ifdef XETEX +static void +read_native_font_record (SIGNED_QUAD tex_id) +{ + UNSIGNED_PAIR flags; + UNSIGNED_QUAD point_size; + char *font_name; + int plen, flen, slen, i; + + 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_unsigned_quad(dvi_file); + flags = get_unsigned_pair(dvi_file); + + plen = (int) get_unsigned_byte(dvi_file); /* PS name length */ + flen = (int) get_unsigned_byte(dvi_file); /* family name length */ + slen = (int) get_unsigned_byte(dvi_file); /* style name length */ + font_name = NEW(plen + 1, char); + if (fread(font_name, 1, plen, dvi_file) != plen) { + ERROR(invalid_signature); + } + font_name[plen] = '\0'; + + /* ignore family and style names */ + for (i = 0; i < flen + slen; ++i) + get_unsigned_byte(dvi_file); + + 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 = 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].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); + + 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); + + if (flags & XDV_FLAG_VARIATIONS) { + int v, nvars = get_unsigned_pair(dvi_file); + for (v = 0; v < nvars * 2; ++v) + (void)get_unsigned_quad(dvi_file); /* skip axis and value for each variation setting */ + WARN("Variation axes are not supported; ignoring variation settings for font %s.\n", font_name); + } + + num_def_fonts++; + + return; +} +#endif + +static void +get_dvi_fonts (long post_location) +{ + UNSIGNED_BYTE code; + SIGNED_QUAD tex_id = 0; + + seek_absolute(dvi_file, post_location + 29); + while ((code = get_unsigned_byte(dvi_file)) != POST_POST) { + switch (code) { + case FNT_DEF1: + tex_id = get_unsigned_byte(dvi_file); + break; + case FNT_DEF2: + tex_id = get_unsigned_pair(dvi_file); + break; + case FNT_DEF3: + tex_id = get_unsigned_triple(dvi_file); + break; + case FNT_DEF4: +#ifdef XETEX + case XDV_NATIVE_FONT_DEF: +#endif + tex_id = get_signed_quad(dvi_file); + break; + default: + MESG("Unexpected op code: %3d\n", code); + ERROR(invalid_signature); + } +#ifdef XETEX + if (code != XDV_NATIVE_FONT_DEF) { + read_font_record(tex_id); + } else { + read_native_font_record(tex_id); + } +#else + read_font_record(tex_id); +#endif + } + if (verbose > 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=%5ld, ", + 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) +{ + UNSIGNED_BYTE length; + + seek_absolute(dvi_file, 14); + 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 (verbose) { + 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 +{ + SIGNED_QUAD h, v, w, x, y, z, 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 */ + 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_do_special (const void *buffer, UNSIGNED_QUAD size) +{ + double x_user, y_user, mag; + const char *p; + + if (size > 0x7fffffffUL) { + WARN("Special more than %ul bytes???", size); + return; + } + + 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, (long) size, x_user, y_user, mag) < 0) { + if (verbose) { + dump(p, p + size); + } + } + + 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 (verbose) + 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); + } + + /* 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 (verbose) + 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 (verbose) + 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) { + 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..."); + } + loaded_fonts[cur_id].type = PHYSICAL; + loaded_fonts[cur_id].font_id = font_id; + + if (verbose) + MESG(">"); + + return cur_id; +} + +#ifdef XETEX +static int +dvi_locate_native_font (const char *ps_name, + spt_t ptsize, int layout_dir, int extend, int slant, int embolden) +{ + int cur_id = -1; + fontmap_rec *mrec; + char *fontmap_key = malloc(strlen(ps_name) + 40); // CHECK this is enough + + if (verbose) + MESG("<%s@%.2fpt", ps_name, ptsize * dvi2pts); + + need_more_fonts(1); + + cur_id = num_loaded_fonts++; + + sprintf(fontmap_key, "%s/%c/%d/%d/%d", ps_name, layout_dir == 0 ? 'H' : 'V', extend, slant, embolden); + mrec = pdf_lookup_fontmap_record(fontmap_key); + if (mrec == NULL) { + if (pdf_load_native_font(ps_name, layout_dir, extend, slant, embolden) == -1) { + ERROR("Cannot proceed without the \"native\" font: %s", ps_name); + } + mrec = pdf_lookup_fontmap_record(fontmap_key); + /* FIXME: would be more efficient if pdf_load_native_font returned the mrec ptr (or NULL for error) + so we could avoid doing a second lookup for the item we just inserted */ + } + 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; + free(fontmap_key); + + loaded_fonts[cur_id].ft_face = mrec->opt.ft_face; + 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 (verbose) + MESG(">"); + + return cur_id; +} +#endif + +double +dvi_dev_xpos (void) +{ + return dvi_state.h * dvi2pts; +} + +double +dvi_dev_ypos (void) +{ + return -(dvi_state.v * dvi2pts); +} + +static void do_moveto (SIGNED_QUAD x, SIGNED_QUAD y) +{ + dvi_state.h = x; + dvi_state.v = y; +} + +void dvi_right (SIGNED_QUAD x) +{ + if (!dvi_state.d) { + dvi_state.h += x; + } else { + dvi_state.v += x; + } +} + +void dvi_down (SIGNED_QUAD y) +{ + if (!dvi_state.d) { + dvi_state.v += y; + } else { + dvi_state.h -= y; + } +} + +/* Please remove this. + * Optimization for 8-bit encodings. + */ +static void +do_string (unsigned char *s, int len) +{ + struct loaded_font *font; + spt_t width, height, depth; + int i; + + if (current_font < 0) + ERROR("No font selected!"); + + font = &loaded_fonts[current_font]; + + width = tfm_string_width(font->tfm_id, s, len); + width = sqxfw(font->size, width); + + switch (font->type) { + case PHYSICAL: + if (font->subfont_id < 0) { + pdf_dev_set_string(dvi_state.h, -dvi_state.v, s, len, + width, font->font_id, 1); + if (compute_boxes && link_annot && + marked_depth >= tagged_depth) { + pdf_rect rect; + + height = tfm_string_height(font->tfm_id, s, len); + depth = tfm_string_depth (font->tfm_id, s, len); + height = sqxfw(font->size, height); + depth = sqxfw(font->size, depth); + + pdf_dev_set_rect (&rect, dvi_state.h, -dvi_state.v, + width, height, depth); + pdf_doc_expand_box(&rect); + } + } else { /* Subfonts */ + dvi_push(); + for (i = 0; i < len; i++) { + dvi_set(s[i]); + } + dvi_pop(); + } + break; + case VIRTUAL: + dvi_push(); + for (i = 0; i < len; i++) { + dvi_set(s[i]); + } + dvi_pop(); + } + if (!dvi_state.d) { + dvi_state.h += width; + } else { + dvi_state.v += width; + } +} + +/* _FIXME_ + * CMap decoder wants multibyte strings as input but + * how DVI char codes are converted to multibyte sting + * is not clear. + */ +void +dvi_set (SIGNED_QUAD ch) +{ + struct loaded_font *font; + spt_t width, height, depth; + unsigned char wbuf[2]; + + 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]; + + width = tfm_get_fw_width(font->tfm_id, ch); + width = sqxfw(font->size, width); + + switch (font->type) { + case PHYSICAL: + if (ch > 255) { /* _FIXME_ */ + wbuf[0] = (ch >> 8) & 0xff; + wbuf[1] = ch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else if (font->subfont_id >= 0) { + unsigned short uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch); + wbuf[0] = (uch >> 8) & 0xff; + wbuf[1] = uch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else { + wbuf[0] = (unsigned char) ch; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1, + width, font->font_id, 1); + } + if (compute_boxes && link_annot && + marked_depth >= tagged_depth) { + 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); + + pdf_dev_set_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 (!dvi_state.d) { + dvi_state.h += width; + } else { + dvi_state.v += width; + } +} + +void +dvi_put (SIGNED_QUAD ch) +{ + struct loaded_font *font; + spt_t width, height, depth; + unsigned char wbuf[2]; + + if (current_font < 0) { + ERROR("No font selected!"); + } + + font = &loaded_fonts[current_font]; + + 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 > 255) { /* _FIXME_ */ + wbuf[0] = (ch >> 8) & 0xff; + wbuf[1] = ch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else if (font->subfont_id >= 0) { + unsigned int uch; + + uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch); + wbuf[0] = (uch >> 8) & 0xff; + wbuf[1] = uch & 0xff; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2, + width, font->font_id, 2); + } else { + wbuf[0] = (unsigned char) ch; + pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1, + width, font->font_id, 1); + } + if (compute_boxes && link_annot && + marked_depth >= tagged_depth) { + 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); + + pdf_dev_set_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 (SIGNED_QUAD width, SIGNED_QUAD height) +{ + do_moveto(dvi_state.h, dvi_state.v); + + if (!dvi_state.d) { + pdf_dev_set_rule(dvi_state.h, -dvi_state.v, width, height); + } else { /* right ? */ + pdf_dev_set_rule(dvi_state.h, -dvi_state.v - width, height, width); + } +} + +void +dvi_dir (UNSIGNED_BYTE dir) +{ + dvi_state.d = dir ? 1 : 0; + pdf_dev_set_dirmode(dvi_state.d); /* 0: horizontal, 1: vertical */ +} + +static void +do_set1 (void) +{ + dvi_set(get_buffered_unsigned_byte()); +} + +static void +do_set2 (void) +{ + dvi_set(get_buffered_unsigned_pair()); +} + +static void +do_setrule (void) +{ + SIGNED_QUAD width, height; + + height = get_buffered_signed_quad(); + width = get_buffered_signed_quad(); + if (width > 0 && height > 0) { + dvi_rule(width, height); + } + dvi_right(width); +} + +static void +do_putrule (void) +{ + SIGNED_QUAD width, height; + + height = get_buffered_signed_quad (); + width = get_buffered_signed_quad (); + if (width > 0 && height > 0) { + dvi_rule(width, height); + } +} + +static void +do_put1 (void) +{ + dvi_put(get_buffered_unsigned_byte()); +} + +static void +do_put2 (void) +{ + dvi_put(get_buffered_unsigned_pair()); +} + +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: vertical */ +} + + +static void +do_right1 (void) +{ + dvi_right(get_buffered_signed_byte()); +} + +static void +do_right2 (void) +{ + dvi_right(get_buffered_signed_pair()); +} + +static void +do_right3 (void) +{ + dvi_right(get_buffered_signed_triple()); +} + +static void +do_right4 (void) +{ + dvi_right(get_buffered_signed_quad()); +} + +void +dvi_w (SIGNED_QUAD ch) +{ + dvi_state.w = ch; + dvi_right(ch); +} + +void +dvi_w0 (void) +{ + dvi_right(dvi_state.w); +} + +static void +do_w1 (void) +{ + dvi_w(get_buffered_signed_byte()); +} + +static void +do_w2 (void) +{ + dvi_w(get_buffered_signed_pair()); +} + +static void +do_w3 (void) +{ + dvi_w(get_buffered_signed_triple()); +} + +static void +do_w4 (void) +{ + dvi_w(get_buffered_signed_quad()); +} + +void +dvi_x (SIGNED_QUAD ch) +{ + dvi_state.x = ch; + dvi_right(ch); +} + +void +dvi_x0 (void) +{ + dvi_right(dvi_state.x); +} + +static void +do_x1 (void) +{ + dvi_x(get_buffered_signed_byte()); +} + +static void +do_x2 (void) +{ + dvi_x(get_buffered_signed_pair()); +} + +static void +do_x3 (void) +{ + dvi_x(get_buffered_signed_triple()); +} + +static void +do_x4 (void) +{ + dvi_x(get_buffered_signed_quad()); +} + +static void +do_down1 (void) +{ + dvi_down(get_buffered_signed_byte()); +} + +static void +do_down2 (void) +{ + dvi_down(get_buffered_signed_pair()); +} + +static void +do_down3 (void) +{ + dvi_down(get_buffered_signed_triple()); +} + +static void +do_down4 (void) +{ + dvi_down(get_buffered_signed_quad()); +} + +void +dvi_y (SIGNED_QUAD ch) +{ + dvi_state.y = ch; + dvi_down(ch); +} + +void +dvi_y0 (void) +{ + dvi_down(dvi_state.y); +} + +static +void do_y1 (void) +{ + dvi_y(get_buffered_signed_byte()); +} + +static +void do_y2 (void) +{ + dvi_y(get_buffered_signed_pair()); +} + +static +void do_y3 (void) +{ + dvi_y(get_buffered_signed_triple()); +} + +static +void do_y4 (void) +{ + dvi_y(get_buffered_signed_quad()); +} + +void +dvi_z (SIGNED_QUAD ch) +{ + dvi_state.z = ch; + dvi_down(ch); +} + +void +dvi_z0 (void) +{ + dvi_down(dvi_state.z); +} + +static void +do_z1 (void) +{ + dvi_z(get_buffered_signed_byte()); +} + +static void +do_z2 (void) +{ + dvi_z(get_buffered_signed_pair()); +} + +static void +do_z3 (void) +{ + dvi_z(get_buffered_signed_triple()); +} + +static void +do_z4 (void) +{ + dvi_z(get_buffered_signed_quad()); +} + +static void +skip_fntdef (void) +{ + int area_len, name_len, i; + + get_signed_quad(dvi_file); + get_signed_quad(dvi_file); + get_signed_quad(dvi_file); + area_len = get_unsigned_byte(dvi_file); + name_len = get_unsigned_byte(dvi_file); + for (i = 0; i < area_len + name_len; i++) { + get_unsigned_byte(dvi_file); + } +} + +static void +do_fntdef1 (int scanning) +{ + if (scanning) { + /* when pre-scanning the page, we process fntdef and don't buffer it */ + SIGNED_QUAD tex_id = get_unsigned_byte(dvi_file); + if (linear) { + read_font_record(tex_id); + } + else { + skip_fntdef(); + } + --dvi_page_buf_index; /* remove the fntdef opcode from the buffer */ + } +} + +static void +do_fntdef2 (int scanning) +{ + if (scanning) { + SIGNED_QUAD tex_id = get_unsigned_pair(dvi_file); + if (linear) { + read_font_record(tex_id); + } + else { + skip_fntdef(); + } + --dvi_page_buf_index; + } +} + +static void +do_fntdef3 (int scanning) +{ + if (scanning) { + SIGNED_QUAD tex_id = get_unsigned_triple(dvi_file); + if (linear) { + read_font_record(tex_id); + } + else { + skip_fntdef(); + } + --dvi_page_buf_index; + } +} + +static void +do_fntdef4 (int scanning) +{ + if (scanning) { + SIGNED_QUAD tex_id = get_signed_quad(dvi_file); + 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 (SIGNED_QUAD 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=%ld", tex_id); + } + + if (!def_fonts[i].used) { + int font_id; + +#ifdef XETEX + if (def_fonts[i].native) { + font_id = dvi_locate_native_font(def_fonts[i].font_name, + 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; +#else + font_id = dvi_locate_font(def_fonts[i].font_name, def_fonts[i].point_size); +#endif + 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_fnt1 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_buffered_unsigned_byte(); + do_fnt(tex_id); +} + +static void +do_fnt2 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_buffered_unsigned_pair(); + do_fnt(tex_id); +} + +static void +do_fnt3 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_buffered_unsigned_triple(); + do_fnt(tex_id); +} + +static void +do_fnt4 (void) +{ + SIGNED_QUAD tex_id; + + tex_id = get_buffered_signed_quad(); + do_fnt(tex_id); +} + +static void +do_xxx (UNSIGNED_QUAD size) +{ +#if 0 + UNSIGNED_QUAD i; + Ubyte *buffer; /* FIXME - no need for new buffer here */ + + buffer = NEW(size+1, Ubyte); + for (i = 0; i < size; i++) { + buffer[i] = get_buffered_unsigned_byte(); + } + dvi_do_special(buffer, size); + RELEASE(buffer); +#else + dvi_do_special(dvi_page_buffer + dvi_page_buf_index, size); + dvi_page_buf_index += size; +#endif +} + +static void +do_xxx1 (void) +{ + SIGNED_QUAD size; + + size = get_buffered_unsigned_byte(); + do_xxx(size); +} + +static void +do_xxx2 (void) +{ + SIGNED_QUAD size; + + size = get_buffered_unsigned_pair(); + do_xxx(size); +} + +static void +do_xxx3 (void) +{ + SIGNED_QUAD size; + + size = get_buffered_unsigned_triple(); + do_xxx(size); +} + +static void +do_xxx4 (void) +{ + SIGNED_QUAD size; + + size = get_buffered_unsigned_quad(); + do_xxx(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++) { + get_buffered_signed_quad(); + } + /* Ignore previous page pointer since we have already + * saved this information + */ + get_buffered_signed_quad(); + 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() ? 1 : 0; + pdf_dev_set_dirmode(dvi_state.d); /* 0: horizontal, 1: vertical */ +} + +#ifdef XETEX +static void +do_native_font_def (int scanning) +{ + if (scanning) { + SIGNED_QUAD tex_id = get_signed_quad(dvi_file); + if (linear) { + read_native_font_record(tex_id); + } else { + UNSIGNED_PAIR flags; + int name_length, nvars, i; + + get_unsigned_quad(dvi_file); /* skip point size */ + flags = get_unsigned_pair(dvi_file); + name_length = (int) get_unsigned_byte(dvi_file); + name_length += (int) get_unsigned_byte(dvi_file); + name_length += (int) get_unsigned_byte(dvi_file); + for (i = 0; i < name_length; ++i) + get_unsigned_byte(dvi_file); + if (flags & XDV_FLAG_COLORED) { + get_unsigned_quad(dvi_file); + } + if (flags & XDV_FLAG_VARIATIONS) { + nvars = get_unsigned_pair(dvi_file); + for (i = 0; i < nvars * 2; ++i) + get_unsigned_quad(dvi_file); /* skip axis and value for each variation setting */ + } + } + --dvi_page_buf_index; /* don't buffer the opcode */ + } +} + +static void +do_glyph_array (int yLocsPresent) +{ + struct loaded_font *font; + spt_t width, height, depth, *xloc, *yloc, glyph_width = 0; + unsigned char wbuf[2]; + unsigned int i, glyph_id, slen = 0; + + if (current_font < 0) + ERROR("No font selected!"); + + font = &loaded_fonts[current_font]; + + width = get_buffered_signed_quad(); + + 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] = yLocsPresent ? get_buffered_signed_quad() : 0; + } + + if (font->rgba_color != 0xffffffff) { + 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); + } + + for (i = 0; i < slen; i++) { + glyph_id = get_buffered_unsigned_pair(); /* freetype glyph index */ + if (glyph_id < font->ft_face->num_glyphs) { + FT_Error error; + FT_Fixed advance; + int flags = FT_LOAD_NO_SCALE; + + if (font->layout_dir == 1) + flags |= FT_LOAD_VERTICAL_LAYOUT; + + error = FT_Get_Advance(font->ft_face, glyph_id, flags, &advance); + if (error) + advance = 0; + + glyph_width = (double)font->size * (double)advance / (double)font->ft_face->units_per_EM; + glyph_width = glyph_width * font->extend; + if (compute_boxes && link_annot && marked_depth >= tagged_depth) { + pdf_rect rect; + height = (double)font->size * (double)font->ft_face->ascender / (double)font->ft_face->units_per_EM; + depth = (double)font->size * -(double)font->ft_face->descender / (double)font->ft_face->units_per_EM; + pdf_dev_set_rect(&rect, dvi_state.h + xloc[i], -dvi_state.v - yloc[i], glyph_width, height, depth); + pdf_doc_expand_box(&rect); + } + } + + wbuf[0] = glyph_id >> 8; + wbuf[1] = glyph_id & 0xff; + pdf_dev_set_string(dvi_state.h + xloc[i], -dvi_state.v - yloc[i], wbuf, 2, + glyph_width, font->font_id, -1); + } + + if (font->rgba_color != 0xffffffff) { + pdf_color_pop(); + } + RELEASE(xloc); + RELEASE(yloc); + + if (!dvi_state.d) { + dvi_state.h += width; + } else { + dvi_state.v += width; + } + + return; +} + +static void +do_pic_file(void) + /* parameters for XDV_PIC_FILE opcode: pdf_box[1] t[4][6] p[2] len[2] path[l] */ +{ + int page_no; + UNSIGNED_PAIR len; + char *path; + int i; + int xobj_id; + transform_info ti; + + transform_info_clear(&ti); + + /* pdf_box = */ get_buffered_unsigned_byte(); + + ti.matrix.a = get_buffered_signed_quad() / 65536.0; /* convert 16.16 Fixed to floating-point */ + ti.matrix.b = get_buffered_signed_quad() / 65536.0; + ti.matrix.c = get_buffered_signed_quad() / 65536.0; + ti.matrix.d = get_buffered_signed_quad() / 65536.0; + ti.matrix.e = get_buffered_signed_quad() / 65536.0; + ti.matrix.f = get_buffered_signed_quad() / 65536.0; + + page_no = get_buffered_signed_pair(); + len = get_buffered_unsigned_pair(); + path = NEW(len + 1, char); + for (i = 0; i < len; ++i) + path[i] = get_buffered_unsigned_byte(); + path[len] = 0; + + /* + now we need to place page /page_no/ of the graphic file from /path/, applying /transform/ + if pdf_box=0 the file is a raster image (.jpg, .png, .tif, etc; need to determine format + by examining the file) + else it is a PDF document, pdf_box tells which PDF box (media, trim, crop, etc) to use + page_no is currently only used with PDF documents, though in theory could be used + with multi-page TIFFs, etc + transform is a 3x2 affine transform matrix expressed in fixed-point values + */ + + xobj_id = pdf_ximage_findresource(path, page_no, NULL); + if (xobj_id >= 0) { + /* FIXME: this seems to work for 72dpi JPEGs, but isn't right for others; + need to take the actual image resolution into account in pdf_dev_put_image, + not just assume the "original" size is 100dpi + */ + pdf_dev_put_image(xobj_id, &ti, dvi_dev_xpos(), dvi_dev_ypos()); + } + + RELEASE(path); +} +#endif + +/* Note to be absolutely certain that the string escape buffer doesn't + * hit its limit, FORMAT_BUF_SIZE should set to 4 times S_BUFFER_SIZE + * in pdfobj.c. Is there any application that genenerate words with + * 1k characters? + */ + +#define SBUF_SIZE 1024 + +/* Most of the work of actually interpreting + * the dvi file is here. + */ +void +dvi_do_page (long n, + double paper_width, double paper_height, + double hmargin, double vmargin) +{ + unsigned char opcode; + unsigned char sbuf[SBUF_SIZE]; + unsigned int slen = 0; + + /* 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 = paper_height - vmargin; + + dvi_stack_depth = 0; + for (;;) { + /* The most likely opcodes are individual setchars. + * These are buffered for speed. */ + slen = 0; + while ((opcode = get_buffered_unsigned_byte()) <= SET_CHAR_127 && + slen < SBUF_SIZE) { + sbuf[slen++] = opcode; + } + if (slen > 0) { + do_string(sbuf, slen); + } + if (slen == SBUF_SIZE) + 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: do_set1(); break; + case SET2: do_set2(); break; + case SET3: case SET4: + ERROR("Multibyte (>16 bits) character not supported!"); + break; + + case SET_RULE: + do_setrule(); + break; + + case PUT1: do_put1(); break; + case PUT2: do_put2(); break; + case PUT3: case PUT4: + ERROR ("Multibyte character (>16 bits) not supported!"); + break; + + case PUT_RULE: + do_putrule(); + break; + + case NOP: + break; + + case BOP: + do_bop(); + MESG("[%d", n+1); + break; + case EOP: + do_eop(); + MESG("]"); + return; + break; + + case PUSH: + dvi_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(); + /* Above explanation holds for following line too */ + dvi_mark_depth(); + break; + + case RIGHT1: do_right1(); break; + case RIGHT2: do_right2(); break; + case RIGHT3: do_right3(); break; + case RIGHT4: do_right4(); break; + + case W0: dvi_w0(); break; + case W1: do_w1 (); break; + case W2: do_w2 (); break; + case W3: do_w3 (); break; + case W4: do_w4 (); break; + + case X0: dvi_x0(); break; + case X1: do_x1 (); break; + case X2: do_x2 (); break; + case X3: do_x3 (); break; + case X4: do_x4 (); break; + + case DOWN1: do_down1(); break; + case DOWN2: do_down2(); break; + case DOWN3: do_down3(); break; + case DOWN4: do_down4(); break; + + case Y0: dvi_y0(); break; + case Y1: do_y1 (); break; + case Y2: do_y2 (); break; + case Y3: do_y3 (); break; + case Y4: do_y4 (); break; + + case Z0: dvi_z0(); break; + case Z1: do_z1 (); break; + case Z2: do_z2 (); break; + case Z3: do_z3 (); break; + case Z4: do_z4 (); break; + + case FNT1: do_fnt1(); break; + case FNT2: do_fnt2(); break; + case FNT3: do_fnt3(); break; + case FNT4: do_fnt4(); break; + + /* Specials */ + case XXX1: do_xxx1(); break; + case XXX2: do_xxx2(); break; + case XXX3: do_xxx3(); break; + case XXX4: do_xxx4(); break; + + /* Font definition - skipped except in linear mode. */ + /* actually, these should not occur! */ + case FNT_DEF1: do_fntdef1(0); break; + case FNT_DEF2: do_fntdef2(0); break; + case FNT_DEF3: do_fntdef3(0); break; + case FNT_DEF4: do_fntdef4(0); break; + + /* pTeX extension */ + case PTEXDIR: + do_dir(); + break; + +#ifdef XETEX + /* XeTeX extension */ + case XDV_GLYPH_STRING: + do_glyph_array(0); + break; + case XDV_GLYPH_ARRAY: + do_glyph_array(1); + break; + case XDV_NATIVE_FONT_DEF: + do_native_font_def(0); /* should not occur - processed during pre-scanning */ + break; + case XDV_PIC_FILE: + do_pic_file(); + break; +#endif + 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"); + } + } +} + +#ifdef WIN32 +#define STR_CMP strcasecmp +#else +#define STR_CMP strcmp +#endif + +double +dvi_init (char *dvi_filename, double mag) +{ + long post_location; + + if (dvi_filename == NULL) { /* no filename: reading from stdin, probably a pipe */ +#ifdef WIN32 + setmode(fileno(stdin), _O_BINARY); +#endif + dvi_file = stdin; + linear = 1; + + get_preamble_dvi_info(); + do_scales(mag); + } + else { + dvi_file = MFOPEN(dvi_filename, FOPEN_RBIN_MODE); + if (!dvi_file) { + char *p; + p = strrchr(dvi_filename, '.'); +#ifdef XETEX + if (p == NULL || (STR_CMP(p, ".dvi") && STR_CMP(p, ".xdv"))) { +#else + if (p == NULL || STR_CMP(p, ".dvi")) { +#endif +#ifdef XETEX + strcat(dvi_filename, ".xdv"); + dvi_file = MFOPEN(dvi_filename, FOPEN_RBIN_MODE); + if (!dvi_file) { + dvi_filename[strlen(dvi_filename) - 4] = '\0'; +#endif + strcat(dvi_filename, ".dvi"); + dvi_file = MFOPEN(dvi_filename, FOPEN_RBIN_MODE); +#ifdef XETEX + } +#endif + } + } + if (!dvi_file) { +#ifdef XETEX + ERROR("Could not open specified DVI (or XDV) file: %s", dvi_filename); +#else + ERROR("Could not open specified DVI file: %s", dvi_filename); +#endif + 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; + + 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" + +/* This need to allow 'true' prefix for unit and + * length value must be divided by current magnification. + */ +static int +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 + "pt", "in", "cm", "mm", "bp", + 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; + 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; +} + + +static int +scan_special (double *wd, double *ht, double *xo, double *yo, char *lm, + unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw, + const char *buf, UNSIGNED_QUAD size) +{ + char *q; + const char *p = buf, *endptr; + int ns_pdf = 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); + } + } + 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 = read_length(&tmp, dvi_tell_mag(), &p, endptr); + if (!error) + *wd = tmp * dvi_tell_mag(); + } else if (!strcmp(kp, "height")) { + error = read_length(&tmp, dvi_tell_mag(), &p, endptr); + if (!error) + *ht = tmp * dvi_tell_mag(); + } else if (!strcmp(kp, "xoffset")) { + error = read_length(&tmp, dvi_tell_mag(), &p, endptr); + if (!error) + *xo = tmp * dvi_tell_mag(); + } else if (!strcmp(kp, "yoffset")) { + error = 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 = read_length(&tmp, dvi_tell_mag(), &p, endptr); + if (!error) { + *wd = tmp * dvi_tell_mag(); + skip_white(&p, endptr); + if (p < endptr && *p == ',') { + p++; skip_white(&p, endptr); + } + error = read_length(&tmp, dvi_tell_mag(), &p, endptr); + if (!error) + *ht = tmp * dvi_tell_mag(); + 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 = (unsigned)strtol(kv, NULL, 10); + RELEASE(kv); + } + } else if (ns_pdf && !strcmp(q, "encrypt") && do_enc) { + *do_enc = 1; + *owner_pw = *user_pw = 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))) { + strncpy(owner_pw, pdf_string_value(obj), MAX_PWD_LEN); + pdf_release_obj(obj); + } else + error = -1; + } else if (!strcmp(kp, "userpw")) { + if ((obj = parse_pdf_string(&p, endptr))) { + strncpy(user_pw, pdf_string_value(obj), MAX_PWD_LEN); + 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); + } + } + RELEASE(q); + } + + return error; +} + + +void +dvi_scan_specials (long page_no, + double *page_width, double *page_height, + double *x_offset, double *y_offset, char *landscape, + unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw) +{ + FILE *fp = dvi_file; + long offset; + unsigned char opcode; + static long buffered_page = -1; + + if (page_no == buffered_page) + 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]; + + seek_absolute(fp, offset); + } + + 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) { + UNSIGNED_QUAD size = 0UL; + switch (opcode) { + case XXX1: size = get_and_buffer_unsigned_byte(fp); break; + case XXX2: size = get_and_buffer_unsigned_pair(fp); break; + case XXX3: size = get_and_buffer_unsigned_triple(fp); break; + case XXX4: size = get_and_buffer_unsigned_quad(fp); 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); + } + if (fread(dvi_page_buffer + dvi_page_buf_index, sizeof(char), size, fp) != size) + ERROR("Reading DVI file failed!"); + if (scan_special(page_width, page_height, x_offset, y_offset, landscape, minorversion, + do_enc, key_bits, permission, owner_pw, user_pw, + (char*)dvi_page_buffer + dvi_page_buf_index, size)) + WARN("Reading special command failed: \"%.*s\"", size, (char*)dvi_page_buffer + dvi_page_buf_index); + 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_unsigned_byte(fp); + break; + + case SET2: case PUT2: case RIGHT2: case DOWN2: + case W2: case X2: case Y2: case Z2: case FNT2: + get_and_buffer_signed_pair(fp); + break; + + case SET3: case PUT3: case RIGHT3: case DOWN3: + case W3: case X3: case Y3: case Z3: case FNT3: + get_and_buffer_signed_triple(fp); + break; + + case SET4: case PUT4: case RIGHT4: case DOWN4: + case W4: case X4: case Y4: case Z4: case FNT4: + get_and_buffer_signed_quad(fp); + break; + + case SET_RULE: case PUT_RULE: + get_and_buffer_bytes(fp, 8); + break; + + case FNT_DEF1: do_fntdef1(1); break; + case FNT_DEF2: do_fntdef2(1); break; + case FNT_DEF3: do_fntdef3(1); break; + case FNT_DEF4: do_fntdef4(1); break; + +#ifdef XETEX + case XDV_GLYPH_STRING: + { + UNSIGNED_PAIR count; + get_and_buffer_unsigned_quad(fp); /* width */ + count = get_and_buffer_unsigned_pair(fp); /* glyph count */ + get_and_buffer_bytes(fp, count * 6); /* 2 bytes ID + 4 bytes x-location per glyph */ + } + break; + case XDV_GLYPH_ARRAY: + { + UNSIGNED_PAIR count; + get_and_buffer_unsigned_quad(fp); /* width */ + count = get_and_buffer_unsigned_pair(fp); /* glyph count */ + get_and_buffer_bytes(fp, count * 10); /* 2 bytes ID + 8 bytes x,y-location per glyph */ + } + break; + case XDV_NATIVE_FONT_DEF: + do_native_font_def(1); + break; + case XDV_PIC_FILE: + /* params: flags[1] t[4][6] p[2] len[2] path[l] */ + { + UNSIGNED_PAIR len; + get_and_buffer_bytes(fp, 1 + 4 * 6 + 2); + len = get_and_buffer_unsigned_pair(fp); /* length of pathname */ + get_and_buffer_bytes(fp, len); + } + break; +#endif + case PTEXDIR: + get_and_buffer_unsigned_byte(fp); + 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; +} + diff --git a/Build/source/texk/dvipdf-x/xsrc/dvi.h b/Build/source/texk/dvipdf-x/xsrc/dvi.h new file mode 100644 index 00000000000..9801309730f --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/dvi.h @@ -0,0 +1,103 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 char landscape_mode; + +extern double get_origin (int x); + +extern void dvi_set_verbose (void); + +/* 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 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 (SIGNED_QUAD ch); +extern void dvi_rule (SIGNED_QUAD width, SIGNED_QUAD height); + +extern void dvi_right (SIGNED_QUAD x); +extern void dvi_put (SIGNED_QUAD ch); +extern void dvi_push (void); +extern void dvi_pop (void); +extern void dvi_w0 (void); +extern void dvi_w (SIGNED_QUAD ch); +extern void dvi_x0 (void); +extern void dvi_x (SIGNED_QUAD ch); +extern void dvi_down (SIGNED_QUAD y); +extern void dvi_y (SIGNED_QUAD ch); +extern void dvi_y0 (void); +extern void dvi_z (SIGNED_QUAD ch); +extern void dvi_z0 (void); +extern void dvi_dir (UNSIGNED_BYTE dir); + +extern void dvi_do_page (long page_no, + double paper_width, double paper_height, + double x_offset, double y_offset); +extern void dvi_scan_specials (long page_no, + double *width, double *height, + double *x_offset, double *y_offset, + char *landscape, unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw); +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); +/* 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, UNSIGNED_QUAD size); + +/* allow other modules (pdfdev) to ask whether we're collecting box areas */ +int dvi_is_tracking_boxes(void); + +#endif /* _DVI_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c b/Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c new file mode 100644 index 00000000000..ac97ed11198 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c @@ -0,0 +1,992 @@ +/* + + This is xdvipdfmx, an extended version of... + + DVIPDFMx, an eXtended-2013 version of DVIPDFM by Mark A. Wicks. + + Copyright (c) 2006 SIL. (xdvipdfmx extensions for XeTeX support) + + Copyright (C) 2008-2013 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the DVIPDFMx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "system.h" +#include "mem.h" + +#include "dpxconf.h" +#include "dpxfile.h" +#include "dpxutil.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 "xbb.h" + +#include "tt_aux.h" + +#include "error.h" + +static int verbose = 0; + +static int mp_mode = 0; + +static long opt_flags = 0; + +#define OPT_TPIC_TRANSPARENT_FILL (1 << 1) +#define OPT_CIDFONT_FIXEDPITCH (1 << 2) +#define OPT_FONTMAP_FIRST_MATCH (1 << 3) + +static char ignore_colors = 0; +static double annot_grow = 0.0; +static int bookmark_open = 0; +static double mag = 1.0; +static int font_dpi = 600; +static int really_quiet = 0; +/* + * Precision is essentially limited to 0.01pt. + * See, dev_set_string() in pdfdev.c. + */ +static int pdfdecimaldigits = 2; + +/* 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; + +/* Encryption */ +static int do_encryption = 0; +static unsigned key_bits = 40; +static unsigned permission = 0x003C; + +/* Page device */ +double paper_width = 595.0; /* not static, we allow dvi.c to access them */ +double paper_height = 842.0; +char landscape_mode = 0; + +static double x_offset = 72.0; +static double y_offset = 72.0; + +int always_embed = 0; /* always embed fonts, regardless of licensing flags */ + +char *dvi_filename = NULL, *pdf_filename = NULL; + +static void +read_config_file (const char *config); + +#ifdef WIN32 +#define STRN_CMP strncasecmp +#else +#define STRN_CMP strncmp +#endif + +static void +set_default_pdf_filename(void) +{ + const char *dvi_base; + + dvi_base = xbasename(dvi_filename); + if (mp_mode && + strlen(dvi_base) > 4 && + !STRN_CMP(".mps", dvi_base + strlen(dvi_base) - 4, 4)) { + pdf_filename = NEW(strlen(dvi_base)+1, char); + strncpy(pdf_filename, dvi_base, strlen(dvi_base) - 4); + pdf_filename[strlen(dvi_base)-4] = '\0'; + } else if (strlen(dvi_base) > 4 && +#ifdef XETEX + (!STRN_CMP(".dvi", dvi_base+strlen(dvi_base)-4, 4) || + !STRN_CMP(".xdv", dvi_base+strlen(dvi_base)-4, 4))) { +#else + !STRN_CMP(".dvi", dvi_base+strlen(dvi_base)-4, 4)) { +#endif + pdf_filename = NEW(strlen(dvi_base)+1, char); + strncpy(pdf_filename, dvi_base, strlen(dvi_base)-4); + pdf_filename[strlen(dvi_base)-4] = '\0'; + } else { + pdf_filename = NEW(strlen(dvi_base)+5, char); + strcpy(pdf_filename, dvi_base); + } + + strcat (pdf_filename, ".pdf"); +} + +static void +usage (int exit_code) +{ + fprintf (stdout, "\nThis is %s-%s by Jonathan Kew and Jin-Hwan Cho,\n", PACKAGE, VERSION); + fprintf (stdout, "an extended version of DVIPDFMx, which in turn was\n"); + fprintf (stdout, "an extended version of dvipdfm-0.13.2c developed by Mark A. Wicks.\n"); + fprintf (stdout, "\nCopyright (c) 2006-2013 SIL International and Jin-Hwan Cho.\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"); + fprintf (stdout, "\nUsage: xdvipdfmx [options] xdvfile\n"); + fprintf (stdout, "-c \t\tIgnore color specials (for B&W printing)\n"); + fprintf (stdout, "-d number\tSet PDF decimal digits (0-5) [2]\n"); + fprintf (stdout, "-f filename\tSet font map file name [cid-x.map]\n"); + fprintf (stdout, "-g dimension\tAnnotation \"grow\" amount [0.0in]\n"); + fprintf (stdout, "-h \t\tShow this help message\n"); + fprintf (stdout, "-l \t\tLandscape mode\n"); + fprintf (stdout, "-m number\tSet additional magnification\n"); + fprintf (stdout, "-o filename\tSet output file name [dvifile.pdf]\n"); + fprintf (stdout, "-p papersize\tSet papersize [a4]\n"); + fprintf (stdout, "-q \t\tBe quiet\n"); + fprintf (stdout, "-r resolution\tSet resolution (in DPI) for raster fonts [600]\n"); + fprintf (stdout, "-s pages\tSelect page ranges (-)\n"); + fprintf (stdout, "-t \t\tEmbed thumbnail images of PNG format [dvifile.1] \n"); + fprintf (stdout, "-x dimension\tSet horizontal offset [1.0in]\n"); + fprintf (stdout, "-y dimension\tSet vertical offset [1.0in]\n"); + fprintf (stdout, "-z number \tSet zlib compression level (0-9) [9]\n"); + + fprintf (stdout, "-v \t\tBe verbose\n"); + fprintf (stdout, "-vv\t\tBe more verbose\n"); + fprintf (stdout, "-C number\tSpecify miscellaneous option flags [0]:\n"); + fprintf (stdout, "\t\t 0x0001 reserved\n"); + fprintf (stdout, "\t\t 0x0002 Use semi-transparent filling for tpic shading command,\n"); + fprintf (stdout, "\t\t\t instead of opaque gray color. (requires PDF 1.4)\n"); + fprintf (stdout, "\t\t 0x0004 Treat all CIDFont as fixed-pitch font.\n"); + fprintf (stdout, "\t\t 0x0008 Do not replace duplicate fontmap entries.\n"); + fprintf (stdout, "\t\tPositive values are always ORed with previously given flags.\n"); + fprintf (stdout, "\t\tAnd negative values replace old values.\n"); + fprintf (stdout, "-D template\tPS->PDF conversion command line template [none]\n"); + fprintf (stdout, "-E \t\tAlways try to embed fonts, regardless of licensing flags.\n"); + fprintf (stdout, "-I number\tImage cache life in hours [-2]\n"); + fprintf (stdout, " \t 0: erase all old images and leave new images\n"); + fprintf (stdout, " \t-1: erase all old images and also erase new images\n"); + fprintf (stdout, " \t-2: ignore image cache\n"); + fprintf (stdout, "-K number\tEncryption key length [40]\n"); + fprintf (stdout, "-O number\tSet maximum depth of open bookmark items [0]\n"); + fprintf (stdout, "-P number\tSet permission flags for PDF encryption [0x003C]\n"); + fprintf (stdout, "-S \t\tEnable PDF encryption\n"); + fprintf (stdout, "-V number\tSet PDF minor version [4]\n"); + fprintf (stdout, "\nAll dimensions entered on the command line are \"true\" TeX dimensions.\n"); + fprintf (stdout, "Argument of \"-s\" lists physical page ranges separated by commas, e.g., \"-s 1-3,5-6\"\n"); + fprintf (stdout, "Papersize is specified by paper format (e.g., \"a4\") or by w,h (e.g., \"20cm,30cm\").\n"); + + exit(exit_code); +} + + +static int +read_length (double *vp, 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 + "pt", "in", "cm", "mm", "bp", + 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; + if (strlen(q) >= strlen("true") && + !memcmp(q, "true", strlen("true"))) { + q += strlen("true"); /* just skip "true" */ + } + if (strlen(q) == 0) { + 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; + 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; +} + +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 = read_length(&paper_width, &p, comma); + p = comma + 1; + error = read_length(&paper_height, &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 +{ + long 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(*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(*p); p++); + + if (*p == '-') { + for (++p; *p && isspace(*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(*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(*p); p++); + if (*p) + ERROR("Bad page range specification: %s", p); + } + } + return; +} + +#define POP_ARG() {argv += 1; argc -= 1;} +/* It doesn't work as expected (due to dvi filename). */ +#define CHECK_ARG(n,m) if (argc < (n) + 1) {\ + fprintf (stderr, "\nMissing %s after \"-%c\".\n", (m), *flag);\ + usage(1);\ +} + +static void +set_verbose (int argc, char *argv[]) +{ + while (argc > 0 && *argv[0] == '-') { + char *flag; + + for (flag = argv[0] + 1; *flag != 0; flag++) { + if (*flag == 'q') + really_quiet++; + if (*flag == 'v') + verbose++; + } + POP_ARG(); + } + + if (!really_quiet) { + int i; + + for (i = 0; i < verbose; i++) { + dvi_set_verbose(); + pdf_dev_set_verbose(); + pdf_doc_set_verbose(); + pdf_enc_set_verbose(); + pdf_obj_set_verbose(); + pdf_fontmap_set_verbose(); + dpx_file_set_verbose(); + } + } +} + + +static void +do_args (int argc, char *argv[]) +{ + while (argc > 0 && *argv[0] == '-') { + char *flag, *nextptr; + const char *nnextptr; + + for (flag = argv[0] + 1; *flag != 0; flag++) { + switch (*flag) { + case 'D': + CHECK_ARG(1, "PS->PDF conversion command line template"); + set_distiller_template(argv[1]); + POP_ARG(); + break; + case 'r': + CHECK_ARG(1, "bitmap font dpi"); + font_dpi = atoi(argv[1]); + if (font_dpi <= 0) + ERROR("Invalid bitmap font dpi specified: %s", argv[1]); + POP_ARG(); + break; + case 'm': + CHECK_ARG(1, "magnification value"); + mag = strtod(argv[1], &nextptr); + if (mag < 0.0 || nextptr == argv[1]) + ERROR("Invalid magnification specifiied: %s", argv[1]); + POP_ARG(); + break; + case 'g': + CHECK_ARG(1, "annotation \"grow\" amount"); + nnextptr = nextptr = argv[1]; + read_length(&annot_grow, &nnextptr, nextptr + strlen(nextptr)); + POP_ARG(); + break; + case 'x': + CHECK_ARG(1, "horizontal offset value"); + nnextptr = nextptr = argv[1]; + read_length(&x_offset, &nnextptr, nextptr + strlen(nextptr)); + POP_ARG(); + break; + case 'y': + CHECK_ARG(1, "vertical offset value"); + nnextptr = nextptr = argv[1]; + read_length(&y_offset, &nnextptr, nextptr + strlen(nextptr)); + POP_ARG(); + break; + case 'o': + CHECK_ARG(1, "output file name"); + pdf_filename = NEW (strlen(argv[1])+1,char); + strcpy(pdf_filename, argv[1]); + POP_ARG(); + break; + case 's': + CHECK_ARG(1, "page selection specification"); + select_pages(argv[1]); + POP_ARG(); + break; + case 't': + pdf_doc_enable_manual_thumbnails(); + break; + case 'p': + CHECK_ARG(1, "paper format/size"); + select_paper(argv[1]); + POP_ARG(); + break; + case 'c': + ignore_colors = 1; + break; + case 'l': + landscape_mode = 1; + break; + case 'f': + CHECK_ARG(1, "fontmap file name"); + if (opt_flags & OPT_FONTMAP_FIRST_MATCH) + pdf_load_fontmap_file(argv[1], FONTMAP_RMODE_APPEND); + else + pdf_load_fontmap_file(argv[1], FONTMAP_RMODE_REPLACE); + POP_ARG(); + break; + case 'i': + CHECK_ARG(1, "subsidiary config file"); + read_config_file(argv[1]); + POP_ARG(); + break; + case 'e': + WARN("dvipdfm \"-e\" option not supported."); + break; + case 'q': case 'v': + break; + case 'V': + { + int ver_minor; + + if (isdigit(*(flag+1))) { + flag++; + ver_minor = atoi(flag); + } else { + CHECK_ARG(1, "PDF minor version number"); + ver_minor = atoi(argv[1]); + POP_ARG(); + } + if (ver_minor < PDF_VERSION_MIN) { + WARN("PDF version 1.%d not supported. Using PDF 1.%d instead.", + ver_minor, PDF_VERSION_MIN); + ver_minor = PDF_VERSION_MIN; + } else if (ver_minor > PDF_VERSION_MAX) { + WARN("PDF version 1.%d not supported. Using PDF 1.%d instead.", + ver_minor, PDF_VERSION_MAX); + ver_minor = PDF_VERSION_MAX; + } + pdf_set_version((unsigned) ver_minor); + } + break; + case 'z': + { + int level; + + if (isdigit(*(flag+1))) { + flag++; + level = atoi(flag); + } else { + CHECK_ARG(1, "compression level"); + level = atoi(argv[1]); + POP_ARG(); + } + pdf_set_compression(level); + } + break; + case 'd': + if (isdigit(*(flag+1))) { + flag++; + pdfdecimaldigits = atoi(flag); + } else { + CHECK_ARG(1, "number of fractional digits"); + pdfdecimaldigits = atoi(argv[1]); + POP_ARG(); + } + break; + case 'I': + CHECK_ARG(1, "image cache life in hours"); + image_cache_life = atoi(argv[1]); + POP_ARG(); + break; + case 'S': + do_encryption = 1; + break; + case 'K': + CHECK_ARG(1, "encryption key length"); + key_bits = (unsigned) atoi(argv[1]); + if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7)) + ERROR("Invalid encryption key length specified: %s", argv[1]); + POP_ARG(); + break; + case 'P': + CHECK_ARG(1, "encryption permission flag"); + permission = (unsigned) strtoul(argv[1], &nextptr, 0); + if (nextptr == argv[1]) + ERROR("Invalid encryption permission flag: %s", argv[1]); + POP_ARG(); + break; + case 'O': + /* Bookmark open level */ + CHECK_ARG(1, "bookmark open level"); + bookmark_open = atoi(argv[1]); + POP_ARG(); + break; + case 'M': + mp_mode = 1; + break; + case 'C': + CHECK_ARG(1, "a number"); + { + long flags; + + flags = (unsigned) strtol(argv[1], &nextptr, 0); + if (nextptr == argv[1]) + ERROR("Invalid flag: %s", argv[1]); + if (flags < 0) + opt_flags = -flags; + else + opt_flags |= flags; + } + POP_ARG(); + break; + case 'E': + always_embed = 1; + break; + case 'h': + usage(0); + break; + default: + fprintf (stderr, "Unknown option in \"%s\"", flag); + usage(1); + break; + } + } + POP_ARG(); + } + + if (argc > 1) { + fprintf(stderr, "Multiple dvi filenames?"); + usage(1); + } else if (argc > 0) { + /* + * The only legitimate way to have argc == 0 here is + * do_args was called from config file. In that case, there is + * no dvi file name. Check for that case . + */ + dvi_filename = NEW(strlen(argv[0]) + 5, char); /* space to append .dvi */ + strcpy(dvi_filename, argv[0]); + } +} + +static void +cleanup (void) +{ + if (dvi_filename) + RELEASE(dvi_filename); + if (pdf_filename) + RELEASE(pdf_filename); + if (page_ranges) + RELEASE(page_ranges); +} + +static void +read_config_file (const char *config) +{ + const char *start, *end; + char *option; + FILE *fp; + + fp = DPXFOPEN(config, DPX_RES_TYPE_TEXT); + if (!fp) { + WARN("Could not open config file \"%s\".", config); + return; + } + while ((start = mfgets (work_buffer, WORK_BUFFER_SIZE, fp)) != NULL) { + char *argv[2]; + int argc; + + argc = 0; + 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 = 1; + argv[0] = NEW (strlen(option)+2, char); + strcpy (argv[0]+1, option); + RELEASE (option); + *argv[0] = '-'; + skip_white (&start, end); + if (start < end) { + argc += 1; + if (*start == '"') { + argv[1] = parse_c_string (&start, end); + } + else + argv[1] = parse_ident (&start, end); + } + } + do_args (argc, argv); + while (argc > 0) { + RELEASE (argv[--argc]); + } + } + if (fp) + MFCLOSE(fp); +} + +static void +system_default (void) +{ + if (systempapername() != NULL) { + select_paper(systempapername()); + } else if (defaultpapername() != NULL) { + select_paper(defaultpapername()); + } +} + +void +error_cleanup (void) +{ + pdf_error_cleanup(); + if (pdf_filename) { + remove(pdf_filename); + fprintf(stderr, "\nOutput file removed.\n"); + } +} + +#define SWAP(v1,v2) do {\ + double _tmp = (v1);\ + (v1) = (v2);\ + (v2) = _tmp;\ + } while (0) + +static void +do_dvi_pages (void) +{ + long 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() > 0; 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() > 0) { + if (page_no < dvi_npages()) { + double w, h, xo, yo; + char lm; + + /* Users want to change page size even after page is started! */ + 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, NULL, NULL, NULL, NULL, NULL, NULL); + if (lm != landscape_mode) { + SWAP(w, h); + landscape_mode = lm; + } + 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_no, + page_width, page_height, x_offset, y_offset); + page_count++; + } + + 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++) { + if (page_ranges[i].last < 0) + ERROR("Invalid page number for MPS input: -1"); + + step = (page_ranges[i].first <= page_ranges[i].last) ? 1 : -1; + page_no = page_ranges[i].first; + for (;;) { + sprintf(filename, "%s.%d", dvi_filename, page_no + 1); + fp = MFOPEN(filename, FOPEN_RBIN_MODE); + if (fp) { + MESG("[%d<%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); + } +} + + +/* TODO: MetaPost mode */ +#if defined(MIKTEX) +# define main Main +#endif +int CDECL +main (int argc, char *argv[]) +{ + double dvi2pts; + + const char *av0 = xbasename(argv[0]); + if (STRN_CMP(av0, "ebb", 3) == 0) + return extractbb(argc, argv, EBB_OUTPUT); + else if (STRN_CMP(av0, "xbb", 3) == 0 || STRN_CMP(av0, "extractbb", 9) == 0) + return extractbb(argc, argv, XBB_OUTPUT); + +#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 (); +#endif +#endif + + paperinit(); + system_default(); + + argv+=1; + argc-=1; + + set_verbose(argc, argv); + + pdf_init_fontmaps(); /* This must come before parsing options... */ + + read_config_file(DPX_CONFIG_FILE); + + do_args (argc, argv); + + if (really_quiet) + shut_up(really_quiet); + +#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); + dpx_delete_old_cache(image_cache_life); + + if (dvi_filename == NULL) { + if (verbose) + MESG("No dvi filename specified, reading standard input.\n"); + if (pdf_filename == NULL) + if (verbose) + MESG("No pdf filename specified, writing to standard output.\n"); + } + + if (pdf_filename == NULL && dvi_filename != NULL) + set_default_pdf_filename(); + + pdf_enc_compute_id_string(dvi_filename, pdf_filename); + if (do_encryption) { + pdf_enc_set_passwd(key_bits, permission, NULL, NULL); + if (key_bits > 40 && pdf_get_version() < 4) + pdf_set_version(4); + } + + if (mp_mode) { + x_offset = 0.0; + y_offset = 0.0; + dvi2pts = 0.01; /* dvi2pts controls accuracy. */ + } else { + unsigned ver_minor = 0; + char owner_pw[MAX_PWD_LEN], user_pw[MAX_PWD_LEN]; + /* Dependency between DVI and PDF side is rather complicated... */ + dvi2pts = dvi_init(dvi_filename, mag); + if (dvi2pts == 0.0) + ERROR("dvi_init() failed!"); + + pdf_doc_set_creator(dvi_comment()); + + if (do_encryption) + /* command line takes precedence */ + dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, + &ver_minor, NULL, NULL, NULL, NULL, NULL); + else { + dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, + &ver_minor, &do_encryption, &key_bits, &permission, owner_pw, user_pw); + if (do_encryption) { + if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7)) + ERROR("Invalid encryption key length specified: %u", key_bits); + else if (key_bits > 40 && pdf_get_version() < 4) + ERROR("Chosen key length requires at least PDF 1.4. " + "Use \"-V 4\" to change."); + do_encryption = 1; + pdf_enc_set_passwd(key_bits, permission, owner_pw, user_pw); + } + } + if (ver_minor >= PDF_VERSION_MIN && ver_minor <= PDF_VERSION_MAX) { + pdf_set_version(ver_minor); + } + if (landscape_mode) { + SWAP(paper_width, paper_height); + } + } + + MESG("%s -> %s\n", dvi_filename == NULL ? "stdin" : dvi_filename, + pdf_filename == NULL ? "stdout" : pdf_filename); + + pdf_files_init(); + + /* 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. + */ + pdf_open_document(pdf_filename, do_encryption, + paper_width, paper_height, annot_grow, bookmark_open); + + /* Ignore_colors placed here since + * they are considered as device's capacity. + */ + pdf_init_device(dvi2pts, pdfdecimaldigits, ignore_colors); + + 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 (mp_mode) { + do_mps_pages(); + } else { + do_dvi_pages(); + } + + pdf_files_close(); + + /* Order of close... */ + pdf_close_device (); + /* pdf_close_document flushes XObject (image) and other resources. */ + pdf_close_document(); + + pdf_close_fontmaps(); /* pdf_font may depend on fontmap. */ + + if (!mp_mode) + dvi_close(); + + MESG("\n"); + cleanup(); + + paperdone(); +#ifdef MIKTEX + miktex_uninitialize (); +#endif + + return 0; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/epdf.c b/Build/source/texk/dvipdf-x/xsrc/epdf.c new file mode 100644 index 00000000000..73a8ec21f63 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/epdf.c @@ -0,0 +1,906 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 ... + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "mfileio.h" +#include "error.h" + +#include "pdfobj.h" +#include "pdfdev.h" +#include "pdfdraw.h" +#include "pdfparse.h" + +#include "pdfximage.h" + +#include "pdfdoc.h" + +#include "epdf.h" + +#if HAVE_ZLIB +#include +static int add_stream_flate (pdf_obj *dst, const void *data, long len); +#endif +static int concat_stream (pdf_obj *dst, pdf_obj *src); + +static int rect_equal (pdf_obj *rect1, pdf_obj *rect2); + +/* + * 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. + */ + +static int +rect_equal (pdf_obj *rect1, pdf_obj *rect2) +{ + int i; + + if (!rect1 || !rect2) + return 0; + for (i = 0; i < 4; i++) { + if (pdf_number_value(pdf_get_array(rect1, i)) != + pdf_number_value(pdf_get_array(rect2, i))) + return 0; + } + + return 1; +} + +static pdf_obj* +pdf_get_page_obj (pdf_file *pf, long page_no, + pdf_obj **ret_bbox, pdf_obj **ret_resources) +{ + pdf_obj *page_tree; + pdf_obj *bbox = NULL, *resources = NULL, *rotate = NULL; + long page_idx; + + /* + * Get Page Tree. + */ + page_tree = NULL; + { + pdf_obj *trailer, *catalog; + pdf_obj *markinfo, *tmp; + + trailer = pdf_file_get_trailer(pf); + + if (pdf_lookup_dict(trailer, "Encrypt")) { + WARN("This PDF document is encrypted."); + pdf_release_obj(trailer); + return NULL; + } + + catalog = pdf_deref_obj(pdf_lookup_dict(trailer, "Root")); + if (!PDF_OBJ_DICTTYPE(catalog)) { + WARN("Can't read document catalog."); + pdf_release_obj(trailer); + if (catalog) + pdf_release_obj(catalog); + return NULL; + } + pdf_release_obj(trailer); + + markinfo = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo")); + if (markinfo) { + tmp = pdf_lookup_dict(markinfo, "Marked"); + if (PDF_OBJ_BOOLEANTYPE(tmp) && pdf_boolean_value(tmp)) + WARN("File contains tagged PDF. Ignoring tags."); + pdf_release_obj(markinfo); + } + + page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages")); + pdf_release_obj(catalog); + } + if (!page_tree) { + WARN("Page tree not found."); + return NULL; + } + + /* + * Negative page numbers are counted from the back. + */ + { + long count = pdf_number_value(pdf_lookup_dict(page_tree, "Count")); + page_idx = page_no + (page_no >= 0 ? -1 : count); + if (page_idx < 0 || page_idx >= count) { + WARN("Page %ld does not exist.", page_no); + pdf_release_obj(page_tree); + return NULL; + } + page_no = page_idx+1; + } + + /* + * Seek correct page. Get Media/Crop Box. + * Media box and resources can be inherited. + */ + { + pdf_obj *kids_ref, *kids; + pdf_obj *crop_box = NULL; + pdf_obj *tmp; + + tmp = pdf_lookup_dict(page_tree, "Resources"); + resources = tmp ? pdf_deref_obj(tmp) : pdf_new_dict(); + + while (1) { + long kids_length, i; + + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "MediaBox")))) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "BleedBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "TrimBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "ArtBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(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, "Rotate")))) { + if (rotate) + pdf_release_obj(rotate); + rotate = tmp; + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Resources")))) { +#if 0 + pdf_merge_dict(tmp, resources); +#endif + if (resources) + pdf_release_obj(resources); + resources = tmp; + } + + kids_ref = pdf_lookup_dict(page_tree, "Kids"); + if (!kids_ref) + break; + kids = pdf_deref_obj(kids_ref); + kids_length = pdf_array_length(kids); + + for (i = 0; i < kids_length; i++) { + long count; + + pdf_release_obj(page_tree); + page_tree = pdf_deref_obj(pdf_get_array(kids, i)); + + tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count")); + if (tmp) { + /* Pages object */ + count = pdf_number_value(tmp); + pdf_release_obj(tmp); + } else + /* Page object */ + count = 1; + + if (page_idx < count) + break; + + page_idx -= count; + } + + pdf_release_obj(kids); + + if (i == kids_length) { + WARN("Page %ld not found! Broken PDF file?", page_no); + if (bbox) + pdf_release_obj(bbox); + if (crop_box) + pdf_release_obj(crop_box); + if (rotate) + pdf_release_obj(rotate); + pdf_release_obj(resources); + pdf_release_obj(page_tree); + return NULL; + } + } + if (crop_box) { + pdf_release_obj(bbox); + bbox = crop_box; + } + } + + if (!bbox) { + WARN("No BoundingBox information available."); + pdf_release_obj(page_tree); + pdf_release_obj(resources); + if (rotate) + pdf_release_obj(rotate); + return NULL; + } + + if (rotate) { + if (pdf_number_value(rotate) != 0.0) + WARN("<< /Rotate %d >> found. (Not supported yet)", (int)pdf_number_value(rotate)); + pdf_release_obj(rotate); + rotate = NULL; + } + + if (ret_bbox != NULL) + *ret_bbox = bbox; + if (ret_resources != NULL) + *ret_resources = resources; + + return page_tree; +} + +static pdf_obj* +pdf_get_page_content (pdf_obj* page) +{ + pdf_obj *contents, *content_new; + + contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents")); + if (!contents) + return NULL; + + if (pdf_obj_typeof(contents) == PDF_NULL) { + /* 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 idx = 0; + content_new = pdf_new_stream(STREAM_COMPRESS); + for (;;) { + content_seg = pdf_deref_obj(pdf_get_array(contents, idx)); + if (!content_seg) + break; + else if (PDF_OBJ_NULLTYPE(content_seg)) { + /* Silently ignore. */ + } else if (!PDF_OBJ_STREAMTYPE(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; + } else if (concat_stream(content_new, content_seg) < 0) { + WARN("Could not handle content stream with multiple segments."); + pdf_release_obj(content_seg); + pdf_release_obj(content_new); + pdf_release_obj(contents); + return NULL; + } + pdf_release_obj(content_seg); + idx++; + } + 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); + if (concat_stream(content_new, contents) < 0) { + WARN("Could not handle a content stream."); + pdf_release_obj(contents); + pdf_release_obj(content_new); + return NULL; + } + pdf_release_obj(contents); + contents = content_new; + } + + return contents; +} + +int +pdf_include_page (pdf_ximage *ximage, FILE *image_file) +{ + xform_info info; + pdf_obj *contents, *contents_dict; + pdf_obj *page_tree; + pdf_obj *matrix; + pdf_obj *bbox = NULL, *resources = NULL; + long page_no; + pdf_file *pf; + char *ident = pdf_ximage_get_ident(ximage); + + pdf_ximage_init_form_info(&info); + + pf = pdf_open(ident, image_file); + if (!pf) + return -1; + + /* + * Get Page Tree. + */ + page_no = pdf_ximage_get_page(ximage); + if (page_no == 0) + page_no = 1; + + page_tree = pdf_get_page_obj(pf, page_no, &bbox, &resources); + if (page_tree == NULL) { + pdf_close(pf); + return -1; + } + + if (bbox != NULL) { + pdf_obj *tmp; + + tmp = pdf_deref_obj(pdf_get_array(bbox, 0)); + info.bbox.llx = pdf_number_value(tmp); + pdf_release_obj(tmp); + tmp = pdf_deref_obj(pdf_get_array(bbox, 1)); + info.bbox.lly = pdf_number_value(tmp); + pdf_release_obj(tmp); + tmp = pdf_deref_obj(pdf_get_array(bbox, 2)); + info.bbox.urx = pdf_number_value(tmp); + pdf_release_obj(tmp); + tmp = pdf_deref_obj(pdf_get_array(bbox, 3)); + info.bbox.ury = pdf_number_value(tmp); + pdf_release_obj(tmp); + } + + /* + * Handle page content stream. + * page_tree is now set to the correct page. + */ + contents = pdf_get_page_content(page_tree); + pdf_release_obj(page_tree); + if (contents == NULL) { + pdf_close(pf); + return -1; + } + + { + pdf_obj *tmp; + + tmp = pdf_import_object(resources); + pdf_release_obj(resources); + resources = tmp; + tmp = pdf_import_object(bbox); + pdf_release_obj(bbox); + bbox = tmp; + } + + pdf_close(pf); + + 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)); + + pdf_add_dict(contents_dict, pdf_new_name("BBox"), bbox); + + matrix = pdf_new_array(); + pdf_add_array(matrix, pdf_new_number(1.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(1.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + + pdf_add_dict(contents_dict, pdf_new_name("Matrix"), matrix); + + pdf_add_dict(contents_dict, pdf_new_name("Resources"), resources); + + pdf_ximage_set_form(ximage, &info, contents); + + return 0; +} + +typedef enum { + OP_SETCOLOR = 1, + OP_CLOSEandCLIP = 2, + OP_CLIP = 3, + OP_CONCATMATRIX = 4, + OP_SETCOLORSPACE = 5, + OP_RECTANGLE = 6, + OP_CURVETO = 7, + OP_CLOSEPATH = 8, + OP_LINETO = 9, + OP_MOVETO = 10, + OP_NOOP = 11, + OP_GSAVE = 12, + OP_GRESTORE = 13, + OP_CURVETO1 = 14, + OP_CURVETO2 = 15, + OP_UNKNOWN = 16 +} pdf_opcode; + +static struct operator +{ + const char *token; + int opcode; +} pdf_operators[] = { + {"SCN", OP_SETCOLOR}, + {"b*", OP_CLOSEandCLIP}, + {"B*", OP_CLIP}, + {"cm", OP_CONCATMATRIX}, + {"CS", OP_SETCOLORSPACE}, + {"f*", 0}, + {"gs", -1}, + {"re", OP_RECTANGLE}, + {"rg", -3}, + {"RG", -3}, + {"sc", OP_SETCOLOR}, + {"SC", OP_SETCOLOR}, + {"W*", OP_CLIP}, + {"b", OP_CLOSEandCLIP}, + {"B", OP_CLIP}, + {"c", OP_CURVETO}, + {"d", -2}, + {"f", 0}, + {"F", 0}, + {"g", -1}, + {"G", -1}, + {"h", OP_CLOSEPATH}, + {"i", -1}, + {"j", -1}, + {"J", -1}, + {"k", -4}, + {"K", -4}, + {"l", OP_LINETO}, + {"m", OP_MOVETO}, + {"M", -1}, + {"n", OP_NOOP}, + {"q", OP_GSAVE}, + {"Q", OP_GRESTORE}, + {"s", OP_CLOSEandCLIP}, + {"S", OP_CLIP}, + {"v", OP_CURVETO1}, + {"w", -1}, + {"W", OP_CLIP}, + {"y", OP_CURVETO2} +}; + + +int +pdf_copy_clip (FILE *image_file, int pageNo, double x_user, double y_user) +{ + pdf_obj *page_tree, *contents; + int depth = 0, top = -1; + const char *clip_path, *end_path; + char *save_path, *temp; + pdf_tmatrix M; + double stack[6]; + pdf_file *pf; + + 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_get_page_obj (pf, pageNo, NULL, NULL); + if (!page_tree) { + pdf_close(pf); + return -1; + } + + contents = pdf_get_page_content(page_tree); + pdf_release_obj(page_tree); + if (!contents) { + pdf_close(pf); + return -1; + } + + pdf_doc_add_page_content(" ", 1); + + save_path = malloc(pdf_stream_length(contents) + 1); + strncpy(save_path, (const char *) pdf_stream_dataptr(contents), pdf_stream_length(contents)); + clip_path = save_path; + end_path = clip_path + pdf_stream_length(contents); + depth = 0; + + for (; clip_path < end_path; clip_path++) { + int color_dimen = 0; /* silence uninitialized warning */ + char *token; + skip_white(&clip_path, end_path); + if (clip_path == end_path) + break; + if (depth > 1) { + if (*clip_path == 'q') + depth++; + if (*clip_path == 'Q') + depth--; + parse_ident(&clip_path, end_path); + continue; + } else if (*clip_path == '-' + || *clip_path == '+' + || *clip_path == '.' + || isdigit(*clip_path)) { + stack[++top] = strtod(clip_path, &temp); + clip_path = temp; + } else if (*clip_path == '[') { + /* Ignore, but put a dummy value on the stack (in case of d operator) */ + parse_pdf_array(&clip_path, end_path, pf); + stack[++top] = 0; + } else if (*clip_path == '/') { + if (strncmp("/DeviceGray", clip_path, 11) == 0 + || strncmp("/Indexed", clip_path, 8) == 0 + || strncmp("/CalGray", clip_path, 8) == 0) { + color_dimen = 1; + continue; + } + else if (strncmp("/DeviceRGB", clip_path, 10) == 0 + || strncmp("/CalRGB", clip_path, 7) == 0 + || strncmp("/Lab", clip_path, 4) == 0) { + color_dimen = 3; + continue; + } + else if (strncmp("/DeviceCMYK", clip_path, 11) == 0) { + color_dimen = 4; + continue; + } + else { + clip_path++; + parse_ident(&clip_path, end_path); + skip_white(&clip_path, end_path); + token = parse_ident(&clip_path, end_path); + if (strcmp(token, "gs") == 0) { + continue; + } + return -1; + } + } else { + int j; + pdf_tmatrix T; + pdf_coord p0, p1, p2, p3; + + token = parse_ident(&clip_path, end_path); + for (j = 0; j < sizeof(pdf_operators) / sizeof(pdf_operators[0]); j++) + if (strcmp(token, pdf_operators[j].token) == 0) + break; + if (j == sizeof(pdf_operators) / sizeof(pdf_operators[0])) { + return -1; + } + switch (pdf_operators[j].opcode) { + case 0: + case -1: + case -2: + case -3: + case -4: + /* Just pop the stack and do nothing. */ + top += pdf_operators[j].opcode; + if (top < -1) + return -1; + break; + case OP_SETCOLOR: + top -= color_dimen; + if (top < -1) + return -1; + break; + case OP_CLOSEandCLIP: + pdf_dev_closepath(); + case OP_CLIP: +#if 0 + pdf_dev_clip(); +#else + pdf_dev_flushpath('W', PDF_FILL_RULE_NONZERO); +#endif + break; + case OP_CONCATMATRIX: + if (top < 5) + return -1; + T.f = stack[top--]; + T.e = stack[top--]; + T.d = stack[top--]; + T.c = stack[top--]; + T.b = stack[top--]; + T.a = stack[top--]; + pdf_concatmatrix(&M, &T); + break; + case OP_SETCOLORSPACE: + /* Do nothing. */ + break; + case OP_RECTANGLE: + if (top < 3) + return -1; + p1.y = stack[top--]; + p1.x = stack[top--]; + p0.y = stack[top--]; + p0.x = stack[top--]; + if (M.b == 0 && M.c == 0) { + pdf_tmatrix M0; + M0.a = M.a; M0.b = M.b; M0.c = M.c; M0.d = M.d; + M0.e = 0; M0.f = 0; + pdf_dev_transform(&p0, &M); + pdf_dev_transform(&p1, &M0); + pdf_dev_rectadd(p0.x, p0.y, p1.x, p1.y); + } else { + p2.x = p0.x + p1.x; p2.y = p0.y + p1.y; + p3.x = p0.x; p3.y = p0.y + p1.y; + p1.x += p0.x; p1.y = p0.y; + pdf_dev_transform(&p0, &M); + pdf_dev_transform(&p1, &M); + pdf_dev_transform(&p2, &M); + pdf_dev_transform(&p3, &M); + pdf_dev_moveto(p0.x, p0.y); + pdf_dev_lineto(p1.x, p1.y); + pdf_dev_lineto(p2.x, p2.y); + pdf_dev_lineto(p3.x, p3.y); + pdf_dev_closepath(); + } + break; + case OP_CURVETO: + if (top < 5) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + p1.y = stack[top--]; + p1.x = stack[top--]; + pdf_dev_transform(&p1, &M); + p2.y = stack[top--]; + p2.x = stack[top--]; + pdf_dev_transform(&p2, &M); + pdf_dev_curveto(p2.x, p2.y, p1.x, p1.y, p0.x, p0.y); + break; + case OP_CLOSEPATH: + pdf_dev_closepath(); + break; + case OP_LINETO: + if (top < 1) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + pdf_dev_lineto(p0.x, p0.y); + break; + case OP_MOVETO: + if (top < 1) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + pdf_dev_moveto(p0.x, p0.y); + break; + case OP_NOOP: + pdf_doc_add_page_content(" n", 2); + break; + case OP_GSAVE: + depth++; + break; + case OP_GRESTORE: + depth--; + break; + case OP_CURVETO1: + if (top < 3) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + p1.y = stack[top--]; + p1.x = stack[top--]; + pdf_dev_transform(&p1, &M); + pdf_dev_vcurveto(p1.x, p1.y, p0.x, p0.y); + break; + case OP_CURVETO2: + if (top < 3) + return -1; + p0.y = stack[top--]; + p0.x = stack[top--]; + pdf_dev_transform(&p0, &M); + p1.y = stack[top--]; + p1.x = stack[top--]; + pdf_dev_transform(&p1, &M); + pdf_dev_ycurveto(p1.x, p1.y, p0.x, p0.y); + break; + default: + return -1; + } + } + } + free(save_path); + + pdf_release_obj(contents); + pdf_close(pf); + + return 0; +} + +#define WBUF_SIZE 4096 +#if HAVE_ZLIB +static int +add_stream_flate (pdf_obj *dst, const void *data, long len) +{ + z_stream z; + Bytef wbuf[WBUF_SIZE]; + + z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; + + z.next_in = (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 -1; + } + + for (;;) { + int status; + status = inflate(&z, Z_NO_FLUSH); + if (status == Z_STREAM_END) + break; + else if (status != Z_OK) { + WARN("inflate() failed. Broken PDF file?"); + inflateEnd(&z); + return -1; + } + + if (z.avail_out == 0) { + pdf_add_stream(dst, wbuf, WBUF_SIZE); + z.next_out = wbuf; + z.avail_out = WBUF_SIZE; + } + } + + if (WBUF_SIZE - z.avail_out > 0) + pdf_add_stream(dst, wbuf, WBUF_SIZE - z.avail_out); + + return (inflateEnd(&z) == Z_OK ? 0 : -1); +} +#endif + +static int +concat_stream (pdf_obj *dst, pdf_obj *src) +{ + const char *stream_data; + long stream_length; + pdf_obj *stream_dict; + pdf_obj *filter; + + if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src)) + ERROR("Invalid type."); + + stream_data = pdf_stream_dataptr(src); + stream_length = pdf_stream_length (src); + stream_dict = pdf_stream_dict (src); + + if (pdf_lookup_dict(stream_dict, "DecodeParms")) { + WARN("DecodeParams not supported."); + return -1; + } + + filter = pdf_lookup_dict(stream_dict, "Filter"); + if (!filter) { + pdf_add_stream(dst, stream_data, stream_length); + return 0; +#if HAVE_ZLIB + } else { + char *filter_name; + if (PDF_OBJ_NAMETYPE(filter)) { + filter_name = pdf_name_value(filter); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } else if (PDF_OBJ_ARRAYTYPE(filter)) { + if (pdf_array_length(filter) > 1) { + WARN("Multiple DecodeFilter not supported."); + return -1; + } else { + filter_name = pdf_name_value(pdf_get_array(filter, 0)); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } + } else + ERROR("Broken PDF file?"); +#endif /* HAVE_ZLIB */ + } + + return -1; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/epdf.h b/Build/source/texk/dvipdf-x/xsrc/epdf.h new file mode 100644 index 00000000000..698b5140b8e --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/epdf.h @@ -0,0 +1,41 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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, int page_index, int pdf_box); +extern int pdf_include_page (pdf_ximage *ximage, FILE *file); + +#endif /* _EPDF_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/error.c b/Build/source/texk/dvipdf-x/xsrc/error.c new file mode 100644 index 00000000000..d9070f5350b --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/error.c @@ -0,0 +1,92 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include +#include + +#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, "** WARNING ** "); + 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, "** ERROR ** "); + va_start(argp, fmt); + vfprintf(stderr, fmt, argp); + va_end(argp); + fprintf(stderr, "\n"); + } + error_cleanup(); + exit( 1 ); +} diff --git a/Build/source/texk/dvipdf-x/xsrc/error.h b/Build/source/texk/dvipdf-x/xsrc/error.h new file mode 100644 index 00000000000..a4dbb6bb39f --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/error.h @@ -0,0 +1,46 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); + +#define FATAL_ERROR -1 +#define NO_ERROR 0 + +#include +#include + +extern void shut_up (int quietness); + +extern void ERROR (const char *fmt, ...); +extern void MESG (const char *fmt, ...); +extern void WARN (const char *fmt, ...); + +#define ASSERT(e) assert(e) + +#endif /* _ERROR_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/fontmap.c b/Build/source/texk/dvipdf-x/xsrc/fontmap.c new file mode 100644 index 00000000000..044dea7d803 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/fontmap.c @@ -0,0 +1,1513 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "error.h" + +#include "dpxfile.h" +#include "dpxutil.h" + +#include "subfont.h" + +#include "fontmap.h" + +#ifdef XETEX +#include "ft2build.h" +#include FT_FREETYPE_H +#endif + +/* CIDFont */ +static char *strip_options (const char *map_name, fontmap_opt *opt); + +static int verbose = 0; +void +pdf_fontmap_set_verbose (void) +{ + verbose++; +} + + +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; /* deactivated */ + mrec->opt.index = 0; + mrec->opt.charcoll = NULL; + mrec->opt.style = FONTMAP_STYLE_NONE; + mrec->opt.stemv = -1; /* not given explicitly by an option */ + +#ifdef XETEX + mrec->opt.ft_face = NULL; +#endif +} + +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; + +#ifdef XETEX + dst->opt.ft_face = src->opt.ft_face; +#endif +} + + +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(*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]; + long 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 = atoi(q); + if (mrec->opt.index < 0) { + WARN("Invalid TTC index number: %s", q); + return -1; + } + 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; + + /* 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(*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; + break; + } + 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 (++p < endptr && *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; + break; + } + 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 (verbose > 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 (verbose > 3) + MESG("\n"); + + return 0; +} + +int +pdf_remove_fontmap_record (const char *kp) +{ + char *fnt_name, *sfd_name = NULL; + + if (!kp) + return -1; + + if (verbose > 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 (verbose > 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 (verbose > 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 (verbose > 3) + MESG("\n"); + + return 0; +} + +int +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 -1; + } + + if (verbose > 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); + return -1; + } + if (verbose > 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 (verbose > 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 (verbose > 3) + MESG("\n"); + + return 0; +} + + +int +pdf_read_fontmap_line (fontmap_rec *mrec, const char *mline, long 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; + long llen, lpos = 0; + int error = 0, format = 0; + + ASSERT(filename); + ASSERT(fontmap) ; + + if (verbose) + MESG(" 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 (verbose) + MESG(">"); + + return error; +} + +#ifdef XETEX +static int +pdf_insert_native_fontmap_record (const char *name, const char *path, int index, FT_Face face, + int layout_dir, int extend, int slant, int embolden) +{ + char *fontmap_key; + fontmap_rec *mrec; + + ASSERT(name); + ASSERT(path || face); + + fontmap_key = malloc(strlen(name) + 40); // CHECK + sprintf(fontmap_key, "%s/%c/%d/%d/%d", name, layout_dir == 0 ? 'H' : 'V', extend, slant, embolden); + + if (verbose) + MESG("map_name = fontmap_key; + mrec->enc_name = mstrdup(layout_dir == 0 ? "Identity-H" : "Identity-V"); + mrec->font_name = (path != NULL) ? mstrdup(path) : NULL; + mrec->opt.index = index; + mrec->opt.ft_face = face; + 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; + + pdf_insert_fontmap_record(mrec->map_name, mrec); + pdf_clear_fontmap_record(mrec); + RELEASE(mrec); + + if (verbose) + MESG(">"); + + return 0; +} + +static FT_Library ftLib; + +int +pdf_load_native_font (const char *ps_name, + int layout_dir, int extend, int slant, int embolden) +{ + const char *p; + char *filename = NEW(strlen(ps_name), char); + char *q = filename; + int index = 0; + FT_Face face = NULL; + int error = -1; + + if (ps_name[0] != '[') { + ERROR("Loading fonts by font name is not supported: %s", ps_name); + return error; + } + + if (FT_Init_FreeType(&ftLib) != 0) { + ERROR("FreeType initialization failed."); + return error; + } + +#ifdef WIN32 + for (p = ps_name + 1; *p && *p != ']'; ++p) { + if (*p == ':') { + if (p == ps_name+2 && isalpha(*(p-1)) && (*(p+1) == '/' || *(p+1) == '\\')) + *q++ = *p; + else + break; + } + else + *q++ = *p; + } +#else + for (p = ps_name + 1; *p && *p != ':' && *p != ']'; ++p) + *q++ = *p; +#endif + *q = 0; + if (*p == ':') { + ++p; + while (*p && *p != ']') + index = index * 10 + *p++ - '0'; + } + + /* try loading the filename directly */ + error = FT_New_Face(ftLib, filename, index, &face); + + /* if failed, try locating the file in the TEXMF tree */ + if ( error && + ( (q = dpx_find_opentype_file(filename)) != NULL + || (q = dpx_find_truetype_file(filename)) != NULL + || (q = dpx_find_type1_file(filename)) != NULL + || (q = dpx_find_dfont_file(filename)) != NULL) ) { + error = FT_New_Face(ftLib, q, index, &face); + RELEASE(q); + } + + if (error == 0) + error = pdf_insert_native_fontmap_record(ps_name, filename, index, face, + layout_dir, extend, slant, embolden); + RELEASE(filename); + return error; +} +#endif /* XETEX */ + +#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 +#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(*(p+1))) { + opt->index = (int) 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, " \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, "\n"); + fprintf(stdout, "\n"); + fprintf(stdout, "\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, "\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/dvipdf-x/xsrc/fontmap.h b/Build/source/texk/dvipdf-x/xsrc/fontmap.h new file mode 100644 index 00000000000..fee6f238fa5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/fontmap.h @@ -0,0 +1,109 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +#ifdef XETEX +#include "ft2build.h" +#include FT_FREETYPE_H +#endif + +/* Options */ +typedef struct fontmap_opt { + /* Synthetic font */ + double slant, extend, bold; + /* comaptibility and other flags */ + long mapc, flags; + + char *otl_tags; /* currently unused */ + char *tounicode; /* not implemented yet */ + + double design_size; /* unused */ + + char *charcoll; /* Adobe-Japan1-4, etc. */ + int index; /* TTC index */ + int style; /* ,Bold, etc. */ + int stemv; /* StemV value especially for CJK fonts */ +#ifdef XETEX + FT_Face ft_face; +#endif +} 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_fontmap_set_verbose (void); + +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, long 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 int 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); + +#ifdef XETEX +extern int pdf_load_native_font (const char *ps_name, + int layout_dir, int extend, int slant, int embolden); +#endif + +#endif /* _FONTMAP_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/jpegimage.c b/Build/source/texk/dvipdf-x/xsrc/jpegimage.c new file mode 100644 index 00000000000..75d6607c2a0 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/jpegimage.c @@ -0,0 +1,916 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + + +#if 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 "pdfobj.h" + +#include "jpegimage.h" +#include "pdfcolor.h" + +#include "pdfximage.h" + +#define JPEG_DEBUG_STR "JPEG" +#define JPEG_DEBUG 3 + +#ifdef HAVE_LIBJPEG +#include +#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 +} JPEG_APPn_sig; + +struct JPEG_APPn_JFIF /* APP0 */ +{ + unsigned short version; + unsigned char units; /* 0: only aspect ratio + * 1: dots per inch + * 2: dots per cm + */ + unsigned short Xdensity; + unsigned short Ydensity; + unsigned char Xthumbnail; + unsigned char Ythumbnail; + unsigned char *thumbnail; /* Thumbnail data. */ +}; + +struct JPEG_APPn_ICC /* APP2 */ +{ + unsigned char seq_id; + unsigned char num_chunks; + unsigned char *chunk; + + /* Length of ICC profile data in this chunk. */ + unsigned short length; +}; + +struct JPEG_APPn_Adobe /* APP14 */ +{ + unsigned short version; + unsigned short flag0; + unsigned short flag1; + unsigned char transform; /* color transform code */ +}; + +struct JPEG_ext +{ + JPEG_marker marker; + JPEG_APPn_sig app_sig; + void *app_data; +}; + +#define MAX_COUNT 1024 +struct JPEG_info +{ + unsigned short height; + unsigned short width; + + unsigned char bits_per_component; + unsigned char 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) + +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, int flags); /* flags unused yet */ + +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_iccp (struct JPEG_info *j_info); + +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")); + + colorspace = NULL; + if (j_info.flags & HAVE_APPn_ICC) { + pdf_obj *icc_stream, *intent; + + icc_stream = JPEG_get_iccp(&j_info); + + if (!icc_stream) + colorspace = NULL; + else { + int cspc_id; + + 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, 0); + + 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; + +#define IS_Exif(j) ((j).flags & HAVE_APPn_Exif) +#define IS_JFIF(j) ((j).flags & HAVE_APPn_JFIF) + + if (IS_Exif(j_info)) { /* resolution data from EXIF is handled here, + takes precedence over JFIF */ + info.xdensity = 72.0 / j_info.xdpi; + info.ydensity = 72.0 / j_info.ydpi; + } + else if (IS_JFIF(j_info)) { + int i; + for (i = 0; i < j_info.num_appn; i++) { + if (j_info.appn[i].marker == JM_APP0 && j_info.appn[i].app_sig == JS_APPn_JFIF) + break; + } + if (i < j_info.num_appn) { + struct JPEG_APPn_JFIF *app_data = (struct JPEG_APPn_JFIF *)j_info.appn[i].app_data; + switch (app_data->units) { + case 1: /* pixels per inch */ + info.xdensity = 72.0 / app_data->Xdensity; + info.ydensity = 72.0 / app_data->Ydensity; + break; + case 2: /* pixels per centimeter */ + info.xdensity = 72.0 / 2.54 / app_data->Xdensity; + info.ydensity = 72.0 / 2.54 / app_data->Ydensity; + break; + default: + break; + } + } + } + + pdf_ximage_set_image(ximage, &info, stream); + JPEG_info_clear(&j_info); + + return 0; +} + +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; + j_info->ydpi = 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); + } +} + +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 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; + } + } + + return -1; +} + +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, unsigned short length) +{ + 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; +} + +static unsigned long +read_exif_bytes(unsigned char **p, int n, int b) +{ + unsigned long rval = 0; + unsigned char *pp = *p; + if (b) { + switch (n) { + case 4: + rval += *pp++; rval <<= 8; + rval += *pp++; rval <<= 8; + case 2: + rval += *pp++; rval <<= 8; + rval += *pp; + break; + } + } + else { + pp += n; + switch (n) { + case 4: + rval += *--pp; rval <<= 8; + rval += *--pp; rval <<= 8; + case 2: + rval += *--pp; rval <<= 8; + rval += *--pp; + break; + } + } + *p += n; + return rval; +} + +static unsigned short +read_APP1_Exif (struct JPEG_info *j_info, FILE *fp, unsigned short 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, *rp; + unsigned char *tiff_header; + char bigendian; + int i; + int num_fields, tag, type; + int value = 0, num = 0, den = 0; /* silence uninitialized warnings */ + double xres = 72.0; + double yres = 72.0; + double res_unit = 1.0; + fread(buffer, length, 1, fp); + p = buffer; + while ((p < buffer + length) && (*p == 0)) + ++p; + tiff_header = p; + if ((*p == 'M') && (*(p+1) == 'M')) + bigendian = 1; + else if ((*p == 'I') && (*(p+1) == 'I')) + bigendian = 0; + else + goto err; + p += 2; + i = read_exif_bytes(&p, 2, bigendian); + if (i != 42) + goto err; + i = read_exif_bytes(&p, 4, bigendian); + p = tiff_header + i; + num_fields = read_exif_bytes(&p, 2, bigendian); + while (num_fields-- > 0) { + tag = read_exif_bytes(&p, 2, bigendian); + type = read_exif_bytes(&p, 2, bigendian); + read_exif_bytes(&p, 4, bigendian); + switch (type) { + case 1: /* byte */ + value = *p++; + p += 3; + break; + case 3: /* short */ + value = read_exif_bytes(&p, 2, bigendian); + p += 2; + break; + case 4: /* long */ + case 9: /* slong */ + value = read_exif_bytes(&p, 4, bigendian); + break; + case 5: /* rational */ + case 10: /* srational */ + value = read_exif_bytes(&p, 4, bigendian); + rp = tiff_header + value; + num = read_exif_bytes(&rp, 4, bigendian); + den = read_exif_bytes(&rp, 4, bigendian); + break; + case 7: /* undefined */ + value = *p++; + p += 3; + break; + case 2: /* ascii */ + default: + p += 4; + break; + } + switch (tag) { + case 282: /* x res */ + if (den != 0) + xres = num / den; + break; + case 283: /* y res */ + if (den != 0) + yres = num / den; + break; + case 296: /* res unit */ + switch (value) { + case 2: + res_unit = 1.0; + break; + case 3: + res_unit = 2.54; + break; + } + } + } + + j_info->xdpi = xres * res_unit; + j_info->ydpi = yres * res_unit; + +err: + RELEASE(buffer); + return length; +} + +static unsigned short +read_APP0_JFIF (struct JPEG_info *j_info, FILE *fp, unsigned short length) +{ + struct JPEG_APPn_JFIF *app_data; + unsigned short 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 * app_data->Ydensity / app_data->Xdensity; + break; + } + + return (9 + thumb_data_len); +} + +static unsigned short +read_APP0_JFXX (struct JPEG_info *j_info, FILE *fp, unsigned short 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 unsigned short +read_APP2_ICC (struct JPEG_info *j_info, FILE *fp, unsigned short 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, int flags) /* flags unused yet */ +{ + JPEG_marker marker; + long length, nb_read; + int found_SOFn, count; + + rewind(fp); + count = 0; + found_SOFn = 0; + while (!found_SOFn && + count < MAX_COUNT && + (marker = JPEG_get_marker(fp)) >= 0) { + 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); + count++; + continue; + } + 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); + while (length > 0) { + nb_read = fread(work_buffer, sizeof(char), + MIN(length, WORK_BUFFER_SIZE), fp); + if (nb_read > 0) + pdf_add_stream(stream, work_buffer, nb_read); + length -= nb_read; + } + found_SOFn = 1; + break; + default: + if (j_info->skipbits[count / 8] & (1 << (7 - (count % 8)))) { + /* skip */ + while (length > 0) { + nb_read = fread(work_buffer, sizeof(char), + MIN(length, WORK_BUFFER_SIZE), fp); + length -= nb_read; + } + } 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); + while (length > 0) { + nb_read = fread(work_buffer, sizeof(char), + MIN(length, WORK_BUFFER_SIZE), fp); + if (nb_read > 0) + pdf_add_stream(stream, work_buffer, nb_read); + length -= nb_read; + } + } + } + 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); +} + +static int +JPEG_scan_file (struct JPEG_info *j_info, FILE *fp) +{ + JPEG_marker marker; + unsigned short length; + int found_SOFn, count; + char app_sig[128]; + + rewind(fp); + count = 0; + found_SOFn = 0; + while (!found_SOFn && + (marker = JPEG_get_marker(fp)) >= 0) { + if (marker == JM_SOI || + (marker >= JM_RST0 && marker <= JM_RST7)) { + count++; + continue; + } + 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)) { + j_info->flags |= HAVE_APPn_JFIF; + length -= read_APP0_JFIF(j_info, fp, length); + } else if (!memcmp(app_sig, "JFXX", 5)) { + length -= read_APP0_JFXX(j_info, fp, length); + } + } + 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)) { + j_info->flags |= HAVE_APPn_Exif; + length -= read_APP1_Exif(j_info, fp, length); + } + } + 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); + if (count < MAX_COUNT) { + j_info->skipbits[count / 8] |= (1 << (7 - (count % 8))); + } + } + } + seek_relative(fp, length); + 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)) { + j_info->flags |= HAVE_APPn_ADOBE; + length -= read_APP14_Adobe(j_info, fp, length); + } else { + if (count < MAX_COUNT) { + j_info->skipbits[count/8] |= (1 << (7 - (count % 8))); + } + } + } + seek_relative(fp, length); + break; + default: + seek_relative(fp, length); + if (marker >= JM_APP0 && + marker <= JM_APP15) { + if (count < MAX_COUNT) { + j_info->skipbits[count / 8] |= (1 << (7 - (count % 8))); + } + } + break; + } + count++; + } + + return (found_SOFn ? 0 : -1); +} diff --git a/Build/source/texk/dvipdf-x/xsrc/jpegimage.h b/Build/source/texk/dvipdf-x/xsrc/jpegimage.h new file mode 100644 index 00000000000..5a3c9d86a3d --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/jpegimage.h @@ -0,0 +1,36 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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); + +#endif /* _JPEGIMAGE_H_ */ + + diff --git a/Build/source/texk/dvipdf-x/xsrc/mpost.c b/Build/source/texk/dvipdf-x/xsrc/mpost.c new file mode 100644 index 00000000000..dc56d7f4f47 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/mpost.c @@ -0,0 +1,1671 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "numbers.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" + +/* + * 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 + * + * gsave grestore ... + * + * can't be translated to PDF code + * + * q 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 = -1; + +#define CURRENT_FONT() ((currentfont < 0) ? NULL : &font_stack[currentfont]) + +/* 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(); + + if (font) { + if (!strcmp(font->font_name, font_name) && + font->pt_size == pt_size) + return 0; + } else { /* No currentfont */ +/* ***TODO*** Here some problem exists! */ + font = &font_stack[0]; + font->font_name = NULL; + currentfont = 0; + } + + 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; + + if (currentfont < 0) { + font_stack[0].font_name = NEW(strlen("Courier") + 1, char); + strcpy(font_stack[0].font_name, "Courier"); + font_stack[0].pt_size = 1; + font_stack[0].tfm_id = 0; + font_stack[0].subfont_id = 0; + currentfont = 0; + } + + current = &font_stack[currentfont++]; + next = &font_stack[currentfont ]; + next->font_name = NEW(strlen(current->font_name)+1, char); + strcpy(next->font_name, current->font_name); + next->pt_size = current->pt_size; + + next->subfont_id = current->subfont_id; + next->tfm_id = current->tfm_id; +} + +static void +restore_font (void) +{ + struct mp_font *current; + + current = CURRENT_FONT(); + if (current) { + if (current->font_name) + RELEASE(current->font_name); + current->font_name = NULL; + } else { + ERROR("No currentfont..."); + } + + currentfont--; +} + +static void +clear_fonts (void) +{ + while (currentfont >= 0) { + if (font_stack[currentfont].font_name) + RELEASE(font_stack[currentfont].font_name); + 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(**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 { + bbox->llx = values[0]; + bbox->lly = values[1]; + bbox->urx = values[2]; + bbox->ury = values[3]; + + return 0; + } + } + skip_line (pp, endptr); + while (*pp < endptr && isspace(**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; + skip_line(start, end); + break; + } else if (!strncmp(*start, "%%Page:", 7)) { + skip_line(start, end); + break; + } + skip_line(start, end); + } + if (!found_prolog) { + *start = save; + } + + return; +} + +/* PostScript Operators */ + +#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) { + 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) { + 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, 0); + 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, 0); + } + + 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); + 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_color(&color); + } + break; + case SETGRAY: + /* Not handled properly */ + error = pop_get_numbers(values, 1); + if (!error) { + pdf_color_graycolor(&color, values[0]); + pdf_dev_set_color(&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_color(&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(**start) || + (*start < end - 1 && + (**start == '+' || **start == '-' || **start == '.' ))) { + double value; + char *next; + + value = strtod(*start, &next); + if (next < end && !strchr("<([{/%", *next) && !isspace(*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; + long 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, 0.0, 0.0, &(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; + long 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, 0.0, 0.0); /* 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); +} + +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); +} diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfcolor.c b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.c new file mode 100644 index 00000000000..77c9c499ea5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.c @@ -0,0 +1,1530 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 "dpxfile.h" + +#include "pdfdoc.h" +#include "pdfdev.h" + +#include "pdfcolor.h" + + +static int verbose = 0; +void +pdf_color_set_verbose (void) +{ + verbose++; +} + +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->num_components = 3; + + 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->num_components = 4; + + 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->num_components = 1; + + return 0; +} + + +void +pdf_color_copycolor (pdf_color *color1, const pdf_color *color2) +{ + ASSERT(color1 && color2); + + memcpy(color1, color2, sizeof(pdf_color)); +} + +int +pdf_color_is_white (pdf_color *color) +{ + int is_white = 0; + + ASSERT(color); + + switch (color->num_components) { + case 1: + if (color->values[0] == 1.0) + is_white = 1; + break; + case 4: + if (color->values[0] == 0.0 && + color->values[1] == 0.0 && + color->values[2] == 0.0 && + color->values[3] == 0.0) { + is_white = 1; + } + break; + case 3: + if (color->values[0] == 1.0 && + color->values[1] == 1.0 && + color->values[2] == 1.0) { + is_white = 1; + } + break; + default: + is_white = 0; + break; + } + + return is_white; +} + +pdf_color current_fill = { + 1, + {0.0, 0.0, 0.0, 0.0} +}; + +pdf_color current_stroke = { + 1, + {0.0, 0.0, 0.0, 0.0} +}; + +#if 0 +/* + * This routine is not a real color matching. + */ +static int +compare_color (const pdf_color *color1, const pdf_color *color2) +{ + if (color1->num_components != color2->num_components) + return -1; + + switch (color1->num_components) { + case 4: + if (color1->values[0] == color2->values[0] && + color1->values[1] == color2->values[1] && + color1->values[2] == color2->values[2] && + color1->values[3] == color2->values[3]) + return 0; + break; + case 3: + if (color1->values[0] == color2->values[0] && + color1->values[1] == color2->values[1] && + color1->values[2] == color2->values[2]) + return 0; + break; + case 1: + if (color1->values[0] == color2->values[0]) + return 0; + break; + } + + return -1; +} +#endif + +int +pdf_color_is_valid (pdf_color *color) +{ + int i, num_components; + + num_components = color->num_components; + if (num_components != 1 && + num_components != 3 && + num_components != 4) { + ERROR("Only RGB/CMYK/Gray currently supported."); + return 0; + } + + for (i = 0; i < num_components; i++) { + if (color->values[i] < 0.0 || color->values[i] > 1.0) { + WARN("Invalid color value: %g", color->values[i]); + return 0; + } + } + return 1; +} + +/* Dvipdfm special */ +pdf_color default_color = { + 1, + {0.0, 0.0, 0.0, 0.0} +}; + +void +pdf_color_set_default (const pdf_color *color) +{ + pdf_color_copycolor(&default_color, color); +} + +#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."); + } + color_stack.current = 0; + pdf_color_copycolor(&color_stack.stroke[color_stack.current], &default_color); + pdf_color_copycolor(&color_stack.fill[color_stack.current], &default_color); + return; +} + +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_copycolor(&color_stack.stroke[color_stack.current], sc); + pdf_color_copycolor(&color_stack.fill[color_stack.current], fc); + pdf_dev_reset_color(); + } + 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(); + } + 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; +} + +/* 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]; + } +} + +/***************************** COLOR SPACE *****************************/ + +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); + +#if 0 +struct calgray_cdata +{ + double white_point[3]; /* required, second component must + * be equal to 1.0 + */ + double black_point[3]; /* optional, default: [0 0 0] */ + double gamma; /* optional, default: 1.0 */ +}; + +struct calrgb_cdata +{ + double white_point[3]; /* required, second component must + * be equal to 1.0 + */ + double black_point[3]; /* optional, default: [0 0 0] */ + double gamma[3]; /* optional, default: [1 1 1] */ + double matrix[9]; /* optional, default: identity + * [1 0 0 0 1 0 0 0 1] + */ +}; + +static void +release_calrgb (void *cdata) +{ + struct calrgb_cdata *calrgb; + + if (cdata) { + calrgb = (struct calrgb_cdata *) cdata; + RELEASE(calrgb); + } +} + +static int +compare_calrgb (const char *ident1, const void *cdata1, + const char *ident2, const void *cdata2) +{ + struct calrgb_cdata *calrgb1; + struct calrgb_cdata *calrgb2; + + if (ident1 && ident2 && + !strcmp(ident1, ident2)) { + return 0; + } +} + +static void +init_calrgb (struct calrgb_cdata *calrgb) +{ + ASSERT(calrgb); + + calrgb->white_point[0] = 1.0; + calrgb->white_point[1] = 1.0; + calrgb->white_point[2] = 1.0; + + calrgb->black_point[0] = 0.0; + calrgb->black_point[1] = 0.0; + calrgb->black_point[2] = 0.0; + + calrgb->gamma[0] = 1.0; + calrgb->gamma[1] = 1.0; + calrgb->gamma[2] = 1.0; + + calrgb->matrix[0] = 1.0; + calrgb->matrix[1] = 0.0; + calrgb->matrix[2] = 0.0; + + calrgb->matrix[3] = 0.0; + calrgb->matrix[4] = 1.0; + calrgb->matrix[5] = 0.0; + + calrgb->matrix[6] = 0.0; + calrgb->matrix[7] = 0.0; + calrgb->matrix[8] = 1.0; +} + +static int +valid_calrgb (struct calrgb_cdata *calrgb) +{ + if (calrgb->white_point[1] != 1.0 || + calrgb->white_point[0] <= 0.0 || + calrgb->white_point[2] <= 0.0) + return 0; + + if (calrgb->black_point[0] < 0.0 || + calrgb->black_point[1] < 0.0 || + calrgb->black_point[2] < 0.0) + return 0; + + if (calrgb->gamma[0] < 0.0 || + calrgb->gamma[1] < 0.0 || + calrgb->gamma[2] < 0.0) + return 0; + + /* matrix should be invertible? */ + + return 1; +} + +static pdf_obj * +pdf_color_make_calrgb_resource (struct calrgb_cdata *calrgb) +{ + pdf_obj *colorspace; + pdf_obj *calparams, *tmp_array; + + ASSERT(calrgb); + + if (!valid_calrgb(calrgb)) + return NULL; + + colorspace = pdf_new_array(); + calparams = pdf_new_dict(); + + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->white_point[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(1.0)); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->white_point[2], 0.001))); + pdf_add_dict(calparams, pdf_new_name("WhitePoint"), tmp_array); + + if (calrgb->black_point[0] != 0.0 || + calrgb->black_point[1] != 0.0 || + calrgb->black_point[2] != 0.0) { + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[1], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->black_point[2], 0.001))); + pdf_add_dict(calparams, pdf_new_name("BlackPoint"), tmp_array); + } + + if (calrgb->gamma[0] != 1.0 || + calrgb->gamma[1] != 1.0 || + calrgb->gamma[2] != 1.0) { + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[1], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->gamma[2], 0.001))); + pdf_add_dict(calparams, pdf_new_name("Gamma"), tmp_array); + } + + if (calrgb->matrix[0] != 1.0 || + calrgb->matrix[1] != 0.0 || + calrgb->matrix[2] != 0.0 || + calrgb->matrix[3] != 0.0 || + calrgb->matrix[4] != 1.0 || + calrgb->matrix[5] != 0.0 || + calrgb->matrix[6] != 0.0 || + calrgb->matrix[7] != 0.0 || + calrgb->matrix[8] != 1.0) { + tmp_array = pdf_new_array(); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[0], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[1], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[2], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[3], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[4], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[5], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[6], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[7], 0.001))); + pdf_add_array(tmp_array, pdf_new_number(ROUND(calrgb->matrix[8], 0.001))); + pdf_add_dict(calparams, pdf_new_name("Matrix"), tmp_array); + } + + pdf_add_array(colorspace, pdf_new_name("CalRGB")); + pdf_add_array(colorspace, calparams); + + return colorspace; +} +#endif + +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 */ +}; + +static int +iccp_version_supported (int major, int minor) +{ + int pdf_ver; + + pdf_ver = pdf_get_version(); + if (pdf_ver < 6) { + if (icc_versions[pdf_ver].major < major) + return 0; + else if (icc_versions[pdf_ver].major == major && + icc_versions[pdf_ver].minor < minor) + return 0; + else { + return 1; + } + } + + return 0; +} + +typedef unsigned long 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 +{ + long X, Y, Z; /* s15Fixed16Numeber */ +} iccXYZNumber; + +typedef struct +{ + long size; + iccSig CMMType; + long 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]; + long 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 +{ + long 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_CIELAB: + 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, long 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; + break; + } + + return 0; +} + +pdf_obj * +iccp_get_rendering_intent (const void *profile, long proflen) +{ + pdf_obj *ri = NULL; + const unsigned char *p; + long 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) ((long) ((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, long 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 %ld in ICC profile header.)", + *p, 128 - ((long) (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, long 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, long 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 (verbose) + MESG("(ICCP:[id=%d])", cspc_id); + release_iccbased_cdata(cdata); + return cspc_id; + } + if (verbose > 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; +} + +#define WBUF_SIZE 4096 +static unsigned char wbuf[WBUF_SIZE]; + +static pdf_obj * +iccp_load_file_stream (unsigned char *checksum, long length, FILE *fp) +{ + pdf_obj *stream; + MD5_CONTEXT md5; + long 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; + long 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 (verbose) + MESG("(ICCP:[id=%d])", cspc_id); + release_iccbased_cdata(cdata); + pdf_release_obj(stream); + return cspc_id; + } + if (verbose > 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; +} + +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 (verbose) { + MESG("(ColorSpace:%s", ident); + if (verbose > 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 /* 0 */ + +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/dvipdf-x/xsrc/pdfcolor.h b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.h new file mode 100644 index 00000000000..1d5e0f19116 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.h @@ -0,0 +1,102 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_DEVICECMYK -4 +#define PDF_COLORSPACE_TYPE_DEVICERGB -3 +#define PDF_COLORSPACE_TYPE_DEVICEGRAY -1 +#define PDF_COLORSPACE_TYPE_INVALID 0 +#define PDF_COLORSPACE_TYPE_CALGRAY 1 +#define PDF_COLORSPACE_TYPE_CIELAB 2 +#define PDF_COLORSPACE_TYPE_CALRGB 3 +#define PDF_COLORSPACE_TYPE_ICCBASED 4 + +#define PDF_COLORSPACE_TYPE_CMYK PDF_COLORSPACE_TYPE_DEVICECMYK +#define PDF_COLORSPACE_TYPE_RGB PDF_COLORSPACE_TYPE_DEVICERGB +#define PDF_COLORSPACE_TYPE_GRAY PDF_COLORSPACE_TYPE_DEVICEGRAY + + +#define PDF_COLOR_COMPONENT_MAX 4 + +typedef struct +{ + int num_components; + double values[PDF_COLOR_COMPONENT_MAX]; +} pdf_color; + +extern void pdf_color_set_verbose (void); + +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 void pdf_color_copycolor (pdf_color *color1, const pdf_color *color2); + +extern int pdf_color_is_white (pdf_color *color); +extern int pdf_color_is_valid (pdf_color *color); + +/* Not check size */ +extern pdf_obj *iccp_get_rendering_intent (const void *profile, long proflen); +extern int iccp_check_colorspace (int colortype, + const void *profile, long proflen); + +/* returns colorspace ID */ +extern int iccp_load_profile (const char *ident, + const void *profile, long 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); +#endif + +/* Not working */ +extern int pdf_colorspace_load_ICCBased (const char *ident, + const char *profile_filename); + +/* Color special + * See remark in spc_color.c. + */ +extern void pdf_color_set_default (const pdf_color *color); +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); + +/* Reinstall color */ +extern void pdf_dev_preserve_color(void); + +#endif /* _PDF_COLOR_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdev.c b/Build/source/texk/dvipdf-x/xsrc/pdfdev.c new file mode 100644 index 00000000000..41e6630c26e --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfdev.c @@ -0,0 +1,2000 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.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 "dvi.h" + +#include "pdfdev.h" + +static int verbose = 0; + +void +pdf_dev_set_verbose (void) +{ + verbose++; +} + +/* Not working yet... */ +double +pdf_dev_scale (void) +{ + return 1.0; +} + +/* + * Unit conversion, formatting and others. + */ + +#define TEX_ONE_HUNDRED_BP 6578176 +static struct { + double dvi2pts; + long min_bp_val; /* Shortest resolvable distance in the output PDF. */ + int precision; /* Number of decimal digits (in fractional part) kept. */ +} dev_unit = { + 0.0, + 658, + 2 +}; + + +double +dev_unit_dviunit (void) +{ + return (1.0/dev_unit.dvi2pts); +} + +#define DEV_PRECISION_MAX 8 +static unsigned long ten_pow[10] = { + 1ul, 10ul, 100ul, 1000ul, 10000ul, 100000ul, 1000000ul, 10000000ul, 100000000ul, 1000000000ul +}; + +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(b) ( (spt_t) round( (b) / dev_unit.dvi2pts ) ) +#define spt2bpt(s) ( (s) * dev_unit.dvi2pts ) +#define dround_at(v,p) (ROUND( (v), ten_pow_inv[(p)] )) + +static int +p_itoa (long 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); +} + +/* ... */ +static int +p_dtoa (double value, int prec, char *buf) +{ + int n; + char *p, *q; + + n = sprintf(buf, "%.*f", prec, value); + /* find decimal-point */ + for (p = buf + n - 1; p > buf && *p != '.'; p--); + if (p > buf) { + /* chop trailing zeros */ + for (q = buf + n - 1; q > p && *q == '0'; q--) { + *q = '\0'; n--; + } + /* If a decimal point appears, at least one digit appears + * before it. + */ + if (q == p) { + *q = '\0'; n--; + } + } + /* -0 --> 0 */ + if (n == 2 && buf[0] == '-' && buf[1] == '0') { + buf[0] = '0'; buf[1] = '\0'; n = 1; + } + + return n; +} + +static int +dev_sprint_bp (char *buf, spt_t value, spt_t *error) +{ + double value_in_bp; + double error_in_bp; + int prec = dev_unit.precision; + + value_in_bp = spt2bpt(value); + if (error) { + error_in_bp = value_in_bp - dround_at(value_in_bp, prec); + *error = bpt2spt(error_in_bp); + } + + return p_dtoa(value_in_bp, prec, buf); +} + +/* They are affected by precision (set at device initialization). */ +int +pdf_sprint_matrix (char *buf, const pdf_tmatrix *M) +{ + int len; + int prec2 = MIN(dev_unit.precision + 2, DEV_PRECISION_MAX); + int prec0 = MAX(dev_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; +} + +int +pdf_sprint_rect (char *buf, const pdf_rect *rect) +{ + int len; + + len = p_dtoa(rect->llx, dev_unit.precision, buf); + buf[len++] = ' '; + len += p_dtoa(rect->lly, dev_unit.precision, buf+len); + buf[len++] = ' '; + len += p_dtoa(rect->urx, dev_unit.precision, buf+len); + buf[len++] = ' '; + len += p_dtoa(rect->ury, dev_unit.precision, buf+len); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + +int +pdf_sprint_coord (char *buf, const pdf_coord *p) +{ + int len; + + len = p_dtoa(p->x, dev_unit.precision, buf); + buf[len++] = ' '; + len += p_dtoa(p->y, dev_unit.precision, buf+len); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + +int +pdf_sprint_length (char *buf, double value) +{ + int len; + + len = p_dtoa(value, dev_unit.precision, buf); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + + +int +pdf_sprint_number (char *buf, double value) +{ + int len; + + len = p_dtoa(value, DEV_PRECISION_MAX, buf); + buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */ + + return len; +} + + +static struct +{ + /* 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; + +} dev_param = { + 1, /* autorotate */ + 1, /* 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 + +static int motion_state = GRAPHICS_MODE; + +#define FORMAT_BUF_SIZE 4096 +static char format_buffer[FORMAT_BUF_SIZE]; + +/* + * 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. + * + * 00/11 WMODE_HH/VV h(v) font, h(v) direction. + * 01 WMODE_HV -90 deg. rotated + * 10 WMODE_VH +90 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 2 +#define TEXT_WMODE_VV 3 + +#define ANGLE_CHANGES(m1,m2) ((abs((m1)-(m2)) % 3) == 0 ? 0 : 1) +#define ROTATE_TEXT(m) ((m) != TEXT_WMODE_HH && (m) != TEXT_WMODE_VV) + +static struct { + + /* 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; +} text_state = { + -1, /* font */ + 0, /* offset */ + 0, 0, /* ref_x, ref_y */ + 0, 0, /* raise, leading */ + {0.0, 1.0, 0}, + + 0.0, /* Experimental boldness param */ + + 0, /* dir_mode */ + + /* internal */ + 0, /* force_reset */ + 0 /* 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[7]; /* 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; +#ifdef XETEX + unsigned short *ft_to_gid; +#endif + + /* if >= 0, index of a dev_font that really has the resource and used_chars */ + int real_font_index; + + 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 */ + + /* Compatibility */ + int mapc; /* Nasty workaround for Omega */ + + /* There are no font metric format supporting four-bytes + * charcter code. So we should provide an option to specify + * UCS group and plane. + */ + int ucs_group; + int ucs_plane; + + int is_unicode; +}; +static struct dev_font *dev_fonts = NULL; + +static int num_dev_fonts = 0; +static int max_dev_fonts = 0; +static int num_phys_fonts = 0; + +#define CURRENTFONT() ((text_state.font_id < 0) ? NULL : &(dev_fonts[text_state.font_id])) +#define GET_FONT(n) (&(dev_fonts[(n)])) + + +static void +dev_set_text_matrix (spt_t xpos, spt_t ypos, double slant, double extend, int rotate) +{ + pdf_tmatrix tm; + int len = 0; + + /* 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; + } + tm.e = xpos * dev_unit.dvi2pts; + tm.f = ypos * dev_unit.dvi2pts; + + format_buffer[len++] = ' '; + len += pdf_sprint_matrix(format_buffer+len, &tm); + format_buffer[len++] = ' '; + format_buffer[len++] = 'T'; + format_buffer[len++] = 'm'; + + pdf_doc_add_page_content(format_buffer, len); + + text_state.ref_x = xpos; + text_state.ref_y = ypos; + text_state.matrix.slant = slant; + text_state.matrix.extend = extend; + 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 (void) +{ + /* + * We need to reset the line matrix to handle slanted fonts. + */ + pdf_doc_add_page_content(" BT", 3); + /* + * 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 (text_state.force_reset || + text_state.matrix.slant != 0.0 || + text_state.matrix.extend != 1.0 || + ROTATE_TEXT(text_state.matrix.rotate)) { + dev_set_text_matrix(0, 0, + text_state.matrix.slant, + text_state.matrix.extend, + text_state.matrix.rotate); + } + text_state.ref_x = 0; + text_state.ref_y = 0; + text_state.offset = 0; + text_state.force_reset = 0; +} + +static void +text_mode (void) +{ + switch (motion_state) { + case TEXT_MODE: + break; + case STRING_MODE: + pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4); + break; + case GRAPHICS_MODE: + reset_text_state(); + break; + } + motion_state = TEXT_MODE; + text_state.offset = 0; +} + +void +graphics_mode (void) +{ + switch (motion_state) { + case GRAPHICS_MODE: + break; + case STRING_MODE: + pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4); + /* continue */ + case TEXT_MODE: + pdf_doc_add_page_content(" ET", 3); + text_state.force_reset = 0; + text_state.font_id = -1; + break; + } + motion_state = GRAPHICS_MODE; +} + +static void +start_string (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; + + delx = xpos - text_state.ref_x; + dely = ypos - 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. + */ + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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) + */ + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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; + + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx); + format_buffer[len++] = ' '; + len += dev_sprint_bp(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); + + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx); + format_buffer[len++] = ' '; + len += dev_sprint_bp(format_buffer+len, desired_dely, &error_dely); + break; + } + pdf_doc_add_page_content(format_buffer, len); + /* + * dvipdfm wrongly using "TD" in place of "Td". + * The TD operator set leading, but we are not using T* etc. + */ + pdf_doc_add_page_content(text_state.is_mb ? " Td[<" : " Td[(", 5); + + /* Error correction */ + text_state.ref_x = xpos - error_delx; + text_state.ref_y = ypos - error_dely; + + text_state.offset = 0; +} + +static void +string_mode (spt_t xpos, spt_t ypos, double slant, double extend, int rotate) +{ + switch (motion_state) { + case STRING_MODE: + break; + case GRAPHICS_MODE: + reset_text_state(); + /* continue */ + case TEXT_MODE: + if (text_state.force_reset) { + dev_set_text_matrix(xpos, ypos, slant, extend, rotate); + pdf_doc_add_page_content(text_state.is_mb ? "[<" : "[(", 2); + text_state.force_reset = 0; + } else { + start_string(xpos, ypos, slant, extend, rotate); + } + break; + } + 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 +dev_set_font (int font_id) +{ + struct dev_font *font; + struct dev_font *real_font; + int text_rotate; + double font_scale; + int len; + int vert_dir, vert_font; + + /* text_mode() must come before text_state.is_mb is changed. */ + text_mode(); + + font = GET_FONT(font_id); + ASSERT(font); /* Caller should check font_id. */ + + if (font->real_font_index >= 0) + real_font = GET_FONT(font->real_font_index); + else + real_font = font; + + text_state.is_mb = (font->format == PDF_FONTTYPE_COMPOSITE) ? 1 : 0; + + vert_font = font->wmode ? 1 : 0; + if (dev_param.autorotate) { + vert_dir = text_state.dir_mode ? 1 : 0; + } else { + vert_dir = vert_font; + } + text_rotate = (vert_font << 1)|vert_dir; + + if (font->slant != text_state.matrix.slant || + font->extend != text_state.matrix.extend || + ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) { + text_state.force_reset = 1; + } + text_state.matrix.slant = font->slant; + text_state.matrix.extend = font->extend; + text_state.matrix.rotate = text_rotate; + + if (!real_font->resource) { + real_font->resource = pdf_get_font_reference(real_font->font_id); + real_font->used_chars = pdf_get_font_usedchars(real_font->font_id); + } + + if (!real_font->used_on_this_page) { + pdf_doc_add_page_resource("Font", + real_font->short_name, + pdf_link_obj(real_font->resource)); + real_font->used_on_this_page = 1; + } + + font_scale = (double) font->sptsize * dev_unit.dvi2pts; + len = sprintf(format_buffer, " /%s", real_font->short_name); /* space not necessary. */ + format_buffer[len++] = ' '; + len += p_dtoa(font_scale, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), format_buffer+len); + format_buffer[len++] = ' '; + format_buffer[len++] = 'T'; + format_buffer[len++] = 'f'; + pdf_doc_add_page_content(format_buffer, len); + + if (font->bold > 0.0 || font->bold != text_state.bold_param) { + if (font->bold <= 0.0) + len = sprintf(format_buffer, " 0 Tr"); + else + len = sprintf(format_buffer, " 2 Tr %.6f w", font->bold); /* _FIXME_ */ + pdf_doc_add_page_content(format_buffer, len); + } + text_state.bold_param = font->bold; + + text_state.font_id = font_id; + + return 0; +} + + +/* Access text state parameters. + */ +#if 0 +int +pdf_dev_currentfont (void) +{ + return text_state.font_id; +} + +double +pdf_dev_get_font_ptsize (int font_id) +{ + struct dev_font *font; + + font = GET_FONT(font_id); + if (font) { + return font->sptsize * dev_unit.dvi2pts; + } + + return 1.0; +} +#endif /* 0 */ + +int +pdf_dev_get_font_wmode (int font_id) +{ + struct dev_font *font; + + font = GET_FONT(font_id); + if (font) { + return font->wmode; + } + + return 0; +} + +static unsigned char sbuf0[FORMAT_BUF_SIZE]; +static unsigned char sbuf1[FORMAT_BUF_SIZE]; + +static int +handle_multibyte_string (struct dev_font *font, + const unsigned char **str_ptr, int *str_len, int ctype) +{ + const unsigned char *p; + int i, length; + + p = *str_ptr; + length = *str_len; + +#ifdef XETEX + if (ctype == -1) { /* freetype glyph indexes */ + if (font->ft_to_gid) { + /* convert freetype glyph indexes to physical GID */ + const unsigned char *inbuf = p; + unsigned char *outbuf = sbuf0; + for (i = 0; i < length; i += 2) { + unsigned int gid; + gid = *inbuf++ << 8; + gid += *inbuf++; + gid = font->ft_to_gid[gid]; + *outbuf++ = gid >> 8; + *outbuf++ = gid & 0xff; + } + p = sbuf0; + length = outbuf - sbuf0; + } + } + else +#endif + /* _FIXME_ */ + if (font->is_unicode) { /* UCS-4 */ + if (ctype == 1) { + if (length * 4 >= FORMAT_BUF_SIZE) { + WARN("Too long string..."); + return -1; + } + for (i = 0; i < length; i++) { + sbuf1[i*4 ] = font->ucs_group; + sbuf1[i*4+1] = font->ucs_plane; + sbuf1[i*4+2] = '\0'; + sbuf1[i*4+3] = p[i]; + } + length *= 4; + } else if (ctype == 2) { + int len = 0; + + if (length * 2 >= FORMAT_BUF_SIZE) { + WARN("Too long string..."); + return -1; + } + for (i = 0; i < length; i += 2, len += 4) { + sbuf1[len ] = font->ucs_group; + if ((p[i] & 0xf8) == 0xd8) { + int c; + /* Check for valid surrogate pair. */ + if ((p[i] & 0xfc) != 0xd8 || i + 2 >= length || (p[i+2] & 0xfc) != 0xdc) { + WARN("Invalid surrogate p[%d]=%02X...", i, p[i]); + return -1; + } + c = (((p[i] & 0x03) << 10) | (p[i+1] << 2) | (p[i+2] & 0x03)) + 0x100; + sbuf1[len+1] = (c >> 8) & 0xff; + sbuf1[len+2] = c & 0xff; + i += 2; + } else { + sbuf1[len+1] = font->ucs_plane; + sbuf1[len+2] = p[i]; + } + sbuf1[len+3] = p[i+1]; + } + length = len; + } + p = sbuf1; + } else if (ctype == 1 && font->mapc >= 0) { + /* Omega workaround... + * Translate single-byte chars to double byte code space. + */ + if (length * 2 >= FORMAT_BUF_SIZE) { + WARN("Too long string..."); + return -1; + } + for (i = 0; i < length; i++) { + sbuf1[i*2 ] = (font->mapc & 0xff); + sbuf1[i*2+1] = p[i]; + } + length *= 2; + p = sbuf1; + } + + /* + * Font is double-byte font. Output is assumed to be 16-bit fixed length + * encoding. + * TODO: A character decomposed to multiple characters. + */ + if (ctype != -1 && font->enc_id >= 0) { + const unsigned char *inbuf; + unsigned char *outbuf; + long 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; +} + + +static pdf_coord *dev_coords = NULL; +static int num_dev_coords = 0; +static int max_dev_coords = 0; + +void pdf_dev_get_coord(double *xpos, double *ypos) +{ + if (num_dev_coords > 0) { + *xpos = dev_coords[num_dev_coords-1].x; + *ypos = dev_coords[num_dev_coords-1].y; + } else { + *xpos = *ypos = 0.0; + } +} + +void pdf_dev_push_coord(double xpos, double ypos) +{ + if (num_dev_coords >= max_dev_coords) { + max_dev_coords += 4; + dev_coords = RENEW(dev_coords, max_dev_coords, pdf_coord); + } + dev_coords[num_dev_coords].x = xpos; + dev_coords[num_dev_coords].y = ypos; + num_dev_coords++; +} + +void pdf_dev_pop_coord(void) +{ + if (num_dev_coords > 0) num_dev_coords--; +} + +/* + * ctype: +#ifdef XETEX + * -1 input string contains 2-byte Freetype glyph index values +#endif + * 0 byte-width of char can be variable and input string + * is properly encoded. + * n Single character cosumes n bytes in input string. + * + * _FIXME_ + * --> + * selectfont(font_name, point_size) and show_string(pos, string) + */ +void +pdf_dev_set_string (spt_t xpos, spt_t ypos, + const void *instr_ptr, int instr_len, + spt_t width, + int font_id, int ctype) +{ + struct dev_font *font; + struct dev_font *real_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 >= num_dev_fonts) { + ERROR("Invalid font: %d (%d)", font_id, num_dev_fonts); + return; + } + if (font_id != text_state.font_id) { + dev_set_font(font_id); + } + + font = CURRENTFONT(); + if (!font) { + ERROR("Currentfont not set."); + return; + } + + if (font->real_font_index >= 0) + real_font = GET_FONT(font->real_font_index); + else + real_font = font; + + text_xorigin = text_state.ref_x; + text_yorigin = 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, ctype) < 0) { + ERROR("Error in converting input string..."); + return; + } + if (real_font->used_chars != NULL) { + for (i = 0; i < length; i += 2) + add_to_used_chars2(real_font->used_chars, + (unsigned short) (str_ptr[i] << 8)|str_ptr[i+1]); + } + } else { + if (real_font->used_chars != NULL) { + for (i = 0; i < length; i++) + real_font->used_chars[str_ptr[i]] = 1; + } + } + + if (num_dev_coords > 0) { + xpos -= bpt2spt(dev_coords[num_dev_coords-1].x); + ypos -= bpt2spt(dev_coords[num_dev_coords-1].y); + } + + /* + * 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 (text_state.dir_mode) { + /* Top-to-bottom */ + delh = ypos - text_yorigin + text_state.offset; + delv = xpos - text_xorigin; + } else { + /* Left-to-right */ + delh = text_xorigin + text_state.offset - xpos; + delv = ypos - text_yorigin; + } + + /* 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 (text_state.force_reset || + labs(delv) > dev_unit.min_bp_val || + labs(delh) > WORD_SPACE_MAX(font)) { + text_mode(); + 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 (motion_state != STRING_MODE) + string_mode(xpos, ypos, + font->slant, font->extend, 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(). + */ + text_state.offset -= + (spt_t) (kern * font->extend * (font->sptsize / 1000.0)); + format_buffer[len++] = text_state.is_mb ? '>' : ')'; + if (font->wmode) + len += p_itoa(-kern, format_buffer + len); + else { + len += p_itoa( kern, format_buffer + len); + } + format_buffer[len++] = text_state.is_mb ? '<' : '('; + pdf_doc_add_page_content(format_buffer, len); + len = 0; + } + + if (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; + format_buffer[len++] = ((first >= 10) ? first + 'W' : first + '0'); + format_buffer[len++] = ((second >= 10) ? second + 'W' : second + '0'); + } + } else { + len += pdfobj_escape_str(format_buffer + len, + FORMAT_BUF_SIZE - len, str_ptr, length); + } + /* I think if you really care about speed, you should avoid memcopy here. */ + pdf_doc_add_page_content(format_buffer, len); + + text_state.offset += width; +} + +void +pdf_init_device (double dvi2pts, int precision, int black_and_white) +{ + if (precision < 0 || + precision > DEV_PRECISION_MAX) + WARN("Number of decimal digits out of range [0-%d].", + DEV_PRECISION_MAX); + + if (precision < 0) { + dev_unit.precision = 0; + } else if (precision > DEV_PRECISION_MAX) { + dev_unit.precision = DEV_PRECISION_MAX; + } else { + dev_unit.precision = precision; + } + dev_unit.dvi2pts = dvi2pts; + dev_unit.min_bp_val = (long) ROUND(1.0/(ten_pow[dev_unit.precision]*dvi2pts), 1); + if (dev_unit.min_bp_val < 0) + dev_unit.min_bp_val = -dev_unit.min_bp_val; + + dev_param.colormode = (black_and_white ? 0 : 1); + + graphics_mode(); + pdf_color_clear_stack(); + pdf_dev_init_gstates(); + + num_dev_fonts = max_dev_fonts = 0; + dev_fonts = NULL; + num_dev_coords = max_dev_coords = 0; + dev_coords = NULL; +} + +void +pdf_close_device (void) +{ + if (dev_fonts) { + int i; + + for (i = 0; i < num_dev_fonts; i++) { + if (dev_fonts[i].tex_name) + RELEASE(dev_fonts[i].tex_name); + if (dev_fonts[i].resource) + pdf_release_obj(dev_fonts[i].resource); + dev_fonts[i].tex_name = NULL; + dev_fonts[i].resource = NULL; + } + RELEASE(dev_fonts); + } + if (dev_coords) RELEASE(dev_coords); + 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 (void) +{ + int i; + + for (i = 0; i < num_dev_fonts; i++) { + dev_fonts[i].used_on_this_page = 0; + } + + text_state.font_id = -1; + + text_state.matrix.slant = 0.0; + text_state.matrix.extend = 1.0; + text_state.matrix.rotate = TEXT_WMODE_HH; + + text_state.bold_param = 0.0; + + text_state.is_mb = 0; +} + +void +pdf_dev_reset_color(void) +{ + pdf_color *sc, *fc; + + if (pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) { + pdf_color_get_current(&sc, &fc); + pdf_dev_set_strokingcolor(sc); + pdf_dev_set_nonstrokingcolor(fc); + } + return; +} + +static int +color_to_string (pdf_color *color, char *buffer) +{ + int i, len = 0; + + for (i = 0; i < color->num_components; i++) { + len += sprintf(format_buffer+len, " %g", ROUND(color->values[i], 0.001)); + } + return len; +} + +void +pdf_dev_set_color (pdf_color *color) +{ + int len; + + if (!pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) { + WARN("Ignore color option was set. Just ignore."); + return; + } else if (!(color && pdf_color_is_valid(color))) { + WARN("No valid color is specified. Just ignore."); + return; + } + + graphics_mode(); + len = color_to_string(color, format_buffer); + format_buffer[len++] = ' '; + switch (color->num_components) { + case 3: + format_buffer[len++] = 'R'; + format_buffer[len++] = 'G'; + break; + case 4: + format_buffer[len++] = 'K'; + break; + case 1: + format_buffer[len++] = 'G'; + break; + default: /* already verified the given color */ + break; + } + strncpy(format_buffer+len, format_buffer, len); + len = len << 1; + switch (color->num_components) { + case 3: + format_buffer[len-2] = 'r'; + format_buffer[len-1] = 'g'; + break; + case 4: + format_buffer[len-1] = 'k'; + break; + case 1: + format_buffer[len-1] = 'g'; + break; + default: /* already verified the given color */ + break; + } + pdf_doc_add_page_content(format_buffer, len); + return; +} + +void +pdf_dev_set_strokingcolor (pdf_color *color) +{ + int len; + + if (!pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) { + WARN("Ignore color option was set. Just ignore."); + return; + } else if (!(color && pdf_color_is_valid(color))) { + WARN("No valid color is specified. Just ignore."); + return; + } + + graphics_mode(); + len = color_to_string(color, format_buffer); + format_buffer[len++] = ' '; + switch (color->num_components) { + case 3: + format_buffer[len++] = 'R'; + format_buffer[len++] = 'G'; + break; + case 4: + format_buffer[len++] = 'K'; + break; + case 1: + format_buffer[len++] = 'G'; + break; + default: /* already verified the given color */ + break; + } + pdf_doc_add_page_content(format_buffer, len); + return; +} + +void +pdf_dev_set_nonstrokingcolor (pdf_color *color) +{ + int len; + + if (!pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) { + WARN("Ignore color option was set. Just ignore."); + return; + } else if (!(color && pdf_color_is_valid(color))) { + WARN("No valid color is specified. Just ignore."); + return; + } + + graphics_mode(); + len = color_to_string(color, format_buffer); + format_buffer[len++] = ' '; + switch (color->num_components) { + case 3: + format_buffer[len++] = 'r'; + format_buffer[len++] = 'g'; + break; + case 4: + format_buffer[len++] = 'k'; + break; + case 1: + format_buffer[len++] = 'g'; + break; + default: /* already verified the given color */ + break; + } + pdf_doc_add_page_content(format_buffer, len); + return; +} + +/* Not working */ +void +pdf_dev_set_origin (double phys_x, double phys_y) +{ + pdf_tmatrix M0, M1; + + pdf_dev_currentmatrix(&M0); + pdf_dev_currentmatrix(&M1); + pdf_invertmatrix(&M1); + M0.e = phys_x; M0.f = phys_y; + pdf_concatmatrix(&M1, &M0); + + pdf_dev_concat(&M1); +} + +void +pdf_dev_bop (const pdf_tmatrix *M) +{ + graphics_mode(); + + text_state.force_reset = 0; + + pdf_dev_gsave(); + pdf_dev_concat(M); + + pdf_dev_reset_fonts(); + pdf_dev_reset_color(); +} + +void +pdf_dev_eop (void) +{ + int depth; + + graphics_mode(); + + 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) +{ + 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 < num_dev_fonts; i++) { + if (strcmp(font_name, dev_fonts[i].tex_name) == 0) { + if (ptsize == dev_fonts[i].sptsize) + return i; /* found a dev_font that matches the request */ + if (dev_fonts[i].format != PDF_FONTTYPE_BITMAP) + break; /* new dev_font will share pdf resource with /i/ */ + } + } + + /* + * Make sure we have room for a new one, even though we may not + * actually create one. + */ + if (num_dev_fonts >= max_dev_fonts) { + max_dev_fonts += 16; + dev_fonts = RENEW(dev_fonts, max_dev_fonts, struct dev_font); + } + + font = &dev_fonts[num_dev_fonts]; + + /* New font */ + mrec = pdf_lookup_fontmap_record(font_name); + + if (verbose > 1) + print_fontmap(font_name, mrec); + + font->font_id = pdf_font_findresource(font_name, ptsize * dev_unit.dvi2pts, mrec); + if (font->font_id < 0) + return -1; + + /* We found device font here. */ + if (i < num_dev_fonts) { + font->real_font_index = i; + strcpy(font->short_name, dev_fonts[i].short_name); + } + else { + font->real_font_index = -1; + font->short_name[0] = 'F'; + p_itoa(num_phys_fonts + 1, &font->short_name[1]); /* NULL terminated here */ + num_phys_fonts++; + } + + 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); +#ifdef XETEX + font->ft_to_gid = pdf_get_font_ft_to_gid(font->font_id); +#endif + + 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; + font->mapc = -1; + font->is_unicode = 0; + font->ucs_group = 0; + font->ucs_plane = 0; + + if (mrec) { + font->extend = mrec->opt.extend; + font->slant = mrec->opt.slant; + font->bold = mrec->opt.bold; + if (mrec->opt.mapc >= 0) + font->mapc = (mrec->opt.mapc >> 8) & 0xff; + else { + font->mapc = -1; + } + if (mrec->enc_name && + !strcmp(mrec->enc_name, "unicode")) { + font->is_unicode = 1; + if (mrec->opt.mapc >= 0) { + font->ucs_group = (mrec->opt.mapc >> 24) & 0xff; + font->ucs_plane = (mrec->opt.mapc >> 16) & 0xff; + } else { + font->ucs_group = 0; + font->ucs_plane = 0; + } + } else { + font->is_unicode = 0; + } + } + + return num_dev_fonts++; +} + + +/* This does not remember current stroking width. */ +static int +dev_sprint_line (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 * dev_unit.dvi2pts; + + len += p_dtoa(w, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), buf+len); + buf[len++] = ' '; + buf[len++] = 'w'; + buf[len++] = ' '; + len += dev_sprint_bp(buf+len, p0_x, NULL); + buf[len++] = ' '; + len += dev_sprint_bp(buf+len, p0_y, NULL); + buf[len++] = ' '; + buf[len++] = 'm'; + buf[len++] = ' '; + len += dev_sprint_bp(buf+len, p1_x, NULL); + buf[len++] = ' '; + len += dev_sprint_bp(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) +{ + int len = 0; + double width_in_bp; + + if (num_dev_coords > 0) { + xpos -= bpt2spt(dev_coords[num_dev_coords-1].x); + ypos -= bpt2spt(dev_coords[num_dev_coords-1].y); + } + + graphics_mode(); + + format_buffer[len++] = ' '; + format_buffer[len++] = 'q'; + format_buffer[len++] = ' '; + /* Don't use too thick line. */ + width_in_bp = ((width < height) ? width : height) * dev_unit.dvi2pts; + if (width_in_bp < 0.0 || /* Shouldn't happen */ + width_in_bp > PDF_LINE_THICKNESS_MAX) { + pdf_rect rect; + + rect.llx = dev_unit.dvi2pts * xpos; + rect.lly = dev_unit.dvi2pts * ypos; + rect.urx = dev_unit.dvi2pts * width; + rect.ury = dev_unit.dvi2pts * height; + len += pdf_sprint_rect(format_buffer+len, &rect); + format_buffer[len++] = ' '; + format_buffer[len++] = 'r'; + format_buffer[len++] = 'e'; + format_buffer[len++] = ' '; + 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 < dev_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(format_buffer+len, + height, + xpos, + ypos + height/2, + xpos + width, + ypos + height/2); + } else { + if (width < dev_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(format_buffer+len, + width, + xpos + width/2, + ypos, + xpos + width/2, + ypos + height); + } + } + format_buffer[len++] = ' '; + format_buffer[len++] = 'Q'; + pdf_doc_add_page_content(format_buffer, len); +} + +/* 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) +{ + double dev_x, dev_y; + pdf_coord p0, p1, p2, p3; + double min_x, min_y, max_x, max_y; + + dev_x = x_user * dev_unit.dvi2pts; + dev_y = y_user * dev_unit.dvi2pts; + if (text_state.dir_mode) { + p0.x = dev_x - dev_unit.dvi2pts * depth; + p0.y = dev_y - dev_unit.dvi2pts * width; + p1.x = dev_x + dev_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 - dev_unit.dvi2pts * depth; + p1.x = dev_x + dev_unit.dvi2pts * width; + p1.y = p0.y; + p2.x = p1.x; + p2.y = dev_y + dev_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) +{ + return text_state.dir_mode; +} + +void +pdf_dev_set_dirmode (int text_dir) +{ + struct dev_font *font; + int text_rotate; + int vert_dir, vert_font; + + font = CURRENTFONT(); + + vert_font = (font && font->wmode) ? 1 : 0; + if (dev_param.autorotate) { + vert_dir = text_dir ? 1 : 0; + } else { + vert_dir = vert_font; + } + text_rotate = (vert_font << 1)|vert_dir; + + if (font && + ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) { + text_state.force_reset = 1; + } + + text_state.matrix.rotate = text_rotate; + text_state.dir_mode = text_dir; +} + +static void +dev_set_param_autorotate (int auto_rotate) +{ + struct dev_font *font; + int text_rotate, vert_font, vert_dir; + + font = CURRENTFONT(); + + vert_font = (font && font->wmode) ? 1 : 0; + if (auto_rotate) { + vert_dir = text_state.dir_mode ? 1 : 0; + } else { + vert_dir = vert_font; + } + text_rotate = (vert_font << 1)|vert_dir; + + if (ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) { + text_state.force_reset = 1; + } + text_state.matrix.rotate = text_rotate; + dev_param.autorotate = auto_rotate; +} + +int +pdf_dev_get_param (int param_type) +{ + int value = 0; + + switch (param_type) { + case PDF_DEV_PARAM_AUTOROTATE: + value = dev_param.autorotate; + break; + case PDF_DEV_PARAM_COLORMODE: + value = dev_param.colormode; + break; + default: + ERROR("Unknown device parameter: %d", param_type); + } + + return value; +} + +void +pdf_dev_set_param (int param_type, int value) +{ + switch (param_type) { + case PDF_DEV_PARAM_AUTOROTATE: + dev_set_param_autorotate(value); + break; + case PDF_DEV_PARAM_COLORMODE: + dev_param.colormode = value; /* 0 for B&W */ + break; + default: + ERROR("Unknown device parameter: %d", param_type); + } + + return; +} + + +int +pdf_dev_put_image (int id, + transform_info *p, + double ref_x, + double ref_y) +{ + char *res_name; + pdf_tmatrix M; + pdf_rect r; + int len = 0; + + if (num_dev_coords > 0) { + ref_x -= dev_coords[num_dev_coords-1].x; + ref_y -= dev_coords[num_dev_coords-1].y; + } + + pdf_copymatrix(&M, &(p->matrix)); + M.e += ref_x; M.f += ref_y; + /* Just rotate by -90, but not tested yet. Any problem if M has scaling? */ + if (dev_param.autorotate && + 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; + } + + graphics_mode(); + pdf_dev_gsave(); + + pdf_dev_concat(&M); + + pdf_ximage_scale_image(id, &M, &r, p); + pdf_dev_concat(&M); + + /* Clip */ + if (p->flags & INFO_DO_CLIP) { +#if 0 + pdf_dev_newpath(); + pdf_dev_moveto(r.llx, r.lly); + pdf_dev_lineto(r.urx, r.lly); + pdf_dev_lineto(r.urx, r.ury); + pdf_dev_lineto(r.llx, r.ury); + pdf_dev_closepath(); + pdf_dev_clip(); + pdf_dev_newpath(); +#else + pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly); +#endif + } + + res_name = pdf_ximage_get_resname(id); + len = sprintf(work_buffer, " /%s Do", res_name); + pdf_doc_add_page_content(work_buffer, len); + + pdf_dev_grestore(); + + pdf_doc_add_page_resource("XObject", + res_name, + pdf_ximage_get_reference(id)); + + if (dvi_is_tracking_boxes()) { + pdf_tmatrix P; + int i; + pdf_rect rect; + pdf_coord corner[4]; + + pdf_dev_set_rect(&rect, 65536 * ref_x, 65536 * ref_y, + 65536 * (r.urx - r.llx), 65536 * (r.ury - r.lly), 0); + + corner[0].x = rect.llx; corner[0].y = rect.lly; + corner[1].x = rect.llx; corner[1].y = rect.ury; + corner[2].x = rect.urx; corner[2].y = rect.ury; + corner[3].x = rect.urx; corner[3].y = rect.lly; + + pdf_copymatrix(&P, &(p->matrix)); + for (i = 0; i < 4; ++i) { + corner[i].x -= rect.llx; + corner[i].y -= rect.lly; + pdf_dev_transform(&(corner[i]), &P); + corner[i].x += rect.llx; + corner[i].y += rect.lly; + } + + rect.llx = corner[0].x; + rect.lly = corner[0].y; + rect.urx = corner[0].x; + rect.ury = corner[0].y; + for (i = 0; i < 4; ++i) { + if (corner[i].x < rect.llx) + rect.llx = corner[i].x; + if (corner[i].x > rect.urx) + rect.urx = corner[i].x; + if (corner[i].y < rect.lly) + rect.lly = corner[i].y; + if (corner[i].y > rect.ury) + rect.ury = corner[i].y; + } + + pdf_doc_expand_box(&rect); + } + + 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; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdev.h b/Build/source/texk/dvipdf-x/xsrc/pdfdev.h new file mode 100644 index 00000000000..25bac2ecd47 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfdev.h @@ -0,0 +1,231 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 signed long 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); + + +extern void pdf_dev_set_verbose (void); + +/* 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); + +#if 0 +/* DVI interpreter knows text positioning in relative motion. + * However, pdf_dev_set_string() recieves text string with placement + * in absolute position in user space, and it convert absolute + * positioning back to relative positioning. It is quite wasteful. + * + * TeX using DVI register stack operation to do CR and then use down + * command for LF. DVI interpreter knows hint for current leading + * and others (raised or lowered), but they are mostly lost in + * pdf_dev_set_string(). + */ + +typedef struct +{ + int argc; + + struct { + int is_kern; /* kern or string */ + + spt_t kern; /* negative kern means space */ + + int offset; /* offset to sbuf */ + int length; /* length of string */ + } args[]; + + unsigned char sbuf[PDF_STRING_LEN_MAX]; + +} pdf_text_string; + +/* Something for handling raise, leading, etc. here. */ + +#endif + +/* 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, int ctype); +extern void pdf_dev_set_rule (spt_t xpos, spt_t ypos, + spt_t width, spt_t height); + +/* Place XObject */ +extern int pdf_dev_put_image (int xobj_id, + transform_info *p, double ref_x, double ref_y); + +/* The design_size and ptsize required by PK font support... + */ +extern int pdf_dev_locate_font (const char *font_name, spt_t ptsize); + +extern int pdf_dev_setfont (const char *font_name, spt_t ptsize); + +/* The following two routines are NOT WORKING. + * Dvipdfmx doesn't manage gstate well.. + */ +/* pdf_dev_translate() or pdf_dev_concat() should be used. */ +extern void pdf_dev_set_origin (double orig_x, double orig_y); +/* Always returns 1.0, please rename this. */ +extern double pdf_dev_scale (void); + +/* Access text state parameters. */ +#if 0 +extern int pdf_dev_currentfont (void); /* returns font_id */ +extern double pdf_dev_get_font_ptsize (int font_id); +#endif /* 0 */ +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)) +#define pdf_dev_set_colormode(v) pdf_dev_set_param(PDF_DEV_PARAM_COLORMODE, (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 (void); +extern void pdf_dev_reset_color (void); + +extern void pdf_dev_set_color (pdf_color *color); +extern void pdf_dev_set_strokingcolor (pdf_color *color); +extern void pdf_dev_set_nonstrokingcolor (pdf_color *color); + +/* 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_get_coord(double *xpos, double *ypos); +extern void pdf_dev_push_coord(double xpos, double ypos); +extern void pdf_dev_pop_coord(void); + +#endif /* _PDFDEV_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdoc.c b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.c new file mode 100644 index 00000000000..9c4731ecffd --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.c @@ -0,0 +1,2331 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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)... + */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" + +#include "numbers.h" + +#include "pdfobj.h" +#include "pdfparse.h" +#include "pdfnames.h" + +#include "pdfencrypt.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 int verbose = 0; + +static char manual_thumb_enabled = 0; +static char *thumb_basename = NULL; + +void +pdf_doc_enable_manual_thumbnails (void) +{ +#if HAVE_LIBPNG + manual_thumb_enabled = 1; +#else + WARN("Manual thumbnail is not supported without the libpng library."); +#endif +} + +static pdf_obj * +read_thumbnail (const char *thumb_filename) +{ + pdf_obj *image_ref; + int xobj_id; + FILE *fp; + + 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_findresource(thumb_filename, 0, NULL); + 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; +} + +void +pdf_doc_set_verbose (void) +{ + verbose++; + pdf_font_set_verbose(); + pdf_color_set_verbose(); + pdf_ximage_set_verbose(); +} + +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; + long page_no; + pdf_rect rect; +} pdf_bead; + +typedef struct pdf_article +{ + char *id; + pdf_obj *info; + long num_beads; + long 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; + + long num_entries; /* This is not actually total number of pages. */ + long max_entries; + pdf_page *entries; + } pages; + + struct { + pdf_olitem *first; + pdf_olitem *current; + int current_depth; + } outlines; + + struct { + long num_entries; + long max_entries; + pdf_article *entries; + } articles; + + struct name_dict *names; + + struct { + int outline_open_depth; + double annot_grow; + } opt; + + struct form_list_node *pending_forms; + +} 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, long size) +{ + if (size > MAXPAGES(p)) { + long 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 long 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); +static void pdf_doc_close_names (pdf_doc *p); + +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; +} + +#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 long +compute_timezone_offset() +{ + const time_t now = time(NULL); + struct tm tm; + struct tm local; + time_t gmtoff; + + localtime_r(&now, &local); + gmtime_r(&now, &tm); + return (mktime(&local) - mktime(&tm)); +} + +#endif /* HAVE_TIMEZONE */ +#endif /* HAVE_TM_GMTOFF */ + +/* + * Docinfo + */ +static long +asn_date (char *date_string) +{ + long tz_offset; + time_t current_time; + struct tm *bd_time; + + time(¤t_time); + bd_time = localtime(¤t_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 */ + + sprintf(date_string, "D:%04d%02d%02d%02d%02d%02d%c%02ld'%02ld'", + 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) ? '+' : '-', labs(tz_offset) / 3600, + (labs(tz_offset) / 60) % 60); + + return strlen(date_string); +} + +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; + char *banner; + 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]); + } + } + } + + banner = NEW(strlen(PACKAGE)+strlen(VERSION)+4, char); + sprintf(banner, "%s (%s)", PACKAGE, 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]; + + asn_date(now); + 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); + } + + 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; + + if (!PDF_OBJ_INDIRECTTYPE(resource_ref)) { + WARN("Passed non indirect reference..."); + resource_ref = pdf_ref_obj(resource_ref); /* leak */ + } + resources = pdf_doc_get_page_resources(p, category); + duplicate = pdf_lookup_dict(resources, resource_name); + if (duplicate && pdf_compare_reference(duplicate, resource_ref)) { + WARN("Conflicting page resource found (page: %ld, category: %s, name: %s).", + pdf_doc_current_page_number(), category, resource_name); + WARN("Ignoring..."); + pdf_release_obj(resource_ref); + } 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, long num_pages, + pdf_obj *parent_ref) +{ + pdf_obj *self, *self_ref, *kids; + long 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++) { + long 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; + long 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; +} + + +#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->opt.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 "" + 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)->opt.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; + + 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 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 = NULL; + } + p->names[NUM_NAME_CATEGORY].category = NULL; + p->names[NUM_NAME_CATEGORY].data = NULL; + + 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_close_names (pdf_doc *p) +{ + pdf_obj *tmp; + int i; + + for (i = 0; p->names[i].category != NULL; i++) { + if (p->names[i].data) { + pdf_obj *name_tree; + + name_tree = pdf_names_create_tree(p->names[i].data); + 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; + + return; +} + + +void +pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, pdf_obj *annot_dict) +{ + pdf_doc *p = &pdoc; + pdf_page *page; + pdf_obj *rect_array; + double annot_grow = p->opt.annot_grow; + + page = doc_get_page_entry(p, page_no); + if (!page->annots) + page->annots = pdf_new_array(); + +#if 1 + { + 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); + } + } +#endif + + rect_array = pdf_new_array(); + pdf_add_array(rect_array, pdf_new_number(ROUND(rect->llx - annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(rect->lly - annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(rect->urx + annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(rect->ury + annot_grow, 0.001))); + pdf_add_dict (annot_dict, pdf_new_name("Rect"), rect_array); + + pdf_add_array(page->annots, pdf_ref_obj(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; +} + +#if 0 +void +pdf_doc_end_article (const char *article_id) +{ + return; /* no-op */ +} +#endif + +static pdf_bead * +find_bead (pdf_article *article, const char *bead_id) +{ + pdf_bead *bead; + long 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, long page_no, const pdf_rect *rect) +{ + pdf_doc *p = &pdoc; + pdf_article *article; + pdf_bead *bead; + long 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; + long 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) { + long 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; +} + +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; +} + +long +pdf_doc_current_page_number (void) +{ + pdf_doc *p = &pdoc; + + return (long) (PAGECOUNT(p) + 1); +} + +pdf_obj * +pdf_doc_ref_page (unsigned long 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; + long 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 (manual_thumb_enabled) { + char *thumb_filename; + pdf_obj *thumb_ref; + + thumb_filename = NEW(strlen(thumb_basename)+7, char); + sprintf(thumb_filename, "%s.%ld", + 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, { 1.0 } }; +void +pdf_doc_set_bgcolor (const pdf_color *color) +{ + if (color) + memcpy(&bgcolor, color, sizeof(pdf_color)); + else { /* as clear... */ + pdf_color_graycolor(&bgcolor, 1.0); + } +} + +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_color_push(); + pdf_dev_set_nonstrokingcolor(&bgcolor); + pdf_dev_rectfill(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly); + //pdf_color_pop(); + 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; +} + +static char *doccreator = NULL; /* Ugh */ + +void +pdf_open_document (const char *filename, + int do_encryption, + double media_width, double media_height, + double annot_grow_amount, int bookmark_open_depth) +{ + pdf_doc *p = &pdoc; + + pdf_out_init(filename, do_encryption); + + pdf_doc_init_catalog(p); + + p->opt.annot_grow = annot_grow_amount; + p->opt.outline_open_depth = bookmark_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 (doccreator) { + pdf_add_dict(p->info, + pdf_new_name("Creator"), + pdf_new_string(doccreator, strlen(doccreator))); + RELEASE(doccreator); doccreator = NULL; + } + + pdf_doc_init_bookmarks(p, bookmark_open_depth); + pdf_doc_init_articles (p); + pdf_doc_init_names (p); + pdf_doc_init_page_tree(p, media_width, media_height); + + if (do_encryption) { + pdf_obj *encrypt = pdf_encrypt_obj(); + pdf_set_encrypt(encrypt, pdf_enc_id_array()); + pdf_release_obj(encrypt); + } + + /* Create a default name for thumbnail image files */ + if (manual_thumb_enabled) { + if (strlen(filename) > 4 && + !strncmp(".pdf", filename + strlen(filename) - 4, 4)) { + thumb_basename = NEW(strlen(filename)-4+1, char); + strncpy(thumb_basename, filename, strlen(filename)-4); + thumb_basename[strlen(filename)-4] = 0; + } else { + thumb_basename = NEW(strlen(filename)+1, char); + strcpy(thumb_basename, filename); + } + } + + p->pending_forms = NULL; + + return; +} + +void +pdf_doc_set_creator (const char *creator) +{ + if (!creator || + creator[0] == '\0') + return; + + doccreator = NEW(strlen(creator)+1, char); + strcpy(doccreator, creator); /* Ugh */ +} + + +void +pdf_close_document (void) +{ + pdf_doc *p = &pdoc; + + /* + * 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_out_flush(); + + if (thumb_basename) + RELEASE(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; + + 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. */ + xobj_id = pdf_ximage_defineresource(ident, + PDF_XOBJECT_TYPE_FORM, + &info, pdf_ref_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(); + pdf_dev_reset_color(); + + 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; + + /* Here we do not need pdf_dev_reset_color(). */ + pdf_dev_reset_fonts(); + + RELEASE(fnode); + + return; +} + +static struct +{ + int dirty; + pdf_obj *annot_dict; + pdf_rect rect; +} breaking_state = {0, NULL, {0.0, 0.0, 0.0, 0.0}}; + +static void +reset_box (void) +{ + breaking_state.rect.llx = 10000.0; /* large value */ + breaking_state.rect.lly = 10000.0; /* large value */ + breaking_state.rect.urx = 0.0; /* small value */ + breaking_state.rect.ury = 0.0; /* small value */ + breaking_state.dirty = 0; +} + +void +pdf_doc_begin_annot (pdf_obj *dict) +{ + breaking_state.annot_dict = dict; + reset_box(); +} + +void +pdf_doc_end_annot (void) +{ + pdf_doc_break_annot(); + breaking_state.annot_dict = NULL; +} + +void +pdf_doc_break_annot (void) +{ + if (breaking_state.dirty) { + pdf_obj *annot_dict; + + /* Copy dict */ + annot_dict = pdf_new_dict(); + pdf_merge_dict(annot_dict, breaking_state.annot_dict); + pdf_doc_add_annot(pdf_doc_current_page_number(), + &(breaking_state.rect), annot_dict); + pdf_release_obj(annot_dict); + } + 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 (long pg_start, + const char *type, + const void *prefix, int prfx_len, long 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/dvipdf-x/xsrc/pdfdoc.h b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.h new file mode 100644 index 00000000000..5e65da405e3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.h @@ -0,0 +1,137 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +#define PDF_DOC_GRABBING_NEST_MAX 4 + +extern void pdf_doc_set_verbose (void); + +extern void pdf_open_document (const char *filename, + int do_encryption, + double media_width, double media_height, + double annot_grow_amount, int bookmark_open_depth); +extern void pdf_close_document (void); + + +/* PDF document metadata */ +extern void pdf_doc_set_creator (const char *creator); + + +/* 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 long pdf_doc_current_page_number (void); +extern pdf_obj *pdf_doc_current_page_resources (void); + +extern pdf_obj *pdf_doc_ref_page (unsigned long 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_get_mediabox (unsigned page_no, 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); +#if 0 +extern void pdf_doc_end_article (const char *article_id); /* Do nothing... */ +#endif +extern void pdf_doc_make_article (const char *article_id, + const char **bead_order, int num_beads); +extern void pdf_doc_add_bead (const char *article_id, + const char *bead_id, + long 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); + +/* 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 (long page_start, + const char *type, + const void *prefix, int pfrx_len, + long counter_start); +#endif + +/* Similar to bop_content */ +#include "pdfcolor.h" +extern void pdf_doc_set_bgcolor (const pdf_color *color); + +#endif /* _PDFDOC_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdraw.c b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.c new file mode 100644 index 00000000000..9f1f0713fc6 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.c @@ -0,0 +1,1842 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +#include "system.h" +#include "error.h" +#include "mem.h" +#include "mfileio.h" +#include "dpxutil.h" +#include "numbers.h" + +#include "pdfdoc.h" +#include "pdfdev.h" +#include "pdfcolor.h" + +#include "pdfdraw.h" + +#if 1 +typedef void pdf_dev; +#endif + + +/* + * 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) < 1.e-8) { +#if 1 + WARN("Inverting matrix with zero determinant..."); +#endif + 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); + + 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; +} + +#if 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; +} +#endif /* 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) < 1.e-8) { + 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) + + +static char fmt_buf[1024]; /* FIXME */ +#define FORMAT_BUFF_PTR(p) fmt_buf +#define FORMAT_BUFF_LEN(p) 1024 + +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) < 1.e-8 || + fabs(r_y) < 1.e-8) + 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) < 1.e-8) + 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' || (c) == ' ' \ +) + +static /* __inline__ */ int +INVERTIBLE_MATRIX (const pdf_tmatrix *M) +{ + if (fabs(detP(M)) < 1.e-8) { + 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 (pdf_dev *P, + const pdf_rect *r, + const pdf_tmatrix *M, + char opchr + ) +{ + char *buf = FORMAT_BUFF_PTR(P); + int len = 0; + int isclip = 0; + pdf_coord p; + double wd, ht; + + ASSERT(r && PT_OP_VALID(opchr)); + + isclip = (opchr == 'W' || opchr == ' ') ? 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(); + + buf[len++] = ' '; + if (!isclip) { + buf[len++] = 'q'; + if (M) { + buf[len++] = ' '; + len += pdf_sprint_matrix(buf + len, M); + buf[len++] = ' '; + buf[len++] = 'c'; buf[len++] = 'm'; + } + buf[len++] = ' '; + } + buf[len++] = 'n'; + + 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'; + + if (opchr != ' ') { + buf[len++] = ' '; + buf[len++] = opchr; + + buf[len++] = ' '; + buf[len++] = isclip ? 'n' : 'Q'; + } + + pdf_doc_add_page_content(buf, len); len = 0; + + return 0; +} + +static int path_added = 0; + +/* FIXME */ +static int +pdf_dev__flushpath (pdf_dev *P, + pdf_path *pa, + char opchr, + int rule, + int ignore_rule) +{ + pa_elem *pe, *pe1; + char *b = FORMAT_BUFF_PTR(P); + long b_len = FORMAT_BUFF_LEN(P); + pdf_rect r; /* FIXME */ + pdf_coord *pt; + int n_pts, n_seg; + int len = 0; + int isclip = 0; + int isrect, i, j; + + ASSERT(pa && PT_OP_VALID(opchr)); + + isclip = (opchr == 'W') ? 1 : 0; + + if (PA_LENGTH(pa) <= 0 && path_added == 0) + return 0; + + path_added = 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); 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); len = 0; + } + } + if (len > 0) { + pdf_doc_add_page_content(b, len); len = 0; + } + } + + b[len++] = ' '; + b[len++] = opchr; + if (rule == PDF_FILL_RULE_EVENODD) + b[len++] = '*'; + if (isclip) { + b[len++] = ' '; b[len++] = 'n'; + } + + pdf_doc_add_page_content(b, len); + + return 0; +} + + +/* 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; + long flags; + /* bookkeeping the origin of the last transform applied */ + pdf_coord pt_fixee; +} pdf_gstate; + + +typedef struct m_stack_elem +{ + void *data; + struct m_stack_elem *prev; +} m_stack_elem; + +typedef struct m_stack +{ + int size; + m_stack_elem *top; + m_stack_elem *bottom; +} m_stack; + +static void +m_stack_init (m_stack *stack) +{ + ASSERT(stack); + + stack->size = 0; + stack->top = NULL; + stack->bottom = NULL; + + return; +} + +static void +m_stack_push (m_stack *stack, void *data) +{ + m_stack_elem *elem; + + ASSERT(stack); + + elem = NEW(1, m_stack_elem); + elem->prev = stack->top; + elem->data = data; + + stack->top = elem; + if (stack->size == 0) + stack->bottom = elem; + + stack->size++; + + return; +} + +static void * +m_stack_pop (m_stack *stack) +{ + m_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; +} + +static void * +m_stack_top (m_stack *stack) +{ + void *data; + + ASSERT(stack); + + if (stack->size == 0) + return NULL; + + data = stack->top->data; + + return data; +} + +#define m_stack_depth(s) ((s)->size) + +static m_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_graycolor(&gs->strokecolor, 0.0); + pdf_color_graycolor(&gs->fillcolor, 0.0); + + 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->pt_fixee.x = 0; + gs->pt_fixee.y = 0; + + return; +} + +static void +clear_a_gstate (pdf_gstate *gs) +{ + clear_a_path(&gs->path); + 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->pt_fixee.x = gs2->pt_fixee.x; + gs1->pt_fixee.y = gs2->pt_fixee.y; + + return; +} + +void +pdf_dev_init_gstates (void) +{ + pdf_gstate *gs; + + m_stack_init(&gs_stack); + + gs = NEW(1, pdf_gstate); + init_a_gstate(gs); + + m_stack_push(&gs_stack, gs); /* Initial state */ + + return; +} + +void +pdf_dev_clear_gstates (void) +{ + pdf_gstate *gs; + + if (m_stack_depth(&gs_stack) > 1) /* at least 1 elem. */ + WARN("GS stack depth is not zero at the end of the document."); + + while ((gs = m_stack_pop(&gs_stack)) != NULL) { + clear_a_gstate(gs); + RELEASE(gs); + } + return; +} + +int +pdf_dev_gsave (void) +{ + pdf_gstate *gs0, *gs1; + pdf_color *sc, *fc; + + gs0 = m_stack_top(&gs_stack); + gs1 = NEW(1, pdf_gstate); + init_a_gstate(gs1); + copy_a_gstate(gs1, gs0); + pdf_color_get_current(&sc, &fc); + pdf_color_copycolor(&gs1->strokecolor, sc); + pdf_color_copycolor(&gs1->fillcolor, fc); + m_stack_push(&gs_stack, gs1); + + pdf_doc_add_page_content(" q", 2); + + return 0; +} + +int +pdf_dev_grestore (void) +{ + pdf_gstate *gs; + + if (m_stack_depth(&gs_stack) <= 1) { /* Initial state at bottom */ + WARN("Too many grestores."); + return -1; + } + + gs = m_stack_pop(&gs_stack); + clear_a_gstate(gs); + RELEASE(gs); + + pdf_doc_add_page_content(" Q", 2); + + pdf_dev_reset_fonts(); + + return 0; +} + + +int +pdf_dev_push_gstate (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs0; + + gs0 = NEW(1, pdf_gstate); + + init_a_gstate(gs0); + + m_stack_push(gss, gs0); + + return 0; +} + + +int +pdf_dev_pop_gstate (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs; + + if (m_stack_depth(gss) <= 1) { /* Initial state at bottom */ + WARN("Too many grestores."); + return -1; + } + + gs = m_stack_pop(gss); + clear_a_gstate(gs); + RELEASE(gs); + + return 0; +} + + +int +pdf_dev_current_depth (void) +{ + return (m_stack_depth(&gs_stack) - 1); /* 0 means initial state */ +} + +void +pdf_dev_grestore_to (int depth) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs; + + ASSERT(depth >= 0); + + if (m_stack_depth(gss) > depth + 1) { + WARN("Closing pending transformations at end of page/XObject."); + } + + while (m_stack_depth(gss) > depth + 1) { + pdf_doc_add_page_content(" Q", 2); + gs = m_stack_pop(gss); + clear_a_gstate(gs); + RELEASE(gs); + } + pdf_dev_reset_fonts(); + + return; +} + +int +pdf_dev_currentpoint (pdf_coord *p) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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 */ + +int +pdf_dev_concat (const pdf_tmatrix *M) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_path *cpa = &gs->path; + pdf_coord *cpt = &gs->cp; + pdf_tmatrix *CTM = &gs->matrix; + pdf_tmatrix W; + char *buf = FORMAT_BUFF_PTR(NULL); + int len = 0; + + ASSERT(M); + + /* Adobe Reader erases page content if there are + * non invertible transformation. + */ + if (fabs(detP(M)) < 1.0e-8) { + 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) > 1.e-8 || fabs(M->b) > 1.e-8 + || fabs(M->c) > 1.e-8 || fabs(M->d - 1.0) > 1.e-8 + || fabs(M->e) > 1.e-8 || fabs(M->f) > 1.e-8) { + buf[len++] = ' '; + len += pdf_sprint_matrix(buf + len, M); + buf[len++] = ' '; + buf[len++] = 'c'; + buf[len++] = 'm'; + pdf_doc_add_page_content(buf, len); + + 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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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); + gs->miterlimit = mlimit; + } + + return 0; +} + +int +pdf_dev_setlinecap (int capstyle) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + if (gs->linecap != capstyle) { + len = sprintf(buf, " %d J", capstyle); + pdf_doc_add_page_content(buf, len); + gs->linecap = capstyle; + } + + return 0; +} + +int +pdf_dev_setlinejoin (int joinstyle) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + if (gs->linejoin != joinstyle) { + len = sprintf(buf, " %d j", joinstyle); + pdf_doc_add_page_content(buf, len); + gs->linejoin = joinstyle; + } + + return 0; +} + +int +pdf_dev_setlinewidth (double width) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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); + gs->linewidth = width; + } + + return 0; +} + +int +pdf_dev_setdash (int count, double *pattern, double offset) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + int i; + + gs->linedash.num_dash = count; + gs->linedash.offset = offset; + pdf_doc_add_page_content(" [", 2); + for (i = 0; i < count; i++) { + buf[0] = ' '; + len = pdf_sprint_length (buf + 1, pattern[i]); + pdf_doc_add_page_content(buf, len + 1); + gs->linedash.pattern[i] = pattern[i]; + } + pdf_doc_add_page_content("] ", 2); + len = pdf_sprint_length (buf, offset); + pdf_doc_add_page_content(buf, len); + pdf_doc_add_page_content(" d", 2); + + return 0; +} + +#if 0 +int +pdf_dev_setflat (int flatness) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + int len = 0; + char *buf = FORMAT_BUFF_PTR(NULL); + + 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); + } + + return 0; +} +#endif /* 0 */ + +/* ZSYUEDVEDEOF */ +int +pdf_dev_clip (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_path *cpa = &gs->path; + + return pdf_dev__flushpath(NULL, cpa, 'W', PDF_FILL_RULE_NONZERO, 0); +} + +int +pdf_dev_eoclip (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_path *cpa = &gs->path; + + return pdf_dev__flushpath(NULL, cpa, 'W', PDF_FILL_RULE_EVENODD, 0); +} + +int +pdf_dev_flushpath (char p_op, int fill_rule) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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(NULL, cpa, p_op, fill_rule, 1); + pdf_path__clearpath(cpa); + + gs->flags &= ~GS_FLAG_CURRENTPOINT_SET; + + return error; +} + +int +pdf_dev_newpath (void) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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); + + return 0; +} + +int +pdf_dev_moveto (double x, double y) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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_vcurveto (double x0, double y0, + double x1, double y1) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_path *cpa = &gs->path; + pdf_coord *cpt = &gs->cp; + pdf_coord p0, p1; + + p0.x = x0; p0.y = y0; + p1.x = x1; p1.y = y1; + + return pdf_path__curveto(cpa, cpt, cpt, &p0, &p1); +} + +int +pdf_dev_ycurveto (double x0, double y0, + double x1, double y1) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_path *cpa = &gs->path; + pdf_coord *cpt = &gs->cp; + pdf_coord p0, p1; + + p0.x = x0; p0.y = y0; + p1.x = x1; p1.y = y1; + + return pdf_path__curveto(cpa, cpt, &p0, &p1, &p1); +} + +int +pdf_dev_rcurveto (double x0, double y0, + double x1, double y1, + double x2, double y2) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_tmatrix *CTM = &gs->matrix; + + ASSERT(p); + + pdf_coord__transform(p, (M ? M : CTM)); + + return; +} + +#if 0 +void +pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + pdf_tmatrix *CTM = &gs->matrix; + + ASSERT(p); + + pdf_coord__itransform(p, (M ? M : CTM)); + + return; +} +#endif /* 0 */ + +int +pdf_dev_arc (double c_x , double c_y, double r, + double a_0 , double a_1) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_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); +} + +#if 0 +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(NULL, &r, M, 'S'); +} +#endif /* 0 */ + +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(NULL, &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(NULL, &r, NULL, 'W'); +} + +int +pdf_dev_rectadd (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; + path_added = 1; + + return pdf_dev__rectshape(NULL, &r, NULL, ' '); +} + +void +pdf_dev_set_fixed_point (double x, double y) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + gs->pt_fixee.x = x; + gs->pt_fixee.y = y; +} + +void +pdf_dev_get_fixed_point (pdf_coord *p) +{ + m_stack *gss = &gs_stack; + pdf_gstate *gs = m_stack_top(gss); + p->x = gs->pt_fixee.x; + p->y = gs->pt_fixee.y; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdraw.h b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.h new file mode 100644 index 00000000000..f24540ef2bf --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.h @@ -0,0 +1,172 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 /* 0 */ + +/* 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_vcurveto (double x0 , double y0, + double x1 , double y1); +extern int pdf_dev_ycurveto (double x0 , double y0, + double x1 , double y1); +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); + +#if 0 +extern int pdf_dev_rectstroke (double x, double y, + double w, double h, + const pdf_tmatrix *M /* optional */ + ); +#endif /* 0 */ + +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_rectadd (double x, double y, double w, double h); + +extern int pdf_dev_flushpath (char p_op, int fill_rule); + +#define pdf_dev_fill() pdf_dev_flushpath('f', PDF_FILL_RULE_NONZERO) +#define pdf_dev_eofill() pdf_dev_flushpath('f', PDF_FILL_RULE_EVENODD) +#define pdf_dev_stroke() pdf_dev_flushpath('S', PDF_FILL_RULE_NONZERO) +#define pdf_dev_fillstroke() pdf_dev_flushpath('B', PDF_FILL_RULE_NONZERO) + +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); +#if 0 +extern void pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M); +#endif /* 0 */ + +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); +#define pdf_dev_grestoreall() pdf_dev_grestore_to(0); + +extern int pdf_dev_currentcolor (pdf_color *color, int is_fill); +extern int pdf_dev_setcolor (const pdf_color *color, int is_fill); + +extern void pdf_dev_set_fixed_point (double x, double y); +extern void pdf_dev_get_fixed_point (pdf_coord *p); +#endif /* _PDF_DRAW_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfencrypt.c b/Build/source/texk/dvipdf-x/xsrc/pdfencrypt.c new file mode 100644 index 00000000000..464f97e2b3d --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfencrypt.c @@ -0,0 +1,539 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#ifdef WIN32 +#include +#define getch _getch +#else /* !WIN32 */ +#include +#endif /* WIN32 */ + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "pdfobj.h" +#include "dpxcrypt.h" + +#include "pdfencrypt.h" + +#define MAX_KEY_LEN 16 +#define MAX_STR_LEN 32 + +static unsigned char algorithm, revision, key_size; +static unsigned long permission; + +static unsigned char key_data[MAX_KEY_LEN], id_string[MAX_KEY_LEN]; +static unsigned char opwd_string[MAX_STR_LEN], upwd_string[MAX_STR_LEN]; + +static unsigned long current_label = 0; +static unsigned current_generation = 0; + +static ARC4_KEY key; +static MD5_CONTEXT md5_ctx; + +static unsigned char md5_buf[MAX_KEY_LEN], key_buf[MAX_KEY_LEN]; +static unsigned char in_buf[MAX_STR_LEN], out_buf[MAX_STR_LEN]; + +static const unsigned char padding_string[MAX_STR_LEN] = { + 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 +}; + +static char owner_passwd[MAX_PWD_LEN], user_passwd[MAX_PWD_LEN]; + +static unsigned char verbose = 0; + +void pdf_enc_set_verbose (void) +{ + if (verbose < 255) verbose++; +} + +#define PRODUCER "%s-%s, Copyright \251 2002-2010 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata" +void pdf_enc_compute_id_string (char *dviname, char *pdfname) +{ + char *date_string, *producer; + time_t current_time; + struct tm *bd_time; + + MD5_init(&md5_ctx); + + date_string = NEW (15, char); + time(¤t_time); + bd_time = localtime(¤t_time); + sprintf (date_string, "%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); + MD5_write(&md5_ctx, (unsigned char *)date_string, strlen(date_string)); + RELEASE (date_string); + + producer = NEW (strlen(PRODUCER)+strlen(PACKAGE)+strlen(VERSION), char); + sprintf(producer, PRODUCER, PACKAGE, VERSION); + MD5_write(&md5_ctx, (unsigned char *)producer, strlen(producer)); + RELEASE (producer); + + if (dviname) + MD5_write(&md5_ctx, (unsigned char *)dviname, strlen(dviname)); + if (pdfname) + MD5_write(&md5_ctx, (unsigned char *)pdfname, strlen(pdfname)); + MD5_final(id_string, &md5_ctx); +} + +static void passwd_padding (unsigned char *src, unsigned char *dst) +{ + register int len = strlen((char *)src); + + if (len > MAX_STR_LEN) + len = MAX_STR_LEN; + + memcpy(dst, src, len); + memcpy(dst+len, padding_string, MAX_STR_LEN-len); +} + +static void compute_owner_password (void) +{ + register unsigned char i, j; + /* + * Algorithm 3.3 Computing the encryption dictionary's O (owner password) + * value + * + * 1. Pad or truncate the owner password string as described in step 1 + * of Algorithm 3.2. If there is no owner password, use the user + * password instead. (See implementation note 17 in Appendix H.) + */ + passwd_padding((unsigned char *)(strlen(owner_passwd) > 0 ? owner_passwd : user_passwd), in_buf); + /* + * 2. Initialize the MD5 hash function and pass the result of step 1 + * as input to this function. + */ + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, in_buf, MAX_STR_LEN); + MD5_final(md5_buf, &md5_ctx); + /* + * 3. (Revision 3 only) Do the following 50 times: Take the output + * from the previous MD5 hash and pass it as input into a new + * MD5 hash. + */ + if (revision == 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_ctx); + MD5_write(&md5_ctx, md5_buf, key_size); + MD5_final(md5_buf, &md5_ctx); + } + /* + * 4. Create an RC4 encryption key using the first n bytes of the output + * from the final MD5 hash, where n is always 5 for revision 2 but + * for revision 3 depends on the value of the encryption dictionary's + * Length entry. + */ + ARC4_set_key(&key, key_size, md5_buf); + /* + * 5. Pad or truncate the user password string as described in step 1 + * of Algorithm 3.2. + */ + passwd_padding((unsigned char *)user_passwd, in_buf); + /* + * 6. Encrypt the result of step 5, using an RC4 encryption function + * with the encryption key obtained in step 4. + */ + ARC4(&key, MAX_STR_LEN, in_buf, out_buf); + /* + * 7. (Revision 3 only) Do the following 19 times: Take the output + * from the previous invocation of the RC4 function and pass it + * as input to a new invocation of the function; use an encryption + * key generated by taking each byte of the encryption key obtained + * in step 4 and performing an XOR (exclusive or) operation between + * that byte and the single-byte value of the iteration counter + * (from 1 to 19). + */ + if (revision == 3) + for (i = 1; i <= 19; i++) { + memcpy(in_buf, out_buf, MAX_STR_LEN); + for (j = 0; j < key_size; j++) + key_buf[j] = md5_buf[j] ^ i; + ARC4_set_key(&key, key_size, key_buf); + ARC4(&key, MAX_STR_LEN, in_buf, out_buf); + } + /* + * 8. Store the output from the final invocation of the RC4 function + * as the value of the O entry in the encryption dictionary. + */ + memcpy(opwd_string, out_buf, MAX_STR_LEN); +} + +static void compute_encryption_key (unsigned char *pwd) +{ + register unsigned char i; + /* + * Algorithm 3.2 Computing an encryption key + * + * 1. Pad or truncate the password string to exactly 32 bytes. If the + * password string is more than 32 bytes long, use only its first + * 32 bytes; if it is less than 32 bytes long, pad it by appending + * the required number of additional bytes from the beginning of + * the following padding string: + * + * < 28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08 + * 2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A > + * + * That is, if the password string is n bytes long, append the + * first 32 - n bytes of the padding string to the end of the + * password string. If the password string is empty (zero-length), + * meaning there is no user password, substitute the entire + * padding string in its place. + */ + passwd_padding(pwd, in_buf); + /* + * 2. Initialize the MD5 hash function and pass the result of step 1 + * as input to this fuction. + */ + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, in_buf, MAX_STR_LEN); + /* + * 3. Pass the value of the encryption dictionary's O entry to the + * MD5 hash function. (Algorithm 3.3 shows how the O value is + * computed.) + */ + MD5_write(&md5_ctx, opwd_string, MAX_STR_LEN); + /* + * 4. Treat the value of the P entry as an unsigned 4-byte integer + * and pass these bytes to the MD5 hash function, low-order byte + * first. + */ + in_buf[0] = (unsigned char)(permission) & 0xFF; + in_buf[1] = (unsigned char)(permission >> 8) & 0xFF; + in_buf[2] = (unsigned char)(permission >> 16) & 0xFF; + in_buf[3] = (unsigned char)(permission >> 24) & 0xFF; + MD5_write(&md5_ctx, in_buf, 4); + /* + * 5. Pass the first element of the file's file identifier array + * (the value of the ID entry in the document's trailer dictionary; + * see Table 3.12 on page 68) to the MD5 hash function and + * finish the hash. + */ + MD5_write(&md5_ctx, id_string, MAX_KEY_LEN); + MD5_final(md5_buf, &md5_ctx); + /* + * 6. (Revision 3 only) Do the following 50 times; Take the output from + * the previous MD5 hash and pass it as input into a new MD5 hash. + */ + if (revision == 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_ctx); + MD5_write(&md5_ctx, md5_buf, key_size); + MD5_final(md5_buf, &md5_ctx); + } + /* + * 7. Set the encryption key to the first n bytes of the output from + * the final MD5 hash, where n is always 5 for revision 2 but for + * revision 3 depends on the value of the encryption dictionary's + * Length entry. + */ + memcpy(key_data, md5_buf, key_size); +} + +static void compute_user_password (void) +{ + register unsigned char i, j; + /* + * Algorithm 3.4 Computing the encryption dictionary's U (user password) + * value (Revision 2) + * + * 1. Create an encryption key based on the user password string, as + * described in Algorithm 3.2. + * + * 2. Encrypt the 32-byte padding string shown in step 1 of Algorithm + * 3.2, using an RC4 encryption fuction with the encryption key from + * the preceeding step. + * + * 3. Store the result of step 2 as the value of the U entry in the + * encryption dictionary. + */ + /* + * Algorithm 3.5 Computing the encryption dictionary's U (user password) + * value (Revision 3) + * + * 1. Create an encryption key based on the user password string, as + * described in Algorithm 3.2. + * + * 2. Initialize the MD5 hash function and pass the 32-byte padding + * string shown in step 1 of Algorithm 3.2 as input to this function. + * + * 3. Pass the first element of the file's file identifier array (the + * value of the ID entry in the document's trailer dictionary; see + * Table 3.12 on page 68) to the hash function and finish the hash. + * + * 4. Encrypt the 16-byte result of the hash, using an RC4 encryption + * function with the encryption key from step 1. + * + * 5. Do the following 19 times: Take the output from the previous + * invocation of the RC4 function and pass it as input to a new + * invocation of the function; use an encryption key generated by + * taking each byte of the original encryption key (obtained in + * step 1) and performing an XOR (exclusive or) operation between + * that byte and the single-byte value of the iteration counter + * (from 1 to 19). + * + * 6. Append 16 bytes of arbitrary padding to the output from the + * final invocation of the RC4 function and store the 32-byte + * result as the value of the U entry in the encryption dictionary. + */ + compute_encryption_key((unsigned char *)user_passwd); + + switch (revision) { + case 2: + ARC4_set_key(&key, key_size, key_data); + ARC4(&key, MAX_STR_LEN, padding_string, out_buf); + break; + case 3: + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, padding_string, MAX_STR_LEN); + + MD5_write(&md5_ctx, id_string, MAX_KEY_LEN); + MD5_final(md5_buf, &md5_ctx); + + ARC4_set_key(&key, key_size, key_data); + ARC4(&key, MAX_KEY_LEN, md5_buf, out_buf); + + for (i = 1; i <= 19; i++) { + memcpy(in_buf, out_buf, MAX_KEY_LEN); + for (j = 0; j < key_size; j++) + key_buf[j] = key_data[j] ^ i; + ARC4_set_key(&key, key_size, key_buf); + ARC4(&key, MAX_KEY_LEN, in_buf, out_buf); + } + break; + default: + ERROR("Invalid revision number.\n"); + } + + memcpy(upwd_string, out_buf, MAX_STR_LEN); +} + +#ifdef WIN32 +static char *getpass (const char *prompt) +{ + static char pwd_buf[128]; + 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') + break; + fputs("*", stderr); + fflush(stderr); + } + pwd_buf[i] = '\0'; + fputs("\n", stderr); + return pwd_buf; +} +#endif + +void pdf_enc_set_passwd (unsigned bits, unsigned perm, const char *owner_pw, const char *user_pw) +{ + char *retry_passwd; + + if (owner_pw) { + strncpy(owner_passwd, owner_pw, MAX_PWD_LEN); + } else + while (1) { + strncpy(owner_passwd, getpass("Owner password: "), MAX_PWD_LEN); + retry_passwd = getpass("Re-enter owner password: "); + if (!strncmp(owner_passwd, retry_passwd, MAX_PWD_LEN)) + break; + fputs("Password is not identical.\nTry again.\n", stderr); + fflush(stderr); + } + + if (user_pw) { + strncpy(user_passwd, user_pw, MAX_PWD_LEN); + } else + while (1) { + strncpy(user_passwd, getpass("User password: "), MAX_PWD_LEN); + retry_passwd = getpass("Re-enter user password: "); + if (!strncmp(user_passwd, retry_passwd, MAX_PWD_LEN)) + break; + fputs("Password is not identical.\nTry again.\n", stderr); + fflush(stderr); + } + + key_size = (unsigned char)(bits / 8); + algorithm = (key_size == 5 ? 1 : 2); + permission = (unsigned long)perm | 0x000000C0; + revision = ((algorithm == 1 && permission < 0x100) ? 2 : 3); + if (revision == 3) + permission |= 0xFFFFF000; + + compute_owner_password(); + compute_user_password(); +} + +void pdf_encrypt_data (unsigned char *data, unsigned long len) +{ + unsigned char *result; + + memcpy(in_buf, key_data, key_size); + in_buf[key_size] = (unsigned char)(current_label) & 0xFF; + in_buf[key_size+1] = (unsigned char)(current_label >> 8) & 0xFF; + in_buf[key_size+2] = (unsigned char)(current_label >> 16) & 0xFF; + in_buf[key_size+3] = (unsigned char)(current_generation) & 0xFF; + in_buf[key_size+4] = (unsigned char)(current_generation >> 8) & 0xFF; + + MD5_init(&md5_ctx); + MD5_write(&md5_ctx, in_buf, key_size+5); + MD5_final(md5_buf, &md5_ctx); + + result = NEW (len, unsigned char); + ARC4_set_key(&key, (key_size > 10 ? MAX_KEY_LEN : key_size+5), md5_buf); + ARC4(&key, len, data, result); + memcpy(data, result, len); + RELEASE (result); +} + +pdf_obj *pdf_encrypt_obj (void) +{ + pdf_obj *doc_encrypt; + +#ifdef DEBUG + fprintf (stderr, "(pdf_encrypt_obj)"); +#endif + + doc_encrypt = pdf_new_dict (); + + /* KEY : Filter + * TYPE : name + * VALUE: (Required) The name of the security handler for this document; + * see below. Default value: Standard, for the built-in security + * handler. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("Filter"), + pdf_new_name ("Standard")); + /* KEY : V + * TYPE : number + * VALUE: (Optional but strongly recommended) A code specifying the + * algorithm to be used in encrypting and decrypting the document: + * 0 An algorithm that is undocumented and no longer supported, + * and whose use is strongly discouraged. + * 1 Algorithm 3.1 on page 73, with an encryption key length + * of 40 bits; see below. + * 2 (PDF 1.4) Algorithm 3.1 on page 73, but allowing encryption + * key lengths greater than 40 bits. + * 3 (PDF 1.4) An unpublished algorithm allowing encryption key + * lengths ranging from 40 to 128 bits. (This algorithm is + * unpublished as an export requirement of the U.S. Department + * of Commerce.) + * The default value if this entry is omitted is 0, but a value + * of 1 or greater is strongly recommended. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("V"), + pdf_new_number (algorithm)); + /* KEY : Length + * TYPE : integer + * VALUE: (Optional; PDF 1.4; only if V is 2 or 3) The length of the + * encryption key, in bits. The value must be a multiple of 8, + * in the range 40 to 128. Default value: 40. + */ + if (algorithm > 1) + pdf_add_dict (doc_encrypt, + pdf_new_name ("Length"), + pdf_new_number (key_size * 8)); + /* KEY : R + * TYPE : number + * VALUE: (Required) A number specifying which revision of the standard + * security handler should be used to interpret this dictionary. + * The revison number should be 2 if the document is encrypted + * with a V value less than 2; otherwise this value should be 3. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("R"), + pdf_new_number (revision)); + /* KEY : O + * TYPE : string + * VALUE: (Required) A 32-byte string, based on both the owner and + * user passwords, that is used in computing the encryption + * key and in determining whether a valid owner password was + * entered. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("O"), + pdf_new_string (opwd_string, 32)); + /* KEY : U + * TYPE : string + * VALUE: (Required) A 32-byte string, based on the user password, + * that is used in determining whether to prompt the user + * for a password and, if so, whether a valid user or owner + * password was entered. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("U"), + pdf_new_string (upwd_string, 32)); + /* KEY : P + * TYPE : integer + * VALUE: (Required) A set of flags specifying which operations are + * permitted when the document is opened with user access. + */ + pdf_add_dict (doc_encrypt, + pdf_new_name ("P"), + pdf_new_number (permission)); + + return doc_encrypt; +} + +pdf_obj *pdf_enc_id_array (void) +{ + pdf_obj *id = pdf_new_array(); + pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN)); + pdf_add_array(id, pdf_new_string(id_string, MAX_KEY_LEN)); + return id; +} + +void pdf_enc_set_label (unsigned long label) +{ + current_label = label; +} + +void pdf_enc_set_generation (unsigned generation) +{ + current_generation = generation; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfnames.c b/Build/source/texk/dvipdf-x/xsrc/pdfnames.c new file mode 100644 index 00000000000..83eb997e249 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfnames.c @@ -0,0 +1,488 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "numbers.h" + +/* Hash */ +#include "dpxutil.h" + +#include "pdfobj.h" + +#include "pdfnames.h" + +struct obj_data +{ + pdf_obj *object_ref; + pdf_obj *object; + int reserve; /* 1 if object is not actually defined. */ +}; + +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(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 void +flush_objects (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 (value->reserve) { + WARN("Unresolved object reference \"%s\" found!!!", + printable_key(key, keylen)); + } + if (value->object) { + pdf_release_obj(value->object); + } + if (value->object_ref) { + pdf_release_obj(value->object_ref); + } + value->object = NULL; + value->object_ref = NULL; + value->reserve = 0; + } while (ht_iter_next(&iter) >= 0); + ht_clear_iter(&iter); + } +} + +static void CDECL +hval_free (void *hval) +{ + struct obj_data *value; + + value = (struct obj_data *) hval; + if (value->object) + pdf_release_obj(value->object); + if (value->object_ref) + pdf_release_obj(value->object_ref); + + value->object = NULL; + value->object_ref = NULL; + value->reserve = 0; + + 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; +} + +void +pdf_delete_name_tree (struct ht_table **names) +{ + ASSERT(names && *names); + + flush_objects (*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->object_ref = NULL; + value->reserve = 0; + ht_append_table(names, key, keylen, value); + } else { + if (value->reserve) { + /* null object is used for undefined objects */ + pdf_copy_object(value->object, object); + pdf_release_obj(object); /* PLEASE FIX THIS!!! */ + } else { + if (value->object || value->object_ref) { + if (pdf_obj_get_verbose()) { + WARN("Object reference with key \"%s\" is in use.", printable_key(key, keylen)); + } + pdf_release_obj(object); + return -1; + } else { + value->object = object; + } + } + value->reserve = 0; + } + + return 0; +} + +int +pdf_names_add_reference (struct ht_table *names, + const void *key, int keylen, pdf_obj *object_ref) +{ + struct obj_data *value; + + ASSERT(names); + + if (!PDF_OBJ_INDIRECTTYPE(object_ref)) { + WARN("Invalid type: @%s is not reference...", + printable_key(key, keylen)); + return -1; + } + + value = ht_lookup_table(names, key, keylen); + if (!value) { + value = NEW(1, struct obj_data); + value->object = NULL; + value->object_ref = object_ref; + value->reserve = 0; + ht_append_table(names, key, keylen, value); + } else { + if (value->object || value->object_ref) { + WARN("Object reference \"%s\" is in use.", + printable_key(key, keylen)); + WARN("Please close it before redefining."); + return -1; + } else { + value->object = NULL; + value->object_ref = object_ref; + } + value->reserve = 0; + } + + return 0; +} + +/* + * 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; + + ASSERT(names); + + value = ht_lookup_table(names, key, keylen); + /* Reserve object label */ + if (!value) { + value = NEW(1, struct obj_data); + value->object = pdf_new_null(); /* dummy */ + value->object_ref = NULL; + value->reserve = 1; + ht_append_table(names, key, keylen, value); + } + + if (!value->object_ref) { + if (value->object) + value->object_ref = pdf_ref_obj(value->object); + else { + WARN("Object @%s not defined or already closed.", + printable_key(key, keylen)); + } + } + + return pdf_link_obj(value->object_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) + return NULL; + else if (!value->object) { + WARN("Object @%s not defined or 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) { + WARN("Tried to release nonexistent reference: %s", + printable_key(key, keylen)); + return -1; + } + + if (value->object) { + pdf_release_obj(value->object); + value->object = NULL; + } else { + WARN("Trying to close object @%s twice?", + printable_key(key, keylen)); + return -1; + } + + return 0; +} + +struct named_object +{ + char *key; + int keylen; + pdf_obj *value; +}; + +static int CDECL +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, long 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)); + break; + 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; + long 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, long *num_entries) +{ + struct named_object *objects; + struct ht_iter iter; + long count; + + ASSERT(ht_tab); + + *num_entries = count = ht_tab->count; + objects = NEW(count, struct named_object); + if (ht_set_iter(ht_tab, &iter) >= 0) { + do { + char *key; + int keylen; + struct obj_data *value; + + count--; + key = ht_iter_getkey(&iter, &keylen); + value = ht_iter_getval(&iter); + if (value->reserve) { + WARN("Named object \"%s\" not defined!!!", + printable_key(key, keylen)); + WARN("Replacing with null."); + objects[count].key = (char *) key; + objects[count].keylen = keylen; + objects[count].value = pdf_new_null(); + } else if (value->object_ref) { + objects[count].key = (char *) key; + objects[count].keylen = keylen; + objects[count].value = pdf_link_obj(value->object_ref); + } else if (value->object) { + objects[count].key = (char *) key; + objects[count].keylen = keylen; + objects[count].value = pdf_link_obj(value->object); + } else { + WARN("Named object \"%s\" not defined!!!", + printable_key(key, keylen)); + WARN("Replacing with null."); + objects[count].key = (char *) key; + objects[count].keylen = keylen; + objects[count].value = pdf_new_null(); + } + } while (ht_iter_next(&iter) >= 0 && count > 0); + ht_clear_iter(&iter); + } + + return objects; +} + +pdf_obj * +pdf_names_create_tree (struct ht_table *names) +{ + pdf_obj *name_tree; + struct named_object *flat; + long count; + + flat = flat_table(names, &count); + if (!flat) + name_tree = NULL; + else { + if (count < 1) + 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/dvipdf-x/xsrc/pdfnames.h b/Build/source/texk/dvipdf-x/xsrc/pdfnames.h new file mode 100644 index 00000000000..ca4a7dbc0bf --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfnames.h @@ -0,0 +1,52 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 int pdf_names_add_reference (struct ht_table *names, + const void *key, int keylen, pdf_obj *object_ref); +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); + +/* Really create name tree... */ +extern pdf_obj *pdf_names_create_tree (struct ht_table *names); + +extern char *printable_key (const char *key, int keylen); + +#endif /* _PDF_NAMES_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfobj.c b/Build/source/texk/dvipdf-x/xsrc/pdfobj.c new file mode 100644 index 00000000000..30a9b6bdb3b --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfobj.c @@ -0,0 +1,3170 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "dpxutil.h" +#include "pdflimits.h" +#include "pdfencrypt.h" +#include "pdfparse.h" + +#ifdef HAVE_ZLIB +#include +#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; + + unsigned long label; /* Only used for indirect objects + all other "label" to zero */ + unsigned short generation; /* Only used if "label" is used */ + unsigned refcount; /* Number of links to this object */ + int flags; + void *data; +}; + +struct pdf_boolean +{ + char value; +}; + +struct pdf_number +{ + double value; +}; + +struct pdf_string +{ + unsigned char *string; + unsigned short length; +}; + +struct pdf_name +{ + char *name; +}; + +struct pdf_array +{ + unsigned long max; + unsigned long size; + struct pdf_obj **values; +}; + +struct pdf_dict +{ + struct pdf_obj *key; + struct pdf_obj *value; + struct pdf_dict *next; +}; + +struct pdf_stream +{ + struct pdf_obj *dict; + unsigned char *stream; + long *objstm_data; /* used for object streams */ + unsigned long stream_length; + unsigned long max_length; + unsigned char _flags; +}; + +struct pdf_indirect +{ + pdf_file *pf; + unsigned long label; + unsigned short 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; + +static FILE *pdf_output_file = NULL; + +static long pdf_output_file_position = 0; +static long pdf_output_line_position = 0; +static long compression_saved = 0; + +#define FORMAT_BUF_SIZE 4096 +static char format_buffer[FORMAT_BUF_SIZE]; + +typedef struct xref_entry +{ + unsigned char type; /* object storage type */ + unsigned long field2; /* offset in file or object stream */ + unsigned short field3; /* generation or index */ + pdf_obj *direct; /* used for imported objects */ + pdf_obj *indirect; /* used for imported objects */ +} xref_entry; + +static xref_entry *output_xref; + +static unsigned long pdf_max_ind_objects; +static unsigned long next_label; + +static unsigned long startxref; + +struct pdf_file +{ + FILE *file; + pdf_obj *trailer; + xref_entry *xref_table; + long num_obj; + long file_size; + int version; +}; + +static pdf_obj *output_stream; + +#define OBJSTM_MAX_OBJS 200 +/* the limit is only 100 for linearized PDF */ + +static int enc_mode; +static int doc_enc_mode; + +static pdf_obj *trailer_dict; +static pdf_obj *xref_stream; + +/* Internal static routines */ + +static void pdf_flush_obj (pdf_obj *object, FILE *file); +static void pdf_label_obj (pdf_obj *object); +static void pdf_write_obj (pdf_obj *object, FILE *file); + +static void set_objstm_data (pdf_obj *objstm, long *data); +static long *get_objstm_data (pdf_obj *objstm); +static void release_objstm (pdf_obj *objstm); + +static void pdf_out_char (FILE *file, char c); +static void pdf_out (FILE *file, const void *buffer, long length); + +static void release_indirect (pdf_indirect *data); +static void write_indirect (pdf_indirect *indirect, FILE *file); + +static void release_boolean (pdf_obj *data); +static void write_boolean (pdf_boolean *data, FILE *file); + +static void release_null (pdf_null *data); +static void write_null (pdf_null *data, FILE *file); + +static void release_number (pdf_number *number); +static void write_number (pdf_number *number, FILE *file); + +static void write_string (pdf_string *str, FILE *file); +static void release_string (pdf_string *str); + +static void write_name (pdf_name *name, FILE *file); +static void release_name (pdf_name *name); + +static void write_array (pdf_array *array, FILE *file); +static void release_array (pdf_array *array); + +static void write_dict (pdf_dict *dict, FILE *file); +static void release_dict (pdf_dict *dict); + +static void write_stream (pdf_stream *stream, FILE *file); +static void release_stream (pdf_stream *stream); + +static int verbose = 0; +static char compression_level = 9; + +void +pdf_set_compression (int level) +{ +#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) + compression_level = level; + else { + ERROR("set_compression: invalid compression level: %d", level); + } +#endif /* !HAVE_ZLIB */ + + return; +} + +static unsigned pdf_version = PDF_VERSION_DEFAULT; + +void +pdf_set_version (unsigned version) +{ + /* Don't forget to update CIDFont_stdcc_def[] in cid.c too! */ + if (version >= PDF_VERSION_MIN && version <= PDF_VERSION_MAX) { + pdf_version = version; + } +} + +unsigned +pdf_get_version (void) +{ + return pdf_version; +} + +int +pdf_obj_get_verbose(void) +{ + return verbose; +} + +void +pdf_obj_set_verbose(void) +{ + verbose++; +} + +static pdf_obj *current_objstm = NULL; +static int do_objstm; + +static void +add_xref_entry (unsigned long label, unsigned char type, unsigned long field2, unsigned short field3) +{ + if (label >= pdf_max_ind_objects) { + pdf_max_ind_objects = (label/IND_OBJECTS_ALLOC_SIZE+1)*IND_OBJECTS_ALLOC_SIZE; + output_xref = RENEW(output_xref, pdf_max_ind_objects, xref_entry); + } + + output_xref[label].type = type; + output_xref[label].field2 = field2; + output_xref[label].field3 = field3; + output_xref[label].direct = NULL; + output_xref[label].indirect = NULL; +} + +#define BINARY_MARKER "%\344\360\355\370\n" +void +pdf_out_init (const char *filename, int do_encryption) +{ + char v; + + output_xref = NULL; + pdf_max_ind_objects = 0; + add_xref_entry(0, 0, 0, 0xffff); + next_label = 1; + + if (pdf_version >= 5) { + xref_stream = pdf_new_stream(STREAM_COMPRESS); + xref_stream->flags |= OBJ_NO_ENCRYPT; + trailer_dict = pdf_stream_dict(xref_stream); + pdf_add_dict(trailer_dict, pdf_new_name("Type"), pdf_new_name("XRef")); + do_objstm = 1; + } else { + xref_stream = NULL; + trailer_dict = pdf_new_dict(); + do_objstm = 0; + } + + output_stream = NULL; + + if (filename == NULL) { /* no filename: writing to stdout */ +#ifdef WIN32 + setmode(fileno(stdout), _O_BINARY); +#endif + pdf_output_file = stdout; + } + else + pdf_output_file = MFOPEN(filename, FOPEN_WBIN_MODE); + + if (!pdf_output_file) { + if (strlen(filename) < 128) + ERROR("Unable to open \"%s\".", filename); + else + ERROR("Unable to open file."); + } + pdf_out(pdf_output_file, "%PDF-1.", strlen("%PDF-1.")); + v = '0' + pdf_version; + pdf_out(pdf_output_file, &v, 1); + pdf_out(pdf_output_file, "\n", 1); + pdf_out(pdf_output_file, BINARY_MARKER, strlen(BINARY_MARKER)); + + enc_mode = 0; + doc_enc_mode = do_encryption; +} + +static void +dump_xref_table (void) +{ + long length; + unsigned long i; + + pdf_out(pdf_output_file, "xref\n", 5); + + length = sprintf(format_buffer, "%d %lu\n", 0, next_label); + pdf_out(pdf_output_file, format_buffer, 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 < next_label; i++) { + unsigned char type = output_xref[i].type; + if (type > 1) + ERROR("object type %hu not allowed in xref table", type); + length = sprintf(format_buffer, "%010lu %05hu %c \n", + output_xref[i].field2, output_xref[i].field3, + type ? 'n' : 'f'); + pdf_out(pdf_output_file, format_buffer, length); + } +} + +static void +dump_trailer_dict (void) +{ + pdf_out(pdf_output_file, "trailer\n", 8); + enc_mode = 0; + write_dict(trailer_dict->data, pdf_output_file); + pdf_release_obj(trailer_dict); + pdf_out_char(pdf_output_file, '\n'); +} + +/* + * output a PDF 1.5 cross-reference stream; + * contributed by Matthias Franz (March 21, 2007) + */ +static void +dump_xref_stream (void) +{ + unsigned long pos, i; + unsigned poslen; + unsigned char buf[7] = {0, 0, 0, 0, 0}; + + pdf_obj *w; + + /* determine the necessary size of the offset field */ + pos = 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(trailer_dict, pdf_new_name("W"), w); + + /* We need the xref entry for the xref stream right now */ + add_xref_entry(next_label-1, 1, startxref, 0); + + for (i = 0; i < next_label; i++) { + unsigned j; + unsigned short f3; + buf[0] = output_xref[i].type; + pos = output_xref[i].field2; + for (j = poslen; j--; ) { + buf[1+j] = (unsigned char) pos; + pos >>= 8; + } + f3 = output_xref[i].field3; + buf[poslen+1] = (unsigned char) (f3 >> 8); + buf[poslen+2] = (unsigned char) (f3); + pdf_add_stream(xref_stream, &buf, poslen+3); + } + + pdf_release_obj(xref_stream); +} + +void +pdf_out_flush (void) +{ + if (pdf_output_file) { + long length; + + /* Flush current object stream */ + if (current_objstm) { + release_objstm(current_objstm); + 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 (xref_stream) + pdf_label_obj(xref_stream); + + /* Record where this xref is for trailer */ + startxref = pdf_output_file_position; + + pdf_add_dict(trailer_dict, pdf_new_name("Size"), + pdf_new_number(next_label)); + + if (xref_stream) + dump_xref_stream(); + else { + dump_xref_table(); + dump_trailer_dict(); + } + + /* Done with xref table */ + RELEASE(output_xref); + + pdf_out(pdf_output_file, "startxref\n", 10); + length = sprintf(format_buffer, "%lu\n", startxref); + pdf_out(pdf_output_file, format_buffer, length); + pdf_out(pdf_output_file, "%%EOF\n", 6); + + MESG("\n"); + if (verbose) { + if (compression_level > 0) { + MESG("Compression saved %ld bytes%s\n", compression_saved, + pdf_version < 5 ? ". Try \"-V 5\" for better compression" : ""); + } + } + MESG("%ld bytes written", pdf_output_file_position); + + MFCLOSE(pdf_output_file); + } +} + +void +pdf_error_cleanup (void) +{ + /* + * This routine is the cleanup required for an abnormal exit. + * For now, simply close the file. + */ + if (pdf_output_file) + MFCLOSE(pdf_output_file); +} + + +void +pdf_set_root (pdf_obj *object) +{ + if (pdf_add_dict(trailer_dict, pdf_new_name("Root"), pdf_ref_obj(object))) { + ERROR("Root object already set!"); + } + /* 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 (doc_enc_mode) + object->flags |= OBJ_NO_OBJSTM; +} + +void +pdf_set_info (pdf_obj *object) +{ + if (pdf_add_dict(trailer_dict, pdf_new_name("Info"), pdf_ref_obj(object))) { + ERROR ("Info object already set!"); + } +} + +void +pdf_set_encrypt (pdf_obj *encrypt, pdf_obj *id) +{ + if (pdf_add_dict(trailer_dict, pdf_new_name("Encrypt"), pdf_ref_obj(encrypt))) { + ERROR("Encrypt object already set!"); + } + encrypt->flags |= OBJ_NO_ENCRYPT; + + pdf_add_dict(trailer_dict, pdf_new_name("ID"), id); +} + +static +void pdf_out_char (FILE *file, char c) +{ + if (output_stream && file == pdf_output_file) + pdf_add_stream(output_stream, &c, 1); + else { + fputc(c, file); + /* Keep tallys for xref table *only* if writing a pdf file. */ + if (file == pdf_output_file) { + pdf_output_file_position += 1; + if (c == '\n') + pdf_output_line_position = 0; + else + pdf_output_line_position += 1; + } + } +} + +static char xchar[] = "0123456789abcdef"; + +#define pdf_out_xchar(f,c) do {\ + pdf_out_char((f), xchar[((c) >> 4) & 0x0f]);\ + pdf_out_char((f), xchar[(c) & 0x0f]);\ +} while (0) + +static +void pdf_out (FILE *file, const void *buffer, long length) +{ + if (output_stream && file == pdf_output_file) + pdf_add_stream(output_stream, buffer, length); + else { + fwrite(buffer, 1, length, file); + /* Keep tallys for xref table *only* if writing a pdf file */ + if (file == pdf_output_file) { + pdf_output_file_position += length; + pdf_output_line_position += length; + /* "foo\nbar\n "... */ + if (length > 0 && + ((const char *)buffer)[length-1] == '\n') + pdf_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 (FILE *file) +{ + if (file == pdf_output_file && pdf_output_line_position >= 80) { + pdf_out_char(file, '\n'); + } else { + pdf_out_char(file, ' '); + } +} + +#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_INDIRECT) + +pdf_obj * +pdf_new_obj(int type) +{ + pdf_obj *result; + + if (type > PDF_INDIRECT || type < PDF_UNDEFINED) + 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; + + 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_obj *object) +{ + 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) { + object->label = next_label++; + object->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) +{ + if (INVALIDOBJ(object)) + ERROR("pdf_ref_obj(): passed invalid object."); + + if (object->refcount == 0) { + MESG("\nTrying to refer already released object!!!\n"); + pdf_write_obj(object, stderr); + ERROR("Cannot continue..."); + } + + if (PDF_OBJ_INDIRECTTYPE(object)) { + return pdf_link_obj(object); + } else { + if (object->label == 0) { + pdf_label_obj(object); + } + return pdf_new_indirect(NULL, object->label, object->generation); + } +} + +static void +release_indirect (pdf_indirect *data) +{ + RELEASE(data); +} + +static void +write_indirect (pdf_indirect *indirect, FILE *file) +{ + long length; + + ASSERT(!indirect->pf); + + length = sprintf(format_buffer, "%lu %hu R", indirect->label, indirect->generation); + pdf_out(file, format_buffer, length); +} + +pdf_obj * +pdf_new_null (void) +{ + pdf_obj *result; + + result = pdf_new_obj(PDF_NULL); + result->data = NULL; + + return result; +} + +static void +release_null (pdf_null *obj) +{ + return; +} + +static void +write_null (pdf_null *obj, FILE *file) +{ + pdf_out(file, "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_boolean *data, FILE *file) +{ + if (data->value) { + pdf_out(file, "true", 4); + } else { + pdf_out(file, "false", 5); + } +} + +void +pdf_set_boolean (pdf_obj *object, char value) +{ + pdf_boolean *data; + + TYPECHECK(object, PDF_BOOLEAN); + + data = object->data; + data->value = value; +} + +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_number *number, FILE *file) +{ + int count; + + count = pdf_sprint_number(format_buffer, number->value); + + pdf_out(file, format_buffer, 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; + + result = pdf_new_obj(PDF_STRING); + data = NEW(1, pdf_string); + result->data = data; + if (length != 0) { + data->length = length; + data->string = NEW(length+1, unsigned char); + memcpy(data->string, str, length); + /* Shouldn't assume NULL terminated. */ + data->string[length] = '\0'; + } else { + data->length = 0; + 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) +{ + int result = 0; + int 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 result; +} + +static void +write_string (pdf_string *str, FILE *file) +{ + unsigned char *s; + char wbuf[FORMAT_BUF_SIZE]; /* Shouldn't use format_buffer[]. */ + int nescc = 0, i, count; + + s = str->string; + + if (enc_mode) + pdf_encrypt_data(s, str->length); + + /* + * Count all ASCII non-printable characters. + */ + for (i = 0; i < str->length; i++) { + if (!isprint(s[i])) + nescc++; + } + /* + * If the string contains much escaped chars, then we write it as + * ASCII hex string. + */ + if (nescc > str->length / 3) { + pdf_out_char(file, '<'); + for (i = 0; i < str->length; i++) { + pdf_out_xchar(file, s[i]); + } + pdf_out_char(file, '>'); + } else { + pdf_out_char(file, '('); + /* + * 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 < str->length; i++) { + count = pdfobj_escape_str(wbuf, FORMAT_BUF_SIZE, &(s[i]), 1); + pdf_out(file, wbuf, count); + } + pdf_out_char(file, ')'); + } +} + +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; + unsigned 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_name *name, FILE *file) +{ + char *s; + int i, length; + + 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) == '%') +#endif + pdf_out_char(file, '/'); + for (i = 0; i < length; i++) { + if (s[i] < '!' || s[i] > '~' || s[i] == '#' || is_delim(s[i])) { + /* ^ "space" is here. */ + pdf_out_char (file, '#'); + pdf_out_xchar(file, s[i]); + } else { + pdf_out_char (file, s[i]); + } + } +} + +static void +release_name (pdf_name *data) +{ + if (data->name != NULL) { + RELEASE(data->name); + data->name = NULL; + } + RELEASE(data); +} + +void +pdf_set_name (pdf_obj *object, const char *name) +{ + pdf_name *data; + unsigned length; + + TYPECHECK(object, PDF_NAME); + + length = strlen(name); + data = object->data; + if (data->name != NULL) { + RELEASE(data->name); + } + if (length != 0) { + data->name = NEW(length+1, char); + memcpy(data->name, name, length); + data->name[length] = 0; + } else { + data->name = NULL; + } +} + +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_array *array, FILE *file) +{ + pdf_out_char(file, '['); + if (array->size > 0) { + unsigned long 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(file); + type1 = type2; + pdf_write_obj(array->values[i], file); + } else + WARN("PDF array element #ld undefined.", i); + } + } + pdf_out_char(file, ']'); +} + +pdf_obj * +pdf_get_array (pdf_obj *array, long 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 int +pdf_array_length (pdf_obj *array) +{ + pdf_array *data; + + TYPECHECK(array, PDF_ARRAY); + + data = (pdf_array *) array->data; + + return (unsigned int) data->size; +} + +static void +release_array (pdf_array *data) +{ + unsigned long 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, unsigned idx, pdf_obj *object) +{ + pdf_array *data; + long 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) { + int i; + + result = data->values[0]; + for (i = 1; i < data->size; i++) + data->values[i-1] = data->values[i]; + data->size--; + } + + return result; +} +#endif /* 0 */ + +/* Prepend an object to an array */ +void +pdf_unshift_array (pdf_obj *array, pdf_obj *object) +{ + pdf_array *data; + int i; + + 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 *); + } + for (i = 0; i < data->size; i++) + data->values[i+1] = data->values[i]; + 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 /* 0 */ + +static void +write_dict (pdf_dict *dict, FILE *file) +{ + pdf_out (file, "<<\n", 3); /* dropping \n saves few kb. */ + while (dict->key != NULL) { + pdf_write_obj(dict->key, file); + if (pdf_need_white(PDF_NAME, (dict->value)->type)) { + pdf_out_white(file); + } + pdf_write_obj(dict->value, file); + pdf_out_char (file, '\n'); /* removing this saves few kb. */ + dict = dict->next; + } + pdf_out(file, ">>", 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 /* 0 */ + +/* 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; + + result->data = data; + result->flags |= OBJ_NO_OBJSTM; + + return result; +} + +static void +write_stream (pdf_stream *stream, FILE *file) +{ + unsigned char *filtered; + unsigned long filtered_length; + unsigned long buffer_length; + unsigned char *buffer; + + /* + * 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; + +#if 0 + if (stream->stream_length < 10) + stream->_flags &= ^STREAM_COMPRESS; +#endif + +#ifdef HAVE_ZLIB + /* Apply compression filter if requested */ + if (stream->stream_length > 0 && + (stream->_flags & STREAM_COMPRESS) && + compression_level > 0) { + + pdf_obj *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, compression_level)) { + ERROR("Zlib error"); + } +#else + if (compress(buffer, &buffer_length, filtered, + filtered_length)) { + ERROR ("Zlib error"); + } +#endif /* HAVE_ZLIB_COMPRESS2 */ + RELEASE(filtered); + compression_saved += filtered_length - buffer_length + - (filters ? strlen("/FlateDecode "): strlen("/Filter/FlateDecode\n")); + + filtered = buffer; + filtered_length = buffer_length; + } +#endif /* HAVE_ZLIB */ + +#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(stream->dict, file); + + pdf_out(file, "\nstream\n", 8); + + if (enc_mode) + pdf_encrypt_data(filtered, filtered_length); + + if (filtered_length > 0) { + pdf_out(file, 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(file, "\n", 1); + pdf_out(file, "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; +} + +long +pdf_stream_length (pdf_obj *stream) +{ + pdf_stream *data; + + TYPECHECK(stream, PDF_STREAM); + + data = stream->data; + + return (long) data->stream_length; +} + +static void +set_objstm_data (pdf_obj *objstm, long *data) { + TYPECHECK(objstm, PDF_STREAM); + + ((pdf_stream *) objstm->data)->objstm_data = data; +} + +static long * +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, long 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 +int +pdf_add_stream_flate (pdf_obj *dst, const void *data, long len) +{ + z_stream z; + Bytef wbuf[WBUF_SIZE]; + + z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; + + z.next_in = (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 -1; + } + + for (;;) { + int status; + status = inflate(&z, Z_NO_FLUSH); + if (status == Z_STREAM_END) + break; + else if (status != Z_OK) { + WARN("inflate() failed. Broken PDF file?"); + inflateEnd(&z); + return -1; + } + + if (z.avail_out == 0) { + pdf_add_stream(dst, wbuf, WBUF_SIZE); + z.next_out = wbuf; + z.avail_out = WBUF_SIZE; + } + } + + if (WBUF_SIZE - z.avail_out > 0) + pdf_add_stream(dst, wbuf, WBUF_SIZE - z.avail_out); + + return (inflateEnd(&z) == Z_OK ? 0 : -1); +} +#endif + + +int +pdf_concat_stream (pdf_obj *dst, pdf_obj *src) +{ + const char *stream_data; + long stream_length; + pdf_obj *stream_dict; + pdf_obj *filter; + + if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src)) + ERROR("Invalid type."); + + stream_data = pdf_stream_dataptr(src); + stream_length = pdf_stream_length (src); + stream_dict = pdf_stream_dict (src); + + if (pdf_lookup_dict(stream_dict, "DecodeParms")) { + WARN("Streams with DecodeParams not supported."); + return -1; + } + + filter = pdf_lookup_dict(stream_dict, "Filter"); + if (!filter) { + pdf_add_stream(dst, stream_data, stream_length); + return 0; +#if HAVE_ZLIB + } else { + char *filter_name; + if (PDF_OBJ_NAMETYPE(filter)) { + filter_name = pdf_name_value(filter); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return pdf_add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } else if (PDF_OBJ_ARRAYTYPE(filter)) { + if (pdf_array_length(filter) > 1) { + WARN("Multiple DecodeFilter not supported."); + return -1; + } else { + filter_name = pdf_name_value(pdf_get_array(filter, 0)); + if (filter_name && !strcmp(filter_name, "FlateDecode")) + return pdf_add_stream_flate(dst, stream_data, stream_length); + else { + WARN("DecodeFilter \"%s\" not supported.", filter_name); + return -1; + } + } + } else + ERROR("Broken PDF file?"); +#endif /* HAVE_ZLIB */ + } + + return -1; +} + +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 /* 0 */ + +static void +pdf_write_obj (pdf_obj *object, FILE *file) +{ + if (object == NULL) { + write_null(NULL, file); + return; + } + + if (INVALIDOBJ(object)) + ERROR("pdf_write_obj: Invalid object, type = %d\n", object->type); + + if (file == stderr) + fprintf(stderr, "{%d}", object->refcount); + + switch (object->type) { + case PDF_BOOLEAN: + write_boolean(object->data, file); + break; + case PDF_NUMBER: + write_number (object->data, file); + break; + case PDF_STRING: + write_string (object->data, file); + break; + case PDF_NAME: + write_name(object->data, file); + break; + case PDF_ARRAY: + write_array(object->data, file); + break; + case PDF_DICT: + write_dict (object->data, file); + break; + case PDF_STREAM: + write_stream(object->data, file); + break; + case PDF_NULL: + write_null(NULL, file); + break; + case PDF_INDIRECT: + write_indirect(object->data, file); + break; + } +} + +/* Write the object to the file */ +static void +pdf_flush_obj (pdf_obj *object, FILE *file) +{ + long length; + + /* + * Record file position + */ + add_xref_entry(object->label, 1, + pdf_output_file_position, object->generation); + length = sprintf(format_buffer, "%lu %hu obj\n", object->label, object->generation); + enc_mode = doc_enc_mode && !(object->flags & OBJ_NO_ENCRYPT); + pdf_enc_set_label(object->label); + pdf_enc_set_generation(object->generation); + pdf_out(file, format_buffer, length); + pdf_write_obj(object, file); + pdf_out(file, "\nendobj\n", 8); +} + +static long +pdf_add_objstm (pdf_obj *objstm, pdf_obj *object) +{ + long *data, pos; + + TYPECHECK(objstm, PDF_STREAM); + + data = get_objstm_data(objstm); + pos = ++data[0]; + + data[2*pos] = object->label; + data[2*pos+1] = pdf_stream_length(objstm); + + add_xref_entry(object->label, 2, objstm->label, pos-1); + + /* redirect output into objstm */ + output_stream = objstm; + enc_mode = 0; + pdf_write_obj(object, pdf_output_file); + pdf_out_char(pdf_output_file, '\n'); + output_stream = NULL; + + return pos; +} + +static void +release_objstm (pdf_obj *objstm) +{ + long *data = get_objstm_data(objstm); + long pos = data[0]; + pdf_obj *dict; + pdf_stream *stream; + unsigned char *old_buf; + unsigned long 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; + + { + long i = 2*pos, *val = data+2; + while (i--) { + long length = sprintf(format_buffer, "%ld ", *(val++)); + pdf_add_stream(objstm, format_buffer, 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); +} + +void +pdf_release_obj (pdf_obj *object) +{ + 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); + pdf_write_obj(object, stderr); + ERROR("pdf_release_obj: Called with invalid object."); + } + object->refcount -= 1; + if (object->refcount == 0) { + /* + * 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 && pdf_output_file != NULL) { + if (!do_objstm || object->flags & OBJ_NO_OBJSTM + || (doc_enc_mode && object->flags & OBJ_NO_ENCRYPT) + || object->generation) + pdf_flush_obj(object, pdf_output_file); + else { + if (!current_objstm) { + long *data = NEW(2*OBJSTM_MAX_OBJS+2, long); + data[0] = data[1] = 0; + current_objstm = pdf_new_stream(STREAM_COMPRESS); + set_objstm_data(current_objstm, data); + pdf_label_obj(current_objstm); + } + if (pdf_add_objstm(current_objstm, object) == OBJSTM_MAX_OBJS) { + release_objstm(current_objstm); + current_objstm = NULL; + } + } + } + switch (object->type) { + case PDF_BOOLEAN: + release_boolean(object->data); + break; + case PDF_NULL: + release_null(object->data); + 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); + } +} + +/* Copy object data without changing object label. */ +void +pdf_copy_object (pdf_obj *dst, pdf_obj *src) +{ + if (!dst || !src) + return; + + switch (dst->type) { + case PDF_BOOLEAN: release_boolean(dst->data); break; + case PDF_NULL: release_null(dst->data); break; + case PDF_NUMBER: release_number(dst->data); break; + case PDF_STRING: release_string(dst->data); break; + case PDF_NAME: release_name(dst->data); break; + case PDF_ARRAY: release_array(dst->data); break; + case PDF_DICT: release_dict(dst->data); break; + case PDF_STREAM: release_stream(dst->data); break; + case PDF_INDIRECT: release_indirect(dst->data); break; + } + + dst->type = src->type; + switch (src->type) { + case PDF_BOOLEAN: + dst->data = NEW(1, pdf_boolean); + pdf_set_boolean(dst, pdf_boolean_value(src)); + break; + case PDF_NULL: + dst->data = NULL; + break; + case PDF_NUMBER: + dst->data = NEW(1, pdf_number); + pdf_set_number(dst, pdf_number_value(src)); + break; + case PDF_STRING: + dst->data = NEW(1, pdf_string); + pdf_set_string(dst, + pdf_string_value(src), + pdf_string_length(src)); + break; + case PDF_NAME: + dst->data = NEW(1, pdf_name); + pdf_set_name(dst, pdf_name_value(src)); + break; + case PDF_ARRAY: + { + pdf_array *data; + unsigned long i; + + dst->data = data = NEW(1, pdf_array); + data->size = 0; + data->max = 0; + data->values = NULL; + for (i = 0; i < pdf_array_length(src); i++) { + pdf_add_array(dst, pdf_link_obj(pdf_get_array(src, i))); + } + } + break; + case PDF_DICT: + { + pdf_dict *data; + + dst->data = data = NEW(1, pdf_dict); + data->key = NULL; + data->value = NULL; + data->next = NULL; + pdf_merge_dict(dst, src); + } + break; + case PDF_STREAM: + { + pdf_stream *data; + + dst->data = data = NEW(1, pdf_stream); + data->dict = pdf_new_dict(); + data->_flags = ((pdf_stream *)src->data)->_flags; + data->stream_length = 0; + data->max_length = 0; + + pdf_add_stream(dst, pdf_stream_dataptr(src), pdf_stream_length(src)); + pdf_merge_dict(data->dict, pdf_stream_dict(src)); + } + break; + case PDF_INDIRECT: + { + pdf_indirect *data; + + dst->data = data = NEW(1, pdf_indirect); + data->pf = ((pdf_indirect *) (src->data))->pf; + data->label = ((pdf_indirect *) (src->data))->label; + data->generation = ((pdf_indirect *) (src->data))->generation; + } + break; + } + + return; +} + +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 long +find_xref (FILE *pdf_input_file) +{ + long xref_pos; + int tries = 10; + + do { + long 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 */ + mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file); + + { + const char *start, *end; + char *number; + + start = work_buffer; + end = start + strlen(work_buffer); + skip_white(&start, end); + number = parse_number(&start, end); + xref_pos = (long) 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 long +next_object_offset (pdf_file *pf, unsigned long obj_num) +{ + long next = pf->file_size; /* Worst case */ + long i, 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, unsigned long obj_num, unsigned short obj_gen) +{ + pdf_obj *result; + pdf_indirect *indirect; + + indirect = NEW(1, pdf_indirect); + indirect->pf = pf; + 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 (unsigned long obj_num, unsigned short obj_gen, + pdf_file *pf, long offset, long limit) +{ + long length; + char *buffer; + const char *p, *endptr; + pdf_obj *result; + + 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; + unsigned long 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, unsigned long num) +{ + unsigned long offset = pf->xref_table[num].field2; + unsigned short gen = pf->xref_table[num].field3; + long limit = next_object_offset(pf, num), 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 = (long) pdf_number_value(n_obj); + + first_obj = pdf_lookup_dict(dict, "First"); + if (!PDF_OBJ_NUMBERTYPE(first_obj)) + goto error; + first = (long) pdf_number_value(first_obj); + /* reject object streams without object data */ + if (first >= pdf_stream_length(objstm)) + goto error; + + header = NEW(2*(n+1), long); + 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, unsigned long obj_num, unsigned short 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 */ + unsigned long offset; + long 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 */ + unsigned long objstm_num = pf->xref_table[obj_num].field2; + unsigned short index = pf->xref_table[obj_num].field3; + pdf_obj *objstm; + long *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_NUM(o) (((pdf_indirect *)((o)->data))->label) +#define OBJ_GEN(o) (((pdf_indirect *)((o)->data))->generation) + +/* 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) +{ + if (obj) + obj = pdf_link_obj(obj); + + while (PDF_OBJ_INDIRECTTYPE(obj)) { + pdf_file *pf = OBJ_FILE(obj); + unsigned long obj_num = OBJ_NUM(obj); + unsigned short obj_gen = OBJ_GEN(obj); + if (!pf) + ERROR("Tried to deref a non-file object"); + pdf_release_obj(obj); + obj = pdf_get_object(pf, obj_num, obj_gen); + } + + if (PDF_OBJ_NULLTYPE(obj)) { + pdf_release_obj(obj); + return NULL; + } else + return obj; +} + +static void +extend_xref (pdf_file *pf, long new_size) +{ + unsigned long 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; +} + +static int +parse_xref_table (pdf_file *pf, long xref_pos) +{ + FILE *pdf_input_file = pf->file; + unsigned long first, size; + unsigned long i, offset; + unsigned int obj_gen; + char flag; + int r; + + /* + * 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); + + mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file); + if (memcmp(work_buffer, "xref", strlen("xref"))) { + /* Might be an xref stream and not an xref table */ + return 0; + } + /* Next line in file has first item and size of table */ + for (;;) { + unsigned long current_pos; + + current_pos = tell_position(pdf_input_file); + if (mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file) == NULL) { + WARN("Premature end of PDF file while parsing xref table."); + return -1; + } + if (!strncmp(work_buffer, "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. + */ + seek_absolute(pdf_input_file, current_pos); + break; + } + sscanf(work_buffer, "%lu %lu", &first, &size); + if (pf->num_obj < first + size) { + extend_xref(pf, first + size); + } + + for (i = first; i < first + size; i++) { + fread(work_buffer, sizeof(char), 20, pdf_input_file); + /* + * 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. + */ + work_buffer[19] = 0; + offset = 0UL; obj_gen = 0; flag = 0; + r = sscanf(work_buffer, "%010lu %05u %c", &offset, &obj_gen, &flag); + if ( r != 3 || + ((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; + } + 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; + } + } + } + + return 1; +} + +static unsigned long +parse_xrefstm_field (const char **p, int length, unsigned long def) +{ + unsigned long 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, long *length, + int *W, int wsum, + long first, long 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--) { + unsigned char type; + unsigned long field2; + unsigned short field3; + + type = (unsigned char) parse_xrefstm_field(p, W[0], 1); + if (type > 2) + WARN("Unknown cross-reference stream entry type."); + else if (!W[1] || (type != 1 && !W[2])) + return -1; + + field2 = (unsigned long) parse_xrefstm_field(p, W[1], 0); + field3 = (unsigned short) 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, long xref_pos, pdf_obj **trailer) +{ + pdf_obj *xrefstm, *size_obj, *W_obj, *index; + unsigned long size; + long 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 = (unsigned long) 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 = pdf_lookup_dict(*trailer, "Index"); + if (index) { + unsigned int index_len; + if (!PDF_OBJ_ARRAYTYPE(index) || + ((index_len = pdf_array_length(index)) % 2 )) + goto error; + + i = 0; + while (i < index_len) { + pdf_obj *first = pdf_get_array(index, i++); + size_obj = pdf_get_array(index, i++); + if (!PDF_OBJ_NUMBERTYPE(first) || + !PDF_OBJ_NUMBERTYPE(size_obj) || + parse_xrefstm_subsec(pf, &p, &length, W, wsum, + (long) pdf_number_value(first), + (long) 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; + long 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, (long) 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 = (long) 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->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) +{ + unsigned long 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); + pdf_release_obj(pf->trailer); + + RELEASE(pf); +} + +void +pdf_files_init (void) +{ + pdf_files = NEW(1, struct ht_table); + ht_init_table(pdf_files, (void (*)(void *)) pdf_file_free); +} + +pdf_obj * +pdf_file_get_trailer (pdf_file *pf) +{ + ASSERT(pf); + return pdf_link_obj(pf->trailer); +} + +pdf_file * +pdf_open (char *ident, FILE *file) +{ + 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 { + int version = check_for_pdf(file); + if (!version) { + WARN("pdf_open: Not a PDF 1.[1-5] file."); + return NULL; + } + + pf = pdf_file_new(file); + pf->version = version; + + if (!(pf->trailer = read_xref(pf))) { + pdf_file_free(pf); + return NULL; + } + + if (ident) + ht_append_table(pdf_files, ident, strlen(ident), pf); + } + + return pf; +} + +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); +} + +int +check_for_pdf (FILE *file) +{ + int result = 0; + + rewind(file); + if (fread(work_buffer, sizeof(char), strlen("%PDF-1.x"), file) == + strlen("%PDF-1.x") && + !strncmp(work_buffer, "%PDF-1.", strlen("%PDF-1."))) { + if (work_buffer[7] >= '0' && work_buffer[7] <= '0' + pdf_version) + result = 1; + else { + WARN("Version of PDF file (1.%c) is newer than version limit specification.", + work_buffer[7]); + } + } + + return result; +} + +static int CDECL +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_file *pf = OBJ_FILE(object); + unsigned long obj_num = OBJ_NUM(object); + unsigned short 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(); + } + + if ((ref = pf->xref_table[obj_num].indirect)) { + return pdf_link_obj(ref); + } else { + pdf_obj *obj, *tmp; + + obj = pdf_get_object(pf, obj_num, obj_gen); + if (!obj) { + WARN("Could not read object: %lu %u", obj_num, obj_gen); + return NULL; + } + + tmp = pdf_import_object(obj); + + pf->xref_table[obj_num].indirect = ref = pdf_ref_obj(tmp); + + pdf_release_obj(tmp); + 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; + int 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; +} + + +int +pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2) +{ + pdf_indirect *data1, *data2; + + if (!PDF_OBJ_INDIRECTTYPE(ref1) || + !PDF_OBJ_INDIRECTTYPE(ref2)) { + ERROR("Not indirect reference..."); + } + + data1 = (pdf_indirect *) ref1->data; + data2 = (pdf_indirect *) ref2->data; + + if (data1->pf != data2->pf) + return (int) (data1->pf - data2->pf); + if (data1->label != data2->label) + return (int) (data1->label - data2->label); + if (data1->generation != data2->generation) + return (int) (data1->generation - data2->generation); + + return 0; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfobj.h b/Build/source/texk/dvipdf-x/xsrc/pdfobj.h new file mode 100644 index 00000000000..036e9f53ef4 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfobj.h @@ -0,0 +1,196 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 + +/* 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_OBJ_INVALID 0 +#define PDF_UNDEFINED PDF_OBJ_INVALID + +#define STREAM_COMPRESS (1 << 0) + +typedef struct pdf_obj pdf_obj; +typedef struct pdf_file pdf_file; + +/* External interface to pdf routines */ + +extern int pdf_obj_get_verbose (void); +extern void pdf_obj_set_verbose (void); +extern void pdf_error_cleanup (void); + +extern void pdf_out_init (const char *filename, int do_encryption); +extern void pdf_out_flush (void); +extern void pdf_set_version (unsigned version); +extern unsigned pdf_get_version (void); + +extern pdf_obj *pdf_new_obj (int type); +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_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 pdf_obj *pdf_new_null (void); + +extern pdf_obj *pdf_new_boolean (char value); +extern void pdf_set_boolean (pdf_obj *object, 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 void pdf_set_name (pdf_obj *object, 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 /* 0 */ +extern pdf_obj *pdf_get_array (pdf_obj *array, long idx); +extern unsigned pdf_array_length (pdf_obj *array); + +extern void pdf_unshift_array (pdf_obj *array, pdf_obj *object); +#if 0 +extern pdf_obj *pdf_shift_array (pdf_obj *array); +extern pdf_obj *pdf_pop_array (pdf_obj *array); +#endif /* 0 */ + +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 /* 0 */ + +/* 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, + long stream_data_len); +#if HAVE_ZLIB +extern int pdf_add_stream_flate (pdf_obj *stream, + const void *stream_data_ptr, + long stream_data_len); +#endif +extern int pdf_concat_stream (pdf_obj *dst, pdf_obj *src); +extern pdf_obj *pdf_stream_dict (pdf_obj *stream); +extern long 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 /* 0 */ +extern const void *pdf_stream_dataptr (pdf_obj *stream); + +#if 0 +extern int pdf_stream_pop_filter (pdf_obj *stream); +#endif + +/* Compare label of two indirect reference object. + */ +extern int pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2); + +/* The following routines are not appropriate for pdfobj. + */ + +extern void pdf_set_compression (int level); + +extern void pdf_set_info (pdf_obj *obj); +extern void pdf_set_root (pdf_obj *obj); +extern void pdf_set_encrypt (pdf_obj *encrypt, pdf_obj *id); + +extern void pdf_files_init (void); +extern void pdf_files_close (void); +extern int check_for_pdf (FILE *file); +extern pdf_file *pdf_open (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_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, unsigned long label, unsigned short generation); +extern void pdf_copy_object (pdf_obj *dst, pdf_obj *src); + +#endif /* _PDFOBJ_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfparse.c b/Build/source/texk/dvipdf-x/xsrc/pdfparse.c new file mode 100644 index 00000000000..4d0444b5a30 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfparse.c @@ -0,0 +1,1078 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#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) == '%') +#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); + +static const char *save = NULL; + +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"); +} + +#define SAVE(s,e) do {\ + save = (s);\ + } while (0) +#define DUMP_RESTORE(s,e) do {\ + dump(save, end);\ + (s) = save;\ + } while (0) + +void +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 == '%') + 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(*p)) + p++; + if (p < end && *p == '.') { + p++; + while (p < end && isdigit(*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(*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; +} + +#define DDIGITS_MAX 10 +pdf_obj * +parse_pdf_number (const char **pp, const char *endptr) +{ + const char *p; + unsigned long ipart = 0, dpart = 0; + int nddigits = 0, sign = 1; + int has_dot = 0; + static double ipot[DDIGITS_MAX+1] = { + 1.0, + 0.1, + 0.01, + 0.001, + 0.0001, + 0.00001, + 0.000001, + 0.0000001, + 0.00000001, + 0.000000001, + 0.0000000001 + }; + + p = *pp; + skip_white(&p, endptr); + if (p >= endptr || + (!isdigit(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(p[0])) { + if (has_dot) { + if (nddigits == DDIGITS_MAX && pdf_obj_get_verbose() > 1) { + WARN("Number with more than %d fractional digits.", DDIGITS_MAX); + } else if (nddigits < DDIGITS_MAX) { + dpart = dpart * 10 + p[0] - '0'; + nddigits++; + } /* Ignore decimal digits more than DDIGITS_MAX */ + } else { + ipart = ipart * 10 + p[0] - '0'; + } + } else { + WARN("Could not find a numeric object."); + return NULL; + } + p++; + } + + *pp = p; + return pdf_new_number((double) sign * (((double ) ipart) + dpart * ipot[nddigits])); +} + +/* + * 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(p[1]) || !isxdigit(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++; + + /* + * Accroding to the PDF spec., an end-of-line marker, not preceded + * by a backslash, must be converted to single \n. + */ + 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; + long 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(*(*pp + 1)))) { + return parse_pdf_hex_string(pp, endptr); + } + } + + WARN("Could not find a string object."); + + return NULL; +} + +#ifndef PDF_PARSE_STRICT +pdf_obj * +parse_pdf_tainted_dict (const char **pp, const char *endptr) +{ + pdf_obj *result; + + parser_state.tainted = 1; + result = parse_pdf_dict(pp, endptr, NULL); + parser_state.tainted = 0; + + return result; +} +#else /* PDF_PARSE_STRICT */ +pdf_obj * +parse_pdf_tainted_dict (const char **pp, const char *endptr, int level) +{ + return parse_pdf_dict(pp, endptr, NULL); +} +#endif /* !PDF_PARSE_STRICT */ + +pdf_obj * +parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf) +{ + 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(&p, endptr, pf); + 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; +} + +pdf_obj * +parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf) +{ + 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(&p, endptr, pf); + 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_file *pf) +{ + pdf_obj *result = NULL; + const char *p; + pdf_obj *stream_dict; + long stream_length; + + p = *pp; + skip_white(&p, endptr); + if (p + 6 > endptr || + strncmp(p, "stream", 6)) { + return NULL; + } + p += 6; + + /* Carrige return alone is not allowed after keyword "stream". + * See, PDF Reference, 4th ed., version 1.5, p. 36. + */ + if (p < endptr && p[0] == '\n') { + p++; + } else if (p + 1 < endptr && + (p[0] == '\r' && p[1] == '\n')) { + p += 2; + } +#ifndef PDF_PARSE_STRICT + else { + /* TeX translate end-of-line marker to a single space. */ + if (parser_state.tainted) { + if (p < endptr && p[0] == ' ') { + p++; + } + } + } + /* The end-of-line marker not mandatory? */ +#endif /* !PDF_PARSE_STRICT */ + + /* 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 = (long) pdf_number_value(tmp2); + } + pdf_release_obj(tmp2); + } +#ifndef PDF_PARSE_STRICT + else if (p + 9 <= endptr) + { + /* + * This was added to allow TeX users to write PDF stream object + * directly in their TeX source. This violates PDF spec. + */ + const char *q; + + stream_length = -1; + for (q = endptr - 1; q >= p + 8; q--) { + if (q[0] != 'm') + continue; + else { + if (!memcmp(q - 8, "endstrea", 8)) { + /* The end-of-line marker is not skipped here. There are + * no way to decide if it is a part of the stream or not. + */ + stream_length = ((long) (q - p)) - 8; + break; + } + } + } + } +#endif /* !PDF_PARSE_STRICT */ + 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 an error if the stream contained too much data except there + * may be an extra end-of-line marker before the keyword "endstream". + */ +#ifdef PDF_PARSE_STRICT + if (p < endptr && p[0] == '\r') + p++; + if (p < endptr && p[0] == '\n') + p++; +#else /* !PDF_PARSE_STRICT */ + /* + * This may skip data starting with '%' and terminated by a + * '\r' or '\n' or '\r\n'. The PDF syntax rule should not be + * applied to the content of the stream data. + * TeX may have converted end-of-line to single white space. + */ + skip_white(&p, endptr); +#endif /* !PDF_PARSE_STRICT */ + + if (p + 9 > endptr || + memcmp(p, "endstream", 9)) { + pdf_release_obj(result); + return NULL; + } + p += 9; + } + + *pp = p; + return result; +} + +#ifndef PDF_PARSE_STRICT + +/* PLEASE REMOVE THIS */ +#include "specials.h" + +/* This is not PDF indirect reference. */ +static pdf_obj * +parse_pdf_reference (const char **start, const char *end) +{ + pdf_obj *result = NULL; + char *name; + + SAVE(*start, end); + + 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); + DUMP_RESTORE(*start, end); + } + RELEASE(name); + } else { + WARN("Could not find a reference name."); + DUMP_RESTORE(*start, end); + result = NULL; + } + + return result; +} +#endif /* !PDF_PARSE_STRICT */ + +static pdf_obj * +try_pdf_reference (const char *start, const char *end, const char **endptr, pdf_file *pf) +{ + unsigned long id = 0; + unsigned short gen = 0; + + ASSERT(pf); + + if (endptr) + *endptr = start; + + skip_white(&start, end); + if (start > end - 5 || !isdigit(*start)) { + return NULL; + } + while (!is_space(*start)) { + if (start >= end || !isdigit(*start)) { + return NULL; + } + id = id * 10 + (*start - '0'); + start++; + } + + skip_white(&start, end); + if (start >= end || !isdigit(*start)) + return NULL; + while (!is_space(*start)) { + if (start >= end || !isdigit(*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 (const char **pp, const char *endptr, pdf_file *pf) +/* 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(pp, endptr, pf); + skip_white(pp, endptr); + if ( result && + *pp <= endptr - 15 && + !memcmp(*pp, "stream", 6)) { + dict = result; + result = parse_pdf_stream(pp, endptr, dict, pf); + pdf_release_obj(dict); + } + } + + break; + case '(': + result = parse_pdf_string(pp, endptr); + break; + case '[': + result = parse_pdf_array(pp, endptr, pf); + 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; + + case '@': + +#ifndef PDF_PARSE_STRICT + result = parse_pdf_reference(pp, endptr); +#endif /* !PDF_PARSE_STRICT */ + break; + + default: + WARN("Unknown PDF object type."); + result = NULL; + } + + return result; +} + diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfximage.c b/Build/source/texk/dvipdf-x/xsrc/pdfximage.c new file mode 100644 index 00000000000..f16829f18ba --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfximage.c @@ -0,0 +1,924 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dpxfile.h" + +#include "pdfobj.h" + +#include "pdfdoc.h" +#include "pdfdev.h" +#include "pdfdraw.h" + +#include "epdf.h" +#include "mpost.h" +#include "pngimage.h" +#include "jpegimage.h" +#include "bmpimage.h" + +#include "pdfximage.h" + +/* From psimage.h */ +static int check_for_ps (FILE *fp); +static int ps_include_page (pdf_ximage *ximage, const char *file_name); + + +#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 + + +struct attr_ +{ + long width, height; + double xdensity, ydensity; + pdf_rect bbox; +}; + +struct pdf_ximage_ +{ + char *ident; + char res_name[16]; + long page_no, page_count; + + int subtype; + + struct attr_ attr; + + char *filename; + pdf_obj *reference; + pdf_obj *resource; + pdf_obj *attr_dict; + + char tempfile; +}; + + +/* verbose, verbose, verbose... */ +struct opt_ +{ + int verbose; + char *cmdtmpl; +}; + +static struct opt_ _opts = { + 0, NULL +}; + +void pdf_ximage_set_verbose (void) { _opts.verbose++; } + + +struct ic_ +{ + int count, capacity; + pdf_ximage *ximages; +}; + +static struct ic_ _ic = { + 0, 0, NULL +}; + +static void +pdf_init_ximage_struct (pdf_ximage *I, const char *ident, const char *filename, pdf_obj *dict) +{ + if (ident) { + I->ident = NEW(strlen(ident)+1, char); + strcpy(I->ident, ident); + } else + I ->ident = NULL; + I->page_no = I->page_count = 0; + if (filename) { + I->filename = NEW(strlen(filename)+1, char); + strcpy(I->filename, filename); + } else + I->filename = NULL; + I->subtype = -1; + memset(I->res_name, 0, 16); + I->reference = NULL; + I->resource = NULL; + I->attr_dict = dict; + + 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->tempfile = 0; +} + +static void +pdf_set_ximage_tempfile (pdf_ximage *I, const char *filename) +{ + if (I->filename) + RELEASE(I->filename); + I->filename = NEW(strlen(filename)+1, char); + strcpy(I->filename, filename); + I->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->reference) + pdf_release_obj(I->reference); + if (I->resource) + pdf_release_obj(I->resource); + if (I->attr_dict) + pdf_release_obj(I->attr_dict); + pdf_init_ximage_struct(I, NULL, NULL, NULL); +} + + +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->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 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 (_opts.verbose > 1 && keep_cache != 1) + MESG("pdf_image>> deleting temporary file \"%s\"\n", I->filename); + dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */ + I->filename = 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; + } +#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 *fullname, int format, FILE *fp, + long page_no, pdf_obj *dict) +{ + struct ic_ *ic = &_ic; + int id = -1; /* ret */ + pdf_ximage *I; + + 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, ident, ident, dict); + pdf_ximage_set_page(I, page_no, 0); + + switch (format) { + case IMAGE_TYPE_JPEG: + if (_opts.verbose) + MESG("[JPEG]"); + if (jpeg_include_image(I, fp) < 0) + goto error; + I->subtype = PDF_XOBJECT_TYPE_IMAGE; + break; +#ifdef HAVE_LIBPNG + case IMAGE_TYPE_PNG: + if (_opts.verbose) + MESG("[PNG]"); + if (png_include_image(I, fp) < 0) + goto error; + I->subtype = PDF_XOBJECT_TYPE_IMAGE; + break; +#endif + case IMAGE_TYPE_BMP: + if (_opts.verbose) + MESG("[BMP]"); + if (bmp_include_image(I, fp) < 0) + goto error; + I->subtype = PDF_XOBJECT_TYPE_IMAGE; + break; + case IMAGE_TYPE_PDF: + if (_opts.verbose) + MESG("[PDF]"); + if (pdf_include_page(I, fp) < 0) + goto error; + if (_opts.verbose) + MESG(",Page:%ld", I->page_no); + I->subtype = PDF_XOBJECT_TYPE_FORM; + break; + // case IMAGE_TYPE_EPS: + default: + if (_opts.verbose) + MESG(format == IMAGE_TYPE_EPS ? "[PS]" : "[UNKNOWN]"); + if (ps_include_page(I, fullname) < 0) + goto error; + if (_opts.verbose) + MESG(",Page:%ld", I->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; + } + + ic->count++; + + 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))) + +int +pdf_ximage_findresource (const char *ident, long page_no, pdf_obj *dict) +{ + struct ic_ *ic = &_ic; + int id = -1; + pdf_ximage *I; + char *fullname; + int format; + FILE *fp; + + for (id = 0; id < ic->count; id++) { + I = &ic->ximages[id]; + if (I->ident && !strcmp(ident, I->ident) && + I->page_no == page_no + (page_no < 0 ? I->page_count+1 : 0) && + I->attr_dict == dict) { + return id; + } + } + + /* try loading image */ + fullname = dpx_find_file(ident, "_pic_", ""); + if (!fullname) { + WARN("Error locating image file \"%s\"", ident); + return -1; + } + + fp = dpx_fopen(fullname, FOPEN_RBIN_MODE); + if (!fp) { + WARN("Error opening image file \"%s\"", fullname); + RELEASE(fullname); + return -1; + } + if (_opts.verbose) { + MESG("(Image:%s", ident); + if (_opts.verbose > 1) + MESG("[%s]", fullname); + } + + format = source_image_type(fp); + switch (format) { + case IMAGE_TYPE_MPS: + if (_opts.verbose) + MESG("[MPS]"); + id = mps_include_page(ident, fp); + if (id < 0) { + WARN("Try again with the distiller."); + format = IMAGE_TYPE_EPS; + rewind(fp); + } else + break; + default: + id = load_image(ident, fullname, format, fp, page_no, dict); + break; + } + dpx_fclose(fp); + + RELEASE(fullname); + + if (_opts.verbose) + MESG(")"); + + if (id < 0) + WARN("pdf: image inclusion failed for \"%s\".", ident); + + return id; +} + +/* 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; +} + +char * +pdf_ximage_get_ident (pdf_ximage *I) +{ + return I->ident; +} + +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; + + I->reference = pdf_ref_obj(resource); + + 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)); + 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); + + 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; + + I->subtype = PDF_XOBJECT_TYPE_FORM; + + I->attr.bbox.llx = info->bbox.llx; + I->attr.bbox.lly = info->bbox.lly; + I->attr.bbox.urx = info->bbox.urx; + I->attr.bbox.ury = info->bbox.ury; + + I->reference = pdf_ref_obj(resource); + + pdf_release_obj(resource); /* Caller don't know we are using reference. */ + I->resource = NULL; +} + +long +pdf_ximage_get_page (pdf_ximage *I) +{ + return I->page_no; +} + +void +pdf_ximage_set_page (pdf_ximage *I, long page_no, long page_count) +{ + I->page_no = page_no; + I->page_count = page_count; +} + + +#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->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; + pdf_ximage *I; + + 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, ident, NULL, NULL); + + 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); + } + 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; +} + + +/* 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; + } + + 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) +{ + 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 (keep_cache != -1 && stat(temp, &stat_t)==0 && stat(filename, &stat_o)==0 + && stat_t.st_mtime > stat_o.st_mtime) { + /* cache exist */ + /*printf("\nLast file modification: %s", ctime(&stat_o.st_mtime)); + printf("Last file modification: %s", ctime(&stat_t.st_mtime));*/ + ; + } else { + if (_opts.verbose > 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, + (unsigned char) 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, 0, pdfbox_crop); + error = pdf_include_page(ximage, fp); + 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; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfximage.h b/Build/source/texk/dvipdf-x/xsrc/pdfximage.h new file mode 100644 index 00000000000..b1746aa3383 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pdfximage.h @@ -0,0 +1,92 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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" + +#define PDF_XOBJECT_TYPE_FORM 0 +#define PDF_XOBJECT_TYPE_IMAGE 1 + +typedef struct { + int flags; + + long width; + long height; + + int bits_per_component; + int num_components; + + long 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 pdf_ximage_ pdf_ximage; + +extern void pdf_ximage_set_verbose (void); + +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, long page_no, + pdf_obj *dict); +extern int pdf_ximage_defineresource (const char *ident, int subtype, + void *cdata, pdf_obj *resource); + +/* 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 char *pdf_ximage_get_ident (pdf_ximage *ximage); +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 void pdf_ximage_set_page (pdf_ximage *ximage, long page_no, long page_count); +extern long pdf_ximage_get_page (pdf_ximage *I); + +/* from psimage.h */ +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 dvipdfmx.c */ +extern void pdf_ximage_disable_ebb (void); +#endif /* _PDFXIMAGE_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pngimage.c b/Build/source/texk/dvipdf-x/xsrc/pngimage.c new file mode 100644 index 00000000000..f60983a7c40 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pngimage.c @@ -0,0 +1,1013 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * PNG SUPPORT + * + * All bitdepth less than 16 is supported. + * Supported color types are: PALETTE, RGB, GRAY, RGB_ALPHA, GRAY_ALPHA. + * Supported ancillary chunks: tRNS, cHRM + gAMA, (sRGB), (iCCP) + * + * gAMA support is available only when cHRM exists. cHRM support is not + * tested well. CalRGB/CalGray colorspace is used for PNG images that + * have cHRM chunk (but not sRGB). + * + * LIMITATIONS + * + * Recent version of PDF (>= 1.5) support 16 bpc, but 16 bit bitdepth PNG + * images are automatically converted to 8 bit bitpedth image. + * + * TODO + * + * sBIT ? iTXT, tEXT and tIME as MetaData ?, pHYS (see below) + * 16 bpc support for PDF-1.5. JBIG compression for monochrome image. + * Predictor for deflate ? + */ + +#include "system.h" +#include "error.h" +#include "mem.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 +#if 0 +/* 16_TO_8 required. */ +#define PNG_NO_READ_TRANSFORMS +#endif + +#include +#include "pngimage.h" + +#include "pdfximage.h" + +#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 + * + * We ignore gAMA if cHRM is not found. + */ +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_infop info_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; +} + +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, xppm, yppm; + + 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, NULL); + 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); + 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); + xppm = png_get_x_pixels_per_meter(png_ptr, png_info_ptr); + yppm = png_get_y_pixels_per_meter(png_ptr, png_info_ptr); + + /* We do not need 16-bpc color. Ask libpng to convert down to 8-bpc. */ + if (bpc > 8) { + png_set_strip_16(png_ptr); + bpc = 8; + } + + 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); + + stream = pdf_new_stream (STREAM_COMPRESS); + stream_dict = pdf_stream_dict(stream); + + /* Values listed below will not be modified in the remaining process. */ + info.width = width; + info.height = height; + info.bits_per_component = bpc; + if (xppm > 0) + info.xdensity = 72.0 / 0.0254 / xppm; + if (yppm > 0) + info.ydensity = 72.0 / 0.0254 / yppm; + + stream_data_ptr = (png_bytep) NEW(rowbytes*height, png_byte); + read_image_data(png_ptr, png_info_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; + } + 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: + if (color_type != PNG_COLOR_TYPE_RGB) + ERROR("Unexpected error in png_include_image()."); + mask = create_ckey_mask(png_ptr, png_info_ptr); + break; + /* rowbytes changes 4 to 3 at here */ + case PDF_TRANS_TYPE_ALPHA: + if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) + ERROR("Unexpected error in png_include_image()."); + 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: + if (color_type != PNG_COLOR_TYPE_GRAY) + ERROR("Unexpected error in png_include_image()."); + mask = create_ckey_mask(png_ptr, png_info_ptr); + break; + case PDF_TRANS_TYPE_ALPHA: + if (color_type != PNG_COLOR_TYPE_GRAY_ALPHA) + ERROR("Unexpected error in png_include_image()."); + 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) { + pdf_add_dict(stream_dict, pdf_new_name("SMask"), pdf_ref_obj(mask)); + pdf_release_obj(mask); + } else { + WARN("%s: You found a bug in pngimage.c.", PNG_DEBUG_STR); + pdf_release_obj(mask); + } + } + + 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); + + 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; + unsigned pdf_version; + png_byte color_type; + png_color_16p trans_values; + png_bytep trans; + int num_trans; + + pdf_version = pdf_get_version(); + 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_version < 3 && trans_type != PDF_TRANS_TYPE_NONE ) || + ( pdf_version < 4 && 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_version < 3) + WARN("%s: Please use -V 3 option to enable binary transparency support.", PNG_DEBUG_STR); + if (pdf_version < 4) + 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: %g", PNG_DEBUG_STR, G); + return NULL; + } + G = 1.0 / G; /* Gamma is inverted. */ + } else { + G = 1.0; + } + + 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: %g", PNG_DEBUG_STR, G); + return NULL; + } + G = 1.0 / G; /* Gamma is inverted. */ + } else { + G = 1.0; + } + + 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: %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; +} + +/* + * pHYs: no support + * + * pngimage.c is not responsible for adjusting image size. + * Higher layer must do something for this. + */ + +/* + * 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; + + 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; + } + + 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("XObjcect")); + 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++) { + png_byte idx = image_data_ptr[i]; + 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; + png_bytep smask_data_ptr; + png_uint_32 i; + + color_type = png_get_color_type(png_ptr, info_ptr); + + if (color_type & PNG_COLOR_MASK_COLOR) { + if (*rowbytes_ptr != 4*width*sizeof(png_byte)) { /* Something wrong */ + WARN("%s: Inconsistent rowbytes value.", PNG_DEBUG_STR); + return NULL; + } + } else { + if (*rowbytes_ptr != 2*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("XObjcect")); + 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)); + + smask_data_ptr = (png_bytep) NEW(width*height, png_byte); + + switch (color_type) { + case PNG_COLOR_TYPE_RGB_ALPHA: + 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); + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + 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); + 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, width*height); + RELEASE(smask_data_ptr); + + return smask; +} + +static void +read_image_data (png_structp png_ptr, png_infop info_ptr, /* info_ptr unused */ + 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); +} + +#endif /* HAVE_LIBPNG */ diff --git a/Build/source/texk/dvipdf-x/xsrc/pngimage.h b/Build/source/texk/dvipdf-x/xsrc/pngimage.h new file mode 100644 index 00000000000..747b7b1d223 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/pngimage.h @@ -0,0 +1,43 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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_ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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); + +#endif + +#endif /* _PNGIMAGE_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/sfnt.c b/Build/source/texk/dvipdf-x/xsrc/sfnt.c new file mode 100644 index 00000000000..754fe366db3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/sfnt.c @@ -0,0 +1,652 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 /* HAVE_CONFIG_H_ */ + +#include + +#include "system.h" + +#include "error.h" +#include "mem.h" +#include "mfileio.h" + +#include "sfnt.h" + +#ifdef XETEX +UNSIGNED_BYTE +ft_unsigned_byte(sfnt* f) +{ + unsigned char byte; + unsigned long length = 1; + + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, &byte, &length) != 0) + ERROR("sfnt: Freetype failure..."); + f->loc += 1; + + return byte; +} + +SIGNED_BYTE +ft_signed_byte(sfnt* f) +{ + int b = ft_unsigned_byte(f); + if (b >= 0x80) + b -= 0x100; + return (SIGNED_BYTE)b; +} + +UNSIGNED_PAIR +ft_unsigned_pair(sfnt* f) +{ + unsigned char buf[2]; + unsigned long length = 2; + + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) + ERROR("sfnt: Freetype failure..."); + f->loc += 2; + + return (UNSIGNED_PAIR)((unsigned)buf[0] << 8) + buf[1]; +} + +SIGNED_PAIR +ft_signed_pair(sfnt* f) +{ + int p = ft_unsigned_pair(f); + if (p >= 0x8000U) + p -= 0x10000U; + + return (SIGNED_PAIR)p; +} + +UNSIGNED_QUAD +ft_unsigned_quad(sfnt* f) +{ + unsigned char buf[4]; + unsigned long length = 4; + + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) + ERROR("sfnt: Freetype failure..."); + f->loc += 4; + + return ((unsigned long)buf[0] << 24) + ((unsigned long)buf[1] << 16) + + ((unsigned long)buf[2] << 8) + (unsigned long)buf[3]; +} + +unsigned long +ft_read(unsigned char* buf, unsigned long len, sfnt* f) +{ + unsigned long length = len; + if (FT_Load_Sfnt_Table(f->ft_face, 0, f->loc, buf, &length) != 0) + ERROR("sfnt: Freetype failure..."); + f->loc += len; + + return length; +} +#endif + + +/* + * 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 + +#ifdef XETEX +sfnt * +sfnt_open (FT_Face face, int accept_types) +{ + sfnt *sfont; + ULONG type; + + if (!face || !FT_IS_SFNT(face)) + return NULL; + + sfont = NEW(1, sfnt); + sfont->ft_face = face; + sfont->type = 0; + sfont->loc = 0; + sfont->offset = 0; + + 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; + } + + if ((sfont->type & accept_types) == 0) { + RELEASE(sfont); + return NULL; + } + + sfont->directory = NULL; + + return sfont; +} +#else /* not XETEX */ +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; +} +#endif + +static void +release_directory (struct sfnt_table_directory *td) +{ + long 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, unsigned long 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; + unsigned long i, u_tag; + + ASSERT(sfont); + + if (sfont->directory) + release_directory(sfont->directory); + sfont->directory = td = NEW (1, struct sfnt_table_directory); + +#ifdef XETEX + ASSERT(sfont->ft_face); +#else + ASSERT(sfont->stream); +#endif + + 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; + long 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) { +#ifdef XETEX + if (!sfont->ft_face) +#else + if (!sfont->stream) +#endif + { + 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/dvipdf-x/xsrc/spc_color.c b/Build/source/texk/dvipdf-x/xsrc/spc_color.c new file mode 100644 index 00000000000..ae1d85cf8f1 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/spc_color.c @@ -0,0 +1,192 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if 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_set_default(&colorspec); + pdf_color_clear_stack(); /* the default color is saved on color_stack */ + pdf_color_push(&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, long len) +{ + int r = 0; + char *q; + const char *p, *endptr; + + 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/dvipdf-x/xsrc/spc_dvips.c b/Build/source/texk/dvipdf-x/xsrc/spc_dvips.c new file mode 100644 index 00000000000..d9e713511a5 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/spc_dvips.c @@ -0,0 +1,1075 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#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 "mfileio.h" + +#include "spc_dvips.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; + + 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, NULL, 1) < 0) { + RELEASE(filename); + return -1; + } + + form_id = pdf_ximage_findresource(filename, 1, NULL); + if (form_id < 0) { + spc_warn(spe, "Failed to read image file: %s", filename); + RELEASE(filename); + return -1; + } + RELEASE(filename); + + pdf_dev_put_image(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; + + 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_findresource(filename, 1, NULL); + 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 + pdf_dev_put_image(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; + + ASSERT(spe && args && args->curptr <= args->endptr); + + if (args->curptr + strlen(":[begin]") <= args->endptr && + !strncmp(args->curptr, ":[begin]", strlen(":[begin]"))) { + block_pending++; + position_set = 1; + + x_user = pending_x = spe->x_user; + y_user = pending_y = spe->y_user; + 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 : spe->x_user; + y_user = position_set ? pending_y : spe->y_user; + args->curptr++; + } else { + position_set = 1; + x_user = pending_x = spe->x_user; + y_user = pending_y = spe->y_user; + } + + 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); + pdf_dev_get_fixed_point(&pt); + 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 *string, 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->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->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 ", 17); + 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->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, + int flag) +{ + FILE* fp; + int k; + pdf_tmatrix M; + char *distiller_template = get_distiller_template(); + 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 + error = dpx_file_apply_filter(distiller_template, gs_in, gs_out, + (unsigned char) 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; + + 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 *distiller_template = get_distiller_template(); + 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 + error = dpx_file_apply_filter(distiller_template, gs_in, gs_out, + (unsigned char) pdf_get_version()); + if (error) { + WARN("Image format conversion for PSTricks failed."); + RELEASE(gs_in); + gs_in = 0; + return error; + } + + form_id = pdf_ximage_findresource(gs_out, 1, NULL); + 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; + } + pdf_dev_put_image(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, f_exec); + 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; + M.a = M.d = 1.0; M.b = M.c = 0.0; M.e = spe->x_user; M.f = spe->y_user; + pdf_dev_concat(&M); + error = mps_exec_inline(&args->curptr, + args->endptr, + spe->x_user, spe->y_user); + M.e = -spe->x_user; M.f = -spe->y_user; + 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} +}; + +#ifdef XETEX +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; +} +#endif + +int +spc_dvips_at_end_page (void) +{ + mps_eop_cleanup(); +#ifdef XETEX + if (!temporary_defs) { + dpx_delete_temp_file(temporary_defs, true); + temporary_defs = 0; + } +#endif + return 0; +} + +int +spc_dvips_check_special (const char *buf, long len) +{ + const char *p, *endptr; + int i; + + p = buf; + endptr = p + len; + + skip_white(&p, endptr); + if (p >= endptr) + return 0; + + len = (long) (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(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, strlen(dvips_handlers[i].key))) { + + 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 -dNOPAUSE -dBATCH -sDEVICE=nullpage -f " +#elif defined(WIN32) +#define GS_CALCULATOR "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=nullpage -f " +#else +#define GS_CALCULATOR "gs -q -dNOPAUSE -dBATCH -sDEVICE=nullpage -f " +#endif + +static +int calculate_PS (char *string, 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(string, 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/dvipdf-x/xsrc/spc_html.c b/Build/source/texk/dvipdf-x/xsrc/spc_html.c new file mode 100644 index 00000000000..5d9fc66ab4f --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/spc_html.c @@ -0,0 +1,944 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 { + long 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(*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(*p); p++); + if (p >= endptr || *p != '<') + return -1; + + *type = HTML_TAG_TYPE_OPEN; + for (++p; p < endptr && isspace(*p); p++); + if (p < endptr && *p == '/') { + *type = HTML_TAG_TYPE_CLOSE; + for (++p; p < endptr && isspace(*p); p++); + } + +#define ISDELIM(c) ((c) == '>' || (c) == '/' || isspace(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(*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(*p); p++); + } + if (error) { + *pp = p; + return error; + } + + if (p < endptr && *p == '/') { + *type = HTML_TAG_TYPE_EMPTY; + for (++p; p < endptr && isspace(*p); p++); + } + if (p == endptr || *p != '>') { + *pp = p; + return -1; + } + p++; + + downcasify(name); + *pp = p; + return 0; +} + + +static int +spc_handler_html__init (struct spc_env *spe, struct spc_arg *ap, 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, struct spc_arg *ap, 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, struct spc_arg *ap, 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, struct spc_arg *ap, 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, 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, pdf_obj *attr, 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 + "pt", "in", "cm", "mm", "bp", +#define K_UNIT__PX 5 + "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__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 /* 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; +} +#endif /* ENABLE_HTML_SVG_OPACITY */ + +static int +spc_html__img_empty (struct spc_env *spe, pdf_obj *attr, struct spc_html_ *sd) +{ + pdf_obj *src, *obj; + transform_info ti; + int id, error = 0; +#ifdef ENABLE_HTML_SVG_OPACITY + double alpha = 1.0; /* meaning fully opaque */ +#endif /* ENABLE_HTML_SVG_OPACITY */ +#ifdef ENABLE_HTML_SVG_TRANSFORM + pdf_tmatrix M; + + pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user, spe->y_user); +#endif /* ENABLE_HTML_SVG_TRANSFORM */ + + 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(*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(&M, &N); + for ( ; *p && isspace(*p); p++); + if (*p == ',') + for (++p; *p && isspace(*p); p++); + } + } + } +#endif /* ENABLE_HTML_SVG_TRANSFORM */ + + if (error) { + spc_warn(spe, "Error in html \"img\" tag attribute."); + return error; + } + + id = pdf_ximage_findresource(pdf_string_value(src), 0, NULL); + if (id < 0) { + spc_warn(spe, "Could not find/load image: %s", pdf_string_value(src)); + error = -1; + } else { +#if defined(ENABLE_HTML_SVG_TRANSFORM) || defined(ENABLE_HTML_SVG_OPACITY) + { + char *res_name; + pdf_rect r; + + graphics_mode(); + + pdf_dev_gsave(); + +#ifdef ENABLE_HTML_SVG_OPACITY + { + pdf_obj *dict; + int a = round(100.0 * alpha); + if (a != 0) { + res_name = NEW(strlen("_Tps_a100_") + 1, char); + sprintf(res_name, "_Tps_a%03d_", a); /* Not Tps prefix but... */ + if (!check_resourcestatus("ExtGState", res_name)) { + dict = create_xgstate(round_at(0.01 * a, 0.01), 0); + pdf_doc_add_page_resource("ExtGState", + res_name, pdf_ref_obj(dict)); + pdf_release_obj(dict); + } + pdf_doc_add_page_content(" /", 2); + pdf_doc_add_page_content(res_name, strlen(res_name)); + pdf_doc_add_page_content(" gs", 3); + RELEASE(res_name); + } + } +#endif /* ENABLE_HTML_SVG_OPACITY */ + + pdf_dev_concat(&M); + + pdf_ximage_scale_image(id, &M, &r, &ti); + pdf_dev_concat(&M); + + pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly); + + res_name = pdf_ximage_get_resname(id); + pdf_doc_add_page_content(" /", 2); + pdf_doc_add_page_content(res_name, strlen(res_name)); + pdf_doc_add_page_content(" Do", 3); + + pdf_dev_grestore(); + + pdf_doc_add_page_resource("XObject", + res_name, + pdf_ximage_get_reference(id)); + } +#else + pdf_dev_put_image(id, &ti, spe->x_user, spe->y_user); +#endif /* ENABLE_HTML_SVG_XXX */ + } + + return error; +} +#else +static int +spc_html__img_empty (struct spc_env *spe, pdf_obj *attr, struct spc_html_ *sd) +{ + 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, attr, 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, sd); + } + } + pdf_release_obj(attr); + + for ( ; ap->curptr < ap->endptr && isspace(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(*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(*p); p++); + if (*p != '(' || *(p + 1) == 0) + return -1; + for (++p; *p && isspace(*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(*p); p++); + if (*p == ',') + for (++p; *p && isspace(*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(NULL, NULL, sd); +} + +int +spc_html_at_begin_page (void) +{ + struct spc_html_ *sd = &_html_state; + return spc_handler_html__bophook(NULL, NULL, sd); +} + +int +spc_html_at_end_page (void) +{ + struct spc_html_ *sd = &_html_state; + return spc_handler_html__eophook(NULL, NULL, sd); +} + +int +spc_html_at_end_document (void) +{ + struct spc_html_ *sd = &_html_state; + return spc_handler_html__clean(NULL, NULL, sd); +} + + +int +spc_html_check_special (const char *buffer, long size) +{ + const char *p, *endptr; + + p = buffer; + endptr = p + size; + + for ( ; p < endptr && isspace(*p); p++); + size = (long) (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(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(ap->curptr[0]); ap->curptr++); + + return 0; +} + diff --git a/Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c b/Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c new file mode 100644 index 00000000000..7aa8863ae9b --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c @@ -0,0 +1,2115 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#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 "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" + + +#define ENABLE_TOUNICODE 1 + + +/* PLEASE REMOVE THIS */ +struct resource_map { + int type; + int res_id; +}; + +#ifdef ENABLE_TOUNICODE +struct tounicode { + int cmap_id; + int unescape_backslash; + pdf_obj *taintkeys; /* An array of PDF names. */ +}; +#endif /* ENABLE_TOUNICODE */ + +struct spc_pdf_ +{ + pdf_obj *annot_dict; /* pending annotation dict */ + int lowest_level; /* current min level of outlines */ + struct ht_table *resourcemap; /* see remark below (somewhere) */ +#ifdef ENABLE_TOUNICODE + struct tounicode cd; /* For to-UTF16-BE conversion :( */ +#endif /* ENABLE_TOUNICODE */ +}; + +#if 1 +static struct spc_pdf_ _pdf_stat = { + NULL, + 255, + NULL, +#ifdef ENABLE_TOUNICODE + { -1, 0, NULL } +#endif /* ENABLE_TOUNICODE */ +}; +#endif + +/* PLEASE REMOVE THIS */ +static void +hval_free (void *vp) +{ + RELEASE(vp); +} + + +static int +addresource (struct spc_pdf_ *sd, const char *ident, int res_id) +{ + struct resource_map *r; + + if (!ident || res_id < 0) + return -1; + + r = NEW(1, struct resource_map); + r->type = 0; /* unused */ + r->res_id = res_id; + + ht_append_table(sd->resourcemap, ident, strlen(ident), r); + spc_push_object(ident, pdf_ximage_get_reference(res_id)); + + return 0; +} + +static int +findresource (struct spc_pdf_ *sd, const char *ident) +{ + struct resource_map *r; + + if (!ident) + return -1; + + r = ht_lookup_table(sd->resourcemap, ident, strlen(ident)); + + return (r ? r->res_id : -1); +} + + +static int +spc_handler_pdfm__init (struct spc_env *spe, struct spc_arg *ap, void *dp) +{ + struct spc_pdf_ *sd = dp; +#ifdef ENABLE_TOUNICODE + static const char *default_taintkeys[] = { + "Title", "Author", "Subject", "Keywords", + "Creator", "Producer", "Contents", "Subj", + "TU", "T", "TM", NULL /* EOD */ + }; + int i; +#endif /* ENABLE_TOUNICODE */ + + sd->annot_dict = NULL; + sd->lowest_level = 255; + sd->resourcemap = NEW(1, struct ht_table); + ht_init_table(sd->resourcemap, hval_free); + +#ifdef ENABLE_TOUNICODE + 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])); + } +#endif /* ENABLE_TOUNICODE */ + + return 0; +} + +static int +spc_handler_pdfm__clean (struct spc_env *spe, struct spc_arg *ap, 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->resourcemap) { + ht_clear_table(sd->resourcemap); + RELEASE(sd->resourcemap); + } + sd->resourcemap = NULL; + +#ifdef ENABLE_TOUNICODE + if (sd->cd.taintkeys) + pdf_release_obj(sd->cd.taintkeys); + sd->cd.taintkeys = NULL; +#endif /* ENABLE_TOUNICODE */ + + return 0; +} + + +int +spc_pdfm_at_begin_document (void) +{ + struct spc_pdf_ *sd = &_pdf_stat; + return spc_handler_pdfm__init(NULL, NULL, sd); +} + +int +spc_pdfm_at_end_document (void) +{ + struct spc_pdf_ *sd = &_pdf_stat; + return spc_handler_pdfm__clean(NULL, NULL, sd); +} + + +/* 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, + (long) (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, + (long) (args->endptr - args->curptr)); + } + + args->curptr = args->endptr; + + return 0; +} + +#define streamfiltered(o) \ + (pdf_lookup_dict(pdf_stream_dict((o)), "Filter") ? 1 : 0) + +/* 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; +} + +#ifndef pdf_obj_isaref +#define pdf_obj_isaref(o) (pdf_obj_typeof((o)) == PDF_INDIRECT) +#endif + +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); + + if (pdf_obj_isaref(vp)) { + 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; +} + + +/* 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(&ap->curptr, ap->endptr, NULL); + 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(&ap->curptr, ap->endptr, NULL); + 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; +} + + +#ifdef ENABLE_TOUNICODE + +/* For pdf:tounicode support + * This feature is provided for convenience. TeX can't do + * input encoding conversion. + */ +#include "cmap.h" + +static int +reencodestring (CMap *cmap, pdf_obj *instring) +{ +#define WBUF_SIZE 4096 + unsigned char wbuf[WBUF_SIZE]; + unsigned char *obufcur; + const unsigned char *inbufcur; + long inbufleft, obufleft; + + if (!cmap || !instring) + return 0; + + inbufleft = pdf_string_length(instring); + inbufcur = pdf_string_value (instring); + + wbuf[0] = 0xfe; + wbuf[1] = 0xff; + obufcur = wbuf + 2; + obufleft = WBUF_SIZE - 2; + + CMap_decode(cmap, + &inbufcur, &inbufleft, + &obufcur, &obufleft); + + if (inbufleft > 0) { + return -1; + } + + pdf_set_string(instring, wbuf, WBUF_SIZE - obufleft); + + return 0; +} + +/* tables/values used in UTF-8 interpretation - + code is based on ConvertUTF.[ch] sample code + published by the Unicode consortium */ +static unsigned long +offsetsFromUTF8[6] = { + 0x00000000UL, + 0x00003080UL, + 0x000E2080UL, + 0x03C82080UL, + 0xFA082080UL, + 0x82082080UL +}; + +static unsigned char +bytesFromUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +static int +maybe_reencode_utf8(pdf_obj *instring) +{ + unsigned char* inbuf; + int inlen; + int non_ascii = 0; + unsigned char* cp; + unsigned char* op; + unsigned char wbuf[WBUF_SIZE]; + + if (!instring) + return 0; + + inlen = pdf_string_length(instring); + inbuf = pdf_string_value(instring); + + /* check if the input string is strictly ASCII */ + for (cp = inbuf; cp < inbuf + inlen; ++cp) { + if (*cp > 127) { + non_ascii = 1; + } + } + if (non_ascii == 0) + return 0; /* no need to reencode ASCII strings */ + + cp = inbuf; + op = wbuf; + *op++ = 0xfe; + *op++ = 0xff; + while (cp < inbuf + inlen) { + unsigned long usv = *cp++; + int extraBytes = bytesFromUTF8[usv]; + if (cp + extraBytes > inbuf + inlen) + return -1; /* ill-formed, so give up reencoding */ + switch (extraBytes) { /* note: code falls through cases! */ + case 5: usv <<= 6; usv += *cp++; + case 4: usv <<= 6; usv += *cp++; + case 3: usv <<= 6; usv += *cp++; + case 2: usv <<= 6; usv += *cp++; + case 1: usv <<= 6; usv += *cp++; + case 0: ; + }; + usv -= offsetsFromUTF8[extraBytes]; + if (usv > 0x10FFFF) + return -1; /* out of valid Unicode range, give up */ + if (usv > 0xFFFF) { + /* supplementary-plane character: generate high surrogate */ + unsigned long hi = 0xdc00 + (usv - 0x10000) % 0x0400; + if (op > wbuf + WBUF_SIZE - 2) + return -1; /* out of space */ + *op++ = hi / 256; + *op++ = hi % 256; + usv = 0xd800 + (usv - 0x10000) / 0x0400; + /* remaining value in usv is the low surrogate */ + } + if (op > wbuf + WBUF_SIZE - 2) + return -1; /* out of space */ + *op++ = usv / 256; + *op++ = usv % 256; + } + + pdf_set_string(instring, wbuf, op - wbuf); + + return 0; +} + +static int +needreencode (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 modstrings (pdf_obj *key, pdf_obj *value, void *pdata); + +static int +modstrings (pdf_obj *kp, pdf_obj *vp, void *dp) +{ + int r = 0; /* continue */ + + ASSERT( pdf_obj_typeof(kp) == PDF_NAME ); + + switch (pdf_obj_typeof(vp)) { + case PDF_STRING: + { + CMap *cmap; + struct tounicode *cd = dp; + if (cd && cd->cmap_id >= 0 && cd->taintkeys) { + cmap = CMap_cache_get(cd->cmap_id); + if (needreencode(kp, vp, cd)) { + r = reencodestring(cmap, vp); + } + } + else { + r = maybe_reencode_utf8(vp); + } + if (r < 0) /* error occured... */ + WARN("Failed to convert input string to UTF16..."); + } + break; + case PDF_DICT: + r = pdf_foreach_dict(vp, modstrings, dp); + break; + case PDF_STREAM: + r = pdf_foreach_dict(pdf_stream_dict(vp), modstrings, dp); + break; + } + + return r; +} + +static pdf_obj * +my_parse_pdf_dict (const char **pp, const char *endptr, struct tounicode *cd) +{ + pdf_obj *dict; + +#if 0 +/* disable this test, as we do utf8 reencoding with no cmap */ + if (cd->cmap_id < 0) + return parse_pdf_dict(pp, endptr, NULL); +#endif + + /* :( */ + if (cd && cd->unescape_backslash) + dict = parse_pdf_tainted_dict(pp, endptr); + else { + dict = parse_pdf_dict(pp, endptr, NULL); + } + if (dict) + pdf_foreach_dict(dict, modstrings, cd); + + return dict; +} + +#endif /* ENABLE_TOUNICODE */ + + +static int +spc_handler_pdfm_annot (struct spc_env *spe, struct spc_arg *args) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *annot_dict; + pdf_rect rect; + char *ident = NULL; + pdf_coord cp; + 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, NULL, 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; + } + +#ifdef ENABLE_TOUNICODE + annot_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + annot_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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; + } + + cp.x = spe->x_user; cp.y = spe->y_user; + pdf_dev_transform(&cp, NULL); + if (ti.flags & INFO_HAS_USER_BBOX) { + rect.llx = ti.bbox.llx + cp.x; + rect.lly = ti.bbox.lly + cp.y; + rect.urx = ti.bbox.urx + cp.x; + rect.ury = ti.bbox.ury + cp.y; + } else { + rect.llx = cp.x; + rect.lly = cp.y - spe->mag * ti.depth; + rect.urx = cp.x + spe->mag * ti.width; + rect.ury = cp.y + spe->mag * ti.height; + } + + /* Order is important... */ + if (ident) + spc_push_object(ident, pdf_link_obj(annot_dict)); + /* This add reference. */ + pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict); + + if (ident) { + spc_flush_object(ident); + RELEASE(ident); + } + pdf_release_obj(annot_dict); + + return 0; +} + +/* NOTE: This can't have ident. See "Dvipdfm User's Manual". */ +static int +spc_handler_pdfm_bann (struct spc_env *spe, struct spc_arg *args) +{ + struct spc_pdf_ *sd = &_pdf_stat; + 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); + +#ifdef ENABLE_TOUNICODE + sd->annot_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + sd->annot_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + if (!sd->annot_dict) { + spc_warn(spe, "Ignoring annotation with invalid dictionary."); + 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; + return -1; + } + + error = spc_begin_annot(spe, sd->annot_dict); + + 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; +} + + +/* Color:.... */ +static int +spc_handler_pdfm_bcolor (struct spc_env *spe, struct spc_arg *ap) +{ + int error; + pdf_color fc, sc; + + error = spc_util_read_colorspec(spe, &fc, ap, 0); + if (!error) { + if (ap->curptr < ap->endptr) { + error = spc_util_read_colorspec(spe, &sc, ap, 0); + } else { + pdf_color_copycolor(&sc, &fc); + } + } + + if (error) + spc_warn(spe, "Invalid color specification?"); + else { + pdf_color_push(&sc, &fc); /* save currentcolor */ + pdf_dev_set_strokingcolor(&sc); + pdf_dev_set_nonstrokingcolor(&fc); + } + + return error; +} + +/* Different than "color rgb 1 0 0" ? */ +static int +spc_handler_pdfm_scolor (struct spc_env *spe, struct spc_arg *ap) +{ + int error; + pdf_color fc, sc; + + error = spc_util_read_colorspec(spe, &fc, ap, 0); + if (!error) { + if (ap->curptr < ap->endptr) { + error = spc_util_read_colorspec(spe, &sc, ap, 0); + } else { + pdf_color_copycolor(&sc, &fc); + } + } + + if (error) + spc_warn(spe, "Invalid color specification?"); + else { + pdf_color_set_default(&fc); /* ????? */ + pdf_dev_set_strokingcolor(&sc); + pdf_dev_set_nonstrokingcolor(&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; + transform_info ti; + + transform_info_clear(&ti); + if (spc_util_read_dimtrns(spe, &ti, args, NULL, 0) < 0) { + return -1; + } + + /* Create transformation matrix */ + pdf_copymatrix(&M, &(ti.matrix)); + M.e += ((1.0 - M.a) * spe->x_user - M.c * spe->y_user); + M.f += ((1.0 - M.d) * spe->y_user - M.b * spe->x_user); + + 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 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(); + pdf_dev_reset_color(); + + 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; + +#ifdef ENABLE_TOUNICODE + item_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + item_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + 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; + } + +#ifdef ENABLE_TOUNICODE + info_dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + info_dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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(ident, info_dict); + RELEASE(ident); + + return 0; +} + +static int +spc_handler_pdfm_bead (struct spc_env *spe, struct spc_arg *args) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *article; + pdf_obj *article_info; + char *article_name; + pdf_rect rect; + long page_no; + transform_info ti; + pdf_coord cp; + + 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, NULL, 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; + } + + cp.x = spe->x_user; cp.y = spe->y_user; + pdf_dev_transform(&cp, NULL); + if (ti.flags & INFO_HAS_USER_BBOX) { + rect.llx = ti.bbox.llx + cp.x; + rect.lly = ti.bbox.lly + cp.y; + rect.urx = ti.bbox.urx + cp.x; + rect.ury = ti.bbox.ury + cp.y; + } else { + rect.llx = cp.x; + rect.lly = cp.y - spe->mag * ti.depth; + rect.urx = cp.x + spe->mag * ti.width; + rect.ury = cp.y + spe->mag * ti.height; + } + + skip_white(&args->curptr, args->endptr); + if (args->curptr[0] != '<') { + article_info = pdf_new_dict(); + } else { +#ifdef ENABLE_TOUNICODE + article_info = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + article_info = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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(article_name, article_info); + } + page_no = pdf_doc_current_page_number(); + 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) +{ + struct spc_pdf_ *sd = &_pdf_stat; + int xobj_id; + char *ident = NULL; + pdf_obj *fspec, *attr = NULL; + transform_info ti; + long page_no; + + skip_white(&args->curptr, args->endptr); + if (args->curptr[0] == '@') { + ident = parse_opt_ident(&args->curptr, args->endptr); + xobj_id = findresource(sd, ident); + if (xobj_id >= 0) { + spc_warn(spe, "Object reference name for image \"%s\" already used.", ident); + RELEASE(ident); + return -1; + } + } + + transform_info_clear(&ti); + page_no = 1; + if (spc_util_read_dimtrns(spe, &ti, args, &page_no, 0) < 0) { + 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) { + attr = parse_pdf_object(&args->curptr, args->endptr, NULL); + if (!attr || !PDF_OBJ_DICTTYPE(attr)) { + spc_warn(spe, "Ignore invalid attribute dictionary."); + if (attr) pdf_release_obj(attr); + } + } + + xobj_id = pdf_ximage_findresource(pdf_string_value(fspec), page_no, attr); + 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)) + pdf_dev_put_image(xobj_id, &ti, spe->x_user, spe->y_user); + + if (ident) { + addresource(sd, ident, xobj_id); + 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; + int error = 0; + + 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; + } +#ifdef ENABLE_TOUNICODE + error = maybe_reencode_utf8(name); + if (error < 0) + WARN("Failed to convert input string to UTF16..."); +#endif + array = parse_pdf_object(&args->curptr, args->endptr, NULL); + if (!array) { + spc_warn(spe, "Destination not 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; + } + + error = 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(&args->curptr, args->endptr, NULL); + 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(&args->curptr, args->endptr, NULL); + 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) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *docinfo, *dict; + +#ifdef ENABLE_TOUNICODE + dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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) +{ +#ifdef ENABLE_TOUNICODE + struct spc_pdf_ *sd = &_pdf_stat; +#endif /* ENABLE_TOUNICODE */ + pdf_obj *catalog, *dict; + pdf_obj *pref_old, *pref_add; + +#ifdef ENABLE_TOUNICODE + dict = my_parse_pdf_dict(&args->curptr, args->endptr, &sd->cd); +#else + dict = parse_pdf_dict(&args->curptr, args->endptr, NULL); +#endif /* ENABLE_TOUNICODE */ + 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(ident); + RELEASE(ident); + } else { /* Close all? */ + spc_clear_objects(); + } + + 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(&args->curptr, args->endptr, NULL); + if (!object) { + spc_warn(spe, "Could not find an object definition for \"%s\".", ident); + RELEASE(ident); + return -1; + } else { + spc_push_object(ident, object); + } + RELEASE(ident); + + return 0; +} + +static int +spc_handler_pdfm_content (struct spc_env *spe, struct spc_arg *args) +{ + long len = 0; + + skip_white(&args->curptr, args->endptr); + if (args->curptr < args->endptr) { + pdf_tmatrix M; + + pdf_setmatrix(&M, 1.0, 0.0, 0.0, 1.0, spe->x_user, spe->y_user); + 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); + len = (long) (args->endptr - args->curptr); + pdf_doc_add_page_content(args->curptr, len); + pdf_doc_add_page_content(" Q", 2); + } + 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; + if (!direct) { + M.a = M.d = 1.0; M.b = M.c = 0.0; + M.e = spe->x_user; M.f = spe->y_user; + pdf_dev_concat(&M); + } + pdf_doc_add_page_content(" ", 1); + pdf_doc_add_page_content(args->curptr, (long) (args->endptr - args->curptr)); + if (!direct) { + M.e = -spe->x_user; M.f = -spe->y_user; + 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(); + pdf_dev_get_coord(&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); + pdf_dev_push_coord(spe->x_user, spe->y_user); + return 0; +} + +static int +spc_handler_pdfm_econtent (struct spc_env *spe, struct spc_arg *args) +{ + pdf_dev_pop_coord(); + pdf_dev_grestore(); + 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); + pdf_doc_add_page_content(args->curptr, (long) (args->endptr - args->curptr)); + 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; + long 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); + if (instring) + pdf_add_stream(fstream, instring, strlen(instring)); + 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_dict(&args->curptr, args->endptr, NULL); + if (!tmp) { + spc_warn(spe, "Parsing dictionary failed."); + pdf_release_obj(fstream); + 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(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 xobj_id; + char *ident; + pdf_rect cropbox; + 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, NULL, 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; + } + + xobj_id = pdf_doc_begin_grabbing(ident, spe->x_user, spe->y_user, &cropbox); + + if (xobj_id < 0) { + RELEASE(ident); + spc_warn(spe, "Couldn't start form object."); + return -1; + } + + spc_push_object(ident, pdf_ximage_get_reference(xobj_id)); + RELEASE(ident); + + return 0; +} + +/* 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) +{ + pdf_obj *attrib = NULL; + + skip_white(&args->curptr, args->endptr); + + if (args->curptr < args->endptr) { + attrib = parse_pdf_dict(&args->curptr, args->endptr, NULL); + if (attrib && !PDF_OBJ_DICTTYPE(attrib)) { + pdf_release_obj(attrib); + attrib = NULL; + } + } + pdf_doc_end_grabbing(attrib); + + return 0; +} + +/* 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) +{ + struct spc_pdf_ *sd = &_pdf_stat; + 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, NULL, 0) < 0) { + RELEASE(ident); + return -1; + } + } + + /* Dvipdfmx was suddenly changed to use file name to identify + * external images. We can't use ident to find image resource + * here. + */ + xobj_id = findresource(sd, ident); + if (xobj_id < 0) { + xobj_id = pdf_ximage_findresource(ident, 0, NULL); + if (xobj_id < 0) { + spc_warn(spe, "Specified (image) object doesn't exist: %s", ident); + RELEASE(ident); + return -1; + } + } + + pdf_dev_put_image(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_colorspec(spe, &colorspec, args, 0); + if (error) + spc_warn(spe, "No valid color specified?"); + else { + pdf_doc_set_bgcolor(&colorspec); + } + + return error; +} + +static int +spc_handler_pdfm_mapline (struct spc_env *spe, struct spc_arg *ap) +{ + fontmap_rec *mrec; + char *map_name, opchr; + int error = 0; + + 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; + case '+': + mrec = NEW(1, fontmap_rec); + pdf_init_fontmap_record(mrec); + error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr), is_pdfm_mapline(ap->curptr)); + if (error) + spc_warn(spe, "Invalid fontmap line."); + else { + pdf_append_fontmap_record(mrec->map_name, mrec); + } + pdf_clear_fontmap_record(mrec); + RELEASE(mrec); + break; + default: + mrec = NEW(1, fontmap_rec); + pdf_init_fontmap_record(mrec); + error = pdf_read_fontmap_line(mrec, ap->curptr, (long) (ap->endptr - ap->curptr), is_pdfm_mapline(ap->curptr)); + if (error) + spc_warn(spe, "Invalid fontmap line."); + 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; +} + + +#ifdef ENABLE_TOUNICODE +static int +spc_handler_pdfm_tounicode (struct spc_env *spe, struct spc_arg *args) +{ + struct spc_pdf_ *sd = &_pdf_stat; + char *cmap_name; + + /* 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); + return 0; +} +#endif /* ENABLE_TOUNICODE */ + + +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}, + +#ifdef ENABLE_TOUNICODE + {"tounicode", spc_handler_pdfm_tounicode}, +#endif /* ENABLE_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}, + {"encrypt", spc_handler_pdfm_do_nothing}, +}; + +int +spc_pdfm_check_special (const char *buf, long 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) { + 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/dvipdf-x/xsrc/spc_tpic.c b/Build/source/texk/dvipdf-x/xsrc/spc_tpic.c new file mode 100644 index 00000000000..bf8652c0e02 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/spc_tpic.c @@ -0,0 +1,1151 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if 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); + } + pdf_doc_add_page_content(" 0 G", 4); + + return 0; +} + +static int +set_fillstyle (double g, double a, int f_ais) +{ + pdf_obj *dict; + char resname[32]; + char buf[32]; + 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); + } + len += sprintf(buf + len, " %.2f g", g); + + pdf_doc_add_page_content(buf, len); + + return 0; +} + + +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) +{ + pdf_tmatrix M; + double pn = tp->pen_size; + int f_fs = tp->fill_shape; + int f_ais = 0; + double g = 0.5; + double a = 0.0; + 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; + f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0; + switch (tp->mode.fill) { + case TPIC_MODE__FILL_SOLID: + g = 1.0 - tp->fill_color; + a = 0.0; + break; + case TPIC_MODE__FILL_SHAPE: + case TPIC_MODE__FILL_OPACITY: + if (tp->fill_color > 0.0) { + a = tp->fill_color; + g = 0.0; + } else { + a = 0.0; + g = 1.0; + } + break; + } + + if (f_vp || f_fs) { + pdf_dev_gsave(); + + 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) + set_fillstyle(g, a, f_ais); + + 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]; + pdf_tmatrix M; + double pn = tp->pen_size; + int f_fs = tp->fill_shape; + int f_ais = 0; + double g = 0.5; + double a = 0.0; + int i, error = 0; + + f_fs = CLOSED_PATH(tp) ? f_fs : 0; + f_vp = (pn > 0.0) ? f_vp : 0; + f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0; + switch (tp->mode.fill) { + case TPIC_MODE__FILL_SOLID: + g = 1.0 - tp->fill_color; + a = 0.0; + break; + case TPIC_MODE__FILL_SHAPE: + case TPIC_MODE__FILL_OPACITY: + if (tp->fill_color > 0.0) { + a = tp->fill_color; + g = 0.0; + } else { + a = 0.0; + g = 1.0; + } + break; + } + + if ( f_vp || f_fs ) { + pdf_dev_gsave(); + + 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) + set_fillstyle(g, a, f_ais); + + 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 */ ) +{ + pdf_tmatrix M; + double pn = tp->pen_size; + int f_fs = tp->fill_shape; + int f_ais = 0; + double g = 0.5; + double a = 0.0; + + f_fs = (round(fabs(v[4] - v[5]) + 0.5) >= 360) ? f_fs : 0; + f_vp = (pn > 0.0) ? f_vp : 0; + f_ais = (tp->mode.fill == TPIC_MODE__FILL_SHAPE) ? 1 : 0; + switch (tp->mode.fill) { + case TPIC_MODE__FILL_SOLID: + g = 1.0 - tp->fill_color; + a = 0.0; + break; + case TPIC_MODE__FILL_SHAPE: + case TPIC_MODE__FILL_OPACITY: + if (tp->fill_color > 0.0) { + a = tp->fill_color; + g = 0.0; + } else { + a = 0.0; + g = 1.0; + } + break; + } + + if ( f_vp || f_fs ) { + pdf_dev_gsave(); + + 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) + set_fillstyle(g, a, f_ais); + + 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, long *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; + long 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; + long 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; + long 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; + long 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; + long 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; + long 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; + long 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) { + tp->fill_color = atof(q); + RELEASE(q); + } + + 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, + struct spc_arg *ap, 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_get_version() < 4) { + 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 (struct spc_env *spe, + struct spc_arg *ap, void *dp) +{ + struct spc_tpic_ *tp = dp; + + ASSERT(tp); + + tpic__clear(tp); + + return 0; +} + +static int +spc_handler_tpic__eophook (struct spc_env *spe, + struct spc_arg *ap, 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, + struct spc_arg *ap, 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(NULL, NULL, tp); +} + +int +spc_tpic_at_end_page (void) +{ + struct spc_tpic_ *tp = &_tpic_state; + return spc_handler_tpic__eophook(NULL, NULL, tp); +} + + +int +spc_tpic_at_begin_document (void) +{ + struct spc_tpic_ *tp = &_tpic_state; + return spc_handler_tpic__init(NULL, NULL, tp); +} + +int +spc_tpic_at_end_document (void) +{ + struct spc_tpic_ *tp = &_tpic_state; + return spc_handler_tpic__clean(NULL, NULL, tp); +} + + +#if DEBUG +#include "pdfparse.h" /* parse_val_ident :( */ + +static pdf_obj * +spc_parse_kvpairs (struct spc_env *spe, 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 ) /* , void *dp) */ +{ + struct spc_tpic_ *tp = &_tpic_state; + pdf_obj *dict; + int error = 0; + + dict = spc_parse_kvpairs(spe, 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_get_version() < 4) { + 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, long 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/dvipdf-x/xsrc/spc_util.c b/Build/source/texk/dvipdf-x/xsrc/spc_util.c new file mode 100644 index 00000000000..7ea4f5aa929 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/spc_util.c @@ -0,0 +1,796 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxutil.h" + +#include "pdfdev.h" +#include "pdfparse.h" +#include "pdfcolor.h" +#include "pdfdraw.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_env *spe, 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, spe, 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, spe, 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, spe, 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, "hsb")) { + nc = spc_util_read_numbers(cv, 3, spe, 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; +} + +/* Argumaent 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[4]; /* at most four */ + int nc, isarry = 0; + int error = 0; + char *q; + + skip_blank(&ap->curptr, ap->endptr); + + if (ap->curptr[0] == '[') { + ap->curptr++; skip_blank(&ap->curptr, ap->endptr); + isarry = 1; + } + + nc = spc_util_read_numbers(cv, 4, spe, 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", q); + RELEASE(q); + break; + } + + if (!error && 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) +{ + int error = 0; + + ASSERT(colorspec && spe && ap); + + skip_blank(&ap->curptr, ap->endptr); + if (ap->curptr >= ap->endptr) { + return -1; + } + + if (syntax) + error = spc_read_color_color(spe, colorspec, ap); + else + error = spc_read_color_pdf(spe, colorspec, ap); + + skip_blank(&ap->curptr, ap->endptr); + + return error; +} + + +/* This need to allow 'true' prefix for unit and + * length value must be divided by current magnification. + */ +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 + "pt", "in", "cm", "mm", "bp", 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 (strlen(q) == 0) { + 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; + 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; +} + + +static int +spc_read_dimtrns_pdfm (struct spc_env *spe, transform_info *p, struct spc_arg *ap, long *page_no) +{ + 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", +#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__PAGE 10 + "page", +#define K__HIDE 11 + "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, spe, 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, spe, 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, spe, ap) == 1) + *page_no = (long) page; + else + error = -1; + } + 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, long *page_no, int syntax) +{ + ASSERT(ti && spe && args); + + if (syntax) { + ASSERT(!page_no); + return spc_read_dimtrns_dvips(spe, ti, args); + } else { + return spc_read_dimtrns_pdfm (spe, ti, args, page_no); + } + + return -1; +} + + +/* Color names */ +#ifdef rgb +#undef rgb +#endif +#ifdef cmyk +#undef cmyk +#endif +#define gray(g) {1, {g}} +#define rgb8(r,g,b) {3, {((r)/255.0), ((g)/255.0), ((b)/255.0), 0.0}} +#define cmyk(c,m,y,k) {4, {(c), (m), (y), (k)}} + +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/dvipdf-x/xsrc/spc_util.h b/Build/source/texk/dvipdf-x/xsrc/spc_util.h new file mode 100644 index 00000000000..db5b16cf245 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/spc_util.h @@ -0,0 +1,44 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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 "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, long *page, int syntax); +extern int spc_util_read_length (struct spc_env *spe, double *length, struct spc_arg *ap); + +extern int spc_util_read_numbers (double *values, int num_values, struct spc_env *spe, struct spc_arg *args); + +#endif /* _SPC_UTIL_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/specials.c b/Build/source/texk/dvipdf-x/xsrc/specials.c new file mode 100644 index 00000000000..0b9800eb81b --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/specials.c @@ -0,0 +1,619 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "numbers.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" +#ifdef XETEX +#include "spc_xtx.h" +#endif + +#include "specials.h" + +static int verbose = 0; +void +spc_set_verbose (void) +{ + verbose++; +} + + +void +spc_warn (struct spc_env *spe, const char *fmt, ...) +{ + va_list ap; + static char buf[1024]; + + va_start(ap, fmt); + + vsprintf(buf, 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; +} + + + +static struct ht_table *named_objects = NULL; + +/* 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; + + ASSERT(named_objects); + + 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 = 0.0; + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.x, .01)); + break; + case K_OBJ__YPOS: + cp.x = 0.0; 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(named_objects, 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; + + ASSERT(named_objects); + + 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 = 0.0; + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.x, .01)); + break; + case K_OBJ__YPOS: + cp.x = 0.0; 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(named_objects, 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 (const char *key, pdf_obj *value) +{ + int error = 0; + + if (!key || !value) + return; + + if (PDF_OBJ_INDIRECTTYPE(value)) { + pdf_names_add_reference(named_objects, + key, strlen(key), value); + } else { + error = pdf_names_add_object(named_objects, + key, strlen(key), value); + if (!error) { + /* _FIXME_: + * Objects created by pdf:obj must always + * be written to output regardless of if + * they are actually used in document. + */ + pdf_obj *obj_ref = pdf_names_lookup_reference(named_objects, + key, strlen(key)); + if (obj_ref) + pdf_release_obj(obj_ref); + } + } + + return; +} + +void +spc_flush_object (const char *key) +{ + pdf_names_close_object(named_objects, key, strlen(key)); +} + +void +spc_clear_objects (void) +{ + pdf_delete_name_tree(&named_objects); + named_objects = pdf_new_name_tree(); +} + + +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, long 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_ */ + + 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) (); + int (*eodhk_func) (); + int (*bophk_func) (); + int (*eophk_func) (); + int (*check_func) (const char *, long); + 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, + NULL, + spc_pdfm_check_special, + spc_pdfm_setup_handler + }, + +#ifdef XETEX + {"x:", + NULL, + NULL, + NULL, + NULL, + spc_xtx_check_special, + spc_xtx_setup_handler + }, +#endif + + {"ps:", +#ifdef XETEX + spc_dvips_at_begin_document, + spc_dvips_at_end_document, + spc_dvips_at_begin_page, +#else + NULL, + NULL, + NULL, +#endif + spc_dvips_at_end_page, + spc_dvips_check_special, + spc_dvips_setup_handler + }, + + {"color", + 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, + 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, + spc_html_check_special, + spc_html_setup_handler + }, + + {"unknown", + NULL, + NULL, + NULL, + NULL, + spc_misc_check_special, + spc_misc_setup_handler + }, + + {NULL} /* end */ +}; + +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; + + ASSERT(!named_objects); + + named_objects = pdf_new_name_tree(); + + for (i = 0; known_specials[i].key != NULL; i++) { + if (known_specials[i].bodhk_func) { + error = known_specials[i].bodhk_func(); + } + } + + return error; +} + +int +spc_exec_at_end_document (void) +{ + int error = 0; + int i; + + for (i = 0; known_specials[i].key != NULL; i++) { + if (known_specials[i].eodhk_func) { + error = known_specials[i].eodhk_func(); + } + } + + if (named_objects) { + pdf_delete_name_tree(&named_objects); + } + + 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; + long 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(*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(*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, long size, + double x_user, double y_user, double mag) +{ + int error = -1; + int i, found; + struct spc_env spe; + struct spc_arg args; + struct spc_handler special; + + if (verbose > 3) { + 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); + } + break; + } + } + + check_garbage(&args); + + return error; +} + diff --git a/Build/source/texk/dvipdf-x/xsrc/tfm.c b/Build/source/texk/dvipdf-x/xsrc/tfm.c new file mode 100644 index 00000000000..3622b16f071 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tfm.c @@ -0,0 +1,1209 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "mfileio.h" +#include "error.h" + +#include "numbers.h" +#include "dpxutil.h" + +#include "tfm.h" + +#define TFM_FORMAT 1 +#define OFM_FORMAT 2 + +#define FWBASE ((double) (1<<20)) + +static int verbose = 0; + + +#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) +#endif /* !WITHOUT_ASCII_PTEX */ + +/* + * TFM Record structure: + * Multiple TFM's may be read in at once. + */ + +struct tfm_font +{ +#ifndef WITHOUT_ASCII_PTEX + UNSIGNED_BYTE id; + UNSIGNED_BYTE nt; +#endif /* !WITHOUT_ASCII_PTEX */ +#ifndef WITHOUT_OMEGA + SIGNED_QUAD level; +#endif /* !WITHOUT_OMEGA */ + UNSIGNED_QUAD wlenfile; + UNSIGNED_QUAD wlenheader; + UNSIGNED_QUAD bc, ec; + UNSIGNED_QUAD nwidths, nheights, ndepths; + UNSIGNED_QUAD nitcor, nlig, nkern, nextens; + UNSIGNED_QUAD nfonparm; +#ifndef WITHOUT_OMEGA + UNSIGNED_QUAD fontdir; + UNSIGNED_QUAD nco, ncw, npc; +#endif /* !WITHOUT_OMEGA */ + SIGNED_QUAD *header; +#ifndef WITHOUT_ASCII_PTEX + UNSIGNED_PAIR *chartypes; +#endif /* !WITHOUT_ASCII_PTEX */ + UNSIGNED_QUAD *char_info; + UNSIGNED_PAIR *width_index; + UNSIGNED_BYTE *height_index; + UNSIGNED_BYTE *depth_index; + SIGNED_QUAD *width; + SIGNED_QUAD *height; + SIGNED_QUAD *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 +{ + long first_char; + unsigned short 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; + unsigned short *indices; +}; + +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 long +lookup_char (const struct char_map *map, long charcode) +{ + if (charcode >= map->coverage.first_char && + charcode <= map->coverage.first_char + map->coverage.num_chars) + return map->indices[charcode - map->coverage.first_char]; + else + return -1; + + return -1; +} + +static long +lookup_range (const struct range_map *map, long charcode) +{ + long 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[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; + long 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); + } +} + +void +tfm_set_verbose (void) +{ + verbose++; +} + + +static long +fread_fwords (SIGNED_QUAD *words, SIGNED_QUAD nmemb, FILE *fp) +{ + long i; + + for (i = 0; i < nmemb; i++) + words[i] = get_signed_quad(fp); + + return nmemb*4; +} + +static long +fread_uquads (UNSIGNED_QUAD *quads, SIGNED_QUAD nmemb, FILE *fp) +{ + long 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, SIGNED_QUAD tfm_file_size) +{ + UNSIGNED_QUAD 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 (tfm_file_size < 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 %ld bytes but it says it is %ld bytes!", + expected_size * 4, tfm->wlenfile * 4); + if (tfm_file_size > expected_size *4) { + WARN("Proceeding nervously..."); + } else { + ERROR("Can't proceed..."); + } + } +} + +static void +tfm_get_sizes (FILE *tfm_file, SIGNED_QUAD tfm_file_size, struct tfm_font *tfm) +{ +#ifndef WITHOUT_ASCII_PTEX + { + UNSIGNED_PAIR 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 void +jfm_do_char_type_array (FILE *tfm_file, struct tfm_font *tfm) +{ + UNSIGNED_PAIR charcode; + UNSIGNED_PAIR chartype; + long i; + + tfm->chartypes = NEW(65536, UNSIGNED_PAIR); + for (i = 0; i < 65536; i++) { + tfm->chartypes[i] = 0; + } + for (i = 0; i < tfm->nt; i++) { + charcode = get_unsigned_pair(tfm_file); + chartype = get_unsigned_pair(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; + long code; + + fm->charmap.type = MAPTYPE_CHAR; + fm->charmap.data = map = NEW(1, struct char_map); + map->coverage.first_char = 0; + map->coverage.num_chars = 0xFFFFu; + map->indices = NEW(0x10000L, unsigned short); + + for (code = 0; code <= 0xFFFFu; code++) { + 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; + map->coverages[0].num_chars = 0xFFFFu; + 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) +{ + UNSIGNED_QUAD charinfo; + UNSIGNED_PAIR width_index, 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 / 16777216ul); + height_index = (charinfo / 0x100000ul) & 0xf; + depth_index = (charinfo / 0x10000ul) & 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, SIGNED_QUAD 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, SIGNED_QUAD ofm_file_size) +{ + UNSIGNED_QUAD 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, UNSIGNED_QUAD ofm_file_size, struct tfm_font *tfm) +{ + tfm->level = get_signed_quad(ofm_file); + + tfm->wlenfile = get_signed_quad(ofm_file); + tfm->wlenheader = get_signed_quad(ofm_file); + tfm->bc = get_signed_quad(ofm_file); + tfm->ec = get_signed_quad(ofm_file); + if (tfm->ec < tfm->bc) { + ERROR("OFM file error: ec(%u) < bc(%u) ???", tfm->ec, tfm->bc); + } + tfm->nwidths = get_signed_quad(ofm_file); + tfm->nheights = get_signed_quad(ofm_file); + tfm->ndepths = get_signed_quad(ofm_file); + tfm->nitcor = get_signed_quad(ofm_file); + tfm->nlig = get_signed_quad(ofm_file); + tfm->nkern = get_signed_quad(ofm_file); + tfm->nextens = get_signed_quad(ofm_file); + tfm->nfonparm = get_signed_quad(ofm_file); + tfm->fontdir = get_signed_quad(ofm_file); + 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_signed_quad(ofm_file); + tfm->ncw = get_signed_quad(ofm_file); + tfm->npc = get_signed_quad(ofm_file); + seek_absolute(ofm_file, 4*(tfm->nco - tfm->wlenheader)); + } 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) +{ + UNSIGNED_QUAD num_chars; + + num_chars = tfm->ec - tfm->bc + 1; + if (num_chars != 0) { + UNSIGNED_QUAD i; + + tfm->width_index = NEW(num_chars, UNSIGNED_PAIR); + tfm->height_index = NEW(num_chars, UNSIGNED_BYTE); + tfm->depth_index = NEW(num_chars, UNSIGNED_BYTE); + 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 */ + get_unsigned_quad(tfm_file); + } + } +} + +static void +ofm_do_char_info_one (FILE *tfm_file, struct tfm_font *tfm) +{ + UNSIGNED_QUAD num_char_infos; + UNSIGNED_QUAD num_chars; + + num_char_infos = tfm->ncw / (3 + (tfm->npc / 2)); + num_chars = tfm->ec - tfm ->bc + 1; + + if (num_chars != 0) { + UNSIGNED_QUAD i; + UNSIGNED_QUAD char_infos_read; + + tfm->width_index = NEW(num_chars, UNSIGNED_PAIR); + tfm->height_index = NEW(num_chars, UNSIGNED_BYTE); + tfm->depth_index = NEW(num_chars, UNSIGNED_BYTE); + 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 */ + get_unsigned_quad(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, UNSIGNED_QUAD num_chars) +{ + long 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, UNSIGNED_QUAD 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, UNSIGNED_QUAD 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 = 0xFFFFl; + 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, UNSIGNED_QUAD); + 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; + UNSIGNED_QUAD 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 (verbose) { + if (format == TFM_FORMAT) + MESG("(TFM:%s", tfm_name); + else if (format == OFM_FORMAT) + MESG("(OFM:%s", tfm_name); + if (verbose > 1) + MESG("[%s]", file_name); + } + + RELEASE(file_name); + + tfm_file_size = file_size(tfm_file); + 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 (verbose) + 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, SIGNED_QUAD ch) +{ + struct font_metric *fm; + long 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, SIGNED_QUAD ch) +{ + struct font_metric *fm; + long 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, SIGNED_QUAD ch) +{ + struct font_metric *fm; + long 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, SIGNED_QUAD ch) +{ + return ((double) tfm_get_fw_width(font_id, ch)/FWBASE); +} + +#if 0 +double +tfm_get_height (int font_id, SIGNED_QUAD ch) +{ + return ((double) tfm_get_fw_height(font_id, ch)/FWBASE); +} + +double +tfm_get_depth (int font_id, SIGNED_QUAD 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++) { + SIGNED_QUAD 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; +} + +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++) { + SIGNED_QUAD 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++) { + SIGNED_QUAD 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; +} + +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 + +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/dvipdf-x/xsrc/truetype.c b/Build/source/texk/dvipdf-x/xsrc/truetype.c new file mode 100644 index 00000000000..4b8a7e59de1 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/truetype.c @@ -0,0 +1,1009 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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. +*/ + + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" + +#include "numbers.h" +#include "error.h" +#include "mem.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" + +#include "tfm.h" + +/* Modifying this has no effect :P */ +#ifdef ENABLE_NOEMBED +# undef ENABLE_NOEMBED +#endif + +int +pdf_font_open_truetype (pdf_font *font) +{ + char *ident; + int index, encoding_id; + pdf_obj *fontdict, *descriptor; + sfnt *sfont; + int embedding = 1; /* Must be embedded. */ + FILE *fp = NULL; + int length, error = 0; + + ASSERT( font ); + + ident = pdf_font_get_ident(font); + index = pdf_font_get_index(font); + + ASSERT( ident ); + +#ifdef XETEX + sfont = sfnt_open(pdf_font_get_ft_face(font), SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE); + if (!sfont) + return -1; +#else + 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); + } +#endif + + if (!sfont) { + WARN("Could not open TrueType font: %s", ident); + if (fp) + DPXFCLOSE(fp); + return -1; + } + + if (sfont->type == SFNT_TYPE_TTC) { + unsigned long 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) { + 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. + */ + encoding_id = pdf_font_get_encoding(font); + fontdict = pdf_font_get_resource(font); + descriptor = pdf_font_get_descriptor(font); +#ifdef ENABLE_NOEMBED + embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; +#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); + strncpy(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) + ERROR("Can't find valid fontname for \"%s\".", ident); + pdf_font_set_fontname(font, fontname); + + tmp = tt_get_fontdesc(sfont, &embedding, -1, 1, fontname); + if (!tmp) { + ERROR("Could not obtain necessary font info."); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + } + ASSERT(pdf_obj_typeof(tmp) == PDF_DICT); + + pdf_merge_dict(descriptor, tmp); + pdf_release_obj(tmp); + } + + if (!embedding) { + if (encoding_id >= 0 && + !pdf_encoding_is_predefined(encoding_id)) { + ERROR("Custom encoding not allowed for non-embedded TrueType font."); + sfnt_close(sfont); + return -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; + long flags; + +#ifndef ENABLE_NOEMBED + ERROR("Font file=\"%s\" can't be embedded due to liscence restrictions.", ident); +#endif /* ENABLE_NOEMBED */ + pdf_font_set_flags(font, PDF_FONT_FLAG_NOEMBED); + tmp = pdf_lookup_dict(descriptor, "Flags"); + if (tmp && pdf_obj_typeof(tmp) == PDF_NUMBER) { + flags = (long) 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)); + } + } + } + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + pdf_add_dict(fontdict, + pdf_new_name("Type"), pdf_new_name("Font")); + pdf_add_dict(fontdict, + pdf_new_name("Subtype"), pdf_new_name("TrueType")); + + return 0; +} + +/* + * 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 *tmparray; + int code, firstchar, lastchar, tfm_id; + char *usedchars; + + fontdict = pdf_font_get_resource (font); + usedchars = pdf_font_get_usedchars (font); + + tmparray = pdf_new_array(); + 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???"); + pdf_release_obj(tmparray); + return; + } + tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + for (code = firstchar; code <= lastchar; code++) { + if (usedchars[code]) { + double width; + if (tfm_id < 0) /* tfm is not found */ + width = widths[code]; + else + width = 1000. * tfm_get_width(tfm_id, code); + pdf_add_array(tmparray, + pdf_new_number(ROUND(width, 0.1))); + } else { + pdf_add_array(tmparray, pdf_new_number(0.0)); + } + } + + if (pdf_array_length(tmparray) > 0) { + pdf_add_dict(fontdict, + pdf_new_name("Widths"), pdf_ref_obj(tmparray)); + } + pdf_release_obj(tmparray); + + 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 verbose = 0; + +#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 (verbose > 2) + MESG("[glyphs:/.notdef"); + + count = 1; /* .notdef */ + for (code = 0; code < 256; code++) { + if (!usedchars[code]) + continue; + + if (verbose > 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, pdf_font_get_ident(font)); + 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 (verbose > 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 (verbose > 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 (verbose > 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 (long *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 (verbose > 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 (verbose >= 0) /* give warning */ + WARN("Glyph \"%s\" looks like a composite glyph...", + agln->name); + error = composeuchar(agln->unicodes, agln->n_components, NULL, gm, &idx); + if (verbose >= 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+%06lX", agln->unicodes[_i]); + else + _n += sprintf(_p+_n, "U+%04lX", 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; + long 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", + pdf_font_get_ident(font)); + 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, pdf_font_get_ident(font)); + 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], pdf_font_get_ident(font)); + } else { + if (verbose > 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 (verbose > 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 = pdf_font_get_descriptor(font); + char *ident = pdf_font_get_ident(font); + int encoding_id = pdf_font_get_encoding(font); + char *usedchars = pdf_font_get_usedchars(font); +#ifdef ENABLE_NOEMBED + int embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; +#endif /* ENABLE_NOEMBED */ + int index = pdf_font_get_index(font); + char **enc_vec; + pdf_obj *fontfile; + FILE *fp = NULL; + sfnt *sfont; + int i, error = 0; + + if (!pdf_font_is_in_use(font)) + return 0; + + verbose = pdf_font_get_verbose(); + +#ifdef XETEX + sfont = sfnt_open(pdf_font_get_ft_face(font), SFNT_TYPE_TTC | SFNT_TYPE_TRUETYPE); +#else + 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); + } +#endif + + 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) { + unsigned long offset; + offset = ttc_read_offset(sfont, index); + if (offset == 0) ERROR("Invalid TTC index in %s.", ident); + error = sfnt_read_table_directory(sfont, ttc_read_offset(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 (verbose > 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/dvipdf-x/xsrc/tt_aux.c b/Build/source/texk/dvipdf-x/xsrc/tt_aux.c new file mode 100644 index 00000000000..4a07da531e7 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tt_aux.c @@ -0,0 +1,294 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 /* HAVE_CONFIG_H */ + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "numbers.h" + +#include "pdfobj.h" + +#include "sfnt.h" +#include "tt_table.h" +#include "tt_post.h" +#include "tt_aux.h" + +static int verbose = 0; + +void tt_aux_set_verbose(void) +{ + ++verbose; +} + +ULONG ttc_read_offset (sfnt *sfont, int ttc_idx) +{ + ULONG offset = 0, num_dirs = 0; + + if (sfont == NULL || +#ifdef XETEX + sfont->ft_face == NULL +#else + sfont->stream == NULL +#endif + ) + 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 < 0 || 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) { + 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 (verbose > 0) + MESG("** NOTICE: Font \"%s\" permits \"Preview & Print\" embedding only **\n", fontname); + *embed = 1; + } else { + if (always_embed) { + MESG("** NOTICE: Font \"%s\" may be subject to embedding restrictions **\n", fontname); + *embed = 1; + } + else { + 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/dvipdf-x/xsrc/tt_aux.h b/Build/source/texk/dvipdf-x/xsrc/tt_aux.h new file mode 100644 index 00000000000..3b17d3a70aa --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tt_aux.h @@ -0,0 +1,39 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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" + +extern int always_embed; /* flag declared in dvipdfmx.c */ + +extern void tt_aux_set_verbose(void); + +/* TTC (TrueType Collection) */ +extern ULONG ttc_read_offset (sfnt *sfont, int 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/dvipdf-x/xsrc/tt_cmap.c b/Build/source/texk/dvipdf-x/xsrc/tt_cmap.c new file mode 100644 index 00000000000..ac8610485fd --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tt_cmap.c @@ -0,0 +1,1940 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 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 "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 "unicode.h" +#include "agl.h" +#include "pdfparse.h" +#include "pdfresource.h" +#include "otl_conf.h" + +#include "dpxfile.h" + +/* Hash */ +#include "dpxutil.h" + +#include "tt_cmap.h" + +#define VERBOSE_LEVEL_MIN 0 +static int verbose = 0; +void +otf_cmap_set_verbose (void) +{ + otl_gsub_set_verbose(); + verbose++; +} + +/* 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) + ERROR("invalid cmap subtable"); + + 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) + ERROR("invalid cmap subtable"); + + 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 */ + + 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) + ERROR("invalid cmap subtable"); + + 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) + ERROR("invalid cmap subtable"); + + 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]; + else + return 0; + + 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) + ERROR("invalid cmap subtable"); + + 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; + ULONG 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; + } + + 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: + ERROR("Unrecognized OpenType/TrueType cmap format."); + } + } + RELEASE(cmap); + } + + return; +} + + +USHORT +tt_cmap_lookup (tt_cmap *cmap, long 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: + ERROR("Unrecognized OpenType/TrueType cmap subtable format"); + break; + } + + return gid; +} + +/* Sorry for placing this here. + * We need to rewrite TrueType font support code... + */ + +#define WBUF_SIZE 1024 +static unsigned char wbuf[WBUF_SIZE]; + +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}; + +static void +load_cmap4 (struct cmap4 *map, + unsigned char *GIDToCIDMap, CMap *cmap) +{ + USHORT c0, c1, gid, cid; + USHORT j, d, segCount; + USHORT ch; + long i; + + 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) { + if (GIDToCIDMap) { + cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); + if (cid == 0) + WARN("GID %u does not have corresponding CID %u.", + gid, cid); + } else { + cid = gid; + } + wbuf[0] = 0; + wbuf[1] = 0; + wbuf[2] = (ch >> 8) & 0xff; + wbuf[3] = ch & 0xff; + CMap_add_cidchar(cmap, wbuf, 4, cid); + } + } + } + + return; +} + +static void +load_cmap12 (struct cmap12 *map, + unsigned char *GIDToCIDMap, CMap *cmap) +{ + ULONG i, ch; /* LONG ? */ + USHORT gid, cid; + + for (i = 0; i < map->nGroups; i++) { + for (ch = map->groups[i].startCharCode; + ch <= map->groups[i].endCharCode; + ch++) { + long d = ch - map->groups[i].startCharCode; + gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); + if (GIDToCIDMap) { + cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); + if (cid == 0) + WARN("GID %u does not have corresponding CID %u.", gid, cid); + } else { + cid = gid; + } + wbuf[0] = (ch >> 24) & 0xff; + wbuf[1] = (ch >> 16) & 0xff; + wbuf[2] = (ch >> 8) & 0xff; + wbuf[3] = ch & 0xff; + CMap_add_cidchar(cmap, wbuf, 4, cid); + } + } + + return; +} + +/* 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" + +static int +handle_CIDFont (sfnt *sfont, + unsigned char **GIDToCIDMap, CIDSysInfo *csi) +{ + cff_font *cffont; + long offset, i; + card16 num_glyphs, gid; + cff_charsets *charset; + unsigned char *map; + struct tt_maxp_table *maxp; + + ASSERT(csi); + + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset == 0) { + csi->registry = NULL; + csi->ordering = NULL; + *GIDToCIDMap = NULL; + return 0; + } + + maxp = tt_read_maxp_table(sfont); + num_glyphs = (card16) maxp->numGlyphs; + RELEASE(maxp); + if (num_glyphs < 1) + ERROR("No glyph contained in this font..."); + + cffont = cff_open(sfont, offset, 0); + if (!cffont) + ERROR("Could not open CFF font..."); + + + if (!(cffont->flag & FONTTYPE_CIDFONT)) { + cff_close(cffont); + csi->registry = NULL; + csi->ordering = NULL; + *GIDToCIDMap = NULL; + return 0; + } + + if (!cff_dict_known(cffont->topdict, "ROS")) { + ERROR("No CIDSystemInfo???"); + } 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); + charset = cffont->charsets; + if (!charset) { + ERROR("No CFF charset data???"); + } + + map = NEW(num_glyphs * 2, unsigned char); + memset(map, 0, num_glyphs * 2); + switch (charset->format) { + case 0: + { + s_SID *cids; /* CID... */ + + cids = charset->data.glyphs; + for (gid = 1, i = 0; + i < charset->num_entries; i++) { + map[2*gid ] = (cids[i] >> 8) & 0xff; + map[2*gid+1] = cids[i] & 0xff; + 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) { + map[2*gid ] = (cid >> 8) & 0xff; + map[2*gid + 1] = cid & 0xff; + gid++; + } + } + } + break; + case 2: + { + cff_range2 *ranges; + card16 cid, count; + + ranges = charset->data.range2; + if (charset->num_entries == 1 && + ranges[0].first == 1) { + /* "Complete" CIDFont */ + RELEASE(map); map = NULL; + } 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) { + map[gid] = (cid >> 8) & 0xff; + map[gid] = cid & 0xff; + gid++; + } + } + + } + } + break; + default: + RELEASE(map); map = NULL; + ERROR("Unknown CFF charset format...: %d", charset->format); + break; + } + cff_close(cffont); + + *GIDToCIDMap = map; + return 1; +} + +/* + * 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 USHORT +handle_subst_glyphs (CMap *cmap, + CMap *cmap_add, const char *used_glyphs, + sfnt *sfont) +{ + USHORT count; + USHORT i, gid; + + for (count = 0, i = 0; i < 8192; i++) { + int j; + long len, inbytesleft, outbytesleft; + const unsigned char *inbuf; + unsigned char *outbuf; + + if (used_glyphs[i] == 0) + continue; + + for (j = 0; j < 8; j++) { + gid = 8 * i + j; + + if (!is_used_char2(used_glyphs, gid)) + continue; + + if (!cmap_add) { +#if XETEX + if (FT_HAS_GLYPH_NAMES(sfont->ft_face)) { + /* JK: try to look up Unicode values from the glyph name... */ +#define MAX_UNICODES 16 +#define MAX_NAME 256 + static char name[MAX_NAME] = "(none)"; + long unicodes[MAX_UNICODES]; + int unicode_count = -1; + FT_Error err = FT_Get_Glyph_Name(sfont->ft_face, gid, name, MAX_NAME); + if (!err) { + unicode_count = agl_get_unicodes(name, unicodes, MAX_UNICODES); + } +#undef MAX_UNICODES +#undef MAX_NAME + if (unicode_count == -1) { + MESG("No Unicode mapping available: GID=%u, name=%s\n", gid, name); + } else { + /* the Unicode characters go into wbuf[2] and following, in UTF16BE */ + /* we rely on WBUF_SIZE being more than adequate for MAX_UNICODES */ + unsigned char* p = wbuf + 2; + int k; + len = 0; + for (k = 0; k < unicode_count; ++k) { + len += UC_sput_UTF16BE(unicodes[k], &p, wbuf+WBUF_SIZE); + } + wbuf[0] = (gid >> 8) & 0xff; + wbuf[1] = gid & 0xff; + CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len); + } + } +#else + WARN("No Unicode mapping available: GID=%u", gid); +#endif + } else { + wbuf[0] = (gid >> 8) & 0xff; + wbuf[1] = gid & 0xff; + inbuf = wbuf; + inbytesleft = 2; + outbuf = wbuf + 2; + outbytesleft = WBUF_SIZE - 2; + CMap_decode(cmap_add, + &inbuf , &inbytesleft, + &outbuf, &outbytesleft); + if (inbytesleft != 0) { + WARN("CMap conversion failed..."); + } else { + len = WBUF_SIZE - 2 - outbytesleft; + CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len); + count++; + + if (verbose > VERBOSE_LEVEL_MIN) { + long _i; + + MESG("otf_cmap>> Additional ToUnicode mapping: <%04X> <", gid); + for (_i = 0; _i < len; _i++) { + MESG("%02X", wbuf[2 + _i]); + } + MESG(">\n"); + } + + } + } + + } + } + + return count; +} + +static pdf_obj * +create_ToUnicode_cmap4 (struct cmap4 *map, + const char *cmap_name, CMap *cmap_add, + const char *used_glyphs, + sfnt *sfont) +{ + pdf_obj *stream = NULL; + CMap *cmap; + USHORT c0, c1, gid, count, ch; + USHORT i, j, d, segCount; + char used_glyphs_copy[8192]; + + 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); + + memcpy(used_glyphs_copy, used_glyphs, 8192); + + segCount = map->segCountX2 / 2; + for (count = 0, i = 0; i < segCount; 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 (is_used_char2(used_glyphs_copy, gid)) { + count++; + + wbuf[0] = (gid >> 8) & 0xff; + wbuf[1] = (gid & 0xff); + + wbuf[2] = (ch >> 8) & 0xff; + wbuf[3] = ch & 0xff; + + CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, 2); + + /* Avoid duplicate entry + * There are problem when two Unicode code is mapped to + * single glyph... + */ + used_glyphs_copy[gid/8] &= ~(1 << (7 - (gid % 8))); + count++; + } + } + } + + count += handle_subst_glyphs(cmap, cmap_add, used_glyphs_copy, sfont); + + if (count < 1) + stream = NULL; + else { + stream = CMap_create_stream(cmap, 0); + } + CMap_release(cmap); + + return stream; +} + + +static pdf_obj * +create_ToUnicode_cmap12 (struct cmap12 *map, + const char *cmap_name, CMap *cmap_add, + const char *used_glyphs, + sfnt *sfont) +{ + pdf_obj *stream = NULL; + CMap *cmap; + ULONG i, ch; + USHORT gid, count; + char used_glyphs_copy[8192]; + + 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); + + memcpy(used_glyphs_copy, used_glyphs, 8192); + for (count = 0, i = 0; i < map->nGroups; i++) { + for (ch = map->groups[i].startCharCode; + ch <= map->groups[i].endCharCode; ch++) { + unsigned char *p; + int len; + long d; + + p = wbuf + 2; + d = ch - map->groups[i].startCharCode; + gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); + if (is_used_char2(used_glyphs_copy, gid)) { + count++; + wbuf[0] = (gid >> 8) & 0xff; + wbuf[1] = (gid & 0xff); + len = UC_sput_UTF16BE((long)ch, &p, wbuf+WBUF_SIZE); + + used_glyphs_copy[gid/8] &= ~(1 << (7 - (gid % 8))); + CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, len); + } + } + } + + count += handle_subst_glyphs(cmap, cmap_add, used_glyphs_copy, sfont); + + if (count < 1) + stream = NULL; + else { + stream = CMap_create_stream(cmap, 0); + } + CMap_release(cmap); + + 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, + int ttc_index, /* 0 for non-TTC */ + FT_Face face, + const char *used_glyphs) +{ + pdf_obj *cmap_ref = NULL; + long res_id; + pdf_obj *cmap_obj = NULL; + CMap *cmap_add; + int cmap_add_id; + tt_cmap *ttcmap; + char *normalized_font_name; + char *cmap_name; + FILE *fp = NULL; + sfnt *sfont; + long offset = 0; + int i; + + /* replace slash in map name with dash to make the output cmap name valid, + * happens when XeTeX embeds full font path + * https://sourceforge.net/p/xetex/bugs/52/ + */ + normalized_font_name = NEW(strlen(font_name)+1, char); + strcpy(normalized_font_name, font_name); + for (i = 0; i < strlen(font_name); ++i) { + if (normalized_font_name[i] == '/') + normalized_font_name[i] = '-'; + } + + cmap_name = NEW(strlen(font_name)+strlen("-UTF16")+5, char); + sprintf(cmap_name, "%s,%03d-UTF16", normalized_font_name, ttc_index); + + res_id = pdf_findresource("CMap", cmap_name); + if (res_id >= 0) { + RELEASE(cmap_name); + cmap_ref = pdf_get_resource_reference(res_id); + return cmap_ref; + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otf_cmap>> Creating ToUnicode CMap for \"%s\"...\n", font_name); + } + +#ifdef XETEX + sfont = sfnt_open(face, -1); +#else + fp = DPXFOPEN(font_name, DPX_RES_TYPE_TTFONT); + if (!fp) { + fp = DPXFOPEN(font_name, DPX_RES_TYPE_OTFONT); + } + + if (!fp) { + RELEASE(cmap_name); + return NULL; + } + + sfont = sfnt_open(fp); +#endif + + if (!sfont) { + ERROR("Could not open OpenType/TrueType font file \"%s\"", font_name); + } + + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { + ERROR("Invalid TTC index"); + } + break; + default: + offset = 0; + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) { + ERROR("Could not read OpenType/TrueType table directory."); + } + + cmap_add_id = CMap_cache_find(cmap_name); + if (cmap_add_id < 0) { + cmap_add = NULL; + } else { + cmap_add = CMap_cache_get(cmap_add_id); + } + + CMap_set_silent(1); /* many warnings without this... */ + 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) { + cmap_obj = create_ToUnicode_cmap4(ttcmap->map, + cmap_name, cmap_add, used_glyphs, sfont); + break; + } + if (ttcmap->format == 12) { + cmap_obj = create_ToUnicode_cmap12(ttcmap->map, + cmap_name, cmap_add, used_glyphs, sfont); + break; + } + } + if (cmap_obj == NULL) + WARN("Unable to read OpenType/TrueType Unicode cmap table."); + tt_cmap_release(ttcmap); + CMap_set_silent(0); + + if (cmap_obj) { + res_id = pdf_defineresource("CMap", cmap_name, + cmap_obj, PDF_RES_FLUSH_IMMEDIATE); + cmap_ref = pdf_get_resource_reference(res_id); + } else { + cmap_ref = NULL; + } + RELEASE(cmap_name); + + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + + return cmap_ref; +} + +/* Must be smaller than (WBUF_SIZE-2)/8 */ +#define MAX_UNICODES 16 + +struct gent +{ + USHORT gid; + long ucv; /* assigned PUA unicode */ + + int num_unicodes; + long unicodes[MAX_UNICODES]; +}; + +static void +create_cmaps (CMap *cmap, CMap *tounicode, + struct ht_table *unencoded, unsigned char *GIDToCIDMap) +{ + struct ht_iter iter; + + ASSERT(cmap && unencoded); + + if (ht_set_iter(unencoded, &iter) < 0) + return; + + CMap_set_silent(1); /* many warnings without this... */ + + do { + struct gent *glyph; + unsigned char *ucv; + int i, len; + unsigned char *p, *endptr; + CID cid; + + glyph = (struct gent *) ht_iter_getval(&iter); + ucv = (unsigned char *) ht_iter_getkey(&iter, &len); + + if (GIDToCIDMap) { + cid = ((GIDToCIDMap[2 * glyph->gid] << 8)|GIDToCIDMap[2 * glyph->gid + 1]); + if (cid == 0) + WARN("Glyph gid=%u does not have corresponding CID.", glyph->gid); + } else { + cid = glyph->gid; + } + + CMap_add_cidchar(cmap, ucv, 4, cid); + + if (tounicode) { + wbuf[0] = (cid >> 8) & 0xff; + wbuf[1] = cid & 0xff; + p = wbuf + 2; + endptr = wbuf + WBUF_SIZE; + len = 0; + for (i = 0; i < glyph->num_unicodes; i++) { + len += UC_sput_UTF16BE(glyph->unicodes[i], &p, endptr); + } + CMap_add_bfchar(tounicode, wbuf, 2, wbuf + 2, len); + } + } while (ht_iter_next(&iter) >= 0); + + CMap_set_silent(0); + + ht_clear_iter(&iter); +} + +static void +add_glyph (struct ht_table *unencoded, + USHORT gid, long ucv, int num_unicodes, long *unicodes) +{ + struct gent *glyph; + int i; + + ASSERT(unencoded); + + if (gid == 0 || num_unicodes < 1) { + return; + } + + wbuf[0] = (ucv >> 24) & 0xff; + wbuf[1] = (ucv >> 16) & 0xff; + wbuf[2] = (ucv >> 8) & 0xff; + wbuf[3] = ucv & 0xff; + + glyph = NEW(1, struct gent); + glyph->gid = gid; + glyph->num_unicodes = num_unicodes; + for (i = 0; + i < num_unicodes && i < MAX_UNICODES; i++) { + glyph->unicodes[i] = unicodes[i]; + } + + ht_append_table(unencoded, wbuf, 4, glyph); +} + +/* This seriously affects speed... */ +static struct gent * +find_glyph (struct ht_table *unencoded, long ucv) +{ + ASSERT(unencoded); + + wbuf[0] = (ucv >> 24) & 0xff; + wbuf[1] = (ucv >> 16) & 0xff; + wbuf[2] = (ucv >> 8) & 0xff; + wbuf[3] = ucv & 0xff; + + return (struct gent *) ht_lookup_table(unencoded, wbuf, 4); +} + +static void +handle_subst (pdf_obj *dst_obj, pdf_obj *src_obj, int flag, + otl_gsub *gsub_list, tt_cmap *ttcmap, + struct ht_table *unencoded) +{ + pdf_obj *tmp; + long i, j, src_size, dst_size; + long src, dst; + long src_start, src_end, dst_start, dst_end; + + src_size = pdf_array_length(src_obj); + dst_size = pdf_array_length(dst_obj); + + dst_start = dst_end = -1; dst = 0; + src_start = src_end = -1; src = 0; + for (i = 0, j = 0; + i < src_size && j < dst_size; i++) { + USHORT gid; + int rv; + struct gent *glyph; + + tmp = pdf_get_array(src_obj, i); + if (PDF_OBJ_ARRAYTYPE(tmp)) { + src_start = (long) pdf_number_value(pdf_get_array(tmp, 0)); + src_end = (long) pdf_number_value(pdf_get_array(tmp, 1)); + } else { + src_start = src_end = (long) pdf_number_value(tmp); + } + for (src = src_start; src <= src_end; src++) { + glyph = find_glyph(unencoded, src); + if (glyph) + gid = glyph->gid; + else { + gid = tt_cmap_lookup(ttcmap, src); + } + dst++; + if (dst > dst_end) { + tmp = pdf_get_array(dst_obj, j++); + if (PDF_OBJ_ARRAYTYPE(tmp)) { + dst_start = (long) pdf_number_value(pdf_get_array(tmp, 0)); + dst_end = (long) pdf_number_value(pdf_get_array(tmp, 1)); + } else { + dst_start = dst_end = (long) pdf_number_value(tmp); + } + dst = dst_start; + } + if (gid == 0) { + if (flag == 'r' || flag == 'p') { + if (src < 0x10000) { + WARN("Font does not have glyph for U+%04X.", src); + } else { + WARN("Font does not have glyph for U+%06X.", src); + } + } + if (flag == 'r') { + ERROR("Missing glyph found..."); + } + continue; + } + rv = otl_gsub_apply(gsub_list, &gid); + if (rv < 0) { + if (flag == 'p' || flag == 'r') { + if (src < 0x10000) { + WARN("No substituted glyph for U+%04X.", src); + } else { + WARN("No substituted glyph for U+%06X.", src); + } + } + if (flag == 'r') { + ERROR("Missing glyph found..."); + } + continue; + } + + if (glyph) { + glyph->gid = gid; + } else { + add_glyph(unencoded, gid, dst, 1, &src); + } + + if (verbose > VERBOSE_LEVEL_MIN) { + if (dst < 0x10000) { + MESG("otf_cmap>> Substituted glyph gid=%u assigned to U+%04X\n", + gid, dst); + } else { + MESG("otf_cmap>> Substituted glyph gid=%u assigned to U+%06X\n", + gid, dst); + } + } + + } + } + + if (dst < dst_end || src < src_end || + i < src_size || j < dst_size) { + WARN("Number of glyphs in left-side and right-side not equal..."); + WARN("Please check .otl file..."); + } +} + +static void +handle_assign (pdf_obj *dst, pdf_obj *src, int flag, + otl_gsub *gsub_list, tt_cmap *ttcmap, + struct ht_table *unencoded) +{ + long unicodes[MAX_UNICODES], ucv; + int i, n_unicodes, rv; + USHORT gid_in[MAX_UNICODES], lig; + + n_unicodes = pdf_array_length(src); /* FIXME */ + ucv = (long) pdf_number_value(pdf_get_array(dst, 0)); /* FIXME */ + if (!UC_is_valid(ucv)) { + if (flag == 'r' || flag == 'p') { + if (ucv < 0x10000) { + WARN("Invalid Unicode in: %04X", ucv); + } else { + WARN("Invalid Unicode in: %06X", ucv); + } + } + if (flag == 'r') { + ERROR("Invalid Unicode code specified.", ucv); + } + return; + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Ligature component:"); + } + + for (i = 0; i < n_unicodes; i++) { + unicodes[i] = + (long) pdf_number_value(pdf_get_array(src, i)); + gid_in[i] = tt_cmap_lookup(ttcmap, unicodes[i]); + + if (verbose > VERBOSE_LEVEL_MIN) { + if (unicodes[i] < 0x10000) { + MESG(" U+%04X (gid=%u)", unicodes[i], gid_in[i]); + } else { + MESG(" U+%06X (gid=%u)", unicodes[i], gid_in[i]); + } + } + + if (gid_in[i] == 0) { + if (flag == 'r' || flag == 'p') { + if (unicodes[i] < 0x10000) { + WARN("Unicode char U+%04X not exist in font...", unicodes[i]); + } else { + WARN("Unicode char U+%06X not exist in font...", unicodes[i]); + } + } + if (flag == 'r') { + ERROR("Missing glyph found..."); + } + return; + } + + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + } + + rv = otl_gsub_apply_lig(gsub_list, + gid_in, (USHORT)n_unicodes, &lig); + if (rv < 0) { + if (flag == 'p') + WARN("No ligature found..."); + else if (flag == 'r') + ERROR("No ligature found..."); + return; + } + + add_glyph(unencoded, lig, ucv, n_unicodes, unicodes); + + if (verbose > VERBOSE_LEVEL_MIN) { + if (ucv < 0x10000) { + MESG("otf_cmap>> Ligature glyph gid=%u assigned to U+%04X\n", lig, ucv); + } else { + MESG("otf_cmap>> Ligature glyph gid=%u assigned to U+%06X\n", lig, ucv); + } + } + + return; +} + +static int +load_base_CMap (const char *cmap_name, int wmode, + CIDSysInfo *csi, unsigned char *GIDToCIDMap, + tt_cmap *ttcmap) +{ + int cmap_id; + + cmap_id = CMap_cache_find(cmap_name); + if (cmap_id < 0) { + CMap *cmap; + + 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); + + if (csi) { /* CID */ + CMap_set_CIDSysInfo(cmap, csi); + } else { + CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY); + } + + if (ttcmap->format == 12) { + load_cmap12(ttcmap->map, GIDToCIDMap, cmap); + } else if (ttcmap->format == 4) { + load_cmap4(ttcmap->map, GIDToCIDMap, cmap); + } + + cmap_id = CMap_cache_add(cmap); + } + + return cmap_id; +} + +static void +load_gsub (pdf_obj *conf, otl_gsub *gsub_list, sfnt *sfont) +{ + pdf_obj *rule; + char *script, *language, *feature; + long i, size; + + rule = otl_conf_get_rule(conf); + if (!rule) + return; + + script = otl_conf_get_script (conf); + language = otl_conf_get_language(conf); + + size = pdf_array_length(rule); + for (i = 0; i < size; i += 2) { + pdf_obj *tmp, *commands; + int flag; + long j, num_comms; + + tmp = pdf_get_array(rule, i); + flag = (int) pdf_number_value(tmp); + + commands = pdf_get_array(rule, i+1); + num_comms = pdf_array_length(commands); + + /* (assign|substitute) tag dst src */ + for (j = 0 ; j < num_comms; j += 4) { + tmp = pdf_get_array(commands, 1); + if (PDF_OBJ_STRINGTYPE(tmp)) { + feature = pdf_string_value(tmp); + if (otl_gsub_add_feat(gsub_list, + script, language, feature, sfont) < 0) { + if (flag == 'p') + WARN("No OTL feature matches \"%s.%s.%s\" found.", + script, language, feature); + else if (flag == 'r') + ERROR("No OTL feature matches \"%s.%s.%s\" found.", + script, language, feature); + } + } + + } + } + +} + +static void +handle_gsub (pdf_obj *conf, + tt_cmap *ttcmap, otl_gsub *gsub_list, + struct ht_table *unencoded) +{ + pdf_obj *rule; + char *script, *language, *feature; + long i, size; + + if (!conf) + return; + + rule = otl_conf_get_rule(conf); + if (!rule) { + return; + } + + if (!PDF_OBJ_ARRAYTYPE(rule)) { + WARN("Not arraytype?"); + return; + } + script = otl_conf_get_script (conf); + language = otl_conf_get_language(conf); + + size = pdf_array_length(rule); + for (i = 0; i < size; i += 2) { + pdf_obj *tmp, *commands; + long j, num_comms; + int flag; + + tmp = pdf_get_array(rule, i); + flag = (int) pdf_number_value(tmp); + + commands = pdf_get_array (rule, i+1); + num_comms = pdf_array_length(commands); + + for (j = 0; j < num_comms; j += 4) { + pdf_obj *operator; + pdf_obj *src, *dst, *feat; + int rv; + + /* (assing|substitute) tag dst src */ + operator = pdf_get_array(commands, j); + + feat = pdf_get_array(commands, j+1); + if (PDF_OBJ_STRINGTYPE(feat)) + feature = pdf_string_value(feat); + else + feature = NULL; + + dst = pdf_get_array(commands, j+2); + src = pdf_get_array(commands, j+3); + + rv = otl_gsub_select(gsub_list, script, language, feature); + if (rv < 0) { + if (flag == 'p') { + WARN("No GSUB feature %s.%s.%s loaded...", + script, language, feature); + } else if (flag == 'r') { + ERROR("No GSUB feature %s.%s.%s loaded...", + script, language, feature); + } + } else { + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> %s:\n", pdf_name_value(operator)); + } + + if (!strcmp(pdf_name_value(operator), "assign")) { + handle_assign(dst, src, flag, + gsub_list, ttcmap, unencoded); + } else if (!strcmp(pdf_name_value(operator), "substitute")) { + handle_subst(dst, src, flag, + gsub_list, ttcmap, unencoded); + } + } + + } + + } + +} + +static void CDECL +hval_free (void *hval) +{ + RELEASE(hval); +} + +int +otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC font */ + const char *otl_tags, int wmode) +{ + int cmap_id = -1; + int tounicode_id = -1, is_cidfont = 0; + sfnt *sfont; + unsigned long offset = 0; + char *base_name = NULL, *cmap_name = NULL; + char *tounicode_name = NULL; + FILE *fp = NULL; + otl_gsub *gsub_list = NULL; + tt_cmap *ttcmap; + CMap *cmap, *base, *tounicode = NULL; + CIDSysInfo csi = {NULL, NULL, 0}; + unsigned char *GIDToCIDMap = NULL; + + if (!map_name) + return -1; + + if (ttc_index > 999 || ttc_index < 0) { + return -1; /* Sorry for this... */ + } + +fprintf(stderr, "otf_load_Unicode_CMap(%s, %d)\n", map_name, ttc_index); +#ifdef XETEX + sfont = NULL; /* FIXME */ +#else + 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) return -1; + sfont = dfont_open(fp, ttc_index); + } else { + sfont = sfnt_open(fp); + } +#endif + + if (!sfont) { + ERROR("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name); + } + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { + ERROR("Invalid TTC index"); + } + break; + case SFNT_TYPE_TRUETYPE: + case SFNT_TYPE_POSTSCRIPT: + offset = 0; + break; + case SFNT_TYPE_DFONT: + offset = sfont->offset; + break; + default: + ERROR("Not a OpenType/TrueType/TTC font?: %s", map_name); + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) + ERROR("Could not read OpenType/TrueType table directory."); + + base_name = NEW(strlen(map_name)+strlen("-UCS4-H")+5, char); + if (wmode) + sprintf(base_name, "%s,%03d-UCS4-V", map_name, ttc_index); + else { + sprintf(base_name, "%s,%03d-UCS4-H", map_name, ttc_index); + } + + if (otl_tags) { + cmap_name = NEW(strlen(map_name)+strlen(otl_tags)+strlen("-UCS4-H")+6, char); + if (wmode) + sprintf(cmap_name, "%s,%03d,%s-UCS4-V", map_name, ttc_index, otl_tags); + else + sprintf(cmap_name, "%s,%03d,%s-UCS4-H", map_name, ttc_index, otl_tags); + } else { + cmap_name = NEW(strlen(base_name)+1, char); + strcpy(cmap_name, base_name); + } + + if (sfont->type == SFNT_TYPE_POSTSCRIPT) { + is_cidfont = handle_CIDFont(sfont, &GIDToCIDMap, &csi); + } else { + is_cidfont = 0; + } + + if (is_cidfont) { + tounicode_name = NULL; + } else { + tounicode_name = NEW(strlen(map_name)+strlen("-UTF16")+5, char); + sprintf(tounicode_name, "%s,%03d-UTF16", map_name, ttc_index); + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otf_cmap>> Unicode charmap for font=\"%s\" layout=\"%s\"\n", + map_name, (otl_tags ? otl_tags : "none")); + } + + cmap_id = CMap_cache_find(cmap_name); + if (cmap_id >= 0) { + RELEASE(cmap_name); + RELEASE(base_name); + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (tounicode_name) + RELEASE(tounicode_name); + + sfnt_close(sfont); + DPXFCLOSE(fp); + + if (verbose > VERBOSE_LEVEL_MIN) + MESG("otf_cmap>> Found at cmap_id=%d.\n", cmap_id); + + return cmap_id; + } + + 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) { + ERROR("Unable to read OpenType/TrueType Unicode cmap table."); + } + } + } + cmap_id = load_base_CMap(base_name, wmode, + (is_cidfont ? &csi : NULL), + GIDToCIDMap, ttcmap); + if (cmap_id < 0) + ERROR("Failed to read OpenType/TrueType cmap table."); + + if (!otl_tags) { + RELEASE(cmap_name); + RELEASE(base_name); + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (tounicode_name) + RELEASE(tounicode_name); + if (is_cidfont) { + if (csi.registry) + RELEASE(csi.registry); + if (csi.ordering) + RELEASE(csi.ordering); + } + tt_cmap_release(ttcmap); + sfnt_close(sfont); + DPXFCLOSE(fp); + + return cmap_id; + } + + base = CMap_cache_get(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, lrange_min, lrange_max, 4); */ + CMap_set_usecmap(cmap, base); + CMap_add_cidchar(cmap, lrange_max, 4, 0); /* FIXME */ + + if (is_cidfont) { + CMap_set_CIDSysInfo(cmap, &csi); + if (csi.registry) + RELEASE(csi.registry); + if (csi.ordering) + RELEASE(csi.ordering); + } else { + CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY); + } + + gsub_list = otl_gsub_new(); + + { + struct ht_table unencoded; + char *conf_name, *opt_tag; + pdf_obj *conf, *opt_conf; + + conf_name = NEW(strlen(otl_tags)+1, char); + memset (conf_name, 0, strlen(otl_tags)+1); + opt_tag = strchr(otl_tags, ':'); + if (opt_tag) { + opt_tag++; + strncpy(conf_name, otl_tags, + strlen(otl_tags) - strlen(opt_tag) - 1); + } else { + strcpy(conf_name, otl_tags); + } + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Read layout config. \"%s\"\n", conf_name); + } + + conf = otl_find_conf(conf_name); + if (!conf) + ERROR("Layout file \"%s\" not found...", conf_name); + + load_gsub(conf, gsub_list, sfont); + if (opt_tag) { + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Layout option \"%s\" enabled\n", opt_tag); + } + opt_conf = otl_conf_find_opt(conf, opt_tag); + if (!opt_conf) + ERROR("There is no option \"%s\" in \"%s\".", + opt_tag, conf_name); + load_gsub(opt_conf, gsub_list, sfont); + } + + ht_init_table(&unencoded, hval_free); + + handle_gsub(conf, ttcmap, gsub_list, &unencoded); + if (opt_tag) { + opt_conf = otl_conf_find_opt(conf, opt_tag); + if (!opt_conf) + ERROR("There is no option \"%s\" in \"%s\".", + opt_tag, conf_name); + handle_gsub(opt_conf, ttcmap, gsub_list, &unencoded); + } + if (is_cidfont) { + tounicode_id = -1; + tounicode = NULL; + } else { + 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); + /* FIXME */ + CMap_add_bfchar(tounicode, srange_min, 2, srange_max, 2); + } + } + create_cmaps(cmap, tounicode, &unencoded, GIDToCIDMap); + + ht_clear_table(&unencoded); + RELEASE(conf_name); + } + + cmap_id = CMap_cache_add(cmap); + if (!is_cidfont && tounicode_id < 0) /* New */ + CMap_cache_add(tounicode); + + tt_cmap_release(ttcmap); + if (gsub_list) + otl_gsub_release(gsub_list); + + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("otf_cmap>> Overwrite CMap \"%s\" by \"%s\" with usecmap\n", + base_name, cmap_name); + } + + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (base_name) + RELEASE(base_name); + if (cmap_name) + RELEASE(cmap_name); + if (tounicode_name) + RELEASE(tounicode_name); + + sfnt_close(sfont); + DPXFCLOSE(fp); + + return cmap_id; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/tt_cmap.h b/Build/source/texk/dvipdf-x/xsrc/tt_cmap.h new file mode 100644 index 00000000000..30e28950fd4 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tt_cmap.h @@ -0,0 +1,80 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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" + +extern void otf_cmap_set_verbose (void); + +/* 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, long 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, + int ttc_index, + FT_Face face, + const char *used_glyphs); +/* CMap ID */ +extern int otf_load_Unicode_CMap (const char *map_name, + int ttc_index, + const char *otl_opts, int wmode); + +#endif /* _TT_CMAP_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/tt_glyf.c b/Build/source/texk/dvipdf-x/xsrc/tt_glyf.c new file mode 100644 index 00000000000..5ae56d8d707 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tt_glyf.c @@ -0,0 +1,671 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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, ... + * + */ + +#include "config.h" + +#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 int CDECL +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; + long i; + USHORT *w_stat; /* Estimate most frequently appeared width */ + + ASSERT(g); + + if (sfont == NULL || +#ifdef XETEX + sfont->ft_face == NULL +#else + sfont->stream == NULL +#endif + ) + 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++) { + long gap, j; + gap = (long) 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; + long i; + USHORT *w_stat; + + ASSERT(g); + + if (sfont == NULL || +#ifdef XETEX + sfont->ft_face == NULL +#else + sfont->stream == NULL +#endif + ) + 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/dvipdf-x/xsrc/tt_post.c b/Build/source/texk/dvipdf-x/xsrc/tt_post.c new file mode 100644 index 00000000000..0deb3ab8b23 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tt_post.c @@ -0,0 +1,276 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. +*/ + +#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 (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; + } + } + 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((unsigned char*)(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; + post->count = 0; + post->names = NULL; + } else if (post->Version == 0x00025000UL) { + WARN("TrueType 'post' version 2.5 found (deprecated)"); + post->numberOfGlyphs = 0; /* wrong */ + post->glyphNamePtr = NULL; + post->count = 0; + post->names = NULL; + } 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->numberOfGlyphs = 0; /* wrong */ + post->glyphNamePtr = NULL; + post->count = 0; + post->names = NULL; + } else if (post->Version == 0x00040000UL) { /* Apple format for printer-based fonts */ + post->numberOfGlyphs = 0; /* don't bother constructing char names, not sure if they'll ever be needed */ + post->glyphNamePtr = NULL; + post->count = 0; + post->names = NULL; + } else { + WARN("Unknown 'post' version: %08X", post->Version); + tt_release_post_table(post); + post = NULL; + } + + 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->count; gid++) { + if (post->glyphNamePtr[gid] && + !strcmp(glyphname, post->glyphNamePtr[gid])) { + return gid; + } + } + + return 0; +} + +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/dvipdf-x/xsrc/tt_table.c b/Build/source/texk/dvipdf-x/xsrc/tt_table.c new file mode 100644 index 00000000000..88b3a33c781 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/tt_table.c @@ -0,0 +1,505 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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. +*/ + +#include + +#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 = NULL; + + 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 = NULL; + + 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 = NULL; + + sfnt_locate_table(sfont, "hhea"); + + table = NEW(1, struct tt_hhea_table); + 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 = NULL; + + 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; + + if (sfnt_find_table_pos(sfont, "OS/2") == 0) + return NULL; + + sfnt_locate_table(sfont, "OS/2"); + + table = NEW(1, struct tt_os2__table); + + 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); + } + } + } + + return table; +} + +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; + + name_offset = sfnt_locate_table (sfont, "name"); + + if (sfnt_get_ushort(sfont)) + ERROR ("Expecting zero"); + + num_names = sfnt_get_ushort(sfont); + string_offset = sfnt_get_ushort(sfont); + for (i=0;i destlen - 1) { + fprintf(stderr, "\n** Notice: Name string too long. Truncating **\n"); + length = destlen - 1; + } + sfnt_seek_set (sfont, name_offset+string_offset+offset); + 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; + +#ifdef XETEX + + const char* name = FT_Get_Postscript_Name(sfont->ft_face); + namelen = strlen(name); + if (namelen > destlen - 1) { + strncpy(dest, name, destlen - 1); + dest[destlen] = 0; + } + else + strcpy(dest, name); + +#else + + /* 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; + + fprintf(stderr, "\n** Warning: No valid PostScript name available **\n"); + /* + Wrokaround 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); + } + +#endif + + return namelen; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/type0.c b/Build/source/texk/dvipdf-x/xsrc/type0.c new file mode 100644 index 00000000000..29acb44ea8b --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/type0.c @@ -0,0 +1,687 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.h" +#include "dpxfile.h" + +#include "pdfobj.h" +#include "fontmap.h" + +#include "cmap.h" +#include "cid.h" + +#include "type0.h" + + +#define TYPE0FONT_DEBUG_STR "Type0" +#define TYPE0FONT_DEBUG 3 + +static int __verbose = 0; + +static pdf_obj *pdf_read_ToUnicode_file (const char *cmap_name); + +void +Type0Font_set_verbose(void) +{ + __verbose++; +} + +/* + * used_chars: + * + * Single bit is used for each CIDs since used_chars can be reused as a + * stream content of CIDSet by doing so. See, cid.h for add_to_used() and + * is_used(). + */ + +static char * +new_used_chars2(void) +{ + char *used_chars; + + used_chars = NEW(8192, char); + memset(used_chars, 0, 8192); + + return used_chars; +} + +#define FLAG_NONE 0 +#define FLAG_USED_CHARS_SHARED (1 << 0) + +struct Type0Font { + char *fontname; /* BaseFont */ + char *encoding; /* "Identity-H" or "Identity-V" (not ID) */ + char *used_chars; /* Used chars (CIDs) */ + + /* + * Type0 only + */ + CIDFont *descendant; /* Only single descendant is allowed. */ + int flags; + int wmode; + + /* + * PDF Font Resource + */ + pdf_obj *indirect; + pdf_obj *fontdict; + pdf_obj *descriptor; /* MUST BE NULL */ +}; + +static void +Type0Font_init_font_struct (Type0Font *font) +{ + ASSERT(font); + + font->fontname = NULL; + font->fontdict = NULL; + font->indirect = NULL; + font->descriptor = NULL; + font->encoding = NULL; + font->used_chars = NULL; + font->descendant = NULL; + font->wmode = -1; + font->flags = FLAG_NONE; + + return; +} + +static void +Type0Font_clean (Type0Font *font) +{ + if (font) { + if (font->fontdict) + ERROR("%s: Object not flushed.", TYPE0FONT_DEBUG_STR); + if (font->indirect) + ERROR("%s: Object not flushed.", TYPE0FONT_DEBUG_STR); + if (font->descriptor) + ERROR("%s: FontDescriptor unexpected for Type0 font.", TYPE0FONT_DEBUG_STR); + if (!(font->flags & FLAG_USED_CHARS_SHARED) && font->used_chars) + RELEASE(font->used_chars); + if (font->encoding) + RELEASE(font->encoding); + if (font->fontname) + RELEASE(font->fontname); + font->fontdict = NULL; + font->indirect = NULL; + font->descriptor = NULL; + font->used_chars = NULL; + font->encoding = NULL; + font->fontname = NULL; + } +} + +/* PLEASE FIX THIS */ +#include "tt_cmap.h" + +static void +add_ToUnicode (Type0Font *font) +{ + pdf_obj *tounicode; + CIDFont *cidfont; + CIDSysInfo *csi; + char *cmap_name, *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. + */ + + cidfont = font->descendant; + if (!cidfont) { + ERROR("%s: No descendant CID-keyed font.", TYPE0FONT_DEBUG_STR); + return; + } + + 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. + */ + tounicode = pdf_read_ToUnicode_file("Adobe-Identity-UCS2"); + if (!tounicode) { /* This should work */ + tounicode = pdf_new_name("Identity-H"); + } + pdf_add_dict(font->fontdict, pdf_new_name("ToUnicode"), tounicode); + return; + } + + tounicode = NULL; + csi = CIDFont_get_CIDSysInfo(cidfont); + fontname = CIDFont_get_fontname(cidfont); + if (CIDFont_get_embedding(cidfont)) { + fontname += 7; /* FIXME */ + } + + if (!strcmp(csi->registry, "Adobe") && + !strcmp(csi->ordering, "Identity")) { + switch (CIDFont_get_subtype(cidfont)) { + case CIDFONT_TYPE2: + /* PLEASE FIX THIS */ + tounicode = otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), + CIDFont_get_opt_index(cidfont), + CIDFont_get_ft_face(cidfont), + Type0Font_get_usedchars(font)); + break; + default: + if (CIDFont_get_flag(cidfont, CIDFONT_FLAG_TYPE1C)) { /* FIXME */ + tounicode = otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), + CIDFont_get_opt_index(cidfont), + CIDFont_get_ft_face(cidfont), + Type0Font_get_usedchars(font)); + } else if (CIDFont_get_flag(cidfont, CIDFONT_FLAG_TYPE1)) { /* FIXME */ + /* Font loader will create ToUnicode and set. */ + return; + } else { + cmap_name = NEW(strlen(fontname) + 7, char); + sprintf(cmap_name, "%s-UTF16", fontname); + tounicode = pdf_read_ToUnicode_file(cmap_name); + if (!tounicode) { + sprintf(cmap_name, "%s-UCS2", fontname); + tounicode = pdf_read_ToUnicode_file(cmap_name); + } + RELEASE(cmap_name); + } + break; + } + } else { + cmap_name = NEW(strlen(csi->registry)+strlen(csi->ordering)+8, char); + sprintf(cmap_name, "%s-%s-UTF16", csi->registry, csi->ordering); + tounicode = pdf_read_ToUnicode_file(cmap_name); + if (!tounicode) { + sprintf(cmap_name, "%s-%s-UCS2", csi->registry, csi->ordering); + tounicode = pdf_read_ToUnicode_file(cmap_name); + } + RELEASE(cmap_name); + } + + if (tounicode) { + pdf_add_dict(font->fontdict, + pdf_new_name("ToUnicode"), tounicode); + } else { + WARN("Failed to load ToUnicode CMap for font \"%s\"", fontname); + } + + return; +} + +void +Type0Font_set_ToUnicode (Type0Font *font, pdf_obj *cmap_ref) +{ + ASSERT(font); + + pdf_add_dict(font->fontdict, + pdf_new_name("ToUnicode"), cmap_ref); +} + +static void +Type0Font_dofont (Type0Font *font) +{ + if (!font || !font->indirect) + return; + + if (!pdf_lookup_dict(font->fontdict, "ToUnicode")) { /* FIXME */ + add_ToUnicode(font); + } +} + +static void +Type0Font_flush (Type0Font *font) +{ + if (font) { + if (font->fontdict) + pdf_release_obj(font->fontdict); + font->fontdict = NULL; + if (font->indirect) + pdf_release_obj(font->indirect); + font->indirect = NULL; + if (font->descriptor) + ERROR("%s: FontDescriptor unexpected for Type0 font.", TYPE0FONT_DEBUG_STR); + font->descriptor = NULL; + } +} + +int +Type0Font_get_wmode (Type0Font *font) +{ + ASSERT(font); + + return font->wmode; +} + +#if 0 +char * +Type0Font_get_encoding (Type0Font *font) +{ + ASSERT(font); + + return font->encoding; +} +#endif /* 0 */ + +char * +Type0Font_get_usedchars (Type0Font *font) +{ + ASSERT(font); + + return font->used_chars; +} + +pdf_obj * +Type0Font_get_resource (Type0Font *font) +{ + ASSERT(font); + + /* + * This looks somewhat strange. + */ + if (!font->indirect) { + pdf_obj *array; + + array = pdf_new_array(); + pdf_add_array(array, CIDFont_get_resource(font->descendant)); + pdf_add_dict(font->fontdict, pdf_new_name("DescendantFonts"), array); + font->indirect = pdf_ref_obj(font->fontdict); + } + + return pdf_link_obj(font->indirect); +} + +/******************************** CACHE ********************************/ + +#define CHECK_ID(n) do {\ + if ((n) < 0 || (n) >= __cache.count)\ + ERROR("%s: Invalid ID %d", TYPE0FONT_DEBUG_STR, (n));\ +} while (0) + +#define CACHE_ALLOC_SIZE 16u + +static struct font_cache { + int count; + int capacity; + Type0Font *fonts; +} __cache = { + 0, 0, NULL +}; + +void +Type0Font_cache_init (void) +{ + if (__cache.fonts) + ERROR("%s: Already initialized.", TYPE0FONT_DEBUG_STR); + __cache.count = 0; + __cache.capacity = 0; + __cache.fonts = NULL; +} + +Type0Font * +Type0Font_cache_get (int id) +{ + CHECK_ID(id); + + return &__cache.fonts[id]; +} + +#ifdef XETEX +unsigned short* +Type0Font_get_ft_to_gid(int id) +{ + return CIDFont_get_ft_to_gid(Type0Font_cache_get(id)->descendant); +} +#endif + +int +Type0Font_cache_find (const char *map_name, int cmap_id, fontmap_opt *fmap_opt) +{ + int font_id = -1; + Type0Font *font; + CIDFont *cidfont; + CMap *cmap; + CIDSysInfo *csi; + char *fontname = NULL; + int cid_id = -1, parent_id = -1, wmode = 0; + int pdf_ver; + + pdf_ver = pdf_get_version(); + if (!map_name || cmap_id < 0 || pdf_ver < 2) + return -1; + + /* + * Encoding is Identity-H or Identity-V according as thier WMode value. + * + * We do not use match against the map_name since fonts (TrueType) covers + * characters across multiple character collection (eg, Adobe-Japan1 and + * Adobe-Japan2) must be splited into multiple CID-keyed fonts. + */ + + cmap = CMap_cache_get(cmap_id); + csi = (CMap_is_Identity(cmap)) ? NULL : CMap_get_CIDSysInfo(cmap) ; + + cid_id = CIDFont_cache_find(map_name, csi, fmap_opt); + + if (cid_id < 0) + return -1; + + /* + * The descendant CID-keyed font has already been registerd. + * If CID-keyed font with ID = cid_id is new font, then create new parent + * Type 0 font. Otherwise, there already exists parent Type 0 font and + * then we find him and return his ID. We must check against their WMode. + */ + + cidfont = CIDFont_cache_get(cid_id); + wmode = CMap_get_wmode(cmap); + + /* Does CID-keyed font already have parent ? */ + parent_id = CIDFont_get_parent_id(cidfont, wmode); + if (parent_id >= 0) + return parent_id; /* If so, we don't need new one. */ + + /* + * CIDFont does not have parent or his parent's WMode does not matched with + * wmode. Create new Type0 font. + */ + + if (__cache.count >= __cache.capacity) { + __cache.capacity += CACHE_ALLOC_SIZE; + __cache.fonts = RENEW(__cache.fonts, __cache.capacity, struct Type0Font); + } + font_id = __cache.count; + font = &__cache.fonts[font_id]; + + Type0Font_init_font_struct(font); + + /* + * All CJK double-byte characters are mapped so that resulting + * character codes coincide with CIDs of given character collection. + * So, the Encoding is always Identity-H for horizontal fonts or + * Identity-V for vertical fonts. + */ + if (wmode) { + font->encoding = NEW(strlen("Identity-V")+1, char); + strcpy(font->encoding, "Identity-V"); + } else { + font->encoding = NEW(strlen("Identity-H")+1, char); + strcpy(font->encoding, "Identity-H"); + } + font->wmode = wmode; + + /* + * Now we start font dictionary. + */ + font->fontdict = pdf_new_dict(); + pdf_add_dict(font->fontdict, pdf_new_name ("Type"), pdf_new_name ("Font")); + pdf_add_dict(font->fontdict, pdf_new_name ("Subtype"), pdf_new_name ("Type0")); + + /* + * Type0 font does not have FontDescriptor because it is not a simple font. + * Instead, DescendantFonts appears here. + * + * Up to PDF version 1.5, Type0 font must have single descendant font which + * is a CID-keyed font. Future PDF spec. will allow multiple desecendant + * fonts. + */ + font->descendant = cidfont; + CIDFont_attach_parent(cidfont, font_id, wmode); + + /* + * PostScript Font name: + * + * Type0 font's fontname is usually descendant CID-keyed font's font name + * appended by -ENCODING. + */ + fontname = CIDFont_get_fontname(cidfont); + + if (__verbose) { + if (CIDFont_get_embedding(cidfont) && strlen(fontname) > 7) + MESG("(CID:%s)", fontname+7); /* skip XXXXXX+ */ + else + MESG("(CID:%s)", fontname); + } + + /* + * The difference between CID-keyed font and TrueType font appears here. + * + * Glyph substitution for vertical writing is done in CMap mapping process + * for CID-keyed fonts. But we must rely on OpenType layout table in the + * case of TrueType fonts. So, we must use different used_chars for each + * horizontal and vertical fonts in that case. + * + * In most PDF file, encoding name is not appended to fontname for Type0 + * fonts having CIDFontType 2 font as their descendant. + */ + + font->used_chars = NULL; + font->flags = FLAG_NONE; + + switch (CIDFont_get_subtype(cidfont)) { + case CIDFONT_TYPE0: + font->fontname = NEW(strlen(fontname)+strlen(font->encoding)+2, char); + sprintf(font->fontname, "%s-%s", fontname, font->encoding); + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), pdf_new_name(font->fontname)); + /* + * Need used_chars to write W, W2. + */ + if ((parent_id = CIDFont_get_parent_id(cidfont, wmode ? 0 : 1)) < 0) + font->used_chars = new_used_chars2(); + else { + /* Don't allocate new one. */ + font->used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); + font->flags |= FLAG_USED_CHARS_SHARED; + } + break; + case CIDFONT_TYPE2: + /* + * TrueType: + * + * Use different used_chars for H and V. + */ + pdf_add_dict(font->fontdict, + pdf_new_name("BaseFont"), pdf_new_name(fontname)); + font->used_chars = new_used_chars2(); + break; + default: + ERROR("Unrecognized CIDFont Type"); + break; + } + + pdf_add_dict(font->fontdict, + pdf_new_name("Encoding"), pdf_new_name(font->encoding)); + + __cache.count++; + + return font_id; +} + +void +Type0Font_cache_close (void) +{ + int font_id; + + /* + * This need to be fixed. + * + * CIDFont_cache_close() before Type0Font_release because of used_chars. + * ToUnicode support want descendant CIDFont's CSI and fontname. + */ + if (__cache.fonts) { + for (font_id = 0; font_id < __cache.count; font_id++) + Type0Font_dofont(&__cache.fonts[font_id]); + } + CIDFont_cache_close(); + if (__cache.fonts) { + for (font_id = 0; font_id < __cache.count; font_id++) { + Type0Font_flush(&__cache.fonts[font_id]); + Type0Font_clean(&__cache.fonts[font_id]); + } + RELEASE(__cache.fonts); + } + __cache.fonts = NULL; + __cache.count = 0; + __cache.capacity = 0; +} + + +/************************************************************************/ + +int +pdf_font_findfont0 (const char *font_name, int cmap_id, fontmap_opt *fmap_opt) +{ + return Type0Font_cache_find(font_name, cmap_id, fmap_opt); +} + +/******************************** 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> \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; + long 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/dvipdf-x/xsrc/type0.h b/Build/source/texk/dvipdf-x/xsrc/type0.h new file mode 100644 index 00000000000..68979decbc6 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/type0.h @@ -0,0 +1,58 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2012 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 "pdfobj.h" + +#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)))) + +typedef struct Type0Font Type0Font; + +extern void Type0Font_set_verbose (void); + +extern int Type0Font_get_wmode (Type0Font *font); +#if 0 +extern char *Type0Font_get_encoding (Type0Font *font); +#endif /* 0 */ +extern char *Type0Font_get_usedchars (Type0Font *font); + +extern pdf_obj *Type0Font_get_resource (Type0Font *font); + +extern void Type0Font_set_ToUnicode (Type0Font *font, pdf_obj *cmap_ref); + +#include "fontmap.h" +extern int pdf_font_findfont0 (const char *font_name, + int cmap_id, fontmap_opt *fmap_opt); + +extern unsigned short *Type0Font_get_ft_to_gid(int id); + +/******************************** CACHE ********************************/ + +extern void Type0Font_cache_init (void); +extern Type0Font *Type0Font_cache_get (int id); +extern int Type0Font_cache_find (const char *map_name, int cmap_id, fontmap_opt *fmap_opt); +extern void Type0Font_cache_close (void); + +#endif /* _TYPE0_H_ */ diff --git a/Build/source/texk/dvipdf-x/xsrc/type1.c b/Build/source/texk/dvipdf-x/xsrc/type1.c new file mode 100644 index 00000000000..f72b5b9d21a --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/type1.c @@ -0,0 +1,805 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "system.h" +#include "mem.h" +#include "error.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" + +#include "tfm.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) +{ + char *ident; + FILE *fp; + char fontname[PDF_NAME_LEN_MAX+1]; + + ASSERT(font); + + ident = pdf_font_get_ident(font); + + if (is_basefont(ident)) { + pdf_font_set_fontname(font, ident); + pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1); + pdf_font_set_flags (font, + (PDF_FONT_FLAG_NOEMBED|PDF_FONT_FLAG_BASEFONT)); + } else { + fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT); + if (!fp) + return -1; + + 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); + + pdf_font_set_fontname(font, fontname); + pdf_font_set_subtype (font, 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; + long 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 = pdf_font_get_fontname (font); + 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, long num_glyphs) +{ + pdf_obj *fontdict, *descriptor; + pdf_obj *tmp_array; + int code, firstchar, lastchar; + double val; + int i, tfm_id; + char *usedchars; + double scaling; + + fontdict = pdf_font_get_resource (font); + descriptor = pdf_font_get_descriptor(font); + usedchars = pdf_font_get_usedchars (font); + + /* + * 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; + + tmp_array = pdf_new_array(); + for (i = 0; i < 4; i++) { + val = cff_dict_get(cffont->topdict, "FontBBox", i); + pdf_add_array(tmp_array, pdf_new_number(ROUND(val, 1.0))); + } + pdf_add_dict(descriptor, pdf_new_name("FontBBox"), tmp_array); + + tmp_array = pdf_new_array(); + if (num_glyphs <= 1) { /* This must be an error. */ + firstchar = lastchar = 0; + pdf_add_array(tmp_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; + } + } + if (firstchar > lastchar) { + WARN("No glyphs actually used???"); + pdf_release_obj(tmp_array); + return; + } + tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + for (code = firstchar; code <= lastchar; code++) { + if (usedchars[code]) { + double width; + if (tfm_id < 0) /* tfm is not found */ + width = scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])]; + else + width = 1000. * tfm_get_width(tfm_id, code); + pdf_add_array(tmp_array, + pdf_new_number(ROUND(width, 0.1))); + } else { + pdf_add_array(tmp_array, pdf_new_number(0.0)); + } + } + } + + if (pdf_array_length(tmp_array) > 0) { + pdf_add_dict(fontdict, + pdf_new_name("Widths"), pdf_ref_obj(tmp_array)); + } + pdf_release_obj(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; +} + + +static long +write_fontfile (pdf_font *font, cff_font *cffont, long num_glyphs) +{ + pdf_obj *descriptor; + pdf_obj *fontfile, *stream_dict; + cff_index *topdict; + long private_size, stream_data_len, charstring_len; + long 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); + if (private_size > 0 && !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); + + RELEASE(stream_data_ptr); + + return offset; +} + + +int +pdf_font_load_type1 (pdf_font *font) +{ + pdf_obj *fontdict; + 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; + long offset; + int code, verbose; + + ASSERT(font); + + if (!pdf_font_is_in_use(font)) { + return 0; + } + + verbose = pdf_font_get_verbose(); + + encoding_id = pdf_font_get_encoding (font); + fontdict = pdf_font_get_resource (font); + + pdf_font_get_descriptor(font); + usedchars = pdf_font_get_usedchars (font); + ident = pdf_font_get_ident (font); + fontname = pdf_font_get_fontname (font); + uniqueTag = pdf_font_get_uniqueTag (font); + if (!usedchars || !ident || !fontname) { + ERROR("Type1: Unexpected error."); + } + + 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); + { + int prev, duplicate; + long 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 (verbose > 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 (verbose > 2) { + MESG("/%s", glyph); + } + + } + } + 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; + long 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) { + long 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 (verbose > 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; + } + + for (i = 0; i < num_glyphs; i++) { + if (GIDMap[i] == bchar_gid) + break; + } + if (i == num_glyphs) { + if (verbose > 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; + } + } + 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 (verbose > 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); + + offset = write_fontfile(font, cffont, num_glyphs); + if (verbose > 1) + MESG("[%u glyphs][%ld bytes]", num_glyphs, offset); + + 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); + + /* + * Maybe writing Charset is recommended for subsetted font. + */ + + return 0; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/type1c.c b/Build/source/texk/dvipdf-x/xsrc/type1c.c new file mode 100644 index 00000000000..64c67ecb4d3 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/type1c.c @@ -0,0 +1,750 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "system.h" +#include "mem.h" +#include "error.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" + +#include "tfm.h" + +int +pdf_font_open_type1c (pdf_font *font) +{ + char *fontname; + FILE *fp = NULL; + sfnt *sfont; + cff_font *cffont; + pdf_obj *descriptor, *tmp; + unsigned long offset = 0; + int encoding_id, embedding; + + ASSERT(font); + + pdf_font_get_ident (font); + encoding_id = pdf_font_get_encoding(font); + +#ifdef XETEX + sfont = sfnt_open(pdf_font_get_ft_face(font), SFNT_TYPE_POSTSCRIPT); + if (!sfont) + return -1; +#else + fp = DPXFOPEN(ident, DPX_RES_TYPE_OTFONT); + if (!fp) + return -1; + + sfont = sfnt_open(fp); +#endif + if (!sfont || + sfont->type != SFNT_TYPE_POSTSCRIPT || + sfnt_read_table_directory(sfont, 0) < 0) { + ERROR("Not a CFF/OpenType font?"); + } + + offset = sfnt_find_table_pos(sfont, "CFF "); + if (offset < 1) { + ERROR("No \"CFF \" table found. Not a CFF/OpenType font?"); + } + + cffont = cff_open(sfont, offset, 0); + if (!cffont) { + ERROR("Could not read CFF font data"); + } + + if (cffont->flag & FONTTYPE_CIDFONT) { + cff_close (cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; + } + + fontname = cff_get_name(cffont); + if (!fontname) { + ERROR("No valid FontName found in CFF/OpenType font."); + } + pdf_font_set_fontname(font, fontname); + RELEASE(fontname); + + cff_close(cffont); + + /* + * 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."); + } + pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1C); + + embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; + 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 */ + pdf_font_set_flags(font, PDF_FONT_FLAG_NOEMBED); + } + + 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, tfm_id; + char *usedchars; + pdf_obj *tmp_array; + double scaling; + + fontdict = pdf_font_get_resource(font); + usedchars = pdf_font_get_usedchars(font); + + /* 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; + + tmp_array = pdf_new_array(); + if (num_glyphs <= 1) { + /* This should be error. */ + firstchar = lastchar = 0; + pdf_add_array(tmp_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; + } + } + if (firstchar > lastchar) { + ERROR("No glyphs used at all!"); + pdf_release_obj(tmp_array); + return; + } + tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + for (code = firstchar; code <= lastchar; code++) { + if (usedchars[code]) { + double width; + if (tfm_id < 0) /* tfm is not found */ + width = scaling * widths[code]; + else + width = 1000. * tfm_get_width(tfm_id, code); + pdf_add_array(tmp_array, + pdf_new_number(ROUND(width, 0.1))); + } else { + pdf_add_array(tmp_array, pdf_new_number(0.0)); + } + } + } + + if (pdf_array_length(tmp_array) > 0) { + pdf_add_dict(fontdict, + pdf_new_name("Widths"), pdf_ref_obj(tmp_array)); + } + pdf_release_obj(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; +} + +int +pdf_font_load_type1c (pdf_font *font) +{ + pdf_obj *fontdict, *descriptor; + 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; + long topdict_offset, private_size; + long charstring_len, max_len; + long size, offset = 0; + long 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]; + int verbose; + + ASSERT(font); + + verbose = pdf_font_get_verbose(); + + if (!pdf_font_is_in_use(font)) { + return 0; + } + + if (pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) { + ERROR("Only embedded font supported for CFF/OpenType font."); + } + + usedchars = pdf_font_get_usedchars (font); + fontname = pdf_font_get_fontname (font); + ident = pdf_font_get_ident (font); + uniqueTag = pdf_font_get_uniqueTag (font); + if (!usedchars || + !fontname || !ident) { + ERROR("Unexpected error...."); + } + + fontdict = pdf_font_get_resource (font); + descriptor = pdf_font_get_descriptor(font); + encoding_id = pdf_font_get_encoding (font); + +#ifdef XETEX + sfont = sfnt_open(pdf_font_get_ft_face(font), SFNT_TYPE_POSTSCRIPT); +#else + fp = DPXFOPEN(ident, DPX_RES_TYPE_OTFONT); + if (!fp) { + ERROR("Could not open OpenType font: %s", ident); + } + + sfont = sfnt_open(fp); +#endif + 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 ?"); + } + + cffont = cff_open(sfont, 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 = (long) 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 = cffont->sfont->loc; + 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 (verbose > 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; + sfnt_seek_set(cffont->sfont, offset + cs_idx->offset[0] - 1); + sfnt_read(data, size, cffont->sfont); + 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; + 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; + } + if (verbose > 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; + sfnt_seek_set(cffont->sfont, offset + cs_idx->offset[gid] - 1); + sfnt_read(data, size, cffont->sfont); + 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 (verbose > 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 (verbose > 1) { + MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, offset); + } + + /* + * CharSet might be recommended for subsetted font, but it is meaningful + * only for Type 1 font... + */ + + /* + * 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/dvipdf-x/xsrc/vf.c b/Build/source/texk/dvipdf-x/xsrc/vf.c new file mode 100644 index 00000000000..fea4f2739df --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/vf.c @@ -0,0 +1,1042 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + 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. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "numbers.h" +#include "error.h" +#include "mem.h" + +#include "dpxfile.h" +/* pdfdev... */ +#include "pdfdev.h" + +#include "tfm.h" +#include "dvi.h" +#include "vf.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))) + +static unsigned char verbose = 0; + +void vf_set_verbose(void) +{ + if (verbose < 255) verbose++; +} + +struct font_def { + signed long font_id /* id used internally in vf file */; + unsigned long 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; + unsigned long design_size; /* A fixword-pts quantity */ + int num_dev_fonts, max_dev_fonts; + struct font_def *dev_fonts; + unsigned char **ch_pkt; + unsigned long *pkt_len; + unsigned num_chars; +}; + +struct vf *vf_fonts = NULL; +int num_vf_fonts = 0, max_vf_fonts = 0; + +static int read_header(FILE *vf_file, int thisfont) +{ + int i, result = 1, ch; + + /* Check for usual signature */ + if ((ch = get_unsigned_byte (vf_file)) == PRE && + (ch = get_unsigned_byte (vf_file)) == VF_ID) { + + /* If here, assume it's a legitimate vf file */ + ch = get_unsigned_byte (vf_file); + + /* skip comment */ + for (i=0; i max_vf_fonts) { + vf_fonts = RENEW (vf_fonts, size, struct vf); + for (i=max_vf_fonts; i (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, unsigned long); + for (i=a_vf->num_chars; ich_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, unsigned long pkt_len, + unsigned ch) +{ + unsigned char *pkt; +#ifdef DEBUG + fprintf (stderr, "read_a_char_def: len=%ld, ch=%d\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, signed long font_id, int thisfont) +{ + struct font_def *dev_font; + int dir_length, name_length; +#ifdef DEBUG + fprintf (stderr, "read_a_font_def: font_id = %ld\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_unsigned_quad (vf_file); + dev_font -> design_size = get_unsigned_quad (vf_file); + 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; + unsigned long font_id; + while (!eof) { + code = get_unsigned_byte (vf_file); + switch (code) { + case FNT_DEF1: + font_id = get_unsigned_byte (vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + case FNT_DEF2: + font_id = get_unsigned_pair (vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + case FNT_DEF3: + font_id = get_unsigned_triple(vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + case FNT_DEF4: + font_id = get_signed_quad(vf_file); + read_a_font_def (vf_file, font_id, thisfont); + break; + default: + if (code < 242) { + long ch; + /* For a short packet, code is the pkt_len */ + ch = get_unsigned_byte (vf_file); + /* Skip over TFM width since we already know it */ + get_unsigned_triple (vf_file); + read_a_char_def (vf_file, thisfont, code, ch); + break; + } + if (code == 242) { + unsigned long pkt_len, ch; + pkt_len = get_unsigned_quad(vf_file); + ch = get_unsigned_quad (vf_file); + /* Skip over TFM width since we already know it */ + get_unsigned_quad (vf_file); + if (ch < 65536L) + read_a_char_def (vf_file, thisfont, pkt_len, ch); + else { + fprintf (stderr, "char=%ld\n", ch); + ERROR ("Long character (>16 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 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 (verbose) + fprintf (stderr, ")"); + MFCLOSE (vf_file); + } + if (full_vf_file_name) + RELEASE(full_vf_file_name); + } + return thisfont; +} + +#define next_byte() (*((*start)++)) +static UNSIGNED_BYTE unsigned_byte (unsigned char **start, unsigned char *end) +{ + UNSIGNED_BYTE byte = 0; + if (*start < end) + byte = next_byte(); + else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return byte; +} + +static SIGNED_BYTE signed_byte (unsigned char **start, unsigned char *end) +{ + int byte = 0; + if (*start < end) { + byte = next_byte(); + if (byte >= 0x80) + byte -= 0x100; + } + else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_BYTE) byte; +} + +static UNSIGNED_PAIR unsigned_pair (unsigned char **start, unsigned char *end) +{ + int i; + UNSIGNED_BYTE byte; + UNSIGNED_PAIR pair = 0; + if (end-*start > 1) { + for (i=0; i<2; i++) { + byte = next_byte(); + pair = pair*0x100u + byte; + } + } + else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return pair; +} + +static SIGNED_PAIR signed_pair (unsigned char **start, unsigned char *end) +{ + int i; + long pair = 0; + if (end - *start > 1) { + for (i=0; i<2; i++) { + pair = pair*0x100 + next_byte(); + } + if (pair >= 0x8000) { + pair -= 0x10000l; + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_PAIR) pair; +} + +static UNSIGNED_TRIPLE unsigned_triple(unsigned char **start, unsigned + char *end) +{ + int i; + long triple = 0; + if (end-*start > 2) { + for (i=0; i<3; i++) { + triple = triple*0x100u + next_byte(); + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (UNSIGNED_TRIPLE) triple; +} + +static SIGNED_TRIPLE signed_triple(unsigned char **start, unsigned char *end) +{ + int i; + long triple = 0; + if (end-*start > 2) { + for (i=0; i<3; i++) { + triple = triple*0x100 + next_byte(); + } + if (triple >= 0x800000l) + triple -= 0x1000000l; + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_TRIPLE) triple; +} + +static SIGNED_QUAD signed_quad(unsigned char **start, unsigned char *end) +{ + int byte, i; + long quad = 0; + /* Check sign on first byte before reading others */ + if (end-*start > 3) { + byte = next_byte(); + quad = byte; + if (quad >= 0x80) + quad = byte - 0x100; + for (i=0; i<3; i++) { + quad = quad*0x100 + next_byte(); + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (SIGNED_QUAD) quad; +} + +static UNSIGNED_QUAD unsigned_quad(unsigned char **start, unsigned char *end) +{ + int i; + unsigned long quad = 0; + if (end-*start > 3) { + for (i=0; i<4; i++) { + quad = quad*0x100u + next_byte(); + } + } else + ERROR ("Premature end of DVI byte stream in VF font\n"); + return (UNSIGNED_QUAD) quad; +} + +static void vf_set (SIGNED_QUAD ch) +{ + /* Defer to the dvi_set() defined in dvi.c */ + dvi_set (ch); + return; +} + +static void vf_set1(unsigned char **start, unsigned char *end) +{ + vf_set (unsigned_byte(start, end)); + return; +} + +static void vf_set2(unsigned char **start, unsigned char *end) +{ + vf_set (unsigned_pair(start, end)); + return; +} + +static void vf_putrule(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + SIGNED_QUAD width, height; + height = signed_quad (start, end); + width = signed_quad (start, end); + if (width > 0 && height > 0) { + dvi_rule (sqxfw(ptsize,width), sqxfw(ptsize, height)); + } + return; +} + +static void vf_setrule(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + SIGNED_QUAD width, height, s_width; + height = signed_quad (start, end); + width = signed_quad (start, end); + s_width = sqxfw(ptsize, width); + if (width > 0 && height > 0) { + dvi_rule (s_width, sqxfw(ptsize, height)); + } + dvi_right (s_width); + return; +} + +static void vf_put1(unsigned char **start, unsigned char *end) +{ + dvi_put (unsigned_byte(start, end)); + return; +} + +static void vf_put2(unsigned char **start, unsigned char *end) +{ + dvi_put (unsigned_pair(start, end)); + return; +} + +static void vf_push(void) +{ + dvi_push(); + return; +} + +static void vf_pop(void) +{ + dvi_pop(); + return; +} + +static void vf_right (SIGNED_QUAD x, spt_t ptsize) +{ + dvi_right ((SIGNED_QUAD) (sqxfw(ptsize, x))); + return; +} + + +static void vf_right1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_byte (start, end), ptsize); + return; +} + +static void vf_right2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_pair (start, end), ptsize); + return; +} + +static void vf_right3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_triple (start, end), ptsize); + return; +} + +static void vf_right4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_right (signed_quad (start, end), ptsize); + return; +} + +static void vf_w0(void) +{ + dvi_w0(); + return; +} + +static void vf_w (SIGNED_QUAD w, spt_t ptsize) +{ + dvi_w ((SIGNED_QUAD) (sqxfw(ptsize, w))); + return; +} + +static void vf_w1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_byte(start, end), ptsize); + return; +} + +static void vf_w2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_pair(start, end), ptsize); + return; +} + +static void vf_w3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_triple(start, end), ptsize); + return; +} + +static void vf_w4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_w (signed_quad(start, end), ptsize); + return; +} + +static void vf_x0(void) +{ + dvi_x0(); + return; +} + +static void vf_x (SIGNED_QUAD x, spt_t ptsize) +{ + dvi_x ((SIGNED_QUAD) (sqxfw(ptsize, x))); + return; +} + +static void vf_x1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_byte(start, end), ptsize); + return; +} + +static void vf_x2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_pair(start, end), ptsize); + return; +} + +static void vf_x3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_triple(start, end), ptsize); + return; +} + +static void vf_x4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_x (signed_quad(start, end), ptsize); + return; +} + +static void vf_down (SIGNED_QUAD y, spt_t ptsize) +{ + dvi_down ((SIGNED_QUAD) (sqxfw(ptsize, y))); + return; +} + +static void vf_down1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_byte(start, end), ptsize); + return; +} + +static void vf_down2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_pair(start, end), ptsize); + return; +} + +static void vf_down3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_triple(start, end), ptsize); + return; +} + +static void vf_down4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_down (signed_quad(start, end), ptsize); + return; +} + +static void vf_y0(void) +{ + dvi_y0(); + return; +} + +static void vf_y (SIGNED_QUAD y, spt_t ptsize) +{ + dvi_y ((SIGNED_QUAD) (sqxfw(ptsize, y))); + return; +} + + +static void vf_y1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_byte(start, end), ptsize); + return; +} + +static void vf_y2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_pair(start, end), ptsize); + return; +} + +static void vf_y3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_triple(start, end), ptsize); + return; +} + +static void vf_y4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_y (signed_quad(start, end), ptsize); + return; +} + +static void vf_z0(void) +{ + dvi_z0(); + return; +} + +static void vf_z (SIGNED_QUAD z, spt_t ptsize) +{ + dvi_z ((SIGNED_QUAD) (sqxfw(ptsize, z))); + return; +} + +static void vf_z1(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_byte(start, end), ptsize); + return; +} + +static void vf_z2(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_pair(start, end), ptsize); + return; +} + +static void vf_z3(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_triple(start, end), ptsize); + return; +} + +static void vf_z4(unsigned char **start, unsigned char *end, spt_t ptsize) +{ + vf_z (signed_quad(start, end), ptsize); + return; +} + +static void vf_fnt (SIGNED_QUAD font_id, unsigned long vf_font) +{ + int i; + for (i=0; i 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])) { + fprintf (stderr, "\nchar=0x%lx(%ld)\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: + vf_set1(&start, end); + break; + case SET2: + vf_set2(&start, end); + break; + case SET3: + case SET4: + ERROR ("Multibyte (>16 bits) character in VF packet.\nI can't handle this!"); + break; + case SET_RULE: + vf_setrule(&start, end, ptsize); + break; + case PUT1: + vf_put1(&start, end); + break; + case PUT2: + vf_put2(&start, end); + break; + case PUT3: + case PUT4: + ERROR ("Multibyte (>16 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: + vf_push(); + break; + case POP: + vf_pop(); + break; + case RIGHT1: + vf_right1(&start, end, ptsize); + break; + case RIGHT2: + vf_right2(&start, end, ptsize); + break; + case RIGHT3: + vf_right3(&start, end, ptsize); + break; + case RIGHT4: + vf_right4(&start, end, ptsize); + break; + case W0: + vf_w0(); + break; + case W1: + vf_w1(&start, end, ptsize); + break; + case W2: + vf_w2(&start, end, ptsize); + break; + case W3: + vf_w3(&start, end, ptsize); + break; + case W4: + vf_w4(&start, end, ptsize); + break; + case X0: + vf_x0(); + break; + case X1: + vf_x1(&start, end, ptsize); + break; + case X2: + vf_x2(&start, end, ptsize); + break; + case X3: + vf_x3(&start, end, ptsize); + break; + case X4: + vf_x4(&start, end, ptsize); + break; + case DOWN1: + vf_down1(&start, end, ptsize); + break; + case DOWN2: + vf_down2(&start, end, ptsize); + break; + case DOWN3: + vf_down3(&start, end, ptsize); + break; + case DOWN4: + vf_down4(&start, end, ptsize); + break; + case Y0: + vf_y0(); + break; + case Y1: + vf_y1(&start, end, ptsize); + break; + case Y2: + vf_y2(&start, end, ptsize); + break; + case Y3: + vf_y3(&start, end, ptsize); + break; + case Y4: + vf_y4(&start, end, ptsize); + break; + case Z0: + vf_z0(); + break; + case Z1: + vf_z1(&start, end, ptsize); + break; + case Z2: + vf_z2(&start, end, ptsize); + break; + case Z3: + vf_z3(&start, end, ptsize); + break; + case Z4: + vf_z4(&start, end, ptsize); + break; + case FNT1: + vf_fnt1(&start, end, vf_font); + break; + case FNT2: + vf_fnt2(&start, end, vf_font); + break; + case FNT3: + vf_fnt3(&start, end, vf_font); + break; + case FNT4: + vf_fnt4(&start, end, vf_font); + break; + case XXX1: + vf_xxx1(&start, end); + break; + case XXX2: + vf_xxx2(&start, end); + break; + case XXX3: + vf_xxx3(&start, end); + break; + case XXX4: + vf_xxx4(&start, end); + break; + case PTEXDIR: + vf_dir(&start, end); + break; + default: + if (opcode <= SET_CHAR_127) { + vf_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) +{ + unsigned long i; + int j; + struct font_def *one_font; + for (i=0; i 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; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/xbb.c b/Build/source/texk/dvipdf-x/xsrc/xbb.c new file mode 100644 index 00000000000..f447d3a0170 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/xbb.c @@ -0,0 +1,511 @@ +/* + + This is extractbb, a bounding box extraction program. + + Copyright (C) 2008-2012 by Jin-Hwan Cho + + 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 +*/ +#include +#include +#include +#include "system.h" +#include "mem.h" +#include "error.h" +#include "mfileio.h" +#include "numbers.h" +#include "pdfobj.h" +#include "pdfparse.h" + +#include "config.h" + +#ifdef HAVE_LIBPNG +#include +#endif + +#include "xbb.h" + +#define XBB_PROGRAM "extractbb" +#define XBB_VERSION "Version 0.2" + +static int xbb_output_mode = XBB_OUTPUT; + +static void usage(void) +{ + fprintf (stderr, "%s, version %s, Copyright (C) 2008 by Jin-Hwan Cho\n", + XBB_PROGRAM, XBB_VERSION); + fprintf (stderr, "A bounding box extraction utility from PDF, PNG, and JPG.\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"); + fprintf (stderr, "\nUsage: %s [-v] [-b] [-m|-x] [files]\n", XBB_PROGRAM); + fprintf (stderr, "\t-b\tWrite output file in binary mode\n"); + if(xbb_output_mode == EBB_OUTPUT) { + fprintf (stderr, "\t-m\tOutput .bb file used in DVIPDFM (default)\n"); + fprintf (stderr, "\t-x\tOutput .xbb file used in DVIPDFMx\n"); + } else { + fprintf (stderr, "\t-m\tOutput .bb file used in DVIPDFM\n"); + fprintf (stderr, "\t-x\tOutput .xbb file used in DVIPDFMx (default)\n"); + } + fprintf (stderr, "\t-v\tVerbose\n"); + exit(1); +} + +static char verbose = 0; + +static void do_time(FILE *file) +{ + time_t current_time; + struct tm *bd_time; + + time(¤t_time); + bd_time = localtime(¤t_time); + fprintf(file, "%%%%CreationDate: %s\n", asctime(bd_time)); +} + +const char *extensions[] = { + ".jpeg", ".JPEG", ".jpg", ".JPG", ".pdf", ".PDF", ".png", ".PNG" +}; + +static char *make_xbb_filename(const char *name) +{ + int i; + char *result; + + 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])) { + fprintf(stderr, "Warning: %s: Filename does not end in a recognizeable extension.\n", name); + result = NEW(strlen(name)+3, char); + strcpy(result, name); + } else { /* Remove extension */ + result = NEW(strlen(name)+3-strlen(extensions[i])+1, char); + strncpy(result, name, strlen(name)-strlen(extensions[i])); + result[strlen(name)-strlen(extensions[i])] = 0; + } + strcat(result, (xbb_output_mode == XBB_OUTPUT ? ".xbb" : ".bb")); + return result; +} + +static const char *xbb_file_mode = FOPEN_W_MODE; + +static void write_xbb(char *fname, int bbllx, int bblly, int bburx, int bbury) +{ + char *outname; + FILE *fp; + + outname = make_xbb_filename(fname); + if ((fp = MFOPEN(outname, xbb_file_mode)) == NULL) { + fprintf(stderr, "Unable to open output file: %s\n", outname); + RELEASE(outname); + return; + } + if (verbose) { + fprintf(stderr, "Writing to %s: ", outname); + fprintf(stderr, "Bounding box: %d %d %d %d\n", bbllx, bblly, bburx, bbury); + } + fprintf(fp,"%%%%Title: %s\n", fname); + fprintf(fp,"%%%%Creator: %s %s\n", XBB_PROGRAM, XBB_VERSION); + fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n", bbllx, bblly, bburx, bbury); + do_time(fp); + RELEASE(outname); + MFCLOSE(fp); +} + +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_APP2 = 0xe2, JM_APP14 = 0xee, JM_APP15 = 0xef, + + JM_COM = 0xfe +} JPEG_marker; + +static JPEG_marker JPEG_get_marker (FILE *fp) +{ + int 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; + } + return -1; +} + +static 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; +} + +static int jpeg_get_info (FILE *fp, int *width, int *height) +{ + JPEG_marker marker; + unsigned short length; + int count; + float xdensity = 1.0, ydensity = 1.0; + char app_sig[128]; + + if (!check_for_jpeg(fp)) { + rewind(fp); + return -1; + } + rewind(fp); + count = 0; + while ((marker = JPEG_get_marker(fp)) >= 0) { + if (marker == JM_SOI || (marker >= JM_RST0 && marker <= JM_RST7)) { + count++; continue; + } + 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: + get_unsigned_byte(fp); + if (xbb_output_mode != XBB_OUTPUT) { /* EBB_OUTPUT */ + xdensity = ydensity = 72.0 / 100.0; + } + *height = (int)(get_unsigned_pair(fp) * ydensity + 0.5); + *width = (int)(get_unsigned_pair(fp) * xdensity + 0.5); + return 0; + 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)) { + int units, xden, yden; + get_unsigned_pair(fp); + units = (int)get_unsigned_byte(fp); + xden = (int)get_unsigned_pair(fp); + yden = (int)get_unsigned_pair(fp); + switch (units) { + case 1: /* pixels per inch */ + xdensity = 72.0 / xden; + ydensity = 72.0 / yden; + break; + case 2: /* pixels per centimeter */ + xdensity = 72.0 / 2.54 / xden; + ydensity = 72.0 / 2.54 / yden; + break; + default: + break; + } + length -= 7; + } + } + seek_relative(fp, length); + break; + default: + seek_relative(fp, length); + break; + } + count++; + } + return -1; +} + +static void do_jpeg (FILE *fp, char *filename) +{ + int width, height; + + if (jpeg_get_info(fp, &width, &height) < 0) { + fprintf (stderr, "%s does not look like a JPEG file...\n", filename); + return; + } + write_xbb(filename, 0, 0, width, height); + return; +} + +#ifdef HAVE_LIBPNG +static 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 int png_get_info(FILE *png_file, int *width, int *height) +{ + png_structp png_ptr; + png_infop png_info_ptr; + png_uint_32 xppm, yppm; + + rewind(png_file); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL || (png_info_ptr = png_create_info_struct(png_ptr)) == NULL) { + if (png_ptr) png_destroy_read_struct(&png_ptr, NULL, NULL); + return -1; + } + png_init_io(png_ptr, png_file); + png_read_info(png_ptr, png_info_ptr); + + *width = (int)png_get_image_width(png_ptr, png_info_ptr); + *height = (int)png_get_image_height(png_ptr, png_info_ptr); + + if (xbb_output_mode == XBB_OUTPUT) { + xppm = png_get_x_pixels_per_meter(png_ptr, png_info_ptr); + yppm = png_get_y_pixels_per_meter(png_ptr, png_info_ptr); + if (xppm > 0) + *width = (int)(*width * 72.0 / 0.0254 / xppm + 0.5); + if (yppm > 0) + *height = (int)(*height * 72.0 / 0.0254 / yppm + 0.5); + } else { /* EBB_OUTPUT */ + *width = (int)(*width * 72.0 / 100.0 + 0.5); + *height = (int)(*height * 72.0 / 100.0 + 0.5); + } + return 0; +} + +static void do_png (FILE *fp, char *filename) +{ + int width, height; + + if (png_get_info(fp, &width, &height) < 0) { + fprintf (stderr, "%s does not look like a PNG file...\n", filename); + return; + } + write_xbb(filename, 0, 0, width, height); + return; +} +#endif /* HAVE_LIBPNG */ + +static int rect_equal (pdf_obj *rect1, pdf_obj *rect2) +{ + int i; + if (!rect1 || !rect2) return 0; + for (i = 0; i < 4; i++) { + if (pdf_number_value(pdf_get_array(rect1, i)) != pdf_number_value(pdf_get_array(rect2, i))) return 0; + } + return 1; +} + +static int pdf_get_info (FILE *image_file, char *filename, int *llx, int *lly, int *urx, int *ury) +{ + pdf_obj *page_tree; + pdf_obj *bbox; + pdf_file *pf; + + page_tree = NULL; + { + pdf_obj *trailer, *catalog; + + pf = pdf_open(filename, image_file); + if (!pf) + return -1; + + trailer = pdf_file_get_trailer(pf); + + if (pdf_lookup_dict(trailer, "Encrypt")) { + WARN("This PDF document is encrypted."); + pdf_release_obj(trailer); + pdf_close(pf); + return -1; + } + catalog = pdf_deref_obj(pdf_lookup_dict(trailer, "Root")); + if (!catalog) { + WARN("Catalog isn't where I expect it."); + pdf_close(pf); + return -1; + } + pdf_release_obj(trailer); + page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages")); + pdf_release_obj(catalog); + } + if (!page_tree) { + WARN("Page tree not found."); + pdf_close(pf); + return -1; + } + { + pdf_obj *kids_ref, *kids; + pdf_obj *crop_box; + pdf_obj *tmp; + + tmp = pdf_lookup_dict(page_tree, "MediaBox"); + bbox = tmp ? pdf_deref_obj(tmp) : NULL; + tmp = pdf_lookup_dict(page_tree, "CropBox"); + crop_box = tmp ? pdf_deref_obj(tmp) : NULL; + + while ((kids_ref = pdf_lookup_dict(page_tree, "Kids")) != NULL) { + kids = pdf_deref_obj(kids_ref); + pdf_release_obj(page_tree); + page_tree = pdf_deref_obj(pdf_get_array(kids, 0)); + pdf_release_obj(kids); + + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "MediaBox")))) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "BleedBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "TrimBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "ArtBox")))) { + if (!rect_equal(tmp, bbox)) { + if (bbox) + pdf_release_obj(bbox); + bbox = tmp; + } else + pdf_release_obj(tmp); + } + if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "CropBox")))) { + if (crop_box) + pdf_release_obj(crop_box); + crop_box = tmp; + } + } + if (crop_box) { + pdf_release_obj(bbox); + bbox = crop_box; + } + } + pdf_release_obj(page_tree); + + if (!bbox) { + WARN("No BoundingBox information available."); + pdf_close(pf); + return -1; + } + + *llx = (int)pdf_number_value(pdf_get_array(bbox, 0)); + *lly = (int)pdf_number_value(pdf_get_array(bbox, 1)); + *urx = (int)pdf_number_value(pdf_get_array(bbox, 2)); + *ury = (int)pdf_number_value(pdf_get_array(bbox, 3)); + + pdf_release_obj(bbox); + + pdf_close(pf); + return 0; +} + +static void do_pdf (FILE *fp, char *filename) +{ + int llx, lly, urx, ury; + + if (pdf_get_info(fp, filename, &llx, &lly, &urx, &ury) < 0) { + fprintf (stderr, "%s does not look like a PDF file...\n", filename); + return; + } + write_xbb(filename, llx, lly, urx, ury); + return; +} + +int extractbb (int argc, char *argv[], int mode) +{ + xbb_output_mode = mode; + + pdf_files_init(); + + pdf_set_version(5); + + kpse_set_program_name(argv[0], NULL); + + argc -= 1; argv += 1; + if (argc == 0) + usage(); + + while (argc > 0 && *argv[0] == '-') { + switch (*(argv[0]+1)) { + case 'b': + xbb_file_mode = FOPEN_WBIN_MODE; + argc -= 1; argv += 1; + break; + case 'm': + xbb_output_mode = EBB_OUTPUT; + argc -= 1; argv += 1; + break; + case 'x': + xbb_output_mode = XBB_OUTPUT; + argc -= 1; argv += 1; + break; + case 'v': + verbose = 1; + argc -= 1; argv += 1; + break; + case 'h': + usage(); + argc -= 1; argv += 1; + break; + default: + usage(); + } + } + for (; argc > 0; argc--, argv++) { + FILE *infile = NULL; + char *kpse_file_name; + if (!(kpse_file_name = kpse_find_pict(argv[0])) || + (infile = MFOPEN(kpse_file_name, FOPEN_RBIN_MODE)) == NULL) { + fprintf(stderr, "Can't find file (%s)...skipping\n", argv[0]); + goto cont; + } + if (check_for_jpeg(infile)) { + do_jpeg(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 */ + fprintf(stderr, "Can't handle file type for file named %s\n", argv[0]); + cont: + if (kpse_file_name) + RELEASE(kpse_file_name); + if (infile) + MFCLOSE(infile); + } + + pdf_files_close(); + + return 0; +} diff --git a/Build/source/texk/dvipdf-x/xsrc/xbb.h b/Build/source/texk/dvipdf-x/xsrc/xbb.h new file mode 100644 index 00000000000..5c8e25c1fd8 --- /dev/null +++ b/Build/source/texk/dvipdf-x/xsrc/xbb.h @@ -0,0 +1,31 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2008-2012 by Jin-Hwan Cho, Matthias Franz, 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 _XBB_H_ +#define _XBB_H_ + +#define EBB_OUTPUT 0 +#define XBB_OUTPUT 1 + +extern int extractbb(int argc, char *argv[], int mode); + +#endif /* _XBB_H_ */ diff --git a/Build/source/texk/dvipdfm-x/ac/dvipdfm-x.ac b/Build/source/texk/dvipdfm-x/ac/dvipdfm-x.ac index 4d534f48848..f5499b12a85 100644 --- a/Build/source/texk/dvipdfm-x/ac/dvipdfm-x.ac +++ b/Build/source/texk/dvipdfm-x/ac/dvipdfm-x.ac @@ -10,4 +10,4 @@ AS_CASE([enable_]Kpse_Prog, [yes | no], , [enable_]Kpse_Prog[=yes]) ]) -test "x$enable_dvipdfm_x:$enable_xdviodfm" = xyes:yes && need_freetype2=yes +test "x$enable_dvipdfm_x:$enable_xdvipdfmx" = xyes:yes && need_freetype2=yes diff --git a/Build/source/texk/dvipdfm-x/configure b/Build/source/texk/dvipdfm-x/configure index 5cefc649821..6e7090b963b 100755 --- a/Build/source/texk/dvipdfm-x/configure +++ b/Build/source/texk/dvipdfm-x/configure @@ -13200,7 +13200,7 @@ case enable_xdvipdfmx in #( enable_xdvipdfmx=yes ;; esac -test "x$enable_dvipdfm_x:$enable_xdviodfm" = xyes:yes && need_freetype2=yes +test "x$enable_dvipdfm_x:$enable_xdvipdfmx" = xyes:yes && need_freetype2=yes ac_config_headers="$ac_config_headers config.h" diff --git a/Build/source/utils/Makefile.in b/Build/source/utils/Makefile.in index a8d09c645b9..c069d7ca9a6 100644 --- a/Build/source/utils/Makefile.in +++ b/Build/source/utils/Makefile.in @@ -145,6 +145,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../texk/dvi2tty/ac/withenable.ac \ $(top_srcdir)/../texk/dvidvi/ac/withenable.ac \ $(top_srcdir)/../texk/dviljk/ac/withenable.ac \ + $(top_srcdir)/../texk/dvipdf-x/ac/withenable.ac \ + $(top_srcdir)/../texk/dvipdf-x/ac/dvipdf-x.ac \ $(top_srcdir)/../texk/dvipdfm-x/ac/withenable.ac \ $(top_srcdir)/../texk/dvipdfm-x/ac/dvipdfm-x.ac \ $(top_srcdir)/../texk/dvipng/ac/withenable.ac \ diff --git a/Build/source/utils/configure b/Build/source/utils/configure index 28bd2e567e3..3d1e052fd74 100755 --- a/Build/source/utils/configure +++ b/Build/source/utils/configure @@ -761,6 +761,9 @@ enable_dtl enable_dvi2tty enable_dvidvi enable_dviljk +enable_dvipdf_x +enable_dvipdf +enable_xdvipdf enable_dvipdfm_x enable_dvipdfmx enable_xdvipdfmx @@ -1553,6 +1556,9 @@ Optional Features: --disable-dvi2tty do not build the dvi2tty package --disable-dvidvi do not build the dvidvi package --disable-dviljk do not build the dviljk package + --enable-dvipdf-x build the dvipdf-x package + --disable-dvipdf do not build the dvipdf program + --disable-xdvipdf do not build the xdvipdf program --disable-dvipdfm-x do not build the dvipdfm-x package --disable-dvipdfmx do not build the dvipdfmx program --disable-xdvipdfmx do not build the xdvipdfmx program @@ -4168,6 +4174,56 @@ test "x$enable_dviljk" = xno || { } +## texk/dvipdf-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdf-x/ +## configure options and TL libraries required for dvipdf-x +# Check whether --enable-dvipdf-x was given. +if test "${enable_dvipdf_x+set}" = set; then : + enableval=$enable_dvipdf_x; +fi +case $enable_dvipdf_x in #( + yes|no) : + ;; #( + *) : + + enable_dvipdf_x=no + { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&5 +$as_echo "$as_me: Assuming \`--enable-dvipdf-x=$enable_dvipdf_x'" >&6;} + ac_configure_args="$ac_configure_args '--enable-dvipdf-x=$enable_dvipdf_x'" + ;; +esac + +test "x$enable_dvipdf_x" = xno || { + need_kpathsea=yes + need_libpng=yes +} + +## Define configure options for dvipdf-x. +# Check whether --enable-dvipdf was given. +if test "${enable_dvipdf+set}" = set; then : + enableval=$enable_dvipdf; +fi + +case enable_dvipdf in #( + yes | no) : + ;; #( + *) : + enable_dvipdf=yes ;; +esac +# Check whether --enable-xdvipdf was given. +if test "${enable_xdvipdf+set}" = set; then : + enableval=$enable_xdvipdf; +fi + +case enable_xdvipdf in #( + yes | no) : + ;; #( + *) : + enable_xdvipdf=yes ;; +esac + +test "x$enable_dvipdf_x:$enable_xdvipdf" = xyes:yes && need_freetype2=yes + + ## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/ ## configure options and TL libraries required for dvipdfm-x # Check whether --enable-dvipdfm-x was given. @@ -4215,7 +4271,7 @@ case enable_xdvipdfmx in #( enable_xdvipdfmx=yes ;; esac -test "x$enable_dvipdfm_x:$enable_xdviodfm" = xyes:yes && need_freetype2=yes +test "x$enable_dvipdfm_x:$enable_xdvipdfmx" = xyes:yes && need_freetype2=yes ## texk/dvipng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/ -- cgit v1.2.3