From 7b52cc13af4e85f1ca2deb6b6c77de9c95ea0dcf Mon Sep 17 00:00:00 2001 From: scuri Date: Fri, 17 Oct 2008 06:10:33 +0000 Subject: First commit - moving from LuaForge to SourceForge --- src/pdflib/flate/adler32.c | 144 + src/pdflib/flate/compress.c | 79 + src/pdflib/flate/crc32.c | 424 ++ src/pdflib/flate/crc32.h | 441 ++ src/pdflib/flate/deflate.c | 1740 +++++ src/pdflib/flate/deflate.h | 334 + src/pdflib/flate/inffast.c | 319 + src/pdflib/flate/inffast.h | 11 + src/pdflib/flate/inffixed.h | 94 + src/pdflib/flate/inflate.c | 1369 ++++ src/pdflib/flate/inflate.h | 115 + src/pdflib/flate/inftrees.c | 330 + src/pdflib/flate/inftrees.h | 55 + src/pdflib/flate/trees.c | 1220 ++++ src/pdflib/flate/trees.h | 131 + src/pdflib/flate/uncompr.c | 62 + src/pdflib/flate/zconf.h | 280 + src/pdflib/flate/zlib.h | 1360 ++++ src/pdflib/flate/zprefix.h | 134 + src/pdflib/flate/zutil.c | 319 + src/pdflib/flate/zutil.h | 276 + src/pdflib/font/ft_cid.c | 295 + src/pdflib/font/ft_cid.h | 63 + src/pdflib/font/ft_corefont.c | 411 ++ src/pdflib/font/ft_corefont.h | 2642 ++++++++ src/pdflib/font/ft_font.c | 532 ++ src/pdflib/font/ft_font.h | 267 + src/pdflib/font/ft_generr.h | 109 + src/pdflib/font/ft_hostfont.c | 24 + src/pdflib/font/ft_pdffont.c | 18 + src/pdflib/font/ft_pdffont.h | 26 + src/pdflib/font/ft_truetype.c | 2310 +++++++ src/pdflib/font/ft_truetype.h | 558 ++ src/pdflib/font/ft_type1.c | 39 + src/pdflib/pdcore/pc_aes.c | 32 + src/pdflib/pdcore/pc_aes.h | 53 + src/pdflib/pdcore/pc_aescbc.c | 53 + src/pdflib/pdcore/pc_aeslocal.h | 53 + src/pdflib/pdcore/pc_arc4.c | 61 + src/pdflib/pdcore/pc_arc4.h | 60 + src/pdflib/pdcore/pc_chartabs.c | 613 ++ src/pdflib/pdcore/pc_chartabs.h | 13851 ++++++++++++++++++++++++++++++++++++++ src/pdflib/pdcore/pc_classic.h | 24 + src/pdflib/pdcore/pc_config.h | 388 ++ src/pdflib/pdcore/pc_contain.c | 518 ++ src/pdflib/pdcore/pc_contain.h | 110 + src/pdflib/pdcore/pc_core.c | 1190 ++++ src/pdflib/pdcore/pc_core.h | 270 + src/pdflib/pdcore/pc_crypt.c | 27 + src/pdflib/pdcore/pc_crypt.h | 27 + src/pdflib/pdcore/pc_ctype.c | 309 + src/pdflib/pdcore/pc_ctype.h | 77 + src/pdflib/pdcore/pc_digsig.c | 20 + src/pdflib/pdcore/pc_digsig.h | 17 + src/pdflib/pdcore/pc_ebcdic.c | 27 + src/pdflib/pdcore/pc_ebcdic.h | 35 + src/pdflib/pdcore/pc_encoding.c | 2549 +++++++ src/pdflib/pdcore/pc_encoding.h | 295 + src/pdflib/pdcore/pc_exports.h | 24 + src/pdflib/pdcore/pc_file.c | 1548 +++++ src/pdflib/pdcore/pc_file.h | 150 + src/pdflib/pdcore/pc_generr.h | 444 ++ src/pdflib/pdcore/pc_geom.c | 681 ++ src/pdflib/pdcore/pc_geom.h | 116 + src/pdflib/pdcore/pc_md5.c | 307 + src/pdflib/pdcore/pc_md5.h | 59 + src/pdflib/pdcore/pc_optparse.c | 1383 ++++ src/pdflib/pdcore/pc_optparse.h | 292 + src/pdflib/pdcore/pc_output.c | 1126 ++++ src/pdflib/pdcore/pc_output.h | 203 + src/pdflib/pdcore/pc_prefix.h | 17 + src/pdflib/pdcore/pc_pstok.h | 15 + src/pdflib/pdcore/pc_resource.c | 1906 ++++++ src/pdflib/pdcore/pc_resource.h | 124 + src/pdflib/pdcore/pc_scan.c | 19 + src/pdflib/pdcore/pc_scan.h | 15 + src/pdflib/pdcore/pc_scantok.h | 14 + src/pdflib/pdcore/pc_scope.c | 26 + src/pdflib/pdcore/pc_scope.h | 23 + src/pdflib/pdcore/pc_strconst.h | 5 + src/pdflib/pdcore/pc_string.c | 514 ++ src/pdflib/pdcore/pc_string.h | 267 + src/pdflib/pdcore/pc_unicode.c | 1886 ++++++ src/pdflib/pdcore/pc_unicode.h | 283 + src/pdflib/pdcore/pc_util.c | 2726 ++++++++ src/pdflib/pdcore/pc_util.h | 268 + src/pdflib/pdcore/pc_xmp.c | 31 + src/pdflib/pdcore/pc_xmp.h | 27 + src/pdflib/pdflib/p_3d.c | 22 + src/pdflib/pdflib/p_actions.c | 1155 ++++ src/pdflib/pdflib/p_afm.c | 756 +++ src/pdflib/pdflib/p_annots.c | 2078 ++++++ src/pdflib/pdflib/p_block.c | 26 + src/pdflib/pdflib/p_bmp.c | 795 +++ src/pdflib/pdflib/p_ccitt.c | 186 + src/pdflib/pdflib/p_cid.c | 198 + src/pdflib/pdflib/p_color.c | 1130 ++++ src/pdflib/pdflib/p_color.h | 109 + src/pdflib/pdflib/p_defopt.h | 494 ++ src/pdflib/pdflib/p_document.c | 1939 ++++++ src/pdflib/pdflib/p_draw.c | 410 ++ src/pdflib/pdflib/p_encoding.c | 187 + src/pdflib/pdflib/p_fields.c | 30 + src/pdflib/pdflib/p_filter.c | 120 + src/pdflib/pdflib/p_font.c | 2513 +++++++ src/pdflib/pdflib/p_font.h | 225 + src/pdflib/pdflib/p_generr.h | 705 ++ src/pdflib/pdflib/p_gif.c | 744 ++ src/pdflib/pdflib/p_gstate.c | 451 ++ src/pdflib/pdflib/p_hkscmyk.h | 28 + src/pdflib/pdflib/p_hkslab.h | 26 + src/pdflib/pdflib/p_hyper.c | 1449 ++++ src/pdflib/pdflib/p_icc.c | 32 + src/pdflib/pdflib/p_icc.h | 24 + src/pdflib/pdflib/p_icc9809.h | 38 + src/pdflib/pdflib/p_icclib.c | 62 + src/pdflib/pdflib/p_icclib.h | 38 + src/pdflib/pdflib/p_image.c | 2253 +++++++ src/pdflib/pdflib/p_image.h | 358 + src/pdflib/pdflib/p_intern.h | 1027 +++ src/pdflib/pdflib/p_jpeg.c | 1560 +++++ src/pdflib/pdflib/p_jpx.c | 73 + src/pdflib/pdflib/p_kerning.c | 21 + src/pdflib/pdflib/p_keyconn.h | 827 +++ src/pdflib/pdflib/p_layer.c | 36 + src/pdflib/pdflib/p_layer.h | 24 + src/pdflib/pdflib/p_mbox.c | 943 +++ src/pdflib/pdflib/p_object.c | 257 + src/pdflib/pdflib/p_opi.c | 21 + src/pdflib/pdflib/p_page.c | 2261 +++++++ src/pdflib/pdflib/p_page.h | 34 + src/pdflib/pdflib/p_pantlab.h | 28 + src/pdflib/pdflib/p_params.c | 1306 ++++ src/pdflib/pdflib/p_params.h | 373 + src/pdflib/pdflib/p_pattern.c | 231 + src/pdflib/pdflib/p_pdi.c | 28 + src/pdflib/pdflib/p_pfm.c | 406 ++ src/pdflib/pdflib/p_photoshp.c | 23 + src/pdflib/pdflib/p_png.c | 855 +++ src/pdflib/pdflib/p_shading.c | 381 ++ src/pdflib/pdflib/p_subsett.c | 26 + src/pdflib/pdflib/p_table.c | 26 + src/pdflib/pdflib/p_tagged.c | 53 + src/pdflib/pdflib/p_tagged.h | 25 + src/pdflib/pdflib/p_template.c | 246 + src/pdflib/pdflib/p_text.c | 3715 ++++++++++ src/pdflib/pdflib/p_textflow.c | 27 + src/pdflib/pdflib/p_tiff.c | 1169 ++++ src/pdflib/pdflib/p_truetype.c | 301 + src/pdflib/pdflib/p_type1.c | 427 ++ src/pdflib/pdflib/p_type3.c | 740 ++ src/pdflib/pdflib/p_util.c | 733 ++ src/pdflib/pdflib/p_xgstate.c | 514 ++ src/pdflib/pdflib/p_xmp.c | 25 + src/pdflib/pdflib/pdflib.c | 4052 +++++++++++ src/pdflib/pdflib/pdflib.h | 1572 +++++ 156 files changed, 94636 insertions(+) create mode 100644 src/pdflib/flate/adler32.c create mode 100644 src/pdflib/flate/compress.c create mode 100644 src/pdflib/flate/crc32.c create mode 100644 src/pdflib/flate/crc32.h create mode 100644 src/pdflib/flate/deflate.c create mode 100644 src/pdflib/flate/deflate.h create mode 100644 src/pdflib/flate/inffast.c create mode 100644 src/pdflib/flate/inffast.h create mode 100644 src/pdflib/flate/inffixed.h create mode 100644 src/pdflib/flate/inflate.c create mode 100644 src/pdflib/flate/inflate.h create mode 100644 src/pdflib/flate/inftrees.c create mode 100644 src/pdflib/flate/inftrees.h create mode 100644 src/pdflib/flate/trees.c create mode 100644 src/pdflib/flate/trees.h create mode 100644 src/pdflib/flate/uncompr.c create mode 100644 src/pdflib/flate/zconf.h create mode 100644 src/pdflib/flate/zlib.h create mode 100644 src/pdflib/flate/zprefix.h create mode 100644 src/pdflib/flate/zutil.c create mode 100644 src/pdflib/flate/zutil.h create mode 100644 src/pdflib/font/ft_cid.c create mode 100644 src/pdflib/font/ft_cid.h create mode 100644 src/pdflib/font/ft_corefont.c create mode 100644 src/pdflib/font/ft_corefont.h create mode 100644 src/pdflib/font/ft_font.c create mode 100644 src/pdflib/font/ft_font.h create mode 100644 src/pdflib/font/ft_generr.h create mode 100644 src/pdflib/font/ft_hostfont.c create mode 100644 src/pdflib/font/ft_pdffont.c create mode 100644 src/pdflib/font/ft_pdffont.h create mode 100644 src/pdflib/font/ft_truetype.c create mode 100644 src/pdflib/font/ft_truetype.h create mode 100644 src/pdflib/font/ft_type1.c create mode 100644 src/pdflib/pdcore/pc_aes.c create mode 100644 src/pdflib/pdcore/pc_aes.h create mode 100644 src/pdflib/pdcore/pc_aescbc.c create mode 100644 src/pdflib/pdcore/pc_aeslocal.h create mode 100644 src/pdflib/pdcore/pc_arc4.c create mode 100644 src/pdflib/pdcore/pc_arc4.h create mode 100644 src/pdflib/pdcore/pc_chartabs.c create mode 100644 src/pdflib/pdcore/pc_chartabs.h create mode 100644 src/pdflib/pdcore/pc_classic.h create mode 100644 src/pdflib/pdcore/pc_config.h create mode 100644 src/pdflib/pdcore/pc_contain.c create mode 100644 src/pdflib/pdcore/pc_contain.h create mode 100644 src/pdflib/pdcore/pc_core.c create mode 100644 src/pdflib/pdcore/pc_core.h create mode 100644 src/pdflib/pdcore/pc_crypt.c create mode 100644 src/pdflib/pdcore/pc_crypt.h create mode 100644 src/pdflib/pdcore/pc_ctype.c create mode 100644 src/pdflib/pdcore/pc_ctype.h create mode 100644 src/pdflib/pdcore/pc_digsig.c create mode 100644 src/pdflib/pdcore/pc_digsig.h create mode 100644 src/pdflib/pdcore/pc_ebcdic.c create mode 100644 src/pdflib/pdcore/pc_ebcdic.h create mode 100644 src/pdflib/pdcore/pc_encoding.c create mode 100644 src/pdflib/pdcore/pc_encoding.h create mode 100644 src/pdflib/pdcore/pc_exports.h create mode 100644 src/pdflib/pdcore/pc_file.c create mode 100644 src/pdflib/pdcore/pc_file.h create mode 100644 src/pdflib/pdcore/pc_generr.h create mode 100644 src/pdflib/pdcore/pc_geom.c create mode 100644 src/pdflib/pdcore/pc_geom.h create mode 100644 src/pdflib/pdcore/pc_md5.c create mode 100644 src/pdflib/pdcore/pc_md5.h create mode 100644 src/pdflib/pdcore/pc_optparse.c create mode 100644 src/pdflib/pdcore/pc_optparse.h create mode 100644 src/pdflib/pdcore/pc_output.c create mode 100644 src/pdflib/pdcore/pc_output.h create mode 100644 src/pdflib/pdcore/pc_prefix.h create mode 100644 src/pdflib/pdcore/pc_pstok.h create mode 100644 src/pdflib/pdcore/pc_resource.c create mode 100644 src/pdflib/pdcore/pc_resource.h create mode 100644 src/pdflib/pdcore/pc_scan.c create mode 100644 src/pdflib/pdcore/pc_scan.h create mode 100644 src/pdflib/pdcore/pc_scantok.h create mode 100644 src/pdflib/pdcore/pc_scope.c create mode 100644 src/pdflib/pdcore/pc_scope.h create mode 100644 src/pdflib/pdcore/pc_strconst.h create mode 100644 src/pdflib/pdcore/pc_string.c create mode 100644 src/pdflib/pdcore/pc_string.h create mode 100644 src/pdflib/pdcore/pc_unicode.c create mode 100644 src/pdflib/pdcore/pc_unicode.h create mode 100644 src/pdflib/pdcore/pc_util.c create mode 100644 src/pdflib/pdcore/pc_util.h create mode 100644 src/pdflib/pdcore/pc_xmp.c create mode 100644 src/pdflib/pdcore/pc_xmp.h create mode 100644 src/pdflib/pdflib/p_3d.c create mode 100644 src/pdflib/pdflib/p_actions.c create mode 100644 src/pdflib/pdflib/p_afm.c create mode 100644 src/pdflib/pdflib/p_annots.c create mode 100644 src/pdflib/pdflib/p_block.c create mode 100644 src/pdflib/pdflib/p_bmp.c create mode 100644 src/pdflib/pdflib/p_ccitt.c create mode 100644 src/pdflib/pdflib/p_cid.c create mode 100644 src/pdflib/pdflib/p_color.c create mode 100644 src/pdflib/pdflib/p_color.h create mode 100644 src/pdflib/pdflib/p_defopt.h create mode 100644 src/pdflib/pdflib/p_document.c create mode 100644 src/pdflib/pdflib/p_draw.c create mode 100644 src/pdflib/pdflib/p_encoding.c create mode 100644 src/pdflib/pdflib/p_fields.c create mode 100644 src/pdflib/pdflib/p_filter.c create mode 100644 src/pdflib/pdflib/p_font.c create mode 100644 src/pdflib/pdflib/p_font.h create mode 100644 src/pdflib/pdflib/p_generr.h create mode 100644 src/pdflib/pdflib/p_gif.c create mode 100644 src/pdflib/pdflib/p_gstate.c create mode 100644 src/pdflib/pdflib/p_hkscmyk.h create mode 100644 src/pdflib/pdflib/p_hkslab.h create mode 100644 src/pdflib/pdflib/p_hyper.c create mode 100644 src/pdflib/pdflib/p_icc.c create mode 100644 src/pdflib/pdflib/p_icc.h create mode 100644 src/pdflib/pdflib/p_icc9809.h create mode 100644 src/pdflib/pdflib/p_icclib.c create mode 100644 src/pdflib/pdflib/p_icclib.h create mode 100644 src/pdflib/pdflib/p_image.c create mode 100644 src/pdflib/pdflib/p_image.h create mode 100644 src/pdflib/pdflib/p_intern.h create mode 100644 src/pdflib/pdflib/p_jpeg.c create mode 100644 src/pdflib/pdflib/p_jpx.c create mode 100644 src/pdflib/pdflib/p_kerning.c create mode 100644 src/pdflib/pdflib/p_keyconn.h create mode 100644 src/pdflib/pdflib/p_layer.c create mode 100644 src/pdflib/pdflib/p_layer.h create mode 100644 src/pdflib/pdflib/p_mbox.c create mode 100644 src/pdflib/pdflib/p_object.c create mode 100644 src/pdflib/pdflib/p_opi.c create mode 100644 src/pdflib/pdflib/p_page.c create mode 100644 src/pdflib/pdflib/p_page.h create mode 100644 src/pdflib/pdflib/p_pantlab.h create mode 100644 src/pdflib/pdflib/p_params.c create mode 100644 src/pdflib/pdflib/p_params.h create mode 100644 src/pdflib/pdflib/p_pattern.c create mode 100644 src/pdflib/pdflib/p_pdi.c create mode 100644 src/pdflib/pdflib/p_pfm.c create mode 100644 src/pdflib/pdflib/p_photoshp.c create mode 100644 src/pdflib/pdflib/p_png.c create mode 100644 src/pdflib/pdflib/p_shading.c create mode 100644 src/pdflib/pdflib/p_subsett.c create mode 100644 src/pdflib/pdflib/p_table.c create mode 100644 src/pdflib/pdflib/p_tagged.c create mode 100644 src/pdflib/pdflib/p_tagged.h create mode 100644 src/pdflib/pdflib/p_template.c create mode 100644 src/pdflib/pdflib/p_text.c create mode 100644 src/pdflib/pdflib/p_textflow.c create mode 100644 src/pdflib/pdflib/p_tiff.c create mode 100644 src/pdflib/pdflib/p_truetype.c create mode 100644 src/pdflib/pdflib/p_type1.c create mode 100644 src/pdflib/pdflib/p_type3.c create mode 100644 src/pdflib/pdflib/p_util.c create mode 100644 src/pdflib/pdflib/p_xgstate.c create mode 100644 src/pdflib/pdflib/p_xmp.c create mode 100644 src/pdflib/pdflib/pdflib.c create mode 100644 src/pdflib/pdflib/pdflib.h (limited to 'src/pdflib') diff --git a/src/pdflib/flate/adler32.c b/src/pdflib/flate/adler32.c new file mode 100644 index 0000000..3f309ba --- /dev/null +++ b/src/pdflib/flate/adler32.c @@ -0,0 +1,144 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: adler32.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: adler32.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 > BASE) sum1 -= BASE; + if (sum1 > BASE) sum1 -= BASE; + if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 > BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} diff --git a/src/pdflib/flate/compress.c b/src/pdflib/flate/compress.c new file mode 100644 index 0000000..64dd6f3 --- /dev/null +++ b/src/pdflib/flate/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: compress.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: compress.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 ( + Bytef *dest, + uLongf *destLen, + const Bytef *source, + uLong sourceLen, + int level) +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress ( + Bytef *dest, + uLongf *destLen, + const Bytef *source, + uLong sourceLen) +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (uLong sourceLen) +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/src/pdflib/flate/crc32.c b/src/pdflib/flate/crc32.c new file mode 100644 index 0000000..df92f90 --- /dev/null +++ b/src/pdflib/flate/crc32.c @@ -0,0 +1,424 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* $Id: crc32.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: crc32.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table( + FILE *out, + const unsigned long FAR *table) +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32( + unsigned long crc, + const unsigned char FAR *buf, + unsigned len) +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little( + unsigned long crc, + const unsigned char FAR *buf, + unsigned len) +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big( + unsigned long crc, + const unsigned char FAR *buf, + unsigned len) +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times( + unsigned long *mat, + unsigned long vec) +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square( + unsigned long *square, + unsigned long *mat) +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine( + uLong crc1, + uLong crc2, + z_off_t len2) +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case */ + if (len2 == 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} diff --git a/src/pdflib/flate/crc32.h b/src/pdflib/flate/crc32.h new file mode 100644 index 0000000..8053b61 --- /dev/null +++ b/src/pdflib/flate/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/src/pdflib/flate/deflate.c b/src/pdflib/flate/deflate.c new file mode 100644 index 0000000..5454e60 --- /dev/null +++ b/src/pdflib/flate/deflate.c @@ -0,0 +1,1740 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* $Id: deflate.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: deflate.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_( + z_streamp strm, + int level, + const char *version, + int stream_size) +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_( + z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy, + const char *version, + int stream_size) +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + /* we don't use calloc -> to satisfy purify + * at least here memset is needed */ + memset((void *)s->window, 0, (size_t) s->w_size * 2*sizeof(Byte)); + + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary ( + z_streamp strm, + const Bytef *dictionary, + uInt dictLength) +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset ( + z_streamp strm) +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader ( + z_streamp strm, + gz_headerp head) +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime ( + z_streamp strm, + int bits, + int value) +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams( + z_streamp strm, + int level, + int strategy) +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune( + z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain) +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound( + z_streamp strm, + uLong sourceLen) +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB ( + deflate_state *s, + uInt b) +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending( + z_streamp strm) +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate ( + z_streamp strm, + int flush) +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd ( + z_streamp strm) +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy ( + z_streamp dest, + z_streamp source) +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf( + z_streamp strm, + Bytef *buf, + unsigned size) +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init ( + deflate_state *s) +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match( + deflate_state *s, + IPos cur_match) /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast( + deflate_state *s, + IPos cur_match) /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match( + deflate_state *s, + IPos start, IPos match, + int length) +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window( + deflate_state *s) +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored( + deflate_state *s, + int flush) +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast( + deflate_state *s, + int flush) +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow( + deflate_state *s, + int flush) +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/src/pdflib/flate/deflate.h b/src/pdflib/flate/deflate.h new file mode 100644 index 0000000..36e0961 --- /dev/null +++ b/src/pdflib/flate/deflate.h @@ -0,0 +1,334 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + + +/* $Id: deflate.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +/* @(#) $Id: deflate.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/src/pdflib/flate/inffast.c b/src/pdflib/flate/inffast.c new file mode 100644 index 0000000..c3d8a1d --- /dev/null +++ b/src/pdflib/flate/inffast.c @@ -0,0 +1,319 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ +/* $Id: inffast.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast( +z_streamp strm, +unsigned start) /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wwrite; /* window wwrite index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code tthis; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wwrite = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + tthis = lcode[hold & lmask]; + dolen: + op = (unsigned)(tthis.bits); + hold >>= op; + bits -= op; + op = (unsigned)(tthis.op); + if (op == 0) { /* literal */ + Tracevv((stderr, tthis.val >= 0x20 && tthis.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", tthis.val)); + PUP(out) = (unsigned char)(tthis.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(tthis.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + tthis = dcode[hold & dmask]; + dodist: + op = (unsigned)(tthis.bits); + hold >>= op; + bits -= op; + op = (unsigned)(tthis.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(tthis.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (wwrite == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wwrite < op) { /* wrap around window */ + from += wsize + wwrite - op; + op -= wwrite; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wwrite < len) { /* some from start of window */ + op = wwrite; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wwrite - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + tthis = dcode[tthis.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + tthis = lcode[tthis.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/src/pdflib/flate/inffast.h b/src/pdflib/flate/inffast.h new file mode 100644 index 0000000..1e88d2d --- /dev/null +++ b/src/pdflib/flate/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/src/pdflib/flate/inffixed.h b/src/pdflib/flate/inffixed.h new file mode 100644 index 0000000..75ed4b5 --- /dev/null +++ b/src/pdflib/flate/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/src/pdflib/flate/inflate.c b/src/pdflib/flate/inflate.c new file mode 100644 index 0000000..87cd287 --- /dev/null +++ b/src/pdflib/flate/inflate.c @@ -0,0 +1,1369 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ +/* $Id: inflate.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset( +z_streamp strm) +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->write = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflatePrime( +z_streamp strm, +int bits, +int value) +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +int ZEXPORT inflateInit2_( +z_streamp strm, +int windowBits, +const char *version, +int stream_size) +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_( +z_streamp strm, +const char *version, +int stream_size) +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables( +struct inflate_state FAR *state) +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow( +z_streamp strm, +unsigned out) +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate( +z_streamp strm, +int flush) +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code tthis; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + tthis = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(tthis.bits) <= bits) break; + PULLBYTE(); + } + if (tthis.val < 16) { + NEEDBITS(tthis.bits); + DROPBITS(tthis.bits); + state->lens[state->have++] = tthis.val; + } + else { + if (tthis.val == 16) { + NEEDBITS(tthis.bits + 2); + DROPBITS(tthis.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (tthis.val == 17) { + NEEDBITS(tthis.bits + 3); + DROPBITS(tthis.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(tthis.bits + 7); + DROPBITS(tthis.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + tthis = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(tthis.bits) <= bits) break; + PULLBYTE(); + } + if (tthis.op && (tthis.op & 0xf0) == 0) { + last = tthis; + for (;;) { + tthis = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + tthis.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(tthis.bits); + state->length = (unsigned)tthis.val; + if ((int)(tthis.op) == 0) { + Tracevv((stderr, tthis.val >= 0x20 && tthis.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", tthis.val)); + state->mode = LIT; + break; + } + if (tthis.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (tthis.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(tthis.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + tthis = state->distcode[BITS(state->distbits)]; + if ((unsigned)(tthis.bits) <= bits) break; + PULLBYTE(); + } + if ((tthis.op & 0xf0) == 0) { + last = tthis; + for (;;) { + tthis = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + tthis.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(tthis.bits); + if (tthis.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)tthis.val; + state->extra = (unsigned)(tthis.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd( +z_streamp strm) +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary( +z_streamp strm, +const Bytef *dictionary, +uInt dictLength) +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader( +z_streamp strm, +gz_headerp head) +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch( +unsigned FAR *have, +unsigned char FAR *buf, +unsigned len) +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync( +z_streamp strm) +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint( +z_streamp strm) +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy( +z_streamp dest, +z_streamp source) +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} diff --git a/src/pdflib/flate/inflate.h b/src/pdflib/flate/inflate.h new file mode 100644 index 0000000..07bd3e7 --- /dev/null +++ b/src/pdflib/flate/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/src/pdflib/flate/inftrees.c b/src/pdflib/flate/inftrees.c new file mode 100644 index 0000000..0f67881 --- /dev/null +++ b/src/pdflib/flate/inftrees.c @@ -0,0 +1,330 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ +/* $Id: inftrees.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table( +codetype type, +unsigned short FAR *lens, +unsigned codes, +code FAR * FAR *table, +unsigned FAR *bits, +unsigned short FAR *work) +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code tthis; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + tthis.op = (unsigned char)64; /* invalid code marker */ + tthis.bits = (unsigned char)1; + tthis.val = (unsigned short)0; + *(*table)++ = tthis; /* make a table to force an error */ + *(*table)++ = tthis; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + tthis.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + tthis.op = (unsigned char)0; + tthis.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + tthis.op = (unsigned char)(extra[work[sym]]); + tthis.val = base[work[sym]]; + } + else { + tthis.op = (unsigned char)(32 + 64); /* end of block */ + tthis.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = tthis; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + tthis.op = (unsigned char)64; /* invalid code marker */ + tthis.bits = (unsigned char)(len - drop); + tthis.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + tthis.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = tthis; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/src/pdflib/flate/inftrees.h b/src/pdflib/flate/inftrees.h new file mode 100644 index 0000000..b1104c8 --- /dev/null +++ b/src/pdflib/flate/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1444 code structures (852 for length/literals + and 592 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/src/pdflib/flate/trees.c b/src/pdflib/flate/trees.c new file mode 100644 index 0000000..a885cd4 --- /dev/null +++ b/src/pdflib/flate/trees.c @@ -0,0 +1,1220 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* $Id: trees.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: trees.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits( + deflate_state *s, + int value, /* value to send */ + int length) /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init( + deflate_state *s) +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block( + deflate_state *s) +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap( + deflate_state *s, + ct_data *tree, /* the tree to restore */ + int k) /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen( + deflate_state *s, + tree_desc *desc) /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes ( + ct_data *tree, /* the tree to decorate */ + int max_code, /* largest code with non zero frequency */ + ushf *bl_count) /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree ( + deflate_state *s, + ct_data *tree, /* the tree to be scanned */ + int max_code) /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree ( + deflate_state *s, + ct_data *tree, /* the tree to be scanned */ + int max_code) /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree( + deflate_state *s) +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees( + deflate_state *s, + int lcodes, int dcodes, int blcodes) /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block( + deflate_state *s, + charf *buf, /* input block */ + ulg stored_len, /* length of input block */ + int eof) /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align( + deflate_state *s) +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block( + deflate_state *s, + charf *buf, /* input block, or NULL if too old */ + ulg stored_len, /* length of input block */ + int eof) /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) + set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally ( + deflate_state *s, + unsigned dist, /* distance of matched string */ + unsigned lc) /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block( + deflate_state *s, + ct_data *ltree, /* literal tree */ + ct_data *dtree) /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type( + deflate_state *s) +{ + int n; + + for (n = 0; n < 9; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + if (n == 9) + for (n = 14; n < 32; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse( + unsigned code, /* the value to invert */ + int len) /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush( + deflate_state *s) +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup( + deflate_state *s) +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block( + deflate_state *s, + charf *buf, /* the input data */ + unsigned len, /* its length */ + int header) /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/src/pdflib/flate/trees.h b/src/pdflib/flate/trees.h new file mode 100644 index 0000000..3669ef9 --- /dev/null +++ b/src/pdflib/flate/trees.h @@ -0,0 +1,131 @@ +/* header created automatically with -DGEN_TREES_H */ + + +/* $Id: trees.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/src/pdflib/flate/uncompr.c b/src/pdflib/flate/uncompr.c new file mode 100644 index 0000000..e01ad4b --- /dev/null +++ b/src/pdflib/flate/uncompr.c @@ -0,0 +1,62 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: uncompr.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: uncompr.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress ( + Bytef *dest, + uLongf *destLen, + const Bytef *source, + uLong sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/src/pdflib/flate/zconf.h b/src/pdflib/flate/zconf.h new file mode 100644 index 0000000..1e664a8 --- /dev/null +++ b/src/pdflib/flate/zconf.h @@ -0,0 +1,280 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + + +/* $Id: zconf.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: zconf.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +#include "pc_config.h" +#include "zprefix.h" + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* PDFlib GmbH: Windows CE portability */ +#ifdef _WIN32_WCE +#define NO_ERRNO_H +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifndef STDC /* PDFlib GmbH: we require ANSI C anyway */ +#define STDC +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +/* PDFlib GmbH: also do the typedef on the Mac +#if defined(MAC) || defined(MACOSX) +#include +#else +*/ +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif + +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +/* PDFlib GmbH: Windows portability */ +#if !defined(WIN32) && !defined(OS2) && !defined(MAC) +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# define FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ + +/* PDFlib GmbH: This is not true anymore.... +** But it won't hurt anything to do it . +*/ + +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/src/pdflib/flate/zlib.h b/src/pdflib/flate/zlib.h new file mode 100644 index 0000000..977a8bd --- /dev/null +++ b/src/pdflib/flate/zlib.h @@ -0,0 +1,1360 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + + +/* $Id: zlib.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/src/pdflib/flate/zprefix.h b/src/pdflib/flate/zprefix.h new file mode 100644 index 0000000..ddac287 --- /dev/null +++ b/src/pdflib/flate/zprefix.h @@ -0,0 +1,134 @@ +/* $Id: zprefix.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +/* PDFlib GmbH: We use "pdf_z_". +** The original list was incomplete, by the way. +*/ +#ifndef ZPREFIX_H +#define ZPREFIX_H + +#define Z_PREFIX +#ifdef Z_PREFIX + +/* redefine names of all functions for integrating into + * TET/PLOP/PCOS library, to avoid name clashes if used together with + * pdflib */ +#ifdef PDFLIB_TET_BUILD +#define FLATE_PREFIX(x) tet_z_##x +#define _FLATE_PREFIX(x) _tet_z_##x +#else +#ifdef PDFLIB_PLOP_BUILD +#define FLATE_PREFIX(x) plop_z_##x +#define _FLATE_PREFIX(x) _plop_z_##x +#else +#ifdef PDFLIB_PCOS_BUILD +#define FLATE_PREFIX(x) pcos_z_##x +#define _FLATE_PREFIX(x) _pcos_z_##x +#else +#define FLATE_PREFIX(x) pdf_z_##x +#define _FLATE_PREFIX(x) _pdf_z_##x +#endif /* PDFLIB_PCOS_BUILD */ +#endif /* PDFLIB_PLOP_BUILD */ +#endif /* PDFLIB_TET_BUILD */ + +# define longest_match FLATE_PREFIX(longest_match) +# define match_init FLATE_PREFIX(match_init) +# define longest_match_7fff FLATE_PREFIX(longest_match_7fff) +# define cpudetect32 FLATE_PREFIX(cpudetect32) +# define longest_match_686 FLATE_PREFIX(longest_match_686) +# define inflate_fast FLATE_PREFIX(inflate_fast) + +# define _longest_match _FLATE_PREFIX(longest_match) +# define _match_init _FLATE_PREFIX(match_init) +# define _longest_match_7fff _FLATE_PREFIX(longest_match_7fff) +# define _cpudetect32 _FLATE_PREFIX(cpudetect32) +# define _longest_match_686 _FLATE_PREFIX(longest_match_686) +# define _inflate_fast _FLATE_PREFIX(inflate_fast) + + +# define inflate_copyright FLATE_PREFIX(inflate_copyright) +# define inflate_table FLATE_PREFIX(inflate_table) +# define _dist_code FLATE_PREFIX(_dist_code) +# define _length_code FLATE_PREFIX(_length_code) +# define _tr_align FLATE_PREFIX(_tr_align) +# define _tr_flush_block FLATE_PREFIX(_tr_flush_block) +# define _tr_init FLATE_PREFIX(_tr_init) +# define _tr_stored_block FLATE_PREFIX(_tr_stored_block) +# define _tr_tally FLATE_PREFIX(_tr_tally) +# define zcalloc FLATE_PREFIX(zcalloc) +# define zcfree FLATE_PREFIX(zcfree) +# define z_errmsg FLATE_PREFIX(z_errmsg) +# define z_error FLATE_PREFIX(z_error) +# define zlibCompileFlags FLATE_PREFIX(zlibCompileFlags) +# define zlibVersion FLATE_PREFIX(zlibVersion) +# define z_verbose FLATE_PREFIX(z_verbose) +# define inflateGetHeader FLATE_PREFIX(inflateGetHeader) +# define inflatePrime FLATE_PREFIX(inflatePrime) +# define adler32_combine FLATE_PREFIX(adler32_combine) +# define crc32_combine FLATE_PREFIX(crc32_combine) +# define deflate_copyright FLATE_PREFIX(deflate_copyright) +# define deflateSetHeader FLATE_PREFIX(deflateSetHeader) +# define deflateTune FLATE_PREFIX(deflateTune) + +# define deflateInit_ FLATE_PREFIX(deflateInit_) +# define deflate FLATE_PREFIX(deflate) +# define deflateEnd FLATE_PREFIX(deflateEnd) +# define inflateInit_ FLATE_PREFIX(inflateInit_) +# define inflate FLATE_PREFIX(inflate) +# define inflateEnd FLATE_PREFIX(inflateEnd) +# define deflateInit2_ FLATE_PREFIX(deflateInit2_) +# define deflateSetDictionary FLATE_PREFIX(deflateSetDictionary) +# define deflateCopy FLATE_PREFIX(deflateCopy) +# define deflateReset FLATE_PREFIX(deflateReset) +# define deflateParams FLATE_PREFIX(deflateParams) +# define deflateBound FLATE_PREFIX(deflateBound) +# define deflatePrime FLATE_PREFIX(deflatePrime) +# define inflateInit2_ FLATE_PREFIX(inflateInit2_) +# define inflateSetDictionary FLATE_PREFIX(inflateSetDictionary) +# define inflateSync FLATE_PREFIX(inflateSync) +# define inflateSyncPoint FLATE_PREFIX(inflateSyncPoint) +# define inflateCopy FLATE_PREFIX(inflateCopy) +# define inflateReset FLATE_PREFIX(inflateReset) +# define inflateBack FLATE_PREFIX(inflateBack) +# define inflateBackEnd FLATE_PREFIX(inflateBackEnd) +# define compress FLATE_PREFIX(compress) +# define compress2 FLATE_PREFIX(compress2) +# define compressBound FLATE_PREFIX(compressBound) +# define uncompress FLATE_PREFIX(uncompress) +# define adler32 FLATE_PREFIX(adler32) +# define crc32 FLATE_PREFIX(crc32) +# define get_crc_table FLATE_PREFIX(get_crc_table) +# define zError FLATE_PREFIX(zError) + +#if 0 +/* + * PDFlib GmbH: Avoid these redefinitions since they are not required + * for typedefs, and can break functions of the same name in other + * modules. + */ +# define alloc_func FLATE_PREFIX(alloc_func) +# define free_func FLATE_PREFIX(free_func) +# define in_func FLATE_PREFIX(in_func) +# define out_func FLATE_PREFIX(out_func) +#endif + +/* special handling required on the Mac where Byte is alread defined */ +#if !(defined(MAC) || defined(MACOSX)) +# define Byte z_Byte +#endif + +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#endif /* ZPREFIX_H */ diff --git a/src/pdflib/flate/zutil.c b/src/pdflib/flate/zutil.c new file mode 100644 index 0000000..2fa45b3 --- /dev/null +++ b/src/pdflib/flate/zutil.c @@ -0,0 +1,319 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: zutil.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: zutil.c,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error ( + char *m) +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError( + int err) +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy( + Bytef* dest, + const Bytef* source, + uInt len) +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp( + const Bytef* s1, + const Bytef* s2, + uInt len) +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero( + Bytef* dest, + uInt len) +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc ( + voidpf opaque, + unsigned items, + unsigned size) +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree ( + voidpf opaque, + voidpf ptr) +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/src/pdflib/flate/zutil.h b/src/pdflib/flate/zutil.h new file mode 100644 index 0000000..0db04c2 --- /dev/null +++ b/src/pdflib/flate/zutil.h @@ -0,0 +1,276 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + + +/* $Id: zutil.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ +/* @(#) $Id: zutil.h,v 1.1 2008/10/17 06:10:42 scuri Exp $ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MAC) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +#else +# define Assert(cond,msg) +#endif + +/* PDFlib GmbH: we don't like trace messages from here. */ +#if 0 +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/src/pdflib/font/ft_cid.c b/src/pdflib/font/ft_cid.c new file mode 100644 index 0000000..aff9784 --- /dev/null +++ b/src/pdflib/font/ft_cid.c @@ -0,0 +1,295 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_cid.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT CID functions + * + */ + +#define FT_CID_C + +#include + +#include "ft_font.h" +#include "pc_file.h" + +/* ------------------------ Predefined CMaps ------------------------ */ + +/* Predefined CMaps and the corresponding character collection */ +static const fnt_cmap_info fnt_predefined_cmaps[] = +{ + { "83pv-RKSJ-H", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 0}, + { "90ms-RKSJ-H", cc_japanese, 0, PDC_1_3, 2, 2, 2, 2, 0}, + { "90ms-RKSJ-V", cc_japanese, 0, PDC_1_3, 2, 2, 2, 2, 1}, + { "90msp-RKSJ-H", cc_japanese, 0, PDC_1_3, 2, 2, 2, 2, 0}, + { "90msp-RKSJ-V", cc_japanese, 0, PDC_1_3, 2, 2, 2, 2, 1}, + { "90pv-RKSJ-H", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 0}, + { "Add-RKSJ-H", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 0}, + { "Add-RKSJ-V", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 1}, + { "EUC-H", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 0}, + { "EUC-V", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 1}, + { "Ext-RKSJ-H", cc_japanese, 0, PDC_1_3, 2, 2, 2, 2, 0}, + { "Ext-RKSJ-V", cc_japanese, 0, PDC_1_3, 2, 2, 2, 2, 1}, + { "H", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 0}, + { "V", cc_japanese, 0, PDC_1_3, 1, 1, 1, 1, 1}, + { "UniJIS-UCS2-H", cc_japanese, 2, PDC_1_3, 2, 4, 4, 6, 0}, + { "UniJIS-UCS2-V", cc_japanese, 2, PDC_1_3, 2, 4, 4, 6, 1}, + { "UniJIS-UCS2-HW-H", cc_japanese,-2, PDC_1_3, 2, 4, 4, 6, 0}, + { "UniJIS-UCS2-HW-V", cc_japanese -2, PDC_1_3, 2, 4, 4, 6, 1}, + { "UniJIS-UTF16-H", cc_japanese, 2, PDC_1_5, 0, 0, 5, 6, 0}, + { "UniJIS-UTF16-V", cc_japanese, 2, PDC_1_5, 0, 0, 5, 6, 1}, + + { "GB-EUC-H", cc_simplified_chinese, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "GB-EUC-V", cc_simplified_chinese, 0, PDC_1_3, 0, 0, 0, 0, 1}, + { "GBpc-EUC-H", cc_simplified_chinese, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "GBpc-EUC-V", cc_simplified_chinese, 0, PDC_1_3, 0, 0, 0, 0, 1}, + { "GBK-EUC-H", cc_simplified_chinese, 0, PDC_1_3, 2, 2, 2, 2, 0}, + { "GBK-EUC-V", cc_simplified_chinese, 0, PDC_1_3, 2, 2, 2, 2, 1}, + { "GBKp-EUC-H", cc_simplified_chinese, 0, PDC_1_4, 0, 2, 2, 2, 0}, + { "GBKp-EUC-V", cc_simplified_chinese, 0, PDC_1_4, 0, 2, 2, 2, 1}, + { "GBK2K-H", cc_simplified_chinese, 0, PDC_1_4, 0, 4, 4, 4, 0}, + { "GBK2K-V", cc_simplified_chinese, 0, PDC_1_4, 0, 4, 4, 4, 1}, + { "UniGB-UCS2-H", cc_simplified_chinese, 2, PDC_1_3, 2, 4, 4, 4, 0}, + { "UniGB-UCS2-V", cc_simplified_chinese, 2, PDC_1_3, 2, 4, 4, 4, 1}, + { "UniGB-UTF16-H", cc_simplified_chinese, 2, PDC_1_5, 0, 0, 4, 4, 0}, + { "UniGB-UTF16-V", cc_simplified_chinese, 2, PDC_1_5, 0, 0, 4, 4, 1}, + + { "B5pc-H", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "B5pc-V", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 1}, + { "HKscs-B5-H", cc_traditional_chinese, 0, PDC_1_4, 0, 3, 3, 3, 0}, + { "HKscs-B5-V", cc_traditional_chinese, 0, PDC_1_4, 0, 3, 3, 3, 1}, + { "ETen-B5-H", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "ETen-B5-V", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 1}, + { "ETenms-B5-H", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "ETenms-B5-V", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 1}, + { "CNS-EUC-H", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "CNS-EUC-V", cc_traditional_chinese, 0, PDC_1_3, 0, 0, 0, 0, 1}, + { "UniCNS-UCS2-H", cc_traditional_chinese, 2, PDC_1_3, 0, 3, 3, 3, 0}, + { "UniCNS-UCS2-V", cc_traditional_chinese, 2, PDC_1_3, 0, 3, 3, 3, 1}, + { "UniCNS-UTF16-H", cc_traditional_chinese, 2, PDC_1_5, 0, 0, 4, 4, 0}, + { "UniCNS-UTF16-V", cc_traditional_chinese, 2, PDC_1_5, 0, 0, 4, 4, 1}, + + { "KSC-EUC-H", cc_korean, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "KSC-EUC-V", cc_korean, 0, PDC_1_3, 0, 0, 0, 0, 1}, + { "KSCms-UHC-H", cc_korean, 0, PDC_1_3, 1, 1, 1, 1, 0}, + { "KSCms-UHC-V", cc_korean, 0, PDC_1_3, 1, 1, 1, 1, 1}, + { "KSCms-UHC-HW-H", cc_korean, 0, PDC_1_3, 1, 1, 1, 1, 0}, + { "KSCms-UHC-HW-V", cc_korean, 0, PDC_1_3, 1, 1, 1, 1, 1}, + { "KSCpc-EUC-H", cc_korean, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "UniKS-UCS2-H", cc_korean, 2, PDC_1_3, 1, 1, 1, 1, 0}, + { "UniKS-UCS2-V", cc_korean, 2, PDC_1_3, 1, 1, 1, 1, 1}, + { "UniKS-UTF16-H", cc_korean, 2, PDC_1_5, 0, 0, 2, 2, 0}, + { "UniKS-UTF16-V", cc_korean, 2, PDC_1_5, 0, 0, 2, 2, 1}, + + { "Identity-H", cc_identity, 0, PDC_1_3, 0, 0, 0, 0, 0}, + { "Identity-V", cc_identity, 0, PDC_1_3, 0, 0, 0, 0, 1}, + + { NULL, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +static int +fnt_get_predefined_cmap_slot(const char *cmapname) +{ + int slot; + + for (slot = 0; ; slot++) + { + if (fnt_predefined_cmaps[slot].name == NULL) + { + slot = -1; + break; + } + if (!strcmp(fnt_predefined_cmaps[slot].name, cmapname)) + break; + } + + return slot; +} + +int +fnt_get_predefined_cmap_info(const char *cmapname, fnt_cmap_info *cmapinfo) +{ + int slot; + + slot = fnt_get_predefined_cmap_slot(cmapname); + + if (slot == -1) + return cc_none; + + if (cmapinfo) + *cmapinfo = fnt_predefined_cmaps[slot]; + + return fnt_predefined_cmaps[slot].charcoll; +} + +static const pdc_keyconn fnt_charcoll_keylist[] = +{ + { "Japan1", cc_japanese}, + { "GB1", cc_simplified_chinese}, + { "CNS1", cc_traditional_chinese}, + { "Korea1", cc_korean}, + { "Identity", cc_identity}, + { "Unknown", cc_unknown}, + { NULL, 0} +}; + +const char * +fnt_get_ordering_cid(int charcoll) +{ + return pdc_get_keyword(charcoll, fnt_charcoll_keylist); +} + +int +fnt_get_charcoll(const char *ordering) +{ + int charcoll; + + charcoll = (int) pdc_get_keycode(ordering, fnt_charcoll_keylist); + + if (charcoll == PDC_KEY_NOTFOUND) + return cc_unknown; + else + return charcoll; +} + +int +fnt_get_supplement(fnt_cmap_info *cmapinfo, int compatibility) +{ + int retval = 0; + + switch(compatibility) + { + case PDC_1_3: + retval = cmapinfo->supplement13; + break; + + case PDC_1_4: + retval = cmapinfo->supplement14; + break; + + case PDC_1_5: + retval = cmapinfo->supplement15; + break; + + default: + case PDC_1_6: + retval = cmapinfo->supplement16; + break; + } + + return retval; +} + +/* + * See: + * Adobe Technical Note #5078 (Japanese1) + * Adobe Technical Note #5079 (GB1) + * Adobe Technical Note #5080 (CNS1) + * Adobe Technical Note #5093 (Korea1) + * + */ + +int +fnt_get_maxcid(int charcoll, int supplement) +{ + switch(charcoll) + { + case cc_japanese: + switch(supplement) + { + case 0: + return 8283; + + case 1: + return 8358; + + case 2: + return 8719; + + case 3: + return 9353; + + case 4: + return 15443; + + case 5: + return 20316; + + case 6: + default: + return 23057; + } + + case cc_simplified_chinese: + switch(supplement) + { + case 0: + return 7716; + + case 1: + return 9896; + + case 2: + return 22126; + + case 3: + return 22352; + + case 4: + default: + return 29063; + } + + case cc_traditional_chinese: + switch(supplement) + { + case 0: + return 14098; + + case 1: + return 17407; + + case 2: + return 17600; + + case 3: + return 18845; + + case 4: + default: + return 18964; + } + + case cc_korean: + switch(supplement) + { + case 0: + return 9332; + + case 1: + return 18154; + + case 2: + default: + return 18351; + } + + case cc_identity: + case cc_unknown: + return FNT_MAXCID; + + default: + return 0; + } +} + diff --git a/src/pdflib/font/ft_cid.h b/src/pdflib/font/ft_cid.h new file mode 100644 index 0000000..12187cb --- /dev/null +++ b/src/pdflib/font/ft_cid.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_cid.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * CID data structures + * + */ + +#ifndef FT_CID_H +#define FT_CID_H + +typedef struct fnt_cmap_s fnt_cmap; +typedef struct fnt_cmap_info_s fnt_cmap_info; +typedef struct fnt_cmap_stack_s fnt_cmap_stack; + +#define FNT_MAXCID 30000 /* actual maximal CID */ + +#define FNT_CIDMETRIC_INCR 5 /* increment of table fnt_cid_width_arrays */ + +#define FNT_MAX_ILLBYTES 8 /* maximal number of illegal bytes */ + + +/* Predefined CMap info */ +struct fnt_cmap_info_s +{ + const char *name; /* CMap name */ + int charcoll; /* character collection */ + short codesize; /* =0: not UTF-16, =2: UTF-16, -2: HW UTF-16 */ + short compatibility; /* PDF version */ + short supplement13; /* supplement for PDF 1.3 */ + short supplement14; /* supplement for PDF 1.4 */ + short supplement15; /* supplement for PDF 1.5 */ + short supplement16; /* supplement for PDF 1.6 */ + short vertical; /* =1: vertical, =0: horizontal */ +}; + +/* internal CMap types */ +typedef enum +{ + cmap_code2cid, + cmap_cid2unicode, + cmap_code2unicode +} +fnt_cmaptype; + +int fnt_get_predefined_cmap_info(const char *cmapname, fnt_cmap_info *cmapinfo); +const char *fnt_get_ordering_cid(int charcoll); +int fnt_get_maxcid(int charcoll, int supplement); +int fnt_get_charcoll(const char *ordering); +int fnt_get_supplement(fnt_cmap_info *cmapinfo, int compatibility); + + +#endif /* FT_CID_H */ diff --git a/src/pdflib/font/ft_corefont.c b/src/pdflib/font/ft_corefont.c new file mode 100644 index 0000000..b368f67 --- /dev/null +++ b/src/pdflib/font/ft_corefont.c @@ -0,0 +1,411 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_corefont.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT in-core and basic font metric functions + * + */ + +#define FT_COREFONT_C + +#include "ft_font.h" +#include "ft_corefont.h" + + +/* ------------------------------ core fonts ------------------------------ */ + +/* PDF basic font names */ +static const char *fnt_base14_names[] = +{ + "Courier", + "Courier-Bold", + "Courier-Oblique", + "Courier-BoldOblique", + "Helvetica", + "Helvetica-Bold", + "Helvetica-Oblique", + "Helvetica-BoldOblique", + "Symbol", + "Times-Roman", + "Times-Bold", + "Times-Italic", + "Times-BoldItalic", + "ZapfDingbats" +}; + +pdc_bool +fnt_is_standard_font(const char *fontname) +{ + int slot; + + for (slot = 0; + slot < (int)(sizeof(fnt_base14_names) / sizeof(fnt_base14_names[0])); + slot++) + { + if (!strcmp(fnt_base14_names[slot], fontname)) + return pdc_true; + } + + return pdc_false; +} + +/* abbreviations of PDF basic font names for form fields */ +static const char *fnt_abb_base14_names[] = +{ + "Cour", + "CoBo", + "CoOb", + "CoBO", + "Helv", + "HeBo", + "HeOb", + "HeBO", + "Symb", + "TiRo", + "TiBo", + "TiIt", + "TiBI", + "ZaDb" +}; + +const char * +fnt_get_abb_std_fontname(const char *fontname) +{ + int slot; + + for (slot = 0; + slot < (int)(sizeof(fnt_base14_names) / sizeof(fnt_base14_names[0])); + slot++) + { + if (!strcmp(fnt_base14_names[slot], fontname)) + return fnt_abb_base14_names[slot]; + } + + return NULL; +} + + +/* Basic fonts core metrics */ +static const fnt_font_metric *fnt_base_font_metrics[] = +{ + &fnt_font_metric_01, + &fnt_font_metric_02, + &fnt_font_metric_03, + &fnt_font_metric_04, + &fnt_font_metric_05, + &fnt_font_metric_06, + &fnt_font_metric_07, + &fnt_font_metric_08, + &fnt_font_metric_09, + &fnt_font_metric_10, + &fnt_font_metric_11, + &fnt_font_metric_12, + &fnt_font_metric_13, + &fnt_font_metric_14 +}; + +const fnt_font_metric * +fnt_get_core_metric(const char *fontname) +{ +#ifdef PDF_BUILTINMETRIC_SUPPORTED + const fnt_font_metric *metric = NULL; + int slot; + + for (slot = 0; + slot < (int)(sizeof(fnt_base_font_metrics) / + sizeof(fnt_base_font_metrics[0])); + slot++) + { + metric = fnt_base_font_metrics[slot]; + if (!strcmp(metric->name, fontname)) + return metric; + } +#endif /* PDF_BUILTINMETRIC_SUPPORTED */ + return(NULL); +} + + +/* --------------------- Pre-installed CID fonts ---------------------- */ + +int +fnt_get_preinstalled_cidfont(const char *fontname, + const fnt_font_metric **fontmetric) +{ + int slot; + + for (slot = 0; slot < FNT_NUM_OF_CIDFONTS; slot++) + { + if (!strcmp(fnt_cid_metrics[slot].name, fontname)) + { + if (fontmetric) + *fontmetric = &fnt_cid_metrics[slot]; + return fnt_cid_metrics[slot].charcoll; + } + } + + if (fontmetric) + *fontmetric = NULL; + + return (int) cc_none; +} + +/* abbreviations of PDF basic CJK font names for form fields */ +static const char *fnt_abb_cjk_names[] = +{ + "KaGo", + "KaMi", + "HyGo", + "HySm", + "MHei", + "MSun", + "STSo", +}; + +const char * +fnt_get_abb_cjk_fontname(const char *fontname) +{ + int slot; + + for (slot = 0; + slot < (int)(sizeof(fnt_abb_cjk_names) / sizeof(fnt_abb_cjk_names[0])); + slot++) + { + if (!strcmp(fnt_cid_metrics[slot].name, fontname)) + return fnt_abb_cjk_names[slot]; + } + + return NULL; +} + +#ifdef PDF_CJKFONTWIDTHS_SUPPORTED + +const char ** +fnt_get_cid_widths_array(pdc_core *pdc, fnt_font *font) +{ + int slot, slotm; + + (void) pdc; + + /* search for font name */ + slotm = 100; + for (slot = 0; slot < slotm; slot += FNT_CIDMETRIC_INCR) + { + if (!strcmp(fnt_cid_width_arrays[slot], font->name)) + break; + } + + return &fnt_cid_width_arrays[slot + 1]; /* skip font name */ +} + +static void +fnt_parse_cid_widths(pdc_core *pdc, fnt_font *font) +{ + static const char fn[] = "fnt_parse_cid_widths"; + int slot, slota, slotm; + const char *chunk; + char **strlist = NULL, **sstrlist = NULL, *str; + int cid = 0, cidfirst, cidlast, width; + int il, is, ns, nss = 0; + int wformat = 2; + + /* search for font name */ + slotm = 100; + for (slot = 0; slot < slotm; slot += FNT_CIDMETRIC_INCR) + { + if (!strcmp(fnt_cid_width_arrays[slot], font->name)) + break; + } + if (slot == slotm) + return; + + /* we take the maximum */ + font->m.numwidths = fnt_get_maxcid(font->m.charcoll, -1) + 1; + font->m.widths = (int *) pdc_malloc(pdc, + font->m.numwidths * sizeof(int), fn); + + slota = slot + 1; /* skip font name */ + slotm = slot + FNT_CIDMETRIC_INCR; + for (slot = slota; slot < slotm; slot++) + { + chunk = fnt_cid_width_arrays[slot]; + + ns = pdc_split_stringlist(pdc, chunk, " \n", 0, &strlist); + for (is = 0; is < ns; is++) + { + str = strlist[is]; + + /* check for next format 1 chunk */ + if (wformat == 2 && strchr(str, '[')) + { + nss = pdc_split_stringlist(pdc, str, " [", 0, &sstrlist); + str = sstrlist[0]; + pdc_str2integer(str, 0, &cidfirst); + for (; cid < cidfirst; cid++) + font->m.widths[cid] = FNT_DEFAULT_CIDWIDTH; + str = sstrlist[1]; + wformat = 1; + } + + /* format 1: cid [width_1 width_2 ... width_n] */ + if (wformat == 1) + { + il = (int) strlen(str) - 1; + if (str[il] == ']') + { + str[il] = 0; + wformat = 2; + } + + pdc_str2integer(str, 0, &font->m.widths[cid]); + cid++; + + if (nss) + { + pdc_cleanup_stringlist(pdc, sstrlist); + nss = 0; + } + } + else + { + /* format 2: cid_first cid_last width */ + pdc_str2integer(str, 0, &cidfirst); + is++; + str = strlist[is]; + pdc_str2integer(str, 0, &cidlast); + is++; + str = strlist[is]; + pdc_str2integer(str, 0, &width); + + for (; cid < cidfirst; cid++) + font->m.widths[cid] = FNT_DEFAULT_CIDWIDTH; + for (; cid <= cidlast; cid++) + font->m.widths[cid] = width; + } + } + + pdc_cleanup_stringlist(pdc, strlist); + } + + for (; cid < font->m.numwidths; cid++) + font->m.widths[cid] = FNT_DEFAULT_CIDWIDTH; + + if (pdc_logg_is_enabled(pdc, 5, trc_font)) + { + for (cid = 0; cid < font->m.numwidths; cid++) + pdc_logg(pdc, "\t\t\tCID width[%d]: %d\n", + cid, font->m.widths[cid]); + } +} + +#endif /* PDF_CJKFONTWIDTHS_SUPPORTED */ + + +/* ------------------------- general functions -------------------------- */ + +/* + * Fill font metric struct from core metric struct + */ +void +fnt_fill_font_metric(pdc_core *pdc, fnt_font *font, pdc_bool kerning, + const fnt_font_metric *metric) +{ + static const char fn[] = "fnt_fill_font_metric"; + + (void) kerning; + + /* Fill font metric struct. Font struct must be initialized */ + font->m = *metric; + font->m.charcoll = abs(font->m.charcoll); + font->m.name = pdc_strdup(pdc, metric->name); + font->name = pdc_strdup(pdc, metric->name); + + /* Fill glyph widths array (double mapping Unicode <-> code <-> width) */ + if (font->m.numglwidths) + { + font->m.glw = (fnt_glyphwidth *) pdc_calloc(pdc, + metric->numglwidths * sizeof(fnt_glyphwidth), fn); + memcpy(font->m.glw, metric->glw, + metric->numglwidths * sizeof(fnt_glyphwidth)); + } + + /* Fill glyph width array (mapping Unicode interval <-> width) */ + if (metric->numinters) + { + /* We must convert */ + if (font->m.type == fnt_Type1) + { + int i, j, iw, iwe; + pdc_ushort uv; + + for (i = 0; i < metric->numinters; i++) + { + if (i && metric->ciw[i-1].width != 0) + font->m.numglwidths += metric->ciw[i].startcode - + metric->ciw[i-1].startcode; + } + font->m.glw = (fnt_glyphwidth *) pdc_calloc(pdc, + font->m.numglwidths * sizeof(fnt_glyphwidth), fn); + + j = 0; + iw = 0; + for (i = 0; i < metric->numinters; i++) + { + if (i && metric->ciw[j].width != 0) + { + uv = metric->ciw[j].startcode; + iwe = iw + metric->ciw[i].startcode - uv; + for (; iw < iwe; iw++) + { + font->m.glw[iw].unicode = uv; + font->m.glw[iw].width = metric->ciw[j].width; + uv++; + } + } + j = i; + } + font->m.numinters = 0; + font->m.ciw = NULL; + } + else + { + font->m.ciw = (fnt_interwidth *) pdc_calloc(pdc, + font->m.numinters * sizeof(fnt_interwidth), fn); + memcpy(font->m.ciw, metric->ciw, + metric->numinters * sizeof(fnt_interwidth)); + } + } + +#ifdef PDF_CJKFONTWIDTHS_SUPPORTED + /* Fill glyph width array (mapping CID -> width) */ + if (font->m.type == fnt_CIDFontType0) + fnt_parse_cid_widths(pdc, font); +#endif /* PDF_CJKFONTWIDTHS_SUPPORTED */ + + /* Number of glyphs */ + if (font->m.type == fnt_Type1) + font->numglyphs = font->m.numglwidths; + + + /* font weight */ + font->weight = fnt_stemv2weight(font->m.StdVW); + + /* standard Adobe font */ + font->isstdfont = pdc_true; + + /* symbol font */ + if (!(font->m.flags & FNT_SYMBOL)) + font->issymbfont = pdc_false; +} + + + diff --git a/src/pdflib/font/ft_corefont.h b/src/pdflib/font/ft_corefont.h new file mode 100644 index 0000000..526212e --- /dev/null +++ b/src/pdflib/font/ft_corefont.h @@ -0,0 +1,2642 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_corefont.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * This file contains the metric for the base and + * pre-installed CID fonts of PDF + * + * ft_corefont.h is included only in ft_corefont.c. + * + */ + +#ifndef FT_COREMETR_H +#define FT_COREMETR_H + +#ifdef PDF_BUILTINMETRIC_SUPPORTED + +/* -------- Generated from CourierStd.otf -------- */ + +static fnt_interwidth fnt_glyph_width_01[203] = +{ + {0x0000, 600}, {0x0001, 0}, {0x0020, 600}, {0x007F, 0}, + {0x00A0, 600}, {0x0100, 0}, {0x0111, 600}, {0x0112, 0}, + {0x0126, 600}, {0x0128, 0}, {0x0131, 600}, {0x0134, 0}, + {0x0138, 600}, {0x0139, 0}, {0x013F, 600}, {0x0143, 0}, + {0x0149, 600}, {0x014C, 0}, {0x0152, 600}, {0x0154, 0}, + {0x0160, 600}, {0x0162, 0}, {0x0166, 600}, {0x0168, 0}, + {0x0178, 600}, {0x0179, 0}, {0x017D, 600}, {0x017F, 0}, + {0x0192, 600}, {0x0193, 0}, {0x02C6, 600}, {0x02C8, 0}, + {0x02C9, 600}, {0x02CA, 0}, {0x02D8, 600}, {0x02DE, 0}, + {0x0393, 600}, {0x0394, 0}, {0x0398, 600}, {0x0399, 0}, + {0x03A6, 600}, {0x03A7, 0}, {0x03A9, 600}, {0x03AA, 0}, + {0x03B1, 600}, {0x03B2, 0}, {0x03B4, 600}, {0x03B6, 0}, + {0x03BC, 600}, {0x03BD, 0}, {0x03C0, 600}, {0x03C1, 0}, + {0x03C3, 600}, {0x03C5, 0}, {0x03D5, 600}, {0x03D6, 0}, + {0x2013, 600}, {0x2015, 0}, {0x2017, 600}, {0x201F, 0}, + {0x2020, 600}, {0x2023, 0}, {0x2026, 600}, {0x2027, 0}, + {0x2030, 600}, {0x2031, 0}, {0x2039, 600}, {0x203B, 0}, + {0x203C, 600}, {0x203D, 0}, {0x203E, 600}, {0x203F, 0}, + {0x2044, 600}, {0x2045, 0}, {0x207F, 600}, {0x2080, 0}, + {0x20A3, 600}, {0x20A4, 0}, {0x20A7, 600}, {0x20A8, 0}, + {0x20AC, 600}, {0x20AD, 0}, {0x2113, 600}, {0x2114, 0}, + {0x2122, 600}, {0x2123, 0}, {0x2126, 600}, {0x2127, 0}, + {0x212E, 600}, {0x212F, 0}, {0x215B, 600}, {0x215F, 0}, + {0x2190, 600}, {0x2196, 0}, {0x21A8, 600}, {0x21A9, 0}, + {0x2202, 600}, {0x2203, 0}, {0x2206, 600}, {0x2207, 0}, + {0x220F, 600}, {0x2210, 0}, {0x2211, 600}, {0x2213, 0}, + {0x2215, 600}, {0x2216, 0}, {0x2219, 600}, {0x221B, 0}, + {0x221E, 600}, {0x221F, 0}, {0x2229, 600}, {0x222A, 0}, + {0x222B, 600}, {0x222C, 0}, {0x2248, 600}, {0x2249, 0}, + {0x2260, 600}, {0x2262, 0}, {0x2264, 600}, {0x2266, 0}, + {0x22C5, 600}, {0x22C6, 0}, {0x2302, 600}, {0x2303, 0}, + {0x2304, 600}, {0x2305, 0}, {0x2310, 600}, {0x2311, 0}, + {0x2319, 600}, {0x231A, 0}, {0x2320, 600}, {0x2322, 0}, + {0x2500, 600}, {0x2501, 0}, {0x2502, 600}, {0x2503, 0}, + {0x250C, 600}, {0x250D, 0}, {0x2510, 600}, {0x2511, 0}, + {0x2514, 600}, {0x2515, 0}, {0x2518, 600}, {0x2519, 0}, + {0x251C, 600}, {0x251D, 0}, {0x2524, 600}, {0x2525, 0}, + {0x252C, 600}, {0x252D, 0}, {0x2534, 600}, {0x2535, 0}, + {0x253C, 600}, {0x253D, 0}, {0x2550, 600}, {0x256D, 0}, + {0x2580, 600}, {0x2581, 0}, {0x2584, 600}, {0x2585, 0}, + {0x2588, 600}, {0x2589, 0}, {0x258C, 600}, {0x258D, 0}, + {0x2590, 600}, {0x2594, 0}, {0x25A0, 600}, {0x25A1, 0}, + {0x25B2, 600}, {0x25B3, 0}, {0x25B6, 600}, {0x25B7, 0}, + {0x25BC, 600}, {0x25BD, 0}, {0x25C0, 600}, {0x25C1, 0}, + {0x25CA, 600}, {0x25CC, 0}, {0x25D8, 600}, {0x25DA, 0}, + {0x263A, 600}, {0x263D, 0}, {0x2640, 600}, {0x2641, 0}, + {0x2642, 600}, {0x2643, 0}, {0x2660, 600}, {0x2661, 0}, + {0x2662, 600}, {0x2664, 0}, {0x2665, 600}, {0x2667, 0}, + {0x266A, 600}, {0x266B, 0}, {0x266C, 600}, {0x266D, 0}, + {0xE000, 600}, {0xE002, 0}, {0xF638, 600}, {0xF639, 0}, + {0xFB01, 600}, {0xFB03, 0}, {0xFFFF, 0} +}; + +static const fnt_font_metric fnt_font_metric_01 = +{ + "Courier", + 35L, + fnt_Type1, + cc_none, + 0, + 1, + -56, + -250, + 678, + 857, + -198, + 52, + 573, + 435, + 627, + -373, + 109, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 203, + fnt_glyph_width_01, + 0, + NULL, + +}; + +/* -------- Generated from CourierStd-Bold.otf -------- */ + +static fnt_interwidth fnt_glyph_width_02[203] = +{ + {0x0000, 600}, {0x0001, 0}, {0x0020, 600}, {0x007F, 0}, + {0x00A0, 600}, {0x0100, 0}, {0x0111, 600}, {0x0112, 0}, + {0x0126, 600}, {0x0128, 0}, {0x0131, 600}, {0x0134, 0}, + {0x0138, 600}, {0x0139, 0}, {0x013F, 600}, {0x0143, 0}, + {0x0149, 600}, {0x014C, 0}, {0x0152, 600}, {0x0154, 0}, + {0x0160, 600}, {0x0162, 0}, {0x0166, 600}, {0x0168, 0}, + {0x0178, 600}, {0x0179, 0}, {0x017D, 600}, {0x017F, 0}, + {0x0192, 600}, {0x0193, 0}, {0x02C6, 600}, {0x02C8, 0}, + {0x02C9, 600}, {0x02CA, 0}, {0x02D8, 600}, {0x02DE, 0}, + {0x0393, 600}, {0x0394, 0}, {0x0398, 600}, {0x0399, 0}, + {0x03A6, 600}, {0x03A7, 0}, {0x03A9, 600}, {0x03AA, 0}, + {0x03B1, 600}, {0x03B2, 0}, {0x03B4, 600}, {0x03B6, 0}, + {0x03BC, 600}, {0x03BD, 0}, {0x03C0, 600}, {0x03C1, 0}, + {0x03C3, 600}, {0x03C5, 0}, {0x03D5, 600}, {0x03D6, 0}, + {0x2013, 600}, {0x2015, 0}, {0x2017, 600}, {0x201F, 0}, + {0x2020, 600}, {0x2023, 0}, {0x2026, 600}, {0x2027, 0}, + {0x2030, 600}, {0x2031, 0}, {0x2039, 600}, {0x203B, 0}, + {0x203C, 600}, {0x203D, 0}, {0x203E, 600}, {0x203F, 0}, + {0x2044, 600}, {0x2045, 0}, {0x207F, 600}, {0x2080, 0}, + {0x20A3, 600}, {0x20A4, 0}, {0x20A7, 600}, {0x20A8, 0}, + {0x20AC, 600}, {0x20AD, 0}, {0x2113, 600}, {0x2114, 0}, + {0x2122, 600}, {0x2123, 0}, {0x2126, 600}, {0x2127, 0}, + {0x212E, 600}, {0x212F, 0}, {0x215B, 600}, {0x215F, 0}, + {0x2190, 600}, {0x2196, 0}, {0x21A8, 600}, {0x21A9, 0}, + {0x2202, 600}, {0x2203, 0}, {0x2206, 600}, {0x2207, 0}, + {0x220F, 600}, {0x2210, 0}, {0x2211, 600}, {0x2213, 0}, + {0x2215, 600}, {0x2216, 0}, {0x2219, 600}, {0x221B, 0}, + {0x221E, 600}, {0x221F, 0}, {0x2229, 600}, {0x222A, 0}, + {0x222B, 600}, {0x222C, 0}, {0x2248, 600}, {0x2249, 0}, + {0x2260, 600}, {0x2262, 0}, {0x2264, 600}, {0x2266, 0}, + {0x22C5, 600}, {0x22C6, 0}, {0x2302, 600}, {0x2303, 0}, + {0x2304, 600}, {0x2305, 0}, {0x2310, 600}, {0x2311, 0}, + {0x2319, 600}, {0x231A, 0}, {0x2320, 600}, {0x2322, 0}, + {0x2500, 600}, {0x2501, 0}, {0x2502, 600}, {0x2503, 0}, + {0x250C, 600}, {0x250D, 0}, {0x2510, 600}, {0x2511, 0}, + {0x2514, 600}, {0x2515, 0}, {0x2518, 600}, {0x2519, 0}, + {0x251C, 600}, {0x251D, 0}, {0x2524, 600}, {0x2525, 0}, + {0x252C, 600}, {0x252D, 0}, {0x2534, 600}, {0x2535, 0}, + {0x253C, 600}, {0x253D, 0}, {0x2550, 600}, {0x256D, 0}, + {0x2580, 600}, {0x2581, 0}, {0x2584, 600}, {0x2585, 0}, + {0x2588, 600}, {0x2589, 0}, {0x258C, 600}, {0x258D, 0}, + {0x2590, 600}, {0x2594, 0}, {0x25A0, 600}, {0x25A1, 0}, + {0x25B2, 600}, {0x25B3, 0}, {0x25B6, 600}, {0x25B7, 0}, + {0x25BC, 600}, {0x25BD, 0}, {0x25C0, 600}, {0x25C1, 0}, + {0x25CA, 600}, {0x25CC, 0}, {0x25D8, 600}, {0x25DA, 0}, + {0x263A, 600}, {0x263D, 0}, {0x2640, 600}, {0x2641, 0}, + {0x2642, 600}, {0x2643, 0}, {0x2660, 600}, {0x2661, 0}, + {0x2662, 600}, {0x2664, 0}, {0x2665, 600}, {0x2667, 0}, + {0x266A, 600}, {0x266B, 0}, {0x266C, 600}, {0x266D, 0}, + {0xE000, 600}, {0xE002, 0}, {0xF638, 600}, {0xF639, 0}, + {0xFB01, 600}, {0xFB03, 0}, {0xFFFF, 0} +}; + +static const fnt_font_metric fnt_font_metric_02 = +{ + "Courier-Bold", + 262179L, + fnt_Type1, + cc_none, + 0, + 1, + -88, + -250, + 697, + 854, + -198, + 52, + 573, + 435, + 627, + -373, + 166, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 203, + fnt_glyph_width_02, + 0, + NULL, + +}; + +/* -------- Generated from CourierStd-Oblique.otf -------- */ + +static fnt_interwidth fnt_glyph_width_03[203] = +{ + {0x0000, 600}, {0x0001, 0}, {0x0020, 600}, {0x007F, 0}, + {0x00A0, 600}, {0x0100, 0}, {0x0111, 600}, {0x0112, 0}, + {0x0126, 600}, {0x0128, 0}, {0x0131, 600}, {0x0134, 0}, + {0x0138, 600}, {0x0139, 0}, {0x013F, 600}, {0x0143, 0}, + {0x0149, 600}, {0x014C, 0}, {0x0152, 600}, {0x0154, 0}, + {0x0160, 600}, {0x0162, 0}, {0x0166, 600}, {0x0168, 0}, + {0x0178, 600}, {0x0179, 0}, {0x017D, 600}, {0x017F, 0}, + {0x0192, 600}, {0x0193, 0}, {0x02C6, 600}, {0x02C8, 0}, + {0x02C9, 600}, {0x02CA, 0}, {0x02D8, 600}, {0x02DE, 0}, + {0x0393, 600}, {0x0394, 0}, {0x0398, 600}, {0x0399, 0}, + {0x03A6, 600}, {0x03A7, 0}, {0x03A9, 600}, {0x03AA, 0}, + {0x03B1, 600}, {0x03B2, 0}, {0x03B4, 600}, {0x03B6, 0}, + {0x03BC, 600}, {0x03BD, 0}, {0x03C0, 600}, {0x03C1, 0}, + {0x03C3, 600}, {0x03C5, 0}, {0x03D5, 600}, {0x03D6, 0}, + {0x2013, 600}, {0x2015, 0}, {0x2017, 600}, {0x201F, 0}, + {0x2020, 600}, {0x2023, 0}, {0x2026, 600}, {0x2027, 0}, + {0x2030, 600}, {0x2031, 0}, {0x2039, 600}, {0x203B, 0}, + {0x203C, 600}, {0x203D, 0}, {0x203E, 600}, {0x203F, 0}, + {0x2044, 600}, {0x2045, 0}, {0x207F, 600}, {0x2080, 0}, + {0x20A3, 600}, {0x20A4, 0}, {0x20A7, 600}, {0x20A8, 0}, + {0x20AC, 600}, {0x20AD, 0}, {0x2113, 600}, {0x2114, 0}, + {0x2122, 600}, {0x2123, 0}, {0x2126, 600}, {0x2127, 0}, + {0x212E, 600}, {0x212F, 0}, {0x215B, 600}, {0x215F, 0}, + {0x2190, 600}, {0x2196, 0}, {0x21A8, 600}, {0x21A9, 0}, + {0x2202, 600}, {0x2203, 0}, {0x2206, 600}, {0x2207, 0}, + {0x220F, 600}, {0x2210, 0}, {0x2211, 600}, {0x2213, 0}, + {0x2215, 600}, {0x2216, 0}, {0x2219, 600}, {0x221B, 0}, + {0x221E, 600}, {0x221F, 0}, {0x2229, 600}, {0x222A, 0}, + {0x222B, 600}, {0x222C, 0}, {0x2248, 600}, {0x2249, 0}, + {0x2260, 600}, {0x2262, 0}, {0x2264, 600}, {0x2266, 0}, + {0x22C5, 600}, {0x22C6, 0}, {0x2302, 600}, {0x2303, 0}, + {0x2304, 600}, {0x2305, 0}, {0x2310, 600}, {0x2311, 0}, + {0x2319, 600}, {0x231A, 0}, {0x2320, 600}, {0x2322, 0}, + {0x2500, 600}, {0x2501, 0}, {0x2502, 600}, {0x2503, 0}, + {0x250C, 600}, {0x250D, 0}, {0x2510, 600}, {0x2511, 0}, + {0x2514, 600}, {0x2515, 0}, {0x2518, 600}, {0x2519, 0}, + {0x251C, 600}, {0x251D, 0}, {0x2524, 600}, {0x2525, 0}, + {0x252C, 600}, {0x252D, 0}, {0x2534, 600}, {0x2535, 0}, + {0x253C, 600}, {0x253D, 0}, {0x2550, 600}, {0x256D, 0}, + {0x2580, 600}, {0x2581, 0}, {0x2584, 600}, {0x2585, 0}, + {0x2588, 600}, {0x2589, 0}, {0x258C, 600}, {0x258D, 0}, + {0x2590, 600}, {0x2594, 0}, {0x25A0, 600}, {0x25A1, 0}, + {0x25B2, 600}, {0x25B3, 0}, {0x25B6, 600}, {0x25B7, 0}, + {0x25BC, 600}, {0x25BD, 0}, {0x25C0, 600}, {0x25C1, 0}, + {0x25CA, 600}, {0x25CC, 0}, {0x25D8, 600}, {0x25DA, 0}, + {0x263A, 600}, {0x263D, 0}, {0x2640, 600}, {0x2641, 0}, + {0x2642, 600}, {0x2643, 0}, {0x2660, 600}, {0x2661, 0}, + {0x2662, 600}, {0x2664, 0}, {0x2665, 600}, {0x2667, 0}, + {0x266A, 600}, {0x266B, 0}, {0x266C, 600}, {0x266D, 0}, + {0xE000, 600}, {0xE002, 0}, {0xF638, 600}, {0xF639, 0}, + {0xFB01, 600}, {0xFB03, 0}, {0xFFFF, 0} +}; + +static const fnt_font_metric fnt_font_metric_03 = +{ + "Courier-Oblique", + 99L, + fnt_Type1, + cc_none, + -11, + 1, + -48, + -250, + 748, + 857, + -198, + 52, + 573, + 435, + 627, + -373, + 109, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 203, + fnt_glyph_width_03, + 0, + NULL, + +}; + +/* -------- Generated from CourierStd-BoldOblique.otf -------- */ + +static fnt_interwidth fnt_glyph_width_04[203] = +{ + {0x0000, 600}, {0x0001, 0}, {0x0020, 600}, {0x007F, 0}, + {0x00A0, 600}, {0x0100, 0}, {0x0111, 600}, {0x0112, 0}, + {0x0126, 600}, {0x0128, 0}, {0x0131, 600}, {0x0134, 0}, + {0x0138, 600}, {0x0139, 0}, {0x013F, 600}, {0x0143, 0}, + {0x0149, 600}, {0x014C, 0}, {0x0152, 600}, {0x0154, 0}, + {0x0160, 600}, {0x0162, 0}, {0x0166, 600}, {0x0168, 0}, + {0x0178, 600}, {0x0179, 0}, {0x017D, 600}, {0x017F, 0}, + {0x0192, 600}, {0x0193, 0}, {0x02C6, 600}, {0x02C8, 0}, + {0x02C9, 600}, {0x02CA, 0}, {0x02D8, 600}, {0x02DE, 0}, + {0x0393, 600}, {0x0394, 0}, {0x0398, 600}, {0x0399, 0}, + {0x03A6, 600}, {0x03A7, 0}, {0x03A9, 600}, {0x03AA, 0}, + {0x03B1, 600}, {0x03B2, 0}, {0x03B4, 600}, {0x03B6, 0}, + {0x03BC, 600}, {0x03BD, 0}, {0x03C0, 600}, {0x03C1, 0}, + {0x03C3, 600}, {0x03C5, 0}, {0x03D5, 600}, {0x03D6, 0}, + {0x2013, 600}, {0x2015, 0}, {0x2017, 600}, {0x201F, 0}, + {0x2020, 600}, {0x2023, 0}, {0x2026, 600}, {0x2027, 0}, + {0x2030, 600}, {0x2031, 0}, {0x2039, 600}, {0x203B, 0}, + {0x203C, 600}, {0x203D, 0}, {0x203E, 600}, {0x203F, 0}, + {0x2044, 600}, {0x2045, 0}, {0x207F, 600}, {0x2080, 0}, + {0x20A3, 600}, {0x20A4, 0}, {0x20A7, 600}, {0x20A8, 0}, + {0x20AC, 600}, {0x20AD, 0}, {0x2113, 600}, {0x2114, 0}, + {0x2122, 600}, {0x2123, 0}, {0x2126, 600}, {0x2127, 0}, + {0x212E, 600}, {0x212F, 0}, {0x215B, 600}, {0x215F, 0}, + {0x2190, 600}, {0x2196, 0}, {0x21A8, 600}, {0x21A9, 0}, + {0x2202, 600}, {0x2203, 0}, {0x2206, 600}, {0x2207, 0}, + {0x220F, 600}, {0x2210, 0}, {0x2211, 600}, {0x2213, 0}, + {0x2215, 600}, {0x2216, 0}, {0x2219, 600}, {0x221B, 0}, + {0x221E, 600}, {0x221F, 0}, {0x2229, 600}, {0x222A, 0}, + {0x222B, 600}, {0x222C, 0}, {0x2248, 600}, {0x2249, 0}, + {0x2260, 600}, {0x2262, 0}, {0x2264, 600}, {0x2266, 0}, + {0x22C5, 600}, {0x22C6, 0}, {0x2302, 600}, {0x2303, 0}, + {0x2304, 600}, {0x2305, 0}, {0x2310, 600}, {0x2311, 0}, + {0x2319, 600}, {0x231A, 0}, {0x2320, 600}, {0x2322, 0}, + {0x2500, 600}, {0x2501, 0}, {0x2502, 600}, {0x2503, 0}, + {0x250C, 600}, {0x250D, 0}, {0x2510, 600}, {0x2511, 0}, + {0x2514, 600}, {0x2515, 0}, {0x2518, 600}, {0x2519, 0}, + {0x251C, 600}, {0x251D, 0}, {0x2524, 600}, {0x2525, 0}, + {0x252C, 600}, {0x252D, 0}, {0x2534, 600}, {0x2535, 0}, + {0x253C, 600}, {0x253D, 0}, {0x2550, 600}, {0x256D, 0}, + {0x2580, 600}, {0x2581, 0}, {0x2584, 600}, {0x2585, 0}, + {0x2588, 600}, {0x2589, 0}, {0x258C, 600}, {0x258D, 0}, + {0x2590, 600}, {0x2594, 0}, {0x25A0, 600}, {0x25A1, 0}, + {0x25B2, 600}, {0x25B3, 0}, {0x25B6, 600}, {0x25B7, 0}, + {0x25BC, 600}, {0x25BD, 0}, {0x25C0, 600}, {0x25C1, 0}, + {0x25CA, 600}, {0x25CC, 0}, {0x25D8, 600}, {0x25DA, 0}, + {0x263A, 600}, {0x263D, 0}, {0x2640, 600}, {0x2641, 0}, + {0x2642, 600}, {0x2643, 0}, {0x2660, 600}, {0x2661, 0}, + {0x2662, 600}, {0x2664, 0}, {0x2665, 600}, {0x2667, 0}, + {0x266A, 600}, {0x266B, 0}, {0x266C, 600}, {0x266D, 0}, + {0xE000, 600}, {0xE002, 0}, {0xF638, 600}, {0xF639, 0}, + {0xFB01, 600}, {0xFB03, 0}, {0xFFFF, 0} +}; + +static const fnt_font_metric fnt_font_metric_04 = +{ + "Courier-BoldOblique", + 262243L, + fnt_Type1, + cc_none, + -11, + 1, + -48, + -250, + 757, + 854, + -198, + 52, + 573, + 435, + 627, + -373, + 166, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 203, + fnt_glyph_width_04, + 0, + NULL, + +}; + +/* -------- Generated from ARIAL.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_05[268] = +{ + {0x0000, 0}, {0x0020, 278}, {0x0022, 355}, {0x0023, 556}, + {0x0025, 889}, {0x0026, 667}, {0x0027, 191}, {0x0028, 333}, + {0x002A, 389}, {0x002B, 584}, {0x002C, 278}, {0x002D, 333}, + {0x002E, 278}, {0x0030, 556}, {0x003A, 278}, {0x003C, 584}, + {0x003F, 556}, {0x0040,1015}, {0x0041, 667}, {0x0043, 722}, + {0x0045, 667}, {0x0046, 611}, {0x0047, 778}, {0x0048, 722}, + {0x0049, 278}, {0x004A, 500}, {0x004B, 667}, {0x004C, 556}, + {0x004D, 833}, {0x004E, 722}, {0x004F, 778}, {0x0050, 667}, + {0x0051, 778}, {0x0052, 722}, {0x0053, 667}, {0x0054, 611}, + {0x0055, 722}, {0x0056, 667}, {0x0057, 944}, {0x0058, 667}, + {0x005A, 611}, {0x005B, 278}, {0x005E, 469}, {0x005F, 556}, + {0x0060, 333}, {0x0061, 556}, {0x0063, 500}, {0x0064, 556}, + {0x0066, 278}, {0x0067, 556}, {0x0069, 222}, {0x006B, 500}, + {0x006C, 222}, {0x006D, 833}, {0x006E, 556}, {0x0072, 333}, + {0x0073, 500}, {0x0074, 278}, {0x0075, 556}, {0x0076, 500}, + {0x0077, 722}, {0x0078, 500}, {0x007B, 334}, {0x007C, 260}, + {0x007D, 334}, {0x007E, 584}, {0x007F, 0}, {0x00A0, 278}, + {0x00A1, 333}, {0x00A2, 556}, {0x00A6, 260}, {0x00A7, 556}, + {0x00A8, 333}, {0x00A9, 737}, {0x00AA, 370}, {0x00AB, 556}, + {0x00AC, 584}, {0x00AD, 333}, {0x00AE, 737}, {0x00AF, 552}, + {0x00B0, 400}, {0x00B1, 549}, {0x00B2, 333}, {0x00B5, 576}, + {0x00B6, 537}, {0x00B7, 278}, {0x00B8, 333}, {0x00BA, 365}, + {0x00BB, 556}, {0x00BC, 834}, {0x00BF, 611}, {0x00C0, 667}, + {0x00C6,1000}, {0x00C7, 722}, {0x00C8, 667}, {0x00CC, 278}, + {0x00D0, 722}, {0x00D2, 778}, {0x00D7, 584}, {0x00D8, 778}, + {0x00D9, 722}, {0x00DD, 667}, {0x00DF, 611}, {0x00E0, 556}, + {0x00E6, 889}, {0x00E7, 500}, {0x00E8, 556}, {0x00EC, 278}, + {0x00F0, 556}, {0x00F7, 549}, {0x00F8, 611}, {0x00F9, 556}, + {0x00FD, 500}, {0x00FE, 556}, {0x00FF, 500}, {0x0100, 667}, + {0x0101, 556}, {0x0102, 667}, {0x0103, 556}, {0x0104, 667}, + {0x0105, 556}, {0x0106, 722}, {0x0107, 500}, {0x0108, 0}, + {0x010C, 722}, {0x010D, 500}, {0x010E, 722}, {0x010F, 615}, + {0x0110, 722}, {0x0111, 556}, {0x0112, 667}, {0x0113, 556}, + {0x0114, 0}, {0x0116, 667}, {0x0117, 556}, {0x0118, 667}, + {0x0119, 556}, {0x011A, 667}, {0x011B, 556}, {0x011C, 0}, + {0x011E, 778}, {0x011F, 556}, {0x0120, 0}, {0x0122, 778}, + {0x0123, 556}, {0x0124, 0}, {0x0128, 278}, {0x012C, 0}, + {0x012E, 278}, {0x012F, 222}, {0x0130, 278}, {0x0132, 0}, + {0x0136, 667}, {0x0137, 500}, {0x0139, 556}, {0x013A, 222}, + {0x013B, 556}, {0x013C, 222}, {0x013D, 556}, {0x013E, 292}, + {0x013F, 0}, {0x0141, 556}, {0x0142, 222}, {0x0143, 722}, + {0x0144, 556}, {0x0145, 722}, {0x0146, 556}, {0x0147, 722}, + {0x0148, 556}, {0x0149, 0}, {0x014A, 723}, {0x014B, 556}, + {0x014C, 778}, {0x014D, 556}, {0x014E, 0}, {0x0150, 778}, + {0x0151, 556}, {0x0152,1000}, {0x0153, 944}, {0x0154, 722}, + {0x0155, 333}, {0x0156, 722}, {0x0157, 333}, {0x0158, 722}, + {0x0159, 333}, {0x015A, 667}, {0x015B, 500}, {0x015C, 0}, + {0x015E, 667}, {0x015F, 500}, {0x0160, 667}, {0x0161, 500}, + {0x0162, 611}, {0x0163, 278}, {0x0164, 611}, {0x0165, 375}, + {0x0166, 611}, {0x0167, 278}, {0x0168, 722}, {0x0169, 556}, + {0x016A, 722}, {0x016B, 556}, {0x016C, 0}, {0x016E, 722}, + {0x016F, 556}, {0x0170, 722}, {0x0171, 556}, {0x0172, 722}, + {0x0173, 556}, {0x0174, 0}, {0x0178, 667}, {0x0179, 611}, + {0x017A, 500}, {0x017B, 611}, {0x017C, 500}, {0x017D, 611}, + {0x017E, 500}, {0x017F, 0}, {0x0192, 556}, {0x0193, 0}, + {0x0218, 750}, {0x021A, 611}, {0x021B, 278}, {0x021C, 0}, + {0x02C6, 333}, {0x02C8, 0}, {0x02D8, 333}, {0x02DA, 0}, + {0x02DB, 333}, {0x02DE, 0}, {0x2013, 556}, {0x2014,1000}, + {0x2016, 0}, {0x2018, 222}, {0x201B, 0}, {0x201C, 333}, + {0x201F, 0}, {0x2020, 556}, {0x2022, 350}, {0x2023, 0}, + {0x2026,1000}, {0x2027, 0}, {0x2030,1000}, {0x2031, 0}, + {0x2039, 333}, {0x203B, 0}, {0x20AC, 556}, {0x20AD, 0}, + {0x2122,1000}, {0x2123, 0}, {0x2202, 494}, {0x2203, 0}, + {0x2211, 713}, {0x2212, 584}, {0x2213, 0}, {0x221A, 549}, + {0x221B, 0}, {0x2260, 549}, {0x2261, 0}, {0x2264, 549}, + {0x2266, 0}, {0x25CA, 494}, {0x25CB, 0}, {0xF6C3, 750}, + {0xF6C4, 0}, {0xFB01, 500}, {0xFB03, 0}, {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_05 = +{ + "Helvetica", + 32L, + fnt_Type1, + cc_none, + 0, + 0, + -665, + -325, + 2028, + 1037, + -106, + 73, + 718, + 523, + 718, + -207, + 88, + 0, + FNT_DEFAULT_WIDTH, + 0, + NULL, + 268, + fnt_glyph_width_05, + 0, + NULL, + +}; + +/* -------- Generated from ARIALBD.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_06[269] = +{ + {0x0000, 0}, {0x0020, 278}, {0x0021, 333}, {0x0022, 474}, + {0x0023, 556}, {0x0025, 889}, {0x0026, 722}, {0x0027, 238}, + {0x0028, 333}, {0x002A, 389}, {0x002B, 584}, {0x002C, 278}, + {0x002D, 333}, {0x002E, 278}, {0x0030, 556}, {0x003A, 333}, + {0x003C, 584}, {0x003F, 611}, {0x0040, 975}, {0x0041, 722}, + {0x0045, 667}, {0x0046, 611}, {0x0047, 778}, {0x0048, 722}, + {0x0049, 278}, {0x004A, 556}, {0x004B, 722}, {0x004C, 611}, + {0x004D, 833}, {0x004E, 722}, {0x004F, 778}, {0x0050, 667}, + {0x0051, 778}, {0x0052, 722}, {0x0053, 667}, {0x0054, 611}, + {0x0055, 722}, {0x0056, 667}, {0x0057, 944}, {0x0058, 667}, + {0x005A, 611}, {0x005B, 333}, {0x005C, 278}, {0x005D, 333}, + {0x005E, 584}, {0x005F, 556}, {0x0060, 333}, {0x0061, 556}, + {0x0062, 611}, {0x0063, 556}, {0x0064, 611}, {0x0065, 556}, + {0x0066, 333}, {0x0067, 611}, {0x0069, 278}, {0x006B, 556}, + {0x006C, 278}, {0x006D, 889}, {0x006E, 611}, {0x0072, 389}, + {0x0073, 556}, {0x0074, 333}, {0x0075, 611}, {0x0076, 556}, + {0x0077, 778}, {0x0078, 556}, {0x007A, 500}, {0x007B, 389}, + {0x007C, 280}, {0x007D, 389}, {0x007E, 584}, {0x007F, 0}, + {0x00A0, 278}, {0x00A1, 333}, {0x00A2, 556}, {0x00A6, 280}, + {0x00A7, 556}, {0x00A8, 333}, {0x00A9, 737}, {0x00AA, 370}, + {0x00AB, 556}, {0x00AC, 584}, {0x00AD, 333}, {0x00AE, 737}, + {0x00AF, 552}, {0x00B0, 400}, {0x00B1, 549}, {0x00B2, 333}, + {0x00B5, 576}, {0x00B6, 556}, {0x00B7, 278}, {0x00B8, 333}, + {0x00BA, 365}, {0x00BB, 556}, {0x00BC, 834}, {0x00BF, 611}, + {0x00C0, 722}, {0x00C6,1000}, {0x00C7, 722}, {0x00C8, 667}, + {0x00CC, 278}, {0x00D0, 722}, {0x00D2, 778}, {0x00D7, 584}, + {0x00D8, 778}, {0x00D9, 722}, {0x00DD, 667}, {0x00DF, 611}, + {0x00E0, 556}, {0x00E6, 889}, {0x00E7, 556}, {0x00EC, 278}, + {0x00F0, 611}, {0x00F7, 549}, {0x00F8, 611}, {0x00FD, 556}, + {0x00FE, 611}, {0x00FF, 556}, {0x0100, 722}, {0x0101, 556}, + {0x0102, 722}, {0x0103, 556}, {0x0104, 722}, {0x0105, 556}, + {0x0106, 722}, {0x0107, 556}, {0x0108, 0}, {0x010C, 722}, + {0x010D, 556}, {0x010E, 722}, {0x010F, 719}, {0x0110, 722}, + {0x0111, 611}, {0x0112, 667}, {0x0113, 556}, {0x0114, 0}, + {0x0116, 667}, {0x0117, 556}, {0x0118, 667}, {0x0119, 556}, + {0x011A, 667}, {0x011B, 556}, {0x011C, 0}, {0x011E, 778}, + {0x011F, 611}, {0x0120, 0}, {0x0122, 778}, {0x0123, 611}, + {0x0124, 0}, {0x0128, 278}, {0x012C, 0}, {0x012E, 278}, + {0x0132, 0}, {0x0136, 722}, {0x0137, 556}, {0x0139, 611}, + {0x013A, 278}, {0x013B, 611}, {0x013C, 278}, {0x013D, 611}, + {0x013E, 385}, {0x013F, 0}, {0x0141, 611}, {0x0142, 278}, + {0x0143, 722}, {0x0144, 611}, {0x0145, 722}, {0x0146, 611}, + {0x0147, 722}, {0x0148, 611}, {0x0149, 0}, {0x014A, 723}, + {0x014B, 611}, {0x014C, 778}, {0x014D, 611}, {0x014E, 0}, + {0x0150, 778}, {0x0151, 611}, {0x0152,1000}, {0x0153, 944}, + {0x0154, 722}, {0x0155, 389}, {0x0156, 722}, {0x0157, 389}, + {0x0158, 722}, {0x0159, 389}, {0x015A, 667}, {0x015B, 556}, + {0x015C, 0}, {0x015E, 667}, {0x015F, 556}, {0x0160, 667}, + {0x0161, 556}, {0x0162, 611}, {0x0163, 333}, {0x0164, 611}, + {0x0165, 479}, {0x0166, 611}, {0x0167, 333}, {0x0168, 722}, + {0x0169, 611}, {0x016A, 722}, {0x016B, 611}, {0x016C, 0}, + {0x016E, 722}, {0x016F, 611}, {0x0170, 722}, {0x0171, 611}, + {0x0172, 722}, {0x0173, 611}, {0x0174, 0}, {0x0178, 667}, + {0x0179, 611}, {0x017A, 500}, {0x017B, 611}, {0x017C, 500}, + {0x017D, 611}, {0x017E, 500}, {0x017F, 0}, {0x0192, 556}, + {0x0193, 0}, {0x0218, 750}, {0x021A, 611}, {0x021B, 333}, + {0x021C, 0}, {0x02C6, 333}, {0x02C8, 0}, {0x02D8, 333}, + {0x02DA, 0}, {0x02DB, 333}, {0x02DE, 0}, {0x2013, 556}, + {0x2014,1000}, {0x2016, 0}, {0x2018, 278}, {0x201B, 0}, + {0x201C, 500}, {0x201F, 0}, {0x2020, 556}, {0x2022, 350}, + {0x2023, 0}, {0x2026,1000}, {0x2027, 0}, {0x2030,1000}, + {0x2031, 0}, {0x2039, 333}, {0x203B, 0}, {0x20AC, 556}, + {0x20AD, 0}, {0x2122,1000}, {0x2123, 0}, {0x2202, 494}, + {0x2203, 0}, {0x2211, 713}, {0x2212, 584}, {0x2213, 0}, + {0x221A, 549}, {0x221B, 0}, {0x2260, 549}, {0x2261, 0}, + {0x2264, 549}, {0x2266, 0}, {0x25CA, 494}, {0x25CB, 0}, + {0xF6C3, 750}, {0xF6C4, 0}, {0xFB01, 611}, {0xFB03, 0}, + {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_06 = +{ + "Helvetica-Bold", + 262176L, + fnt_Type1, + cc_none, + 0, + 0, + -628, + -376, + 2000, + 1010, + -106, + 105, + 718, + 532, + 718, + -207, + 166, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 269, + fnt_glyph_width_06, + 0, + NULL, + +}; + +/* -------- Generated from ARIALI.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_07[268] = +{ + {0x0000, 0}, {0x0020, 278}, {0x0022, 355}, {0x0023, 556}, + {0x0025, 889}, {0x0026, 667}, {0x0027, 191}, {0x0028, 333}, + {0x002A, 389}, {0x002B, 584}, {0x002C, 278}, {0x002D, 333}, + {0x002E, 278}, {0x0030, 556}, {0x003A, 278}, {0x003C, 584}, + {0x003F, 556}, {0x0040,1015}, {0x0041, 667}, {0x0043, 722}, + {0x0045, 667}, {0x0046, 611}, {0x0047, 778}, {0x0048, 722}, + {0x0049, 278}, {0x004A, 500}, {0x004B, 667}, {0x004C, 556}, + {0x004D, 833}, {0x004E, 722}, {0x004F, 778}, {0x0050, 667}, + {0x0051, 778}, {0x0052, 722}, {0x0053, 667}, {0x0054, 611}, + {0x0055, 722}, {0x0056, 667}, {0x0057, 944}, {0x0058, 667}, + {0x005A, 611}, {0x005B, 278}, {0x005E, 469}, {0x005F, 556}, + {0x0060, 333}, {0x0061, 556}, {0x0063, 500}, {0x0064, 556}, + {0x0066, 278}, {0x0067, 556}, {0x0069, 222}, {0x006B, 500}, + {0x006C, 222}, {0x006D, 833}, {0x006E, 556}, {0x0072, 333}, + {0x0073, 500}, {0x0074, 278}, {0x0075, 556}, {0x0076, 500}, + {0x0077, 722}, {0x0078, 500}, {0x007B, 334}, {0x007C, 260}, + {0x007D, 334}, {0x007E, 584}, {0x007F, 0}, {0x00A0, 278}, + {0x00A1, 333}, {0x00A2, 556}, {0x00A6, 260}, {0x00A7, 556}, + {0x00A8, 333}, {0x00A9, 737}, {0x00AA, 370}, {0x00AB, 556}, + {0x00AC, 584}, {0x00AD, 333}, {0x00AE, 737}, {0x00AF, 552}, + {0x00B0, 400}, {0x00B1, 549}, {0x00B2, 333}, {0x00B5, 576}, + {0x00B6, 537}, {0x00B7, 278}, {0x00B8, 333}, {0x00BA, 365}, + {0x00BB, 556}, {0x00BC, 834}, {0x00BF, 611}, {0x00C0, 667}, + {0x00C6,1000}, {0x00C7, 722}, {0x00C8, 667}, {0x00CC, 278}, + {0x00D0, 722}, {0x00D2, 778}, {0x00D7, 584}, {0x00D8, 778}, + {0x00D9, 722}, {0x00DD, 667}, {0x00DF, 611}, {0x00E0, 556}, + {0x00E6, 889}, {0x00E7, 500}, {0x00E8, 556}, {0x00EC, 278}, + {0x00F0, 556}, {0x00F7, 549}, {0x00F8, 611}, {0x00F9, 556}, + {0x00FD, 500}, {0x00FE, 556}, {0x00FF, 500}, {0x0100, 667}, + {0x0101, 556}, {0x0102, 667}, {0x0103, 556}, {0x0104, 667}, + {0x0105, 556}, {0x0106, 722}, {0x0107, 500}, {0x0108, 0}, + {0x010C, 722}, {0x010D, 500}, {0x010E, 722}, {0x010F, 625}, + {0x0110, 722}, {0x0111, 556}, {0x0112, 667}, {0x0113, 556}, + {0x0114, 0}, {0x0116, 667}, {0x0117, 556}, {0x0118, 667}, + {0x0119, 556}, {0x011A, 667}, {0x011B, 556}, {0x011C, 0}, + {0x011E, 778}, {0x011F, 556}, {0x0120, 0}, {0x0122, 778}, + {0x0123, 556}, {0x0124, 0}, {0x0128, 278}, {0x012C, 0}, + {0x012E, 278}, {0x012F, 222}, {0x0130, 278}, {0x0132, 0}, + {0x0136, 667}, {0x0137, 500}, {0x0139, 556}, {0x013A, 222}, + {0x013B, 556}, {0x013C, 222}, {0x013D, 556}, {0x013E, 281}, + {0x013F, 0}, {0x0141, 556}, {0x0142, 222}, {0x0143, 722}, + {0x0144, 556}, {0x0145, 722}, {0x0146, 556}, {0x0147, 722}, + {0x0148, 556}, {0x0149, 0}, {0x014A, 723}, {0x014B, 556}, + {0x014C, 778}, {0x014D, 556}, {0x014E, 0}, {0x0150, 778}, + {0x0151, 556}, {0x0152,1000}, {0x0153, 944}, {0x0154, 722}, + {0x0155, 333}, {0x0156, 722}, {0x0157, 333}, {0x0158, 722}, + {0x0159, 333}, {0x015A, 667}, {0x015B, 500}, {0x015C, 0}, + {0x015E, 667}, {0x015F, 500}, {0x0160, 667}, {0x0161, 500}, + {0x0162, 611}, {0x0163, 278}, {0x0164, 611}, {0x0165, 354}, + {0x0166, 611}, {0x0167, 278}, {0x0168, 722}, {0x0169, 556}, + {0x016A, 722}, {0x016B, 556}, {0x016C, 0}, {0x016E, 722}, + {0x016F, 556}, {0x0170, 722}, {0x0171, 556}, {0x0172, 722}, + {0x0173, 556}, {0x0174, 0}, {0x0178, 667}, {0x0179, 611}, + {0x017A, 500}, {0x017B, 611}, {0x017C, 500}, {0x017D, 611}, + {0x017E, 500}, {0x017F, 0}, {0x0192, 556}, {0x0193, 0}, + {0x0218, 750}, {0x021A, 611}, {0x021B, 278}, {0x021C, 0}, + {0x02C6, 333}, {0x02C8, 0}, {0x02D8, 333}, {0x02DA, 0}, + {0x02DB, 333}, {0x02DE, 0}, {0x2013, 556}, {0x2014,1000}, + {0x2016, 0}, {0x2018, 222}, {0x201B, 0}, {0x201C, 333}, + {0x201F, 0}, {0x2020, 556}, {0x2022, 350}, {0x2023, 0}, + {0x2026,1000}, {0x2027, 0}, {0x2030,1000}, {0x2031, 0}, + {0x2039, 333}, {0x203B, 0}, {0x20AC, 556}, {0x20AD, 0}, + {0x2122,1000}, {0x2123, 0}, {0x2202, 494}, {0x2203, 0}, + {0x2211, 713}, {0x2212, 584}, {0x2213, 0}, {0x221A, 549}, + {0x221B, 0}, {0x2260, 549}, {0x2261, 0}, {0x2264, 549}, + {0x2266, 0}, {0x25CA, 494}, {0x25CB, 0}, {0xF6C3, 750}, + {0xF6C4, 0}, {0xFB01, 500}, {0xFB03, 0}, {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_07 = +{ + "Helvetica-Oblique", + 96L, + fnt_Type1, + cc_none, + -12, + 0, + -517, + -325, + 1082, + 998, + -106, + 73, + 718, + 523, + 718, + -207, + 88, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 268, + fnt_glyph_width_07, + 0, + NULL, + +}; + +/* -------- Generated from ARIALBI.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_08[269] = +{ + {0x0000, 0}, {0x0020, 278}, {0x0021, 333}, {0x0022, 474}, + {0x0023, 556}, {0x0025, 889}, {0x0026, 722}, {0x0027, 238}, + {0x0028, 333}, {0x002A, 389}, {0x002B, 584}, {0x002C, 278}, + {0x002D, 333}, {0x002E, 278}, {0x0030, 556}, {0x003A, 333}, + {0x003C, 584}, {0x003F, 611}, {0x0040, 975}, {0x0041, 722}, + {0x0045, 667}, {0x0046, 611}, {0x0047, 778}, {0x0048, 722}, + {0x0049, 278}, {0x004A, 556}, {0x004B, 722}, {0x004C, 611}, + {0x004D, 833}, {0x004E, 722}, {0x004F, 778}, {0x0050, 667}, + {0x0051, 778}, {0x0052, 722}, {0x0053, 667}, {0x0054, 611}, + {0x0055, 722}, {0x0056, 667}, {0x0057, 944}, {0x0058, 667}, + {0x005A, 611}, {0x005B, 333}, {0x005C, 278}, {0x005D, 333}, + {0x005E, 584}, {0x005F, 556}, {0x0060, 333}, {0x0061, 556}, + {0x0062, 611}, {0x0063, 556}, {0x0064, 611}, {0x0065, 556}, + {0x0066, 333}, {0x0067, 611}, {0x0069, 278}, {0x006B, 556}, + {0x006C, 278}, {0x006D, 889}, {0x006E, 611}, {0x0072, 389}, + {0x0073, 556}, {0x0074, 333}, {0x0075, 611}, {0x0076, 556}, + {0x0077, 778}, {0x0078, 556}, {0x007A, 500}, {0x007B, 389}, + {0x007C, 280}, {0x007D, 389}, {0x007E, 584}, {0x007F, 0}, + {0x00A0, 278}, {0x00A1, 333}, {0x00A2, 556}, {0x00A6, 280}, + {0x00A7, 556}, {0x00A8, 333}, {0x00A9, 737}, {0x00AA, 370}, + {0x00AB, 556}, {0x00AC, 584}, {0x00AD, 333}, {0x00AE, 737}, + {0x00AF, 552}, {0x00B0, 400}, {0x00B1, 549}, {0x00B2, 333}, + {0x00B5, 576}, {0x00B6, 556}, {0x00B7, 278}, {0x00B8, 333}, + {0x00BA, 365}, {0x00BB, 556}, {0x00BC, 834}, {0x00BF, 611}, + {0x00C0, 722}, {0x00C6,1000}, {0x00C7, 722}, {0x00C8, 667}, + {0x00CC, 278}, {0x00D0, 722}, {0x00D2, 778}, {0x00D7, 584}, + {0x00D8, 778}, {0x00D9, 722}, {0x00DD, 667}, {0x00DF, 611}, + {0x00E0, 556}, {0x00E6, 889}, {0x00E7, 556}, {0x00EC, 278}, + {0x00F0, 611}, {0x00F7, 549}, {0x00F8, 611}, {0x00FD, 556}, + {0x00FE, 611}, {0x00FF, 556}, {0x0100, 722}, {0x0101, 556}, + {0x0102, 722}, {0x0103, 556}, {0x0104, 722}, {0x0105, 556}, + {0x0106, 722}, {0x0107, 556}, {0x0108, 0}, {0x010C, 722}, + {0x010D, 556}, {0x010E, 722}, {0x010F, 740}, {0x0110, 722}, + {0x0111, 611}, {0x0112, 667}, {0x0113, 556}, {0x0114, 0}, + {0x0116, 667}, {0x0117, 556}, {0x0118, 667}, {0x0119, 556}, + {0x011A, 667}, {0x011B, 556}, {0x011C, 0}, {0x011E, 778}, + {0x011F, 611}, {0x0120, 0}, {0x0122, 778}, {0x0123, 611}, + {0x0124, 0}, {0x0128, 278}, {0x012C, 0}, {0x012E, 278}, + {0x0132, 0}, {0x0136, 722}, {0x0137, 556}, {0x0139, 611}, + {0x013A, 278}, {0x013B, 611}, {0x013C, 278}, {0x013D, 611}, + {0x013E, 396}, {0x013F, 0}, {0x0141, 611}, {0x0142, 278}, + {0x0143, 722}, {0x0144, 611}, {0x0145, 722}, {0x0146, 611}, + {0x0147, 722}, {0x0148, 611}, {0x0149, 0}, {0x014A, 723}, + {0x014B, 611}, {0x014C, 778}, {0x014D, 611}, {0x014E, 0}, + {0x0150, 778}, {0x0151, 611}, {0x0152,1000}, {0x0153, 944}, + {0x0154, 722}, {0x0155, 389}, {0x0156, 722}, {0x0157, 389}, + {0x0158, 722}, {0x0159, 389}, {0x015A, 667}, {0x015B, 556}, + {0x015C, 0}, {0x015E, 667}, {0x015F, 556}, {0x0160, 667}, + {0x0161, 556}, {0x0162, 611}, {0x0163, 333}, {0x0164, 611}, + {0x0165, 479}, {0x0166, 611}, {0x0167, 333}, {0x0168, 722}, + {0x0169, 611}, {0x016A, 722}, {0x016B, 611}, {0x016C, 0}, + {0x016E, 722}, {0x016F, 611}, {0x0170, 722}, {0x0171, 611}, + {0x0172, 722}, {0x0173, 611}, {0x0174, 0}, {0x0178, 667}, + {0x0179, 611}, {0x017A, 500}, {0x017B, 611}, {0x017C, 500}, + {0x017D, 611}, {0x017E, 500}, {0x017F, 0}, {0x0192, 556}, + {0x0193, 0}, {0x0218, 750}, {0x021A, 611}, {0x021B, 333}, + {0x021C, 0}, {0x02C6, 333}, {0x02C8, 0}, {0x02D8, 333}, + {0x02DA, 0}, {0x02DB, 333}, {0x02DE, 0}, {0x2013, 556}, + {0x2014,1000}, {0x2016, 0}, {0x2018, 278}, {0x201B, 0}, + {0x201C, 500}, {0x201F, 0}, {0x2020, 556}, {0x2022, 350}, + {0x2023, 0}, {0x2026,1000}, {0x2027, 0}, {0x2030,1000}, + {0x2031, 0}, {0x2039, 333}, {0x203B, 0}, {0x20AC, 556}, + {0x20AD, 0}, {0x2122,1000}, {0x2123, 0}, {0x2202, 494}, + {0x2203, 0}, {0x2211, 713}, {0x2212, 584}, {0x2213, 0}, + {0x221A, 549}, {0x221B, 0}, {0x2260, 549}, {0x2261, 0}, + {0x2264, 549}, {0x2266, 0}, {0x25CA, 494}, {0x25CB, 0}, + {0xF6C3, 750}, {0xF6C4, 0}, {0xFB01, 611}, {0xFB03, 0}, + {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_08 = +{ + "Helvetica-BoldOblique", + 262240L, + fnt_Type1, + cc_none, + -12, + 0, + -560, + -376, + 1157, + 1000, + -106, + 105, + 718, + 532, + 718, + -207, + 166, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 269, + fnt_glyph_width_08, + 0, + NULL, + +}; + +/* -------- Generated from Symbol.afm -------- */ + +static fnt_glyphwidth fnt_glyph_width_09[191] = +{ + {0x0020, 32, 250}, {0x0021, 33, 333}, {0x2200, 34, 713}, + {0x0023, 35, 500}, {0x2203, 36, 549}, {0x0025, 37, 833}, + {0x0026, 38, 778}, {0x220b, 39, 439}, {0x0028, 40, 333}, + {0x0029, 41, 333}, {0x2217, 42, 500}, {0x002b, 43, 549}, + {0x002c, 44, 250}, {0x2212, 45, 549}, {0x002e, 46, 250}, + {0x002f, 47, 278}, {0x0030, 48, 500}, {0x0031, 49, 500}, + {0x0032, 50, 500}, {0x0033, 51, 500}, {0x0034, 52, 500}, + {0x0035, 53, 500}, {0x0036, 54, 500}, {0x0037, 55, 500}, + {0x0038, 56, 500}, {0x0039, 57, 500}, {0x003a, 58, 278}, + {0x003b, 59, 278}, {0x003c, 60, 549}, {0x003d, 61, 549}, + {0x003e, 62, 549}, {0x003f, 63, 444}, {0x2245, 64, 549}, + {0x0391, 65, 722}, {0x0392, 66, 667}, {0x03a7, 67, 722}, + {0x0394, 68, 612}, {0x0395, 69, 611}, {0x03a6, 70, 763}, + {0x0393, 71, 603}, {0x0397, 72, 722}, {0x0399, 73, 333}, + {0x03d1, 74, 631}, {0x039a, 75, 722}, {0x039b, 76, 686}, + {0x039c, 77, 889}, {0x039d, 78, 722}, {0x039f, 79, 722}, + {0x03a0, 80, 768}, {0x0398, 81, 741}, {0x03a1, 82, 556}, + {0x03a3, 83, 592}, {0x03a4, 84, 611}, {0x03a5, 85, 690}, + {0x03c2, 86, 439}, {0x03a9, 87, 768}, {0x039e, 88, 645}, + {0x03a8, 89, 795}, {0x0396, 90, 611}, {0x005b, 91, 333}, + {0x2234, 92, 863}, {0x005d, 93, 333}, {0x22a5, 94, 658}, + {0x005f, 95, 500}, {0xf8e5, 96, 500}, {0x03b1, 97, 631}, + {0x03b2, 98, 549}, {0x03c7, 99, 549}, {0x03b4, 100, 494}, + {0x03b5, 101, 439}, {0x03c6, 102, 521}, {0x03b3, 103, 411}, + {0x03b7, 104, 603}, {0x03b9, 105, 329}, {0x03d5, 106, 603}, + {0x03ba, 107, 549}, {0x03bb, 108, 549}, {0x03bc, 109, 576}, + {0x03bd, 110, 521}, {0x03bf, 111, 549}, {0x03c0, 112, 549}, + {0x03b8, 113, 521}, {0x03c1, 114, 549}, {0x03c3, 115, 603}, + {0x03c4, 116, 439}, {0x03c5, 117, 576}, {0x03d6, 118, 713}, + {0x03c9, 119, 686}, {0x03be, 120, 493}, {0x03c8, 121, 686}, + {0x03b6, 122, 494}, {0x007b, 123, 480}, {0x007c, 124, 200}, + {0x007d, 125, 480}, {0x223c, 126, 549}, {0x20ac, 160, 750}, + {0x03d2, 161, 620}, {0x2032, 162, 247}, {0x2264, 163, 549}, + {0x2044, 164, 167}, {0x221e, 165, 713}, {0x0192, 166, 500}, + {0x2663, 167, 753}, {0x2666, 168, 753}, {0x2665, 169, 753}, + {0x2660, 170, 753}, {0x2194, 171, 1042}, {0x2190, 172, 987}, + {0x2191, 173, 603}, {0x2192, 174, 987}, {0x2193, 175, 603}, + {0x00b0, 176, 400}, {0x00b1, 177, 549}, {0x2033, 178, 411}, + {0x2265, 179, 549}, {0x00d7, 180, 549}, {0x221d, 181, 713}, + {0x2202, 182, 494}, {0x2022, 183, 460}, {0x00f7, 184, 549}, + {0x2260, 185, 549}, {0x2261, 186, 549}, {0x2248, 187, 549}, + {0x2026, 188, 1000}, {0xf8e6, 189, 603}, {0xf8e7, 190, 1000}, + {0x21b5, 191, 658}, {0x2135, 192, 823}, {0x2111, 193, 686}, + {0x211c, 194, 795}, {0x2118, 195, 987}, {0x2297, 196, 768}, + {0x2295, 197, 768}, {0x2205, 198, 823}, {0x2229, 199, 768}, + {0x222a, 200, 768}, {0x2283, 201, 713}, {0x2287, 202, 713}, + {0x2284, 203, 713}, {0x2282, 204, 713}, {0x2286, 205, 713}, + {0x2208, 206, 713}, {0x2209, 207, 713}, {0x2220, 208, 768}, + {0x2207, 209, 713}, {0xf6da, 210, 790}, {0xf6d9, 211, 790}, + {0xf6db, 212, 890}, {0x220f, 213, 823}, {0x221a, 214, 549}, + {0x22c5, 215, 250}, {0x00ac, 216, 713}, {0x2227, 217, 603}, + {0x2228, 218, 603}, {0x21d4, 219, 1042}, {0x21d0, 220, 987}, + {0x21d1, 221, 603}, {0x21d2, 222, 987}, {0x21d3, 223, 603}, + {0x25ca, 224, 494}, {0x2329, 225, 329}, {0xf8e8, 226, 790}, + {0xf8e9, 227, 790}, {0xf8ea, 228, 786}, {0x2211, 229, 713}, + {0xf8eb, 230, 384}, {0xf8ec, 231, 384}, {0xf8ed, 232, 384}, + {0xf8ee, 233, 384}, {0xf8ef, 234, 384}, {0xf8f0, 235, 384}, + {0xf8f1, 236, 494}, {0xf8f2, 237, 494}, {0xf8f3, 238, 494}, + {0xf8f4, 239, 494}, {0x232a, 241, 329}, {0x222b, 242, 274}, + {0x2320, 243, 686}, {0xf8f5, 244, 686}, {0x2321, 245, 686}, + {0xf8f6, 246, 384}, {0xf8f7, 247, 384}, {0xf8f8, 248, 384}, + {0xf8f9, 249, 384}, {0xf8fa, 250, 384}, {0xf8fb, 251, 384}, + {0xf8fc, 252, 494}, {0xf8fd, 253, 494}, {0xf8fe, 254, 494}, + {0xf8ff, -1, 790}, {0x0000, -1, 790} +}; + +static const fnt_font_metric fnt_font_metric_09 = +{ + "Symbol", /* FontName */ + 4L, /* flags */ + fnt_Type1, /* font type */ + cc_none, /* Character collection */ + 0.0, /* ItalicAngle */ + 0, /* isFixedPitch */ + -180, /* llx */ + -293, /* lly */ + 1090, /* urx */ + 1010, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 700, /* CapHeight */ + 0, /* xHeight */ + 800, /* Ascender */ + -200, /* Descender */ + 85, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 0, + NULL, + 191, + fnt_glyph_width_09, + +}; + +/* -------- Generated from TIMES.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_10[271] = +{ + {0x0000, 0}, {0x0020, 250}, {0x0021, 333}, {0x0022, 408}, + {0x0023, 500}, {0x0025, 833}, {0x0026, 778}, {0x0027, 180}, + {0x0028, 333}, {0x002A, 500}, {0x002B, 564}, {0x002C, 250}, + {0x002D, 333}, {0x002E, 250}, {0x002F, 278}, {0x0030, 500}, + {0x003A, 278}, {0x003C, 564}, {0x003F, 444}, {0x0040, 921}, + {0x0041, 722}, {0x0042, 667}, {0x0044, 722}, {0x0045, 611}, + {0x0046, 556}, {0x0047, 722}, {0x0049, 333}, {0x004A, 389}, + {0x004B, 722}, {0x004C, 611}, {0x004D, 889}, {0x004E, 722}, + {0x0050, 556}, {0x0051, 722}, {0x0052, 667}, {0x0053, 556}, + {0x0054, 611}, {0x0055, 722}, {0x0057, 944}, {0x0058, 722}, + {0x005A, 611}, {0x005B, 333}, {0x005C, 278}, {0x005D, 333}, + {0x005E, 469}, {0x005F, 500}, {0x0060, 333}, {0x0061, 444}, + {0x0062, 500}, {0x0063, 444}, {0x0064, 500}, {0x0065, 444}, + {0x0066, 333}, {0x0067, 500}, {0x0069, 278}, {0x006B, 500}, + {0x006C, 278}, {0x006D, 778}, {0x006E, 500}, {0x0072, 333}, + {0x0073, 389}, {0x0074, 278}, {0x0075, 500}, {0x0077, 722}, + {0x0078, 500}, {0x007A, 444}, {0x007B, 480}, {0x007C, 200}, + {0x007D, 480}, {0x007E, 541}, {0x007F, 0}, {0x00A0, 250}, + {0x00A1, 333}, {0x00A2, 500}, {0x00A6, 200}, {0x00A7, 500}, + {0x00A8, 333}, {0x00A9, 760}, {0x00AA, 276}, {0x00AB, 500}, + {0x00AC, 564}, {0x00AD, 333}, {0x00AE, 760}, {0x00AF, 500}, + {0x00B0, 400}, {0x00B1, 549}, {0x00B2, 300}, {0x00B4, 333}, + {0x00B5, 576}, {0x00B6, 453}, {0x00B7, 250}, {0x00B8, 333}, + {0x00B9, 300}, {0x00BA, 310}, {0x00BB, 500}, {0x00BC, 750}, + {0x00BF, 444}, {0x00C0, 722}, {0x00C6, 889}, {0x00C7, 667}, + {0x00C8, 611}, {0x00CC, 333}, {0x00D0, 722}, {0x00D7, 564}, + {0x00D8, 722}, {0x00DE, 556}, {0x00DF, 500}, {0x00E0, 444}, + {0x00E6, 667}, {0x00E7, 444}, {0x00EC, 278}, {0x00F0, 500}, + {0x00F7, 549}, {0x00F8, 500}, {0x0100, 722}, {0x0101, 444}, + {0x0102, 722}, {0x0103, 444}, {0x0104, 722}, {0x0105, 444}, + {0x0106, 667}, {0x0107, 444}, {0x0108, 0}, {0x010C, 667}, + {0x010D, 444}, {0x010E, 722}, {0x010F, 646}, {0x0110, 722}, + {0x0111, 500}, {0x0112, 611}, {0x0113, 444}, {0x0114, 0}, + {0x0116, 611}, {0x0117, 444}, {0x0118, 611}, {0x0119, 444}, + {0x011A, 611}, {0x011B, 444}, {0x011C, 0}, {0x011E, 722}, + {0x011F, 500}, {0x0120, 0}, {0x0122, 722}, {0x0123, 500}, + {0x0124, 0}, {0x0128, 333}, {0x0129, 278}, {0x012A, 333}, + {0x012B, 278}, {0x012C, 0}, {0x012E, 333}, {0x012F, 278}, + {0x0130, 333}, {0x0131, 278}, {0x0132, 0}, {0x0136, 722}, + {0x0137, 500}, {0x0139, 611}, {0x013A, 278}, {0x013B, 611}, + {0x013C, 278}, {0x013D, 611}, {0x013E, 406}, {0x013F, 0}, + {0x0141, 611}, {0x0142, 278}, {0x0143, 722}, {0x0144, 500}, + {0x0145, 722}, {0x0146, 500}, {0x0147, 722}, {0x0148, 500}, + {0x0149, 0}, {0x014A, 702}, {0x014B, 495}, {0x014C, 722}, + {0x014D, 500}, {0x014E, 0}, {0x0150, 722}, {0x0151, 500}, + {0x0152, 889}, {0x0153, 722}, {0x0154, 667}, {0x0155, 333}, + {0x0156, 667}, {0x0157, 333}, {0x0158, 667}, {0x0159, 333}, + {0x015A, 556}, {0x015B, 389}, {0x015C, 0}, {0x015E, 556}, + {0x015F, 389}, {0x0160, 556}, {0x0161, 389}, {0x0162, 611}, + {0x0163, 278}, {0x0164, 611}, {0x0165, 427}, {0x0166, 611}, + {0x0167, 278}, {0x0168, 722}, {0x0169, 500}, {0x016A, 722}, + {0x016B, 500}, {0x016C, 0}, {0x016E, 722}, {0x016F, 500}, + {0x0170, 722}, {0x0171, 500}, {0x0172, 722}, {0x0173, 500}, + {0x0174, 0}, {0x0178, 722}, {0x0179, 611}, {0x017A, 444}, + {0x017B, 611}, {0x017C, 444}, {0x017D, 611}, {0x017E, 444}, + {0x017F, 0}, {0x0192, 500}, {0x0193, 0}, {0x0218, 778}, + {0x021A, 611}, {0x021B, 278}, {0x021C, 0}, {0x02C6, 333}, + {0x02C8, 0}, {0x02D8, 333}, {0x02DA, 0}, {0x02DB, 333}, + {0x02DE, 0}, {0x2013, 500}, {0x2014,1000}, {0x2016, 0}, + {0x2018, 333}, {0x201B, 0}, {0x201C, 444}, {0x201F, 0}, + {0x2020, 500}, {0x2022, 350}, {0x2023, 0}, {0x2026,1000}, + {0x2027, 0}, {0x2030,1000}, {0x2031, 0}, {0x2039, 333}, + {0x203B, 0}, {0x20AC, 500}, {0x20AD, 0}, {0x2122, 980}, + {0x2123, 0}, {0x2202, 494}, {0x2203, 0}, {0x2211, 713}, + {0x2212, 564}, {0x2213, 0}, {0x221A, 549}, {0x221B, 0}, + {0x2260, 549}, {0x2261, 0}, {0x2264, 549}, {0x2266, 0}, + {0x25CA, 494}, {0x25CB, 0}, {0xF6C3, 778}, {0xF6C4, 0}, + {0xFB01, 556}, {0xFB03, 0}, {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_10 = +{ + "Times-Roman", + 32L, + fnt_Type1, + cc_none, + 0, + 0, + -568, + -307, + 2000, + 1007, + -109, + 49, + 662, + 450, + 683, + -217, + 88, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 271, + fnt_glyph_width_10, + 0, + NULL, + +}; + +/* -------- Generated from TIMESBD.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_11[284] = +{ + {0x0000, 0}, {0x0020, 250}, {0x0021, 333}, {0x0022, 555}, + {0x0023, 500}, {0x0025,1000}, {0x0026, 833}, {0x0027, 278}, + {0x0028, 333}, {0x002A, 500}, {0x002B, 570}, {0x002C, 250}, + {0x002D, 333}, {0x002E, 250}, {0x002F, 278}, {0x0030, 500}, + {0x003A, 333}, {0x003C, 570}, {0x003F, 500}, {0x0040, 930}, + {0x0041, 722}, {0x0042, 667}, {0x0043, 722}, {0x0045, 667}, + {0x0046, 611}, {0x0047, 778}, {0x0049, 389}, {0x004A, 500}, + {0x004B, 778}, {0x004C, 667}, {0x004D, 944}, {0x004E, 722}, + {0x004F, 778}, {0x0050, 611}, {0x0051, 778}, {0x0052, 722}, + {0x0053, 556}, {0x0054, 667}, {0x0055, 722}, {0x0057,1000}, + {0x0058, 722}, {0x005A, 667}, {0x005B, 333}, {0x005C, 278}, + {0x005D, 333}, {0x005E, 581}, {0x005F, 500}, {0x0060, 333}, + {0x0061, 500}, {0x0062, 556}, {0x0063, 444}, {0x0064, 556}, + {0x0065, 444}, {0x0066, 333}, {0x0067, 500}, {0x0068, 556}, + {0x0069, 278}, {0x006A, 333}, {0x006B, 556}, {0x006C, 278}, + {0x006D, 833}, {0x006E, 556}, {0x006F, 500}, {0x0070, 556}, + {0x0072, 444}, {0x0073, 389}, {0x0074, 333}, {0x0075, 556}, + {0x0076, 500}, {0x0077, 722}, {0x0078, 500}, {0x007A, 444}, + {0x007B, 394}, {0x007C, 220}, {0x007D, 394}, {0x007E, 520}, + {0x007F, 0}, {0x00A0, 250}, {0x00A1, 333}, {0x00A2, 500}, + {0x00A6, 220}, {0x00A7, 500}, {0x00A8, 333}, {0x00A9, 747}, + {0x00AA, 300}, {0x00AB, 500}, {0x00AC, 570}, {0x00AD, 333}, + {0x00AE, 747}, {0x00AF, 500}, {0x00B0, 400}, {0x00B1, 549}, + {0x00B2, 300}, {0x00B4, 333}, {0x00B5, 576}, {0x00B6, 540}, + {0x00B7, 250}, {0x00B8, 333}, {0x00B9, 300}, {0x00BA, 330}, + {0x00BB, 500}, {0x00BC, 750}, {0x00BF, 500}, {0x00C0, 722}, + {0x00C6,1000}, {0x00C7, 722}, {0x00C8, 667}, {0x00CC, 389}, + {0x00D0, 722}, {0x00D2, 778}, {0x00D7, 570}, {0x00D8, 778}, + {0x00D9, 722}, {0x00DE, 611}, {0x00DF, 556}, {0x00E0, 500}, + {0x00E6, 722}, {0x00E7, 444}, {0x00EC, 278}, {0x00F0, 500}, + {0x00F1, 556}, {0x00F2, 500}, {0x00F7, 549}, {0x00F8, 500}, + {0x00F9, 556}, {0x00FD, 500}, {0x00FE, 556}, {0x00FF, 500}, + {0x0100, 722}, {0x0101, 500}, {0x0102, 722}, {0x0103, 500}, + {0x0104, 722}, {0x0105, 500}, {0x0106, 722}, {0x0107, 444}, + {0x0108, 0}, {0x010C, 722}, {0x010D, 444}, {0x010E, 722}, + {0x010F, 733}, {0x0110, 722}, {0x0111, 556}, {0x0112, 667}, + {0x0113, 444}, {0x0114, 0}, {0x0116, 667}, {0x0117, 444}, + {0x0118, 667}, {0x0119, 444}, {0x011A, 667}, {0x011B, 444}, + {0x011C, 0}, {0x011E, 778}, {0x011F, 500}, {0x0120, 0}, + {0x0122, 778}, {0x0123, 500}, {0x0124, 0}, {0x0128, 389}, + {0x0129, 278}, {0x012A, 389}, {0x012B, 278}, {0x012C, 0}, + {0x012E, 389}, {0x012F, 278}, {0x0130, 389}, {0x0131, 278}, + {0x0132, 0}, {0x0136, 778}, {0x0137, 556}, {0x0139, 667}, + {0x013A, 278}, {0x013B, 667}, {0x013C, 278}, {0x013D, 667}, + {0x013E, 469}, {0x013F, 0}, {0x0141, 667}, {0x0142, 278}, + {0x0143, 722}, {0x0144, 556}, {0x0145, 722}, {0x0146, 556}, + {0x0147, 722}, {0x0148, 556}, {0x0149, 0}, {0x014A, 769}, + {0x014B, 556}, {0x014C, 778}, {0x014D, 500}, {0x014E, 0}, + {0x0150, 778}, {0x0151, 500}, {0x0152,1000}, {0x0153, 722}, + {0x0155, 444}, {0x0156, 722}, {0x0157, 444}, {0x0158, 722}, + {0x0159, 444}, {0x015A, 556}, {0x015B, 389}, {0x015C, 0}, + {0x015E, 556}, {0x015F, 389}, {0x0160, 556}, {0x0161, 389}, + {0x0162, 667}, {0x0163, 333}, {0x0164, 667}, {0x0165, 521}, + {0x0166, 667}, {0x0167, 333}, {0x0168, 722}, {0x0169, 556}, + {0x016A, 722}, {0x016B, 556}, {0x016C, 0}, {0x016E, 722}, + {0x016F, 556}, {0x0170, 722}, {0x0171, 556}, {0x0172, 722}, + {0x0173, 556}, {0x0174, 0}, {0x0178, 722}, {0x0179, 667}, + {0x017A, 444}, {0x017B, 667}, {0x017C, 444}, {0x017D, 667}, + {0x017E, 444}, {0x017F, 0}, {0x0192, 500}, {0x0193, 0}, + {0x0218, 778}, {0x021A, 667}, {0x021B, 333}, {0x021C, 0}, + {0x02C6, 333}, {0x02C8, 0}, {0x02D8, 333}, {0x02DA, 0}, + {0x02DB, 333}, {0x02DE, 0}, {0x2013, 500}, {0x2014,1000}, + {0x2016, 0}, {0x2018, 333}, {0x201B, 0}, {0x201C, 500}, + {0x201F, 0}, {0x2020, 500}, {0x2022, 350}, {0x2023, 0}, + {0x2026,1000}, {0x2027, 0}, {0x2030,1000}, {0x2031, 0}, + {0x2039, 333}, {0x203B, 0}, {0x20AC, 500}, {0x20AD, 0}, + {0x2122,1000}, {0x2123, 0}, {0x2202, 494}, {0x2203, 0}, + {0x2211, 713}, {0x2212, 570}, {0x2213, 0}, {0x221A, 549}, + {0x221B, 0}, {0x2260, 549}, {0x2261, 0}, {0x2264, 549}, + {0x2266, 0}, {0x25CA, 494}, {0x25CB, 0}, {0xF6C3, 778}, + {0xF6C4, 0}, {0xFB01, 556}, {0xFB03, 0}, {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_11 = +{ + "Times-Bold", + 262176L, + fnt_Type1, + cc_none, + 0, + 0, + -558, + -307, + 2000, + 1026, + -109, + 95, + 676, + 461, + 683, + -217, + 166, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 284, + fnt_glyph_width_11, + 0, + NULL, + +}; + +/* -------- Generated from TIMESI.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_12[276] = +{ + {0x0000, 0}, {0x0020, 250}, {0x0021, 333}, {0x0022, 420}, + {0x0023, 500}, {0x0025, 833}, {0x0026, 778}, {0x0027, 214}, + {0x0028, 333}, {0x002A, 500}, {0x002B, 675}, {0x002C, 250}, + {0x002D, 333}, {0x002E, 250}, {0x002F, 278}, {0x0030, 500}, + {0x003A, 333}, {0x003C, 675}, {0x003F, 500}, {0x0040, 920}, + {0x0041, 611}, {0x0043, 667}, {0x0044, 722}, {0x0045, 611}, + {0x0047, 722}, {0x0049, 333}, {0x004A, 444}, {0x004B, 667}, + {0x004C, 556}, {0x004D, 833}, {0x004E, 667}, {0x004F, 722}, + {0x0050, 611}, {0x0051, 722}, {0x0052, 611}, {0x0053, 500}, + {0x0054, 556}, {0x0055, 722}, {0x0056, 611}, {0x0057, 833}, + {0x0058, 611}, {0x0059, 556}, {0x005B, 389}, {0x005C, 278}, + {0x005D, 389}, {0x005E, 422}, {0x005F, 500}, {0x0060, 333}, + {0x0061, 500}, {0x0063, 444}, {0x0064, 500}, {0x0065, 444}, + {0x0066, 278}, {0x0067, 500}, {0x0069, 278}, {0x006B, 444}, + {0x006C, 278}, {0x006D, 722}, {0x006E, 500}, {0x0072, 389}, + {0x0074, 278}, {0x0075, 500}, {0x0076, 444}, {0x0077, 667}, + {0x0078, 444}, {0x007A, 389}, {0x007B, 400}, {0x007C, 275}, + {0x007D, 400}, {0x007E, 541}, {0x007F, 0}, {0x00A0, 250}, + {0x00A1, 389}, {0x00A2, 500}, {0x00A6, 275}, {0x00A7, 500}, + {0x00A8, 333}, {0x00A9, 760}, {0x00AA, 276}, {0x00AB, 500}, + {0x00AC, 675}, {0x00AD, 333}, {0x00AE, 760}, {0x00AF, 500}, + {0x00B0, 400}, {0x00B1, 549}, {0x00B2, 300}, {0x00B4, 333}, + {0x00B5, 576}, {0x00B6, 523}, {0x00B7, 250}, {0x00B8, 333}, + {0x00B9, 300}, {0x00BA, 310}, {0x00BB, 500}, {0x00BC, 750}, + {0x00BF, 500}, {0x00C0, 611}, {0x00C6, 889}, {0x00C7, 667}, + {0x00C8, 611}, {0x00CC, 333}, {0x00D0, 722}, {0x00D1, 667}, + {0x00D2, 722}, {0x00D7, 675}, {0x00D8, 722}, {0x00DD, 556}, + {0x00DE, 611}, {0x00DF, 500}, {0x00E6, 667}, {0x00E7, 444}, + {0x00EC, 278}, {0x00F0, 500}, {0x00F7, 549}, {0x00F8, 500}, + {0x00FD, 444}, {0x00FE, 500}, {0x00FF, 444}, {0x0100, 611}, + {0x0101, 500}, {0x0102, 611}, {0x0103, 500}, {0x0104, 611}, + {0x0105, 500}, {0x0106, 667}, {0x0107, 444}, {0x0108, 0}, + {0x010C, 667}, {0x010D, 444}, {0x010E, 722}, {0x010F, 608}, + {0x0110, 722}, {0x0111, 500}, {0x0112, 611}, {0x0113, 444}, + {0x0114, 0}, {0x0116, 611}, {0x0117, 444}, {0x0118, 611}, + {0x0119, 444}, {0x011A, 611}, {0x011B, 444}, {0x011C, 0}, + {0x011E, 722}, {0x011F, 500}, {0x0120, 0}, {0x0122, 722}, + {0x0123, 500}, {0x0124, 0}, {0x0128, 333}, {0x0129, 278}, + {0x012A, 333}, {0x012B, 278}, {0x012C, 0}, {0x012E, 333}, + {0x012F, 278}, {0x0130, 333}, {0x0131, 278}, {0x0132, 0}, + {0x0136, 667}, {0x0137, 444}, {0x0139, 556}, {0x013A, 278}, + {0x013B, 556}, {0x013C, 278}, {0x013D, 556}, {0x013E, 364}, + {0x013F, 0}, {0x0141, 556}, {0x0142, 278}, {0x0143, 667}, + {0x0144, 500}, {0x0145, 667}, {0x0146, 500}, {0x0147, 667}, + {0x0148, 500}, {0x0149, 0}, {0x014A, 696}, {0x014B, 482}, + {0x014C, 722}, {0x014D, 500}, {0x014E, 0}, {0x0150, 722}, + {0x0151, 500}, {0x0152, 944}, {0x0153, 667}, {0x0154, 611}, + {0x0155, 389}, {0x0156, 611}, {0x0157, 389}, {0x0158, 611}, + {0x0159, 389}, {0x015A, 500}, {0x015B, 389}, {0x015C, 0}, + {0x015E, 500}, {0x015F, 389}, {0x0160, 500}, {0x0161, 389}, + {0x0162, 556}, {0x0163, 278}, {0x0164, 556}, {0x0165, 364}, + {0x0166, 556}, {0x0167, 278}, {0x0168, 722}, {0x0169, 500}, + {0x016A, 722}, {0x016B, 500}, {0x016C, 0}, {0x016E, 722}, + {0x016F, 500}, {0x0170, 722}, {0x0171, 500}, {0x0172, 722}, + {0x0173, 500}, {0x0174, 0}, {0x0178, 556}, {0x017A, 389}, + {0x017B, 556}, {0x017C, 389}, {0x017D, 556}, {0x017E, 389}, + {0x017F, 0}, {0x0192, 500}, {0x0193, 0}, {0x0218, 778}, + {0x021A, 556}, {0x021B, 278}, {0x021C, 0}, {0x02C6, 333}, + {0x02C8, 0}, {0x02D8, 333}, {0x02DA, 0}, {0x02DB, 333}, + {0x02DE, 0}, {0x2013, 500}, {0x2014, 889}, {0x2015,1000}, + {0x2016, 0}, {0x2018, 333}, {0x201B, 0}, {0x201C, 556}, + {0x201F, 0}, {0x2020, 500}, {0x2022, 350}, {0x2023, 0}, + {0x2026, 889}, {0x2027, 0}, {0x2030,1000}, {0x2031, 0}, + {0x2039, 333}, {0x203B, 0}, {0x20AC, 500}, {0x20AD, 0}, + {0x2122, 980}, {0x2123, 0}, {0x2202, 494}, {0x2203, 0}, + {0x2211, 713}, {0x2212, 675}, {0x2213, 0}, {0x221A, 549}, + {0x221B, 0}, {0x2260, 549}, {0x2261, 0}, {0x2264, 549}, + {0x2266, 0}, {0x25CA, 494}, {0x25CB, 0}, {0xF6C3, 778}, + {0xF6C4, 0}, {0xFB01, 500}, {0xFB03, 0}, {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_12 = +{ + "Times-Italic", + 96L, + fnt_Type1, + cc_none, + -16.333, + 0, + -498, + -307, + 1120, + 1023, + -109, + 49, + 653, + 441, + 683, + -217, + 88, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 276, + fnt_glyph_width_12, + 0, + NULL, + +}; + +/* -------- Generated from TIMESBI.TTF -------- */ + +static fnt_interwidth fnt_glyph_width_13[275] = +{ + {0x0000, 0}, {0x0020, 250}, {0x0021, 389}, {0x0022, 555}, + {0x0023, 500}, {0x0025, 833}, {0x0026, 778}, {0x0027, 278}, + {0x0028, 333}, {0x002A, 500}, {0x002B, 570}, {0x002C, 250}, + {0x002D, 333}, {0x002E, 250}, {0x002F, 278}, {0x0030, 500}, + {0x003A, 333}, {0x003C, 570}, {0x003F, 500}, {0x0040, 832}, + {0x0041, 667}, {0x0044, 722}, {0x0045, 667}, {0x0047, 722}, + {0x0048, 778}, {0x0049, 389}, {0x004A, 500}, {0x004B, 667}, + {0x004C, 611}, {0x004D, 889}, {0x004E, 722}, {0x0050, 611}, + {0x0051, 722}, {0x0052, 667}, {0x0053, 556}, {0x0054, 611}, + {0x0055, 722}, {0x0056, 667}, {0x0057, 889}, {0x0058, 667}, + {0x0059, 611}, {0x005B, 333}, {0x005C, 278}, {0x005D, 333}, + {0x005E, 570}, {0x005F, 500}, {0x0060, 333}, {0x0061, 500}, + {0x0063, 444}, {0x0064, 500}, {0x0065, 444}, {0x0066, 333}, + {0x0067, 500}, {0x0068, 556}, {0x0069, 278}, {0x006B, 500}, + {0x006C, 278}, {0x006D, 778}, {0x006E, 556}, {0x006F, 500}, + {0x0072, 389}, {0x0074, 278}, {0x0075, 556}, {0x0076, 444}, + {0x0077, 667}, {0x0078, 500}, {0x0079, 444}, {0x007A, 389}, + {0x007B, 348}, {0x007C, 220}, {0x007D, 348}, {0x007E, 570}, + {0x007F, 0}, {0x00A0, 250}, {0x00A1, 389}, {0x00A2, 500}, + {0x00A6, 220}, {0x00A7, 500}, {0x00A8, 333}, {0x00A9, 747}, + {0x00AA, 266}, {0x00AB, 500}, {0x00AC, 606}, {0x00AD, 333}, + {0x00AE, 747}, {0x00AF, 500}, {0x00B0, 400}, {0x00B1, 549}, + {0x00B2, 300}, {0x00B4, 333}, {0x00B5, 576}, {0x00B6, 500}, + {0x00B7, 250}, {0x00B8, 333}, {0x00B9, 300}, {0x00BB, 500}, + {0x00BC, 750}, {0x00BF, 500}, {0x00C0, 667}, {0x00C6, 944}, + {0x00C7, 667}, {0x00CC, 389}, {0x00D0, 722}, {0x00D7, 570}, + {0x00D8, 722}, {0x00DD, 611}, {0x00DF, 500}, {0x00E6, 722}, + {0x00E7, 444}, {0x00EC, 278}, {0x00F0, 500}, {0x00F1, 556}, + {0x00F2, 500}, {0x00F7, 549}, {0x00F8, 500}, {0x00F9, 556}, + {0x00FD, 444}, {0x00FE, 500}, {0x00FF, 444}, {0x0100, 667}, + {0x0101, 500}, {0x0102, 667}, {0x0103, 500}, {0x0104, 667}, + {0x0105, 500}, {0x0106, 667}, {0x0107, 444}, {0x0108, 0}, + {0x010C, 667}, {0x010D, 444}, {0x010E, 722}, {0x010F, 749}, + {0x0110, 722}, {0x0111, 500}, {0x0112, 667}, {0x0113, 444}, + {0x0114, 0}, {0x0116, 667}, {0x0117, 444}, {0x0118, 667}, + {0x0119, 444}, {0x011A, 667}, {0x011B, 444}, {0x011C, 0}, + {0x011E, 722}, {0x011F, 500}, {0x0120, 0}, {0x0122, 722}, + {0x0123, 500}, {0x0124, 0}, {0x0128, 389}, {0x0129, 278}, + {0x012A, 389}, {0x012B, 278}, {0x012C, 0}, {0x012E, 389}, + {0x012F, 278}, {0x0130, 389}, {0x0131, 278}, {0x0132, 0}, + {0x0136, 667}, {0x0137, 500}, {0x0139, 611}, {0x013A, 278}, + {0x013B, 611}, {0x013C, 278}, {0x013D, 611}, {0x013E, 521}, + {0x013F, 0}, {0x0141, 611}, {0x0142, 278}, {0x0143, 722}, + {0x0144, 556}, {0x0145, 722}, {0x0146, 556}, {0x0147, 722}, + {0x0148, 556}, {0x0149, 0}, {0x014A, 784}, {0x014B, 541}, + {0x014C, 722}, {0x014D, 500}, {0x014E, 0}, {0x0150, 722}, + {0x0151, 500}, {0x0152, 944}, {0x0153, 722}, {0x0154, 667}, + {0x0155, 389}, {0x0156, 667}, {0x0157, 389}, {0x0158, 667}, + {0x0159, 389}, {0x015A, 556}, {0x015B, 389}, {0x015C, 0}, + {0x015E, 556}, {0x015F, 389}, {0x0160, 556}, {0x0161, 389}, + {0x0162, 611}, {0x0163, 278}, {0x0164, 611}, {0x0165, 531}, + {0x0166, 611}, {0x0167, 278}, {0x0168, 722}, {0x0169, 556}, + {0x016A, 722}, {0x016B, 556}, {0x016C, 0}, {0x016E, 722}, + {0x016F, 556}, {0x0170, 722}, {0x0171, 556}, {0x0172, 722}, + {0x0173, 556}, {0x0174, 0}, {0x0178, 611}, {0x017A, 389}, + {0x017B, 611}, {0x017C, 389}, {0x017D, 611}, {0x017E, 389}, + {0x017F, 0}, {0x0192, 500}, {0x0193, 0}, {0x0218, 778}, + {0x021A, 611}, {0x021B, 278}, {0x021C, 0}, {0x02C6, 333}, + {0x02C8, 0}, {0x02D8, 333}, {0x02DA, 0}, {0x02DB, 333}, + {0x02DE, 0}, {0x2013, 500}, {0x2014,1000}, {0x2016, 0}, + {0x2018, 333}, {0x201B, 0}, {0x201C, 500}, {0x201F, 0}, + {0x2020, 500}, {0x2022, 350}, {0x2023, 0}, {0x2026,1000}, + {0x2027, 0}, {0x2030,1000}, {0x2031, 0}, {0x2039, 333}, + {0x203B, 0}, {0x20AC, 500}, {0x20AD, 0}, {0x2122,1000}, + {0x2123, 0}, {0x2202, 494}, {0x2203, 0}, {0x2211, 713}, + {0x2212, 606}, {0x2213, 0}, {0x221A, 549}, {0x221B, 0}, + {0x2260, 549}, {0x2261, 0}, {0x2264, 549}, {0x2266, 0}, + {0x25CA, 494}, {0x25CB, 0}, {0xF6C3, 778}, {0xF6C4, 0}, + {0xFB01, 556}, {0xFB03, 0}, {0xFFFF, 0} +}; + + +static const fnt_font_metric fnt_font_metric_13 = +{ + "Times-BoldItalic", + 262240L, + fnt_Type1, + cc_none, + -16.333, + 0, + -547, + -307, + 1206, + 1032, + -109, + 95, + 669, + 462, + 683, + -217, + 166, + 0, + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 275, + fnt_glyph_width_13, + 0, + NULL, + +}; + +/* -------- Generated from ZapfDingbats.afm -------- */ + +static fnt_glyphwidth fnt_glyph_width_14[202] = +{ + {0x0020, 32, 278}, {0x2701, 33, 974}, {0x2702, 34, 961}, + {0x2703, 35, 974}, {0x2704, 36, 980}, {0x260e, 37, 719}, + {0x2706, 38, 789}, {0x2707, 39, 790}, {0x2708, 40, 791}, + {0x2709, 41, 690}, {0x261b, 42, 960}, {0x261e, 43, 939}, + {0x270c, 44, 549}, {0x270d, 45, 855}, {0x270e, 46, 911}, + {0x270f, 47, 933}, {0x2710, 48, 911}, {0x2711, 49, 945}, + {0x2712, 50, 974}, {0x2713, 51, 755}, {0x2714, 52, 846}, + {0x2715, 53, 762}, {0x2716, 54, 761}, {0x2717, 55, 571}, + {0x2718, 56, 677}, {0x2719, 57, 763}, {0x271a, 58, 760}, + {0x271b, 59, 759}, {0x271c, 60, 754}, {0x271d, 61, 494}, + {0x271e, 62, 552}, {0x271f, 63, 537}, {0x2720, 64, 577}, + {0x2721, 65, 692}, {0x2722, 66, 786}, {0x2723, 67, 788}, + {0x2724, 68, 788}, {0x2725, 69, 790}, {0x2726, 70, 793}, + {0x2727, 71, 794}, {0x2605, 72, 816}, {0x2729, 73, 823}, + {0x272a, 74, 789}, {0x272b, 75, 841}, {0x272c, 76, 823}, + {0x272d, 77, 833}, {0x272e, 78, 816}, {0x272f, 79, 831}, + {0x2730, 80, 923}, {0x2731, 81, 744}, {0x2732, 82, 723}, + {0x2733, 83, 749}, {0x2734, 84, 790}, {0x2735, 85, 792}, + {0x2736, 86, 695}, {0x2737, 87, 776}, {0x2738, 88, 768}, + {0x2739, 89, 792}, {0x273a, 90, 759}, {0x273b, 91, 707}, + {0x273c, 92, 708}, {0x273d, 93, 682}, {0x273e, 94, 701}, + {0x273f, 95, 826}, {0x2740, 96, 815}, {0x2741, 97, 789}, + {0x2742, 98, 789}, {0x2743, 99, 707}, {0x2744, 100, 687}, + {0x2745, 101, 696}, {0x2746, 102, 689}, {0x2747, 103, 786}, + {0x2748, 104, 787}, {0x2749, 105, 713}, {0x274a, 106, 791}, + {0x274b, 107, 785}, {0x25cf, 108, 791}, {0x274d, 109, 873}, + {0x25a0, 110, 761}, {0x274f, 111, 762}, {0x2750, 112, 762}, + {0x2751, 113, 759}, {0x2752, 114, 759}, {0x25b2, 115, 892}, + {0x25bc, 116, 892}, {0x25c6, 117, 788}, {0x2756, 118, 784}, + {0x25d7, 119, 438}, {0x2758, 120, 138}, {0x2759, 121, 277}, + {0x275a, 122, 415}, {0x275b, 123, 392}, {0x275c, 124, 392}, + {0x275d, 125, 668}, {0x275e, 126, 668}, {0x2768, 128, 390}, + {0x2769, 129, 390}, {0x276a, 130, 317}, {0x276b, 131, 317}, + {0x276c, 132, 276}, {0x276d, 133, 276}, {0x276e, 134, 509}, + {0x276f, 135, 509}, {0x2770, 136, 410}, {0x2771, 137, 410}, + {0x2772, 138, 234}, {0x2773, 139, 234}, {0x2774, 140, 334}, + {0x2775, 141, 334}, {0x2761, 161, 732}, {0x2762, 162, 544}, + {0x2763, 163, 544}, {0x2764, 164, 910}, {0x2765, 165, 667}, + {0x2766, 166, 760}, {0x2767, 167, 760}, {0x2663, 168, 776}, + {0x2666, 169, 595}, {0x2665, 170, 694}, {0x2660, 171, 626}, + {0x2460, 172, 788}, {0x2461, 173, 788}, {0x2462, 174, 788}, + {0x2463, 175, 788}, {0x2464, 176, 788}, {0x2465, 177, 788}, + {0x2466, 178, 788}, {0x2467, 179, 788}, {0x2468, 180, 788}, + {0x2469, 181, 788}, {0x2776, 182, 788}, {0x2777, 183, 788}, + {0x2778, 184, 788}, {0x2779, 185, 788}, {0x277a, 186, 788}, + {0x277b, 187, 788}, {0x277c, 188, 788}, {0x277d, 189, 788}, + {0x277e, 190, 788}, {0x277f, 191, 788}, {0x2780, 192, 788}, + {0x2781, 193, 788}, {0x2782, 194, 788}, {0x2783, 195, 788}, + {0x2784, 196, 788}, {0x2785, 197, 788}, {0x2786, 198, 788}, + {0x2787, 199, 788}, {0x2788, 200, 788}, {0x2789, 201, 788}, + {0x278a, 202, 788}, {0x278b, 203, 788}, {0x278c, 204, 788}, + {0x278d, 205, 788}, {0x278e, 206, 788}, {0x278f, 207, 788}, + {0x2790, 208, 788}, {0x2791, 209, 788}, {0x2792, 210, 788}, + {0x2793, 211, 788}, {0x2794, 212, 894}, {0x2192, 213, 838}, + {0x2194, 214, 1016}, {0x2195, 215, 458}, {0x2798, 216, 748}, + {0x2799, 217, 924}, {0x279a, 218, 748}, {0x279b, 219, 918}, + {0x279c, 220, 927}, {0x279d, 221, 928}, {0x279e, 222, 928}, + {0x279f, 223, 834}, {0x27a0, 224, 873}, {0x27a1, 225, 828}, + {0x27a2, 226, 924}, {0x27a3, 227, 924}, {0x27a4, 228, 917}, + {0x27a5, 229, 930}, {0x27a6, 230, 931}, {0x27a7, 231, 463}, + {0x27a8, 232, 883}, {0x27a9, 233, 836}, {0x27aa, 234, 836}, + {0x27ab, 235, 867}, {0x27ac, 236, 867}, {0x27ad, 237, 696}, + {0x27ae, 238, 696}, {0x27af, 239, 874}, {0x27b1, 241, 874}, + {0x27b2, 242, 760}, {0x27b3, 243, 946}, {0x27b4, 244, 771}, + {0x27b5, 245, 865}, {0x27b6, 246, 771}, {0x27b7, 247, 888}, + {0x27b8, 248, 967}, {0x27b9, 249, 888}, {0x27ba, 250, 831}, + {0x27bb, 251, 873}, {0x27bc, 252, 927}, {0x27bd, 253, 970}, + {0x27be, 254, 918}, + +}; + +static const fnt_font_metric fnt_font_metric_14 = +{ + "ZapfDingbats", /* FontName */ + 4L, /* flags */ + fnt_Type1, /* font type */ + cc_none, /* Character collection */ + 0.0, /* ItalicAngle */ + 0, /* isFixedPitch */ + -1, /* llx */ + -143, /* lly */ + 981, /* urx */ + 820, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 700, /* CapHeight */ + 0, /* xHeight */ + 800, /* Ascender */ + -200, /* Descender */ + 90, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_WIDTH, + 0, + NULL, + 0, + NULL, + 202, + fnt_glyph_width_14, + +}; + +#endif /* PDF_BUILTINMETRIC_SUPPORTED */ + + +/* --------------------- Pre-installed CID fonts ---------------------- */ + +/* Font descriptors for the pre-installed CID fonts */ + +static const fnt_font_metric fnt_cid_metrics[] = +{ + + /* Acrobat 4 standard fonts */ + /* ---------------------------------------------------------- */ + { + "HeiseiKakuGo-W5", /* FontName */ + 4L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + -1 * (int) cc_japanese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -92, /* llx */ + -250, /* lly */ + 1010, /* urx */ + 922, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -221, /* Descender */ + 114, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "HeiseiMin-W3", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + -1 * (int) cc_japanese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -123, /* llx */ + -257, /* lly */ + 1001, /* urx */ + 910, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 709, /* CapHeight */ + 450, /* xHeight */ + 723, /* Ascender */ + -241, /* Descender */ + 69, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "HYGoThic-Medium", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_korean, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -6, /* llx */ + -145, /* lly */ + 1003, /* urx */ + 880, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "HYSMyeongJo-Medium", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_korean, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -0, /* llx */ + -148, /* lly */ + 1001, /* urx */ + 880, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "MHei-Medium", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_traditional_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -45, /* llx */ + -250, /* lly */ + 1015, /* urx */ + 887, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "MSung-Light", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_traditional_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -160, /* llx */ + -259, /* lly */ + 1015, /* urx */ + 888, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "STSong-Light", /* FontName */ + 4L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_simplified_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -250, /* llx */ + -143, /* lly */ + 600, /* urx */ + 857, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 857, /* CapHeight */ + 599, /* xHeight */ + 857, /* Ascender */ + -143, /* Descender */ + 91, /* StdVW */ + 91, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* Acrobat 5 standard fonts */ + /* ---------------------------------------------------------- */ + { + "HYSMyeongJoStd-Medium-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_korean, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -28, /* llx */ + -148, /* lly */ + 1001, /* urx */ + 880, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "KozMinPro-Regular-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_japanese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -195, /* llx */ + -272, /* lly */ + 1110, /* urx */ + 1075, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "MSungStd-Light-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_traditional_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -160, /* llx */ + -249, /* lly */ + 1015, /* urx */ + 1071, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 553, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "STSongStd-Light-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_simplified_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -134, /* llx */ + -254, /* lly */ + 1001, /* urx */ + 905, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 737, /* CapHeight */ + 535, /* xHeight */ + 752, /* Ascender */ + -271, /* Descender */ + 58, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* Acrobat 6 standard fonts */ + /* ---------------------------------------------------------- */ + { + "AdobeMingStd-Light-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_traditional_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -38, /* llx */ + -121, /* lly */ + 1002, /* urx */ + 1002, /* ury */ + -75, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 731, /* CapHeight */ + 466, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 71, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "AdobeMyungjoStd-Medium-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_korean, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -28, /* llx */ + -148, /* lly */ + 1001, /* urx */ + 1001, /* ury */ + -75, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 719, /* CapHeight */ + 478, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 109, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "AdobeSongStd-Light-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_simplified_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -134, /* llx */ + -254, /* lly */ + 1001, /* urx */ + 1001, /* ury */ + -75, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 626, /* CapHeight */ + 416, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 71, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "KozGoPro-Medium-Acro", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_japanese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -149, /* llx */ + -374, /* lly */ + 1254, /* urx */ + 1008, /* ury */ + -75, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 763, /* CapHeight */ + 549, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 109, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* Acrobat 7 standard fonts */ + /* ---------------------------------------------------------- */ + { + "KozGoPro-Medium", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_japanese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -149, /* llx */ + -374, /* lly */ + 1254, /* urx */ + 1008, /* ury */ + -75, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 763, /* CapHeight */ + 549, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 109, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "KozMinProVI-Regular", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_japanese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -437, /* llx */ + -340, /* lly */ + 1144, /* urx */ + 1317, /* ury */ + -75, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 742, /* CapHeight */ + 503, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 87, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "AdobeMyungjoStd-Medium", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_korean, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -28, /* llx */ + -148, /* lly */ + 1001, /* urx */ + 880, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 719, /* CapHeight */ + 478, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 109, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "AdobeSongStd-Light", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_simplified_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -134, /* llx */ + -254, /* lly */ + 1001, /* urx */ + 905, /* ury */ + -100, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 626, /* CapHeight */ + 416, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 71, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + }, + + /* ---------------------------------------------------------- */ + { + "AdobeMingStd-Light", /* FontName */ + 6L, /* Font flags */ + fnt_CIDFontType0, /* font type */ + (int) cc_traditional_chinese, /* Character collection */ + 0.0, /* ItalicAngle */ + pdc_true, /* isFixedPitch */ + -38, /* llx */ + -121, /* lly */ + 1002, /* urx */ + 918, /* ury */ + -75, /* UnderlinePosition */ + 50, /* UnderlineThickness */ + 731, /* CapHeight */ + 466, /* xHeight */ + 880, /* Ascender */ + -120, /* Descender */ + 71, /* StdVW */ + 0, /* StdHW */ + + FNT_DEFAULT_CIDWIDTH, + 0, + NULL, + + 0, + NULL, + + 0, + (fnt_glyphwidth *) NULL, + + } +}; + +#define FNT_NUM_OF_CIDFONTS \ + ((int) (sizeof(fnt_cid_metrics)/sizeof(fnt_font_metric))) + + +#ifdef PDF_CJKFONTWIDTHS_SUPPORTED + +/* + * PDF width arrays for glyph widths indexed by CID + * of Acrobat CJK standard fonts (see above). + * + * Format: + * + * 1 font name string, + * 4 strings for widths + * --- + * 5 (see define FNT_CIDMETRIC_INCR in ft_cid.h) + * + * Because of compiler warnings each width block must + * be divided at least into 4 parts. + * + */ + +static const char *fnt_cid_width_arrays[] = +{ + /*------------------------------------------------------------------------*/ + "HeiseiKakuGo-W5", + + "1[278 278 355 556 556 889 667 191 333 333 389 584 278 333 278\n" + "278 556 556 556 556 556 556 556 556 556 556 278 278 584 584 584\n" + "556 1015 667 667 722 722 667 611 778 722 278 500 667 556 833 722\n" + "778 667 778 722 667 611 722 667 944 667 667 611 278 556 278 469\n" + "556 333 556 556 500 556 556 278 556 556 222 222 500 222 833 556\n", + + "556 556 556 333 500 278 556 500 722 500 500 500 334 260 334 333\n" + "1000 278 1000 260 1000 333 556 556 167 1000 1000 556 1000 556 333 333\n" + "500 500 556 1000 1000 278 1000 350 222 333 1000 556 1000 1000 611]\n" + "127 137 333\n" + "140[370 556 778 1000\n", + + "365 889 278 222 611 944 611 584 737 584 737 1000 1000 333 333 556\n" + "333 834 834 834 667 667 667 667 667 667 722 667 667 667 667 278\n" + "278 278 278 722 722 778 778 778 778 778 1000 722 722 722 722 667\n" + "667 556 556 556 556 556 556 500 556 556 556 556 278 278 278 278\n", + + "556 556 556 556 556 556 556 1000 556 556 556 556 500 556 500 667\n" + "667 611 556 500 1000 500 556]\n" + "231 632 500\n" + "8718 8719 500", + + + /*------------------------------------------------------------------------*/ + "HeiseiMin-W3", + + "1[250 333 408 500 500 833 778 180 333 333 500 564 250 333 250\n" + "278 500 500 500 500 500 500 500 500 500 500 278 278 564 564 564\n" + "444 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722\n" + "722 556 722 667 556 611 722 722 944 722 722 611 333 500 333 469\n" + "500 333 444 500 444 500 444 333 500 500 278 278 500 278 778 500\n", + + "500 500 500 333 389 278 500 500 722 500 500 444 480 200 480 333\n" + "1000 278 1000 200 1000 333 500 500 167 1000 1000 500 1000 500 333 333\n" + "556 556 500 1000 1000 250 1000 350 333 444 1000 500 1000 1000 444]\n" + "127 137 333\n", + + "139[889 276 611 722 889\n" + "310 667 278 278 500 722 500 564 760 564 760 1000 1000 300 300 500\n" + "300 750 750 750 722 722 722 722 722 722 667 611 611 611 611 333\n" + "333 333 333 722 722 722 722 722 722 722 1000 722 722 722 722 722\n" + "556 444 444 444 444 444 444 444 444 444 444 444 278 278 278 278\n", + + "500 500 500 500 500 500 500 1000 500 500 500 500 500 500 500 556\n" + "722 611 500 389 980 444]\n" + "230 632 500\n" + "8718 8719 500", + + + /*------------------------------------------------------------------------*/ + "HYGoThic-Medium", + + "1[333 416 416 833 666 916 750 250 416 416 583 833 375 833 375\n" + "375 583 583 583 583 583 583 583 583 583 583 416 416 833 833 833\n", + + "583 1000 666 708 750 750 666 625 833 750 291 541 708 583 875 750\n" + "791 666 791 708 666 583 750 625 916 625 625 625 416 375 416 500\n", + + "500 500 583 625 583 625 583 375 625 583 250 250 541 250 916 625\n", + + "625 625 625 333 541 333 583 500 750 500 500 500 500 500 500 750]", + + + /*------------------------------------------------------------------------*/ + "HYSMyeongJo-Medium", + + "1[278 278 355 556 556 889 667 222 333 333 389 584 278 333 278\n" + "278 556 556 556 556 556 556 556 556 556 556 278 278 584 584 584\n", + + "556 1015 667 667 722 722 667 611 778 722 278 500 667 556 833 722\n" + "778 667 778 722 667 611 722 667 944 667 667 611 278 278 278 469\n", + + "556 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556\n", + + "556 556 556 333 500 278 556 500 722 500 500 500 334 260 334 584]", + + + /*------------------------------------------------------------------------*/ + "MHei-Medium", /* identical with HYSMyeongJo-Medium */ + + "1[278 278 355 556 556 889 667 222 333 333 389 584 278 333 278\n" + "278 556 556 556 556 556 556 556 556 556 556 278 278 584 584 584\n", + + "556 1015 667 667 722 722 667 611 778 722 278 500 667 556 833 722\n" + "778 667 778 722 667 611 722 667 944 667 667 611 278 278 278 469\n", + + "556 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556\n", + + "556 556 556 333 500 278 556 500 722 500 500 500 334 260 334 584]", + + + /*------------------------------------------------------------------------*/ + "MSung-Light", + + "1[250 250 408 668 490 875 698 250 240 240 417 667 250 313 250\n" + "520 500 500 500 500 500 500 500 500 500 500 250 250 667 667 667\n", + + "396 921 677 615 719 760 625 552 771 802 354 354 781 604 927 750\n" + "823 563 823 729 542 698 771 729 948 771 677 635 344 520 344 469\n", + + "500 250 469 521 427 521 438 271 469 531 250 250 458 240 802 531\n", + + "500 521 521 365 333 292 521 458 677 479 458 427 480 496 480 667]", + + + /*------------------------------------------------------------------------*/ + "STSong-Light", + + "1[207 270 342 467 462 797 710 239 374 374 423 605 238 375 238\n" + "334 462 462 462 462 462 462 462 462 462 462 238 238 605 605 605\n", + + "344 748 684 560 695 739 563 511 729 793 318 312 666 526 896 758\n" + "772 544 772 628 465 607 753 711 972 647 620 607 374 333 374 606\n", + + "500 239 417 503 427 529 415 264 444 518 241 230 495 228 793 527\n", + + "524 524 504 338 336 277 517 450 652 466 452 407 370 258 370 605]", + + + /*------------------------------------------------------------------------*/ + "HYSMyeongJoStd-Medium-Acro", + + "1[333 416 416 833 625 916 833 250 500 500 500 833 291 833 291\n" + "375 625 625 625 625 625 625 625 625 625 625 333 333 833 833 916\n", + + "500 1000 791 708 708 750 708 666 750 791 375 500 791 666 916 791\n" + "750 666 750 708 666 791 791 750 1000 708 708 666 500 375 500 500\n", + + "500 333 541 583 541 583 583 375 583 583 291 333 583 291 875 583\n", + + "583 583 583 458 541 375 583 583 833 625 625 500 583 583 583 750]", + + + /*------------------------------------------------------------------------*/ + "KozMinPro-Regular-Acro", + + "1[278 299 353 614 614 721 735 216 323 323 449 529 219 306 219\n" + "453 614 614 614 614 614 614 614 614 614 614 219 219 529 529 529\n" + "486 744 646 604 617 681 567 537 647 738 320 433 637 566 904 710\n" + "716 605 716 623 517 601 690 668 990 681 634 578 316 614 316 529\n" + "500 387 509 566 478 565 503 337 549 580 275 266 544 276 854 579\n" + "550 578 566 410 444 340 575 512 760 503 529 453 326 380 326 387\n" + "1000 453 1000 380 1000 299 614 614 265 1000 1000 614 1000 451 291 291\n", + + "588 589 500 1000 1000 219 1000 452 216 353 1000 451 1000 1000 486 387]\n" + "128 135 387\n" + "136[387 387 1000 880 448 566 716 903\n" + "460 805 275 276 550 886 582 529 738 529 738 1000 1000 406 406 575\n" + "406 934 934 934 646 646 646 646 646 646 617 567 567 567 567 320\n" + "320 320 320 681 710 716 716 716 716 716 1000 690 690 690 690 634\n" + "605 509 509 509 509 509 509 478 503 503 503 503 275 275 275 275\n", + + "550 579 550 550 550 550 550 1000 575 575 575 575 529 578 529 517\n" + "634 578 445 444 842 453 1000 500]\n" + "323[500 1000 500 1000 500]\n" + "328 383 500\n" + "384[500 500 500 500 500 500]\n" + "9354[614 684 1000 1000 648 899\n", + + "903 509 275 575 503 550 646 320 690 567 716 934 934 934 934 934\n" + "934 426 426 426 426 426 426 426 426 425 425 425 439 426 426 426\n" + "426 426 646 567 1000 567 320 1000 320 716 1000 690 690 690 509 503\n" + "1000 503 275 1000 275 550 1000 575 575 575 513 1000 1000 805 1000 478\n" + "1000 1000 503 1000 1000 735 1000 1000 426 1000 1000 1000 578 553 512\n" + "1000 1000 640 594 284]", + + + /*------------------------------------------------------------------------*/ + "MSungStd-Light-Acro", + + "1[250 250 408 668 490 875 698 250 240 240 417 667 250 313 250\n" + "520 500 500 500 500 500 500 500 500 500 500 250 250 667 667 667\n", + + "396 921 677 615 719 760 625 552 771 802 354 354 781 604 927 750\n" + "823 563 823 729 542 698 771 729 948 771 677 635 344 520 344 469\n", + + "500 250 469 521 427 521 438 271 469 531 250 250 458 240 802 531\n", + + "500 521 521 365 333 292 521 458 677 479 458 427 480 496 480 667]\n" + "17601 17601 500", + + + /*------------------------------------------------------------------------*/ + "STSongStd-Light-Acro", + + "1[207 270 342 467 462 797 710 239 374 374 423 605 238 375 238\n" + "334 462 462 462 462 462 462 462 462 462 462 238 238 605 605 605\n", + + "344 748 684 560 695 739 563 511 729 793 318 312 666 526 896 758\n" + "772 544 772 628 465 607 753 711 972 647 620 607 374 333 374 606\n", + + "500 239 417 503 427 529 415 264 444 518 241 230 495 228 793 527\n", + + "524 524 504 338 336 277 517 450 652 466 452 407 370 258 370 605]\n" + "22353[462 462 1000 1000 500]", + + + /*------------------------------------------------------------------------*/ + "AdobeMingStd-Light-Acro", + + "0[1000 251 347 405 739 504 758 825 281 293 294 494 620 251 373 252\n" + "309 503 503 503 503 504 503 502 503 503 504 251 251 621 621 621\n", + + "405 1042 749 673 679 679 685 671 738 736 333 494 729 696 901 720\n" + "750 674 746 672 627 769 707 777 887 709 716 616 279 309 277 352\n", + + "575 294 500 511 502 549 494 356 516 550 321 321 510 317 738 533\n" + "535 545 533 376 443 361 529 526 742 534 576 439 447 262 446 472]\n", + + "96 17600 1000\n" + "17601[639]\n" + "17602 18964 1000", + + + /*------------------------------------------------------------------------*/ + "AdobeMyungjoStd-Medium-Acro", + + "0[1000 333 416 416 833 625 916 833 250 500 500 500 833 291\n" + "833 291 375]\n", + + "17 26 625\n" + "27[333 333 833 833 916 500 1000 791 708 708 750 708 666 750 791 375\n", + + "500 791 666 916 791 750 666 750 708 666 791 791 750 1000 708 708\n" + "666 500 375 500 500 500 333 541 583 541 583 583 375 583 583 291\n", + + "333 583 291 875 583 583 583 583 458 541 375 583 583 833 625 625\n" + "500 583 583 583 750 1000 500]\n" + "98 18351 1000", + + + /*------------------------------------------------------------------------*/ + "AdobeSongStd-Light-Acro", + + "0[1000 207 270 342 467 462 797 710 239 374 374 423 605 238 375\n" + "238 334]\n" + "17 26 462\n", + + "27[238 238 605 605 605 344 748 684 560 695 739 563 511 729 793 318\n" + "312 666 526 896 758 772 544 772 628 465 607 753 711 972 647 620\n" + "607 374 333 374 606 500 239 417 503 427 529 415 264 444 518 241\n", + + + "230 495 228 793 527 524 524 504 338 336 277 517 450 652 466 452\n" + "407 370 258 370 605]\n" + "96 22352 1000\n", + + "22353[462 462 1000 1000 500]\n" + "22358 29063 1000", + + + /*------------------------------------------------------------------------*/ + "KozGoPro-Medium-Acro", + + "0[1000 224 266 392 551 562 883 677 213 322 322 470 677 247 343\n" + "245 370]\n" + "17 26 562\n" + "27[245 247 677 677 677 447 808 661 602 610 708 535 528 689 703 275\n" + "404 602 514 871 708 727 585 727 595 539 541 696 619 922 612 591\n" + "584 322 562 322 677 568 340 532 612 475 608 543 332 603 601 265\n" + "276 524 264 901 601 590 612 607 367 433 369 597 527 800 511 518\n" + "468 321 273 321 341 1000 362 1000 273 1000 266 562 562 456 1000 1000\n", + + "562 1000 472 283 283 587 588 568 1000 1000 247 1000 330 239 418 1000\n" + "472 1000 1000 447 340 340 340 340 340 340 455 340 340 340 340 1136\n" + "857 384 519 727 952 398 834 264 275 590 918 605 677 769 677 473\n" + "1000 1000 347 340 599 284 845 845 845 661 661 661 661 661 661 610\n" + "535 535 535 535 275 275 275 275 715 708 727 727 727 727 727 1000\n" + "696 696 696 696 591 584 532 532 532 532 532 532 475 543 543 543\n", + + "543 264 264 264 264 584 601 590 590 590 590 590 1000 597 597 597\n" + "597 518 612 518 539 591 584 446 433 683 468 1000 500]\n" + "232 322 1000\n" + "323[500 1000 500 1000]\n" + "327 389 500\n" + "390 9353 1000\n" + "9354[562 753 1000 1000 650 909 909 532 264 597 543 590 661 275 696 535\n", + + "727 845 845 845 845 845 845 375 387 345 369 328 366 364 375 284\n" + "347 340 387 345 369 328 366 364 661 535 1000 535 275 1000 275 727\n" + "1000 696 696 696 532 543 1000 543 264 1000 264 590 1000 597 597 597\n" + "596 1000 1000 834 1000 475 1000 1000 543 1000 1000 759 1000 1000 478\n" + "1000 1000 1000 602 579 527 1000 1000 509 465 280]\n" + "9444 15443 1000", + + + /*------------------------------------------------------------------------*/ + "KozGoPro-Medium", + + "1[224 266 392 551 562 883 677 213 322 322 470 677 247 343 245 370]\n" + "17 26 562\n" + "27[245 247 677 677 677 447 808 661 602 610 708 535 528 689 703\n" + "275 404 602 514 871 708 727 585 727 595 539 541 696 619 922 612\n" + "591 584 322 562 322 677 568 340 532 612 475 608 543 332 603 601\n" + "265 276 524 264 901 601 590 612 607 367 433 369 597 527 800 511\n" + "518 468 321 273 321 341 241 362 241 273 677 266 562 562 456 562\n" + "571 562 416 472 283 283 587 588 568 545 545 247 561 330 239 418\n" + "416 472 1136 1288 447 340 340 340 340 340 340 455 340 340 340 340\n" + "1136 857 384 519 727 952 398 834 264 275 590 918 605 677 769 677\n" + "473 361 677 347 340 599 284 845 845 845 661 661 661 661 661 661\n" + "610 535 535 535 535 275 275 275 275 715 708 727 727 727 727 727\n", + + "677 696 696 696 696 591 584 532 532 532 532 532 532 475 543 543\n" + "543 543 264 264 264 264 584 601 590 590 590 590 590 677 597 597\n" + "597 597 518 612 518 539 591 584 446 433 683 468 562]\n" + "231 632 500\n" + "8718[500 500]\n" + "9354[562 753 245 436 650 909 909 532 264 597 543 590 661 275 696\n" + "535 727 845 845 845 845 845 845 375 387 345 369 328 366 364 375\n" + "284 347 340 387 345 369 328 366 364 661 535 535 535 275 275 275\n" + "727 727 696 696 696 532 543 543 543 264 264 264 590 590 597 597\n" + "597 596 596 596 834 834 475 475 475 543 543 543 759 759 759 478\n" + "478 478 276 602 579 527 527 527 509 465 280 197 270 359 545 546\n" + "869 664 188 322 322 469 676 249 343 249 359 545]\n", + + "9461 9469 546\n" + "9470[249 249 676 676 676 429 791 620 573 581 688 511 504 665 681\n" + "269 395 572 477 844 677 709 555 709 573 509 515 663 593 898 565\n" + "562 557 322 546 322 676 567 427 566 571 447 570 498 320 567 577\n" + "258 254 507 257 870 577 564 572 568 359 409 343 572 500 767 486\n" + "487 448 322 245 322 427 228 363 228 245 676 269 546 546 442 546\n" + "559 546 404 465 275 275 562 562 568 533 534 249 550 326 228 404\n" + "404 464 1136 1250 429 427 427 427 427 427 427 423 427 427 427 427\n" + "1136 835 396 492 709 923 388 781 258 270 567 858 592 677 765 677\n" + "443 361 677 358 354 573 343 840 840 840 620 620 620 620 620 620\n" + "581 511 511 511 511 269 269 269 269 700 677 709 709 709 709 709\n", + + "677 663 663 663 663 562 555 566 566 566 566 566 566 447 498 498\n" + "498 498 258 258 258 258 562 577 564 564 564 564 564 677 572 572\n" + "572 572 487 573 487 509 562 557 446 409 735 448 546 546 726 241\n" + "432 629 868 868 566 258 572 498 564 620 269 663 511 709 840 840\n" + "840 840 840 840 362 361 355 361 354 363 360 362 343 358 354 361\n" + "355 362 354 363 360 620 511 511 511 269 269 269 709 709 663 663\n" + "663 566 498 498 498 258 258 258 564 564 572 572 572]\n" + "9738 9757 250\n" + "9758 9778 333\n" + "12063 12087 500\n", + + + /*------------------------------------------------------------------------*/ + "KozMinProVI-Regular", + + "1[278 299 353 614 614 721 735 216 323 323 449 529 219 306 219\n" + "453]\n" + "17 26 614\n" + "27[219 219 529 529 529 486 744 646 604 617 681 567 537 647 738\n" + "320 433 637 566 904 710 716 605 716 623 517 601 690 668 990 681\n" + "634 578 316 614 316 529 500 387 509 566 478 565 503 337 549 580\n" + "275 266 544 276 854 579 550 578 566 410 444 340 575 512 760 503\n" + "529 453 326 380 326 387 216 453 216 380 529 299 614 614 265 614\n" + "475 614 353 451 291 291 588 589 500 476 476 219 494 452 216 353\n" + "353 451]\n" + "125[1075 486]\n" + "127 137 387\n" + "139[880 448 566 716 903 460 805 275 276 550 886 582 529 738 529\n" + "738 357 529 406 406 575 406 934 934 934 646 646 646 646 646 646\n" + "617 567 567 567 567 320 320 320 320 681 710 716 716 716 716 716\n" + "529 690 690 690 690 634 605 509 509 509 509 509 509 478 503 503\n" + "503 503 275 275 275 275 550 579 550 550 550 550 550 529 575 575\n" + "575 575 529 578 529 517 634 578 445 444 842 453 614]\n" + "231 632 500\n" + "8718[500 500]\n" + "9354[614 684 216 353 648 899 903 509 275 575 503 550 646 320 690\n" + "567 716 934 934 934 934 934 934]\n" + "9377 9384 426\n" + "9385[425 425 425 439 426 426 426 426 426 646 567 567 567 320 320\n" + "320 716 716 690 690 690 509 503 503 503 275 275 275 550 550 575\n" + "575 575 542 542 542 816 816 486 486 486 517 517 517 758 758 758\n" + "426 426 426 286 597 568 522 522 522 640 611 312 257 281 288 546\n" + "546 703 705 160 312 305 389 545 200 309 200 438]\n" + "9460 9469 546\n", + + "9470[200 200 545 545 545 471 744 607 572 563 650 550 516 622 696\n" + "312 314 603 524 848 665 644 561 645 583 491 566 643 581 872 616\n" + "537 516 312 546 312 472 464 400 548 530 447 558 460 301 486 564\n" + "283 258 509 265 834 578 521 554 551 390 410 335 565 476 717 525\n" + "464 456 312 339 312 400 179 422 177 339 545 281 546 546 248 546\n" + "491 570 310 440 278 279 556 563 586 403 403 207 500 440 170 307\n" + "310 440 786 1009 471 367 400 400 400 400 400 400 364 400 365 400\n" + "1012 849 394 544 644 889 377 744 283 285 521 808 545 504 703 545\n" + "703 324 504 397 397 557 397 859 859 859 607 607 607 607 607 607\n" + "562 550 550 550 550 312 312 312 312 662 665 644 644 644 644 644\n" + "497 643 643 643 643 537 576 548 548 548 548 548 548 446 460 460\n" + "460 460 283 283 283 283 522 578 521 521 521 521 521 545 565 565\n" + "565 565 464 540 464 491 537 516 418 410 842 456 546 563 627 196\n" + "289 560 828 835 548 283 565 460 521 607 312 643 550 644 859 859\n" + "859 859 859 859]\n" + "9697 9713 397\n" + "9714[607 550 550 550 312 312 312 644 644 643 643 643 548 460 460\n" + "460 283 283 283 521 521 565 565 565]\n" + "9738 9757 250\n" + "9758 9778 333\n" + "12063 12087 500\n" + "15449[670 810 640 760]\n" + "15455[980 529 529 529 619 529 891]\n" + "15464[529 529 529 529 534 534 566 566 530 529 529 529 529 581 529\n" + "529 533 533 738 853 676 533 882 882 882 716 716 600 529 589 688\n" + "529 529 559 559 594 619 522 529 468 721 529 529 529 525 529 529\n" + "661 529 660 564 684 500 790 940 870]\n" + "15521[630 740 740 900 840 980]\n" + "15529[900 940 710 870 970]\n" + "15535[820 930 840 940 850 850 960 960]\n" + "15545[960 980 940 970 910 950 870 980 980 910 930 820 850 980 950]\n" + "15562[970 980 980 980]\n" + "15575[980 990 990 880]\n" + "15581[960 850 860]\n", + + "15585[840 950 740 870 830 760 890 990 900 870 990 970 980 950 960]\n" + "15601[850 830 950 930 810 980 910 780 890 760 880 790 870 830 980\n" + "830 900 900 950 940 950 820 910 930 960 880 930 960 980 920 940\n" + "920 950 970 980 890 930 860 930 960 990 820 920 960 930 970 760\n" + "780 920 970 830 950 830 990 990 990 840 890 890 900 940 940 980\n" + "980 980 970 970 970 960 800 950 820 960 810 950 810 990 730 850\n" + "880 760 990 910 920 770 870 970 980 840 920 950 810 800 940 950\n" + "900 960 910 960 960 750 740 860 850 640 690 900 750 740 840 770\n" + "800 790 730 640 860 760 790]\n" + "15723[770 780 529 529 934 841 904 854 710 579 575 575 575 575 646\n" + "387 566 517 517 601 578 578 509 387 313 444 387 444 340 453 387\n" + "453 623 646 566 617 617 567 681 710 710 716 623 690 601 410 509\n" + "276 478 478 503 605 565 579 579 550 410 575 340 387 617 647 738\n" + "433 517 690 478 549 580 266 444 575 869 537 421 364 593 429 310\n" + "573 594 432 452 462 403 275 286 597 285 526 576 876 575 598 384\n" + "384 598 725 421 579 578 300 580 664 293 593 517 426 524 530 876\n" + "564 565 556 775 594 384 384 500 517 414 597 0 238 238 288 558\n" + "391]\n", + + "15851 15857 421\n" + "15858 15866 0\n" + "15867[393]\n" + "15868 15879 0\n" + "15880[468 624 624 541 484 367 580 738 635 555 505 546 598 500 447\n" + "290 474 310 331 220 466 632 976 529 529 882 882 882 446 526 544\n" + "431 627 500 859 848 834 665 578 565 565 565 565 607 524 491 491\n" + "566 516 516 548 265 410 410 335 456 456 583 607 524 563 563 550\n" + "650 665 665 644 583 643 566 390 548 265 447 447 460 558 558 578\n" + "578 521 390 565 335 563 622 696 314 491 643 447 486 564 258 410\n" + "565]\n" + "20317[386 386 458 446 807 677 734 739 563 692 598 514 538 302 575\n" + "337 616 564 645 645 645 314 314 630 563 563 709 618 689 689 689\n" + "689 689 990 633 476 499 546 546 546 270 538 272 272 575 405 570\n" + "757 526 903 669 723 589 589 589 400 400 373 390 732 657 691 613\n" + "521 628 563 534 505 272 574 331 560 546 619 619 619 306 306 597\n" + "521 521 662 576 641 641 641 641 641 867 531 445 457 483 483 483\n" + "279 505 262 262 574 385 561 714 460 1010 601 743 545 545 643]\n", + + + /*------------------------------------------------------------------------*/ + "AdobeMyungjoStd-Medium", + + "1[333 416 416 833 625 916 833 250 500 500 500 833 291 833 291\n" + "375]\n" + "17 26 625\n", + + "27[333 333 833 833 916 500]\n" + "34[791 708 708 750 708 666 750 791 375 500 791 666 916 791 750\n", + + "666 750 708 666 791 791 750]\n" + "57[708 708 666 500 375 500 500 500 333 541 583 541 583 583 375\n", + + "583 583 291 333 583 291 875 583 583 583 583 458 541 375 583 583\n" + "833 625 625 500 583 583 583 750]\n" + "97[500]\n" + "8094 8190 500\n", + + + /*------------------------------------------------------------------------*/ + "AdobeSongStd-Light", + + "1[207 270 342 467 462 797 710 239 374 374 423 605 238 375 238\n" + "334]\n" + "17 26 462\n", + + "27[238 238 605 605 605 344 748 684 560 695 739 563 511 729 793 \n" + "318 312 666 526 896 758 772 544 772 628 465 607 753 711 972 647\n", + + "620 607 374 333 374 606 500 239 417 503 427 529 415 264 444 518\n" + "241 230 495 228 793 527 524 524 504 338 336 277 517 450 652 466\n", + + "452 407 370 258 370 605]\n" + "814 939 500\n" + "7712[517 684 723]\n" + "7716[500]\n" + "22353[462 462 500 500 500]\n", + + + /*------------------------------------------------------------------------*/ + "AdobeMingStd-Light", + + "1[251 347 405 739 504 758 825 281 293 294 494 620 251 373 252\n" + "309 503 503 503 503 504 503 502 503 503 504 251 251 621 621 621\n", + + "405 1042 749 673 679 679 685 671 738 736 333 494 729 696 901 720\n" + "750 674 746 672 627 769 707 777 887 709 716 616 279 309 277 352\n", + + "575 294 500 511 502 549 494 356 516 550 321 321 510 317 738 533\n" + "535 545 533 376 443 361 529 526 742 534 576 439 447 262 446 472]\n", + + "13648 13742 500\n" + "17601[639]\n" + "17603[500]\n" +}; + +#endif /* PDF_CJKFONTWIDTHS_SUPPORTED */ + +#endif /* FT_COREMETR_H */ diff --git a/src/pdflib/font/ft_font.c b/src/pdflib/font/ft_font.c new file mode 100644 index 0000000..53a39a9 --- /dev/null +++ b/src/pdflib/font/ft_font.c @@ -0,0 +1,532 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_font.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT basic font functions + * + */ + +#define FT_FONT_C + +#include "ft_font.h" + + +static pdc_error_info fnt_errors[] = +{ +#define fnt_genInfo 1 +#include "ft_generr.h" +}; + +#define N_FNT_ERRORS (sizeof fnt_errors / sizeof (pdc_error_info)) + +void +fnt_register_errtab(pdc_core *pdc) +{ + pdc_register_errtab(pdc, PDC_ET_FONT, fnt_errors, N_FNT_ERRORS); +} + +static void +fnt_init_font_metric(fnt_font_metric *metric) +{ + metric->name = NULL; + metric->flags = 0L; + metric->type = fnt_unknownType; + metric->charcoll = (int) cc_none; + + /* + * Fill in some reasonable default values in global font info in + * case they're missing from the metrics data. + */ + metric->italicAngle = 0; + metric->isFixedPitch = pdc_false; + metric->llx = FNT_MISSING_FONTVAL; + metric->lly = FNT_MISSING_FONTVAL; + metric->urx = FNT_MISSING_FONTVAL; + metric->ury = FNT_MISSING_FONTVAL; + metric->underlinePosition = -100; + metric->underlineThickness = FNT_DEFAULT_UNDERLINEWIDTH; + metric->ascender = FNT_MISSING_FONTVAL; + metric->descender = FNT_MISSING_FONTVAL; + metric->capHeight = FNT_MISSING_FONTVAL; + metric->xHeight = FNT_MISSING_FONTVAL; + metric->StdHW = 0; + metric->StdVW = 0; + + metric->defwidth = FNT_DEFAULT_WIDTH; + metric->numwidths = 0; + metric->widths = NULL; + metric->numinters = 0; + metric->ciw = NULL; + metric->numglwidths = 0; + metric->glw = NULL; + +} + +void +fnt_init_font(fnt_font *font) +{ + fnt_init_font_metric(&font->m); + + font->name = NULL; + font->utf8name = NULL; + font->filename = NULL; + font->isstdfont = pdc_false; + font->ishostfont = pdc_false; + font->issymbfont = pdc_true; + font->hasdescr = pdc_false; + font->vertical = pdc_false; + font->spacechar = 0; + font->spacewidth = 0; + font->linegap = FNT_MISSING_FONTVAL; + font->weight = 0; + font->vertical = pdc_false; + pdc_identity_matrix(&font->matrix); + font->bbox.llx = 0; + font->bbox.lly = 0; + font->bbox.urx = 0; + font->bbox.ury = 0; + font->fsscale = 1.0; + font->enc = pdc_invalidenc; + font->numglyphs = 0; + font->numcodes = 0; + font->gid2code = NULL; + font->code2gid = NULL; + font->embedded = pdc_false; + font->cmapname = NULL; + font->imgname = NULL; + font->filelen = 0; + font->img = NULL; +} + +static void +fnt_cleanup_font_metric(pdc_core *pdc, fnt_font_metric *metric) +{ + if (metric->name != NULL) + { + pdc_free(pdc, metric->name); + metric->name = NULL; + } + + if (metric->widths != NULL) + { + pdc_free(pdc, metric->widths); + metric->widths = NULL; + } + + if (metric->ciw != NULL) + { + pdc_free(pdc, metric->ciw); + metric->ciw = NULL; + } + + if (metric->glw != NULL) + { + pdc_free(pdc, metric->glw); + metric->glw = NULL; + } + + +} + +void +fnt_cleanup_fontimg(pdc_core *pdc, fnt_font *font) +{ + if (font->img != NULL && font->imgname == NULL) + { + pdc_free(pdc, font->img); + font->img = NULL; + } + + if (font->imgname != NULL) + { + pdc_free(pdc, font->imgname); + font->imgname = NULL; + } +} + +void +fnt_cleanup_font(pdc_core *pdc, fnt_font *font) +{ + int i = 0; + + (void) i; + + fnt_cleanup_font_metric(pdc, &font->m); + + if (font->name != NULL) + { + pdc_free(pdc, font->name); + font->name = NULL; + } + + if (font->utf8name != NULL) + { + pdc_free(pdc, font->utf8name); + font->utf8name = NULL; + } + + if (font->filename != NULL) + { + pdc_free(pdc, font->filename); + font->filename = NULL; + } + + /* delete font specific encoding vector */ + if (font->enc >= pdc_firstvarenc) + { + pdc_encodingvector *ev = pdc_get_encoding_vector(pdc, font->enc); + + if (ev != NULL && ev->flags & PDC_ENC_FONT) + pdc_remove_encoding_vector(pdc, (int) font->enc); + } + + if (font->gid2code != NULL) + { + pdc_free(pdc, font->gid2code); + font->gid2code = NULL; + } + + if (font->code2gid != NULL) + { + pdc_free(pdc, font->code2gid); + font->code2gid = NULL; + } + + + + if (font->cmapname != NULL) + { + pdc_free(pdc, font->cmapname); + font->cmapname = NULL; + } + + + fnt_cleanup_fontimg(pdc, font); +} + +/* + * we assume: + * code!=0 --> gid=0 --> gid=-1 or code=0 <--> gid=0 + * + */ +int +fnt_get_glyphid(int code, fnt_font *font) +{ + if (code >= 0 && code < font->numcodes) + { + if (font->code2gid != NULL) + { + int gid = font->code2gid[code]; + + if (gid) + return gid; + } + else + { + /* this is temporary. for Type1 fonts there is no information + * about glyphs at present. we assume identity code = glyph id. + */ + return code; + } + } + + if (!code) + return 0; + + return -1; +} + +/* + * we assume: + * gid!=0 --> code=0 --> code=-1 or gid=0 <--> code=0 + * + */ +int +fnt_get_code(int gid, fnt_font *font) +{ + if (gid >= 0 && gid < font->numglyphs) + { + if (font->gid2code != NULL) + { + int code = font->gid2code[gid]; + + if (code) + return code; + } + } + + if (!gid) + return 0; + + return -1; +} + +int +fnt_get_glyphwidth(int code, fnt_font *font) +{ + int i; + + if (font->m.widths != NULL) + { + if (code < font->m.numwidths) + return font->m.widths[code]; + } + else if (font->m.ciw != NULL) + { + fnt_interwidth *wd = font->m.ciw; + int lo = 0; + int hi = font->m.numinters - 1; + + while (lo < hi) + { + i = (lo + hi) / 2; + + if (code >= wd[i].startcode && code < wd[i+1].startcode) + return (int) wd[i].width; + + if (code < wd[i].startcode) + hi = i; + else + lo = i + 1; + } + } + else if (font->m.glw != NULL) + { + for (i = 0; i < font->m.numglwidths; i++) + { + if (font->m.glw[i].unicode == (pdc_ushort) code) + { + return font->m.glw[i].width; + } + } + } + + return FNT_MISSING_WIDTH; +} + +void +fnt_font_logg_widths(pdc_core *pdc, fnt_font *font) +{ + if (font != NULL && + pdc_logg_is_enabled(pdc, 2, trc_font)) + { + int code, width; + + for (code = 0; code < PDC_NUM_UNIVAL; code++) + { + width = fnt_get_glyphwidth(code, font); + if (width == FNT_MISSING_WIDTH) + break; + pdc_logg(pdc, + "\t\tWidth[%d]: %d\n", code, width); + } + } +} + +static const pdc_keyconn pdf_fonttype_pdfkeylist[] = +{ + {"Type0", fnt_Type0}, + {"Type1", fnt_Type1}, + {"MMType1", fnt_MMType1}, + {"TrueType", fnt_TrueType}, + {"CIDFontType2", fnt_CIDFontType2}, + {"Type1C", fnt_Type1C}, + {"CIDFontType0", fnt_CIDFontType0}, + {"CIDFontType0C", fnt_CIDFontType0C}, + {"OpenType", fnt_OpenType}, + {"OpenType", fnt_OpenTypeC}, + {"Type3", fnt_Type3}, + {"(unknown)", fnt_unknownType}, + {NULL, 0} +}; + +int +fnt_get_pdf_fonttype_code(const char *typenam) +{ + int type = pdc_get_keycode(typenam, pdf_fonttype_pdfkeylist); + return (type != PDC_KEY_NOTFOUND) ? type : fnt_unknownType; +} + +const char * +fnt_get_pdf_fonttype_name(int typecode) +{ + const char *name = pdc_get_keyword(typecode, pdf_fonttype_pdfkeylist); + return name ? name : ""; +} + +static const pdc_keyconn pdf_fonttype_descrkeylist[] = +{ + /* Acrobat 7 names for comparison */ + {"Composite", fnt_Type0}, /* - */ + {"Type 1", fnt_Type1}, /* Type 1 */ + {"Multiple Master", fnt_MMType1}, /* MM */ + {"TrueType", fnt_TrueType}, /* TrueType */ + {"TrueType (CID)", fnt_CIDFontType2}, /* TrueType (CID) */ + {"Type 1 CFF", fnt_Type1C}, /* Type 1 */ + {"Type 1 (CID)", fnt_CIDFontType0}, /* Type 1 (CID) */ + {"Type 1 CFF (CID)",fnt_CIDFontType0C}, /* Type 1 (CID) */ + {"OpenType", fnt_OpenType}, /* OpenType */ + {"OpenType", fnt_OpenTypeC}, + {"Type 3", fnt_Type3}, /* Type 3 */ + {"(unknown)", fnt_unknownType}, + {NULL, 0} +}; + +const char * +fnt_get_pdf_fonttype_desc(int typecode) +{ + const char *name = pdc_get_keyword(typecode, pdf_fonttype_descrkeylist); + return name ? name : ""; +} + +pdc_encodingvector * +fnt_create_font_ev(pdc_core *pdc, fnt_font *font) +{ + pdc_encodingvector *ev = NULL; + char encname[128]; + + pdc->uniqueno++; + sprintf(encname, "encoding_%s_%d", font->name, pdc->uniqueno); + ev = pdc_new_encoding(pdc, encname); + pdc_insert_encoding_vector(pdc, ev); + font->enc = pdc_find_encoding(pdc, encname); + ev->flags |= PDC_ENC_FONT; + + return ev; +} + +int +fnt_check_weight(int weight) +{ + if (weight == PDC_KEY_NOTFOUND) + weight = FNT_FW_NORMAL; + + if (weight > 1000) + weight = 1000; + + if (weight <= 10) + weight *= 100; + else + weight = 100 * (weight / 100); + + return weight; +} + +static const pdc_keyconn fnt_fontweight_keylist[] = +{ + {"none", FNT_FW_DONTCARE}, + {"thin", FNT_FW_THIN}, + {"extralight", FNT_FW_EXTRALIGHT}, + {"ultralight", FNT_FW_ULTRALIGHT}, + {"light", FNT_FW_LIGHT}, + {"normal", FNT_FW_NORMAL}, + {"regular", FNT_FW_REGULAR}, + {"", FNT_FW_REGULAR}, + {"medium", FNT_FW_MEDIUM}, + {"semibold", FNT_FW_SEMIBOLD}, + {"semi", FNT_FW_SEMIBOLD}, + {"demibold", FNT_FW_DEMIBOLD}, + {"bold", FNT_FW_BOLD}, + {"extrabold", FNT_FW_EXTRABOLD}, + {"extra", FNT_FW_EXTRABOLD}, + {"ultrabold", FNT_FW_ULTRABOLD}, + {"heavy", FNT_FW_HEAVY}, + {"black", FNT_FW_BLACK}, + {NULL, 0} +}; + +int +fnt_weightname2weight(const char *weightname) +{ + return pdc_get_keycode_ci(weightname, fnt_fontweight_keylist); +} + +const char * +fnt_weight2weightname(int weight) +{ + return pdc_get_keyword(weight, fnt_fontweight_keylist); +} + +int +fnt_macfontstyle2weight(int macfontstyle) +{ + return (macfontstyle & (1<<0)) ? FNT_FW_BOLD : FNT_FW_NORMAL; +} + +#define FNT_STEMV_WEIGHT 65.0 + +int +fnt_weight2stemv(int weight) +{ + double w = weight / FNT_STEMV_WEIGHT; + return (int) (FNT_STEMV_MIN + w * w + 0.5); +} + +int +fnt_stemv2weight(int stemv) +{ + double w; + int weight = 0; + + w = (double) (stemv - FNT_STEMV_MIN); + if (w > 0) + weight = (int) (FNT_STEMV_WEIGHT * sqrt(w) + 0.5); + + return weight; +} + +void +fnt_font_logg_protocol(pdc_core *pdc, fnt_font *font) +{ + if (font != NULL && + pdc_logg_is_enabled(pdc, 2, trc_font)) + { + const char *wname = fnt_weight2weightname(font->weight); + char dwname[16]; + + dwname[0] = 0; + if (wname && *wname) + sprintf(dwname, " (%s)", wname); + + pdc_logg(pdc, + "\n" + "\t\tFont type: %s\n" + "\t\tFlags: %d\n" + "\t\tFontBBox: %g,%g %g,%g\n" + "\t\titalicAngle: %g\n" + "\t\tisFixedPitch: %d\n" + "\t\tunderlinePosition: %d\n" + "\t\tunderlineThickness: %d\n" + "\t\tcapHeight: %d\n" + "\t\txHeight: %d\n" + "\t\tascender: %d\n" + "\t\tdescender: %d\n" + "\t\tlinegap: %d\n" + "\t\tweight: %d%s\n" + "\t\tStdVW: %d\n" + "\t\tStdHW: %d\n" + "\t\tdefWidth: %d\n", + fnt_get_pdf_fonttype_name(font->m.type), + font->m.flags, + font->m.llx, font->m.lly, font->m.urx, font->m.ury, + font->m.italicAngle, font->m.isFixedPitch, + font->m.underlinePosition, font->m.underlineThickness, + font->m.capHeight, font->m.xHeight, font->m.ascender, + font->m.descender, font->linegap, font->weight, + dwname, + font->m.StdVW, font->m.StdHW, + font->m.defwidth); + } +} + + diff --git a/src/pdflib/font/ft_font.h b/src/pdflib/font/ft_font.h new file mode 100644 index 0000000..34f2a0b --- /dev/null +++ b/src/pdflib/font/ft_font.h @@ -0,0 +1,267 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_font.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Header file for font handling + * + */ + +#ifndef FT_FONT_H +#define FT_FONT_H + +#include "pc_util.h" +#include "pc_geom.h" +#include "pc_file.h" +#include "ft_cid.h" + +#define FNT_DEFAULT_WIDTH 250 /* some reasonable default */ +#define FNT_DEFAULT_CIDWIDTH 1000 /* for CID fonts */ +#define FNT_MISSING_WIDTH -1234567890 /* missing width value */ + +#define FNT_DEFAULT_UNDERLINEWIDTH 50 /* default value of underlineThickness*/ + +#define FNT_MAX_METRICS 2048.0 /* maximal font metrics value */ + +/* + * these are the font weight values of Microsoft + * see LOGFONT structure member lfWeight + */ +#define FNT_FW_DONTCARE 0 +#define FNT_FW_THIN 100 +#define FNT_FW_EXTRALIGHT 200 +#define FNT_FW_ULTRALIGHT 200 +#define FNT_FW_LIGHT 300 +#define FNT_FW_NORMAL 400 +#define FNT_FW_REGULAR 400 +#define FNT_FW_MEDIUM 500 +#define FNT_FW_SEMIBOLD 600 +#define FNT_FW_DEMIBOLD 600 +#define FNT_FW_BOLD 700 +#define FNT_FW_EXTRABOLD 800 +#define FNT_FW_ULTRABOLD 800 +#define FNT_FW_HEAVY 900 +#define FNT_FW_BLACK 900 + +/* + * these defaults are used when the stem value + * must be derived from the name (unused) + */ +#define FNT_STEMV_MIN 50 /* minimum StemV value */ +#define FNT_STEMV_LIGHT 71 /* light StemV value */ +#define FNT_STEMV_NORMAL 109 /* normal StemV value */ +#define FNT_STEMV_MEDIUM 125 /* mediumbold StemV value */ +#define FNT_STEMV_SEMIBOLD 135 /* semibold StemV value */ +#define FNT_STEMV_BOLD 165 /* bold StemV value */ +#define FNT_STEMV_EXTRABOLD 201 /* extrabold StemV value */ +#define FNT_STEMV_BLACK 241 /* black StemV value */ + +/* + * Bit positions for the font descriptor flag + */ +#define FNT_FIXEDWIDTH (long) (1L<<0) +#define FNT_SERIF (long) (1L<<1) +#define FNT_SYMBOL (long) (1L<<2) +#define FNT_SCRIPT (long) (1L<<3) +#define FNT_ADOBESTANDARD (long) (1L<<5) +#define FNT_ITALIC (long) (1L<<6) +#define FNT_SMALLCAPS (long) (1L<<17) +#define FNT_FORCEBOLD (long) (1L<<18) + +#define FNT_DEF_ITALICANGLE -12 /* default italic angle */ +#define FNT_MISSING_FONTVAL PDC_SHRT_MIN /* missing font value */ + +/* start sequence of PFA files */ +#define FNT_PFA_STARTSEQU "%!PS" + +/* Font types */ +typedef enum +{ + fnt_Type0, /* Type0 fonts */ + fnt_Type1, /* Type1 fonts */ + fnt_MMType1, /* Multiple master fonts */ + fnt_TrueType, /* TrueType fonts for 1-byte encoding */ + fnt_CIDFontType2, /* TrueType fonts for 2-byte encoding */ + fnt_Type1C, /* CFF PostScript fonts for 1-byte encoding */ + fnt_CIDFontType0, /* OpenType fonts with CFF_ table for 2-byte encoding */ + fnt_CIDFontType0C, /* CFF PostScript fonts for 2-byte encoding */ + fnt_OpenType, /* OpenType fonts for 1-byte encoding */ + fnt_OpenTypeC, /* OpenType fonts for 2-byte encoding */ + fnt_Type3, /* Type3 fonts */ + fnt_unknownType /* for initialization only */ +} +fnt_fonttype; + +/* Font styles */ +typedef enum +{ + fnt_Normal, + fnt_Bold, + fnt_Italic, + fnt_BoldItalic +} +fnt_fontstyle; + +typedef struct fnt_interwidth_s fnt_interwidth; +typedef struct fnt_interwidth4_s fnt_interwidth4; +typedef struct fnt_glyphwidth_s fnt_glyphwidth; +typedef struct fnt_font_metric_s fnt_font_metric; +typedef struct fnt_font_s fnt_font; + +/* Code interval for glyph width */ +struct fnt_interwidth_s +{ + pdc_ushort startcode; /* start code of interval */ + pdc_short width; /* width of glyphs in the code interval */ +}; + +struct fnt_interwidth4_s +{ + int startcode; /* start UTF-32 Unicode of interval */ + pdc_short width; /* width of glyphs in the code interval */ +}; + +/* Code and Unicode for glyph width */ +struct fnt_glyphwidth_s +{ + pdc_ushort unicode; /* UTF-16 Unicode of glyph */ + pdc_short code; /* builtin 8-bit code */ + pdc_short width; /* glyph width */ +}; + + +/* Font metric exchange structure */ +struct fnt_font_metric_s +{ + char *name; /* font name (/FontName) */ + pdc_ulong flags; /* font flags of font descriptor */ + fnt_fonttype type; /* type of font */ + int charcoll; /* supported CID character collection */ + /* < 0: Halfwidth Latin-1 character */ + /* font metric */ + pdc_scalar italicAngle; /* AFM key: ItalicAngle */ + int isFixedPitch; /* AFM key: IsFixedPitch */ + pdc_scalar llx; /* AFM key: FontBBox */ + pdc_scalar lly; /* AFM key: FontBBox */ + pdc_scalar urx; /* AFM key: FontBBox */ + pdc_scalar ury; /* AFM key: FontBBox */ + int underlinePosition; /* AFM key: UnderlinePosition */ + int underlineThickness; /* AFM key: UnderlineThickness */ + int capHeight; /* AFM key: CapHeight */ + int xHeight; /* AFM key: XHeight */ + int ascender; /* AFM key: Ascender */ + int descender; /* AFM key: Descender */ + int StdVW; /* AFM key: StdVW */ + int StdHW; /* AFM key: StdHW */ + + /* glyph widths */ + int defwidth; /* default width */ + int numwidths; /* number of entries in widths */ + int *widths; /* ptr to glyph widths (enumerated by codes) */ + int numinters; /* number of entries in ciw */ + fnt_interwidth *ciw; /* ptr to code intervals for widths array */ + int numglwidths; /* number of entries in glw */ + fnt_glyphwidth *glw; /* ptr to glyph widths array */ + + +}; + +/* Font exchange structure */ +struct fnt_font_s +{ + char *name; /* font name (/BaseFont or /Name or 'font_#') */ + char *utf8name; /* UTF-8 encoded font name (maybe with BOM) */ + char *filename; /* font file name */ + + fnt_font_metric m; /* name, type, flags, charcoll and metric */ + pdc_bool isstdfont; /* is an incore font + * or standard CJK font in pdflib */ + pdc_bool ishostfont; /* is an host font */ + pdc_bool hasdescr; /* has font descriptor */ + pdc_bool vertical; /* vertical writing mode */ + + pdc_ushort spacechar; /* code of space character depending on enc */ + int spacewidth; /* width of space character */ + int linegap; /* OpenType lineGap */ + int weight; /* font weight value 0-1000 */ + + pdc_matrix matrix; /* Type3 font matrix */ + pdc_rectangle bbox; /* Type3 font bounding box */ + pdc_scalar fsscale; /* Type3 fontsize scaling */ + + pdc_bool issymbfont; /* is a symbol font */ + pdc_encoding enc; /* font encoding shortcut */ + + int numglyphs; /* number of glyphs */ + int numcodes; /* number of codes */ + + pdc_ushort *gid2code; /* mapping glyph ID -> [Uni]code or NULL */ + pdc_ushort *code2gid; /* mapping [Uni]code -> glyph ID or NULL */ + char *cmapname; /* CID CMap name */ + + + /* font in memory */ + pdc_bool embedded; /* embedded font */ + char *imgname; /* name of virtual file containing *img */ + size_t filelen; /* length of (uncompressed) font data */ + pdc_byte *img; /* font (or CFF table) data */ + +}; + +/* font error numbers. +*/ +enum +{ +#define fnt_genNames 1 +#include "ft_generr.h" + + FNT_E_dummy +}; + +/* ft_font.c */ +void fnt_register_errtab(pdc_core *pdc); +void fnt_init_font(fnt_font *font); +void fnt_cleanup_font(pdc_core *pdc, fnt_font *font); +void fnt_cleanup_fontimg(pdc_core *pdc, fnt_font *font); +int fnt_get_glyphid(int code, fnt_font *font); +int fnt_get_code(int gid, fnt_font *font); +int fnt_get_glyphwidth(int code, fnt_font *font); +int fnt_get_pdf_fonttype_code(const char *typenam); +const char *fnt_get_pdf_fonttype_name(int typecode); +const char *fnt_get_pdf_fonttype_desc(int typecode); +pdc_encodingvector *fnt_create_font_ev(pdc_core *pdc, fnt_font *font); +int fnt_check_weight(int weight); +int fnt_weightname2weight(const char *weightname); +int fnt_stemv2weight(int stemv); +const char *fnt_weight2weightname(int weight); +int fnt_macfontstyle2weight(int macfontstyle); +int fnt_weight2stemv(int weight); +void fnt_font_logg_widths(pdc_core *pdc, fnt_font *font); +void fnt_font_logg_protocol(pdc_core *pdc, fnt_font *font); + +/* ft_corefont.c */ +pdc_bool fnt_is_standard_font(const char *fontname); +const char *fnt_get_abb_std_fontname(const char *fontname); +void fnt_fill_font_metric(pdc_core *pdc, fnt_font *font, pdc_bool kerning, + const fnt_font_metric *metric); +const fnt_font_metric *fnt_get_core_metric(const char *fontname); +const char *fnt_get_abb_cjk_fontname(const char *fontname); +int fnt_get_preinstalled_cidfont(const char *fontname, + const fnt_font_metric **fontmetric); +const char **fnt_get_cid_widths_array(pdc_core *pdc, fnt_font *font); + + +/* ft_type1.c */ +pdc_bool fnt_test_type1_font(pdc_core *pdc, const pdc_byte *img); +pdc_bool fnt_get_type1_encoding(pdc_core *pdc, fnt_font *font, int glyphflags); + +#endif /* FT_FONT_H */ diff --git a/src/pdflib/font/ft_generr.h b/src/pdflib/font/ft_generr.h new file mode 100644 index 0000000..909596b --- /dev/null +++ b/src/pdflib/font/ft_generr.h @@ -0,0 +1,109 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_generr.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT error messages + * + */ + +#define FT_GENERR_H + +#if fnt_genNames +#define gen(n, num, nam, msg) FNT_E_##nam = num, +#elif fnt_genInfo +#define gen(n, num, nam, msg) { n, num, msg, (const char *) 0 }, + +#else +#error invalid inclusion of generator file +#endif + + +/* -------------------------------------------------------------------- */ +/* Font (70xx) */ +/* -------------------------------------------------------------------- */ + +gen(1, 7000, FONT_ILLFONTSTYLE, "Illegal fontstyle '$1' in font name") + +gen(1, 7001, FONT_PREFIX, "Font '$1': ") + +gen(0, 7002, FONT_HOSTNOTFOUND, "Host font not found") + +gen(1, 7004, FONT_UNSUPP_FORMAT, "Font format '$1' not supported") + +gen(0, 7006, FONT_TTHOSTNOTFOUND, "TrueType host font not found") + +gen(1, 7007, FONT_NAMETOOLONG, + "Font name too long (max. $1 characters)") + +gen(0, 7060, TT_BITMAP, "TrueType bitmap font not supported") + +gen(1, 7062, TT_NOFONT, "Font file '%s' is not a TrueType or OpenType font") + +gen(0, 7064, TT_BADCMAP, "Font contains unknown encodings (cmaps) only") + +gen(0, 7066, TT_SYMBOLOS2, "Symbol font does not contain OS/2 table") + +gen(0, 7068, TT_EMBED, + "Font cannot be embedded due to licensing restrictions in the font file") + +gen(0, 7070, TT_ASSERT1, "TrueType parser error") + +gen(0, 7071, TT_CORRUPT1, "Corrupt TrueType font") + +gen(1, 7072, TT_ASSERT2, "TrueType parser error in font file '$1'") + +gen(1, 7073, TT_CORRUPT2, "Corrupt TrueType font file '$1'") + +gen(1, 7074, TTC_NOTFOUND, + "Font not found in TrueType Collection file '$1'") + +gen(0, 7076, TT_NOGLYFDESC, + "TrueType font does not contain any character outlines") + +gen(1, 7077, TT_GLYPHIDNOTFOUND, + "Couldn't find glyph id for Unicode value U+$1") + +gen(0, 7078, TT_NONAME, + "TrueType font contains only unsupported records in 'name' table") + +gen(1, 7079, TT_BADPOST, + "TrueType 'post' table has unknown reserved character index $1") + +gen(1, 7080, OT_CHARSET, + "OpenType font with predefined charset '$1' in CFF table not supported") + +gen(0, 7081, OT_MULTIFONT, + "OpenType font with multiple font entries not supported") + +gen(0, 7082, OT_CHARSTRINGS, + "OpenType font has no CharStrings data in CFF table") + +gen(0, 7083, OT_TOPDICT, + "OpenType CID font has no Top DICT INDEX in CFF table") + +gen(0, 7085, OT_NO_ORDERING, + "OpenType CID font has no ordering string in CFF table") + +gen(1, 7086, OT_ILL_CHARCOLL, + "OpenType CID font has unknown character collection '$1'") + + + + + + + +#undef gen +#undef fnt_genNames +#undef fnt_genInfo + diff --git a/src/pdflib/font/ft_hostfont.c b/src/pdflib/font/ft_hostfont.c new file mode 100644 index 0000000..ec9411d --- /dev/null +++ b/src/pdflib/font/ft_hostfont.c @@ -0,0 +1,24 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_hostfont.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT host font handling routines for Windows and Mac + * + */ + +#include "pc_ctype.h" + +#include "ft_font.h" +#include "ft_truetype.h" + + diff --git a/src/pdflib/font/ft_pdffont.c b/src/pdflib/font/ft_pdffont.c new file mode 100644 index 0000000..0767d74 --- /dev/null +++ b/src/pdflib/font/ft_pdffont.c @@ -0,0 +1,18 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 2002-2006 PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_pdffont.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Routine for parsing font dictionaries in PDF files by pCOS + * + */ + +#include "ft_pdffont.h" +#include "ft_truetype.h" + + diff --git a/src/pdflib/font/ft_pdffont.h b/src/pdflib/font/ft_pdffont.h new file mode 100644 index 0000000..bb40cbc --- /dev/null +++ b/src/pdflib/font/ft_pdffont.h @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_pdffont.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Header file for parsing font dictionaries in PDF files + * + */ + +#ifndef FT_PDFFONT_H +#define FT_PDFFONT_H + +#include "ft_font.h" + + + +#endif /* FT_PDFFONT_H */ diff --git a/src/pdflib/font/ft_truetype.c b/src/pdflib/font/ft_truetype.c new file mode 100644 index 0000000..b4e33a6 --- /dev/null +++ b/src/pdflib/font/ft_truetype.c @@ -0,0 +1,2310 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_truetype.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT TrueType handling routines + * + */ + +#include "ft_font.h" +#include "ft_truetype.h" + +#ifdef PDF_TRUETYPE_SUPPORTED + +void +tt_assert(tt_file *ttf) +{ + pdc_core *pdc = ttf->pdc; + + if (ttf->filename) + pdc_error(pdc, FNT_E_TT_ASSERT2, ttf->filename, 0, 0, 0); + else + pdc_error(pdc, FNT_E_TT_ASSERT1, 0, 0, 0, 0); +} /* tt_assert */ + +void +tt_error(tt_file *ttf) +{ + pdc_core *pdc = ttf->pdc; + + if (ttf->filename) + pdc_error(pdc, FNT_E_TT_CORRUPT2, ttf->filename, 0, 0, 0); + else + pdc_error(pdc, FNT_E_TT_CORRUPT1, 0, 0, 0, 0); +} /* tt_error */ + +void +tt_seek(tt_file *ttf, long offset) +{ + if (ttf->incore) + { + TT_IOCHECK(ttf, ttf->img + (tt_ulong) offset <= ttf->end); + ttf->pos = ttf->img + (tt_ulong) offset; + } + else + TT_IOCHECK(ttf, pdc_fseek(ttf->fp, offset, SEEK_SET) == 0); +} + +void +tt_read(tt_file *ttf, void *buf, unsigned int nbytes) +{ + if (ttf->incore) + { + TT_IOCHECK(ttf, ttf->pos + (tt_ulong) nbytes <= ttf->end); + memcpy(buf, ttf->pos, (size_t) nbytes); + ttf->pos += (tt_ulong) nbytes; + } + else + TT_IOCHECK(ttf, PDC_OK_FREAD(ttf->fp, buf, nbytes)); +} + +long +tt_tell(tt_file *ttf) +{ + if (ttf->incore) + return (long) (ttf->pos - ttf->img); + else + return (long) pdc_ftell(ttf->fp); +} + +tt_ushort +tt_get_ushort(tt_file *ttf) +{ + tt_byte *pos, buf[2]; + + if (ttf->incore) + { + pos = ttf->pos; + TT_IOCHECK(ttf, (ttf->pos += 2) <= ttf->end); + } + else + { + pos = buf; + TT_IOCHECK(ttf, PDC_OK_FREAD(ttf->fp, buf, 2)); + } + + return pdc_get_be_ushort(pos); +} + +tt_short +tt_get_short(tt_file *ttf) +{ + tt_byte *pos, buf[2]; + + if (ttf->incore) + { + pos = ttf->pos; + TT_IOCHECK(ttf, (ttf->pos += 2) <= ttf->end); + } + else + { + pos = buf; + TT_IOCHECK(ttf, PDC_OK_FREAD(ttf->fp, buf, 2)); + } + + return pdc_get_be_short(pos); +} + +tt_ulong +tt_get_ulong3(tt_file *ttf) +{ + tt_byte *pos, buf[3]; + + if (ttf->incore) + { + pos = ttf->pos; + TT_IOCHECK(ttf, (ttf->pos += 3) <= ttf->end); + } + else + { + pos = buf; + TT_IOCHECK(ttf, PDC_OK_FREAD(ttf->fp, buf, 3)); + } + + return pdc_get_be_ulong3(pos); +} + +tt_ulong +tt_get_ulong(tt_file *ttf) +{ + tt_byte *pos, buf[4]; + + if (ttf->incore) + { + pos = ttf->pos; + TT_IOCHECK(ttf, (ttf->pos += 4) <= ttf->end); + } + else + { + pos = buf; + TT_IOCHECK(ttf, PDC_OK_FREAD(ttf->fp, buf, 4)); + } + + return pdc_get_be_ulong(pos); +} + +tt_long +tt_get_long(tt_file *ttf) +{ + tt_byte *pos, buf[4]; + + if (ttf->incore) + { + pos = ttf->pos; + TT_IOCHECK(ttf, (ttf->pos += 4) <= ttf->end); + } + else + { + pos = buf; + TT_IOCHECK(ttf, PDC_OK_FREAD(ttf->fp, buf, 4)); + } + + return pdc_get_be_long(pos); +} + +tt_ulong +tt_get_offset(tt_file *ttf, tt_byte offsize) +{ + tt_byte buf; + + switch (offsize) + { + case 1: + tt_read(ttf, &buf, 1); + return (tt_ulong) buf; + + case 2: + return (tt_ulong) tt_get_ushort(ttf); + + case 3: + return (tt_ulong) tt_get_ulong3(ttf); + + case 4: + return (tt_ulong) tt_get_ulong(ttf); + } + return 0; +} + +static void +tt_get_dirent(tt_dirent *dirent, tt_file *ttf) +{ + tt_read(ttf, dirent->tag, 4); + dirent->tag[4] = 0; + dirent->checksum = tt_get_ulong(ttf); + dirent->offset = tt_get_ulong(ttf); + dirent->length = tt_get_ulong(ttf); +} /* tt_get_dirent */ + + +int +tt_tag2idx(tt_file *ttf, char *tag) +{ + int i; + + for (i = 0; i < ttf->n_tables; ++i) + if (strcmp(ttf->dir[i].tag, tag) == 0) + return i; + + return -1; +} /* tt_tag2idx */ + +void * +tt_get_tab(tt_file *ttf, char *tag, size_t nbytes, pdc_bool tterror, + tt_ulong *offset) +{ + static const char *fn = "tt_get_tab"; + pdc_core *pdc = ttf->pdc; + int idx = tt_tag2idx(ttf, tag); + + if (idx == -1) + { + if (tterror) + tt_error(ttf); + return NULL; + } + + tt_seek(ttf, (long) ttf->dir[idx].offset); + + if (offset) + *offset = ttf->dir[idx].offset; + + return pdc_malloc(pdc, nbytes, fn); +} + +static void +tt_get_cmap0(tt_file *ttf, tt_cmap0_6 *cm0_6) +{ + static const char *fn = "tt_get_cmap0"; + pdc_core *pdc = ttf->pdc; + tt_ushort c; + tt_byte buf[256]; + + cm0_6->glyphIdArray = (tt_ushort *) 0; + + cm0_6->length = tt_get_ushort(ttf); + cm0_6->language = tt_get_ushort(ttf); + + /* These are not used in format 0 */ + cm0_6->firstCode = 0; + cm0_6->entryCount = 256; + + cm0_6->glyphIdArray = (tt_ushort *) + pdc_malloc(pdc, (size_t) (sizeof (tt_ushort) * 256), fn); + + tt_read(ttf, buf, 256); + + for (c = 0; c < 256; c++) + cm0_6->glyphIdArray[c] = (tt_ushort) buf[c]; + +} /* tt_get_cmap0 */ + +static void +tt_get_cmap6(tt_file *ttf, tt_cmap0_6 *cm0_6) +{ + static const char *fn = "tt_get_cmap6"; + pdc_core *pdc = ttf->pdc; + tt_ushort c, last, cmax; + + cm0_6->glyphIdArray = (tt_ushort *) 0; + + cm0_6->length = tt_get_ushort(ttf); + cm0_6->language = tt_get_ushort(ttf); + cm0_6->firstCode = tt_get_ushort(ttf); + cm0_6->entryCount = tt_get_ushort(ttf); + + last = (tt_ushort) (cm0_6->firstCode + cm0_6->entryCount); + cmax = MAX(last, 256); + + cm0_6->glyphIdArray = (tt_ushort *) + pdc_malloc(pdc, (size_t) (sizeof (tt_ushort) * cmax), fn); + + /* default for codes outside the range specified in this table */ + for (c = 0; c < cmax; c++) + cm0_6->glyphIdArray[c] = (tt_ushort) 0; + + for (c = cm0_6->firstCode; c < last; c++) + cm0_6->glyphIdArray[c] = tt_get_ushort(ttf); + +} /* tt_get_cmap6 */ + +static void +tt_get_cmap4(tt_file *ttf, tt_cmap4 *cm4) +{ + static const char *fn = "tt_get_cmap4"; + pdc_core *pdc = ttf->pdc; + int i, segs; + + /* the instruction order is critical for cleanup after exceptions! + */ + cm4->endCount = (tt_ushort *) 0; + cm4->startCount = (tt_ushort *) 0; + cm4->idDelta = (tt_short *) 0; + cm4->idRangeOffs = (tt_ushort *) 0; + cm4->glyphIdArray = (tt_ushort *) 0; + + cm4->length = tt_get_ushort(ttf); + cm4->version = tt_get_ushort(ttf); + cm4->segCountX2 = tt_get_ushort(ttf); + cm4->searchRange = tt_get_ushort(ttf); + cm4->entrySelector = tt_get_ushort(ttf); + cm4->rangeShift = tt_get_ushort(ttf); + + segs = cm4->segCountX2 / 2; + + cm4->numGlyphIds = (tt_ushort)( + ((cm4->length - ( 16L + 8L * segs )) & 0xFFFFU) / 2); + + TT_IOCHECK(ttf, 0 <= cm4->numGlyphIds); + + cm4->endCount = + (tt_ushort *) + pdc_malloc(pdc, (size_t) (sizeof (tt_ushort) * segs), fn); + cm4->startCount = + (tt_ushort *) + pdc_malloc(pdc, (size_t) (sizeof (tt_ushort) * segs), fn); + cm4->idDelta = + (tt_short *) + pdc_malloc(pdc, (size_t) (sizeof (tt_ushort) * segs), fn); + cm4->idRangeOffs = + (tt_ushort *) + pdc_malloc(pdc, (size_t) (sizeof (tt_ushort) * segs), fn); + + if (cm4->numGlyphIds) + { + cm4->glyphIdArray = (tt_ushort *) + pdc_malloc(pdc, + (size_t) (sizeof (tt_ushort) * cm4->numGlyphIds), fn); + } + + for (i = 0; i < segs; ++i) + cm4->endCount[i] = tt_get_ushort(ttf); + + TT_IOCHECK(ttf, cm4->endCount[segs - 1] == 0xFFFF); + + (void) tt_get_ushort(ttf); /* padding */ + for (i = 0; i < segs; ++i) cm4->startCount[i] = tt_get_ushort(ttf); + for (i = 0; i < segs; ++i) cm4->idDelta[i] = tt_get_short(ttf); + for (i = 0; i < segs; ++i) cm4->idRangeOffs[i] = tt_get_ushort(ttf); + + for (i = 0; i < cm4->numGlyphIds; ++i) + cm4->glyphIdArray[i] = tt_get_ushort(ttf); + + /* empty cmap */ + if (segs == 1 && cm4->endCount[0] == cm4->startCount[0]) + { + cm4->segCountX2 = 0; + pdc_free(pdc, cm4->endCount); + cm4->endCount = (tt_ushort *) 0; + pdc_free(pdc, cm4->startCount); + cm4->startCount = (tt_ushort *) 0; + pdc_free(pdc, cm4->idDelta); + cm4->idDelta = (tt_short *) 0; + pdc_free(pdc, cm4->idRangeOffs); + cm4->idRangeOffs = (tt_ushort *) 0; + if (cm4->numGlyphIds) + { + pdc_free(pdc, cm4->glyphIdArray); + cm4->glyphIdArray = (tt_ushort *) 0; + } + } + +} /* tt_get_cmap4 */ + + +void +tt_get_tab_cmap(tt_file *ttf) +{ + static const char *fn = "tt_get_tab_cmap"; + pdc_core *pdc = ttf->pdc; + tt_tab_cmap *tp = NULL; + tt_ulong offset; + tt_ushort numEncTabs; + tt_ushort platformID = 0; + tt_ushort encodingID = 0; + tt_ushort tableFormat = 0; + tt_ulong offsetEncTab = 0; + tt_ulong offset_mac = 0; + tt_ulong offset_win = 0; + tt_ulong offset_ucs4 = 0; + tt_long pos = 0; + int i; + + tp = (tt_tab_cmap *) tt_get_tab(ttf, fnt_str_cmap, sizeof (tt_tab_cmap), + !ttf->fortet, &offset); + if (tp == NULL) + return; + ttf->tab_cmap = tp; + + tp->win = (tt_cmap4 *) 0; + tp->mac = (tt_cmap0_6 *) 0; + tp->ucs4 = (tt_cmap12 *) 0; + + tp->platform = 0; + tp->encoding = 0; + tp->format = 0; + tp->offset = 0; + tp->length = 0; + + (void) tt_get_ushort(ttf); /* version */ + numEncTabs = tt_get_ushort(ttf); + + pdc_logg_cond(pdc, 2, trc_font, + "\tSearching for cmap table entries:\n"); + for (i = 0; i < numEncTabs; ++i) + { + platformID = tt_get_ushort(ttf); + encodingID = tt_get_ushort(ttf); + offsetEncTab = tt_get_ulong(ttf); + pos = tt_tell(ttf); + + tt_seek(ttf, (long) (offset + offsetEncTab)); + tableFormat = tt_get_ushort(ttf); + + pdc_logg_cond(pdc, 2, trc_font, + "\t\tplatformID: %d, encodingID: %2d, " + "tableFormat: %2d, offsetEncTab: 0x%04X\n", + platformID, encodingID, tableFormat, offsetEncTab); + + /* + * platformID: 0 encodingID: 0 tableFormat: 0 + * platformID: 1 encodingID: 0 tableFormat: 0/6 + */ + if (((platformID == tt_pfid_uni && tableFormat == 0) || + platformID == tt_pfid_mac) && encodingID == tt_wenc_symbol) + { + /* we currently do not support cmaps + ** other than format 0 and 6 for Macintosh cmaps. + */ + + if (tableFormat == 0 && tp->mac == (tt_cmap0_6 *) 0) + { + tp->mac = (tt_cmap0_6 *) + pdc_malloc(pdc, sizeof (tt_cmap0_6), fn); + tp->mac->format = 0; + tt_get_cmap0(ttf, tp->mac); + } + else if (tableFormat == 6 && tp->mac == (tt_cmap0_6 *) 0) + { + tp->mac = (tt_cmap0_6 *) + pdc_malloc(pdc, sizeof (tt_cmap0_6), fn); + tp->mac->format = 6; + tt_get_cmap6(ttf, tp->mac); + } + offset_mac = offsetEncTab; + } + + /* + * platformID: 0 encodingID: 3 tableFormat: 4 (old mac) + * platformID: 3 encodingID: 0/1 tableFormat: 4 + */ + else if ((tp->win == (tt_cmap4 *) 0 && tableFormat == 4) && + ((platformID == tt_pfid_win && + (encodingID == tt_wenc_symbol || + encodingID == tt_wenc_text)) || + (platformID == tt_pfid_uni && + encodingID == tt_wenc_mtext))) + { + tp->win = (tt_cmap4 *) pdc_malloc(pdc, sizeof (tt_cmap4), fn); + tp->win->format = tableFormat; + + /* we suppose a windows platform (see old mac hostfont Times) */ + if (encodingID == tt_wenc_mtext) + { + encodingID = tt_wenc_text; + } + + tt_get_cmap4(ttf, tp->win); + + if (tp->win->segCountX2) + { + tp->win->encodingID = encodingID; + } + else + { + pdc_free(pdc, tp->win); + tp->win = (tt_cmap4 *) 0; + } + offset_win = offsetEncTab; + } + + + tt_seek(ttf, pos); + } /* for */ + + /* is symbol font */ + ttf->issymbol = (tp->win && tp->win->encodingID == tt_wenc_symbol) ? + pdc_true : pdc_false; + + /* has Unicode cmap */ + ttf->haswinuni = (!ttf->issymbol && (tp->win || tp->ucs4)) ? + pdc_true : pdc_false; + + /* has only Mac cmap */ + ttf->hasonlymac = (tp->mac && !tp->win && !tp->ucs4) ? + pdc_true : pdc_false; + + if (ttf->hasonlymac) + { + tp->platform = tt_pfid_mac; + tp->encoding = tt_wenc_symbol; + tp->format = tp->mac->format; + tp->offset = offset_mac; + tp->length = tp->mac->length; + } + else if (tp->win || tp->ucs4) + { + tp->platform = tt_pfid_win; + if (ttf->issymbol) + { + tp->encoding = tt_wenc_symbol; + tp->format = tp->win->format; + tp->offset = offset_win; + tp->length = tp->win->length; + } + else if (tp->ucs4) + { + tp->encoding = tt_wenc_utext; + tp->format = tp->ucs4->format; + tp->offset = offset_ucs4; + tp->length = tp->ucs4->length; + } + else + { + tp->encoding = tt_wenc_text; + tp->format = tp->win->format; + tp->offset = offset_win; + tp->length = tp->win->length; + } + } + + pdc_logg_cond(ttf->pdc, 1, trc_font, + "\tUsed cmap table entry:\n" + "\t\tplatformID: %d, encodingID: %2d, tableFormat: %2d (%s font)\n", + tp->platform, tp->encoding, tp->format, + ttf->issymbol ? "symbol" : "text"); + + /* for subsetting and symbolic font: + * tp->platform = tt_pfid_mac according PDF specification + * otherwise GS will emit an error message + */ + if (ttf->issymbol && offset_mac > 0) + { + tp->platform = tt_pfid_mac; + tp->encoding = tt_wenc_symbol; + tp->format = tp->mac->format; + tp->offset = offset_mac; + tp->length = tp->mac->length; + } + +} /* tt_get_tab_cmap */ + +void +tt_get_tab_head(tt_file *ttf) +{ + tt_tab_head *tp = NULL; + + tp = (tt_tab_head *) tt_get_tab(ttf, fnt_str_head, sizeof (tt_tab_head), + !ttf->fortet, NULL); + if (tp == NULL) + return; + ttf->tab_head = tp; + + tp->version = tt_get_fixed(ttf); + tp->fontRevision = tt_get_fixed(ttf); + tp->checkSumAdjustment = tt_get_ulong(ttf); + tp->magicNumber = tt_get_ulong(ttf); + tp->flags = tt_get_ushort(ttf); + tp->unitsPerEm = tt_get_ushort(ttf); + tp->created[1] = tt_get_ulong(ttf); + tp->created[0] = tt_get_ulong(ttf); + tp->modified[1] = tt_get_ulong(ttf); + tp->modified[0] = tt_get_ulong(ttf); + tp->xMin = tt_get_fword(ttf); + tp->yMin = tt_get_fword(ttf); + tp->xMax = tt_get_fword(ttf); + tp->yMax = tt_get_fword(ttf); + tp->macStyle = tt_get_ushort(ttf); + tp->lowestRecPPEM = tt_get_ushort(ttf); + tp->fontDirectionHint = tt_get_short(ttf); + tp->indexToLocFormat = tt_get_short(ttf); + tp->glyphDataFormat = tt_get_short(ttf); +} /* tt_get_tab_head */ + +static void +tt_get_tab_hhea(tt_file *ttf) +{ + tt_tab_hhea *tp = NULL; + + tp = (tt_tab_hhea *) tt_get_tab(ttf, fnt_str_hhea, sizeof (tt_tab_hhea), + !ttf->fortet, NULL); + if (tp == NULL) + return; + ttf->tab_hhea = tp; + + tp->version = tt_get_fixed(ttf); + tp->ascender = tt_get_fword(ttf); + tp->descender = tt_get_fword(ttf); + tp->lineGap = tt_get_fword(ttf); + tp->advanceWidthMax = tt_get_fword(ttf); + tp->minLeftSideBearing = tt_get_fword(ttf); + tp->minRightSideBearing = tt_get_fword(ttf); + tp->xMaxExtent = tt_get_fword(ttf); + tp->caretSlopeRise = tt_get_short(ttf); + tp->caretSlopeRun = tt_get_short(ttf); + tp->res1 = tt_get_short(ttf); + tp->res2 = tt_get_short(ttf); + tp->res3 = tt_get_short(ttf); + tp->res4 = tt_get_short(ttf); + tp->res5 = tt_get_short(ttf); + tp->metricDataFormat = tt_get_short(ttf); + tp->numberOfHMetrics = tt_get_ushort(ttf); +} /* tt_get_tab_hhea */ + +static void +tt_get_tab_hmtx(tt_file *ttf) +{ + static const char *fn = "tt_get_tab_hmtx"; + pdc_core *pdc = ttf->pdc; + tt_tab_hmtx *tp = NULL; + int n_metrics; + int n_lsbs; + int i; + + tp = (tt_tab_hmtx *) tt_get_tab(ttf, fnt_str_hmtx, sizeof (tt_tab_hmtx), + !ttf->fortet, NULL); + if (tp == NULL) + return; + ttf->tab_hmtx = tp; + + TT_ASSERT(ttf, ttf->tab_hhea != 0); + TT_ASSERT(ttf, ttf->tab_maxp != 0); + + tp->metrics = 0; + tp->lsbs = 0; + + n_metrics = ttf->tab_hhea->numberOfHMetrics; + n_lsbs = ttf->numGlyphs - n_metrics; + + TT_IOCHECK(ttf, n_metrics != 0); + TT_IOCHECK(ttf, n_lsbs >= 0); + tp->metrics = (tt_metric *) + pdc_malloc(pdc, n_metrics * sizeof (tt_metric), fn); + + for (i = 0; i < n_metrics; ++i) + { + tp->metrics[i].advanceWidth = tt_get_fword(ttf); + tp->metrics[i].lsb = tt_get_fword(ttf); + } + + if (n_lsbs == 0) + tp->lsbs = (tt_fword *) 0; + else + { + tp->lsbs = (tt_fword *) + pdc_malloc(pdc, n_lsbs * sizeof (tt_fword), fn); + for (i = 0; i < n_lsbs; ++i) + tp->lsbs[i] = tt_get_fword(ttf); + } +} /* tt_get_tab_hmtx */ + + + +pdc_bool +tt_get_tab_CFF_(tt_file *ttf) +{ + static const char *fn = "tt_get_tab_CFF_"; + pdc_core *pdc = ttf->pdc; + int idx = tt_tag2idx(ttf, fnt_str_CFF_); + + if (idx != -1) + { + /* CFF table found */ + ttf->tab_CFF_ = (tt_tab_CFF_ *) + pdc_malloc(pdc, sizeof (tt_tab_CFF_), fn); + ttf->tab_CFF_->offset = ttf->dir[idx].offset; + ttf->tab_CFF_->length = ttf->dir[idx].length; + } + else if (!ttf->fortet) + { + idx = tt_tag2idx(ttf, fnt_str_glyf); + if (idx == -1 || !ttf->dir[idx].length) + { + pdc_set_errmsg(pdc, FNT_E_TT_NOGLYFDESC, 0, 0, 0, 0); + return pdc_false; + } + idx = -1; + } + + + return pdc_true; + +} /* tt_get_tab_CFF_ */ + +void +tt_get_tab_maxp(tt_file *ttf) +{ + tt_tab_maxp *tp = NULL; + + tp = (tt_tab_maxp *) tt_get_tab(ttf, fnt_str_maxp, sizeof (tt_tab_maxp), + !ttf->fortet, NULL); + if (tp == NULL) + return; + ttf->tab_maxp = tp; + + tp->version = tt_get_fixed(ttf); + tp->numGlyphs = tt_get_ushort(ttf); + tp->maxPoints = tt_get_ushort(ttf); + tp->maxContours = tt_get_ushort(ttf); + tp->maxCompositePoints = tt_get_ushort(ttf); + tp->maxCompositeContours = tt_get_ushort(ttf); + tp->maxZones = tt_get_ushort(ttf); + tp->maxTwilightPoints = tt_get_ushort(ttf); + tp->maxStorage = tt_get_ushort(ttf); + tp->maxFunctionDefs = tt_get_ushort(ttf); + tp->maxInstructionDefs = tt_get_ushort(ttf); + tp->maxStackElements = tt_get_ushort(ttf); + tp->maxSizeOfInstructions = tt_get_ushort(ttf); + tp->maxComponentElements = tt_get_ushort(ttf); + tp->maxComponentDepth = tt_get_ushort(ttf); + + ttf->numGlyphs = tp->numGlyphs; + +} /* tt_get_tab_maxp */ + +pdc_bool +tt_get_tab_name(tt_file *ttf) +{ + static const char *fn = "tt_get_tab_name"; + pdc_core *pdc = ttf->pdc; + pdc_bool logg5 = pdc_logg_is_enabled(pdc, 5, trc_font); + tt_tab_name *tp = NULL; + int i, j, k, namid, irec, irec4 = -1, irec6 = -1; + size_t len; + tt_nameref *namerec = NULL, lastnamerec; + char *localname = NULL; + tt_ulong offset, offs; + + tp = (tt_tab_name *) tt_get_tab(ttf, fnt_str_name, sizeof (tt_tab_name ), + pdc_false, &offset); + if (tp == NULL) + return pdc_false; + ttf->tab_name = tp; + + tp->namerecords = NULL; + tp->englishname4 = NULL; + tp->englishname6 = NULL; + tp->producer = NULL; + + tp->format = tt_get_ushort(ttf); + + /* Format 0 is the only document one, but some Apple fonts use 65535. + * This is very consequent since it follows Microsoft's lead in + * disregarding one's own published specifications. + */ + TT_IOCHECK(ttf, (tp->format == 0 || tp->format == 65535)); + + tp->numNameRecords = (tt_ushort) + tt_get_offset(ttf, sizeof(tt_ushort)); + tp->offsetStrings = tt_get_ushort(ttf); + offs = offset + tp->offsetStrings; + + pdc_logg_cond(pdc, 1, trc_font, + "\tRecords in name table of format %d: %d:\n", + tp->format, tp->numNameRecords); + + /* this was observed. we ignore it in TET */ + if (ttf->fortet && tp->numNameRecords == 0) + return pdc_true; + + TT_IOCHECK(ttf, (tp->numNameRecords > 0)); + + len = tp->numNameRecords * sizeof (tt_nameref); + tp->namerecords = (tt_nameref *) pdc_malloc(pdc, len, fn); + + for (i = 0; i < tp->numNameRecords; ++i) + { + tt_ushort platformID = tt_get_ushort(ttf); + tt_ushort encodingID = tt_get_ushort(ttf); + tt_ushort languageID = tt_get_ushort(ttf); + tt_ushort nameID = tt_get_ushort(ttf); + tt_ushort stringLength = tt_get_ushort(ttf); + tt_ushort stringOffset = tt_get_ushort(ttf); + + namerec = &tp->namerecords[i]; + namerec->platform = platformID; + namerec->encoding = encodingID; + namerec->language = languageID; + namerec->namid = nameID; + namerec->length = stringLength; + namerec->offset = stringOffset; + } + + namid = 4; + for (k = 0; k < 2; k++) + { + lastnamerec.platform = 0; + lastnamerec.language = 0; + lastnamerec.namid = 0; + lastnamerec.length = 0; + lastnamerec.offset = 0; + + for (i = 0; i < tp->numNameRecords; ++i) + { + localname = NULL; + namerec = &tp->namerecords[i]; + + if (logg5 && !k) + { + pdc_logg(pdc, "\t\t\t%2d. platformID: %d\n" + "\t\t\t encodingID: %d\n" + "\t\t\t languageID: %d\n" + "\t\t\t nameID: %d\n" + "\t\t\t length: %d\n" + "\t\t\t offset: %d\n", + i, + namerec->platform, namerec->encoding, + namerec->language, namerec->namid, + namerec->length, namerec->offset); + + /* read font name */ + if (namerec->length) + { + localname = + (char *) pdc_calloc(pdc, (size_t) namerec->length, fn); + tt_seek(ttf, (long) (offs + namerec->offset)); + tt_read(ttf, localname, (unsigned int) namerec->length); + + pdc_logg_hexdump(pdc, "data", "\t\t\t ", + localname, namerec->length); + } + pdc_logg(pdc, "\n"); + } + + if (tp->producer == NULL && + namerec->platform == tt_pfid_mac && + namerec->encoding == tt_wenc_symbol && + namerec->language == 0 && + namerec->namid == 0) + { + tp->producer = (char *) pdc_calloc(pdc, + (size_t) namerec->length + 1, fn); + tt_seek(ttf, (long) (offs + namerec->offset)); + tt_read(ttf, tp->producer, (unsigned int) namerec->length); + } + + if (namerec->length && namerec->namid == namid) + { + /* TTC font search */ + if (ttf->utf16fontname) + { + /* read font name */ + if (localname == NULL) + { + localname = (char *) pdc_calloc(pdc, + (size_t) namerec->length, fn); + tt_seek(ttf, (long) (offs + namerec->offset)); + tt_read(ttf, localname, (unsigned int) namerec->length); + } + + if (namerec->platform == tt_pfid_win) + { + pdc_logg_cond(pdc, 1, trc_font, + "\tUnicode fontname: \"%T\"\n", + localname, namerec->length); + + if (namerec->length == ttf->fnamelen && + !memcmp(localname, ttf->utf16fontname, + (size_t) ttf->fnamelen)) + { + /* font found */ + pdc_free(pdc, localname); + return pdc_true; + } + } + } + + /* search for the records with english names */ + else + { + /* we take the names from platformID 3 (Microsoft) or + * 1 (Macintosh). We favor Macintosh and then Microsoft + * with American English (LanguageID = 0x0409 = 1033) + */ + if ((lastnamerec.language != 0x0409 || + lastnamerec.platform != tt_pfid_win) && + (namerec->platform == tt_pfid_win || + (namerec->platform == tt_pfid_mac && + namerec->language == 0))) + { + lastnamerec = *namerec; + + /* We simulate always English */ + if (namerec->platform == tt_pfid_mac) + lastnamerec.language = 0x0409; + + if (namid == 4) irec4 = i; + if (namid == 6) irec6 = i; + } + } + } + + if (localname != NULL) + pdc_free(pdc, localname); + } + namid = 6; + } + + /* TTC font not found */ + if (ttf->utf16fontname) + return pdc_false; + + /* English font names */ + namid = 4; + irec = irec4; + for (k = 0; k < 2; k++) + { + if (irec == -1) + continue; + namerec = &tp->namerecords[irec]; + + /* read font name */ + len = (size_t) (namerec->length + 1); + localname = (char *) pdc_calloc(pdc, (size_t) len, fn); + tt_seek(ttf, (long) (offs + namerec->offset)); + tt_read(ttf, localname, (unsigned int) namerec->length); + + /* low byte picking */ + if (namerec->platform == tt_pfid_win) + { + for (j = 0; j < namerec->length / 2; j++) + { + /* We don't support wide character names */ + if (localname[2*j] != 0) + { + pdc_free(pdc, localname); + localname = NULL; + break; + } + localname[j] = localname[2*j + 1]; + } + if (localname) + localname[j] = 0; + } + + /* We observed this in EUDC fonts */ + if (localname && !strcmp(localname, "\060\060")) + { + pdc_free(pdc, localname); + localname = NULL; + } + + if (namid == 4 && localname) + tp->englishname4 = localname; + else if (namid == 6 && localname) + tp->englishname6 = localname; + + namid = 6; + irec = irec6; + } + + /* font name 4 (full font name) is required */ + if (tp->englishname6 == NULL && tp->englishname4 == NULL) + { + if (!ttf->fortet) + { + pdc_set_errmsg(pdc, FNT_E_TT_NONAME, 0, 0, 0, 0); + return pdc_false; + } + } + else + { + if (tp->englishname4 == NULL) + tp->englishname4 = pdc_strdup(pdc, tp->englishname6); + if (tp->englishname6 == NULL) + tp->englishname6 = pdc_strdup(pdc, tp->englishname4); + } + + return pdc_true; +} /* tt_get_tab_name */ + +static int tt_cpflag2cp[64] = +{ + 1252, 1250, 1251, 1253, 1254, 1255, 1256, 1257, + 1258, 0, 0, 0, 0, 0, 0, 0, + 874, 932, 936, 949, 950, 1361, 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, + 869, 866, 865, 864, 863, 862, 861, 860, + 857, 855, 852, 775, 737, 708, 850, 437 +}; + +static int tt_cpflag2charcoll[4] = +{ + cc_japanese, cc_simplified_chinese, cc_korean, cc_traditional_chinese +}; + +void +tt_get_tab_OS_2(tt_file *ttf) +{ + pdc_bool logg3 = pdc_logg_is_enabled(ttf->pdc, 3, trc_font); + int i, j; + + tt_tab_OS_2 *tp = NULL; + + tp = (tt_tab_OS_2 *) tt_get_tab(ttf, fnt_str_OS_2, sizeof (tt_tab_OS_2), + pdc_false, NULL); + if (tp == NULL) + return; + ttf->tab_OS_2 = tp; + + tp->version = tt_get_ushort(ttf); + tp->xAvgCharWidth = tt_get_short(ttf); + tp->usWeightClass = tt_get_ushort(ttf); + tp->usWidthClass = tt_get_ushort(ttf); + tp->fsType = tt_get_ushort(ttf); + tp->ySubscriptXSize = tt_get_short(ttf); + tp->ySubscriptYSize = tt_get_short(ttf); + tp->ySubscriptXOffset = tt_get_short(ttf); + tp->ySubscriptYOffset = tt_get_short(ttf); + tp->ySuperscriptXSize = tt_get_short(ttf); + tp->ySuperscriptYSize = tt_get_short(ttf); + tp->ySuperscriptXOffset = tt_get_short(ttf); + tp->ySuperscriptYOffset = tt_get_short(ttf); + tp->yStrikeoutSize = tt_get_short(ttf); + tp->yStrikeoutPosition = tt_get_short(ttf); + tp->sFamilyClass = tt_get_ushort(ttf); + + tt_read(ttf, tp->panose, 10); + + tp->ulUnicodeRange1 = tt_get_ulong(ttf); + tp->ulUnicodeRange2 = tt_get_ulong(ttf); + tp->ulUnicodeRange3 = tt_get_ulong(ttf); + tp->ulUnicodeRange4 = tt_get_ulong(ttf); + + tt_read(ttf, tp->achVendID, 4); + + tp->fsSelection = tt_get_ushort(ttf); + tp->usFirstCharIndex = tt_get_ushort(ttf); + tp->usLastCharIndex = tt_get_ushort(ttf); + tp->sTypoAscender = tt_get_short(ttf); + tp->sTypoDescender = tt_get_short(ttf); + tp->sTypoLineGap = tt_get_short(ttf); + tp->usWinAscent = tt_get_ushort(ttf); + tp->usWinDescent = tt_get_ushort(ttf); + + if (tp->version >= 1) + { + tp->ulCodePageRange1 = tt_get_ulong(ttf); + tp->ulCodePageRange2 = tt_get_ulong(ttf); + } + else + { + tp->ulCodePageRange1 = 0; + tp->ulCodePageRange2 = 0; + } + + for (i = 0; i < PDC_NUMCHARCOLL; i++) + { + j = i + 17; + if (tp->ulCodePageRange1 & (1<charcolls[i] = tt_cpflag2charcoll[i]; + else + tp->charcolls[i] = cc_none; + } + + if (tp->version >= 2) + { + tp->sxHeight = tt_get_short(ttf); + tp->sCapHeight = tt_get_short(ttf); + tp->usDefaultChar = tt_get_ushort(ttf); + tp->usBreakChar = tt_get_ushort(ttf); + tp->usMaxContext = tt_get_ushort(ttf); + } + else + { + tp->sxHeight = FNT_MISSING_FONTVAL; + tp->sCapHeight = FNT_MISSING_FONTVAL; + tp->usDefaultChar = 0; + tp->usBreakChar = 0; + tp->usMaxContext = 0; + } + + /* there are fonts with inconsistent usFirstCharIndex */ + if (ttf->tab_cmap && ttf->tab_cmap->win && + tp->usFirstCharIndex != ttf->tab_cmap->win->startCount[0]) + ttf->tab_OS_2->usFirstCharIndex = ttf->tab_cmap->win->startCount[0]; + + if (logg3) + { + int nbit = 8 * sizeof(tt_ulong); + + pdc_logg_bitarr(ttf->pdc, "\t\tulUnicodeRange1 ", + (char *) &tp->ulUnicodeRange1, nbit); + pdc_logg_bitarr(ttf->pdc, "\t\tulUnicodeRange2 ", + (char *) &tp->ulUnicodeRange2, nbit); + pdc_logg_bitarr(ttf->pdc, "\t\tulUnicodeRange3 ", + (char *) &tp->ulUnicodeRange3, nbit); + pdc_logg_bitarr(ttf->pdc, "\t\tulUnicodeRange4 ", + (char *) &tp->ulUnicodeRange4, nbit); + + if (tp->version >= 1) + { + int n = 0; + + pdc_logg_bitarr(ttf->pdc, "\t\tulCodePageRange1", + (char *) &tp->ulCodePageRange1, nbit); + pdc_logg_bitarr(ttf->pdc, "\t\tulCodePageRange2", + (char *) &tp->ulCodePageRange2, nbit); + + for (i = 0; i < 32; i++) + { + if ((tp->ulCodePageRange1 & (1<pdc, "%s%d", + (n ? ", " : "\t\tsupported code pages: "), + tt_cpflag2cp[i]); + n++; + } + } + for (i = 0; i < 32; i++) + { + j = i + 32; + if ((tp->ulCodePageRange1 & (1<pdc, "%s%d", + (n ? ", " : "\t\tsupported code pages: "), + tt_cpflag2cp[j]); + n++; + } + } + + if (n) + pdc_logg(ttf->pdc, "\n"); + + n = 0; + for (i = 0; i < PDC_NUMCHARCOLL; i++) + { + if (tp->charcolls[i]) + { + pdc_logg(ttf->pdc, "%s%s", + (n ? ", " : "\t\tsupported character collections: "), + fnt_get_ordering_cid(tp->charcolls[i])); + n++; + } + } + if (n) + pdc_logg(ttf->pdc, "\n"); + } + } +} /* tt_get_tab_OS_2 */ + + +static void +tt_get_tab_post(tt_file *ttf) +{ + tt_tab_post *tp = NULL; + + + tp = (tt_tab_post *) tt_get_tab(ttf, fnt_str_post, sizeof (tt_tab_post), + !ttf->fortet, NULL); + if (tp == NULL) + return; + ttf->tab_post = tp; + + tp->formatType = tt_get_fixed(ttf); + tp->italicAngle = (tt_get_fixed(ttf) / 65536.0); + tp->underlinePosition = tt_get_fword(ttf); + tp->underlineThickness = tt_get_fword(ttf); + tp->isFixedPitch = tt_get_ulong(ttf); + tp->minMemType42 = tt_get_ulong(ttf); + tp->maxMemType42 = tt_get_ulong(ttf); + tp->minMemType1 = tt_get_ulong(ttf); + tp->maxMemType1 = tt_get_ulong(ttf); + + +} /* tt_get_tab_post */ + + + +/*--------------------------- general functions ------------------------------*/ + +#define FNT_O ((char) 0x4f) /* ASCII 'O' */ +#define FNT_T ((char) 0x54) /* ASCII 'T' */ + +#define FNT_t ((char) 0x74) /* ASCII 't' */ +#define FNT_r ((char) 0x72) /* ASCII 'r' */ +#define FNT_u ((char) 0x75) /* ASCII 'u' */ +#define FNT_e ((char) 0x65) /* ASCII 'e' */ + +#define FNT_c ((char) 0x63) /* ASCII 'c' */ +#define FNT_f ((char) 0x66) /* ASCII 'f' */ + +static const char *fnt_filetypes[4] = +{ + "TrueType", "OpenType", "Apple TrueType", "TrueType Collection" +}; + +pdc_bool +fnt_test_tt_font(pdc_core *pdc, tt_byte *img, tt_ulong *n_fonts, + pdc_bool requested) +{ + tt_ushort n_tables; + int ift = 0; + pdc_bool retval = requested ? pdc_false : pdc_undef; + + /* The TrueType (including OpenType/TT) "version" is always 0x00010000 */ + if (!(img[0] == 0x00 && img[1] == 0x01 && + img[2] == 0x00 && img[3] == 0x00)) + { + ift++; + + /* The OpenType/CFF version is always 'OTTO' */ + if (!(img[0] == FNT_O && img[1] == FNT_T && + img[2] == FNT_T && img[3] == FNT_O)) + { + ift++; + + /* Old Apple fonts have 'true' */ + if (!(img[0] == FNT_t && img[1] == FNT_r && + img[2] == FNT_u && img[3] == FNT_e)) + { + ift++; + + /* TrueType Collection */ + if (n_fonts == NULL || + !(img[0] == FNT_t && img[1] == FNT_t && + img[2] == FNT_c && img[3] == FNT_f)) + return retval; + + /* Version is always 0x00010000 or 0x00020000 */ + if (!(img[4] == 0x00 && (img[5] == 0x01 || img[5] == 0x02) && + img[6] == 0x00 && img[7] == 0x00)) + return retval; + + /* Number of fonts */ + *n_fonts = pdc_get_be_ulong(&img[8]); + + pdc_logg_cond(pdc, 1, trc_font, + "\t%s font with %d single fonts detected\n", + fnt_filetypes[ift], *n_fonts); + + return pdc_true; + } + } + } + + /* Number of tables */ + n_tables = pdc_get_be_ushort(&img[4]); + if (n_tables < 8 && n_tables > 64) /* max. 32 tables ? */ + return retval; + + /* Further check of the next 6 bytes not implemented */ + + if (n_fonts == NULL) + pdc_logg_cond(pdc, 1, trc_font, + "\t%s font with %d tables detected\n", + fnt_filetypes[ift], n_tables); + + return pdc_true; +} + +pdc_bool +fnt_is_opentype_font(tt_file *ttf) +{ + return (ttf->img[0] == FNT_O && + ttf->img[1] == FNT_T && + ttf->img[2] == FNT_T && + ttf->img[3] == FNT_O) ? pdc_true : pdc_false; +} + +pdc_bool +fnt_read_offset_tab(tt_file *ttf) +{ + static const char *fn = "fnt_get_tab_offset"; + pdc_core *pdc = ttf->pdc; + tt_byte img[TT_OFFSETTAB_SIZE]; + int i; + + /* Check */ + tt_read(ttf, img, TT_OFFSETTAB_SIZE); + if (fnt_test_tt_font(pdc, img, NULL, pdc_true) == pdc_false) + { + pdc_set_errmsg(pdc, FNT_E_TT_NOFONT, ttf->filename, 0, 0, 0); + return pdc_false; + } + + /* number of table directories */ + ttf->n_tables = pdc_get_be_ushort(&img[4]); + + /* set up table directory */ + ttf->dir = (tt_dirent *) pdc_malloc(pdc, + (size_t) (ttf->n_tables * sizeof (tt_dirent)), fn); + + tt_seek(ttf, (long) (ttf->offset + TT_OFFSETTAB_SIZE)); + + for (i = 0; i < ttf->n_tables; ++i) + { + tt_get_dirent(ttf->dir + i, ttf); + } + + /* make sure this isn't a bitmap-only Mac font */ + if (tt_tag2idx(ttf, fnt_str_bhed) != -1) + { + pdc_set_errmsg(pdc, FNT_E_TT_BITMAP, 0, 0, 0, 0); + return pdc_false; + } + + return pdc_true; + +} /* fnt_read_offset_tab */ + +pdc_bool +fnt_read_tt(tt_file *ttf) +{ + pdc_core *pdc = ttf->pdc; + + PDC_TRY(pdc) + { + if (fnt_read_offset_tab(ttf) == pdc_false) + { + PDC_EXIT_TRY(pdc); + return pdc_false; + } + + /* These are all required TrueType tables; + * optional tables are not read. + */ + tt_get_tab_cmap(ttf); + tt_get_tab_head(ttf); + tt_get_tab_hhea(ttf); + tt_get_tab_maxp(ttf); + if (!ttf->fortet) + tt_get_tab_hmtx(ttf); /* MUST be read AFTER hhea & maxp! */ + if (tt_get_tab_name(ttf) == pdc_false && !ttf->fortet) + { + PDC_EXIT_TRY(pdc); + return pdc_false; + } + tt_get_tab_post(ttf); + tt_get_tab_OS_2(ttf); /* may be missing from some Apple fonts */ + + /* this is an optional table, present only in OpenType fonts */ + if (tt_get_tab_CFF_(ttf) == pdc_false && !ttf->fortet) + { + PDC_EXIT_TRY(pdc); + return pdc_false; + } + + + PDC_EXIT_TRY(pdc); + return pdc_true; + } + PDC_CATCH(pdc) + { + } + + return pdc_false; +} /* fnt_read_tt */ + + + +/* convert Unicode scalar to glyph ID using cmap12 or cmap4. + */ +int +tt_unicode2gidx(tt_file *ttf, int usv, pdc_bool logg) +{ + pdc_core *pdc = ttf->pdc; + tt_cmap4 *cm4 = ttf->tab_cmap->win; + pdc_ushort uv; + int segs; + int gidx = 0; + int i; + + uv = (pdc_ushort) usv; + if (logg) pdc_logg(pdc, "\t\t\tU+%04X: ", uv); + segs = cm4->segCountX2 / 2; + + for (i = 0; i < segs; ++i) + if (uv <= cm4->endCount[i]) + break; + + if (logg) pdc_logg(pdc, "i=%d start=U+%04X ", i, cm4->startCount[i]); + + TT_IOCHECK(ttf, i != segs); + if (uv < cm4->startCount[i] || uv == 0xFFFF) + { + if (logg) pdc_logg(pdc, "==> gidx=0\n"); + return 0; + } + + if (logg) pdc_logg(pdc, "offs=%d ", cm4->idRangeOffs[i]); + + if (cm4->idRangeOffs[i] == 0) + { + if (logg) pdc_logg(pdc, "delta=%d ", cm4->idDelta[i]); + gidx = (int)((uv + cm4->idDelta[i]) & 0xFFFF); + } + else + { + int idx = (int) cm4->idRangeOffs[i] / 2 + + (int) (uv - cm4->startCount[i]) - (segs - i); + + if (idx < 0 || idx >= cm4->numGlyphIds) + { + pdc_warning(pdc, FNT_E_TT_GLYPHIDNOTFOUND, + pdc_errprintf(pdc, "%04X", uv), + 0, 0, 0); + return 0; + } + + if (logg) pdc_logg(pdc, "array[%d]=%d ", idx, gidx); + if (cm4->glyphIdArray[idx] == 0) + { + if (logg) pdc_logg(pdc, "==> gidx=0\n"); + return 0; + } + else + { + if (logg) pdc_logg(pdc, "delta=%d ", cm4->idDelta[i]); + gidx = (int)((cm4->glyphIdArray[idx] + cm4->idDelta[i]) & 0xFFFF); + } + } + + if (logg) pdc_logg(pdc, "gidx=%d ", gidx); + + /* this is necessary because of some Mac fonts (e.g. Hiragino) */ + if (gidx >= ttf->numGlyphs) + { + gidx = 0; + if (logg) pdc_logg(pdc, "==> gidx=0\n"); + } + else if (logg) + pdc_logg(pdc, "\n"); + + return gidx; +} + +int +tt_gidx2width(tt_file *ttf, int gidx) +{ + TT_ASSERT(ttf, ttf->tab_hmtx != (tt_tab_hmtx *) 0); + TT_ASSERT(ttf, ttf->tab_hhea != (tt_tab_hhea *) 0); + + { + int n_metrics = ttf->tab_hhea->numberOfHMetrics; + + if (gidx >= n_metrics) + gidx = n_metrics - 1; + if (ttf->monospace) + return ttf->monospace; + else + { + return FNT_TT2PDF(ttf->tab_hmtx->metrics[gidx].advanceWidth); + } + } +} /* tt_gidx2width */ + +void +fnt_set_tt_fontvalues(tt_file *ttf) +{ + fnt_font *font = ttf->font; + fnt_font_metric *ftm = &font->m; + + if (ttf->onlyCFF) + return; + + if (ttf->tab_head) + { + ftm->llx = FNT_TT2PDF(ttf->tab_head->xMin); + ftm->lly = FNT_TT2PDF(ttf->tab_head->yMin); + ftm->urx = FNT_TT2PDF(ttf->tab_head->xMax); + ftm->ury = FNT_TT2PDF(ttf->tab_head->yMax); + } + + if (ttf->tab_post) + { + ftm->italicAngle = ttf->tab_post->italicAngle; + ftm->isFixedPitch = (pdc_bool) ttf->tab_post->isFixedPitch; + ftm->underlinePosition = FNT_TT2PDF(ttf->tab_post->underlinePosition); + ftm->underlineThickness =FNT_TT2PDF(ttf->tab_post->underlineThickness); + } + + if (ttf->tab_OS_2) + { + + font->weight = fnt_check_weight(ttf->tab_OS_2->usWeightClass); + ftm->ascender = FNT_TT2PDF(ttf->tab_OS_2->sTypoAscender); + ftm->descender = FNT_TT2PDF(ttf->tab_OS_2->sTypoDescender); + + if (ttf->tab_OS_2->sCapHeight != FNT_MISSING_FONTVAL) + ftm->capHeight = FNT_TT2PDF(ttf->tab_OS_2->sCapHeight); + if (ttf->tab_OS_2->sxHeight != FNT_MISSING_FONTVAL) + ftm->xHeight = FNT_TT2PDF(ttf->tab_OS_2->sxHeight); + font->linegap = FNT_TT2PDF(ttf->tab_OS_2->sTypoLineGap); + } + + /* some fonts have no OS/2 table and + * some Apple fonts have zero values in the OS/2 table . + */ + if (ttf->tab_OS_2 == NULL || + (ttf->tab_OS_2->usWeightClass == 0 && + ttf->tab_OS_2->sTypoAscender == 0 && + ttf->tab_OS_2->sTypoDescender == 0 && + ttf->tab_OS_2->sTypoLineGap == 0)) + { + font->weight = fnt_macfontstyle2weight(ttf->tab_head->macStyle); + ftm->ascender = FNT_TT2PDF(ttf->tab_hhea->ascender); + ftm->descender = FNT_TT2PDF(ttf->tab_hhea->descender); + font->linegap = FNT_TT2PDF(ttf->tab_hhea->lineGap); + } + + /* default width */ + if (!ttf->fortet) + { + ftm->defwidth = tt_gidx2width(ttf, 0); + } +} + + +/* + * Create and fill some arrays in font structure. + * + * Before calling function the members 'encoding' and 'ev' + * of font struct have to been set: + * + * The desired arrays must be requested by following flags + * (enc == font->enc): + * + * TT_FONT_encvec: Encoding vector (enc == pdc_builtin) + * + * TT_FONT_gid2code: font->gid2code[font->numglyphs]: + * glyph ID -> 8-bit code (enc >= 0, == pdc_builtin) + * glyph ID -> Unicode otherwise. + * + * TT_FONT_code2gid: font->code2gid[font->numcodes]: + * 8-bit code -> glyph ID (enc >= 0, == pdc_builtin) + * Unicode -> glyph ID (enc == pdc_unicode) + * glyph ID -> glyph ID (enc == pdc_glyphid) + * + * TT_FONT_gid2name font->gdi2name[font->numglyphs]: + * glyph ID -> glyph name (enc == pdc_glyphid only) + * + * TT_FONT_name2unitab font->name2unitab[font->tabsize]: + * glyph name -> Unicode for unregistered names + * + * TT_FONT_m_ciw font->m.ciw[font->m.numinters] (Interval table) + * Unicode -> glyph width (enc == pdc_unicode only) + * + * TT_FONT_m_widths font->m.widths[font->numcodes] + * 8-bit code -> glyph width (enc >= 0, == pdc_builtin) + * glyph ID -> glyph width (enc == pdc_glyphid) + * + * TT_FONT_names font->m.name = englishname4 + * font->name = englishname6 + */ +int +fnt_set_tt_fontarrays(tt_file *ttf, int flags) +{ + static const char *fn = "pdc_set_tt_fontarrays"; + pdc_core *pdc = ttf->pdc; + fnt_font *font = ttf->font; + pdc_bool logg2 = pdc_logg_is_enabled(pdc, 2, trc_font); + pdc_bool logg5 = pdc_logg_is_enabled(pdc, 5, trc_font); + pdc_bool logg7 = pdc_logg_is_enabled(pdc, 7, trc_font); + pdc_encoding enc = font->enc, encb = pdc_invalidenc; + pdc_encodingvector *ev = NULL, *evb = NULL; + const char *glyphname; + pdc_bool regorder, isencbyte = pdc_false; + pdc_ushort uc, uv; + int ncodes = 0, gidx = 0, width = 0, foundglyphs = 0, uvoffset = 0; + int ucoffset = 0; + int code; + + /* Unicode offset for symbol fonts */ + if (ttf->issymbol == pdc_true) + { + if (ttf->tab_OS_2) + { + /* e.g. WingDings has usFirstChar = 0xF020, but we must start + ** at 0xF000. I haven't seen non-symbol fonts with a usFirstChar + ** like that; perhaps we have to apply similar tricks then... + */ + uvoffset = (ttf->tab_OS_2->usFirstCharIndex & 0xFF00); + } + else + { + /* This would be an Apple font with an encoding different + * from macroman or a subset font withot OS_2 table. + */ + if (!ttf->fortet) + { + pdc_set_errmsg(pdc, FNT_E_TT_SYMBOLOS2, 0, 0, 0, 0); + return -1; + } + uvoffset = 0xF000; + } + + if (logg7) + pdc_logg(pdc, "\t\t\tuvoffset: U+%04X\n", uvoffset); + } + + /* font names */ + if (flags & TT_FONT_names && ttf->tab_name) + { + font->m.name = pdc_strdup(pdc, ttf->tab_name->englishname4); + font->name = pdc_strdup(pdc, ttf->tab_name->englishname6); + } + + /* is Standard Latin font */ + font->issymbfont = ttf->issymbol; + + /* number of glyphs */ + font->numglyphs = ttf->numGlyphs; + + /* number of codes */ + switch(enc) + { + case pdc_cid: + case pdc_unicode: + font->numcodes = ttf->numunicode; + break; + + case pdc_glyphid: + font->numcodes = font->numglyphs; + break; + + default: + font->numcodes = 256; + ev = pdc_get_encoding_vector(pdc, enc); + isencbyte = pdc_true; + break; + } + + + if (enc < 0 && ttf->hasonlymac) + { + encb = pdc_macroman; + evb = pdc_get_encoding_vector(pdc, encb); + } + else + { + encb = enc; + evb = ev; + + if (flags & TT_FONT_encvec && enc == pdc_builtin) + { + evb = fnt_create_font_ev(pdc, font); + ev = evb; + } + } + + if (flags & TT_FONT_code2gid) + { + if (ttf->numunicode <= PDC_NUM_BMPVAL || isencbyte || + enc == pdc_glyphid) + { + font->code2gid = (pdc_ushort *) pdc_calloc(pdc, + font->numcodes * sizeof (pdc_ushort), fn); + } + } + + if ((flags & TT_FONT_gid2code) || logg2) + { + if (ttf->numunicode <= PDC_NUM_BMPVAL || isencbyte) + { + font->gid2code = (pdc_ushort *) pdc_calloc(pdc, + font->numglyphs * sizeof (pdc_ushort), fn); + } + } + + + if (flags & TT_FONT_m_widths) + { + font->m.numwidths = font->numcodes; + font->m.widths = (int *) pdc_calloc(pdc, + font->m.numwidths * sizeof(int), fn); + } + + + /* + * Build the char width tables for the font, set mappings GID <-> Code, + * and count the characters. + */ + foundglyphs = 0; + regorder = pdc_true; + ncodes = (enc == pdc_glyphid) ? ttf->numunicode : font->numcodes; + for (code = 0; code < ncodes; code++) + { + uc = (pdc_ushort) code; + uv = 0; + gidx = 0; + + + if (encb == pdc_macroman && ttf->tab_cmap->mac) + { + tt_cmap0_6 *cm = ttf->tab_cmap->mac; + + if (code > -1 && code < (int) (cm->firstCode + cm->entryCount)) + gidx = cm->glyphIdArray[code]; + } + else if (ttf->issymbol == pdc_true) + { + switch (encb) + { + case pdc_unicode: + if (!ttf->fortet) + { + if (code < 0x00FF) + { + /* we map the lower Unicode values too */ + if (uvoffset > 0x00FF) + regorder = pdc_false; + uv = (pdc_ushort) (code + uvoffset); + break; + } + regorder = pdc_true; + } + + case pdc_glyphid: + uv = (pdc_ushort) code; + break; + + default: + { + uv = (pdc_ushort) (code + uvoffset); + } + if (evb != NULL) + evb->codes[code] = uv; + break; + } + + if (!gidx) + gidx = tt_unicode2gidx(ttf, (int) uv, logg7); + } + else + { + uv = evb->codes[code]; + if (uv) + { + gidx = tt_unicode2gidx(ttf, (int) uv, logg7); + } + } + + /* + * Mapping GID -> [Uni]code + * This is a 1:n relation (e.g. 1 -> SPACE, 1 -> NBSP) + * We prefer the first occurence (SPACE) (regorder), + * in the case of TT symbol fonts the second occurence. + */ + if (gidx && regorder && uc >= ucoffset) + { + /* mapping gid -> code */ + if (font->gid2code) + { + if (!font->gid2code[gidx]) + { + font->gid2code[gidx] = uc; + if (logg5) + pdc_logg(pdc, "\t\tGID: %d -> U+%04X\n", + gidx, font->gid2code[gidx]); + } + else if (logg2) + { + pdc_logg(pdc, "\t\tGID: %d: U+%04X vs. U+%04X\n", + gidx, font->gid2code[gidx], uc); + } + } + foundglyphs++; + + } + + switch (enc) + { + + default: + if (font->m.numwidths) + font->m.widths[code] = tt_gidx2width(ttf, gidx); + break; + } + + /* mapping code -> gid */ + if (font->code2gid) + { + font->code2gid[code] = (pdc_ushort) gidx; + if (logg5 && gidx) + pdc_logg(pdc, "\t\tU+%04X -> GID: %d\n", + code, font->code2gid[code]); + } + } + + + /* logging protocol and/or to check the completeness + * of the glyph names + */ + if (logg2 + ) + { + if (logg2) + pdc_logg(pdc, + "\n\t\tGlyph mapping for %d glyphs:\n", ttf->numGlyphs); + + width = -1; + for (gidx = 0; gidx < ttf->numGlyphs; gidx++) + { + pdc_bool fontspecific = pdc_false; + glyphname = NULL; + + + code = fnt_get_code(gidx, font); + if (!ttf->fortet) + width = tt_gidx2width(ttf, gidx); + + if (code >= 0 && glyphname == NULL) + { + if (enc >= 0 || (ttf->issymbol && ev != NULL)) + glyphname = ev->chars[code]; + else if (enc != pdc_builtin && code <= 0xFFFF) + glyphname = (char *) pdc_unicode2glyphname(pdc, + (pdc_ushort) code); + } + + pdc_logg(pdc, "\t\tGID%5d: ", gidx); + if (!ttf->fortet) + pdc_logg(pdc, "width=%4d ", width); + + switch (enc) + { + + default: + if (!gidx || code > 0) + { + if (enc >= 0 || (ttf->issymbol && ev != NULL)) + { + uv = ev->codes[code]; + pdc_logg(pdc, "code=%3d U+%04X ", code, uv); + } + else + { + if (ttf->fortet && enc == pdc_builtin) + pdc_logg(pdc, "U+%04X ", code); + else + pdc_logg(pdc, "code=%3d ", code); + } + } + break; + } + if (glyphname != NULL) + pdc_logg(pdc, "\"%s\"", glyphname); + if (fontspecific) + pdc_logg(pdc, " (specific)"); + pdc_logg(pdc, "\n"); + } + } + + if (!(flags & TT_FONT_gid2code)) + { + if (ttf->numunicode <= PDC_NUM_BMPVAL && font->gid2code != NULL) + { + pdc_free(pdc, font->gid2code); + font->gid2code = NULL; + } + } + + return foundglyphs; +} + +pdc_encoding +fnt_get_tt_encoding_key(tt_file *ttf, pdc_encoding inenc) +{ + pdc_encoding outenc = inenc; + + /* Symbol font */ + if (ttf->issymbol && inenc >= pdc_winansi) + outenc = pdc_builtin; + + /* MacRoman font */ + if (ttf->hasonlymac && inenc >= pdc_builtin) + outenc = pdc_macroman; + + if (!ttf->issymbol && !ttf->haswinuni && !ttf->hasonlymac) + { + outenc = pdc_invalidenc; + pdc_logg_cond(ttf->pdc, 1, trc_font, + "\tTrueType font contains %s cmap table\n", + ttf->tab_cmap ? "unsupported" : "no" ); + } + else + { + pdc_logg_cond(ttf->pdc, 1, trc_font, + "\tEncoding \"%s\" will be determined\n", + pdc_get_user_encoding(ttf->pdc, outenc)); + } + + return outenc; +} + +static pdc_bool +fnt_check_and_read_ttc(pdc_core *pdc, pdc_file *fp, + const char *filename, const char *fontname, + fnt_font *font, tt_ulong n_fonts) +{ + static const char *fn = "fnt_check_and_read_ttc"; + const char *sf; + tt_file *ttf; + pdc_byte *utf16fontname = NULL; + pdc_bool retval = pdc_false; + pdc_text_format textformat = PDC_UTF8; + pdc_text_format targettextformat = pdc_utf16be; + int i, inlen, outlen; + int ift = -1; + + /* initialize */ + ttf = fnt_new_tt(pdc, font); + ttf->filename = filename; + ttf->fontname = fontname; + ttf->check = pdc_true; + ttf->fp = fp; + ttf->verbose = pdc_false; + + /* searching for font index in font name */ + sf = strrchr(fontname, ':'); + if (sf != NULL) + { + sf++; + if (!*sf) + ift = 0; + else if (pdc_str2integer(sf, PDC_INT_UNSIGNED, &i)) + ift = i; + } + + /* create UTF-16-BE font name string for searching in font file */ + if (ift == -1) + { + inlen = (int) strlen(font->utf8name); + if (pdc_convert_string(pdc, textformat, 0, NULL, + (pdc_byte *) font->utf8name, inlen, + &targettextformat, NULL, + &utf16fontname, &outlen, + PDC_CONV_NOBOM | PDC_CONV_INFLATE, ttf->verbose)) + { + goto FNT_TRUETYPE_EXIT; + } + } + + /* search font */ + for (i = 0; i < (int)n_fonts; ++i) + { + if (i) fnt_delete_tt(ttf); + + tt_seek(ttf, (long) (TT_OFFSETTAB_SIZE + i * sizeof(tt_ulong))); + ttf->offset = tt_get_ulong(ttf); + tt_seek(ttf, (long) ttf->offset); + + pdc_logg_cond(pdc, 1, trc_font, "\tChecking font #%d \n", i+1); + + /* Offset Table */ + if (!fnt_read_offset_tab(ttf)) + goto FNT_TRUETYPE_EXIT; + + /* font name match in Naming Table */ + if (ift > -1) + { + if (ift == i) + break; + } + else + { + /* font name match in Naming Table */ + if (utf16fontname == NULL) + break; + ttf->utf16fontname = (char *) utf16fontname; + ttf->fnamelen = outlen; + if (tt_get_tab_name(ttf)) + break; + } + } + if (utf16fontname != NULL) + pdc_free(pdc, utf16fontname); + + /* font found */ + if (i < (int)n_fonts) + { + tt_byte *pos; + tt_ulong headlen, dirlen, tablen, length, offset; + + /* create file in memory */ + tablen = 0; + dirlen = 4 * sizeof(tt_ulong); + headlen = (tt_ulong) (TT_OFFSETTAB_SIZE + ttf->n_tables * dirlen); + font->filelen = headlen; + for (i = 0; i < ttf->n_tables; i++) + { + length = ttf->dir[i].length; + if (length > tablen) tablen = length; + font->filelen += length; + } + font->img = (pdc_byte *) pdc_malloc(pdc, font->filelen, fn); + + /* read font file */ + tt_seek( ttf, (long) ttf->offset); + tt_read( ttf, font->img, headlen); + pos = font->img + headlen; + for (i = 0; i < ttf->n_tables; i++) + { + length = ttf->dir[i].length; + tt_seek( ttf, (long) ttf->dir[i].offset); + tt_read( ttf, pos, length); + ttf->dir[i].offset = (unsigned int) (pos - font->img); + pos += length; + } + + /* correct offsets in Table Directory */ + pos = font->img + TT_OFFSETTAB_SIZE + 2 * sizeof(tt_ulong); + for (i = 0; i < ttf->n_tables; i++) + { + offset = ttf->dir[i].offset; + pos[0] = (tt_byte) (offset >> 24); + pos[1] = (tt_byte) (offset >> 16); + pos[2] = (tt_byte) (offset >> 8); + pos[3] = (tt_byte) (offset); + pos += dirlen; + } + retval = pdc_true; + } + else + { + pdc_set_errmsg(pdc, FNT_E_TTC_NOTFOUND, filename, 0, 0, 0); + goto FNT_TRUETYPE_EXIT; + } + + FNT_TRUETYPE_EXIT: + + ttf->check = pdc_false; + fnt_delete_tt(ttf); + + return retval; +} + +pdc_bool +fnt_check_tt_font(pdc_core *pdc, const char *filename, const char *fontname, + fnt_font *font, pdc_bool requested) +{ + pdc_file *fp; + char fullname[PDC_FILENAMELEN]; + tt_byte img[TT_OFFSETTAB_SIZE]; + pdc_bool ismem = pdc_false; + tt_ulong n_fonts = 0; + int retval = requested ? pdc_false : pdc_undef; + + fp = pdc_fsearch_fopen(pdc, filename, fullname, "font ",PDC_FILE_BINARY); + if (fp != NULL) + { + if (PDC_OK_FREAD(fp, img, TT_OFFSETTAB_SIZE)) + { + pdc_logg_cond(pdc, 1, trc_font, + "\tLoading TrueType fontfile \"%s\":\n", fullname); + + retval = fnt_test_tt_font(pdc, img, &n_fonts, requested); + if (retval == pdc_true) + { + ismem = pdc_file_isvirtual(fp); + + if (fontname != NULL) + { + if (n_fonts > 1) + { + retval = fnt_check_and_read_ttc(pdc, fp, filename, + fontname, font, n_fonts); + fp = NULL; + } + else + { + font->img = (pdc_byte *) + pdc_freadall(fp, &font->filelen, NULL); + } + + if (retval == pdc_true) + { + if (font->filelen == 0) + { + pdc_set_errmsg(pdc, + PDC_E_IO_READ, fullname, 0, 0, 0); + retval = pdc_false; + } + } + } + + if (retval == pdc_true) + { + if (fp != NULL && ismem) + { + font->imgname = pdc_strdup(pdc, filename); + pdc_lock_pvf(pdc, font->imgname); + } + + font->filename = pdc_strdup(pdc, fullname); + } + } + } + + if (fp != NULL) + pdc_fclose(fp); + } + else + { + retval = pdc_check_fopen_errmsg(pdc, requested); + } + + return retval; +} + + +/* + * After fnt_new_tt initialize following members + * (here with the opposite of default): + * + * ttf->filename = filename; + * ttf->fontname = fontname; + * + * ttf->verbose = pdc_false; + * ttf->kerning = pdc_true; + * ttf->vertical = pdc_true; + * ttf->fortet = pdc_true; + * + * ttf->check = pdc_true; + * ttf->incore = pdc_true; + * ttf->savecff = pdc_true; + * ttf->monospace = 1000; + * + * ttf->fp = fp; + * + */ +tt_file * +fnt_new_tt(pdc_core *pdc, fnt_font *font) +{ + static const char *fn = "fnt_new_tt"; + + tt_file *ttf = (tt_file *) + pdc_malloc(pdc, (size_t) sizeof (tt_file), fn); + + ttf->pdc = pdc; + ttf->font = font; + + ttf->img = (tt_byte *) font->img; + ttf->pos = ttf->img; + ttf->end = ttf->img + font->filelen; + + ttf->filename = NULL; + ttf->fontname = NULL; + ttf->verbose = pdc_true; + ttf->fortet = pdc_false; + ttf->check = pdc_false; + ttf->incore = pdc_false; + ttf->savecff = pdc_false; + ttf->monospace = 0; + ttf->fp = NULL; + + ttf->n_tables = 0; + ttf->offset = 0; + ttf->dir = (tt_dirent *) 0; + + ttf->tab_cmap = (tt_tab_cmap *) 0; + ttf->tab_head = (tt_tab_head *) 0; + ttf->tab_hhea = (tt_tab_hhea *) 0; + ttf->tab_hmtx = (tt_tab_hmtx *) 0; + ttf->tab_maxp = (tt_tab_maxp *) 0; + ttf->tab_name = (tt_tab_name *) 0; + ttf->tab_post = (tt_tab_post *) 0; + ttf->tab_OS_2 = (tt_tab_OS_2 *) 0; + ttf->tab_CFF_ = (tt_tab_CFF_ *) 0; + + ttf->numGlyphs = 0; + ttf->onlyCFF = 0; + ttf->hasGlyphNames = 0; + ttf->numunicode = PDC_NUM_BMPVAL; + ttf->builtinenc = pdc_stdenc; + ttf->regisadobe = pdc_false; + ttf->charcoll = cc_none; + ttf->supplement = 0; + + ttf->issymbol = pdc_false; + ttf->haswinuni = pdc_false; + ttf->hasonlymac = pdc_false; + + + ttf->utf16fontname = (char *) 0; + ttf->fnamelen = 0; + + return ttf; + +} /* fnt_new_tt */ + +void +fnt_delete_tt(tt_file *ttf) +{ + pdc_core *pdc = ttf->pdc; + int i; + + (void) i; + + if (ttf->check == pdc_false && ttf->fp != (pdc_file *) 0) + pdc_fclose(ttf->fp); + + if (ttf->dir != (tt_dirent *) 0) + pdc_free(pdc, ttf->dir); + ttf->dir = (tt_dirent *) 0; + + + if (ttf->tab_head != (tt_tab_head *) 0) + pdc_free(pdc, ttf->tab_head); + if (ttf->tab_hhea != (tt_tab_hhea *) 0) + pdc_free(pdc, ttf->tab_hhea); + if (ttf->tab_maxp != (tt_tab_maxp *) 0) + pdc_free(pdc, ttf->tab_maxp); + if (ttf->tab_OS_2 != (tt_tab_OS_2 *) 0) + pdc_free(pdc, ttf->tab_OS_2); + if (ttf->tab_CFF_ != (tt_tab_CFF_ *) 0) + pdc_free(pdc, ttf->tab_CFF_); + if (ttf->tab_post != (tt_tab_post *) 0) + { + pdc_free(pdc, ttf->tab_post); + } + + if (ttf->tab_cmap != (tt_tab_cmap *) 0) + { + if (ttf->tab_cmap->mac != (tt_cmap0_6 *) 0) { + if (ttf->tab_cmap->mac->glyphIdArray) + pdc_free(pdc, ttf->tab_cmap->mac->glyphIdArray); + pdc_free(pdc, ttf->tab_cmap->mac); + } + + if (ttf->tab_cmap->win != (tt_cmap4 *) 0) + { + tt_cmap4 *cm4 = (tt_cmap4 *) ttf->tab_cmap->win; + + if (cm4->endCount != 0) pdc_free(pdc, cm4->endCount); + if (cm4->startCount != 0) pdc_free(pdc, cm4->startCount); + if (cm4->idDelta != 0) pdc_free(pdc, cm4->idDelta); + if (cm4->idRangeOffs != 0) pdc_free(pdc, cm4->idRangeOffs); + if (cm4->glyphIdArray != 0) pdc_free(pdc, cm4->glyphIdArray); + + pdc_free(pdc, cm4); + } + + if (ttf->tab_cmap->ucs4 != (tt_cmap12 *) 0) + { + tt_cmap12 *cm12 = (tt_cmap12 *) ttf->tab_cmap->ucs4; + + if (cm12->grouptab != 0) pdc_free(pdc, cm12->grouptab); + + pdc_free(pdc, cm12); + } + + pdc_free(pdc, ttf->tab_cmap); + } + + if (ttf->tab_hmtx != (tt_tab_hmtx *) 0) + { + if (ttf->tab_hmtx->metrics != (tt_metric *) 0) + pdc_free(pdc, ttf->tab_hmtx->metrics); + if (ttf->tab_hmtx->lsbs != (tt_fword *) 0) + pdc_free(pdc, ttf->tab_hmtx->lsbs); + pdc_free(pdc, ttf->tab_hmtx); + } + + if (ttf->tab_name != (tt_tab_name *) 0) + { + if (ttf->tab_name->namerecords != (tt_nameref *) 0) + pdc_free(pdc, ttf->tab_name->namerecords); + if (ttf->tab_name->englishname4 != (char *) 0) + pdc_free(pdc, ttf->tab_name->englishname4); + if (ttf->tab_name->englishname6 != (char *) 0) + pdc_free(pdc, ttf->tab_name->englishname6); + if (ttf->tab_name->producer != (char *) 0) + pdc_free(pdc, ttf->tab_name->producer); + pdc_free(pdc, ttf->tab_name); + } + ttf->tab_name = (tt_tab_name *) 0; + + + /* Note: do not clean up ttf->img since the data belongs to font->img + */ + + if (ttf->check == pdc_false) + pdc_free(pdc, ttf); + +} /* fnt_delete_tt */ + + +#endif /* PDF_TRUETYPE_SUPPORTED */ diff --git a/src/pdflib/font/ft_truetype.h b/src/pdflib/font/ft_truetype.h new file mode 100644 index 0000000..89cd3fb --- /dev/null +++ b/src/pdflib/font/ft_truetype.h @@ -0,0 +1,558 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_truetype.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT TrueType typedefs, structures, and enums + * + */ + +#ifndef FT_TRUETYPE_H +#define FT_TRUETYPE_H + +typedef unsigned char tt_byte; +typedef char tt_char; +typedef unsigned short tt_ushort; +typedef short tt_short; +typedef unsigned int tt_ulong; +typedef int tt_long; + +typedef long tt_fixed; +typedef short tt_fword; +typedef unsigned short tt_ufword; + +#define tt_get_fixed tt_get_long +#define tt_get_fword tt_get_short +#define tt_get_ufword tt_get_ushort + +#define TT_XKERNPAIR_CHUNKSIZE 256 +#define TT_ACCGIDTAB_CHUNKSIZE 256 + +#define TT_OPERAND_STACKSIZE 48 + +#define TT_NUMSTDSTRINGS 391 +#define TT_NUMISOSTRINGS 229 +#define TT_NUMEXPSTRINGS 379 +#define TT_NUMEXPERTGIDS 166 + +#define TT_OFFSETTAB_SIZE 12 + +/* flags for fnt_set_tt_fontarrays */ +#define TT_FONT_encvec (1<<0) +#define TT_FONT_gid2code (1<<1) +#define TT_FONT_code2gid (1<<2) +#define TT_FONT_gid2name (1<<3) +#define TT_FONT_m_ciw (1<<4) +#define TT_FONT_m_widths (1<<5) +#define TT_FONT_names (1<<6) +#define TT_FONT_name2unitab (1<<7) + +typedef enum +{ + cff_version = 0, + cff_Notice = 1, + cff_FullName = 2, + cff_FamilyName = 3, + cff_Weight = 4, + cff_FontBBox = 5, + cff_BlueValues = 6, + cff_OtherBlues = 7, + cff_FamilyBlues = 8, + cff_FamilyOtherBlues = 9, + cff_StdHW = 10, + cff_StdVW = 11, + cff_Copyright = 0x100, /* 12 0 */ + cff_isFixedPitch = 0x101, /* 12 1 */ + cff_ItalicAngle = 0x102, /* 12 2 */ + cff_UnderlinePosition = 0x103, /* 12 3 */ + cff_UnderlineThickness = 0x104, /* 12 4 */ + cff_PaintType = 0x105, /* 12 5 */ + cff_CharstringType = 0x106, /* 12 6 */ + cff_FontMatrix = 0x107, /* 12 7 */ + cff_StrokeWidth = 0x108, /* 12 8 */ + cff_BlueScale = 0x109, /* 12 9 */ + cff_BlueShift = 0x10A, /* 12 10 */ + cff_BlueFuzz = 0x10B, /* 12 11 */ + cff_StemSnapH = 0x10C, /* 12 12 */ + cff_StemSnapV = 0x10D, /* 12 13 */ + cff_ForceBold = 0x10E, /* 12 14 */ + /* 0x10F, 12 15 */ + /* 0x110, 12 16 */ + cff_LanguageGroup = 0x111, /* 12 17 */ + cff_ExpansionFactor = 0x112, /* 12 18 */ + cff_initialRandomSeed = 0x113, /* 12 19 */ + cff_SyntheticBase = 0x114, /* 12 20 */ + cff_PostScript = 0x115, /* 12 21 */ + cff_BaseFontName = 0x116, /* 12 22 */ + cff_BaseFontBlend = 0x117, /* 12 23 */ + /* 0x118, 12 24 */ + /* 0x119, 12 25 */ + /* 0x11A, 12 26 */ + /* 0x11B, 12 27 */ + /* 0x11C, 12 28 */ + /* 0x11D, 12 29 */ + cff_ROS = 0x11E, /* 12 30 */ + cff_CIDFontVersion = 0x11F, /* 12 31 */ + cff_CIDFontRevision = 0x120, /* 12 32 */ + cff_CIDFontType = 0x121, /* 12 33 */ + cff_CIDCount = 0x122, /* 12 34 */ + cff_UIDBase = 0x123, /* 12 35 */ + cff_FDArray = 0x124, /* 12 36 */ + cff_FDSelect = 0x125, /* 12 37 */ + cff_FontName = 0x126, /* 12 38 */ + /* 0x127, 12 39 */ + cff_UniqueID = 13, + cff_XUID = 14, + cff_Charsets = 15, + cff_Encoding = 16, + cff_CharStrings = 17, + cff_Private = 18, + cff_Subrs = 19, + cff_defaultWidthX = 20, + cff_nominalWidthX = 21 +} +tt_cff_oper; + +typedef struct +{ + char tag[5]; + tt_ulong checksum; + tt_ulong offset; + tt_ulong length; +} tt_dirent; + +typedef enum +{ + tt_pfid_uni = 0, + tt_pfid_mac = 1, + tt_pfid_iso = 2, + tt_pfid_win = 3, + tt_pfid_custom = 4 +} tt_platform_id; + +typedef enum +{ + tt_wenc_symbol = 0, + tt_wenc_text = 1, + tt_wenc_mtext = 3, + tt_wenc_utext = 10 +} tt_win_encoding_id; + +/* format 4 cmap table: +*/ +typedef struct +{ + tt_ushort encodingID; + tt_ushort format; + tt_ushort length; + tt_ushort version; + tt_ushort segCountX2; /* segCount * 2 */ + tt_ushort searchRange; + tt_ushort entrySelector; + tt_ushort rangeShift; + tt_ushort * endCount; /* [segCount] */ + tt_ushort * startCount; /* [segCount] */ + tt_short * idDelta; /* [segCount] */ + tt_ushort * idRangeOffs; /* [segCount] */ + int numGlyphIds; + tt_ushort * glyphIdArray; +} tt_cmap4; + +/* combined data structure for format 0 and format 6 encoding tables: +*/ +typedef struct +{ + tt_ushort format; + tt_ushort length; + tt_ushort language; + tt_ushort firstCode; + tt_ushort entryCount; + tt_ushort *glyphIdArray; +} tt_cmap0_6; + +/* format 12 cmap table: +*/ +typedef struct +{ + tt_ulong startCharCode; + tt_ulong endCharCode; + tt_ulong startGlyphID; +} tt_grouptab; + +typedef struct +{ + tt_ushort format; + tt_ulong length; + tt_ulong language; + tt_ulong nGroups; + tt_grouptab *grouptab; /* [nGroups] */ +} tt_cmap12; + +typedef struct +{ + tt_ushort version; + tt_ushort numEncTabs; + + tt_cmap4 *win; + tt_cmap0_6 *mac; + tt_cmap12 *ucs4; + + /* picked table */ + tt_ushort platform; + tt_ushort encoding; + tt_ushort format; + tt_ulong offset; + tt_ulong length; +} tt_tab_cmap; + +typedef struct +{ + tt_fixed version; + tt_fixed fontRevision; + tt_ulong checkSumAdjustment; + tt_ulong magicNumber; + tt_ushort flags; + tt_ushort unitsPerEm; + tt_ulong created[2]; + tt_ulong modified[2]; + tt_fword xMin, yMin; + tt_fword xMax, yMax; + tt_ushort macStyle; + tt_ushort lowestRecPPEM; + tt_short fontDirectionHint; + tt_short indexToLocFormat; + tt_short glyphDataFormat; +} tt_tab_head; + +typedef struct +{ + tt_fixed version; + tt_fword ascender; + tt_fword descender; + tt_fword lineGap; + tt_fword advanceWidthMax; /* specification: tt_ufword */ + tt_fword minLeftSideBearing; + tt_fword minRightSideBearing; + tt_fword xMaxExtent; + tt_short caretSlopeRise; + tt_short caretSlopeRun; + tt_short res1; + tt_short res2; + tt_short res3; + tt_short res4; + tt_short res5; + tt_short metricDataFormat; + tt_ushort numberOfHMetrics; +} tt_tab_hhea; + +typedef struct +{ + tt_fword advanceWidth; /* specification: tt_ufword */ + tt_fword lsb; +} tt_metric; + +typedef struct +{ + tt_metric * metrics; + tt_fword * lsbs; +} tt_tab_hmtx; + +typedef struct +{ + tt_fixed version; + tt_ushort numGlyphs; + tt_ushort maxPoints; + tt_ushort maxContours; + tt_ushort maxCompositePoints; + tt_ushort maxCompositeContours; + tt_ushort maxZones; + tt_ushort maxTwilightPoints; + tt_ushort maxStorage; + tt_ushort maxFunctionDefs; + tt_ushort maxInstructionDefs; + tt_ushort maxStackElements; + tt_ushort maxSizeOfInstructions; + tt_ushort maxComponentElements; + tt_ushort maxComponentDepth; +} tt_tab_maxp; + +typedef struct +{ + tt_ushort platform; + tt_ushort encoding; + tt_ushort language; + tt_ushort namid; + tt_ushort length; + tt_ushort offset; +} tt_nameref; + +typedef struct +{ + tt_ushort format; + tt_ushort numNameRecords; + tt_ushort offsetStrings; + tt_nameref *namerecords; + char *englishname4; + char *englishname6; + char *producer; +} tt_tab_name; + +typedef struct +{ + tt_ushort version; + tt_short xAvgCharWidth; + tt_ushort usWeightClass; + tt_ushort usWidthClass; + tt_ushort fsType; /* tt_short? */ + tt_short ySubscriptXSize; + tt_short ySubscriptYSize; + tt_short ySubscriptXOffset; + tt_short ySubscriptYOffset; + tt_short ySuperscriptXSize; + tt_short ySuperscriptYSize; + tt_short ySuperscriptXOffset; + tt_short ySuperscriptYOffset; + tt_short yStrikeoutSize; + tt_short yStrikeoutPosition; + tt_ushort sFamilyClass; /* tt_short? */ + tt_byte panose[10]; + tt_ulong ulUnicodeRange1; + tt_ulong ulUnicodeRange2; + tt_ulong ulUnicodeRange3; + tt_ulong ulUnicodeRange4; + tt_char achVendID[4]; + tt_ushort fsSelection; + tt_ushort usFirstCharIndex; + tt_ushort usLastCharIndex; + + /* tt_ushort according to spec; obviously a spec bug. + */ + tt_short sTypoAscender; + tt_short sTypoDescender; + tt_short sTypoLineGap; + + tt_ushort usWinAscent; + tt_ushort usWinDescent; + + /* if version >= 1 + */ + tt_ulong ulCodePageRange1; + tt_ulong ulCodePageRange2; + + /* if version >= 2 (according to OpenType spec) + */ + tt_short sxHeight; + tt_short sCapHeight; + tt_ushort usDefaultChar; + tt_ushort usBreakChar; + tt_ushort usMaxContext; + + int charcolls[PDC_NUMCHARCOLL]; +} tt_tab_OS_2; + + +typedef struct +{ + tt_ulong offset; + tt_ulong length; +} +tt_tab_CFF_; + +typedef struct +{ + tt_fixed formatType; + double italicAngle; + tt_fword underlinePosition; + tt_fword underlineThickness; + tt_ulong isFixedPitch; + tt_ulong minMemType42; + tt_ulong maxMemType42; + tt_ulong minMemType1; + tt_ulong maxMemType1; + tt_ushort numberOfGlyphs; +} tt_tab_post; + +typedef struct +{ + tt_ushort start; + tt_ushort end; + tt_ushort cclass; +} tt_record_classrange; + +typedef struct +{ + tt_ushort left; + tt_ushort right; + tt_short value; + tt_short dominant; +} tt_xkern_pair; + +typedef struct +{ + tt_xkern_pair *pairs; + int capacity; + int number; +} tt_xkern_pair_list; + +typedef struct +{ + /* -------------------- input members -------------------- */ + + pdc_core *pdc; + fnt_font *font; /* corresponding font struct */ + + const char *filename; /* font file name */ + const char *fontname; /* font API name */ + + pdc_bool verbose; /* put warnings */ + pdc_bool fortet; /* for TET */ + + pdc_bool check; /* check for fontname */ + pdc_bool incore; /* whole font in-core */ + pdc_bool savecff; /* save results of CFF analyzing */ + int monospace; /* monospace amount */ + + tt_byte *img; /* in-core TT font file image */ + tt_byte *end; /* first byte above image buf */ + tt_byte *pos; /* current "file" position */ + pdc_file *fp; + + + /* ----------------- results from parsing ------------------- */ + + int n_tables; + tt_ulong offset; + tt_dirent * dir; + + /* table structs: */ + tt_tab_cmap *tab_cmap; + tt_tab_head *tab_head; + tt_tab_hhea *tab_hhea; + tt_tab_hmtx *tab_hmtx; + tt_tab_maxp *tab_maxp; + tt_tab_name *tab_name; + tt_tab_post *tab_post; + tt_tab_OS_2 *tab_OS_2; + tt_tab_CFF_ *tab_CFF_; + + + int numGlyphs; /* number of glyphs */ + int onlyCFF; /* only CFF_ table */ + int hasGlyphNames; /* CFF: has glyph names */ + int numunicode; /* number of Unicode values incl. 0 */ + int builtinenc; /* builtin encoding */ + pdc_bool regisadobe; /* registry is Adobe */ + int charcoll; /* character collection */ + int supplement; /* supplement number */ + + pdc_bool issymbol; /* symbol font */ + pdc_bool haswinuni; /* has a "Microsoft standard character + * to glyph index mapping table" + * cmap (3, 1) format 4 or + * cmap (3,10) format 12 or + * cmap (0, 3) format 4 (mac old case) */ + pdc_bool hasonlymac; /* has only macroman cmap (0,1) */ + + char *utf16fontname; /* UTF-16-BE font name for TTC fonts */ + int fnamelen; /* font name length */ + + +} tt_file; + +/* TrueType table names, defined as octal codes */ +#define fnt_str_ttcf "\164\164\143\146" +#define fnt_str_bhed "\142\150\145\144" +#define fnt_str_CFF_ "\103\106\106\040" +#define fnt_str_cvt_ "\143\166\164\040" +#define fnt_str_cmap "\143\155\141\160" +#define fnt_str_fpgm "\146\160\147\155" +#define fnt_str_glyf "\147\154\171\146" +#define fnt_str_GPOS "\107\120\117\123" +#define fnt_str_GSUB "\107\123\125\102" +#define fnt_str_head "\150\145\141\144" +#define fnt_str_hhea "\150\150\145\141" +#define fnt_str_hmtx "\150\155\164\170" +#define fnt_str_kern "\153\145\162\156" +#define fnt_str_loca "\154\157\143\141" +#define fnt_str_maxp "\155\141\170\160" +#define fnt_str_name "\156\141\155\145" +#define fnt_str_OS_2 "\117\123\057\062" /* OS/2 */ +#define fnt_str_post "\160\157\163\164" +#define fnt_str_prep "\160\162\145\160" + +#define fnt_str_vert "\166\145\162\164" + +/* Composite font flags. */ +/* See Reference of OpenType: glyf - Glyf Data */ +#define ARGS_ARE_WORDS 0x001 +#define ARGS_ARE_XY_VALUES 0x002 +#define ROUND_XY_TO_GRID 0x004 +#define WE_HAVE_A_SCALE 0x008 +/* reserved 0x010 */ +#define MORE_COMPONENTS 0x020 +#define WE_HAVE_AN_XY_SCALE 0x040 +#define WE_HAVE_A_2X2 0x080 +#define WE_HAVE_INSTR 0x100 +#define USE_MY_METRICS 0x200 + + +/* Functions */ + +#define FNT_TT2PDF(v) (int) PDC_ROUND(v * 1000.0 / ttf->tab_head->unitsPerEm) + +#define TT_ASSERT(ttf, cond) \ + ((cond) ? (void) 0 : tt_assert(ttf)) + +#define TT_IOCHECK(ttf, cond) \ + ((cond) ? (void) 0 : tt_error(ttf)) + +int tt_tag2idx(tt_file *ttf, char *tag); +void *tt_get_tab(tt_file *ttf, char *tag, size_t nbytes, pdc_bool tterror, + tt_ulong *offset); +void tt_get_tab_maxp(tt_file *ttf); +void tt_get_tab_head(tt_file *ttf); +void tt_get_tab_cmap(tt_file *ttf); +pdc_bool tt_get_tab_CFF_(tt_file *ttf); +void tt_get_tab_OS_2(tt_file *ttf); + +void tt_assert(tt_file *ttf); +void tt_error(tt_file *ttf); +void tt_seek(tt_file *ttf, long offset); +void tt_read(tt_file *ttf, void *buf, unsigned int nbytes); +long tt_tell(tt_file *ttf); +tt_ushort tt_get_ushort(tt_file *ttf); +tt_short tt_get_short(tt_file *ttf); +tt_ulong tt_get_ulong3(tt_file *ttf); +tt_ulong tt_get_ulong(tt_file *ttf); +tt_long tt_get_long(tt_file *ttf); +tt_ulong tt_get_offset(tt_file *ttf, tt_byte offsize); +pdc_bool tt_get_tab_name(tt_file *ttf); + +int tt_unicode2gidx(tt_file *ttf, int usv, pdc_bool logg); +int tt_gidx2width(tt_file *ttf, int gidx); + + +tt_file *fnt_new_tt(pdc_core *pdc, fnt_font *font); +void fnt_delete_tt(tt_file *ttf); +void fnt_set_tt_fontvalues(tt_file *ttf); +int fnt_set_tt_fontarrays(tt_file *ttf, int flags); +pdc_encoding fnt_get_tt_encoding_key(tt_file *ttf, pdc_encoding inenc); +pdc_bool fnt_read_tt(tt_file *ttf); +pdc_bool fnt_read_offset_tab(tt_file *ttf); +pdc_bool fnt_test_tt_font(pdc_core *pdc, tt_byte *img, tt_ulong *n_fonts, + pdc_bool requested); +pdc_bool fnt_is_opentype_font(tt_file *ttf); +pdc_bool fnt_check_tt_font(pdc_core *pdc, const char *filename, + const char *fontname, fnt_font *font, pdc_bool requested); + + +#endif /* FT_TRUETYPE_H */ diff --git a/src/pdflib/font/ft_type1.c b/src/pdflib/font/ft_type1.c new file mode 100644 index 0000000..2644284 --- /dev/null +++ b/src/pdflib/font/ft_type1.c @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: ft_type1.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * FONT Type1 font handling routines + * + */ + +#include "ft_font.h" + +pdc_bool +fnt_test_type1_font(pdc_core *pdc, const pdc_byte *img) +{ + char startsequ[5]; + + strcpy(startsequ, FNT_PFA_STARTSEQU); + + /* ASCII block sign and begin of text at byte 7 */ + if (img[0] == 0x80 && img[1] == 0x01 && + strncmp((const char *)&img[6], startsequ, 4) == 0) + { + pdc_logg_cond(pdc, 1, trc_font, + "\tPostScript Type1 font detected\n"); + return pdc_true; + } + return pdc_false; +} + + diff --git a/src/pdflib/pdcore/pc_aes.c b/src/pdflib/pdcore/pc_aes.c new file mode 100644 index 0000000..ddad480 --- /dev/null +++ b/src/pdflib/pdcore/pc_aes.c @@ -0,0 +1,32 @@ +/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */ +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Note: rewritten a little bit to provide error control and an OpenSSL- + compatible API */ + +#include "pc_util.h" + diff --git a/src/pdflib/pdcore/pc_aes.h b/src/pdflib/pdcore/pc_aes.h new file mode 100644 index 0000000..65ef4f4 --- /dev/null +++ b/src/pdflib/pdcore/pc_aes.h @@ -0,0 +1,53 @@ +/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "pc_core.h" + diff --git a/src/pdflib/pdcore/pc_aescbc.c b/src/pdflib/pdcore/pc_aescbc.c new file mode 100644 index 0000000..c9a5a42 --- /dev/null +++ b/src/pdflib/pdcore/pc_aescbc.c @@ -0,0 +1,53 @@ +/* crypto/aes/aes_cbc.c -*- mode:C; c-file-style: "eay" -*- */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "pc_util.h" + diff --git a/src/pdflib/pdcore/pc_aeslocal.h b/src/pdflib/pdcore/pc_aeslocal.h new file mode 100644 index 0000000..65ef4f4 --- /dev/null +++ b/src/pdflib/pdcore/pc_aeslocal.h @@ -0,0 +1,53 @@ +/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "pc_core.h" + diff --git a/src/pdflib/pdcore/pc_arc4.c b/src/pdflib/pdcore/pc_arc4.c new file mode 100644 index 0000000..b48659e --- /dev/null +++ b/src/pdflib/pdcore/pc_arc4.c @@ -0,0 +1,61 @@ +/* crypto/arc4/arc4_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the ARC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "pc_util.h" +#include "pc_arc4.h" + diff --git a/src/pdflib/pdcore/pc_arc4.h b/src/pdflib/pdcore/pc_arc4.h new file mode 100644 index 0000000..9a474a7 --- /dev/null +++ b/src/pdflib/pdcore/pc_arc4.h @@ -0,0 +1,60 @@ +/* crypto/arc4/arc4.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the ARC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "pc_core.h" + diff --git a/src/pdflib/pdcore/pc_chartabs.c b/src/pdflib/pdcore/pc_chartabs.c new file mode 100644 index 0000000..3799d45 --- /dev/null +++ b/src/pdflib/pdcore/pc_chartabs.c @@ -0,0 +1,613 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_chartabs.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib routines for converting glyph or character names to Unicode + * and vice versa + * + */ + +#define PC_CHARTABS_C + +#include "pc_util.h" +#include "pc_chartabs.h" +#include "pc_ctype.h" + + +/* ---------------- general character search functions ------------------- */ + +/* + * Binary search for list of codes in a pdc_glyph_tab array sorted by glyphname + */ +int +pdc_glyphname2codelist(const char *glyphname, const pdc_glyph_tab *glyphtab, + int tabsize, pdc_ushort *codelist) +{ + int lo = 0; + int hi = glyphname ? tabsize : lo; + int nv = 0; + + while (lo < hi) + { + int i = (lo + hi) / 2; + int cmp = strcmp(glyphname, glyphtab[i].name); + + if (cmp == 0) + { + for (; i >= 1; i--) + { + if (strcmp(glyphname, glyphtab[i-1].name)) + break; + } + for (; i < tabsize; i++) + { + if (strcmp(glyphname, glyphtab[i].name)) + break; + codelist[nv] = glyphtab[i].code; + nv++; + } + return nv; + } + + if (cmp < 0) + hi = i; + else + lo = i + 1; + } + + return nv; +} + +/* + * Binary search for code in a pdc_glyph_tab array sorted by glyphname + */ +int +pdc_glyphname2code(const char *glyphname, const pdc_glyph_tab *glyphtab, + int tabsize) +{ + int lo = 0; + int hi = glyphname ? tabsize : lo; + + while (lo < hi) + { + int i = (lo + hi) / 2; + int cmp = strcmp(glyphname, glyphtab[i].name); + + if (cmp == 0) + return (int) glyphtab[i].code; + + if (cmp < 0) + hi = i; + else + lo = i + 1; + } + + return -1; +} + +/* + * Binary search for glyphname in a pdc_glyph_tab array sorted by code + */ +const char * +pdc_code2glyphname(pdc_ushort code, const pdc_glyph_tab *glyphtab, int tabsize) +{ + int lo = 0; + int hi = tabsize; + + while (lo < hi) + { + int i = (lo + hi) / 2; + + if (code == glyphtab[i].code) + return glyphtab[i].name; + + if (code < glyphtab[i].code) + hi = i; + else + lo = i + 1; + } + + return NULL; +} + +/* + * Binary search for list of codes in a pdc_code_map array sorted by source code + */ +int +pdc_code2codelist(pdc_core *pdc, pdc_ushort code, + const pdc_code_map *codemap, int tabsize, + pdc_ushort *codelist, int listsize) +{ + int lo = 0; + int hi = tabsize; + int nv = 0; + + while (lo < hi) + { + int i = (lo + hi) / 2; + + if (codemap[i].src == code) + { + for (; i >= 1; i--) + { + if (codemap[i-1].src != code) + break; + } + + for (; i < tabsize; i++) + { + if (codemap[i].src != code) + break; + + if (nv >= listsize) + pdc_error(pdc, PDC_E_CONV_LIST_MEMOVERFLOW, 0, 0, 0, 0); + + codelist[nv] = codemap[i].dst; + nv++; + } + + return nv; + } + if (codemap[i].src > code) + hi = i; + else + lo = i + 1; + } + + return nv; +} + +/* + * Binary search for glyphname in a pdc_glyph_tab array sorted by glyphname + * to get the static pointer for the glyphname. + */ +const char * +pdc_glyphname2glyphname(const char *glyphname, + const pdc_glyph_tab *glyphtab, int tabsize) +{ + int lo = 0; + int hi = tabsize; + + while (lo < hi) + { + int i = (lo + hi) / 2; + int cmp = strcmp(glyphname, glyphtab[i].name); + + if (cmp == 0) + return glyphtab[i].name; + + if (cmp < 0) + hi = i; + else + lo = i + 1; + } + + return NULL; +} + + +/* ---------------- special character search functions ------------------- */ + +/* + * Returns the Unicode value of a glyph name in Adobe Glyph List 1.2'. + * If the name is not contained in AGL, -1 will be returned. + */ +int +pdc_adobe2unicode(const char *glyphname) +{ + return pdc_glyphname2code(glyphname, tab_agl2uni, + (sizeof (tab_agl2uni)) / (sizeof (pdc_glyph_tab))); +} + +/* + * Returns the name in AGL 1.2' or ZapfDingbats font, + * which corresponds to the supplied Unicode value. + * If the value doesn't have a corresponding glyph name, + * NULL will be returned. + * For control codes ".notdef" will be returned. + * But this is not compatibel with AGL 2.0! + */ +const char * +pdc_unicode2adobe(pdc_ushort uv) +{ + const char *glyphname; + + /* AGL 1.2' glyphname */ + glyphname = pdc_code2glyphname(uv, tab_uni2agl, + (sizeof tab_uni2agl) / (sizeof (pdc_glyph_tab))); + if (glyphname != NULL) + return glyphname; + + /* C0 and C1 control characters. + * They have never a graphical representation but are defined. + */ + if (uv < PDC_UNICODE_SPACE || + (uv >= PDC_UNICODE_DELETE && uv < PDC_UNICODE_NBSP)) + return glyph__notdef; + + return NULL; +} + +const char * +pdc_get_notdef_glyphname(void) +{ + return (char *) glyph__notdef; +} + +/* + * Returns the Unicode value of a ZapfDingbats glyph name. + * If the name is not contained in the ZapfDingbats list + * -1 will be returned. + */ +int +pdc_zadb2unicode(const char *glyphname) +{ + return pdc_glyphname2code(glyphname, tab_zadb2uni, + (sizeof (tab_zadb2uni)) / (sizeof (pdc_glyph_tab))); +} + +/* + * Returns the glyph name in the ZapfDingbats font which corresponds + * to the supplied Unicode value. If the value doesn't have a + * corresponding glyph name NULL will be returned. + */ +const char * +pdc_unicode2zadb(pdc_ushort uv) +{ + return pdc_code2glyphname(uv, tab_uni2zadb, + (sizeof tab_uni2zadb) / (sizeof (pdc_glyph_tab))); +} + +/* + * Returns the Unicode values of a glyph name in Adobe Glyph List 2.0 + * which is not contained in AGL-1.2'. + * + * The function presupposes that uvlist is an array of PDC_MAX_UVLIST. + * + * Return value is the number of Unicodes. + */ +int +pdc_newadobe2unicodelist(const char *glyphname, pdc_ushort *uvlist) +{ + return pdc_glyphname2codelist(glyphname, tab_diffagl2uni, + (sizeof tab_diffagl2uni) / (sizeof (pdc_glyph_tab)), + uvlist); +} + +/* + * Returns the glyph name in Adobe Glyph List 2.0 + * which is not contained in AGL-1.2' corresponding + * to the supplied Unicode value. Ambiguous Unicode + * values or glyph names are not supported! + * If the value doesn't have a corresponding glyph name + * NULL will be returned. + */ +const char * +pdc_unicode2newadobe(pdc_ushort uv) +{ + return pdc_code2glyphname(uv, tab_uni2diffagl, + (sizeof tab_uni2diffagl) / (sizeof (pdc_glyph_tab))); +} + +/* + * Returns the glyph name in Adobe Glyph List 2.0 + * which is not contained in AGL-1.2' and which matches + * the supplied glyph name. + * If no match is found NULL will be returned. + */ +const char * +pdc_get_newadobe_glyphname(const char *glyphname) +{ + return pdc_glyphname2glyphname(glyphname, tab_diffagl2uni, + (sizeof tab_diffagl2uni) / (sizeof (pdc_glyph_tab))); +} + + +/* + * Returns the alternative Unicode value of a double-mapped + * AGL-1.2 glyph name. If the name is not double-mapped, + * -1 will be returned. + */ +int +pdc_glyphname2altunicode(const char *glyphname) +{ + return pdc_glyphname2code(glyphname, tab_double_mappping, + (sizeof (tab_double_mappping)) / (sizeof (pdc_glyph_tab))); +} + +/* + * Returns true if a character name is contained in pc_standard_latin_charset. + * Otherwise false will be returned. + */ +pdc_bool +pdc_is_std_charname(const char *glyphname) +{ + int lo = 0; + int hi = ((sizeof pc_standard_latin_charset) / (sizeof (char *))); + + if (glyphname) + { + while (lo < hi) + { + int i = (lo + hi) / 2; + int cmp = strcmp(glyphname, pc_standard_latin_charset[i]); + + if (cmp == 0) + return pdc_true; + + if (cmp < 0) + hi = i; + else + lo = i + 1; + } + } + + return pdc_false; +} + + + +/* -------------- special character mapping for Type1 fonts --------------- */ + +/* + * Deletes a bit in a bit mask. The bit indicates that + * the respective glyph name of AGL 2.0 is not available + * in a PostScript font. The glyph name is used to avoid + * ambiguities (see comment in pc_chartabs.h) + * + */ + +#define PDC_BIT_NBSP (1L<<0) +#define PDC_BIT_SHY (1L<<1) +#define PDC_BIT_MODMACRON (1L<<2) +#define PDC_BIT_CAPDELTA (1L<<3) +#define PDC_BIT_CAPOMEGA (1L<<4) +#define PDC_BIT_DIVSLASH (1L<<5) +#define PDC_BIT_BULLETOP (1L<<6) +#define PDC_BIT_SMALLMU (1L<<7) + +void +pdc_delete_missingglyph_bit(pdc_ushort uv, pdc_ulong *bmask) +{ + switch(uv) + { + case PDC_UNICODE_NBSP: + *bmask &= ~PDC_BIT_NBSP; + return; + + case PDC_UNICODE_SHY: + *bmask &= ~PDC_BIT_SHY; + return; + + case PDC_UNICODE_MODMACRON: + *bmask &= ~PDC_BIT_MODMACRON; + return; + + case PDC_UNICODE_CAPDELTA: + *bmask &= ~PDC_BIT_CAPDELTA; + return; + + case PDC_UNICODE_CAPOMEGA: + *bmask &= ~PDC_BIT_CAPOMEGA; + return; + + case PDC_UNICODE_DIVSLASH: + *bmask &= ~PDC_BIT_DIVSLASH; + return; + + case PDC_UNICODE_BULLETOP: + *bmask &= ~PDC_BIT_BULLETOP; + return; + + case PDC_UNICODE_SMALLMU: + *bmask &= ~PDC_BIT_SMALLMU; + return; + + default: + return; + } +} + +/* + * Returnes an alternative Unicode value and/or glyph name for an + * AGL 2.0 glyph name which is not available in a PostScript font. + * + */ + +pdc_ushort +pdc_get_alter_glyphname(pdc_ushort uv, pdc_ulong bmask, char **glyphname) +{ + switch(uv) + { + case PDC_UNICODE_NBSP: + if (bmask & PDC_BIT_NBSP) + { + if (glyphname) + *glyphname = (char *) glyph_space; + return PDC_UNICODE_SPACE; + } + break; + + case PDC_UNICODE_SHY: + if (bmask & PDC_BIT_SHY) + { + if (glyphname) + *glyphname = (char *) glyph_hyphen; + return PDC_UNICODE_HYPHEN; + } + break; + + case PDC_UNICODE_MODMACRON: + if (bmask & PDC_BIT_MODMACRON) + { + if (glyphname) + *glyphname = (char *) glyph_macron; + return PDC_UNICODE_MACRON; + } + break; + + case PDC_UNICODE_CAPDELTA: + if (bmask & PDC_BIT_CAPDELTA) + { + if (glyphname) + *glyphname = (char *) glyph_Delta; + return PDC_UNICODE_INCREMENT; + } + break; + + case PDC_UNICODE_CAPOMEGA: + if (bmask & PDC_BIT_CAPOMEGA) + { + if (glyphname) + *glyphname = (char *) glyph_Omega; + return PDC_UNICODE_OHMSIGN; + } + break; + + case PDC_UNICODE_DIVSLASH: + if (bmask & PDC_BIT_DIVSLASH) + { + if (glyphname) + *glyphname = (char *) glyph_fraction; + return PDC_UNICODE_FRACSLASH; + } + + case PDC_UNICODE_BULLETOP: + if (bmask & PDC_BIT_BULLETOP) + { + if (glyphname) + *glyphname = (char *) glyph_periodcentered; + return PDC_UNICODE_MIDDLEDOT; + } + + case PDC_UNICODE_SMALLMU: + if (bmask & PDC_BIT_SMALLMU) + { + if (glyphname) + *glyphname = (char *) glyph_mu; + return PDC_UNICODE_MICRO; + } + + default: + if (glyphname) + { + if (*glyphname == NULL) + *glyphname = (char *) pdc_get_notdef_glyphname(); + return 0; + } + } + + return uv; +} + +/* + * Returns the Unicode value for a given string Unicode expression: + * + * - Byte 1...255 -> U0001...U00FF + * - U+XXXXX + * - 0xXXXXX + * - HTML character reference without frame syntax &...; + * + * If no conversion is possible -1 will be returned. + */ +int +pdc_string2unicode(pdc_core *pdc, const char *text, int i_flags, + const pdc_keyconn *keyconn, pdc_bool verbose) +{ + int iz = PDC_KEY_NOTFOUND, usv = -1; + pdc_bool seterr = pdc_false; + int flags = PDC_INT_UNSIGNED; + int i = 0; + + (void) verbose; + + /* single byte as Unicode value */ + if (strlen(text) == 1) + { + char c = text[0]; + usv = (pdc_byte) c; + } + else + { + /* keyword */ + if (keyconn) + { + if (i_flags & PDC_INT_CASESENS) + iz = pdc_get_keycode(text, keyconn); + else + iz = pdc_get_keycode_ci(text, keyconn); + } + if (iz != PDC_KEY_NOTFOUND) + { + usv = iz; + } + else + { + /* Unicode value */ + if (!pdc_strincmp(text, "U+", 2)) + { + flags |= PDC_INT_HEXADEC; + i = 2; + } + if (!pdc_str2integer(&text[i], flags, &iz)) + { + seterr = pdc_true; + } + else if (iz >= PDC_NUM_UNIVAL || + (iz >= PDC_UNICODE_MINHIGHSUR && + iz <= PDC_UNICODE_MAXLOWSUR)) + { + seterr = pdc_true; + } + else + { + usv = iz; + } + } + } + + if (seterr) + { + pdc_set_errmsg(pdc, PDC_E_CONV_ILLUTF32, &text[i], 0, 0, 0); + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + } + + return usv; +} + +/* + * Returns true if Unicode character is a character relevant for line breaking + * + */ +pdc_bool +pdc_is_linebreaking_relchar(pdc_ushort uv) +{ + switch (uv) + { + case PDC_UNICODE_HT: + case PDC_UNICODE_LF: + case PDC_UNICODE_VT: + case PDC_UNICODE_FF: + case PDC_UNICODE_CR: + case PDC_UNICODE_NEL: + case PDC_UNICODE_SHY: + case PDC_UNICODE_LS: + case PDC_UNICODE_PS: + return pdc_true; + } + + return pdc_false; +} + + diff --git a/src/pdflib/pdcore/pc_chartabs.h b/src/pdflib/pdcore/pc_chartabs.h new file mode 100644 index 0000000..cd6970b --- /dev/null +++ b/src/pdflib/pdcore/pc_chartabs.h @@ -0,0 +1,13851 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_chartabs.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * This file contains Adobe Glyph Names, HTML character reference names and + * some special glyph names. + * + */ + +#ifndef PC_CHARTABS_H +#define PC_CHARTABS_H + +/* + * All glyph names of Adobe Glyph List (AGL) version 2.0 + * + */ + +static const char glyph__notdef[] = ".notdef"; + +static const char glyph_A[] = "A"; +static const char glyph_AE[] = "AE"; +static const char glyph_AEacute[] = "AEacute"; +static const char glyph_AEmacron[] = "AEmacron"; +static const char glyph_AEsmall[] = "AEsmall"; +static const char glyph_Aacute[] = "Aacute"; +static const char glyph_Aacutesmall[] = "Aacutesmall"; +static const char glyph_Abreve[] = "Abreve"; +static const char glyph_Abreveacute[] = "Abreveacute"; +static const char glyph_Abrevecyrillic[] = "Abrevecyrillic"; +static const char glyph_Abrevedotbelow[] = "Abrevedotbelow"; +static const char glyph_Abrevegrave[] = "Abrevegrave"; +static const char glyph_Abrevehookabove[] = "Abrevehookabove"; +static const char glyph_Abrevetilde[] = "Abrevetilde"; +static const char glyph_Acaron[] = "Acaron"; +static const char glyph_Acircle[] = "Acircle"; +static const char glyph_Acircumflex[] = "Acircumflex"; +static const char glyph_Acircumflexacute[] = "Acircumflexacute"; +static const char glyph_Acircumflexdotbelow[] = "Acircumflexdotbelow"; +static const char glyph_Acircumflexgrave[] = "Acircumflexgrave"; +static const char glyph_Acircumflexhookabove[] = "Acircumflexhookabove"; +static const char glyph_Acircumflexsmall[] = "Acircumflexsmall"; +static const char glyph_Acircumflextilde[] = "Acircumflextilde"; +static const char glyph_Acute[] = "Acute"; +static const char glyph_Acutesmall[] = "Acutesmall"; +static const char glyph_Acyrillic[] = "Acyrillic"; +static const char glyph_Adblgrave[] = "Adblgrave"; +static const char glyph_Adieresis[] = "Adieresis"; +static const char glyph_Adieresiscyrillic[] = "Adieresiscyrillic"; +static const char glyph_Adieresismacron[] = "Adieresismacron"; +static const char glyph_Adieresissmall[] = "Adieresissmall"; +static const char glyph_Adotbelow[] = "Adotbelow"; +static const char glyph_Adotmacron[] = "Adotmacron"; +static const char glyph_Agrave[] = "Agrave"; +static const char glyph_Agravesmall[] = "Agravesmall"; +static const char glyph_Ahookabove[] = "Ahookabove"; +static const char glyph_Aiecyrillic[] = "Aiecyrillic"; +static const char glyph_Ainvertedbreve[] = "Ainvertedbreve"; +static const char glyph_Alpha[] = "Alpha"; +static const char glyph_Alphatonos[] = "Alphatonos"; +static const char glyph_Amacron[] = "Amacron"; +static const char glyph_Amonospace[] = "Amonospace"; +static const char glyph_Aogonek[] = "Aogonek"; +static const char glyph_Aring[] = "Aring"; +static const char glyph_Aringacute[] = "Aringacute"; +static const char glyph_Aringbelow[] = "Aringbelow"; +static const char glyph_Aringsmall[] = "Aringsmall"; +static const char glyph_Asmall[] = "Asmall"; +static const char glyph_Atilde[] = "Atilde"; +static const char glyph_Atildesmall[] = "Atildesmall"; +static const char glyph_Aybarmenian[] = "Aybarmenian"; +static const char glyph_B[] = "B"; +static const char glyph_Bcircle[] = "Bcircle"; +static const char glyph_Bdotaccent[] = "Bdotaccent"; +static const char glyph_Bdotbelow[] = "Bdotbelow"; +static const char glyph_Becyrillic[] = "Becyrillic"; +static const char glyph_Benarmenian[] = "Benarmenian"; +static const char glyph_Beta[] = "Beta"; +static const char glyph_Bhook[] = "Bhook"; +static const char glyph_Blinebelow[] = "Blinebelow"; +static const char glyph_Bmonospace[] = "Bmonospace"; +static const char glyph_Brevesmall[] = "Brevesmall"; +static const char glyph_Bsmall[] = "Bsmall"; +static const char glyph_Btopbar[] = "Btopbar"; +static const char glyph_C[] = "C"; +static const char glyph_Caarmenian[] = "Caarmenian"; +static const char glyph_Cacute[] = "Cacute"; +static const char glyph_Caron[] = "Caron"; +static const char glyph_Caronsmall[] = "Caronsmall"; +static const char glyph_Ccaron[] = "Ccaron"; +static const char glyph_Ccedilla[] = "Ccedilla"; +static const char glyph_Ccedillaacute[] = "Ccedillaacute"; +static const char glyph_Ccedillasmall[] = "Ccedillasmall"; +static const char glyph_Ccircle[] = "Ccircle"; +static const char glyph_Ccircumflex[] = "Ccircumflex"; +static const char glyph_Cdot[] = "Cdot"; +static const char glyph_Cdotaccent[] = "Cdotaccent"; +static const char glyph_Cedillasmall[] = "Cedillasmall"; +static const char glyph_Chaarmenian[] = "Chaarmenian"; +static const char glyph_Cheabkhasiancyrillic[] = "Cheabkhasiancyrillic"; +static const char glyph_Checyrillic[] = "Checyrillic"; +static const char glyph_Chedescenderabkhasiancyrillic[] = +"Chedescenderabkhasiancyrillic"; +static const char glyph_Chedescendercyrillic[] = "Chedescendercyrillic"; +static const char glyph_Chedieresiscyrillic[] = "Chedieresiscyrillic"; +static const char glyph_Cheharmenian[] = "Cheharmenian"; +static const char glyph_Chekhakassiancyrillic[] = "Chekhakassiancyrillic"; +static const char glyph_Cheverticalstrokecyrillic[] = +"Cheverticalstrokecyrillic"; +static const char glyph_Chi[] = "Chi"; +static const char glyph_Chook[] = "Chook"; +static const char glyph_Circumflexsmall[] = "Circumflexsmall"; +static const char glyph_Cmonospace[] = "Cmonospace"; +static const char glyph_Coarmenian[] = "Coarmenian"; +static const char glyph_Csmall[] = "Csmall"; +static const char glyph_D[] = "D"; +static const char glyph_DZ[] = "DZ"; +static const char glyph_DZcaron[] = "DZcaron"; +static const char glyph_Daarmenian[] = "Daarmenian"; +static const char glyph_Dafrican[] = "Dafrican"; +static const char glyph_Dcaron[] = "Dcaron"; +static const char glyph_Dcedilla[] = "Dcedilla"; +static const char glyph_Dcircle[] = "Dcircle"; +static const char glyph_Dcircumflexbelow[] = "Dcircumflexbelow"; +static const char glyph_Dcroat[] = "Dcroat"; +static const char glyph_Ddotaccent[] = "Ddotaccent"; +static const char glyph_Ddotbelow[] = "Ddotbelow"; +static const char glyph_Decyrillic[] = "Decyrillic"; +static const char glyph_Deicoptic[] = "Deicoptic"; +static const char glyph_Delta[] = "Delta"; +static const char glyph_Deltagreek[] = "Deltagreek"; +static const char glyph_Dhook[] = "Dhook"; +static const char glyph_Dieresis[] = "Dieresis"; +static const char glyph_DieresisAcute[] = "DieresisAcute"; +static const char glyph_DieresisGrave[] = "DieresisGrave"; +static const char glyph_Dieresissmall[] = "Dieresissmall"; +static const char glyph_Digammagreek[] = "Digammagreek"; +static const char glyph_Djecyrillic[] = "Djecyrillic"; +static const char glyph_Dlinebelow[] = "Dlinebelow"; +static const char glyph_Dmonospace[] = "Dmonospace"; +static const char glyph_Dotaccentsmall[] = "Dotaccentsmall"; +static const char glyph_Dslash[] = "Dslash"; +static const char glyph_Dsmall[] = "Dsmall"; +static const char glyph_Dtopbar[] = "Dtopbar"; +static const char glyph_Dz[] = "Dz"; +static const char glyph_Dzcaron[] = "Dzcaron"; +static const char glyph_Dzeabkhasiancyrillic[] = "Dzeabkhasiancyrillic"; +static const char glyph_Dzecyrillic[] = "Dzecyrillic"; +static const char glyph_Dzhecyrillic[] = "Dzhecyrillic"; +static const char glyph_E[] = "E"; +static const char glyph_Eacute[] = "Eacute"; +static const char glyph_Eacutesmall[] = "Eacutesmall"; +static const char glyph_Ebreve[] = "Ebreve"; +static const char glyph_Ecaron[] = "Ecaron"; +static const char glyph_Ecedillabreve[] = "Ecedillabreve"; +static const char glyph_Echarmenian[] = "Echarmenian"; +static const char glyph_Ecircle[] = "Ecircle"; +static const char glyph_Ecircumflex[] = "Ecircumflex"; +static const char glyph_Ecircumflexacute[] = "Ecircumflexacute"; +static const char glyph_Ecircumflexbelow[] = "Ecircumflexbelow"; +static const char glyph_Ecircumflexdotbelow[] = "Ecircumflexdotbelow"; +static const char glyph_Ecircumflexgrave[] = "Ecircumflexgrave"; +static const char glyph_Ecircumflexhookabove[] = "Ecircumflexhookabove"; +static const char glyph_Ecircumflexsmall[] = "Ecircumflexsmall"; +static const char glyph_Ecircumflextilde[] = "Ecircumflextilde"; +static const char glyph_Ecyrillic[] = "Ecyrillic"; +static const char glyph_Edblgrave[] = "Edblgrave"; +static const char glyph_Edieresis[] = "Edieresis"; +static const char glyph_Edieresissmall[] = "Edieresissmall"; +static const char glyph_Edot[] = "Edot"; +static const char glyph_Edotaccent[] = "Edotaccent"; +static const char glyph_Edotbelow[] = "Edotbelow"; +static const char glyph_Efcyrillic[] = "Efcyrillic"; +static const char glyph_Egrave[] = "Egrave"; +static const char glyph_Egravesmall[] = "Egravesmall"; +static const char glyph_Eharmenian[] = "Eharmenian"; +static const char glyph_Ehookabove[] = "Ehookabove"; +static const char glyph_Eightroman[] = "Eightroman"; +static const char glyph_Einvertedbreve[] = "Einvertedbreve"; +static const char glyph_Eiotifiedcyrillic[] = "Eiotifiedcyrillic"; +static const char glyph_Elcyrillic[] = "Elcyrillic"; +static const char glyph_Elevenroman[] = "Elevenroman"; +static const char glyph_Emacron[] = "Emacron"; +static const char glyph_Emacronacute[] = "Emacronacute"; +static const char glyph_Emacrongrave[] = "Emacrongrave"; +static const char glyph_Emcyrillic[] = "Emcyrillic"; +static const char glyph_Emonospace[] = "Emonospace"; +static const char glyph_Encyrillic[] = "Encyrillic"; +static const char glyph_Endescendercyrillic[] = "Endescendercyrillic"; +static const char glyph_Eng[] = "Eng"; +static const char glyph_Enghecyrillic[] = "Enghecyrillic"; +static const char glyph_Enhookcyrillic[] = "Enhookcyrillic"; +static const char glyph_Eogonek[] = "Eogonek"; +static const char glyph_Eopen[] = "Eopen"; +static const char glyph_Epsilon[] = "Epsilon"; +static const char glyph_Epsilontonos[] = "Epsilontonos"; +static const char glyph_Ercyrillic[] = "Ercyrillic"; +static const char glyph_Ereversed[] = "Ereversed"; +static const char glyph_Ereversedcyrillic[] = "Ereversedcyrillic"; +static const char glyph_Escyrillic[] = "Escyrillic"; +static const char glyph_Esdescendercyrillic[] = "Esdescendercyrillic"; +static const char glyph_Esh[] = "Esh"; +static const char glyph_Esmall[] = "Esmall"; +static const char glyph_Eta[] = "Eta"; +static const char glyph_Etarmenian[] = "Etarmenian"; +static const char glyph_Etatonos[] = "Etatonos"; +static const char glyph_Eth[] = "Eth"; +static const char glyph_Ethsmall[] = "Ethsmall"; +static const char glyph_Etilde[] = "Etilde"; +static const char glyph_Etildebelow[] = "Etildebelow"; +static const char glyph_Euro[] = "Euro"; +static const char glyph_Ezh[] = "Ezh"; +static const char glyph_Ezhcaron[] = "Ezhcaron"; +static const char glyph_Ezhreversed[] = "Ezhreversed"; +static const char glyph_F[] = "F"; +static const char glyph_Fcircle[] = "Fcircle"; +static const char glyph_Fdotaccent[] = "Fdotaccent"; +static const char glyph_Feharmenian[] = "Feharmenian"; +static const char glyph_Feicoptic[] = "Feicoptic"; +static const char glyph_Fhook[] = "Fhook"; +static const char glyph_Fitacyrillic[] = "Fitacyrillic"; +static const char glyph_Fiveroman[] = "Fiveroman"; +static const char glyph_Fmonospace[] = "Fmonospace"; +static const char glyph_Fourroman[] = "Fourroman"; +static const char glyph_Fsmall[] = "Fsmall"; +static const char glyph_G[] = "G"; +static const char glyph_GBsquare[] = "GBsquare"; +static const char glyph_Gacute[] = "Gacute"; +static const char glyph_Gamma[] = "Gamma"; +static const char glyph_Gammaafrican[] = "Gammaafrican"; +static const char glyph_Gangiacoptic[] = "Gangiacoptic"; +static const char glyph_Gbreve[] = "Gbreve"; +static const char glyph_Gcaron[] = "Gcaron"; +static const char glyph_Gcedilla[] = "Gcedilla"; +static const char glyph_Gcircle[] = "Gcircle"; +static const char glyph_Gcircumflex[] = "Gcircumflex"; +static const char glyph_Gcommaaccent[] = "Gcommaaccent"; +static const char glyph_Gdot[] = "Gdot"; +static const char glyph_Gdotaccent[] = "Gdotaccent"; +static const char glyph_Gecyrillic[] = "Gecyrillic"; +static const char glyph_Ghadarmenian[] = "Ghadarmenian"; +static const char glyph_Ghemiddlehookcyrillic[] = "Ghemiddlehookcyrillic"; +static const char glyph_Ghestrokecyrillic[] = "Ghestrokecyrillic"; +static const char glyph_Gheupturncyrillic[] = "Gheupturncyrillic"; +static const char glyph_Ghook[] = "Ghook"; +static const char glyph_Gimarmenian[] = "Gimarmenian"; +static const char glyph_Gjecyrillic[] = "Gjecyrillic"; +static const char glyph_Gmacron[] = "Gmacron"; +static const char glyph_Gmonospace[] = "Gmonospace"; +static const char glyph_Grave[] = "Grave"; +static const char glyph_Gravesmall[] = "Gravesmall"; +static const char glyph_Gsmall[] = "Gsmall"; +static const char glyph_Gsmallhook[] = "Gsmallhook"; +static const char glyph_Gstroke[] = "Gstroke"; +static const char glyph_H[] = "H"; +static const char glyph_H18533[] = "H18533"; +static const char glyph_H18543[] = "H18543"; +static const char glyph_H18551[] = "H18551"; +static const char glyph_H22073[] = "H22073"; +static const char glyph_HPsquare[] = "HPsquare"; +static const char glyph_Haabkhasiancyrillic[] = "Haabkhasiancyrillic"; +static const char glyph_Hadescendercyrillic[] = "Hadescendercyrillic"; +static const char glyph_Hardsigncyrillic[] = "Hardsigncyrillic"; +static const char glyph_Hbar[] = "Hbar"; +static const char glyph_Hbrevebelow[] = "Hbrevebelow"; +static const char glyph_Hcedilla[] = "Hcedilla"; +static const char glyph_Hcircle[] = "Hcircle"; +static const char glyph_Hcircumflex[] = "Hcircumflex"; +static const char glyph_Hdieresis[] = "Hdieresis"; +static const char glyph_Hdotaccent[] = "Hdotaccent"; +static const char glyph_Hdotbelow[] = "Hdotbelow"; +static const char glyph_Hmonospace[] = "Hmonospace"; +static const char glyph_Hoarmenian[] = "Hoarmenian"; +static const char glyph_Horicoptic[] = "Horicoptic"; +static const char glyph_Hsmall[] = "Hsmall"; +static const char glyph_Hungarumlaut[] = "Hungarumlaut"; +static const char glyph_Hungarumlautsmall[] = "Hungarumlautsmall"; +static const char glyph_Hzsquare[] = "Hzsquare"; +static const char glyph_I[] = "I"; +static const char glyph_IAcyrillic[] = "IAcyrillic"; +static const char glyph_IJ[] = "IJ"; +static const char glyph_IUcyrillic[] = "IUcyrillic"; +static const char glyph_Iacute[] = "Iacute"; +static const char glyph_Iacutesmall[] = "Iacutesmall"; +static const char glyph_Ibreve[] = "Ibreve"; +static const char glyph_Icaron[] = "Icaron"; +static const char glyph_Icircle[] = "Icircle"; +static const char glyph_Icircumflex[] = "Icircumflex"; +static const char glyph_Icircumflexsmall[] = "Icircumflexsmall"; +static const char glyph_Icyrillic[] = "Icyrillic"; +static const char glyph_Idblgrave[] = "Idblgrave"; +static const char glyph_Idieresis[] = "Idieresis"; +static const char glyph_Idieresisacute[] = "Idieresisacute"; +static const char glyph_Idieresiscyrillic[] = "Idieresiscyrillic"; +static const char glyph_Idieresissmall[] = "Idieresissmall"; +static const char glyph_Idot[] = "Idot"; +static const char glyph_Idotaccent[] = "Idotaccent"; +static const char glyph_Idotbelow[] = "Idotbelow"; +static const char glyph_Iebrevecyrillic[] = "Iebrevecyrillic"; +static const char glyph_Iecyrillic[] = "Iecyrillic"; +static const char glyph_Ifraktur[] = "Ifraktur"; +static const char glyph_Igrave[] = "Igrave"; +static const char glyph_Igravesmall[] = "Igravesmall"; +static const char glyph_Ihookabove[] = "Ihookabove"; +static const char glyph_Iicyrillic[] = "Iicyrillic"; +static const char glyph_Iinvertedbreve[] = "Iinvertedbreve"; +static const char glyph_Iishortcyrillic[] = "Iishortcyrillic"; +static const char glyph_Imacron[] = "Imacron"; +static const char glyph_Imacroncyrillic[] = "Imacroncyrillic"; +static const char glyph_Imonospace[] = "Imonospace"; +static const char glyph_Iniarmenian[] = "Iniarmenian"; +static const char glyph_Iocyrillic[] = "Iocyrillic"; +static const char glyph_Iogonek[] = "Iogonek"; +static const char glyph_Iota[] = "Iota"; +static const char glyph_Iotaafrican[] = "Iotaafrican"; +static const char glyph_Iotadieresis[] = "Iotadieresis"; +static const char glyph_Iotatonos[] = "Iotatonos"; +static const char glyph_Ismall[] = "Ismall"; +static const char glyph_Istroke[] = "Istroke"; +static const char glyph_Itilde[] = "Itilde"; +static const char glyph_Itildebelow[] = "Itildebelow"; +static const char glyph_Izhitsacyrillic[] = "Izhitsacyrillic"; +static const char glyph_Izhitsadblgravecyrillic[] = "Izhitsadblgravecyrillic"; +static const char glyph_J[] = "J"; +static const char glyph_Jaarmenian[] = "Jaarmenian"; +static const char glyph_Jcircle[] = "Jcircle"; +static const char glyph_Jcircumflex[] = "Jcircumflex"; +static const char glyph_Jecyrillic[] = "Jecyrillic"; +static const char glyph_Jheharmenian[] = "Jheharmenian"; +static const char glyph_Jmonospace[] = "Jmonospace"; +static const char glyph_Jsmall[] = "Jsmall"; +static const char glyph_K[] = "K"; +static const char glyph_KBsquare[] = "KBsquare"; +static const char glyph_KKsquare[] = "KKsquare"; +static const char glyph_Kabashkircyrillic[] = "Kabashkircyrillic"; +static const char glyph_Kacute[] = "Kacute"; +static const char glyph_Kacyrillic[] = "Kacyrillic"; +static const char glyph_Kadescendercyrillic[] = "Kadescendercyrillic"; +static const char glyph_Kahookcyrillic[] = "Kahookcyrillic"; +static const char glyph_Kappa[] = "Kappa"; +static const char glyph_Kastrokecyrillic[] = "Kastrokecyrillic"; +static const char glyph_Kaverticalstrokecyrillic[] = "Kaverticalstrokecyrillic"; +static const char glyph_Kcaron[] = "Kcaron"; +static const char glyph_Kcedilla[] = "Kcedilla"; +static const char glyph_Kcircle[] = "Kcircle"; +static const char glyph_Kcommaaccent[] = "Kcommaaccent"; +static const char glyph_Kdotbelow[] = "Kdotbelow"; +static const char glyph_Keharmenian[] = "Keharmenian"; +static const char glyph_Kenarmenian[] = "Kenarmenian"; +static const char glyph_Khacyrillic[] = "Khacyrillic"; +static const char glyph_Kheicoptic[] = "Kheicoptic"; +static const char glyph_Khook[] = "Khook"; +static const char glyph_Kjecyrillic[] = "Kjecyrillic"; +static const char glyph_Klinebelow[] = "Klinebelow"; +static const char glyph_Kmonospace[] = "Kmonospace"; +static const char glyph_Koppacyrillic[] = "Koppacyrillic"; +static const char glyph_Koppagreek[] = "Koppagreek"; +static const char glyph_Ksicyrillic[] = "Ksicyrillic"; +static const char glyph_Ksmall[] = "Ksmall"; +static const char glyph_L[] = "L"; +static const char glyph_LJ[] = "LJ"; +static const char glyph_LL[] = "LL"; +static const char glyph_Lacute[] = "Lacute"; +static const char glyph_Lambda[] = "Lambda"; +static const char glyph_Lcaron[] = "Lcaron"; +static const char glyph_Lcedilla[] = "Lcedilla"; +static const char glyph_Lcircle[] = "Lcircle"; +static const char glyph_Lcircumflexbelow[] = "Lcircumflexbelow"; +static const char glyph_Lcommaaccent[] = "Lcommaaccent"; +static const char glyph_Ldot[] = "Ldot"; +static const char glyph_Ldotaccent[] = "Ldotaccent"; +static const char glyph_Ldotbelow[] = "Ldotbelow"; +static const char glyph_Ldotbelowmacron[] = "Ldotbelowmacron"; +static const char glyph_Liwnarmenian[] = "Liwnarmenian"; +static const char glyph_Lj[] = "Lj"; +static const char glyph_Ljecyrillic[] = "Ljecyrillic"; +static const char glyph_Llinebelow[] = "Llinebelow"; +static const char glyph_Lmonospace[] = "Lmonospace"; +static const char glyph_Lslash[] = "Lslash"; +static const char glyph_Lslashsmall[] = "Lslashsmall"; +static const char glyph_Lsmall[] = "Lsmall"; +static const char glyph_M[] = "M"; +static const char glyph_MBsquare[] = "MBsquare"; +static const char glyph_Macron[] = "Macron"; +static const char glyph_Macronsmall[] = "Macronsmall"; +static const char glyph_Macute[] = "Macute"; +static const char glyph_Mcircle[] = "Mcircle"; +static const char glyph_Mdotaccent[] = "Mdotaccent"; +static const char glyph_Mdotbelow[] = "Mdotbelow"; +static const char glyph_Menarmenian[] = "Menarmenian"; +static const char glyph_Mmonospace[] = "Mmonospace"; +static const char glyph_Msmall[] = "Msmall"; +static const char glyph_Mturned[] = "Mturned"; +static const char glyph_Mu[] = "Mu"; +static const char glyph_N[] = "N"; +static const char glyph_NJ[] = "NJ"; +static const char glyph_Nacute[] = "Nacute"; +static const char glyph_Ncaron[] = "Ncaron"; +static const char glyph_Ncedilla[] = "Ncedilla"; +static const char glyph_Ncircle[] = "Ncircle"; +static const char glyph_Ncircumflexbelow[] = "Ncircumflexbelow"; +static const char glyph_Ncommaaccent[] = "Ncommaaccent"; +static const char glyph_Ndotaccent[] = "Ndotaccent"; +static const char glyph_Ndotbelow[] = "Ndotbelow"; +static const char glyph_Nhookleft[] = "Nhookleft"; +static const char glyph_Nineroman[] = "Nineroman"; +static const char glyph_Nj[] = "Nj"; +static const char glyph_Njecyrillic[] = "Njecyrillic"; +static const char glyph_Nlinebelow[] = "Nlinebelow"; +static const char glyph_Nmonospace[] = "Nmonospace"; +static const char glyph_Nowarmenian[] = "Nowarmenian"; +static const char glyph_Nsmall[] = "Nsmall"; +static const char glyph_Ntilde[] = "Ntilde"; +static const char glyph_Ntildesmall[] = "Ntildesmall"; +static const char glyph_Nu[] = "Nu"; +static const char glyph_O[] = "O"; +static const char glyph_OE[] = "OE"; +static const char glyph_OEsmall[] = "OEsmall"; +static const char glyph_Oacute[] = "Oacute"; +static const char glyph_Oacutesmall[] = "Oacutesmall"; +static const char glyph_Obarredcyrillic[] = "Obarredcyrillic"; +static const char glyph_Obarreddieresiscyrillic[] = "Obarreddieresiscyrillic"; +static const char glyph_Obreve[] = "Obreve"; +static const char glyph_Ocaron[] = "Ocaron"; +static const char glyph_Ocenteredtilde[] = "Ocenteredtilde"; +static const char glyph_Ocircle[] = "Ocircle"; +static const char glyph_Ocircumflex[] = "Ocircumflex"; +static const char glyph_Ocircumflexacute[] = "Ocircumflexacute"; +static const char glyph_Ocircumflexdotbelow[] = "Ocircumflexdotbelow"; +static const char glyph_Ocircumflexgrave[] = "Ocircumflexgrave"; +static const char glyph_Ocircumflexhookabove[] = "Ocircumflexhookabove"; +static const char glyph_Ocircumflexsmall[] = "Ocircumflexsmall"; +static const char glyph_Ocircumflextilde[] = "Ocircumflextilde"; +static const char glyph_Ocyrillic[] = "Ocyrillic"; +static const char glyph_Odblacute[] = "Odblacute"; +static const char glyph_Odblgrave[] = "Odblgrave"; +static const char glyph_Odieresis[] = "Odieresis"; +static const char glyph_Odieresiscyrillic[] = "Odieresiscyrillic"; +static const char glyph_Odieresissmall[] = "Odieresissmall"; +static const char glyph_Odotbelow[] = "Odotbelow"; +static const char glyph_Ogoneksmall[] = "Ogoneksmall"; +static const char glyph_Ograve[] = "Ograve"; +static const char glyph_Ogravesmall[] = "Ogravesmall"; +static const char glyph_Oharmenian[] = "Oharmenian"; +static const char glyph_Ohm[] = "Ohm"; +static const char glyph_Ohookabove[] = "Ohookabove"; +static const char glyph_Ohorn[] = "Ohorn"; +static const char glyph_Ohornacute[] = "Ohornacute"; +static const char glyph_Ohorndotbelow[] = "Ohorndotbelow"; +static const char glyph_Ohorngrave[] = "Ohorngrave"; +static const char glyph_Ohornhookabove[] = "Ohornhookabove"; +static const char glyph_Ohorntilde[] = "Ohorntilde"; +static const char glyph_Ohungarumlaut[] = "Ohungarumlaut"; +static const char glyph_Oi[] = "Oi"; +static const char glyph_Oinvertedbreve[] = "Oinvertedbreve"; +static const char glyph_Omacron[] = "Omacron"; +static const char glyph_Omacronacute[] = "Omacronacute"; +static const char glyph_Omacrongrave[] = "Omacrongrave"; +static const char glyph_Omega[] = "Omega"; +static const char glyph_Omegacyrillic[] = "Omegacyrillic"; +static const char glyph_Omegagreek[] = "Omegagreek"; +static const char glyph_Omegaroundcyrillic[] = "Omegaroundcyrillic"; +static const char glyph_Omegatitlocyrillic[] = "Omegatitlocyrillic"; +static const char glyph_Omegatonos[] = "Omegatonos"; +static const char glyph_Omicron[] = "Omicron"; +static const char glyph_Omicrontonos[] = "Omicrontonos"; +static const char glyph_Omonospace[] = "Omonospace"; +static const char glyph_Oneroman[] = "Oneroman"; +static const char glyph_Oogonek[] = "Oogonek"; +static const char glyph_Oogonekmacron[] = "Oogonekmacron"; +static const char glyph_Oopen[] = "Oopen"; +static const char glyph_Oslash[] = "Oslash"; +static const char glyph_Oslashacute[] = "Oslashacute"; +static const char glyph_Oslashsmall[] = "Oslashsmall"; +static const char glyph_Osmall[] = "Osmall"; +static const char glyph_Ostrokeacute[] = "Ostrokeacute"; +static const char glyph_Otcyrillic[] = "Otcyrillic"; +static const char glyph_Otilde[] = "Otilde"; +static const char glyph_Otildeacute[] = "Otildeacute"; +static const char glyph_Otildedieresis[] = "Otildedieresis"; +static const char glyph_Otildesmall[] = "Otildesmall"; +static const char glyph_P[] = "P"; +static const char glyph_Pacute[] = "Pacute"; +static const char glyph_Pcircle[] = "Pcircle"; +static const char glyph_Pdotaccent[] = "Pdotaccent"; +static const char glyph_Pecyrillic[] = "Pecyrillic"; +static const char glyph_Peharmenian[] = "Peharmenian"; +static const char glyph_Pemiddlehookcyrillic[] = "Pemiddlehookcyrillic"; +static const char glyph_Phi[] = "Phi"; +static const char glyph_Phook[] = "Phook"; +static const char glyph_Pi[] = "Pi"; +static const char glyph_Piwrarmenian[] = "Piwrarmenian"; +static const char glyph_Pmonospace[] = "Pmonospace"; +static const char glyph_Psi[] = "Psi"; +static const char glyph_Psicyrillic[] = "Psicyrillic"; +static const char glyph_Psmall[] = "Psmall"; +static const char glyph_Q[] = "Q"; +static const char glyph_Qcircle[] = "Qcircle"; +static const char glyph_Qmonospace[] = "Qmonospace"; +static const char glyph_Qsmall[] = "Qsmall"; +static const char glyph_R[] = "R"; +static const char glyph_Raarmenian[] = "Raarmenian"; +static const char glyph_Racute[] = "Racute"; +static const char glyph_Rcaron[] = "Rcaron"; +static const char glyph_Rcedilla[] = "Rcedilla"; +static const char glyph_Rcircle[] = "Rcircle"; +static const char glyph_Rcommaaccent[] = "Rcommaaccent"; +static const char glyph_Rdblgrave[] = "Rdblgrave"; +static const char glyph_Rdotaccent[] = "Rdotaccent"; +static const char glyph_Rdotbelow[] = "Rdotbelow"; +static const char glyph_Rdotbelowmacron[] = "Rdotbelowmacron"; +static const char glyph_Reharmenian[] = "Reharmenian"; +static const char glyph_Rfraktur[] = "Rfraktur"; +static const char glyph_Rho[] = "Rho"; +static const char glyph_Ringsmall[] = "Ringsmall"; +static const char glyph_Rinvertedbreve[] = "Rinvertedbreve"; +static const char glyph_Rlinebelow[] = "Rlinebelow"; +static const char glyph_Rmonospace[] = "Rmonospace"; +static const char glyph_Rsmall[] = "Rsmall"; +static const char glyph_Rsmallinverted[] = "Rsmallinverted"; +static const char glyph_Rsmallinvertedsuperior[] = "Rsmallinvertedsuperior"; +static const char glyph_S[] = "S"; +static const char glyph_SF010000[] = "SF010000"; +static const char glyph_SF020000[] = "SF020000"; +static const char glyph_SF030000[] = "SF030000"; +static const char glyph_SF040000[] = "SF040000"; +static const char glyph_SF050000[] = "SF050000"; +static const char glyph_SF060000[] = "SF060000"; +static const char glyph_SF070000[] = "SF070000"; +static const char glyph_SF080000[] = "SF080000"; +static const char glyph_SF090000[] = "SF090000"; +static const char glyph_SF100000[] = "SF100000"; +static const char glyph_SF110000[] = "SF110000"; +static const char glyph_SF190000[] = "SF190000"; +static const char glyph_SF200000[] = "SF200000"; +static const char glyph_SF210000[] = "SF210000"; +static const char glyph_SF220000[] = "SF220000"; +static const char glyph_SF230000[] = "SF230000"; +static const char glyph_SF240000[] = "SF240000"; +static const char glyph_SF250000[] = "SF250000"; +static const char glyph_SF260000[] = "SF260000"; +static const char glyph_SF270000[] = "SF270000"; +static const char glyph_SF280000[] = "SF280000"; +static const char glyph_SF360000[] = "SF360000"; +static const char glyph_SF370000[] = "SF370000"; +static const char glyph_SF380000[] = "SF380000"; +static const char glyph_SF390000[] = "SF390000"; +static const char glyph_SF400000[] = "SF400000"; +static const char glyph_SF410000[] = "SF410000"; +static const char glyph_SF420000[] = "SF420000"; +static const char glyph_SF430000[] = "SF430000"; +static const char glyph_SF440000[] = "SF440000"; +static const char glyph_SF450000[] = "SF450000"; +static const char glyph_SF460000[] = "SF460000"; +static const char glyph_SF470000[] = "SF470000"; +static const char glyph_SF480000[] = "SF480000"; +static const char glyph_SF490000[] = "SF490000"; +static const char glyph_SF500000[] = "SF500000"; +static const char glyph_SF510000[] = "SF510000"; +static const char glyph_SF520000[] = "SF520000"; +static const char glyph_SF530000[] = "SF530000"; +static const char glyph_SF540000[] = "SF540000"; +static const char glyph_Sacute[] = "Sacute"; +static const char glyph_Sacutedotaccent[] = "Sacutedotaccent"; +static const char glyph_Sampigreek[] = "Sampigreek"; +static const char glyph_Scaron[] = "Scaron"; +static const char glyph_Scarondotaccent[] = "Scarondotaccent"; +static const char glyph_Scaronsmall[] = "Scaronsmall"; +static const char glyph_Scedilla[] = "Scedilla"; +static const char glyph_Schwa[] = "Schwa"; +static const char glyph_Schwacyrillic[] = "Schwacyrillic"; +static const char glyph_Schwadieresiscyrillic[] = "Schwadieresiscyrillic"; +static const char glyph_Scircle[] = "Scircle"; +static const char glyph_Scircumflex[] = "Scircumflex"; +static const char glyph_Scommaaccent[] = "Scommaaccent"; +static const char glyph_Sdotaccent[] = "Sdotaccent"; +static const char glyph_Sdotbelow[] = "Sdotbelow"; +static const char glyph_Sdotbelowdotaccent[] = "Sdotbelowdotaccent"; +static const char glyph_Seharmenian[] = "Seharmenian"; +static const char glyph_Sevenroman[] = "Sevenroman"; +static const char glyph_Shaarmenian[] = "Shaarmenian"; +static const char glyph_Shacyrillic[] = "Shacyrillic"; +static const char glyph_Shchacyrillic[] = "Shchacyrillic"; +static const char glyph_Sheicoptic[] = "Sheicoptic"; +static const char glyph_Shhacyrillic[] = "Shhacyrillic"; +static const char glyph_Shimacoptic[] = "Shimacoptic"; +static const char glyph_Sigma[] = "Sigma"; +static const char glyph_Sixroman[] = "Sixroman"; +static const char glyph_Smonospace[] = "Smonospace"; +static const char glyph_Softsigncyrillic[] = "Softsigncyrillic"; +static const char glyph_Ssmall[] = "Ssmall"; +static const char glyph_Stigmagreek[] = "Stigmagreek"; +static const char glyph_T[] = "T"; +static const char glyph_Tau[] = "Tau"; +static const char glyph_Tbar[] = "Tbar"; +static const char glyph_Tcaron[] = "Tcaron"; +static const char glyph_Tcedilla[] = "Tcedilla"; +static const char glyph_Tcircle[] = "Tcircle"; +static const char glyph_Tcircumflexbelow[] = "Tcircumflexbelow"; +static const char glyph_Tcommaaccent[] = "Tcommaaccent"; +static const char glyph_Tdotaccent[] = "Tdotaccent"; +static const char glyph_Tdotbelow[] = "Tdotbelow"; +static const char glyph_Tecyrillic[] = "Tecyrillic"; +static const char glyph_Tedescendercyrillic[] = "Tedescendercyrillic"; +static const char glyph_Tenroman[] = "Tenroman"; +static const char glyph_Tetsecyrillic[] = "Tetsecyrillic"; +static const char glyph_Theta[] = "Theta"; +static const char glyph_Thook[] = "Thook"; +static const char glyph_Thorn[] = "Thorn"; +static const char glyph_Thornsmall[] = "Thornsmall"; +static const char glyph_Threeroman[] = "Threeroman"; +static const char glyph_Tildesmall[] = "Tildesmall"; +static const char glyph_Tiwnarmenian[] = "Tiwnarmenian"; +static const char glyph_Tlinebelow[] = "Tlinebelow"; +static const char glyph_Tmonospace[] = "Tmonospace"; +static const char glyph_Toarmenian[] = "Toarmenian"; +static const char glyph_Tonefive[] = "Tonefive"; +static const char glyph_Tonesix[] = "Tonesix"; +static const char glyph_Tonetwo[] = "Tonetwo"; +static const char glyph_Tretroflexhook[] = "Tretroflexhook"; +static const char glyph_Tsecyrillic[] = "Tsecyrillic"; +static const char glyph_Tshecyrillic[] = "Tshecyrillic"; +static const char glyph_Tsmall[] = "Tsmall"; +static const char glyph_Twelveroman[] = "Twelveroman"; +static const char glyph_Tworoman[] = "Tworoman"; +static const char glyph_U[] = "U"; +static const char glyph_Uacute[] = "Uacute"; +static const char glyph_Uacutesmall[] = "Uacutesmall"; +static const char glyph_Ubreve[] = "Ubreve"; +static const char glyph_Ucaron[] = "Ucaron"; +static const char glyph_Ucircle[] = "Ucircle"; +static const char glyph_Ucircumflex[] = "Ucircumflex"; +static const char glyph_Ucircumflexbelow[] = "Ucircumflexbelow"; +static const char glyph_Ucircumflexsmall[] = "Ucircumflexsmall"; +static const char glyph_Ucyrillic[] = "Ucyrillic"; +static const char glyph_Udblacute[] = "Udblacute"; +static const char glyph_Udblgrave[] = "Udblgrave"; +static const char glyph_Udieresis[] = "Udieresis"; +static const char glyph_Udieresisacute[] = "Udieresisacute"; +static const char glyph_Udieresisbelow[] = "Udieresisbelow"; +static const char glyph_Udieresiscaron[] = "Udieresiscaron"; +static const char glyph_Udieresiscyrillic[] = "Udieresiscyrillic"; +static const char glyph_Udieresisgrave[] = "Udieresisgrave"; +static const char glyph_Udieresismacron[] = "Udieresismacron"; +static const char glyph_Udieresissmall[] = "Udieresissmall"; +static const char glyph_Udotbelow[] = "Udotbelow"; +static const char glyph_Ugrave[] = "Ugrave"; +static const char glyph_Ugravesmall[] = "Ugravesmall"; +static const char glyph_Uhookabove[] = "Uhookabove"; +static const char glyph_Uhorn[] = "Uhorn"; +static const char glyph_Uhornacute[] = "Uhornacute"; +static const char glyph_Uhorndotbelow[] = "Uhorndotbelow"; +static const char glyph_Uhorngrave[] = "Uhorngrave"; +static const char glyph_Uhornhookabove[] = "Uhornhookabove"; +static const char glyph_Uhorntilde[] = "Uhorntilde"; +static const char glyph_Uhungarumlaut[] = "Uhungarumlaut"; +static const char glyph_Uhungarumlautcyrillic[] = "Uhungarumlautcyrillic"; +static const char glyph_Uinvertedbreve[] = "Uinvertedbreve"; +static const char glyph_Ukcyrillic[] = "Ukcyrillic"; +static const char glyph_Umacron[] = "Umacron"; +static const char glyph_Umacroncyrillic[] = "Umacroncyrillic"; +static const char glyph_Umacrondieresis[] = "Umacrondieresis"; +static const char glyph_Umonospace[] = "Umonospace"; +static const char glyph_Uogonek[] = "Uogonek"; +static const char glyph_Upsilon[] = "Upsilon"; +static const char glyph_Upsilon1[] = "Upsilon1"; +static const char glyph_Upsilonacutehooksymbolgreek[] = +"Upsilonacutehooksymbolgreek"; +static const char glyph_Upsilonafrican[] = "Upsilonafrican"; +static const char glyph_Upsilondieresis[] = "Upsilondieresis"; +static const char glyph_Upsilondieresishooksymbolgreek[] = +"Upsilondieresishooksymbolgreek"; +static const char glyph_Upsilonhooksymbol[] = "Upsilonhooksymbol"; +static const char glyph_Upsilontonos[] = "Upsilontonos"; +static const char glyph_Uring[] = "Uring"; +static const char glyph_Ushortcyrillic[] = "Ushortcyrillic"; +static const char glyph_Usmall[] = "Usmall"; +static const char glyph_Ustraightcyrillic[] = "Ustraightcyrillic"; +static const char glyph_Ustraightstrokecyrillic[] = "Ustraightstrokecyrillic"; +static const char glyph_Utilde[] = "Utilde"; +static const char glyph_Utildeacute[] = "Utildeacute"; +static const char glyph_Utildebelow[] = "Utildebelow"; +static const char glyph_V[] = "V"; +static const char glyph_Vcircle[] = "Vcircle"; +static const char glyph_Vdotbelow[] = "Vdotbelow"; +static const char glyph_Vecyrillic[] = "Vecyrillic"; +static const char glyph_Vewarmenian[] = "Vewarmenian"; +static const char glyph_Vhook[] = "Vhook"; +static const char glyph_Vmonospace[] = "Vmonospace"; +static const char glyph_Voarmenian[] = "Voarmenian"; +static const char glyph_Vsmall[] = "Vsmall"; +static const char glyph_Vtilde[] = "Vtilde"; +static const char glyph_W[] = "W"; +static const char glyph_Wacute[] = "Wacute"; +static const char glyph_Wcircle[] = "Wcircle"; +static const char glyph_Wcircumflex[] = "Wcircumflex"; +static const char glyph_Wdieresis[] = "Wdieresis"; +static const char glyph_Wdotaccent[] = "Wdotaccent"; +static const char glyph_Wdotbelow[] = "Wdotbelow"; +static const char glyph_Wgrave[] = "Wgrave"; +static const char glyph_Wmonospace[] = "Wmonospace"; +static const char glyph_Wsmall[] = "Wsmall"; +static const char glyph_X[] = "X"; +static const char glyph_Xcircle[] = "Xcircle"; +static const char glyph_Xdieresis[] = "Xdieresis"; +static const char glyph_Xdotaccent[] = "Xdotaccent"; +static const char glyph_Xeharmenian[] = "Xeharmenian"; +static const char glyph_Xi[] = "Xi"; +static const char glyph_Xmonospace[] = "Xmonospace"; +static const char glyph_Xsmall[] = "Xsmall"; +static const char glyph_Y[] = "Y"; +static const char glyph_Yacute[] = "Yacute"; +static const char glyph_Yacutesmall[] = "Yacutesmall"; +static const char glyph_Yatcyrillic[] = "Yatcyrillic"; +static const char glyph_Ycircle[] = "Ycircle"; +static const char glyph_Ycircumflex[] = "Ycircumflex"; +static const char glyph_Ydieresis[] = "Ydieresis"; +static const char glyph_Ydieresissmall[] = "Ydieresissmall"; +static const char glyph_Ydotaccent[] = "Ydotaccent"; +static const char glyph_Ydotbelow[] = "Ydotbelow"; +static const char glyph_Yericyrillic[] = "Yericyrillic"; +static const char glyph_Yerudieresiscyrillic[] = "Yerudieresiscyrillic"; +static const char glyph_Ygrave[] = "Ygrave"; +static const char glyph_Yhook[] = "Yhook"; +static const char glyph_Yhookabove[] = "Yhookabove"; +static const char glyph_Yiarmenian[] = "Yiarmenian"; +static const char glyph_Yicyrillic[] = "Yicyrillic"; +static const char glyph_Yiwnarmenian[] = "Yiwnarmenian"; +static const char glyph_Ymonospace[] = "Ymonospace"; +static const char glyph_Ysmall[] = "Ysmall"; +static const char glyph_Ytilde[] = "Ytilde"; +static const char glyph_Yusbigcyrillic[] = "Yusbigcyrillic"; +static const char glyph_Yusbigiotifiedcyrillic[] = "Yusbigiotifiedcyrillic"; +static const char glyph_Yuslittlecyrillic[] = "Yuslittlecyrillic"; +static const char glyph_Yuslittleiotifiedcyrillic[] = +"Yuslittleiotifiedcyrillic"; +static const char glyph_Z[] = "Z"; +static const char glyph_Zaarmenian[] = "Zaarmenian"; +static const char glyph_Zacute[] = "Zacute"; +static const char glyph_Zcaron[] = "Zcaron"; +static const char glyph_Zcaronsmall[] = "Zcaronsmall"; +static const char glyph_Zcircle[] = "Zcircle"; +static const char glyph_Zcircumflex[] = "Zcircumflex"; +static const char glyph_Zdot[] = "Zdot"; +static const char glyph_Zdotaccent[] = "Zdotaccent"; +static const char glyph_Zdotbelow[] = "Zdotbelow"; +static const char glyph_Zecyrillic[] = "Zecyrillic"; +static const char glyph_Zedescendercyrillic[] = "Zedescendercyrillic"; +static const char glyph_Zedieresiscyrillic[] = "Zedieresiscyrillic"; +static const char glyph_Zeta[] = "Zeta"; +static const char glyph_Zhearmenian[] = "Zhearmenian"; +static const char glyph_Zhebrevecyrillic[] = "Zhebrevecyrillic"; +static const char glyph_Zhecyrillic[] = "Zhecyrillic"; +static const char glyph_Zhedescendercyrillic[] = "Zhedescendercyrillic"; +static const char glyph_Zhedieresiscyrillic[] = "Zhedieresiscyrillic"; +static const char glyph_Zlinebelow[] = "Zlinebelow"; +static const char glyph_Zmonospace[] = "Zmonospace"; +static const char glyph_Zsmall[] = "Zsmall"; +static const char glyph_Zstroke[] = "Zstroke"; +static const char glyph_a[] = "a"; +static const char glyph_aabengali[] = "aabengali"; +static const char glyph_aacute[] = "aacute"; +static const char glyph_aadeva[] = "aadeva"; +static const char glyph_aagujarati[] = "aagujarati"; +static const char glyph_aagurmukhi[] = "aagurmukhi"; +static const char glyph_aamatragurmukhi[] = "aamatragurmukhi"; +static const char glyph_aarusquare[] = "aarusquare"; +static const char glyph_aavowelsignbengali[] = "aavowelsignbengali"; +static const char glyph_aavowelsigndeva[] = "aavowelsigndeva"; +static const char glyph_aavowelsigngujarati[] = "aavowelsigngujarati"; +static const char glyph_abbreviationmarkarmenian[] = +"abbreviationmarkarmenian"; +static const char glyph_abbreviationsigndeva[] = "abbreviationsigndeva"; +static const char glyph_abengali[] = "abengali"; +static const char glyph_abopomofo[] = "abopomofo"; +static const char glyph_abreve[] = "abreve"; +static const char glyph_abreveacute[] = "abreveacute"; +static const char glyph_abrevecyrillic[] = "abrevecyrillic"; +static const char glyph_abrevedotbelow[] = "abrevedotbelow"; +static const char glyph_abrevegrave[] = "abrevegrave"; +static const char glyph_abrevehookabove[] = "abrevehookabove"; +static const char glyph_abrevetilde[] = "abrevetilde"; +static const char glyph_acaron[] = "acaron"; +static const char glyph_acircle[] = "acircle"; +static const char glyph_acircumflex[] = "acircumflex"; +static const char glyph_acircumflexacute[] = "acircumflexacute"; +static const char glyph_acircumflexdotbelow[] = "acircumflexdotbelow"; +static const char glyph_acircumflexgrave[] = "acircumflexgrave"; +static const char glyph_acircumflexhookabove[] = "acircumflexhookabove"; +static const char glyph_acircumflextilde[] = "acircumflextilde"; +static const char glyph_acute[] = "acute"; +static const char glyph_acutebelowcmb[] = "acutebelowcmb"; +static const char glyph_acutecmb[] = "acutecmb"; +static const char glyph_acutecomb[] = "acutecomb"; +static const char glyph_acutedeva[] = "acutedeva"; +static const char glyph_acutelowmod[] = "acutelowmod"; +static const char glyph_acutetonecmb[] = "acutetonecmb"; +static const char glyph_acyrillic[] = "acyrillic"; +static const char glyph_adblgrave[] = "adblgrave"; +static const char glyph_addakgurmukhi[] = "addakgurmukhi"; +static const char glyph_adeva[] = "adeva"; +static const char glyph_adieresis[] = "adieresis"; +static const char glyph_adieresiscyrillic[] = "adieresiscyrillic"; +static const char glyph_adieresismacron[] = "adieresismacron"; +static const char glyph_adotbelow[] = "adotbelow"; +static const char glyph_adotmacron[] = "adotmacron"; +static const char glyph_ae[] = "ae"; +static const char glyph_aeacute[] = "aeacute"; +static const char glyph_aekorean[] = "aekorean"; +static const char glyph_aemacron[] = "aemacron"; +static const char glyph_afii00208[] = "afii00208"; +static const char glyph_afii08941[] = "afii08941"; +static const char glyph_afii10017[] = "afii10017"; +static const char glyph_afii10018[] = "afii10018"; +static const char glyph_afii10019[] = "afii10019"; +static const char glyph_afii10020[] = "afii10020"; +static const char glyph_afii10021[] = "afii10021"; +static const char glyph_afii10022[] = "afii10022"; +static const char glyph_afii10023[] = "afii10023"; +static const char glyph_afii10024[] = "afii10024"; +static const char glyph_afii10025[] = "afii10025"; +static const char glyph_afii10026[] = "afii10026"; +static const char glyph_afii10027[] = "afii10027"; +static const char glyph_afii10028[] = "afii10028"; +static const char glyph_afii10029[] = "afii10029"; +static const char glyph_afii10030[] = "afii10030"; +static const char glyph_afii10031[] = "afii10031"; +static const char glyph_afii10032[] = "afii10032"; +static const char glyph_afii10033[] = "afii10033"; +static const char glyph_afii10034[] = "afii10034"; +static const char glyph_afii10035[] = "afii10035"; +static const char glyph_afii10036[] = "afii10036"; +static const char glyph_afii10037[] = "afii10037"; +static const char glyph_afii10038[] = "afii10038"; +static const char glyph_afii10039[] = "afii10039"; +static const char glyph_afii10040[] = "afii10040"; +static const char glyph_afii10041[] = "afii10041"; +static const char glyph_afii10042[] = "afii10042"; +static const char glyph_afii10043[] = "afii10043"; +static const char glyph_afii10044[] = "afii10044"; +static const char glyph_afii10045[] = "afii10045"; +static const char glyph_afii10046[] = "afii10046"; +static const char glyph_afii10047[] = "afii10047"; +static const char glyph_afii10048[] = "afii10048"; +static const char glyph_afii10049[] = "afii10049"; +static const char glyph_afii10050[] = "afii10050"; +static const char glyph_afii10051[] = "afii10051"; +static const char glyph_afii10052[] = "afii10052"; +static const char glyph_afii10053[] = "afii10053"; +static const char glyph_afii10054[] = "afii10054"; +static const char glyph_afii10055[] = "afii10055"; +static const char glyph_afii10056[] = "afii10056"; +static const char glyph_afii10057[] = "afii10057"; +static const char glyph_afii10058[] = "afii10058"; +static const char glyph_afii10059[] = "afii10059"; +static const char glyph_afii10060[] = "afii10060"; +static const char glyph_afii10061[] = "afii10061"; +static const char glyph_afii10062[] = "afii10062"; +static const char glyph_afii10063[] = "afii10063"; +static const char glyph_afii10064[] = "afii10064"; +static const char glyph_afii10065[] = "afii10065"; +static const char glyph_afii10066[] = "afii10066"; +static const char glyph_afii10067[] = "afii10067"; +static const char glyph_afii10068[] = "afii10068"; +static const char glyph_afii10069[] = "afii10069"; +static const char glyph_afii10070[] = "afii10070"; +static const char glyph_afii10071[] = "afii10071"; +static const char glyph_afii10072[] = "afii10072"; +static const char glyph_afii10073[] = "afii10073"; +static const char glyph_afii10074[] = "afii10074"; +static const char glyph_afii10075[] = "afii10075"; +static const char glyph_afii10076[] = "afii10076"; +static const char glyph_afii10077[] = "afii10077"; +static const char glyph_afii10078[] = "afii10078"; +static const char glyph_afii10079[] = "afii10079"; +static const char glyph_afii10080[] = "afii10080"; +static const char glyph_afii10081[] = "afii10081"; +static const char glyph_afii10082[] = "afii10082"; +static const char glyph_afii10083[] = "afii10083"; +static const char glyph_afii10084[] = "afii10084"; +static const char glyph_afii10085[] = "afii10085"; +static const char glyph_afii10086[] = "afii10086"; +static const char glyph_afii10087[] = "afii10087"; +static const char glyph_afii10088[] = "afii10088"; +static const char glyph_afii10089[] = "afii10089"; +static const char glyph_afii10090[] = "afii10090"; +static const char glyph_afii10091[] = "afii10091"; +static const char glyph_afii10092[] = "afii10092"; +static const char glyph_afii10093[] = "afii10093"; +static const char glyph_afii10094[] = "afii10094"; +static const char glyph_afii10095[] = "afii10095"; +static const char glyph_afii10096[] = "afii10096"; +static const char glyph_afii10097[] = "afii10097"; +static const char glyph_afii10098[] = "afii10098"; +static const char glyph_afii10099[] = "afii10099"; +static const char glyph_afii10100[] = "afii10100"; +static const char glyph_afii10101[] = "afii10101"; +static const char glyph_afii10102[] = "afii10102"; +static const char glyph_afii10103[] = "afii10103"; +static const char glyph_afii10104[] = "afii10104"; +static const char glyph_afii10105[] = "afii10105"; +static const char glyph_afii10106[] = "afii10106"; +static const char glyph_afii10107[] = "afii10107"; +static const char glyph_afii10108[] = "afii10108"; +static const char glyph_afii10109[] = "afii10109"; +static const char glyph_afii10110[] = "afii10110"; +static const char glyph_afii10145[] = "afii10145"; +static const char glyph_afii10146[] = "afii10146"; +static const char glyph_afii10147[] = "afii10147"; +static const char glyph_afii10148[] = "afii10148"; +static const char glyph_afii10192[] = "afii10192"; +static const char glyph_afii10193[] = "afii10193"; +static const char glyph_afii10194[] = "afii10194"; +static const char glyph_afii10195[] = "afii10195"; +static const char glyph_afii10196[] = "afii10196"; +static const char glyph_afii10831[] = "afii10831"; +static const char glyph_afii10832[] = "afii10832"; +static const char glyph_afii10846[] = "afii10846"; +static const char glyph_afii299[] = "afii299"; +static const char glyph_afii300[] = "afii300"; +static const char glyph_afii301[] = "afii301"; +static const char glyph_afii57381[] = "afii57381"; +static const char glyph_afii57388[] = "afii57388"; +static const char glyph_afii57392[] = "afii57392"; +static const char glyph_afii57393[] = "afii57393"; +static const char glyph_afii57394[] = "afii57394"; +static const char glyph_afii57395[] = "afii57395"; +static const char glyph_afii57396[] = "afii57396"; +static const char glyph_afii57397[] = "afii57397"; +static const char glyph_afii57398[] = "afii57398"; +static const char glyph_afii57399[] = "afii57399"; +static const char glyph_afii57400[] = "afii57400"; +static const char glyph_afii57401[] = "afii57401"; +static const char glyph_afii57403[] = "afii57403"; +static const char glyph_afii57407[] = "afii57407"; +static const char glyph_afii57409[] = "afii57409"; +static const char glyph_afii57410[] = "afii57410"; +static const char glyph_afii57411[] = "afii57411"; +static const char glyph_afii57412[] = "afii57412"; +static const char glyph_afii57413[] = "afii57413"; +static const char glyph_afii57414[] = "afii57414"; +static const char glyph_afii57415[] = "afii57415"; +static const char glyph_afii57416[] = "afii57416"; +static const char glyph_afii57417[] = "afii57417"; +static const char glyph_afii57418[] = "afii57418"; +static const char glyph_afii57419[] = "afii57419"; +static const char glyph_afii57420[] = "afii57420"; +static const char glyph_afii57421[] = "afii57421"; +static const char glyph_afii57422[] = "afii57422"; +static const char glyph_afii57423[] = "afii57423"; +static const char glyph_afii57424[] = "afii57424"; +static const char glyph_afii57425[] = "afii57425"; +static const char glyph_afii57426[] = "afii57426"; +static const char glyph_afii57427[] = "afii57427"; +static const char glyph_afii57428[] = "afii57428"; +static const char glyph_afii57429[] = "afii57429"; +static const char glyph_afii57430[] = "afii57430"; +static const char glyph_afii57431[] = "afii57431"; +static const char glyph_afii57432[] = "afii57432"; +static const char glyph_afii57433[] = "afii57433"; +static const char glyph_afii57434[] = "afii57434"; +static const char glyph_afii57440[] = "afii57440"; +static const char glyph_afii57441[] = "afii57441"; +static const char glyph_afii57442[] = "afii57442"; +static const char glyph_afii57443[] = "afii57443"; +static const char glyph_afii57444[] = "afii57444"; +static const char glyph_afii57445[] = "afii57445"; +static const char glyph_afii57446[] = "afii57446"; +static const char glyph_afii57448[] = "afii57448"; +static const char glyph_afii57449[] = "afii57449"; +static const char glyph_afii57450[] = "afii57450"; +static const char glyph_afii57451[] = "afii57451"; +static const char glyph_afii57452[] = "afii57452"; +static const char glyph_afii57453[] = "afii57453"; +static const char glyph_afii57454[] = "afii57454"; +static const char glyph_afii57455[] = "afii57455"; +static const char glyph_afii57456[] = "afii57456"; +static const char glyph_afii57457[] = "afii57457"; +static const char glyph_afii57458[] = "afii57458"; +static const char glyph_afii57470[] = "afii57470"; +static const char glyph_afii57505[] = "afii57505"; +static const char glyph_afii57506[] = "afii57506"; +static const char glyph_afii57507[] = "afii57507"; +static const char glyph_afii57508[] = "afii57508"; +static const char glyph_afii57509[] = "afii57509"; +static const char glyph_afii57511[] = "afii57511"; +static const char glyph_afii57512[] = "afii57512"; +static const char glyph_afii57513[] = "afii57513"; +static const char glyph_afii57514[] = "afii57514"; +static const char glyph_afii57519[] = "afii57519"; +static const char glyph_afii57534[] = "afii57534"; +static const char glyph_afii57636[] = "afii57636"; +static const char glyph_afii57645[] = "afii57645"; +static const char glyph_afii57658[] = "afii57658"; +static const char glyph_afii57664[] = "afii57664"; +static const char glyph_afii57665[] = "afii57665"; +static const char glyph_afii57666[] = "afii57666"; +static const char glyph_afii57667[] = "afii57667"; +static const char glyph_afii57668[] = "afii57668"; +static const char glyph_afii57669[] = "afii57669"; +static const char glyph_afii57670[] = "afii57670"; +static const char glyph_afii57671[] = "afii57671"; +static const char glyph_afii57672[] = "afii57672"; +static const char glyph_afii57673[] = "afii57673"; +static const char glyph_afii57674[] = "afii57674"; +static const char glyph_afii57675[] = "afii57675"; +static const char glyph_afii57676[] = "afii57676"; +static const char glyph_afii57677[] = "afii57677"; +static const char glyph_afii57678[] = "afii57678"; +static const char glyph_afii57679[] = "afii57679"; +static const char glyph_afii57680[] = "afii57680"; +static const char glyph_afii57681[] = "afii57681"; +static const char glyph_afii57682[] = "afii57682"; +static const char glyph_afii57683[] = "afii57683"; +static const char glyph_afii57684[] = "afii57684"; +static const char glyph_afii57685[] = "afii57685"; +static const char glyph_afii57686[] = "afii57686"; +static const char glyph_afii57687[] = "afii57687"; +static const char glyph_afii57688[] = "afii57688"; +static const char glyph_afii57689[] = "afii57689"; +static const char glyph_afii57690[] = "afii57690"; +static const char glyph_afii57694[] = "afii57694"; +static const char glyph_afii57695[] = "afii57695"; +static const char glyph_afii57700[] = "afii57700"; +static const char glyph_afii57705[] = "afii57705"; +static const char glyph_afii57716[] = "afii57716"; +static const char glyph_afii57717[] = "afii57717"; +static const char glyph_afii57718[] = "afii57718"; +static const char glyph_afii57723[] = "afii57723"; +static const char glyph_afii57793[] = "afii57793"; +static const char glyph_afii57794[] = "afii57794"; +static const char glyph_afii57795[] = "afii57795"; +static const char glyph_afii57796[] = "afii57796"; +static const char glyph_afii57797[] = "afii57797"; +static const char glyph_afii57798[] = "afii57798"; +static const char glyph_afii57799[] = "afii57799"; +static const char glyph_afii57800[] = "afii57800"; +static const char glyph_afii57801[] = "afii57801"; +static const char glyph_afii57802[] = "afii57802"; +static const char glyph_afii57803[] = "afii57803"; +static const char glyph_afii57804[] = "afii57804"; +static const char glyph_afii57806[] = "afii57806"; +static const char glyph_afii57807[] = "afii57807"; +static const char glyph_afii57839[] = "afii57839"; +static const char glyph_afii57841[] = "afii57841"; +static const char glyph_afii57842[] = "afii57842"; +static const char glyph_afii57929[] = "afii57929"; +static const char glyph_afii61248[] = "afii61248"; +static const char glyph_afii61289[] = "afii61289"; +static const char glyph_afii61352[] = "afii61352"; +static const char glyph_afii61573[] = "afii61573"; +static const char glyph_afii61574[] = "afii61574"; +static const char glyph_afii61575[] = "afii61575"; +static const char glyph_afii61664[] = "afii61664"; +static const char glyph_afii63167[] = "afii63167"; +static const char glyph_afii64937[] = "afii64937"; +static const char glyph_agrave[] = "agrave"; +static const char glyph_agujarati[] = "agujarati"; +static const char glyph_agurmukhi[] = "agurmukhi"; +static const char glyph_ahiragana[] = "ahiragana"; +static const char glyph_ahookabove[] = "ahookabove"; +static const char glyph_aibengali[] = "aibengali"; +static const char glyph_aibopomofo[] = "aibopomofo"; +static const char glyph_aideva[] = "aideva"; +static const char glyph_aiecyrillic[] = "aiecyrillic"; +static const char glyph_aigujarati[] = "aigujarati"; +static const char glyph_aigurmukhi[] = "aigurmukhi"; +static const char glyph_aimatragurmukhi[] = "aimatragurmukhi"; +static const char glyph_ainarabic[] = "ainarabic"; +static const char glyph_ainfinalarabic[] = "ainfinalarabic"; +static const char glyph_aininitialarabic[] = "aininitialarabic"; +static const char glyph_ainmedialarabic[] = "ainmedialarabic"; +static const char glyph_ainvertedbreve[] = "ainvertedbreve"; +static const char glyph_aivowelsignbengali[] = "aivowelsignbengali"; +static const char glyph_aivowelsigndeva[] = "aivowelsigndeva"; +static const char glyph_aivowelsigngujarati[] = "aivowelsigngujarati"; +static const char glyph_akatakana[] = "akatakana"; +static const char glyph_akatakanahalfwidth[] = "akatakanahalfwidth"; +static const char glyph_akorean[] = "akorean"; +static const char glyph_alef[] = "alef"; +static const char glyph_alefarabic[] = "alefarabic"; +static const char glyph_alefdageshhebrew[] = "alefdageshhebrew"; +static const char glyph_aleffinalarabic[] = "aleffinalarabic"; +static const char glyph_alefhamzaabovearabic[] = "alefhamzaabovearabic"; +static const char glyph_alefhamzaabovefinalarabic[] = +"alefhamzaabovefinalarabic"; +static const char glyph_alefhamzabelowarabic[] = "alefhamzabelowarabic"; +static const char glyph_alefhamzabelowfinalarabic[] = +"alefhamzabelowfinalarabic"; +static const char glyph_alefhebrew[] = "alefhebrew"; +static const char glyph_aleflamedhebrew[] = "aleflamedhebrew"; +static const char glyph_alefmaddaabovearabic[] = "alefmaddaabovearabic"; +static const char glyph_alefmaddaabovefinalarabic[] = +"alefmaddaabovefinalarabic"; +static const char glyph_alefmaksuraarabic[] = "alefmaksuraarabic"; +static const char glyph_alefmaksurafinalarabic[] = "alefmaksurafinalarabic"; +static const char glyph_alefmaksurainitialarabic[] = +"alefmaksurainitialarabic"; +static const char glyph_alefmaksuramedialarabic[] = "alefmaksuramedialarabic"; +static const char glyph_alefpatahhebrew[] = "alefpatahhebrew"; +static const char glyph_alefqamatshebrew[] = "alefqamatshebrew"; +static const char glyph_aleph[] = "aleph"; +static const char glyph_allequal[] = "allequal"; +static const char glyph_alpha[] = "alpha"; +static const char glyph_alphatonos[] = "alphatonos"; +static const char glyph_amacron[] = "amacron"; +static const char glyph_amonospace[] = "amonospace"; +static const char glyph_ampersand[] = "ampersand"; +static const char glyph_ampersandmonospace[] = "ampersandmonospace"; +static const char glyph_ampersandsmall[] = "ampersandsmall"; +static const char glyph_amsquare[] = "amsquare"; +static const char glyph_anbopomofo[] = "anbopomofo"; +static const char glyph_angbopomofo[] = "angbopomofo"; +static const char glyph_angkhankhuthai[] = "angkhankhuthai"; +static const char glyph_angle[] = "angle"; +static const char glyph_anglebracketleft[] = "anglebracketleft"; +static const char glyph_anglebracketleftvertical[] = +"anglebracketleftvertical"; +static const char glyph_anglebracketright[] = "anglebracketright"; +static const char glyph_anglebracketrightvertical[] = +"anglebracketrightvertical"; +static const char glyph_angleleft[] = "angleleft"; +static const char glyph_angleright[] = "angleright"; +static const char glyph_angstrom[] = "angstrom"; +static const char glyph_anoteleia[] = "anoteleia"; +static const char glyph_anudattadeva[] = "anudattadeva"; +static const char glyph_anusvarabengali[] = "anusvarabengali"; +static const char glyph_anusvaradeva[] = "anusvaradeva"; +static const char glyph_anusvaragujarati[] = "anusvaragujarati"; +static const char glyph_aogonek[] = "aogonek"; +static const char glyph_apaatosquare[] = "apaatosquare"; +static const char glyph_aparen[] = "aparen"; +static const char glyph_apostrophearmenian[] = "apostrophearmenian"; +static const char glyph_apostrophemod[] = "apostrophemod"; +static const char glyph_apple[] = "apple"; +static const char glyph_approaches[] = "approaches"; +static const char glyph_approxequal[] = "approxequal"; +static const char glyph_approxequalorimage[] = "approxequalorimage"; +static const char glyph_approximatelyequal[] = "approximatelyequal"; +static const char glyph_araeaekorean[] = "araeaekorean"; +static const char glyph_araeakorean[] = "araeakorean"; +static const char glyph_arc[] = "arc"; +static const char glyph_arighthalfring[] = "arighthalfring"; +static const char glyph_aring[] = "aring"; +static const char glyph_aringacute[] = "aringacute"; +static const char glyph_aringbelow[] = "aringbelow"; +static const char glyph_arrowboth[] = "arrowboth"; +static const char glyph_arrowdashdown[] = "arrowdashdown"; +static const char glyph_arrowdashleft[] = "arrowdashleft"; +static const char glyph_arrowdashright[] = "arrowdashright"; +static const char glyph_arrowdashup[] = "arrowdashup"; +static const char glyph_arrowdblboth[] = "arrowdblboth"; +static const char glyph_arrowdbldown[] = "arrowdbldown"; +static const char glyph_arrowdblleft[] = "arrowdblleft"; +static const char glyph_arrowdblright[] = "arrowdblright"; +static const char glyph_arrowdblup[] = "arrowdblup"; +static const char glyph_arrowdown[] = "arrowdown"; +static const char glyph_arrowdownleft[] = "arrowdownleft"; +static const char glyph_arrowdownright[] = "arrowdownright"; +static const char glyph_arrowdownwhite[] = "arrowdownwhite"; +static const char glyph_arrowheaddownmod[] = "arrowheaddownmod"; +static const char glyph_arrowheadleftmod[] = "arrowheadleftmod"; +static const char glyph_arrowheadrightmod[] = "arrowheadrightmod"; +static const char glyph_arrowheadupmod[] = "arrowheadupmod"; +static const char glyph_arrowhorizex[] = "arrowhorizex"; +static const char glyph_arrowleft[] = "arrowleft"; +static const char glyph_arrowleftdbl[] = "arrowleftdbl"; +static const char glyph_arrowleftdblstroke[] = "arrowleftdblstroke"; +static const char glyph_arrowleftoverright[] = "arrowleftoverright"; +static const char glyph_arrowleftwhite[] = "arrowleftwhite"; +static const char glyph_arrowright[] = "arrowright"; +static const char glyph_arrowrightdblstroke[] = "arrowrightdblstroke"; +static const char glyph_arrowrightheavy[] = "arrowrightheavy"; +static const char glyph_arrowrightoverleft[] = "arrowrightoverleft"; +static const char glyph_arrowrightwhite[] = "arrowrightwhite"; +static const char glyph_arrowtableft[] = "arrowtableft"; +static const char glyph_arrowtabright[] = "arrowtabright"; +static const char glyph_arrowup[] = "arrowup"; +static const char glyph_arrowupdn[] = "arrowupdn"; +static const char glyph_arrowupdnbse[] = "arrowupdnbse"; +static const char glyph_arrowupdownbase[] = "arrowupdownbase"; +static const char glyph_arrowupleft[] = "arrowupleft"; +static const char glyph_arrowupleftofdown[] = "arrowupleftofdown"; +static const char glyph_arrowupright[] = "arrowupright"; +static const char glyph_arrowupwhite[] = "arrowupwhite"; +static const char glyph_arrowvertex[] = "arrowvertex"; +static const char glyph_asciicircum[] = "asciicircum"; +static const char glyph_asciicircummonospace[] = "asciicircummonospace"; +static const char glyph_asciitilde[] = "asciitilde"; +static const char glyph_asciitildemonospace[] = "asciitildemonospace"; +static const char glyph_ascript[] = "ascript"; +static const char glyph_ascriptturned[] = "ascriptturned"; +static const char glyph_asmallhiragana[] = "asmallhiragana"; +static const char glyph_asmallkatakana[] = "asmallkatakana"; +static const char glyph_asmallkatakanahalfwidth[] = "asmallkatakanahalfwidth"; +static const char glyph_asterisk[] = "asterisk"; +static const char glyph_asteriskaltonearabic[] = "asteriskaltonearabic"; +static const char glyph_asteriskarabic[] = "asteriskarabic"; +static const char glyph_asteriskmath[] = "asteriskmath"; +static const char glyph_asteriskmonospace[] = "asteriskmonospace"; +static const char glyph_asterisksmall[] = "asterisksmall"; +static const char glyph_asterism[] = "asterism"; +static const char glyph_asuperior[] = "asuperior"; +static const char glyph_asymptoticallyequal[] = "asymptoticallyequal"; +static const char glyph_at[] = "at"; +static const char glyph_atilde[] = "atilde"; +static const char glyph_atmonospace[] = "atmonospace"; +static const char glyph_atsmall[] = "atsmall"; +static const char glyph_aturned[] = "aturned"; +static const char glyph_aubengali[] = "aubengali"; +static const char glyph_aubopomofo[] = "aubopomofo"; +static const char glyph_audeva[] = "audeva"; +static const char glyph_augujarati[] = "augujarati"; +static const char glyph_augurmukhi[] = "augurmukhi"; +static const char glyph_aulengthmarkbengali[] = "aulengthmarkbengali"; +static const char glyph_aumatragurmukhi[] = "aumatragurmukhi"; +static const char glyph_auvowelsignbengali[] = "auvowelsignbengali"; +static const char glyph_auvowelsigndeva[] = "auvowelsigndeva"; +static const char glyph_auvowelsigngujarati[] = "auvowelsigngujarati"; +static const char glyph_avagrahadeva[] = "avagrahadeva"; +static const char glyph_aybarmenian[] = "aybarmenian"; +static const char glyph_ayin[] = "ayin"; +static const char glyph_ayinaltonehebrew[] = "ayinaltonehebrew"; +static const char glyph_ayinhebrew[] = "ayinhebrew"; +static const char glyph_b[] = "b"; +static const char glyph_babengali[] = "babengali"; +static const char glyph_backslash[] = "backslash"; +static const char glyph_backslashmonospace[] = "backslashmonospace"; +static const char glyph_badeva[] = "badeva"; +static const char glyph_bagujarati[] = "bagujarati"; +static const char glyph_bagurmukhi[] = "bagurmukhi"; +static const char glyph_bahiragana[] = "bahiragana"; +static const char glyph_bahtthai[] = "bahtthai"; +static const char glyph_bakatakana[] = "bakatakana"; +static const char glyph_bar[] = "bar"; +static const char glyph_barmonospace[] = "barmonospace"; +static const char glyph_bbopomofo[] = "bbopomofo"; +static const char glyph_bcircle[] = "bcircle"; +static const char glyph_bdotaccent[] = "bdotaccent"; +static const char glyph_bdotbelow[] = "bdotbelow"; +static const char glyph_beamedsixteenthnotes[] = "beamedsixteenthnotes"; +static const char glyph_because[] = "because"; +static const char glyph_becyrillic[] = "becyrillic"; +static const char glyph_beharabic[] = "beharabic"; +static const char glyph_behfinalarabic[] = "behfinalarabic"; +static const char glyph_behinitialarabic[] = "behinitialarabic"; +static const char glyph_behiragana[] = "behiragana"; +static const char glyph_behmedialarabic[] = "behmedialarabic"; +static const char glyph_behmeeminitialarabic[] = "behmeeminitialarabic"; +static const char glyph_behmeemisolatedarabic[] = "behmeemisolatedarabic"; +static const char glyph_behnoonfinalarabic[] = "behnoonfinalarabic"; +static const char glyph_bekatakana[] = "bekatakana"; +static const char glyph_benarmenian[] = "benarmenian"; +static const char glyph_bet[] = "bet"; +static const char glyph_beta[] = "beta"; +static const char glyph_betasymbolgreek[] = "betasymbolgreek"; +static const char glyph_betdagesh[] = "betdagesh"; +static const char glyph_betdageshhebrew[] = "betdageshhebrew"; +static const char glyph_bethebrew[] = "bethebrew"; +static const char glyph_betrafehebrew[] = "betrafehebrew"; +static const char glyph_bhabengali[] = "bhabengali"; +static const char glyph_bhadeva[] = "bhadeva"; +static const char glyph_bhagujarati[] = "bhagujarati"; +static const char glyph_bhagurmukhi[] = "bhagurmukhi"; +static const char glyph_bhook[] = "bhook"; +static const char glyph_bihiragana[] = "bihiragana"; +static const char glyph_bikatakana[] = "bikatakana"; +static const char glyph_bilabialclick[] = "bilabialclick"; +static const char glyph_bindigurmukhi[] = "bindigurmukhi"; +static const char glyph_birusquare[] = "birusquare"; +static const char glyph_blackcircle[] = "blackcircle"; +static const char glyph_blackdiamond[] = "blackdiamond"; +static const char glyph_blackdownpointingtriangle[] = +"blackdownpointingtriangle"; +static const char glyph_blackleftpointingpointer[] = +"blackleftpointingpointer"; +static const char glyph_blackleftpointingtriangle[] = +"blackleftpointingtriangle"; +static const char glyph_blacklenticularbracketleft[] = +"blacklenticularbracketleft"; +static const char glyph_blacklenticularbracketleftvertical[] = +"blacklenticularbracketleftvertical"; +static const char glyph_blacklenticularbracketright[] = +"blacklenticularbracketright"; +static const char glyph_blacklenticularbracketrightvertical[] = +"blacklenticularbracketrightvertical"; +static const char glyph_blacklowerlefttriangle[] = +"blacklowerlefttriangle"; +static const char glyph_blacklowerrighttriangle[] = "blacklowerrighttriangle"; +static const char glyph_blackrectangle[] = "blackrectangle"; +static const char glyph_blackrightpointingpointer[] = +"blackrightpointingpointer"; +static const char glyph_blackrightpointingtriangle[] = +"blackrightpointingtriangle"; +static const char glyph_blacksmallsquare[] = "blacksmallsquare"; +static const char glyph_blacksmilingface[] = "blacksmilingface"; +static const char glyph_blacksquare[] = "blacksquare"; +static const char glyph_blackstar[] = "blackstar"; +static const char glyph_blackupperlefttriangle[] = "blackupperlefttriangle"; +static const char glyph_blackupperrighttriangle[] = "blackupperrighttriangle"; +static const char glyph_blackuppointingsmalltriangle[] = +"blackuppointingsmalltriangle"; +static const char glyph_blackuppointingtriangle[] = "blackuppointingtriangle"; +static const char glyph_blank[] = "blank"; +static const char glyph_blinebelow[] = "blinebelow"; +static const char glyph_block[] = "block"; +static const char glyph_bmonospace[] = "bmonospace"; +static const char glyph_bobaimaithai[] = "bobaimaithai"; +static const char glyph_bohiragana[] = "bohiragana"; +static const char glyph_bokatakana[] = "bokatakana"; +static const char glyph_bparen[] = "bparen"; +static const char glyph_bqsquare[] = "bqsquare"; +static const char glyph_braceex[] = "braceex"; +static const char glyph_braceleft[] = "braceleft"; +static const char glyph_braceleftbt[] = "braceleftbt"; +static const char glyph_braceleftmid[] = "braceleftmid"; +static const char glyph_braceleftmonospace[] = "braceleftmonospace"; +static const char glyph_braceleftsmall[] = "braceleftsmall"; +static const char glyph_bracelefttp[] = "bracelefttp"; +static const char glyph_braceleftvertical[] = "braceleftvertical"; +static const char glyph_braceright[] = "braceright"; +static const char glyph_bracerightbt[] = "bracerightbt"; +static const char glyph_bracerightmid[] = "bracerightmid"; +static const char glyph_bracerightmonospace[] = "bracerightmonospace"; +static const char glyph_bracerightsmall[] = "bracerightsmall"; +static const char glyph_bracerighttp[] = "bracerighttp"; +static const char glyph_bracerightvertical[] = "bracerightvertical"; +static const char glyph_bracketleft[] = "bracketleft"; +static const char glyph_bracketleftbt[] = "bracketleftbt"; +static const char glyph_bracketleftex[] = "bracketleftex"; +static const char glyph_bracketleftmonospace[] = "bracketleftmonospace"; +static const char glyph_bracketlefttp[] = "bracketlefttp"; +static const char glyph_bracketright[] = "bracketright"; +static const char glyph_bracketrightbt[] = "bracketrightbt"; +static const char glyph_bracketrightex[] = "bracketrightex"; +static const char glyph_bracketrightmonospace[] = "bracketrightmonospace"; +static const char glyph_bracketrighttp[] = "bracketrighttp"; +static const char glyph_breve[] = "breve"; +static const char glyph_brevebelowcmb[] = "brevebelowcmb"; +static const char glyph_brevecmb[] = "brevecmb"; +static const char glyph_breveinvertedbelowcmb[] = "breveinvertedbelowcmb"; +static const char glyph_breveinvertedcmb[] = "breveinvertedcmb"; +static const char glyph_breveinverteddoublecmb[] = "breveinverteddoublecmb"; +static const char glyph_bridgebelowcmb[] = "bridgebelowcmb"; +static const char glyph_bridgeinvertedbelowcmb[] = "bridgeinvertedbelowcmb"; +static const char glyph_brokenbar[] = "brokenbar"; +static const char glyph_bstroke[] = "bstroke"; +static const char glyph_bsuperior[] = "bsuperior"; +static const char glyph_btopbar[] = "btopbar"; +static const char glyph_buhiragana[] = "buhiragana"; +static const char glyph_bukatakana[] = "bukatakana"; +static const char glyph_bullet[] = "bullet"; +static const char glyph_bulletinverse[] = "bulletinverse"; +static const char glyph_bulletoperator[] = "bulletoperator"; +static const char glyph_bullseye[] = "bullseye"; +static const char glyph_c[] = "c"; +static const char glyph_caarmenian[] = "caarmenian"; +static const char glyph_cabengali[] = "cabengali"; +static const char glyph_cacute[] = "cacute"; +static const char glyph_cadeva[] = "cadeva"; +static const char glyph_cagujarati[] = "cagujarati"; +static const char glyph_cagurmukhi[] = "cagurmukhi"; +static const char glyph_calsquare[] = "calsquare"; +static const char glyph_candrabindubengali[] = "candrabindubengali"; +static const char glyph_candrabinducmb[] = "candrabinducmb"; +static const char glyph_candrabindudeva[] = "candrabindudeva"; +static const char glyph_candrabindugujarati[] = "candrabindugujarati"; +static const char glyph_capslock[] = "capslock"; +static const char glyph_careof[] = "careof"; +static const char glyph_caron[] = "caron"; +static const char glyph_caronbelowcmb[] = "caronbelowcmb"; +static const char glyph_caroncmb[] = "caroncmb"; +static const char glyph_carriagereturn[] = "carriagereturn"; +static const char glyph_cbopomofo[] = "cbopomofo"; +static const char glyph_ccaron[] = "ccaron"; +static const char glyph_ccedilla[] = "ccedilla"; +static const char glyph_ccedillaacute[] = "ccedillaacute"; +static const char glyph_ccircle[] = "ccircle"; +static const char glyph_ccircumflex[] = "ccircumflex"; +static const char glyph_ccurl[] = "ccurl"; +static const char glyph_cdot[] = "cdot"; +static const char glyph_cdotaccent[] = "cdotaccent"; +static const char glyph_cdsquare[] = "cdsquare"; +static const char glyph_cedilla[] = "cedilla"; +static const char glyph_cedillacmb[] = "cedillacmb"; +static const char glyph_cent[] = "cent"; +static const char glyph_centigrade[] = "centigrade"; +static const char glyph_centinferior[] = "centinferior"; +static const char glyph_centmonospace[] = "centmonospace"; +static const char glyph_centoldstyle[] = "centoldstyle"; +static const char glyph_centsuperior[] = "centsuperior"; +static const char glyph_chaarmenian[] = "chaarmenian"; +static const char glyph_chabengali[] = "chabengali"; +static const char glyph_chadeva[] = "chadeva"; +static const char glyph_chagujarati[] = "chagujarati"; +static const char glyph_chagurmukhi[] = "chagurmukhi"; +static const char glyph_chbopomofo[] = "chbopomofo"; +static const char glyph_cheabkhasiancyrillic[] = "cheabkhasiancyrillic"; +static const char glyph_checkmark[] = "checkmark"; +static const char glyph_checyrillic[] = "checyrillic"; +static const char glyph_chedescenderabkhasiancyrillic[] = +"chedescenderabkhasiancyrillic"; +static const char glyph_chedescendercyrillic[] = "chedescendercyrillic"; +static const char glyph_chedieresiscyrillic[] = "chedieresiscyrillic"; +static const char glyph_cheharmenian[] = "cheharmenian"; +static const char glyph_chekhakassiancyrillic[] = "chekhakassiancyrillic"; +static const char glyph_cheverticalstrokecyrillic[] = +"cheverticalstrokecyrillic"; +static const char glyph_chi[] = "chi"; +static const char glyph_chieuchacirclekorean[] = "chieuchacirclekorean"; +static const char glyph_chieuchaparenkorean[] = "chieuchaparenkorean"; +static const char glyph_chieuchcirclekorean[] = "chieuchcirclekorean"; +static const char glyph_chieuchkorean[] = "chieuchkorean"; +static const char glyph_chieuchparenkorean[] = "chieuchparenkorean"; +static const char glyph_chochangthai[] = "chochangthai"; +static const char glyph_chochanthai[] = "chochanthai"; +static const char glyph_chochingthai[] = "chochingthai"; +static const char glyph_chochoethai[] = "chochoethai"; +static const char glyph_chook[] = "chook"; +static const char glyph_cieucacirclekorean[] = "cieucacirclekorean"; +static const char glyph_cieucaparenkorean[] = "cieucaparenkorean"; +static const char glyph_cieuccirclekorean[] = "cieuccirclekorean"; +static const char glyph_cieuckorean[] = "cieuckorean"; +static const char glyph_cieucparenkorean[] = "cieucparenkorean"; +static const char glyph_cieucuparenkorean[] = "cieucuparenkorean"; +static const char glyph_circle[] = "circle"; +static const char glyph_circlemultiply[] = "circlemultiply"; +static const char glyph_circleot[] = "circleot"; +static const char glyph_circleplus[] = "circleplus"; +static const char glyph_circlepostalmark[] = "circlepostalmark"; +static const char glyph_circlewithlefthalfblack[] = "circlewithlefthalfblack"; +static const char glyph_circlewithrighthalfblack[] = +"circlewithrighthalfblack"; +static const char glyph_circumflex[] = "circumflex"; +static const char glyph_circumflexbelowcmb[] = "circumflexbelowcmb"; +static const char glyph_circumflexcmb[] = "circumflexcmb"; +static const char glyph_clear[] = "clear"; +static const char glyph_clickalveolar[] = "clickalveolar"; +static const char glyph_clickdental[] = "clickdental"; +static const char glyph_clicklateral[] = "clicklateral"; +static const char glyph_clickretroflex[] = "clickretroflex"; +static const char glyph_club[] = "club"; +static const char glyph_clubsuitblack[] = "clubsuitblack"; +static const char glyph_clubsuitwhite[] = "clubsuitwhite"; +static const char glyph_cmcubedsquare[] = "cmcubedsquare"; +static const char glyph_cmonospace[] = "cmonospace"; +static const char glyph_cmsquaredsquare[] = "cmsquaredsquare"; +static const char glyph_coarmenian[] = "coarmenian"; +static const char glyph_colon[] = "colon"; +static const char glyph_colonmonetary[] = "colonmonetary"; +static const char glyph_colonmonospace[] = "colonmonospace"; +static const char glyph_colonsign[] = "colonsign"; +static const char glyph_colonsmall[] = "colonsmall"; +static const char glyph_colontriangularhalfmod[] = "colontriangularhalfmod"; +static const char glyph_colontriangularmod[] = "colontriangularmod"; +static const char glyph_comma[] = "comma"; +static const char glyph_commaabovecmb[] = "commaabovecmb"; +static const char glyph_commaaboverightcmb[] = "commaaboverightcmb"; +static const char glyph_commaaccent[] = "commaaccent"; +static const char glyph_commaarabic[] = "commaarabic"; +static const char glyph_commaarmenian[] = "commaarmenian"; +static const char glyph_commainferior[] = "commainferior"; +static const char glyph_commamonospace[] = "commamonospace"; +static const char glyph_commareversedabovecmb[] = "commareversedabovecmb"; +static const char glyph_commareversedmod[] = "commareversedmod"; +static const char glyph_commasmall[] = "commasmall"; +static const char glyph_commasuperior[] = "commasuperior"; +static const char glyph_commaturnedabovecmb[] = "commaturnedabovecmb"; +static const char glyph_commaturnedmod[] = "commaturnedmod"; +static const char glyph_compass[] = "compass"; +static const char glyph_congruent[] = "congruent"; +static const char glyph_contourintegral[] = "contourintegral"; +static const char glyph_control[] = "control"; +static const char glyph_controlACK[] = "controlACK"; +static const char glyph_controlBEL[] = "controlBEL"; +static const char glyph_controlBS[] = "controlBS"; +static const char glyph_controlCAN[] = "controlCAN"; +static const char glyph_controlCR[] = "controlCR"; +static const char glyph_controlDC1[] = "controlDC1"; +static const char glyph_controlDC2[] = "controlDC2"; +static const char glyph_controlDC3[] = "controlDC3"; +static const char glyph_controlDC4[] = "controlDC4"; +static const char glyph_controlDEL[] = "controlDEL"; +static const char glyph_controlDLE[] = "controlDLE"; +static const char glyph_controlEM[] = "controlEM"; +static const char glyph_controlENQ[] = "controlENQ"; +static const char glyph_controlEOT[] = "controlEOT"; +static const char glyph_controlESC[] = "controlESC"; +static const char glyph_controlETB[] = "controlETB"; +static const char glyph_controlETX[] = "controlETX"; +static const char glyph_controlFF[] = "controlFF"; +static const char glyph_controlFS[] = "controlFS"; +static const char glyph_controlGS[] = "controlGS"; +static const char glyph_controlHT[] = "controlHT"; +static const char glyph_controlLF[] = "controlLF"; +static const char glyph_controlNAK[] = "controlNAK"; +static const char glyph_controlRS[] = "controlRS"; +static const char glyph_controlSI[] = "controlSI"; +static const char glyph_controlSO[] = "controlSO"; +static const char glyph_controlSOT[] = "controlSOT"; +static const char glyph_controlSTX[] = "controlSTX"; +static const char glyph_controlSUB[] = "controlSUB"; +static const char glyph_controlSYN[] = "controlSYN"; +static const char glyph_controlUS[] = "controlUS"; +static const char glyph_controlVT[] = "controlVT"; +static const char glyph_copyright[] = "copyright"; +static const char glyph_copyrightsans[] = "copyrightsans"; +static const char glyph_copyrightserif[] = "copyrightserif"; +static const char glyph_cornerbracketleft[] = "cornerbracketleft"; +static const char glyph_cornerbracketlefthalfwidth[] = +"cornerbracketlefthalfwidth"; +static const char glyph_cornerbracketleftvertical[] = +"cornerbracketleftvertical"; +static const char glyph_cornerbracketright[] = "cornerbracketright"; +static const char glyph_cornerbracketrighthalfwidth[] = +"cornerbracketrighthalfwidth"; +static const char glyph_cornerbracketrightvertical[] = +"cornerbracketrightvertical"; +static const char glyph_corporationsquare[] = "corporationsquare"; +static const char glyph_cosquare[] = "cosquare"; +static const char glyph_coverkgsquare[] = "coverkgsquare"; +static const char glyph_cparen[] = "cparen"; +static const char glyph_cruzeiro[] = "cruzeiro"; +static const char glyph_cstretched[] = "cstretched"; +static const char glyph_curlyand[] = "curlyand"; +static const char glyph_curlyor[] = "curlyor"; +static const char glyph_currency[] = "currency"; +static const char glyph_cyrBreve[] = "cyrBreve"; +static const char glyph_cyrFlex[] = "cyrFlex"; +static const char glyph_cyrbreve[] = "cyrbreve"; +static const char glyph_cyrflex[] = "cyrflex"; +static const char glyph_d[] = "d"; +static const char glyph_daarmenian[] = "daarmenian"; +static const char glyph_dabengali[] = "dabengali"; +static const char glyph_dadarabic[] = "dadarabic"; +static const char glyph_dadeva[] = "dadeva"; +static const char glyph_dadfinalarabic[] = "dadfinalarabic"; +static const char glyph_dadinitialarabic[] = "dadinitialarabic"; +static const char glyph_dadmedialarabic[] = "dadmedialarabic"; +static const char glyph_dagesh[] = "dagesh"; +static const char glyph_dageshhebrew[] = "dageshhebrew"; +static const char glyph_dagger[] = "dagger"; +static const char glyph_daggerdbl[] = "daggerdbl"; +static const char glyph_dagujarati[] = "dagujarati"; +static const char glyph_dagurmukhi[] = "dagurmukhi"; +static const char glyph_dahiragana[] = "dahiragana"; +static const char glyph_dakatakana[] = "dakatakana"; +static const char glyph_dalarabic[] = "dalarabic"; +static const char glyph_dalet[] = "dalet"; +static const char glyph_daletdagesh[] = "daletdagesh"; +static const char glyph_daletdageshhebrew[] = "daletdageshhebrew"; +static const char glyph_dalethatafpatah[] = "dalethatafpatah"; +static const char glyph_dalethatafpatahhebrew[] = "dalethatafpatahhebrew"; +static const char glyph_dalethatafsegol[] = "dalethatafsegol"; +static const char glyph_dalethatafsegolhebrew[] = "dalethatafsegolhebrew"; +static const char glyph_dalethebrew[] = "dalethebrew"; +static const char glyph_dalethiriq[] = "dalethiriq"; +static const char glyph_dalethiriqhebrew[] = "dalethiriqhebrew"; +static const char glyph_daletholam[] = "daletholam"; +static const char glyph_daletholamhebrew[] = "daletholamhebrew"; +static const char glyph_daletpatah[] = "daletpatah"; +static const char glyph_daletpatahhebrew[] = "daletpatahhebrew"; +static const char glyph_daletqamats[] = "daletqamats"; +static const char glyph_daletqamatshebrew[] = "daletqamatshebrew"; +static const char glyph_daletqubuts[] = "daletqubuts"; +static const char glyph_daletqubutshebrew[] = "daletqubutshebrew"; +static const char glyph_daletsegol[] = "daletsegol"; +static const char glyph_daletsegolhebrew[] = "daletsegolhebrew"; +static const char glyph_daletsheva[] = "daletsheva"; +static const char glyph_daletshevahebrew[] = "daletshevahebrew"; +static const char glyph_dalettsere[] = "dalettsere"; +static const char glyph_dalettserehebrew[] = "dalettserehebrew"; +static const char glyph_dalfinalarabic[] = "dalfinalarabic"; +static const char glyph_dammaarabic[] = "dammaarabic"; +static const char glyph_dammalowarabic[] = "dammalowarabic"; +static const char glyph_dammatanaltonearabic[] = "dammatanaltonearabic"; +static const char glyph_dammatanarabic[] = "dammatanarabic"; +static const char glyph_danda[] = "danda"; +static const char glyph_dargahebrew[] = "dargahebrew"; +static const char glyph_dargalefthebrew[] = "dargalefthebrew"; +static const char glyph_dasiapneumatacyrilliccmb[] = +"dasiapneumatacyrilliccmb"; +static const char glyph_dblGrave[] = "dblGrave"; +static const char glyph_dblanglebracketleft[] = "dblanglebracketleft"; +static const char glyph_dblanglebracketleftvertical[] = +"dblanglebracketleftvertical"; +static const char glyph_dblanglebracketright[] = "dblanglebracketright"; +static const char glyph_dblanglebracketrightvertical[] = +"dblanglebracketrightvertical"; +static const char glyph_dblarchinvertedbelowcmb[] = "dblarchinvertedbelowcmb"; +static const char glyph_dblarrowleft[] = "dblarrowleft"; +static const char glyph_dblarrowright[] = "dblarrowright"; +static const char glyph_dbldanda[] = "dbldanda"; +static const char glyph_dblgrave[] = "dblgrave"; +static const char glyph_dblgravecmb[] = "dblgravecmb"; +static const char glyph_dblintegral[] = "dblintegral"; +static const char glyph_dbllowline[] = "dbllowline"; +static const char glyph_dbllowlinecmb[] = "dbllowlinecmb"; +static const char glyph_dbloverlinecmb[] = "dbloverlinecmb"; +static const char glyph_dblprimemod[] = "dblprimemod"; +static const char glyph_dblverticalbar[] = "dblverticalbar"; +static const char glyph_dblverticallineabovecmb[] = "dblverticallineabovecmb"; +static const char glyph_dbopomofo[] = "dbopomofo"; +static const char glyph_dbsquare[] = "dbsquare"; +static const char glyph_dcaron[] = "dcaron"; +static const char glyph_dcedilla[] = "dcedilla"; +static const char glyph_dcircle[] = "dcircle"; +static const char glyph_dcircumflexbelow[] = "dcircumflexbelow"; +static const char glyph_dcroat[] = "dcroat"; +static const char glyph_ddabengali[] = "ddabengali"; +static const char glyph_ddadeva[] = "ddadeva"; +static const char glyph_ddagujarati[] = "ddagujarati"; +static const char glyph_ddagurmukhi[] = "ddagurmukhi"; +static const char glyph_ddalarabic[] = "ddalarabic"; +static const char glyph_ddalfinalarabic[] = "ddalfinalarabic"; +static const char glyph_dddhadeva[] = "dddhadeva"; +static const char glyph_ddhabengali[] = "ddhabengali"; +static const char glyph_ddhadeva[] = "ddhadeva"; +static const char glyph_ddhagujarati[] = "ddhagujarati"; +static const char glyph_ddhagurmukhi[] = "ddhagurmukhi"; +static const char glyph_ddotaccent[] = "ddotaccent"; +static const char glyph_ddotbelow[] = "ddotbelow"; +static const char glyph_decimalseparatorarabic[] = "decimalseparatorarabic"; +static const char glyph_decimalseparatorpersian[] = "decimalseparatorpersian"; +static const char glyph_decyrillic[] = "decyrillic"; +static const char glyph_degree[] = "degree"; +static const char glyph_dehihebrew[] = "dehihebrew"; +static const char glyph_dehiragana[] = "dehiragana"; +static const char glyph_deicoptic[] = "deicoptic"; +static const char glyph_dekatakana[] = "dekatakana"; +static const char glyph_deleteleft[] = "deleteleft"; +static const char glyph_deleteright[] = "deleteright"; +static const char glyph_delta[] = "delta"; +static const char glyph_deltaturned[] = "deltaturned"; +static const char glyph_denominatorminusonenumeratorbengali[] = +"denominatorminusonenumeratorbengali"; +static const char glyph_dezh[] = "dezh"; +static const char glyph_dhabengali[] = "dhabengali"; +static const char glyph_dhadeva[] = "dhadeva"; +static const char glyph_dhagujarati[] = "dhagujarati"; +static const char glyph_dhagurmukhi[] = "dhagurmukhi"; +static const char glyph_dhook[] = "dhook"; +static const char glyph_dialytikatonos[] = "dialytikatonos"; +static const char glyph_dialytikatonoscmb[] = "dialytikatonoscmb"; +static const char glyph_diamond[] = "diamond"; +static const char glyph_diamondsuitwhite[] = "diamondsuitwhite"; +static const char glyph_dieresis[] = "dieresis"; +static const char glyph_dieresisacute[] = "dieresisacute"; +static const char glyph_dieresisbelowcmb[] = "dieresisbelowcmb"; +static const char glyph_dieresiscmb[] = "dieresiscmb"; +static const char glyph_dieresisgrave[] = "dieresisgrave"; +static const char glyph_dieresistonos[] = "dieresistonos"; +static const char glyph_dihiragana[] = "dihiragana"; +static const char glyph_dikatakana[] = "dikatakana"; +static const char glyph_dittomark[] = "dittomark"; +static const char glyph_divide[] = "divide"; +static const char glyph_divides[] = "divides"; +static const char glyph_divisionslash[] = "divisionslash"; +static const char glyph_djecyrillic[] = "djecyrillic"; +static const char glyph_dkshade[] = "dkshade"; +static const char glyph_dlinebelow[] = "dlinebelow"; +static const char glyph_dlsquare[] = "dlsquare"; +static const char glyph_dmacron[] = "dmacron"; +static const char glyph_dmonospace[] = "dmonospace"; +static const char glyph_dnblock[] = "dnblock"; +static const char glyph_dochadathai[] = "dochadathai"; +static const char glyph_dodekthai[] = "dodekthai"; +static const char glyph_dohiragana[] = "dohiragana"; +static const char glyph_dokatakana[] = "dokatakana"; +static const char glyph_dollar[] = "dollar"; +static const char glyph_dollarinferior[] = "dollarinferior"; +static const char glyph_dollarmonospace[] = "dollarmonospace"; +static const char glyph_dollaroldstyle[] = "dollaroldstyle"; +static const char glyph_dollarsmall[] = "dollarsmall"; +static const char glyph_dollarsuperior[] = "dollarsuperior"; +static const char glyph_dong[] = "dong"; +static const char glyph_dorusquare[] = "dorusquare"; +static const char glyph_dotaccent[] = "dotaccent"; +static const char glyph_dotaccentcmb[] = "dotaccentcmb"; +static const char glyph_dotbelowcmb[] = "dotbelowcmb"; +static const char glyph_dotbelowcomb[] = "dotbelowcomb"; +static const char glyph_dotkatakana[] = "dotkatakana"; +static const char glyph_dotlessi[] = "dotlessi"; +static const char glyph_dotlessj[] = "dotlessj"; +static const char glyph_dotlessjstrokehook[] = "dotlessjstrokehook"; +static const char glyph_dotmath[] = "dotmath"; +static const char glyph_dottedcircle[] = "dottedcircle"; +static const char glyph_doubleyodpatah[] = "doubleyodpatah"; +static const char glyph_doubleyodpatahhebrew[] = "doubleyodpatahhebrew"; +static const char glyph_downtackbelowcmb[] = "downtackbelowcmb"; +static const char glyph_downtackmod[] = "downtackmod"; +static const char glyph_dparen[] = "dparen"; +static const char glyph_dsuperior[] = "dsuperior"; +static const char glyph_dtail[] = "dtail"; +static const char glyph_dtopbar[] = "dtopbar"; +static const char glyph_duhiragana[] = "duhiragana"; +static const char glyph_dukatakana[] = "dukatakana"; +static const char glyph_dz[] = "dz"; +static const char glyph_dzaltone[] = "dzaltone"; +static const char glyph_dzcaron[] = "dzcaron"; +static const char glyph_dzcurl[] = "dzcurl"; +static const char glyph_dzeabkhasiancyrillic[] = "dzeabkhasiancyrillic"; +static const char glyph_dzecyrillic[] = "dzecyrillic"; +static const char glyph_dzhecyrillic[] = "dzhecyrillic"; +static const char glyph_e[] = "e"; +static const char glyph_eacute[] = "eacute"; +static const char glyph_earth[] = "earth"; +static const char glyph_ebengali[] = "ebengali"; +static const char glyph_ebopomofo[] = "ebopomofo"; +static const char glyph_ebreve[] = "ebreve"; +static const char glyph_ecandradeva[] = "ecandradeva"; +static const char glyph_ecandragujarati[] = "ecandragujarati"; +static const char glyph_ecandravowelsigndeva[] = "ecandravowelsigndeva"; +static const char glyph_ecandravowelsigngujarati[] = +"ecandravowelsigngujarati"; +static const char glyph_ecaron[] = "ecaron"; +static const char glyph_ecedillabreve[] = "ecedillabreve"; +static const char glyph_echarmenian[] = "echarmenian"; +static const char glyph_echyiwnarmenian[] = "echyiwnarmenian"; +static const char glyph_ecircle[] = "ecircle"; +static const char glyph_ecircumflex[] = "ecircumflex"; +static const char glyph_ecircumflexacute[] = "ecircumflexacute"; +static const char glyph_ecircumflexbelow[] = "ecircumflexbelow"; +static const char glyph_ecircumflexdotbelow[] = "ecircumflexdotbelow"; +static const char glyph_ecircumflexgrave[] = "ecircumflexgrave"; +static const char glyph_ecircumflexhookabove[] = "ecircumflexhookabove"; +static const char glyph_ecircumflextilde[] = "ecircumflextilde"; +static const char glyph_ecyrillic[] = "ecyrillic"; +static const char glyph_edblgrave[] = "edblgrave"; +static const char glyph_edeva[] = "edeva"; +static const char glyph_edieresis[] = "edieresis"; +static const char glyph_edot[] = "edot"; +static const char glyph_edotaccent[] = "edotaccent"; +static const char glyph_edotbelow[] = "edotbelow"; +static const char glyph_eegurmukhi[] = "eegurmukhi"; +static const char glyph_eematragurmukhi[] = "eematragurmukhi"; +static const char glyph_efcyrillic[] = "efcyrillic"; +static const char glyph_egrave[] = "egrave"; +static const char glyph_egujarati[] = "egujarati"; +static const char glyph_eharmenian[] = "eharmenian"; +static const char glyph_ehbopomofo[] = "ehbopomofo"; +static const char glyph_ehiragana[] = "ehiragana"; +static const char glyph_ehookabove[] = "ehookabove"; +static const char glyph_eibopomofo[] = "eibopomofo"; +static const char glyph_eight[] = "eight"; +static const char glyph_eightarabic[] = "eightarabic"; +static const char glyph_eightbengali[] = "eightbengali"; +static const char glyph_eightcircle[] = "eightcircle"; +static const char glyph_eightcircleinversesansserif[] = +"eightcircleinversesansserif"; +static const char glyph_eightdeva[] = "eightdeva"; +static const char glyph_eighteencircle[] = "eighteencircle"; +static const char glyph_eighteenparen[] = "eighteenparen"; +static const char glyph_eighteenperiod[] = "eighteenperiod"; +static const char glyph_eightgujarati[] = "eightgujarati"; +static const char glyph_eightgurmukhi[] = "eightgurmukhi"; +static const char glyph_eighthackarabic[] = "eighthackarabic"; +static const char glyph_eighthangzhou[] = "eighthangzhou"; +static const char glyph_eighthnotebeamed[] = "eighthnotebeamed"; +static const char glyph_eightideographicparen[] = "eightideographicparen"; +static const char glyph_eightinferior[] = "eightinferior"; +static const char glyph_eightmonospace[] = "eightmonospace"; +static const char glyph_eightoldstyle[] = "eightoldstyle"; +static const char glyph_eightparen[] = "eightparen"; +static const char glyph_eightperiod[] = "eightperiod"; +static const char glyph_eightpersian[] = "eightpersian"; +static const char glyph_eightroman[] = "eightroman"; +static const char glyph_eightsuperior[] = "eightsuperior"; +static const char glyph_eightthai[] = "eightthai"; +static const char glyph_einvertedbreve[] = "einvertedbreve"; +static const char glyph_eiotifiedcyrillic[] = "eiotifiedcyrillic"; +static const char glyph_ekatakana[] = "ekatakana"; +static const char glyph_ekatakanahalfwidth[] = "ekatakanahalfwidth"; +static const char glyph_ekonkargurmukhi[] = "ekonkargurmukhi"; +static const char glyph_ekorean[] = "ekorean"; +static const char glyph_elcyrillic[] = "elcyrillic"; +static const char glyph_element[] = "element"; +static const char glyph_elevencircle[] = "elevencircle"; +static const char glyph_elevenparen[] = "elevenparen"; +static const char glyph_elevenperiod[] = "elevenperiod"; +static const char glyph_elevenroman[] = "elevenroman"; +static const char glyph_ellipsis[] = "ellipsis"; +static const char glyph_ellipsisvertical[] = "ellipsisvertical"; +static const char glyph_emacron[] = "emacron"; +static const char glyph_emacronacute[] = "emacronacute"; +static const char glyph_emacrongrave[] = "emacrongrave"; +static const char glyph_emcyrillic[] = "emcyrillic"; +static const char glyph_emdash[] = "emdash"; +static const char glyph_emdashvertical[] = "emdashvertical"; +static const char glyph_emonospace[] = "emonospace"; +static const char glyph_emphasismarkarmenian[] = "emphasismarkarmenian"; +static const char glyph_emptyset[] = "emptyset"; +static const char glyph_enbopomofo[] = "enbopomofo"; +static const char glyph_encyrillic[] = "encyrillic"; +static const char glyph_endash[] = "endash"; +static const char glyph_endashvertical[] = "endashvertical"; +static const char glyph_endescendercyrillic[] = "endescendercyrillic"; +static const char glyph_eng[] = "eng"; +static const char glyph_engbopomofo[] = "engbopomofo"; +static const char glyph_enghecyrillic[] = "enghecyrillic"; +static const char glyph_enhookcyrillic[] = "enhookcyrillic"; +static const char glyph_enspace[] = "enspace"; +static const char glyph_eogonek[] = "eogonek"; +static const char glyph_eokorean[] = "eokorean"; +static const char glyph_eopen[] = "eopen"; +static const char glyph_eopenclosed[] = "eopenclosed"; +static const char glyph_eopenreversed[] = "eopenreversed"; +static const char glyph_eopenreversedclosed[] = "eopenreversedclosed"; +static const char glyph_eopenreversedhook[] = "eopenreversedhook"; +static const char glyph_eparen[] = "eparen"; +static const char glyph_epsilon[] = "epsilon"; +static const char glyph_epsilontonos[] = "epsilontonos"; +static const char glyph_equal[] = "equal"; +static const char glyph_equalmonospace[] = "equalmonospace"; +static const char glyph_equalsmall[] = "equalsmall"; +static const char glyph_equalsuperior[] = "equalsuperior"; +static const char glyph_equivalence[] = "equivalence"; +static const char glyph_erbopomofo[] = "erbopomofo"; +static const char glyph_ercyrillic[] = "ercyrillic"; +static const char glyph_ereversed[] = "ereversed"; +static const char glyph_ereversedcyrillic[] = "ereversedcyrillic"; +static const char glyph_escyrillic[] = "escyrillic"; +static const char glyph_esdescendercyrillic[] = "esdescendercyrillic"; +static const char glyph_esh[] = "esh"; +static const char glyph_eshcurl[] = "eshcurl"; +static const char glyph_eshortdeva[] = "eshortdeva"; +static const char glyph_eshortvowelsigndeva[] = "eshortvowelsigndeva"; +static const char glyph_eshreversedloop[] = "eshreversedloop"; +static const char glyph_eshsquatreversed[] = "eshsquatreversed"; +static const char glyph_esmallhiragana[] = "esmallhiragana"; +static const char glyph_esmallkatakana[] = "esmallkatakana"; +static const char glyph_esmallkatakanahalfwidth[] = "esmallkatakanahalfwidth"; +static const char glyph_estimated[] = "estimated"; +static const char glyph_esuperior[] = "esuperior"; +static const char glyph_eta[] = "eta"; +static const char glyph_etarmenian[] = "etarmenian"; +static const char glyph_etatonos[] = "etatonos"; +static const char glyph_eth[] = "eth"; +static const char glyph_etilde[] = "etilde"; +static const char glyph_etildebelow[] = "etildebelow"; +static const char glyph_etnahtafoukhhebrew[] = "etnahtafoukhhebrew"; +static const char glyph_etnahtafoukhlefthebrew[] = "etnahtafoukhlefthebrew"; +static const char glyph_etnahtahebrew[] = "etnahtahebrew"; +static const char glyph_etnahtalefthebrew[] = "etnahtalefthebrew"; +static const char glyph_eturned[] = "eturned"; +static const char glyph_eukorean[] = "eukorean"; +static const char glyph_euro[] = "euro"; +static const char glyph_evowelsignbengali[] = "evowelsignbengali"; +static const char glyph_evowelsigndeva[] = "evowelsigndeva"; +static const char glyph_evowelsigngujarati[] = "evowelsigngujarati"; +static const char glyph_exclam[] = "exclam"; +static const char glyph_exclamarmenian[] = "exclamarmenian"; +static const char glyph_exclamdbl[] = "exclamdbl"; +static const char glyph_exclamdown[] = "exclamdown"; +static const char glyph_exclamdownsmall[] = "exclamdownsmall"; +static const char glyph_exclammonospace[] = "exclammonospace"; +static const char glyph_exclamsmall[] = "exclamsmall"; +static const char glyph_existential[] = "existential"; +static const char glyph_ezh[] = "ezh"; +static const char glyph_ezhcaron[] = "ezhcaron"; +static const char glyph_ezhcurl[] = "ezhcurl"; +static const char glyph_ezhreversed[] = "ezhreversed"; +static const char glyph_ezhtail[] = "ezhtail"; +static const char glyph_f[] = "f"; +static const char glyph_fadeva[] = "fadeva"; +static const char glyph_fagurmukhi[] = "fagurmukhi"; +static const char glyph_fahrenheit[] = "fahrenheit"; +static const char glyph_fathaarabic[] = "fathaarabic"; +static const char glyph_fathalowarabic[] = "fathalowarabic"; +static const char glyph_fathatanarabic[] = "fathatanarabic"; +static const char glyph_fbopomofo[] = "fbopomofo"; +static const char glyph_fcircle[] = "fcircle"; +static const char glyph_fdotaccent[] = "fdotaccent"; +static const char glyph_feharabic[] = "feharabic"; +static const char glyph_feharmenian[] = "feharmenian"; +static const char glyph_fehfinalarabic[] = "fehfinalarabic"; +static const char glyph_fehinitialarabic[] = "fehinitialarabic"; +static const char glyph_fehmedialarabic[] = "fehmedialarabic"; +static const char glyph_feicoptic[] = "feicoptic"; +static const char glyph_female[] = "female"; +static const char glyph_ff[] = "ff"; +static const char glyph_ffi[] = "ffi"; +static const char glyph_ffl[] = "ffl"; +static const char glyph_fi[] = "fi"; +static const char glyph_fifteencircle[] = "fifteencircle"; +static const char glyph_fifteenparen[] = "fifteenparen"; +static const char glyph_fifteenperiod[] = "fifteenperiod"; +static const char glyph_figuredash[] = "figuredash"; +static const char glyph_filledbox[] = "filledbox"; +static const char glyph_filledrect[] = "filledrect"; +static const char glyph_finalkaf[] = "finalkaf"; +static const char glyph_finalkafdagesh[] = "finalkafdagesh"; +static const char glyph_finalkafdageshhebrew[] = "finalkafdageshhebrew"; +static const char glyph_finalkafhebrew[] = "finalkafhebrew"; +static const char glyph_finalkafqamats[] = "finalkafqamats"; +static const char glyph_finalkafqamatshebrew[] = "finalkafqamatshebrew"; +static const char glyph_finalkafsheva[] = "finalkafsheva"; +static const char glyph_finalkafshevahebrew[] = "finalkafshevahebrew"; +static const char glyph_finalmem[] = "finalmem"; +static const char glyph_finalmemhebrew[] = "finalmemhebrew"; +static const char glyph_finalnun[] = "finalnun"; +static const char glyph_finalnunhebrew[] = "finalnunhebrew"; +static const char glyph_finalpe[] = "finalpe"; +static const char glyph_finalpehebrew[] = "finalpehebrew"; +static const char glyph_finaltsadi[] = "finaltsadi"; +static const char glyph_finaltsadihebrew[] = "finaltsadihebrew"; +static const char glyph_firsttonechinese[] = "firsttonechinese"; +static const char glyph_fisheye[] = "fisheye"; +static const char glyph_fitacyrillic[] = "fitacyrillic"; +static const char glyph_five[] = "five"; +static const char glyph_fivearabic[] = "fivearabic"; +static const char glyph_fivebengali[] = "fivebengali"; +static const char glyph_fivecircle[] = "fivecircle"; +static const char glyph_fivecircleinversesansserif[] = +"fivecircleinversesansserif"; +static const char glyph_fivedeva[] = "fivedeva"; +static const char glyph_fiveeighths[] = "fiveeighths"; +static const char glyph_fivegujarati[] = "fivegujarati"; +static const char glyph_fivegurmukhi[] = "fivegurmukhi"; +static const char glyph_fivehackarabic[] = "fivehackarabic"; +static const char glyph_fivehangzhou[] = "fivehangzhou"; +static const char glyph_fiveideographicparen[] = "fiveideographicparen"; +static const char glyph_fiveinferior[] = "fiveinferior"; +static const char glyph_fivemonospace[] = "fivemonospace"; +static const char glyph_fiveoldstyle[] = "fiveoldstyle"; +static const char glyph_fiveparen[] = "fiveparen"; +static const char glyph_fiveperiod[] = "fiveperiod"; +static const char glyph_fivepersian[] = "fivepersian"; +static const char glyph_fiveroman[] = "fiveroman"; +static const char glyph_fivesuperior[] = "fivesuperior"; +static const char glyph_fivethai[] = "fivethai"; +static const char glyph_fl[] = "fl"; +static const char glyph_florin[] = "florin"; +static const char glyph_fmonospace[] = "fmonospace"; +static const char glyph_fmsquare[] = "fmsquare"; +static const char glyph_fofanthai[] = "fofanthai"; +static const char glyph_fofathai[] = "fofathai"; +static const char glyph_fongmanthai[] = "fongmanthai"; +static const char glyph_forall[] = "forall"; +static const char glyph_four[] = "four"; +static const char glyph_fourarabic[] = "fourarabic"; +static const char glyph_fourbengali[] = "fourbengali"; +static const char glyph_fourcircle[] = "fourcircle"; +static const char glyph_fourcircleinversesansserif[] = +"fourcircleinversesansserif"; +static const char glyph_fourdeva[] = "fourdeva"; +static const char glyph_fourgujarati[] = "fourgujarati"; +static const char glyph_fourgurmukhi[] = "fourgurmukhi"; +static const char glyph_fourhackarabic[] = "fourhackarabic"; +static const char glyph_fourhangzhou[] = "fourhangzhou"; +static const char glyph_fourideographicparen[] = "fourideographicparen"; +static const char glyph_fourinferior[] = "fourinferior"; +static const char glyph_fourmonospace[] = "fourmonospace"; +static const char glyph_fournumeratorbengali[] = "fournumeratorbengali"; +static const char glyph_fouroldstyle[] = "fouroldstyle"; +static const char glyph_fourparen[] = "fourparen"; +static const char glyph_fourperiod[] = "fourperiod"; +static const char glyph_fourpersian[] = "fourpersian"; +static const char glyph_fourroman[] = "fourroman"; +static const char glyph_foursuperior[] = "foursuperior"; +static const char glyph_fourteencircle[] = "fourteencircle"; +static const char glyph_fourteenparen[] = "fourteenparen"; +static const char glyph_fourteenperiod[] = "fourteenperiod"; +static const char glyph_fourthai[] = "fourthai"; +static const char glyph_fourthtonechinese[] = "fourthtonechinese"; +static const char glyph_fparen[] = "fparen"; +static const char glyph_fraction[] = "fraction"; +static const char glyph_franc[] = "franc"; +static const char glyph_g[] = "g"; +static const char glyph_gabengali[] = "gabengali"; +static const char glyph_gacute[] = "gacute"; +static const char glyph_gadeva[] = "gadeva"; +static const char glyph_gafarabic[] = "gafarabic"; +static const char glyph_gaffinalarabic[] = "gaffinalarabic"; +static const char glyph_gafinitialarabic[] = "gafinitialarabic"; +static const char glyph_gafmedialarabic[] = "gafmedialarabic"; +static const char glyph_gagujarati[] = "gagujarati"; +static const char glyph_gagurmukhi[] = "gagurmukhi"; +static const char glyph_gahiragana[] = "gahiragana"; +static const char glyph_gakatakana[] = "gakatakana"; +static const char glyph_gamma[] = "gamma"; +static const char glyph_gammalatinsmall[] = "gammalatinsmall"; +static const char glyph_gammasuperior[] = "gammasuperior"; +static const char glyph_gangiacoptic[] = "gangiacoptic"; +static const char glyph_gbopomofo[] = "gbopomofo"; +static const char glyph_gbreve[] = "gbreve"; +static const char glyph_gcaron[] = "gcaron"; +static const char glyph_gcedilla[] = "gcedilla"; +static const char glyph_gcircle[] = "gcircle"; +static const char glyph_gcircumflex[] = "gcircumflex"; +static const char glyph_gcommaaccent[] = "gcommaaccent"; +static const char glyph_gdot[] = "gdot"; +static const char glyph_gdotaccent[] = "gdotaccent"; +static const char glyph_gecyrillic[] = "gecyrillic"; +static const char glyph_gehiragana[] = "gehiragana"; +static const char glyph_gekatakana[] = "gekatakana"; +static const char glyph_geometricallyequal[] = "geometricallyequal"; +static const char glyph_gereshaccenthebrew[] = "gereshaccenthebrew"; +static const char glyph_gereshhebrew[] = "gereshhebrew"; +static const char glyph_gereshmuqdamhebrew[] = "gereshmuqdamhebrew"; +static const char glyph_germandbls[] = "germandbls"; +static const char glyph_gershayimaccenthebrew[] = "gershayimaccenthebrew"; +static const char glyph_gershayimhebrew[] = "gershayimhebrew"; +static const char glyph_getamark[] = "getamark"; +static const char glyph_ghabengali[] = "ghabengali"; +static const char glyph_ghadarmenian[] = "ghadarmenian"; +static const char glyph_ghadeva[] = "ghadeva"; +static const char glyph_ghagujarati[] = "ghagujarati"; +static const char glyph_ghagurmukhi[] = "ghagurmukhi"; +static const char glyph_ghainarabic[] = "ghainarabic"; +static const char glyph_ghainfinalarabic[] = "ghainfinalarabic"; +static const char glyph_ghaininitialarabic[] = "ghaininitialarabic"; +static const char glyph_ghainmedialarabic[] = "ghainmedialarabic"; +static const char glyph_ghemiddlehookcyrillic[] = "ghemiddlehookcyrillic"; +static const char glyph_ghestrokecyrillic[] = "ghestrokecyrillic"; +static const char glyph_gheupturncyrillic[] = "gheupturncyrillic"; +static const char glyph_ghhadeva[] = "ghhadeva"; +static const char glyph_ghhagurmukhi[] = "ghhagurmukhi"; +static const char glyph_ghook[] = "ghook"; +static const char glyph_ghzsquare[] = "ghzsquare"; +static const char glyph_gihiragana[] = "gihiragana"; +static const char glyph_gikatakana[] = "gikatakana"; +static const char glyph_gimarmenian[] = "gimarmenian"; +static const char glyph_gimel[] = "gimel"; +static const char glyph_gimeldagesh[] = "gimeldagesh"; +static const char glyph_gimeldageshhebrew[] = "gimeldageshhebrew"; +static const char glyph_gimelhebrew[] = "gimelhebrew"; +static const char glyph_gjecyrillic[] = "gjecyrillic"; +static const char glyph_glottalinvertedstroke[] = "glottalinvertedstroke"; +static const char glyph_glottalstop[] = "glottalstop"; +static const char glyph_glottalstopinverted[] = "glottalstopinverted"; +static const char glyph_glottalstopmod[] = "glottalstopmod"; +static const char glyph_glottalstopreversed[] = "glottalstopreversed"; +static const char glyph_glottalstopreversedmod[] = "glottalstopreversedmod"; +static const char glyph_glottalstopreversedsuperior[] = +"glottalstopreversedsuperior"; +static const char glyph_glottalstopstroke[] = "glottalstopstroke"; +static const char glyph_glottalstopstrokereversed[] = +"glottalstopstrokereversed"; +static const char glyph_gmacron[] = "gmacron"; +static const char glyph_gmonospace[] = "gmonospace"; +static const char glyph_gohiragana[] = "gohiragana"; +static const char glyph_gokatakana[] = "gokatakana"; +static const char glyph_gparen[] = "gparen"; +static const char glyph_gpasquare[] = "gpasquare"; +static const char glyph_gradient[] = "gradient"; +static const char glyph_grave[] = "grave"; +static const char glyph_gravebelowcmb[] = "gravebelowcmb"; +static const char glyph_gravecmb[] = "gravecmb"; +static const char glyph_gravecomb[] = "gravecomb"; +static const char glyph_gravedeva[] = "gravedeva"; +static const char glyph_gravelowmod[] = "gravelowmod"; +static const char glyph_gravemonospace[] = "gravemonospace"; +static const char glyph_gravetonecmb[] = "gravetonecmb"; +static const char glyph_greater[] = "greater"; +static const char glyph_greaterequal[] = "greaterequal"; +static const char glyph_greaterequalorless[] = "greaterequalorless"; +static const char glyph_greatermonospace[] = "greatermonospace"; +static const char glyph_greaterorequivalent[] = "greaterorequivalent"; +static const char glyph_greaterorless[] = "greaterorless"; +static const char glyph_greateroverequal[] = "greateroverequal"; +static const char glyph_greatersmall[] = "greatersmall"; +static const char glyph_gscript[] = "gscript"; +static const char glyph_gstroke[] = "gstroke"; +static const char glyph_guhiragana[] = "guhiragana"; +static const char glyph_guillemotleft[] = "guillemotleft"; +static const char glyph_guillemotright[] = "guillemotright"; +static const char glyph_guilsinglleft[] = "guilsinglleft"; +static const char glyph_guilsinglright[] = "guilsinglright"; +static const char glyph_gukatakana[] = "gukatakana"; +static const char glyph_guramusquare[] = "guramusquare"; +static const char glyph_gysquare[] = "gysquare"; +static const char glyph_h[] = "h"; +static const char glyph_haabkhasiancyrillic[] = "haabkhasiancyrillic"; +static const char glyph_haaltonearabic[] = "haaltonearabic"; +static const char glyph_habengali[] = "habengali"; +static const char glyph_hadescendercyrillic[] = "hadescendercyrillic"; +static const char glyph_hadeva[] = "hadeva"; +static const char glyph_hagujarati[] = "hagujarati"; +static const char glyph_hagurmukhi[] = "hagurmukhi"; +static const char glyph_haharabic[] = "haharabic"; +static const char glyph_hahfinalarabic[] = "hahfinalarabic"; +static const char glyph_hahinitialarabic[] = "hahinitialarabic"; +static const char glyph_hahiragana[] = "hahiragana"; +static const char glyph_hahmedialarabic[] = "hahmedialarabic"; +static const char glyph_haitusquare[] = "haitusquare"; +static const char glyph_hakatakana[] = "hakatakana"; +static const char glyph_hakatakanahalfwidth[] = "hakatakanahalfwidth"; +static const char glyph_halantgurmukhi[] = "halantgurmukhi"; +static const char glyph_hamzaarabic[] = "hamzaarabic"; +static const char glyph_hamzadammaarabic[] = "hamzadammaarabic"; +static const char glyph_hamzadammatanarabic[] = "hamzadammatanarabic"; +static const char glyph_hamzafathaarabic[] = "hamzafathaarabic"; +static const char glyph_hamzafathatanarabic[] = "hamzafathatanarabic"; +static const char glyph_hamzalowarabic[] = "hamzalowarabic"; +static const char glyph_hamzalowkasraarabic[] = "hamzalowkasraarabic"; +static const char glyph_hamzalowkasratanarabic[] = "hamzalowkasratanarabic"; +static const char glyph_hamzasukunarabic[] = "hamzasukunarabic"; +static const char glyph_hangulfiller[] = "hangulfiller"; +static const char glyph_hardsigncyrillic[] = "hardsigncyrillic"; +static const char glyph_harpoonleftbarbup[] = "harpoonleftbarbup"; +static const char glyph_harpoonrightbarbup[] = "harpoonrightbarbup"; +static const char glyph_hasquare[] = "hasquare"; +static const char glyph_hatafpatah[] = "hatafpatah"; +static const char glyph_hatafpatah16[] = "hatafpatah16"; +static const char glyph_hatafpatah23[] = "hatafpatah23"; +static const char glyph_hatafpatah2f[] = "hatafpatah2f"; +static const char glyph_hatafpatahhebrew[] = "hatafpatahhebrew"; +static const char glyph_hatafpatahnarrowhebrew[] = "hatafpatahnarrowhebrew"; +static const char glyph_hatafpatahquarterhebrew[] = "hatafpatahquarterhebrew"; +static const char glyph_hatafpatahwidehebrew[] = "hatafpatahwidehebrew"; +static const char glyph_hatafqamats[] = "hatafqamats"; +static const char glyph_hatafqamats1b[] = "hatafqamats1b"; +static const char glyph_hatafqamats28[] = "hatafqamats28"; +static const char glyph_hatafqamats34[] = "hatafqamats34"; +static const char glyph_hatafqamatshebrew[] = "hatafqamatshebrew"; +static const char glyph_hatafqamatsnarrowhebrew[] = "hatafqamatsnarrowhebrew"; +static const char glyph_hatafqamatsquarterhebrew[] = +"hatafqamatsquarterhebrew"; +static const char glyph_hatafqamatswidehebrew[] = "hatafqamatswidehebrew"; +static const char glyph_hatafsegol[] = "hatafsegol"; +static const char glyph_hatafsegol17[] = "hatafsegol17"; +static const char glyph_hatafsegol24[] = "hatafsegol24"; +static const char glyph_hatafsegol30[] = "hatafsegol30"; +static const char glyph_hatafsegolhebrew[] = "hatafsegolhebrew"; +static const char glyph_hatafsegolnarrowhebrew[] = "hatafsegolnarrowhebrew"; +static const char glyph_hatafsegolquarterhebrew[] = "hatafsegolquarterhebrew"; +static const char glyph_hatafsegolwidehebrew[] = "hatafsegolwidehebrew"; +static const char glyph_hbar[] = "hbar"; +static const char glyph_hbopomofo[] = "hbopomofo"; +static const char glyph_hbrevebelow[] = "hbrevebelow"; +static const char glyph_hcedilla[] = "hcedilla"; +static const char glyph_hcircle[] = "hcircle"; +static const char glyph_hcircumflex[] = "hcircumflex"; +static const char glyph_hdieresis[] = "hdieresis"; +static const char glyph_hdotaccent[] = "hdotaccent"; +static const char glyph_hdotbelow[] = "hdotbelow"; +static const char glyph_he[] = "he"; +static const char glyph_heart[] = "heart"; +static const char glyph_heartsuitblack[] = "heartsuitblack"; +static const char glyph_heartsuitwhite[] = "heartsuitwhite"; +static const char glyph_hedagesh[] = "hedagesh"; +static const char glyph_hedageshhebrew[] = "hedageshhebrew"; +static const char glyph_hehaltonearabic[] = "hehaltonearabic"; +static const char glyph_heharabic[] = "heharabic"; +static const char glyph_hehebrew[] = "hehebrew"; +static const char glyph_hehfinalaltonearabic[] = "hehfinalaltonearabic"; +static const char glyph_hehfinalalttwoarabic[] = "hehfinalalttwoarabic"; +static const char glyph_hehfinalarabic[] = "hehfinalarabic"; +static const char glyph_hehhamzaabovefinalarabic[] = +"hehhamzaabovefinalarabic"; +static const char glyph_hehhamzaaboveisolatedarabic[] = +"hehhamzaaboveisolatedarabic"; +static const char glyph_hehinitialaltonearabic[] = "hehinitialaltonearabic"; +static const char glyph_hehinitialarabic[] = "hehinitialarabic"; +static const char glyph_hehiragana[] = "hehiragana"; +static const char glyph_hehmedialaltonearabic[] = "hehmedialaltonearabic"; +static const char glyph_hehmedialarabic[] = "hehmedialarabic"; +static const char glyph_heiseierasquare[] = "heiseierasquare"; +static const char glyph_hekatakana[] = "hekatakana"; +static const char glyph_hekatakanahalfwidth[] = "hekatakanahalfwidth"; +static const char glyph_hekutaarusquare[] = "hekutaarusquare"; +static const char glyph_henghook[] = "henghook"; +static const char glyph_herutusquare[] = "herutusquare"; +static const char glyph_het[] = "het"; +static const char glyph_hethebrew[] = "hethebrew"; +static const char glyph_hhook[] = "hhook"; +static const char glyph_hhooksuperior[] = "hhooksuperior"; +static const char glyph_hieuhacirclekorean[] = "hieuhacirclekorean"; +static const char glyph_hieuhaparenkorean[] = "hieuhaparenkorean"; +static const char glyph_hieuhcirclekorean[] = "hieuhcirclekorean"; +static const char glyph_hieuhkorean[] = "hieuhkorean"; +static const char glyph_hieuhparenkorean[] = "hieuhparenkorean"; +static const char glyph_hihiragana[] = "hihiragana"; +static const char glyph_hikatakana[] = "hikatakana"; +static const char glyph_hikatakanahalfwidth[] = "hikatakanahalfwidth"; +static const char glyph_hiriq[] = "hiriq"; +static const char glyph_hiriq14[] = "hiriq14"; +static const char glyph_hiriq21[] = "hiriq21"; +static const char glyph_hiriq2d[] = "hiriq2d"; +static const char glyph_hiriqhebrew[] = "hiriqhebrew"; +static const char glyph_hiriqnarrowhebrew[] = "hiriqnarrowhebrew"; +static const char glyph_hiriqquarterhebrew[] = "hiriqquarterhebrew"; +static const char glyph_hiriqwidehebrew[] = "hiriqwidehebrew"; +static const char glyph_hlinebelow[] = "hlinebelow"; +static const char glyph_hmonospace[] = "hmonospace"; +static const char glyph_hoarmenian[] = "hoarmenian"; +static const char glyph_hohipthai[] = "hohipthai"; +static const char glyph_hohiragana[] = "hohiragana"; +static const char glyph_hokatakana[] = "hokatakana"; +static const char glyph_hokatakanahalfwidth[] = "hokatakanahalfwidth"; +static const char glyph_holam[] = "holam"; +static const char glyph_holam19[] = "holam19"; +static const char glyph_holam26[] = "holam26"; +static const char glyph_holam32[] = "holam32"; +static const char glyph_holamhebrew[] = "holamhebrew"; +static const char glyph_holamnarrowhebrew[] = "holamnarrowhebrew"; +static const char glyph_holamquarterhebrew[] = "holamquarterhebrew"; +static const char glyph_holamwidehebrew[] = "holamwidehebrew"; +static const char glyph_honokhukthai[] = "honokhukthai"; +static const char glyph_hookabovecomb[] = "hookabovecomb"; +static const char glyph_hookcmb[] = "hookcmb"; +static const char glyph_hookpalatalizedbelowcmb[] = "hookpalatalizedbelowcmb"; +static const char glyph_hookretroflexbelowcmb[] = "hookretroflexbelowcmb"; +static const char glyph_hoonsquare[] = "hoonsquare"; +static const char glyph_horicoptic[] = "horicoptic"; +static const char glyph_horizontalbar[] = "horizontalbar"; +static const char glyph_horncmb[] = "horncmb"; +static const char glyph_hotsprings[] = "hotsprings"; +static const char glyph_house[] = "house"; +static const char glyph_hparen[] = "hparen"; +static const char glyph_hsuperior[] = "hsuperior"; +static const char glyph_hturned[] = "hturned"; +static const char glyph_huhiragana[] = "huhiragana"; +static const char glyph_huiitosquare[] = "huiitosquare"; +static const char glyph_hukatakana[] = "hukatakana"; +static const char glyph_hukatakanahalfwidth[] = "hukatakanahalfwidth"; +static const char glyph_hungarumlaut[] = "hungarumlaut"; +static const char glyph_hungarumlautcmb[] = "hungarumlautcmb"; +static const char glyph_hv[] = "hv"; +static const char glyph_hyphen[] = "hyphen"; +static const char glyph_hypheninferior[] = "hypheninferior"; +static const char glyph_hyphenmonospace[] = "hyphenmonospace"; +static const char glyph_hyphensmall[] = "hyphensmall"; +static const char glyph_hyphensuperior[] = "hyphensuperior"; +static const char glyph_hyphentwo[] = "hyphentwo"; +static const char glyph_i[] = "i"; +static const char glyph_iacute[] = "iacute"; +static const char glyph_iacyrillic[] = "iacyrillic"; +static const char glyph_ibengali[] = "ibengali"; +static const char glyph_ibopomofo[] = "ibopomofo"; +static const char glyph_ibreve[] = "ibreve"; +static const char glyph_icaron[] = "icaron"; +static const char glyph_icircle[] = "icircle"; +static const char glyph_icircumflex[] = "icircumflex"; +static const char glyph_icyrillic[] = "icyrillic"; +static const char glyph_idblgrave[] = "idblgrave"; +static const char glyph_ideographearthcircle[] = "ideographearthcircle"; +static const char glyph_ideographfirecircle[] = "ideographfirecircle"; +static const char glyph_ideographicallianceparen[] = +"ideographicallianceparen"; +static const char glyph_ideographiccallparen[] = "ideographiccallparen"; +static const char glyph_ideographiccentrecircle[] = "ideographiccentrecircle"; +static const char glyph_ideographicclose[] = "ideographicclose"; +static const char glyph_ideographiccomma[] = "ideographiccomma"; +static const char glyph_ideographiccommaleft[] = "ideographiccommaleft"; +static const char glyph_ideographiccongratulationparen[] = +"ideographiccongratulationparen"; +static const char glyph_ideographiccorrectcircle[] = +"ideographiccorrectcircle"; +static const char glyph_ideographicearthparen[] = +"ideographicearthparen"; +static const char glyph_ideographicenterpriseparen[] = +"ideographicenterpriseparen"; +static const char glyph_ideographicexcellentcircle[] = +"ideographicexcellentcircle"; +static const char glyph_ideographicfestivalparen[] = +"ideographicfestivalparen"; +static const char glyph_ideographicfinancialcircle[] = +"ideographicfinancialcircle"; +static const char glyph_ideographicfinancialparen[] = +"ideographicfinancialparen"; +static const char glyph_ideographicfireparen[] = "ideographicfireparen"; +static const char glyph_ideographichaveparen[] = "ideographichaveparen"; +static const char glyph_ideographichighcircle[] = "ideographichighcircle"; +static const char glyph_ideographiciterationmark[] = +"ideographiciterationmark"; +static const char glyph_ideographiclaborcircle[] = "ideographiclaborcircle"; +static const char glyph_ideographiclaborparen[] = "ideographiclaborparen"; +static const char glyph_ideographicleftcircle[] = "ideographicleftcircle"; +static const char glyph_ideographiclowcircle[] = "ideographiclowcircle"; +static const char glyph_ideographicmedicinecircle[] = +"ideographicmedicinecircle"; +static const char glyph_ideographicmetalparen[] = "ideographicmetalparen"; +static const char glyph_ideographicmoonparen[] = "ideographicmoonparen"; +static const char glyph_ideographicnameparen[] = "ideographicnameparen"; +static const char glyph_ideographicperiod[] = "ideographicperiod"; +static const char glyph_ideographicprintcircle[] = "ideographicprintcircle"; +static const char glyph_ideographicreachparen[] = "ideographicreachparen"; +static const char glyph_ideographicrepresentparen[] = +"ideographicrepresentparen"; +static const char glyph_ideographicresourceparen[] = +"ideographicresourceparen"; +static const char glyph_ideographicrightcircle[] = "ideographicrightcircle"; +static const char glyph_ideographicsecretcircle[] = "ideographicsecretcircle"; +static const char glyph_ideographicselfparen[] = "ideographicselfparen"; +static const char glyph_ideographicsocietyparen[] = "ideographicsocietyparen"; +static const char glyph_ideographicspace[] = "ideographicspace"; +static const char glyph_ideographicspecialparen[] = "ideographicspecialparen"; +static const char glyph_ideographicstockparen[] = "ideographicstockparen"; +static const char glyph_ideographicstudyparen[] = "ideographicstudyparen"; +static const char glyph_ideographicsunparen[] = "ideographicsunparen"; +static const char glyph_ideographicsuperviseparen[] = +"ideographicsuperviseparen"; +static const char glyph_ideographicwaterparen[] = "ideographicwaterparen"; +static const char glyph_ideographicwoodparen[] = "ideographicwoodparen"; +static const char glyph_ideographiczero[] = "ideographiczero"; +static const char glyph_ideographmetalcircle[] = "ideographmetalcircle"; +static const char glyph_ideographmooncircle[] = "ideographmooncircle"; +static const char glyph_ideographnamecircle[] = "ideographnamecircle"; +static const char glyph_ideographsuncircle[] = "ideographsuncircle"; +static const char glyph_ideographwatercircle[] = "ideographwatercircle"; +static const char glyph_ideographwoodcircle[] = "ideographwoodcircle"; +static const char glyph_ideva[] = "ideva"; +static const char glyph_idieresis[] = "idieresis"; +static const char glyph_idieresisacute[] = "idieresisacute"; +static const char glyph_idieresiscyrillic[] = "idieresiscyrillic"; +static const char glyph_idotbelow[] = "idotbelow"; +static const char glyph_iebrevecyrillic[] = "iebrevecyrillic"; +static const char glyph_iecyrillic[] = "iecyrillic"; +static const char glyph_ieungacirclekorean[] = "ieungacirclekorean"; +static const char glyph_ieungaparenkorean[] = "ieungaparenkorean"; +static const char glyph_ieungcirclekorean[] = "ieungcirclekorean"; +static const char glyph_ieungkorean[] = "ieungkorean"; +static const char glyph_ieungparenkorean[] = "ieungparenkorean"; +static const char glyph_igrave[] = "igrave"; +static const char glyph_igujarati[] = "igujarati"; +static const char glyph_igurmukhi[] = "igurmukhi"; +static const char glyph_ihiragana[] = "ihiragana"; +static const char glyph_ihookabove[] = "ihookabove"; +static const char glyph_iibengali[] = "iibengali"; +static const char glyph_iicyrillic[] = "iicyrillic"; +static const char glyph_iideva[] = "iideva"; +static const char glyph_iigujarati[] = "iigujarati"; +static const char glyph_iigurmukhi[] = "iigurmukhi"; +static const char glyph_iimatragurmukhi[] = "iimatragurmukhi"; +static const char glyph_iinvertedbreve[] = "iinvertedbreve"; +static const char glyph_iishortcyrillic[] = "iishortcyrillic"; +static const char glyph_iivowelsignbengali[] = "iivowelsignbengali"; +static const char glyph_iivowelsigndeva[] = "iivowelsigndeva"; +static const char glyph_iivowelsigngujarati[] = "iivowelsigngujarati"; +static const char glyph_ij[] = "ij"; +static const char glyph_ikatakana[] = "ikatakana"; +static const char glyph_ikatakanahalfwidth[] = "ikatakanahalfwidth"; +static const char glyph_ikorean[] = "ikorean"; +static const char glyph_ilde[] = "ilde"; +static const char glyph_iluyhebrew[] = "iluyhebrew"; +static const char glyph_imacron[] = "imacron"; +static const char glyph_imacroncyrillic[] = "imacroncyrillic"; +static const char glyph_imageorapproximatelyequal[] = +"imageorapproximatelyequal"; +static const char glyph_imatragurmukhi[] = "imatragurmukhi"; +static const char glyph_imonospace[] = "imonospace"; +static const char glyph_increment[] = "increment"; +static const char glyph_infinity[] = "infinity"; +static const char glyph_iniarmenian[] = "iniarmenian"; +static const char glyph_integral[] = "integral"; +static const char glyph_integralbottom[] = "integralbottom"; +static const char glyph_integralbt[] = "integralbt"; +static const char glyph_integralex[] = "integralex"; +static const char glyph_integraltop[] = "integraltop"; +static const char glyph_integraltp[] = "integraltp"; +static const char glyph_intersection[] = "intersection"; +static const char glyph_intisquare[] = "intisquare"; +static const char glyph_invbullet[] = "invbullet"; +static const char glyph_invcircle[] = "invcircle"; +static const char glyph_invsmileface[] = "invsmileface"; +static const char glyph_iocyrillic[] = "iocyrillic"; +static const char glyph_iogonek[] = "iogonek"; +static const char glyph_iota[] = "iota"; +static const char glyph_iotadieresis[] = "iotadieresis"; +static const char glyph_iotadieresistonos[] = "iotadieresistonos"; +static const char glyph_iotalatin[] = "iotalatin"; +static const char glyph_iotatonos[] = "iotatonos"; +static const char glyph_iparen[] = "iparen"; +static const char glyph_irigurmukhi[] = "irigurmukhi"; +static const char glyph_ismallhiragana[] = "ismallhiragana"; +static const char glyph_ismallkatakana[] = "ismallkatakana"; +static const char glyph_ismallkatakanahalfwidth[] = "ismallkatakanahalfwidth"; +static const char glyph_issharbengali[] = "issharbengali"; +static const char glyph_istroke[] = "istroke"; +static const char glyph_isuperior[] = "isuperior"; +static const char glyph_iterationhiragana[] = "iterationhiragana"; +static const char glyph_iterationkatakana[] = "iterationkatakana"; +static const char glyph_itilde[] = "itilde"; +static const char glyph_itildebelow[] = "itildebelow"; +static const char glyph_iubopomofo[] = "iubopomofo"; +static const char glyph_iucyrillic[] = "iucyrillic"; +static const char glyph_ivowelsignbengali[] = "ivowelsignbengali"; +static const char glyph_ivowelsigndeva[] = "ivowelsigndeva"; +static const char glyph_ivowelsigngujarati[] = "ivowelsigngujarati"; +static const char glyph_izhitsacyrillic[] = "izhitsacyrillic"; +static const char glyph_izhitsadblgravecyrillic[] = "izhitsadblgravecyrillic"; +static const char glyph_j[] = "j"; +static const char glyph_jaarmenian[] = "jaarmenian"; +static const char glyph_jabengali[] = "jabengali"; +static const char glyph_jadeva[] = "jadeva"; +static const char glyph_jagujarati[] = "jagujarati"; +static const char glyph_jagurmukhi[] = "jagurmukhi"; +static const char glyph_jbopomofo[] = "jbopomofo"; +static const char glyph_jcaron[] = "jcaron"; +static const char glyph_jcircle[] = "jcircle"; +static const char glyph_jcircumflex[] = "jcircumflex"; +static const char glyph_jcrossedtail[] = "jcrossedtail"; +static const char glyph_jdotlessstroke[] = "jdotlessstroke"; +static const char glyph_jecyrillic[] = "jecyrillic"; +static const char glyph_jeemarabic[] = "jeemarabic"; +static const char glyph_jeemfinalarabic[] = "jeemfinalarabic"; +static const char glyph_jeeminitialarabic[] = "jeeminitialarabic"; +static const char glyph_jeemmedialarabic[] = "jeemmedialarabic"; +static const char glyph_jeharabic[] = "jeharabic"; +static const char glyph_jehfinalarabic[] = "jehfinalarabic"; +static const char glyph_jhabengali[] = "jhabengali"; +static const char glyph_jhadeva[] = "jhadeva"; +static const char glyph_jhagujarati[] = "jhagujarati"; +static const char glyph_jhagurmukhi[] = "jhagurmukhi"; +static const char glyph_jheharmenian[] = "jheharmenian"; +static const char glyph_jis[] = "jis"; +static const char glyph_jmonospace[] = "jmonospace"; +static const char glyph_jparen[] = "jparen"; +static const char glyph_jsuperior[] = "jsuperior"; +static const char glyph_k[] = "k"; +static const char glyph_kabashkircyrillic[] = "kabashkircyrillic"; +static const char glyph_kabengali[] = "kabengali"; +static const char glyph_kacute[] = "kacute"; +static const char glyph_kacyrillic[] = "kacyrillic"; +static const char glyph_kadescendercyrillic[] = "kadescendercyrillic"; +static const char glyph_kadeva[] = "kadeva"; +static const char glyph_kaf[] = "kaf"; +static const char glyph_kafarabic[] = "kafarabic"; +static const char glyph_kafdagesh[] = "kafdagesh"; +static const char glyph_kafdageshhebrew[] = "kafdageshhebrew"; +static const char glyph_kaffinalarabic[] = "kaffinalarabic"; +static const char glyph_kafhebrew[] = "kafhebrew"; +static const char glyph_kafinitialarabic[] = "kafinitialarabic"; +static const char glyph_kafmedialarabic[] = "kafmedialarabic"; +static const char glyph_kafrafehebrew[] = "kafrafehebrew"; +static const char glyph_kagujarati[] = "kagujarati"; +static const char glyph_kagurmukhi[] = "kagurmukhi"; +static const char glyph_kahiragana[] = "kahiragana"; +static const char glyph_kahookcyrillic[] = "kahookcyrillic"; +static const char glyph_kakatakana[] = "kakatakana"; +static const char glyph_kakatakanahalfwidth[] = "kakatakanahalfwidth"; +static const char glyph_kappa[] = "kappa"; +static const char glyph_kappasymbolgreek[] = "kappasymbolgreek"; +static const char glyph_kapyeounmieumkorean[] = "kapyeounmieumkorean"; +static const char glyph_kapyeounphieuphkorean[] = "kapyeounphieuphkorean"; +static const char glyph_kapyeounpieupkorean[] = "kapyeounpieupkorean"; +static const char glyph_kapyeounssangpieupkorean[] = +"kapyeounssangpieupkorean"; +static const char glyph_karoriisquare[] = "karoriisquare"; +static const char glyph_kashidaautoarabic[] = "kashidaautoarabic"; +static const char glyph_kashidaautonosidebearingarabic[] = +"kashidaautonosidebearingarabic"; +static const char glyph_kasmallkatakana[] = "kasmallkatakana"; +static const char glyph_kasquare[] = "kasquare"; +static const char glyph_kasraarabic[] = "kasraarabic"; +static const char glyph_kasratanarabic[] = "kasratanarabic"; +static const char glyph_kastrokecyrillic[] = "kastrokecyrillic"; +static const char glyph_katahiraprolongmarkhalfwidth[] = +"katahiraprolongmarkhalfwidth"; +static const char glyph_kaverticalstrokecyrillic[] = +"kaverticalstrokecyrillic"; +static const char glyph_kbopomofo[] = "kbopomofo"; +static const char glyph_kcalsquare[] = "kcalsquare"; +static const char glyph_kcaron[] = "kcaron"; +static const char glyph_kcedilla[] = "kcedilla"; +static const char glyph_kcircle[] = "kcircle"; +static const char glyph_kcommaaccent[] = "kcommaaccent"; +static const char glyph_kdotbelow[] = "kdotbelow"; +static const char glyph_keharmenian[] = "keharmenian"; +static const char glyph_kehiragana[] = "kehiragana"; +static const char glyph_kekatakana[] = "kekatakana"; +static const char glyph_kekatakanahalfwidth[] = "kekatakanahalfwidth"; +static const char glyph_kenarmenian[] = "kenarmenian"; +static const char glyph_kesmallkatakana[] = "kesmallkatakana"; +static const char glyph_kgreenlandic[] = "kgreenlandic"; +static const char glyph_khabengali[] = "khabengali"; +static const char glyph_khacyrillic[] = "khacyrillic"; +static const char glyph_khadeva[] = "khadeva"; +static const char glyph_khagujarati[] = "khagujarati"; +static const char glyph_khagurmukhi[] = "khagurmukhi"; +static const char glyph_khaharabic[] = "khaharabic"; +static const char glyph_khahfinalarabic[] = "khahfinalarabic"; +static const char glyph_khahinitialarabic[] = "khahinitialarabic"; +static const char glyph_khahmedialarabic[] = "khahmedialarabic"; +static const char glyph_kheicoptic[] = "kheicoptic"; +static const char glyph_khhadeva[] = "khhadeva"; +static const char glyph_khhagurmukhi[] = "khhagurmukhi"; +static const char glyph_khieukhacirclekorean[] = "khieukhacirclekorean"; +static const char glyph_khieukhaparenkorean[] = "khieukhaparenkorean"; +static const char glyph_khieukhcirclekorean[] = "khieukhcirclekorean"; +static const char glyph_khieukhkorean[] = "khieukhkorean"; +static const char glyph_khieukhparenkorean[] = "khieukhparenkorean"; +static const char glyph_khokhaithai[] = "khokhaithai"; +static const char glyph_khokhonthai[] = "khokhonthai"; +static const char glyph_khokhuatthai[] = "khokhuatthai"; +static const char glyph_khokhwaithai[] = "khokhwaithai"; +static const char glyph_khomutthai[] = "khomutthai"; +static const char glyph_khook[] = "khook"; +static const char glyph_khorakhangthai[] = "khorakhangthai"; +static const char glyph_khzsquare[] = "khzsquare"; +static const char glyph_kihiragana[] = "kihiragana"; +static const char glyph_kikatakana[] = "kikatakana"; +static const char glyph_kikatakanahalfwidth[] = "kikatakanahalfwidth"; +static const char glyph_kiroguramusquare[] = "kiroguramusquare"; +static const char glyph_kiromeetorusquare[] = "kiromeetorusquare"; +static const char glyph_kirosquare[] = "kirosquare"; +static const char glyph_kiyeokacirclekorean[] = "kiyeokacirclekorean"; +static const char glyph_kiyeokaparenkorean[] = "kiyeokaparenkorean"; +static const char glyph_kiyeokcirclekorean[] = "kiyeokcirclekorean"; +static const char glyph_kiyeokkorean[] = "kiyeokkorean"; +static const char glyph_kiyeokparenkorean[] = "kiyeokparenkorean"; +static const char glyph_kiyeoksioskorean[] = "kiyeoksioskorean"; +static const char glyph_kjecyrillic[] = "kjecyrillic"; +static const char glyph_klinebelow[] = "klinebelow"; +static const char glyph_klsquare[] = "klsquare"; +static const char glyph_kmcubedsquare[] = "kmcubedsquare"; +static const char glyph_kmonospace[] = "kmonospace"; +static const char glyph_kmsquaredsquare[] = "kmsquaredsquare"; +static const char glyph_kohiragana[] = "kohiragana"; +static const char glyph_kohmsquare[] = "kohmsquare"; +static const char glyph_kokaithai[] = "kokaithai"; +static const char glyph_kokatakana[] = "kokatakana"; +static const char glyph_kokatakanahalfwidth[] = "kokatakanahalfwidth"; +static const char glyph_kooposquare[] = "kooposquare"; +static const char glyph_koppacyrillic[] = "koppacyrillic"; +static const char glyph_koreanstandardsymbol[] = "koreanstandardsymbol"; +static const char glyph_koroniscmb[] = "koroniscmb"; +static const char glyph_kparen[] = "kparen"; +static const char glyph_kpasquare[] = "kpasquare"; +static const char glyph_ksicyrillic[] = "ksicyrillic"; +static const char glyph_ktsquare[] = "ktsquare"; +static const char glyph_kturned[] = "kturned"; +static const char glyph_kuhiragana[] = "kuhiragana"; +static const char glyph_kukatakana[] = "kukatakana"; +static const char glyph_kukatakanahalfwidth[] = "kukatakanahalfwidth"; +static const char glyph_kvsquare[] = "kvsquare"; +static const char glyph_kwsquare[] = "kwsquare"; +static const char glyph_l[] = "l"; +static const char glyph_labengali[] = "labengali"; +static const char glyph_lacute[] = "lacute"; +static const char glyph_ladeva[] = "ladeva"; +static const char glyph_lagujarati[] = "lagujarati"; +static const char glyph_lagurmukhi[] = "lagurmukhi"; +static const char glyph_lakkhangyaothai[] = "lakkhangyaothai"; +static const char glyph_lamaleffinalarabic[] = "lamaleffinalarabic"; +static const char glyph_lamalefhamzaabovefinalarabic[] = +"lamalefhamzaabovefinalarabic"; +static const char glyph_lamalefhamzaaboveisolatedarabic[] = +"lamalefhamzaaboveisolatedarabic"; +static const char glyph_lamalefhamzabelowfinalarabic[] = +"lamalefhamzabelowfinalarabic"; +static const char glyph_lamalefhamzabelowisolatedarabic[] = +"lamalefhamzabelowisolatedarabic"; +static const char glyph_lamalefisolatedarabic[] = +"lamalefisolatedarabic"; +static const char glyph_lamalefmaddaabovefinalarabic[] = +"lamalefmaddaabovefinalarabic"; +static const char glyph_lamalefmaddaaboveisolatedarabic[] = +"lamalefmaddaaboveisolatedarabic"; +static const char glyph_lamarabic[] = "lamarabic"; +static const char glyph_lambda[] = "lambda"; +static const char glyph_lambdastroke[] = "lambdastroke"; +static const char glyph_lamed[] = "lamed"; +static const char glyph_lameddagesh[] = "lameddagesh"; +static const char glyph_lameddageshhebrew[] = "lameddageshhebrew"; +static const char glyph_lamedhebrew[] = "lamedhebrew"; +static const char glyph_lamedholam[] = "lamedholam"; +static const char glyph_lamedholamdagesh[] = "lamedholamdagesh"; +static const char glyph_lamedholamdageshhebrew[] = "lamedholamdageshhebrew"; +static const char glyph_lamedholamhebrew[] = "lamedholamhebrew"; +static const char glyph_lamfinalarabic[] = "lamfinalarabic"; +static const char glyph_lamhahinitialarabic[] = "lamhahinitialarabic"; +static const char glyph_laminitialarabic[] = "laminitialarabic"; +static const char glyph_lamjeeminitialarabic[] = "lamjeeminitialarabic"; +static const char glyph_lamkhahinitialarabic[] = "lamkhahinitialarabic"; +static const char glyph_lamlamhehisolatedarabic[] = "lamlamhehisolatedarabic"; +static const char glyph_lammedialarabic[] = "lammedialarabic"; +static const char glyph_lammeemhahinitialarabic[] = "lammeemhahinitialarabic"; +static const char glyph_lammeeminitialarabic[] = "lammeeminitialarabic"; +static const char glyph_lammeemjeeminitialarabic[] = +"lammeemjeeminitialarabic"; +static const char glyph_lammeemkhahinitialarabic[] = +"lammeemkhahinitialarabic"; +static const char glyph_largecircle[] = "largecircle"; +static const char glyph_lbar[] = "lbar"; +static const char glyph_lbelt[] = "lbelt"; +static const char glyph_lbopomofo[] = "lbopomofo"; +static const char glyph_lcaron[] = "lcaron"; +static const char glyph_lcedilla[] = "lcedilla"; +static const char glyph_lcircle[] = "lcircle"; +static const char glyph_lcircumflexbelow[] = "lcircumflexbelow"; +static const char glyph_lcommaaccent[] = "lcommaaccent"; +static const char glyph_ldot[] = "ldot"; +static const char glyph_ldotaccent[] = "ldotaccent"; +static const char glyph_ldotbelow[] = "ldotbelow"; +static const char glyph_ldotbelowmacron[] = "ldotbelowmacron"; +static const char glyph_leftangleabovecmb[] = "leftangleabovecmb"; +static const char glyph_lefttackbelowcmb[] = "lefttackbelowcmb"; +static const char glyph_less[] = "less"; +static const char glyph_lessequal[] = "lessequal"; +static const char glyph_lessequalorgreater[] = "lessequalorgreater"; +static const char glyph_lessmonospace[] = "lessmonospace"; +static const char glyph_lessorequivalent[] = "lessorequivalent"; +static const char glyph_lessorgreater[] = "lessorgreater"; +static const char glyph_lessoverequal[] = "lessoverequal"; +static const char glyph_lesssmall[] = "lesssmall"; +static const char glyph_lezh[] = "lezh"; +static const char glyph_lfblock[] = "lfblock"; +static const char glyph_lhookretroflex[] = "lhookretroflex"; +static const char glyph_lira[] = "lira"; +static const char glyph_liwnarmenian[] = "liwnarmenian"; +static const char glyph_lj[] = "lj"; +static const char glyph_ljecyrillic[] = "ljecyrillic"; +static const char glyph_ll[] = "ll"; +static const char glyph_lladeva[] = "lladeva"; +static const char glyph_llagujarati[] = "llagujarati"; +static const char glyph_llinebelow[] = "llinebelow"; +static const char glyph_llladeva[] = "llladeva"; +static const char glyph_llvocalicbengali[] = "llvocalicbengali"; +static const char glyph_llvocalicdeva[] = "llvocalicdeva"; +static const char glyph_llvocalicvowelsignbengali[] = +"llvocalicvowelsignbengali"; +static const char glyph_llvocalicvowelsigndeva[] = "llvocalicvowelsigndeva"; +static const char glyph_lmiddletilde[] = "lmiddletilde"; +static const char glyph_lmonospace[] = "lmonospace"; +static const char glyph_lmsquare[] = "lmsquare"; +static const char glyph_lochulathai[] = "lochulathai"; +static const char glyph_logicaland[] = "logicaland"; +static const char glyph_logicalnot[] = "logicalnot"; +static const char glyph_logicalnotreversed[] = "logicalnotreversed"; +static const char glyph_logicalor[] = "logicalor"; +static const char glyph_lolingthai[] = "lolingthai"; +static const char glyph_longs[] = "longs"; +static const char glyph_lowlinecenterline[] = "lowlinecenterline"; +static const char glyph_lowlinecmb[] = "lowlinecmb"; +static const char glyph_lowlinedashed[] = "lowlinedashed"; +static const char glyph_lozenge[] = "lozenge"; +static const char glyph_lparen[] = "lparen"; +static const char glyph_lslash[] = "lslash"; +static const char glyph_lsquare[] = "lsquare"; +static const char glyph_lsuperior[] = "lsuperior"; +static const char glyph_ltshade[] = "ltshade"; +static const char glyph_luthai[] = "luthai"; +static const char glyph_lvocalicbengali[] = "lvocalicbengali"; +static const char glyph_lvocalicdeva[] = "lvocalicdeva"; +static const char glyph_lvocalicvowelsignbengali[] = +"lvocalicvowelsignbengali"; +static const char glyph_lvocalicvowelsigndeva[] = "lvocalicvowelsigndeva"; +static const char glyph_lxsquare[] = "lxsquare"; +static const char glyph_m[] = "m"; +static const char glyph_mabengali[] = "mabengali"; +static const char glyph_macron[] = "macron"; +static const char glyph_macronbelowcmb[] = "macronbelowcmb"; +static const char glyph_macroncmb[] = "macroncmb"; +static const char glyph_macronlowmod[] = "macronlowmod"; +static const char glyph_macronmonospace[] = "macronmonospace"; +static const char glyph_macute[] = "macute"; +static const char glyph_madeva[] = "madeva"; +static const char glyph_magujarati[] = "magujarati"; +static const char glyph_magurmukhi[] = "magurmukhi"; +static const char glyph_mahapakhhebrew[] = "mahapakhhebrew"; +static const char glyph_mahapakhlefthebrew[] = "mahapakhlefthebrew"; +static const char glyph_mahiragana[] = "mahiragana"; +static const char glyph_maichattawalowleftthai[] = "maichattawalowleftthai"; +static const char glyph_maichattawalowrightthai[] = "maichattawalowrightthai"; +static const char glyph_maichattawathai[] = "maichattawathai"; +static const char glyph_maichattawaupperleftthai[] = +"maichattawaupperleftthai"; +static const char glyph_maieklowleftthai[] = "maieklowleftthai"; +static const char glyph_maieklowrightthai[] = "maieklowrightthai"; +static const char glyph_maiekthai[] = "maiekthai"; +static const char glyph_maiekupperleftthai[] = "maiekupperleftthai"; +static const char glyph_maihanakatleftthai[] = "maihanakatleftthai"; +static const char glyph_maihanakatthai[] = "maihanakatthai"; +static const char glyph_maitaikhuleftthai[] = "maitaikhuleftthai"; +static const char glyph_maitaikhuthai[] = "maitaikhuthai"; +static const char glyph_maitholowleftthai[] = "maitholowleftthai"; +static const char glyph_maitholowrightthai[] = "maitholowrightthai"; +static const char glyph_maithothai[] = "maithothai"; +static const char glyph_maithoupperleftthai[] = "maithoupperleftthai"; +static const char glyph_maitrilowleftthai[] = "maitrilowleftthai"; +static const char glyph_maitrilowrightthai[] = "maitrilowrightthai"; +static const char glyph_maitrithai[] = "maitrithai"; +static const char glyph_maitriupperleftthai[] = "maitriupperleftthai"; +static const char glyph_maiyamokthai[] = "maiyamokthai"; +static const char glyph_makatakana[] = "makatakana"; +static const char glyph_makatakanahalfwidth[] = "makatakanahalfwidth"; +static const char glyph_male[] = "male"; +static const char glyph_mansyonsquare[] = "mansyonsquare"; +static const char glyph_maqafhebrew[] = "maqafhebrew"; +static const char glyph_mars[] = "mars"; +static const char glyph_masoracirclehebrew[] = "masoracirclehebrew"; +static const char glyph_masquare[] = "masquare"; +static const char glyph_mbopomofo[] = "mbopomofo"; +static const char glyph_mbsquare[] = "mbsquare"; +static const char glyph_mcircle[] = "mcircle"; +static const char glyph_mcubedsquare[] = "mcubedsquare"; +static const char glyph_mdotaccent[] = "mdotaccent"; +static const char glyph_mdotbelow[] = "mdotbelow"; +static const char glyph_meemarabic[] = "meemarabic"; +static const char glyph_meemfinalarabic[] = "meemfinalarabic"; +static const char glyph_meeminitialarabic[] = "meeminitialarabic"; +static const char glyph_meemmedialarabic[] = "meemmedialarabic"; +static const char glyph_meemmeeminitialarabic[] = "meemmeeminitialarabic"; +static const char glyph_meemmeemisolatedarabic[] = "meemmeemisolatedarabic"; +static const char glyph_meetorusquare[] = "meetorusquare"; +static const char glyph_mehiragana[] = "mehiragana"; +static const char glyph_meizierasquare[] = "meizierasquare"; +static const char glyph_mekatakana[] = "mekatakana"; +static const char glyph_mekatakanahalfwidth[] = "mekatakanahalfwidth"; +static const char glyph_mem[] = "mem"; +static const char glyph_memdagesh[] = "memdagesh"; +static const char glyph_memdageshhebrew[] = "memdageshhebrew"; +static const char glyph_memhebrew[] = "memhebrew"; +static const char glyph_menarmenian[] = "menarmenian"; +static const char glyph_merkhahebrew[] = "merkhahebrew"; +static const char glyph_merkhakefulahebrew[] = "merkhakefulahebrew"; +static const char glyph_merkhakefulalefthebrew[] = "merkhakefulalefthebrew"; +static const char glyph_merkhalefthebrew[] = "merkhalefthebrew"; +static const char glyph_mhook[] = "mhook"; +static const char glyph_mhzsquare[] = "mhzsquare"; +static const char glyph_middledotkatakanahalfwidth[] = +"middledotkatakanahalfwidth"; +static const char glyph_middot[] = "middot"; +static const char glyph_mieumacirclekorean[] = "mieumacirclekorean"; +static const char glyph_mieumaparenkorean[] = "mieumaparenkorean"; +static const char glyph_mieumcirclekorean[] = "mieumcirclekorean"; +static const char glyph_mieumkorean[] = "mieumkorean"; +static const char glyph_mieumpansioskorean[] = "mieumpansioskorean"; +static const char glyph_mieumparenkorean[] = "mieumparenkorean"; +static const char glyph_mieumpieupkorean[] = "mieumpieupkorean"; +static const char glyph_mieumsioskorean[] = "mieumsioskorean"; +static const char glyph_mihiragana[] = "mihiragana"; +static const char glyph_mikatakana[] = "mikatakana"; +static const char glyph_mikatakanahalfwidth[] = "mikatakanahalfwidth"; +static const char glyph_minus[] = "minus"; +static const char glyph_minusbelowcmb[] = "minusbelowcmb"; +static const char glyph_minuscircle[] = "minuscircle"; +static const char glyph_minusmod[] = "minusmod"; +static const char glyph_minusplus[] = "minusplus"; +static const char glyph_minute[] = "minute"; +static const char glyph_miribaarusquare[] = "miribaarusquare"; +static const char glyph_mirisquare[] = "mirisquare"; +static const char glyph_mlonglegturned[] = "mlonglegturned"; +static const char glyph_mlsquare[] = "mlsquare"; +static const char glyph_mmcubedsquare[] = "mmcubedsquare"; +static const char glyph_mmonospace[] = "mmonospace"; +static const char glyph_mmsquaredsquare[] = "mmsquaredsquare"; +static const char glyph_mohiragana[] = "mohiragana"; +static const char glyph_mohmsquare[] = "mohmsquare"; +static const char glyph_mokatakana[] = "mokatakana"; +static const char glyph_mokatakanahalfwidth[] = "mokatakanahalfwidth"; +static const char glyph_molsquare[] = "molsquare"; +static const char glyph_momathai[] = "momathai"; +static const char glyph_moverssquare[] = "moverssquare"; +static const char glyph_moverssquaredsquare[] = "moverssquaredsquare"; +static const char glyph_mparen[] = "mparen"; +static const char glyph_mpasquare[] = "mpasquare"; +static const char glyph_mssquare[] = "mssquare"; +static const char glyph_msuperior[] = "msuperior"; +static const char glyph_mturned[] = "mturned"; +static const char glyph_mu[] = "mu"; +static const char glyph_mu1[] = "mu1"; +static const char glyph_muasquare[] = "muasquare"; +static const char glyph_muchgreater[] = "muchgreater"; +static const char glyph_muchless[] = "muchless"; +static const char glyph_mufsquare[] = "mufsquare"; +static const char glyph_mugreek[] = "mugreek"; +static const char glyph_mugsquare[] = "mugsquare"; +static const char glyph_muhiragana[] = "muhiragana"; +static const char glyph_mukatakana[] = "mukatakana"; +static const char glyph_mukatakanahalfwidth[] = "mukatakanahalfwidth"; +static const char glyph_mulsquare[] = "mulsquare"; +static const char glyph_multiply[] = "multiply"; +static const char glyph_mumsquare[] = "mumsquare"; +static const char glyph_munahhebrew[] = "munahhebrew"; +static const char glyph_munahlefthebrew[] = "munahlefthebrew"; +static const char glyph_musicalnote[] = "musicalnote"; +static const char glyph_musicalnotedbl[] = "musicalnotedbl"; +static const char glyph_musicflatsign[] = "musicflatsign"; +static const char glyph_musicsharpsign[] = "musicsharpsign"; +static const char glyph_mussquare[] = "mussquare"; +static const char glyph_muvsquare[] = "muvsquare"; +static const char glyph_muwsquare[] = "muwsquare"; +static const char glyph_mvmegasquare[] = "mvmegasquare"; +static const char glyph_mvsquare[] = "mvsquare"; +static const char glyph_mwmegasquare[] = "mwmegasquare"; +static const char glyph_mwsquare[] = "mwsquare"; +static const char glyph_n[] = "n"; +static const char glyph_nabengali[] = "nabengali"; +static const char glyph_nabla[] = "nabla"; +static const char glyph_nacute[] = "nacute"; +static const char glyph_nadeva[] = "nadeva"; +static const char glyph_nagujarati[] = "nagujarati"; +static const char glyph_nagurmukhi[] = "nagurmukhi"; +static const char glyph_nahiragana[] = "nahiragana"; +static const char glyph_nakatakana[] = "nakatakana"; +static const char glyph_nakatakanahalfwidth[] = "nakatakanahalfwidth"; +static const char glyph_napostrophe[] = "napostrophe"; +static const char glyph_nasquare[] = "nasquare"; +static const char glyph_nbopomofo[] = "nbopomofo"; +static const char glyph_nbspace[] = "nbspace"; +static const char glyph_ncaron[] = "ncaron"; +static const char glyph_ncedilla[] = "ncedilla"; +static const char glyph_ncircle[] = "ncircle"; +static const char glyph_ncircumflexbelow[] = "ncircumflexbelow"; +static const char glyph_ncommaaccent[] = "ncommaaccent"; +static const char glyph_ndotaccent[] = "ndotaccent"; +static const char glyph_ndotbelow[] = "ndotbelow"; +static const char glyph_nehiragana[] = "nehiragana"; +static const char glyph_nekatakana[] = "nekatakana"; +static const char glyph_nekatakanahalfwidth[] = "nekatakanahalfwidth"; +static const char glyph_newsheqelsign[] = "newsheqelsign"; +static const char glyph_nfsquare[] = "nfsquare"; +static const char glyph_ngabengali[] = "ngabengali"; +static const char glyph_ngadeva[] = "ngadeva"; +static const char glyph_ngagujarati[] = "ngagujarati"; +static const char glyph_ngagurmukhi[] = "ngagurmukhi"; +static const char glyph_ngonguthai[] = "ngonguthai"; +static const char glyph_nhiragana[] = "nhiragana"; +static const char glyph_nhookleft[] = "nhookleft"; +static const char glyph_nhookretroflex[] = "nhookretroflex"; +static const char glyph_nieunacirclekorean[] = "nieunacirclekorean"; +static const char glyph_nieunaparenkorean[] = "nieunaparenkorean"; +static const char glyph_nieuncieuckorean[] = "nieuncieuckorean"; +static const char glyph_nieuncirclekorean[] = "nieuncirclekorean"; +static const char glyph_nieunhieuhkorean[] = "nieunhieuhkorean"; +static const char glyph_nieunkorean[] = "nieunkorean"; +static const char glyph_nieunpansioskorean[] = "nieunpansioskorean"; +static const char glyph_nieunparenkorean[] = "nieunparenkorean"; +static const char glyph_nieunsioskorean[] = "nieunsioskorean"; +static const char glyph_nieuntikeutkorean[] = "nieuntikeutkorean"; +static const char glyph_nihiragana[] = "nihiragana"; +static const char glyph_nikatakana[] = "nikatakana"; +static const char glyph_nikatakanahalfwidth[] = "nikatakanahalfwidth"; +static const char glyph_nikhahitleftthai[] = "nikhahitleftthai"; +static const char glyph_nikhahitthai[] = "nikhahitthai"; +static const char glyph_nine[] = "nine"; +static const char glyph_ninearabic[] = "ninearabic"; +static const char glyph_ninebengali[] = "ninebengali"; +static const char glyph_ninecircle[] = "ninecircle"; +static const char glyph_ninecircleinversesansserif[] = +"ninecircleinversesansserif"; +static const char glyph_ninedeva[] = "ninedeva"; +static const char glyph_ninegujarati[] = "ninegujarati"; +static const char glyph_ninegurmukhi[] = "ninegurmukhi"; +static const char glyph_ninehackarabic[] = "ninehackarabic"; +static const char glyph_ninehangzhou[] = "ninehangzhou"; +static const char glyph_nineideographicparen[] = "nineideographicparen"; +static const char glyph_nineinferior[] = "nineinferior"; +static const char glyph_ninemonospace[] = "ninemonospace"; +static const char glyph_nineoldstyle[] = "nineoldstyle"; +static const char glyph_nineparen[] = "nineparen"; +static const char glyph_nineperiod[] = "nineperiod"; +static const char glyph_ninepersian[] = "ninepersian"; +static const char glyph_nineroman[] = "nineroman"; +static const char glyph_ninesuperior[] = "ninesuperior"; +static const char glyph_nineteencircle[] = "nineteencircle"; +static const char glyph_nineteenparen[] = "nineteenparen"; +static const char glyph_nineteenperiod[] = "nineteenperiod"; +static const char glyph_ninethai[] = "ninethai"; +static const char glyph_nj[] = "nj"; +static const char glyph_njecyrillic[] = "njecyrillic"; +static const char glyph_nkatakana[] = "nkatakana"; +static const char glyph_nkatakanahalfwidth[] = "nkatakanahalfwidth"; +static const char glyph_nlegrightlong[] = "nlegrightlong"; +static const char glyph_nlinebelow[] = "nlinebelow"; +static const char glyph_nmonospace[] = "nmonospace"; +static const char glyph_nmsquare[] = "nmsquare"; +static const char glyph_nnabengali[] = "nnabengali"; +static const char glyph_nnadeva[] = "nnadeva"; +static const char glyph_nnagujarati[] = "nnagujarati"; +static const char glyph_nnagurmukhi[] = "nnagurmukhi"; +static const char glyph_nnnadeva[] = "nnnadeva"; +static const char glyph_nohiragana[] = "nohiragana"; +static const char glyph_nokatakana[] = "nokatakana"; +static const char glyph_nokatakanahalfwidth[] = "nokatakanahalfwidth"; +static const char glyph_nonbreakingspace[] = "nonbreakingspace"; +static const char glyph_nonenthai[] = "nonenthai"; +static const char glyph_nonuthai[] = "nonuthai"; +static const char glyph_noonarabic[] = "noonarabic"; +static const char glyph_noonfinalarabic[] = "noonfinalarabic"; +static const char glyph_noonghunnaarabic[] = "noonghunnaarabic"; +static const char glyph_noonghunnafinalarabic[] = "noonghunnafinalarabic"; +static const char glyph_noonhehinitialarabic[] = "noonhehinitialarabic"; +static const char glyph_nooninitialarabic[] = "nooninitialarabic"; +static const char glyph_noonjeeminitialarabic[] = "noonjeeminitialarabic"; +static const char glyph_noonjeemisolatedarabic[] = "noonjeemisolatedarabic"; +static const char glyph_noonmedialarabic[] = "noonmedialarabic"; +static const char glyph_noonmeeminitialarabic[] = "noonmeeminitialarabic"; +static const char glyph_noonmeemisolatedarabic[] = "noonmeemisolatedarabic"; +static const char glyph_noonnoonfinalarabic[] = "noonnoonfinalarabic"; +static const char glyph_notcontains[] = "notcontains"; +static const char glyph_notelement[] = "notelement"; +static const char glyph_notelementof[] = "notelementof"; +static const char glyph_notequal[] = "notequal"; +static const char glyph_notgreater[] = "notgreater"; +static const char glyph_notgreaternorequal[] = "notgreaternorequal"; +static const char glyph_notgreaternorless[] = "notgreaternorless"; +static const char glyph_notidentical[] = "notidentical"; +static const char glyph_notless[] = "notless"; +static const char glyph_notlessnorequal[] = "notlessnorequal"; +static const char glyph_notparallel[] = "notparallel"; +static const char glyph_notprecedes[] = "notprecedes"; +static const char glyph_notsubset[] = "notsubset"; +static const char glyph_notsucceeds[] = "notsucceeds"; +static const char glyph_notsuperset[] = "notsuperset"; +static const char glyph_nowarmenian[] = "nowarmenian"; +static const char glyph_nparen[] = "nparen"; +static const char glyph_nssquare[] = "nssquare"; +static const char glyph_nsuperior[] = "nsuperior"; +static const char glyph_ntilde[] = "ntilde"; +static const char glyph_nu[] = "nu"; +static const char glyph_nuhiragana[] = "nuhiragana"; +static const char glyph_nukatakana[] = "nukatakana"; +static const char glyph_nukatakanahalfwidth[] = "nukatakanahalfwidth"; +static const char glyph_nuktabengali[] = "nuktabengali"; +static const char glyph_nuktadeva[] = "nuktadeva"; +static const char glyph_nuktagujarati[] = "nuktagujarati"; +static const char glyph_nuktagurmukhi[] = "nuktagurmukhi"; +static const char glyph_numbersign[] = "numbersign"; +static const char glyph_numbersignmonospace[] = "numbersignmonospace"; +static const char glyph_numbersignsmall[] = "numbersignsmall"; +static const char glyph_numeralsigngreek[] = "numeralsigngreek"; +static const char glyph_numeralsignlowergreek[] = "numeralsignlowergreek"; +static const char glyph_numero[] = "numero"; +static const char glyph_nun[] = "nun"; +static const char glyph_nundagesh[] = "nundagesh"; +static const char glyph_nundageshhebrew[] = "nundageshhebrew"; +static const char glyph_nunhebrew[] = "nunhebrew"; +static const char glyph_nvsquare[] = "nvsquare"; +static const char glyph_nwsquare[] = "nwsquare"; +static const char glyph_nyabengali[] = "nyabengali"; +static const char glyph_nyadeva[] = "nyadeva"; +static const char glyph_nyagujarati[] = "nyagujarati"; +static const char glyph_nyagurmukhi[] = "nyagurmukhi"; +static const char glyph_o[] = "o"; +static const char glyph_oacute[] = "oacute"; +static const char glyph_oangthai[] = "oangthai"; +static const char glyph_obarred[] = "obarred"; +static const char glyph_obarredcyrillic[] = "obarredcyrillic"; +static const char glyph_obarreddieresiscyrillic[] = "obarreddieresiscyrillic"; +static const char glyph_obengali[] = "obengali"; +static const char glyph_obopomofo[] = "obopomofo"; +static const char glyph_obreve[] = "obreve"; +static const char glyph_ocandradeva[] = "ocandradeva"; +static const char glyph_ocandragujarati[] = "ocandragujarati"; +static const char glyph_ocandravowelsigndeva[] = "ocandravowelsigndeva"; +static const char glyph_ocandravowelsigngujarati[] = +"ocandravowelsigngujarati"; +static const char glyph_ocaron[] = "ocaron"; +static const char glyph_ocircle[] = "ocircle"; +static const char glyph_ocircumflex[] = "ocircumflex"; +static const char glyph_ocircumflexacute[] = "ocircumflexacute"; +static const char glyph_ocircumflexdotbelow[] = "ocircumflexdotbelow"; +static const char glyph_ocircumflexgrave[] = "ocircumflexgrave"; +static const char glyph_ocircumflexhookabove[] = "ocircumflexhookabove"; +static const char glyph_ocircumflextilde[] = "ocircumflextilde"; +static const char glyph_ocyrillic[] = "ocyrillic"; +static const char glyph_odblacute[] = "odblacute"; +static const char glyph_odblgrave[] = "odblgrave"; +static const char glyph_odeva[] = "odeva"; +static const char glyph_odieresis[] = "odieresis"; +static const char glyph_odieresiscyrillic[] = "odieresiscyrillic"; +static const char glyph_odotbelow[] = "odotbelow"; +static const char glyph_oe[] = "oe"; +static const char glyph_oekorean[] = "oekorean"; +static const char glyph_ogonek[] = "ogonek"; +static const char glyph_ogonekcmb[] = "ogonekcmb"; +static const char glyph_ograve[] = "ograve"; +static const char glyph_ogujarati[] = "ogujarati"; +static const char glyph_oharmenian[] = "oharmenian"; +static const char glyph_ohiragana[] = "ohiragana"; +static const char glyph_ohookabove[] = "ohookabove"; +static const char glyph_ohorn[] = "ohorn"; +static const char glyph_ohornacute[] = "ohornacute"; +static const char glyph_ohorndotbelow[] = "ohorndotbelow"; +static const char glyph_ohorngrave[] = "ohorngrave"; +static const char glyph_ohornhookabove[] = "ohornhookabove"; +static const char glyph_ohorntilde[] = "ohorntilde"; +static const char glyph_ohungarumlaut[] = "ohungarumlaut"; +static const char glyph_oi[] = "oi"; +static const char glyph_oinvertedbreve[] = "oinvertedbreve"; +static const char glyph_okatakana[] = "okatakana"; +static const char glyph_okatakanahalfwidth[] = "okatakanahalfwidth"; +static const char glyph_okorean[] = "okorean"; +static const char glyph_olehebrew[] = "olehebrew"; +static const char glyph_omacron[] = "omacron"; +static const char glyph_omacronacute[] = "omacronacute"; +static const char glyph_omacrongrave[] = "omacrongrave"; +static const char glyph_omdeva[] = "omdeva"; +static const char glyph_omega[] = "omega"; +static const char glyph_omega1[] = "omega1"; +static const char glyph_omegacyrillic[] = "omegacyrillic"; +static const char glyph_omegalatinclosed[] = "omegalatinclosed"; +static const char glyph_omegaroundcyrillic[] = "omegaroundcyrillic"; +static const char glyph_omegatitlocyrillic[] = "omegatitlocyrillic"; +static const char glyph_omegatonos[] = "omegatonos"; +static const char glyph_omgujarati[] = "omgujarati"; +static const char glyph_omicron[] = "omicron"; +static const char glyph_omicrontonos[] = "omicrontonos"; +static const char glyph_omonospace[] = "omonospace"; +static const char glyph_one[] = "one"; +static const char glyph_onearabic[] = "onearabic"; +static const char glyph_onebengali[] = "onebengali"; +static const char glyph_onecircle[] = "onecircle"; +static const char glyph_onecircleinversesansserif[] = +"onecircleinversesansserif"; +static const char glyph_onedeva[] = "onedeva"; +static const char glyph_onedotenleader[] = "onedotenleader"; +static const char glyph_oneeighth[] = "oneeighth"; +static const char glyph_onefitted[] = "onefitted"; +static const char glyph_onegujarati[] = "onegujarati"; +static const char glyph_onegurmukhi[] = "onegurmukhi"; +static const char glyph_onehackarabic[] = "onehackarabic"; +static const char glyph_onehalf[] = "onehalf"; +static const char glyph_onehangzhou[] = "onehangzhou"; +static const char glyph_oneideographicparen[] = "oneideographicparen"; +static const char glyph_oneinferior[] = "oneinferior"; +static const char glyph_onemonospace[] = "onemonospace"; +static const char glyph_onenumeratorbengali[] = "onenumeratorbengali"; +static const char glyph_oneoldstyle[] = "oneoldstyle"; +static const char glyph_oneparen[] = "oneparen"; +static const char glyph_oneperiod[] = "oneperiod"; +static const char glyph_onepersian[] = "onepersian"; +static const char glyph_onequarter[] = "onequarter"; +static const char glyph_oneroman[] = "oneroman"; +static const char glyph_onesuperior[] = "onesuperior"; +static const char glyph_onethai[] = "onethai"; +static const char glyph_onethird[] = "onethird"; +static const char glyph_oogonek[] = "oogonek"; +static const char glyph_oogonekmacron[] = "oogonekmacron"; +static const char glyph_oogurmukhi[] = "oogurmukhi"; +static const char glyph_oomatragurmukhi[] = "oomatragurmukhi"; +static const char glyph_oopen[] = "oopen"; +static const char glyph_oparen[] = "oparen"; +static const char glyph_openbullet[] = "openbullet"; +static const char glyph_option[] = "option"; +static const char glyph_ordfeminine[] = "ordfeminine"; +static const char glyph_ordmasculine[] = "ordmasculine"; +static const char glyph_orthogonal[] = "orthogonal"; +static const char glyph_oshortdeva[] = "oshortdeva"; +static const char glyph_oshortvowelsigndeva[] = "oshortvowelsigndeva"; +static const char glyph_oslash[] = "oslash"; +static const char glyph_oslashacute[] = "oslashacute"; +static const char glyph_osmallhiragana[] = "osmallhiragana"; +static const char glyph_osmallkatakana[] = "osmallkatakana"; +static const char glyph_osmallkatakanahalfwidth[] = "osmallkatakanahalfwidth"; +static const char glyph_ostrokeacute[] = "ostrokeacute"; +static const char glyph_osuperior[] = "osuperior"; +static const char glyph_otcyrillic[] = "otcyrillic"; +static const char glyph_otilde[] = "otilde"; +static const char glyph_otildeacute[] = "otildeacute"; +static const char glyph_otildedieresis[] = "otildedieresis"; +static const char glyph_oubopomofo[] = "oubopomofo"; +static const char glyph_overline[] = "overline"; +static const char glyph_overlinecenterline[] = "overlinecenterline"; +static const char glyph_overlinecmb[] = "overlinecmb"; +static const char glyph_overlinedashed[] = "overlinedashed"; +static const char glyph_overlinedblwavy[] = "overlinedblwavy"; +static const char glyph_overlinewavy[] = "overlinewavy"; +static const char glyph_overscore[] = "overscore"; +static const char glyph_ovowelsignbengali[] = "ovowelsignbengali"; +static const char glyph_ovowelsigndeva[] = "ovowelsigndeva"; +static const char glyph_ovowelsigngujarati[] = "ovowelsigngujarati"; +static const char glyph_p[] = "p"; +static const char glyph_paampssquare[] = "paampssquare"; +static const char glyph_paasentosquare[] = "paasentosquare"; +static const char glyph_pabengali[] = "pabengali"; +static const char glyph_pacute[] = "pacute"; +static const char glyph_padeva[] = "padeva"; +static const char glyph_pagedown[] = "pagedown"; +static const char glyph_pageup[] = "pageup"; +static const char glyph_pagujarati[] = "pagujarati"; +static const char glyph_pagurmukhi[] = "pagurmukhi"; +static const char glyph_pahiragana[] = "pahiragana"; +static const char glyph_paiyannoithai[] = "paiyannoithai"; +static const char glyph_pakatakana[] = "pakatakana"; +static const char glyph_palatalizationcyrilliccmb[] = +"palatalizationcyrilliccmb"; +static const char glyph_palochkacyrillic[] = "palochkacyrillic"; +static const char glyph_pansioskorean[] = "pansioskorean"; +static const char glyph_paragraph[] = "paragraph"; +static const char glyph_parallel[] = "parallel"; +static const char glyph_parenleft[] = "parenleft"; +static const char glyph_parenleftaltonearabic[] = "parenleftaltonearabic"; +static const char glyph_parenleftbt[] = "parenleftbt"; +static const char glyph_parenleftex[] = "parenleftex"; +static const char glyph_parenleftinferior[] = "parenleftinferior"; +static const char glyph_parenleftmonospace[] = "parenleftmonospace"; +static const char glyph_parenleftsmall[] = "parenleftsmall"; +static const char glyph_parenleftsuperior[] = "parenleftsuperior"; +static const char glyph_parenlefttp[] = "parenlefttp"; +static const char glyph_parenleftvertical[] = "parenleftvertical"; +static const char glyph_parenright[] = "parenright"; +static const char glyph_parenrightaltonearabic[] = "parenrightaltonearabic"; +static const char glyph_parenrightbt[] = "parenrightbt"; +static const char glyph_parenrightex[] = "parenrightex"; +static const char glyph_parenrightinferior[] = "parenrightinferior"; +static const char glyph_parenrightmonospace[] = "parenrightmonospace"; +static const char glyph_parenrightsmall[] = "parenrightsmall"; +static const char glyph_parenrightsuperior[] = "parenrightsuperior"; +static const char glyph_parenrighttp[] = "parenrighttp"; +static const char glyph_parenrightvertical[] = "parenrightvertical"; +static const char glyph_partialdiff[] = "partialdiff"; +static const char glyph_paseqhebrew[] = "paseqhebrew"; +static const char glyph_pashtahebrew[] = "pashtahebrew"; +static const char glyph_pasquare[] = "pasquare"; +static const char glyph_patah[] = "patah"; +static const char glyph_patah11[] = "patah11"; +static const char glyph_patah1d[] = "patah1d"; +static const char glyph_patah2a[] = "patah2a"; +static const char glyph_patahhebrew[] = "patahhebrew"; +static const char glyph_patahnarrowhebrew[] = "patahnarrowhebrew"; +static const char glyph_patahquarterhebrew[] = "patahquarterhebrew"; +static const char glyph_patahwidehebrew[] = "patahwidehebrew"; +static const char glyph_pazerhebrew[] = "pazerhebrew"; +static const char glyph_pbopomofo[] = "pbopomofo"; +static const char glyph_pcircle[] = "pcircle"; +static const char glyph_pdotaccent[] = "pdotaccent"; +static const char glyph_pe[] = "pe"; +static const char glyph_pecyrillic[] = "pecyrillic"; +static const char glyph_pedagesh[] = "pedagesh"; +static const char glyph_pedageshhebrew[] = "pedageshhebrew"; +static const char glyph_peezisquare[] = "peezisquare"; +static const char glyph_pefinaldageshhebrew[] = "pefinaldageshhebrew"; +static const char glyph_peharabic[] = "peharabic"; +static const char glyph_peharmenian[] = "peharmenian"; +static const char glyph_pehebrew[] = "pehebrew"; +static const char glyph_pehfinalarabic[] = "pehfinalarabic"; +static const char glyph_pehinitialarabic[] = "pehinitialarabic"; +static const char glyph_pehiragana[] = "pehiragana"; +static const char glyph_pehmedialarabic[] = "pehmedialarabic"; +static const char glyph_pekatakana[] = "pekatakana"; +static const char glyph_pemiddlehookcyrillic[] = "pemiddlehookcyrillic"; +static const char glyph_perafehebrew[] = "perafehebrew"; +static const char glyph_percent[] = "percent"; +static const char glyph_percentarabic[] = "percentarabic"; +static const char glyph_percentmonospace[] = "percentmonospace"; +static const char glyph_percentsmall[] = "percentsmall"; +static const char glyph_period[] = "period"; +static const char glyph_periodarmenian[] = "periodarmenian"; +static const char glyph_periodcentered[] = "periodcentered"; +static const char glyph_periodhalfwidth[] = "periodhalfwidth"; +static const char glyph_periodinferior[] = "periodinferior"; +static const char glyph_periodmonospace[] = "periodmonospace"; +static const char glyph_periodsmall[] = "periodsmall"; +static const char glyph_periodsuperior[] = "periodsuperior"; +static const char glyph_perispomenigreekcmb[] = "perispomenigreekcmb"; +static const char glyph_perpendicular[] = "perpendicular"; +static const char glyph_perthousand[] = "perthousand"; +static const char glyph_peseta[] = "peseta"; +static const char glyph_pfsquare[] = "pfsquare"; +static const char glyph_phabengali[] = "phabengali"; +static const char glyph_phadeva[] = "phadeva"; +static const char glyph_phagujarati[] = "phagujarati"; +static const char glyph_phagurmukhi[] = "phagurmukhi"; +static const char glyph_phi[] = "phi"; +static const char glyph_phi1[] = "phi1"; +static const char glyph_phieuphacirclekorean[] = "phieuphacirclekorean"; +static const char glyph_phieuphaparenkorean[] = "phieuphaparenkorean"; +static const char glyph_phieuphcirclekorean[] = "phieuphcirclekorean"; +static const char glyph_phieuphkorean[] = "phieuphkorean"; +static const char glyph_phieuphparenkorean[] = "phieuphparenkorean"; +static const char glyph_philatin[] = "philatin"; +static const char glyph_phinthuthai[] = "phinthuthai"; +static const char glyph_phisymbolgreek[] = "phisymbolgreek"; +static const char glyph_phook[] = "phook"; +static const char glyph_phophanthai[] = "phophanthai"; +static const char glyph_phophungthai[] = "phophungthai"; +static const char glyph_phosamphaothai[] = "phosamphaothai"; +static const char glyph_pi[] = "pi"; +static const char glyph_pieupacirclekorean[] = "pieupacirclekorean"; +static const char glyph_pieupaparenkorean[] = "pieupaparenkorean"; +static const char glyph_pieupcieuckorean[] = "pieupcieuckorean"; +static const char glyph_pieupcirclekorean[] = "pieupcirclekorean"; +static const char glyph_pieupkiyeokkorean[] = "pieupkiyeokkorean"; +static const char glyph_pieupkorean[] = "pieupkorean"; +static const char glyph_pieupparenkorean[] = "pieupparenkorean"; +static const char glyph_pieupsioskiyeokkorean[] = "pieupsioskiyeokkorean"; +static const char glyph_pieupsioskorean[] = "pieupsioskorean"; +static const char glyph_pieupsiostikeutkorean[] = "pieupsiostikeutkorean"; +static const char glyph_pieupthieuthkorean[] = "pieupthieuthkorean"; +static const char glyph_pieuptikeutkorean[] = "pieuptikeutkorean"; +static const char glyph_pihiragana[] = "pihiragana"; +static const char glyph_pikatakana[] = "pikatakana"; +static const char glyph_pisymbolgreek[] = "pisymbolgreek"; +static const char glyph_piwrarmenian[] = "piwrarmenian"; +static const char glyph_plus[] = "plus"; +static const char glyph_plusbelowcmb[] = "plusbelowcmb"; +static const char glyph_pluscircle[] = "pluscircle"; +static const char glyph_plusminus[] = "plusminus"; +static const char glyph_plusmod[] = "plusmod"; +static const char glyph_plusmonospace[] = "plusmonospace"; +static const char glyph_plussmall[] = "plussmall"; +static const char glyph_plussuperior[] = "plussuperior"; +static const char glyph_pmonospace[] = "pmonospace"; +static const char glyph_pmsquare[] = "pmsquare"; +static const char glyph_pohiragana[] = "pohiragana"; +static const char glyph_pointingindexdownwhite[] = "pointingindexdownwhite"; +static const char glyph_pointingindexleftwhite[] = "pointingindexleftwhite"; +static const char glyph_pointingindexrightwhite[] = "pointingindexrightwhite"; +static const char glyph_pointingindexupwhite[] = "pointingindexupwhite"; +static const char glyph_pokatakana[] = "pokatakana"; +static const char glyph_poplathai[] = "poplathai"; +static const char glyph_postalmark[] = "postalmark"; +static const char glyph_postalmarkface[] = "postalmarkface"; +static const char glyph_pparen[] = "pparen"; +static const char glyph_precedes[] = "precedes"; +static const char glyph_prescription[] = "prescription"; +static const char glyph_primemod[] = "primemod"; +static const char glyph_primereversed[] = "primereversed"; +static const char glyph_product[] = "product"; +static const char glyph_projective[] = "projective"; +static const char glyph_prolongedkana[] = "prolongedkana"; +static const char glyph_propellor[] = "propellor"; +static const char glyph_propersubset[] = "propersubset"; +static const char glyph_propersuperset[] = "propersuperset"; +static const char glyph_proportion[] = "proportion"; +static const char glyph_proportional[] = "proportional"; +static const char glyph_psi[] = "psi"; +static const char glyph_psicyrillic[] = "psicyrillic"; +static const char glyph_psilipneumatacyrilliccmb[] = +"psilipneumatacyrilliccmb"; +static const char glyph_pssquare[] = "pssquare"; +static const char glyph_puhiragana[] = "puhiragana"; +static const char glyph_pukatakana[] = "pukatakana"; +static const char glyph_pvsquare[] = "pvsquare"; +static const char glyph_pwsquare[] = "pwsquare"; +static const char glyph_q[] = "q"; +static const char glyph_qadeva[] = "qadeva"; +static const char glyph_qadmahebrew[] = "qadmahebrew"; +static const char glyph_qafarabic[] = "qafarabic"; +static const char glyph_qaffinalarabic[] = "qaffinalarabic"; +static const char glyph_qafinitialarabic[] = "qafinitialarabic"; +static const char glyph_qafmedialarabic[] = "qafmedialarabic"; +static const char glyph_qamats[] = "qamats"; +static const char glyph_qamats10[] = "qamats10"; +static const char glyph_qamats1a[] = "qamats1a"; +static const char glyph_qamats1c[] = "qamats1c"; +static const char glyph_qamats27[] = "qamats27"; +static const char glyph_qamats29[] = "qamats29"; +static const char glyph_qamats33[] = "qamats33"; +static const char glyph_qamatsde[] = "qamatsde"; +static const char glyph_qamatshebrew[] = "qamatshebrew"; +static const char glyph_qamatsnarrowhebrew[] = "qamatsnarrowhebrew"; +static const char glyph_qamatsqatanhebrew[] = "qamatsqatanhebrew"; +static const char glyph_qamatsqatannarrowhebrew[] = "qamatsqatannarrowhebrew"; +static const char glyph_qamatsqatanquarterhebrew[] = +"qamatsqatanquarterhebrew"; +static const char glyph_qamatsqatanwidehebrew[] = "qamatsqatanwidehebrew"; +static const char glyph_qamatsquarterhebrew[] = "qamatsquarterhebrew"; +static const char glyph_qamatswidehebrew[] = "qamatswidehebrew"; +static const char glyph_qarneyparahebrew[] = "qarneyparahebrew"; +static const char glyph_qbopomofo[] = "qbopomofo"; +static const char glyph_qcircle[] = "qcircle"; +static const char glyph_qhook[] = "qhook"; +static const char glyph_qmonospace[] = "qmonospace"; +static const char glyph_qof[] = "qof"; +static const char glyph_qofdagesh[] = "qofdagesh"; +static const char glyph_qofdageshhebrew[] = "qofdageshhebrew"; +static const char glyph_qofhatafpatah[] = "qofhatafpatah"; +static const char glyph_qofhatafpatahhebrew[] = "qofhatafpatahhebrew"; +static const char glyph_qofhatafsegol[] = "qofhatafsegol"; +static const char glyph_qofhatafsegolhebrew[] = "qofhatafsegolhebrew"; +static const char glyph_qofhebrew[] = "qofhebrew"; +static const char glyph_qofhiriq[] = "qofhiriq"; +static const char glyph_qofhiriqhebrew[] = "qofhiriqhebrew"; +static const char glyph_qofholam[] = "qofholam"; +static const char glyph_qofholamhebrew[] = "qofholamhebrew"; +static const char glyph_qofpatah[] = "qofpatah"; +static const char glyph_qofpatahhebrew[] = "qofpatahhebrew"; +static const char glyph_qofqamats[] = "qofqamats"; +static const char glyph_qofqamatshebrew[] = "qofqamatshebrew"; +static const char glyph_qofqubuts[] = "qofqubuts"; +static const char glyph_qofqubutshebrew[] = "qofqubutshebrew"; +static const char glyph_qofsegol[] = "qofsegol"; +static const char glyph_qofsegolhebrew[] = "qofsegolhebrew"; +static const char glyph_qofsheva[] = "qofsheva"; +static const char glyph_qofshevahebrew[] = "qofshevahebrew"; +static const char glyph_qoftsere[] = "qoftsere"; +static const char glyph_qoftserehebrew[] = "qoftserehebrew"; +static const char glyph_qparen[] = "qparen"; +static const char glyph_quarternote[] = "quarternote"; +static const char glyph_qubuts[] = "qubuts"; +static const char glyph_qubuts18[] = "qubuts18"; +static const char glyph_qubuts25[] = "qubuts25"; +static const char glyph_qubuts31[] = "qubuts31"; +static const char glyph_qubutshebrew[] = "qubutshebrew"; +static const char glyph_qubutsnarrowhebrew[] = "qubutsnarrowhebrew"; +static const char glyph_qubutsquarterhebrew[] = "qubutsquarterhebrew"; +static const char glyph_qubutswidehebrew[] = "qubutswidehebrew"; +static const char glyph_question[] = "question"; +static const char glyph_questionarabic[] = "questionarabic"; +static const char glyph_questionarmenian[] = "questionarmenian"; +static const char glyph_questiondown[] = "questiondown"; +static const char glyph_questiondownsmall[] = "questiondownsmall"; +static const char glyph_questiongreek[] = "questiongreek"; +static const char glyph_questionmonospace[] = "questionmonospace"; +static const char glyph_questionsmall[] = "questionsmall"; +static const char glyph_quotedbl[] = "quotedbl"; +static const char glyph_quotedblbase[] = "quotedblbase"; +static const char glyph_quotedblleft[] = "quotedblleft"; +static const char glyph_quotedblmonospace[] = "quotedblmonospace"; +static const char glyph_quotedblprime[] = "quotedblprime"; +static const char glyph_quotedblprimereversed[] = "quotedblprimereversed"; +static const char glyph_quotedblright[] = "quotedblright"; +static const char glyph_quoteleft[] = "quoteleft"; +static const char glyph_quoteleftreversed[] = "quoteleftreversed"; +static const char glyph_quotereversed[] = "quotereversed"; +static const char glyph_quoteright[] = "quoteright"; +static const char glyph_quoterightn[] = "quoterightn"; +static const char glyph_quotesinglbase[] = "quotesinglbase"; +static const char glyph_quotesingle[] = "quotesingle"; +static const char glyph_quotesinglemonospace[] = "quotesinglemonospace"; +static const char glyph_r[] = "r"; +static const char glyph_raarmenian[] = "raarmenian"; +static const char glyph_rabengali[] = "rabengali"; +static const char glyph_racute[] = "racute"; +static const char glyph_radeva[] = "radeva"; +static const char glyph_radical[] = "radical"; +static const char glyph_radicalex[] = "radicalex"; +static const char glyph_radoverssquare[] = "radoverssquare"; +static const char glyph_radoverssquaredsquare[] = "radoverssquaredsquare"; +static const char glyph_radsquare[] = "radsquare"; +static const char glyph_rafe[] = "rafe"; +static const char glyph_rafehebrew[] = "rafehebrew"; +static const char glyph_ragujarati[] = "ragujarati"; +static const char glyph_ragurmukhi[] = "ragurmukhi"; +static const char glyph_rahiragana[] = "rahiragana"; +static const char glyph_rakatakana[] = "rakatakana"; +static const char glyph_rakatakanahalfwidth[] = "rakatakanahalfwidth"; +static const char glyph_ralowerdiagonalbengali[] = "ralowerdiagonalbengali"; +static const char glyph_ramiddlediagonalbengali[] = "ramiddlediagonalbengali"; +static const char glyph_ramshorn[] = "ramshorn"; +static const char glyph_ratio[] = "ratio"; +static const char glyph_rbopomofo[] = "rbopomofo"; +static const char glyph_rcaron[] = "rcaron"; +static const char glyph_rcedilla[] = "rcedilla"; +static const char glyph_rcircle[] = "rcircle"; +static const char glyph_rcommaaccent[] = "rcommaaccent"; +static const char glyph_rdblgrave[] = "rdblgrave"; +static const char glyph_rdotaccent[] = "rdotaccent"; +static const char glyph_rdotbelow[] = "rdotbelow"; +static const char glyph_rdotbelowmacron[] = "rdotbelowmacron"; +static const char glyph_referencemark[] = "referencemark"; +static const char glyph_reflexsubset[] = "reflexsubset"; +static const char glyph_reflexsuperset[] = "reflexsuperset"; +static const char glyph_registered[] = "registered"; +static const char glyph_registersans[] = "registersans"; +static const char glyph_registerserif[] = "registerserif"; +static const char glyph_reharabic[] = "reharabic"; +static const char glyph_reharmenian[] = "reharmenian"; +static const char glyph_rehfinalarabic[] = "rehfinalarabic"; +static const char glyph_rehiragana[] = "rehiragana"; +static const char glyph_rehyehaleflamarabic[] = "rehyehaleflamarabic"; +static const char glyph_rekatakana[] = "rekatakana"; +static const char glyph_rekatakanahalfwidth[] = "rekatakanahalfwidth"; +static const char glyph_resh[] = "resh"; +static const char glyph_reshdageshhebrew[] = "reshdageshhebrew"; +static const char glyph_reshhatafpatah[] = "reshhatafpatah"; +static const char glyph_reshhatafpatahhebrew[] = "reshhatafpatahhebrew"; +static const char glyph_reshhatafsegol[] = "reshhatafsegol"; +static const char glyph_reshhatafsegolhebrew[] = "reshhatafsegolhebrew"; +static const char glyph_reshhebrew[] = "reshhebrew"; +static const char glyph_reshhiriq[] = "reshhiriq"; +static const char glyph_reshhiriqhebrew[] = "reshhiriqhebrew"; +static const char glyph_reshholam[] = "reshholam"; +static const char glyph_reshholamhebrew[] = "reshholamhebrew"; +static const char glyph_reshpatah[] = "reshpatah"; +static const char glyph_reshpatahhebrew[] = "reshpatahhebrew"; +static const char glyph_reshqamats[] = "reshqamats"; +static const char glyph_reshqamatshebrew[] = "reshqamatshebrew"; +static const char glyph_reshqubuts[] = "reshqubuts"; +static const char glyph_reshqubutshebrew[] = "reshqubutshebrew"; +static const char glyph_reshsegol[] = "reshsegol"; +static const char glyph_reshsegolhebrew[] = "reshsegolhebrew"; +static const char glyph_reshsheva[] = "reshsheva"; +static const char glyph_reshshevahebrew[] = "reshshevahebrew"; +static const char glyph_reshtsere[] = "reshtsere"; +static const char glyph_reshtserehebrew[] = "reshtserehebrew"; +static const char glyph_reversedtilde[] = "reversedtilde"; +static const char glyph_reviahebrew[] = "reviahebrew"; +static const char glyph_reviamugrashhebrew[] = "reviamugrashhebrew"; +static const char glyph_revlogicalnot[] = "revlogicalnot"; +static const char glyph_rfishhook[] = "rfishhook"; +static const char glyph_rfishhookreversed[] = "rfishhookreversed"; +static const char glyph_rhabengali[] = "rhabengali"; +static const char glyph_rhadeva[] = "rhadeva"; +static const char glyph_rho[] = "rho"; +static const char glyph_rhook[] = "rhook"; +static const char glyph_rhookturned[] = "rhookturned"; +static const char glyph_rhookturnedsuperior[] = "rhookturnedsuperior"; +static const char glyph_rhosymbolgreek[] = "rhosymbolgreek"; +static const char glyph_rhotichookmod[] = "rhotichookmod"; +static const char glyph_rieulacirclekorean[] = "rieulacirclekorean"; +static const char glyph_rieulaparenkorean[] = "rieulaparenkorean"; +static const char glyph_rieulcirclekorean[] = "rieulcirclekorean"; +static const char glyph_rieulhieuhkorean[] = "rieulhieuhkorean"; +static const char glyph_rieulkiyeokkorean[] = "rieulkiyeokkorean"; +static const char glyph_rieulkiyeoksioskorean[] = "rieulkiyeoksioskorean"; +static const char glyph_rieulkorean[] = "rieulkorean"; +static const char glyph_rieulmieumkorean[] = "rieulmieumkorean"; +static const char glyph_rieulpansioskorean[] = "rieulpansioskorean"; +static const char glyph_rieulparenkorean[] = "rieulparenkorean"; +static const char glyph_rieulphieuphkorean[] = "rieulphieuphkorean"; +static const char glyph_rieulpieupkorean[] = "rieulpieupkorean"; +static const char glyph_rieulpieupsioskorean[] = "rieulpieupsioskorean"; +static const char glyph_rieulsioskorean[] = "rieulsioskorean"; +static const char glyph_rieulthieuthkorean[] = "rieulthieuthkorean"; +static const char glyph_rieultikeutkorean[] = "rieultikeutkorean"; +static const char glyph_rieulyeorinhieuhkorean[] = "rieulyeorinhieuhkorean"; +static const char glyph_rightangle[] = "rightangle"; +static const char glyph_righttackbelowcmb[] = "righttackbelowcmb"; +static const char glyph_righttriangle[] = "righttriangle"; +static const char glyph_rihiragana[] = "rihiragana"; +static const char glyph_rikatakana[] = "rikatakana"; +static const char glyph_rikatakanahalfwidth[] = "rikatakanahalfwidth"; +static const char glyph_ring[] = "ring"; +static const char glyph_ringbelowcmb[] = "ringbelowcmb"; +static const char glyph_ringcmb[] = "ringcmb"; +static const char glyph_ringhalfleft[] = "ringhalfleft"; +static const char glyph_ringhalfleftarmenian[] = "ringhalfleftarmenian"; +static const char glyph_ringhalfleftbelowcmb[] = "ringhalfleftbelowcmb"; +static const char glyph_ringhalfleftcentered[] = "ringhalfleftcentered"; +static const char glyph_ringhalfright[] = "ringhalfright"; +static const char glyph_ringhalfrightbelowcmb[] = "ringhalfrightbelowcmb"; +static const char glyph_ringhalfrightcentered[] = "ringhalfrightcentered"; +static const char glyph_rinvertedbreve[] = "rinvertedbreve"; +static const char glyph_rittorusquare[] = "rittorusquare"; +static const char glyph_rlinebelow[] = "rlinebelow"; +static const char glyph_rlongleg[] = "rlongleg"; +static const char glyph_rlonglegturned[] = "rlonglegturned"; +static const char glyph_rmonospace[] = "rmonospace"; +static const char glyph_rohiragana[] = "rohiragana"; +static const char glyph_rokatakana[] = "rokatakana"; +static const char glyph_rokatakanahalfwidth[] = "rokatakanahalfwidth"; +static const char glyph_roruathai[] = "roruathai"; +static const char glyph_rparen[] = "rparen"; +static const char glyph_rrabengali[] = "rrabengali"; +static const char glyph_rradeva[] = "rradeva"; +static const char glyph_rragurmukhi[] = "rragurmukhi"; +static const char glyph_rreharabic[] = "rreharabic"; +static const char glyph_rrehfinalarabic[] = "rrehfinalarabic"; +static const char glyph_rrvocalicbengali[] = "rrvocalicbengali"; +static const char glyph_rrvocalicdeva[] = "rrvocalicdeva"; +static const char glyph_rrvocalicgujarati[] = "rrvocalicgujarati"; +static const char glyph_rrvocalicvowelsignbengali[] = +"rrvocalicvowelsignbengali"; +static const char glyph_rrvocalicvowelsigndeva[] = "rrvocalicvowelsigndeva"; +static const char glyph_rrvocalicvowelsigngujarati[] = +"rrvocalicvowelsigngujarati"; +static const char glyph_rsuperior[] = "rsuperior"; +static const char glyph_rtblock[] = "rtblock"; +static const char glyph_rturned[] = "rturned"; +static const char glyph_rturnedsuperior[] = "rturnedsuperior"; +static const char glyph_ruhiragana[] = "ruhiragana"; +static const char glyph_rukatakana[] = "rukatakana"; +static const char glyph_rukatakanahalfwidth[] = "rukatakanahalfwidth"; +static const char glyph_rupeemarkbengali[] = "rupeemarkbengali"; +static const char glyph_rupeesignbengali[] = "rupeesignbengali"; +static const char glyph_rupiah[] = "rupiah"; +static const char glyph_ruthai[] = "ruthai"; +static const char glyph_rvocalicbengali[] = "rvocalicbengali"; +static const char glyph_rvocalicdeva[] = "rvocalicdeva"; +static const char glyph_rvocalicgujarati[] = "rvocalicgujarati"; +static const char glyph_rvocalicvowelsignbengali[] = +"rvocalicvowelsignbengali"; +static const char glyph_rvocalicvowelsigndeva[] = "rvocalicvowelsigndeva"; +static const char glyph_rvocalicvowelsigngujarati[] = +"rvocalicvowelsigngujarati"; +static const char glyph_s[] = "s"; +static const char glyph_sabengali[] = "sabengali"; +static const char glyph_sacute[] = "sacute"; +static const char glyph_sacutedotaccent[] = "sacutedotaccent"; +static const char glyph_sadarabic[] = "sadarabic"; +static const char glyph_sadeva[] = "sadeva"; +static const char glyph_sadfinalarabic[] = "sadfinalarabic"; +static const char glyph_sadinitialarabic[] = "sadinitialarabic"; +static const char glyph_sadmedialarabic[] = "sadmedialarabic"; +static const char glyph_sagujarati[] = "sagujarati"; +static const char glyph_sagurmukhi[] = "sagurmukhi"; +static const char glyph_sahiragana[] = "sahiragana"; +static const char glyph_sakatakana[] = "sakatakana"; +static const char glyph_sakatakanahalfwidth[] = "sakatakanahalfwidth"; +static const char glyph_sallallahoualayhewasallamarabic[] = +"sallallahoualayhewasallamarabic"; +static const char glyph_samekh[] = "samekh"; +static const char glyph_samekhdagesh[] = "samekhdagesh"; +static const char glyph_samekhdageshhebrew[] = "samekhdageshhebrew"; +static const char glyph_samekhhebrew[] = "samekhhebrew"; +static const char glyph_saraaathai[] = "saraaathai"; +static const char glyph_saraaethai[] = "saraaethai"; +static const char glyph_saraaimaimalaithai[] = "saraaimaimalaithai"; +static const char glyph_saraaimaimuanthai[] = "saraaimaimuanthai"; +static const char glyph_saraamthai[] = "saraamthai"; +static const char glyph_saraathai[] = "saraathai"; +static const char glyph_saraethai[] = "saraethai"; +static const char glyph_saraiileftthai[] = "saraiileftthai"; +static const char glyph_saraiithai[] = "saraiithai"; +static const char glyph_saraileftthai[] = "saraileftthai"; +static const char glyph_saraithai[] = "saraithai"; +static const char glyph_saraothai[] = "saraothai"; +static const char glyph_saraueeleftthai[] = "saraueeleftthai"; +static const char glyph_saraueethai[] = "saraueethai"; +static const char glyph_saraueleftthai[] = "saraueleftthai"; +static const char glyph_sarauethai[] = "sarauethai"; +static const char glyph_sarauthai[] = "sarauthai"; +static const char glyph_sarauuthai[] = "sarauuthai"; +static const char glyph_sbopomofo[] = "sbopomofo"; +static const char glyph_scaron[] = "scaron"; +static const char glyph_scarondotaccent[] = "scarondotaccent"; +static const char glyph_scedilla[] = "scedilla"; +static const char glyph_schwa[] = "schwa"; +static const char glyph_schwacyrillic[] = "schwacyrillic"; +static const char glyph_schwadieresiscyrillic[] = "schwadieresiscyrillic"; +static const char glyph_schwahook[] = "schwahook"; +static const char glyph_scircle[] = "scircle"; +static const char glyph_scircumflex[] = "scircumflex"; +static const char glyph_scommaaccent[] = "scommaaccent"; +static const char glyph_sdotaccent[] = "sdotaccent"; +static const char glyph_sdotbelow[] = "sdotbelow"; +static const char glyph_sdotbelowdotaccent[] = "sdotbelowdotaccent"; +static const char glyph_seagullbelowcmb[] = "seagullbelowcmb"; +static const char glyph_second[] = "second"; +static const char glyph_secondtonechinese[] = "secondtonechinese"; +static const char glyph_section[] = "section"; +static const char glyph_seenarabic[] = "seenarabic"; +static const char glyph_seenfinalarabic[] = "seenfinalarabic"; +static const char glyph_seeninitialarabic[] = "seeninitialarabic"; +static const char glyph_seenmedialarabic[] = "seenmedialarabic"; +static const char glyph_segol[] = "segol"; +static const char glyph_segol13[] = "segol13"; +static const char glyph_segol1f[] = "segol1f"; +static const char glyph_segol2c[] = "segol2c"; +static const char glyph_segolhebrew[] = "segolhebrew"; +static const char glyph_segolnarrowhebrew[] = "segolnarrowhebrew"; +static const char glyph_segolquarterhebrew[] = "segolquarterhebrew"; +static const char glyph_segoltahebrew[] = "segoltahebrew"; +static const char glyph_segolwidehebrew[] = "segolwidehebrew"; +static const char glyph_seharmenian[] = "seharmenian"; +static const char glyph_sehiragana[] = "sehiragana"; +static const char glyph_sekatakana[] = "sekatakana"; +static const char glyph_sekatakanahalfwidth[] = "sekatakanahalfwidth"; +static const char glyph_semicolon[] = "semicolon"; +static const char glyph_semicolonarabic[] = "semicolonarabic"; +static const char glyph_semicolonmonospace[] = "semicolonmonospace"; +static const char glyph_semicolonsmall[] = "semicolonsmall"; +static const char glyph_semivoicedmarkkana[] = "semivoicedmarkkana"; +static const char glyph_semivoicedmarkkanahalfwidth[] = +"semivoicedmarkkanahalfwidth"; +static const char glyph_sentisquare[] = "sentisquare"; +static const char glyph_sentosquare[] = "sentosquare"; +static const char glyph_seven[] = "seven"; +static const char glyph_sevenarabic[] = "sevenarabic"; +static const char glyph_sevenbengali[] = "sevenbengali"; +static const char glyph_sevencircle[] = "sevencircle"; +static const char glyph_sevencircleinversesansserif[] = +"sevencircleinversesansserif"; +static const char glyph_sevendeva[] = "sevendeva"; +static const char glyph_seveneighths[] = "seveneighths"; +static const char glyph_sevengujarati[] = "sevengujarati"; +static const char glyph_sevengurmukhi[] = "sevengurmukhi"; +static const char glyph_sevenhackarabic[] = "sevenhackarabic"; +static const char glyph_sevenhangzhou[] = "sevenhangzhou"; +static const char glyph_sevenideographicparen[] = "sevenideographicparen"; +static const char glyph_seveninferior[] = "seveninferior"; +static const char glyph_sevenmonospace[] = "sevenmonospace"; +static const char glyph_sevenoldstyle[] = "sevenoldstyle"; +static const char glyph_sevenparen[] = "sevenparen"; +static const char glyph_sevenperiod[] = "sevenperiod"; +static const char glyph_sevenpersian[] = "sevenpersian"; +static const char glyph_sevenroman[] = "sevenroman"; +static const char glyph_sevensuperior[] = "sevensuperior"; +static const char glyph_seventeencircle[] = "seventeencircle"; +static const char glyph_seventeenparen[] = "seventeenparen"; +static const char glyph_seventeenperiod[] = "seventeenperiod"; +static const char glyph_seventhai[] = "seventhai"; +static const char glyph_sfthyphen[] = "sfthyphen"; +static const char glyph_shaarmenian[] = "shaarmenian"; +static const char glyph_shabengali[] = "shabengali"; +static const char glyph_shacyrillic[] = "shacyrillic"; +static const char glyph_shaddaarabic[] = "shaddaarabic"; +static const char glyph_shaddadammaarabic[] = "shaddadammaarabic"; +static const char glyph_shaddadammatanarabic[] = "shaddadammatanarabic"; +static const char glyph_shaddafathaarabic[] = "shaddafathaarabic"; +static const char glyph_shaddafathatanarabic[] = "shaddafathatanarabic"; +static const char glyph_shaddakasraarabic[] = "shaddakasraarabic"; +static const char glyph_shaddakasratanarabic[] = "shaddakasratanarabic"; +static const char glyph_shade[] = "shade"; +static const char glyph_shadedark[] = "shadedark"; +static const char glyph_shadelight[] = "shadelight"; +static const char glyph_shademedium[] = "shademedium"; +static const char glyph_shadeva[] = "shadeva"; +static const char glyph_shagujarati[] = "shagujarati"; +static const char glyph_shagurmukhi[] = "shagurmukhi"; +static const char glyph_shalshelethebrew[] = "shalshelethebrew"; +static const char glyph_shbopomofo[] = "shbopomofo"; +static const char glyph_shchacyrillic[] = "shchacyrillic"; +static const char glyph_sheenarabic[] = "sheenarabic"; +static const char glyph_sheenfinalarabic[] = "sheenfinalarabic"; +static const char glyph_sheeninitialarabic[] = "sheeninitialarabic"; +static const char glyph_sheenmedialarabic[] = "sheenmedialarabic"; +static const char glyph_sheicoptic[] = "sheicoptic"; +static const char glyph_sheqel[] = "sheqel"; +static const char glyph_sheqelhebrew[] = "sheqelhebrew"; +static const char glyph_sheva[] = "sheva"; +static const char glyph_sheva115[] = "sheva115"; +static const char glyph_sheva15[] = "sheva15"; +static const char glyph_sheva22[] = "sheva22"; +static const char glyph_sheva2e[] = "sheva2e"; +static const char glyph_shevahebrew[] = "shevahebrew"; +static const char glyph_shevanarrowhebrew[] = "shevanarrowhebrew"; +static const char glyph_shevaquarterhebrew[] = "shevaquarterhebrew"; +static const char glyph_shevawidehebrew[] = "shevawidehebrew"; +static const char glyph_shhacyrillic[] = "shhacyrillic"; +static const char glyph_shimacoptic[] = "shimacoptic"; +static const char glyph_shin[] = "shin"; +static const char glyph_shindagesh[] = "shindagesh"; +static const char glyph_shindageshhebrew[] = "shindageshhebrew"; +static const char glyph_shindageshshindot[] = "shindageshshindot"; +static const char glyph_shindageshshindothebrew[] = "shindageshshindothebrew"; +static const char glyph_shindageshsindot[] = "shindageshsindot"; +static const char glyph_shindageshsindothebrew[] = "shindageshsindothebrew"; +static const char glyph_shindothebrew[] = "shindothebrew"; +static const char glyph_shinhebrew[] = "shinhebrew"; +static const char glyph_shinshindot[] = "shinshindot"; +static const char glyph_shinshindothebrew[] = "shinshindothebrew"; +static const char glyph_shinsindot[] = "shinsindot"; +static const char glyph_shinsindothebrew[] = "shinsindothebrew"; +static const char glyph_shook[] = "shook"; +static const char glyph_sigma[] = "sigma"; +static const char glyph_sigma1[] = "sigma1"; +static const char glyph_sigmafinal[] = "sigmafinal"; +static const char glyph_sigmalunatesymbolgreek[] = "sigmalunatesymbolgreek"; +static const char glyph_sihiragana[] = "sihiragana"; +static const char glyph_sikatakana[] = "sikatakana"; +static const char glyph_sikatakanahalfwidth[] = "sikatakanahalfwidth"; +static const char glyph_siluqhebrew[] = "siluqhebrew"; +static const char glyph_siluqlefthebrew[] = "siluqlefthebrew"; +static const char glyph_similar[] = "similar"; +static const char glyph_sindothebrew[] = "sindothebrew"; +static const char glyph_siosacirclekorean[] = "siosacirclekorean"; +static const char glyph_siosaparenkorean[] = "siosaparenkorean"; +static const char glyph_sioscieuckorean[] = "sioscieuckorean"; +static const char glyph_sioscirclekorean[] = "sioscirclekorean"; +static const char glyph_sioskiyeokkorean[] = "sioskiyeokkorean"; +static const char glyph_sioskorean[] = "sioskorean"; +static const char glyph_siosnieunkorean[] = "siosnieunkorean"; +static const char glyph_siosparenkorean[] = "siosparenkorean"; +static const char glyph_siospieupkorean[] = "siospieupkorean"; +static const char glyph_siostikeutkorean[] = "siostikeutkorean"; +static const char glyph_six[] = "six"; +static const char glyph_sixarabic[] = "sixarabic"; +static const char glyph_sixbengali[] = "sixbengali"; +static const char glyph_sixcircle[] = "sixcircle"; +static const char glyph_sixcircleinversesansserif[] = +"sixcircleinversesansserif"; +static const char glyph_sixdeva[] = "sixdeva"; +static const char glyph_sixgujarati[] = "sixgujarati"; +static const char glyph_sixgurmukhi[] = "sixgurmukhi"; +static const char glyph_sixhackarabic[] = "sixhackarabic"; +static const char glyph_sixhangzhou[] = "sixhangzhou"; +static const char glyph_sixideographicparen[] = "sixideographicparen"; +static const char glyph_sixinferior[] = "sixinferior"; +static const char glyph_sixmonospace[] = "sixmonospace"; +static const char glyph_sixoldstyle[] = "sixoldstyle"; +static const char glyph_sixparen[] = "sixparen"; +static const char glyph_sixperiod[] = "sixperiod"; +static const char glyph_sixpersian[] = "sixpersian"; +static const char glyph_sixroman[] = "sixroman"; +static const char glyph_sixsuperior[] = "sixsuperior"; +static const char glyph_sixteencircle[] = "sixteencircle"; +static const char glyph_sixteencurrencydenominatorbengali[] = +"sixteencurrencydenominatorbengali"; +static const char glyph_sixteenparen[] = "sixteenparen"; +static const char glyph_sixteenperiod[] = "sixteenperiod"; +static const char glyph_sixthai[] = "sixthai"; +static const char glyph_slash[] = "slash"; +static const char glyph_slashmonospace[] = "slashmonospace"; +static const char glyph_slong[] = "slong"; +static const char glyph_slongdotaccent[] = "slongdotaccent"; +static const char glyph_smileface[] = "smileface"; +static const char glyph_smonospace[] = "smonospace"; +static const char glyph_sofpasuqhebrew[] = "sofpasuqhebrew"; +static const char glyph_softhyphen[] = "softhyphen"; +static const char glyph_softsigncyrillic[] = "softsigncyrillic"; +static const char glyph_sohiragana[] = "sohiragana"; +static const char glyph_sokatakana[] = "sokatakana"; +static const char glyph_sokatakanahalfwidth[] = "sokatakanahalfwidth"; +static const char glyph_soliduslongoverlaycmb[] = "soliduslongoverlaycmb"; +static const char glyph_solidusshortoverlaycmb[] = "solidusshortoverlaycmb"; +static const char glyph_sorusithai[] = "sorusithai"; +static const char glyph_sosalathai[] = "sosalathai"; +static const char glyph_sosothai[] = "sosothai"; +static const char glyph_sosuathai[] = "sosuathai"; +static const char glyph_space[] = "space"; +static const char glyph_spacehackarabic[] = "spacehackarabic"; +static const char glyph_spade[] = "spade"; +static const char glyph_spadesuitblack[] = "spadesuitblack"; +static const char glyph_spadesuitwhite[] = "spadesuitwhite"; +static const char glyph_sparen[] = "sparen"; +static const char glyph_squarebelowcmb[] = "squarebelowcmb"; +static const char glyph_squarecc[] = "squarecc"; +static const char glyph_squarecm[] = "squarecm"; +static const char glyph_squarediagonalcrosshatchfill[] = +"squarediagonalcrosshatchfill"; +static const char glyph_squarehorizontalfill[] = "squarehorizontalfill"; +static const char glyph_squarekg[] = "squarekg"; +static const char glyph_squarekm[] = "squarekm"; +static const char glyph_squarekmcapital[] = "squarekmcapital"; +static const char glyph_squareln[] = "squareln"; +static const char glyph_squarelog[] = "squarelog"; +static const char glyph_squaremg[] = "squaremg"; +static const char glyph_squaremil[] = "squaremil"; +static const char glyph_squaremm[] = "squaremm"; +static const char glyph_squaremsquared[] = "squaremsquared"; +static const char glyph_squareorthogonalcrosshatchfill[] = +"squareorthogonalcrosshatchfill"; +static const char glyph_squareupperlefttolowerrightfill[] = +"squareupperlefttolowerrightfill"; +static const char glyph_squareupperrighttolowerleftfill[] = +"squareupperrighttolowerleftfill"; +static const char glyph_squareverticalfill[] = "squareverticalfill"; +static const char glyph_squarewhitewithsmallblack[] = +"squarewhitewithsmallblack"; +static const char glyph_srsquare[] = "srsquare"; +static const char glyph_ssabengali[] = "ssabengali"; +static const char glyph_ssadeva[] = "ssadeva"; +static const char glyph_ssagujarati[] = "ssagujarati"; +static const char glyph_ssangcieuckorean[] = "ssangcieuckorean"; +static const char glyph_ssanghieuhkorean[] = "ssanghieuhkorean"; +static const char glyph_ssangieungkorean[] = "ssangieungkorean"; +static const char glyph_ssangkiyeokkorean[] = "ssangkiyeokkorean"; +static const char glyph_ssangnieunkorean[] = "ssangnieunkorean"; +static const char glyph_ssangpieupkorean[] = "ssangpieupkorean"; +static const char glyph_ssangsioskorean[] = "ssangsioskorean"; +static const char glyph_ssangtikeutkorean[] = "ssangtikeutkorean"; +static const char glyph_ssuperior[] = "ssuperior"; +static const char glyph_sterling[] = "sterling"; +static const char glyph_sterlingmonospace[] = "sterlingmonospace"; +static const char glyph_strokelongoverlaycmb[] = "strokelongoverlaycmb"; +static const char glyph_strokeshortoverlaycmb[] = "strokeshortoverlaycmb"; +static const char glyph_subset[] = "subset"; +static const char glyph_subsetnotequal[] = "subsetnotequal"; +static const char glyph_subsetorequal[] = "subsetorequal"; +static const char glyph_succeeds[] = "succeeds"; +static const char glyph_suchthat[] = "suchthat"; +static const char glyph_suhiragana[] = "suhiragana"; +static const char glyph_sukatakana[] = "sukatakana"; +static const char glyph_sukatakanahalfwidth[] = "sukatakanahalfwidth"; +static const char glyph_sukunarabic[] = "sukunarabic"; +static const char glyph_summation[] = "summation"; +static const char glyph_sun[] = "sun"; +static const char glyph_superset[] = "superset"; +static const char glyph_supersetnotequal[] = "supersetnotequal"; +static const char glyph_supersetorequal[] = "supersetorequal"; +static const char glyph_svsquare[] = "svsquare"; +static const char glyph_syouwaerasquare[] = "syouwaerasquare"; +static const char glyph_t[] = "t"; +static const char glyph_tabengali[] = "tabengali"; +static const char glyph_tackdown[] = "tackdown"; +static const char glyph_tackleft[] = "tackleft"; +static const char glyph_tadeva[] = "tadeva"; +static const char glyph_tagujarati[] = "tagujarati"; +static const char glyph_tagurmukhi[] = "tagurmukhi"; +static const char glyph_taharabic[] = "taharabic"; +static const char glyph_tahfinalarabic[] = "tahfinalarabic"; +static const char glyph_tahinitialarabic[] = "tahinitialarabic"; +static const char glyph_tahiragana[] = "tahiragana"; +static const char glyph_tahmedialarabic[] = "tahmedialarabic"; +static const char glyph_taisyouerasquare[] = "taisyouerasquare"; +static const char glyph_takatakana[] = "takatakana"; +static const char glyph_takatakanahalfwidth[] = "takatakanahalfwidth"; +static const char glyph_tatweelarabic[] = "tatweelarabic"; +static const char glyph_tau[] = "tau"; +static const char glyph_tav[] = "tav"; +static const char glyph_tavdages[] = "tavdages"; +static const char glyph_tavdagesh[] = "tavdagesh"; +static const char glyph_tavdageshhebrew[] = "tavdageshhebrew"; +static const char glyph_tavhebrew[] = "tavhebrew"; +static const char glyph_tbar[] = "tbar"; +static const char glyph_tbopomofo[] = "tbopomofo"; +static const char glyph_tcaron[] = "tcaron"; +static const char glyph_tccurl[] = "tccurl"; +static const char glyph_tcedilla[] = "tcedilla"; +static const char glyph_tcheharabic[] = "tcheharabic"; +static const char glyph_tchehfinalarabic[] = "tchehfinalarabic"; +static const char glyph_tchehinitialarabic[] = "tchehinitialarabic"; +static const char glyph_tchehmedialarabic[] = "tchehmedialarabic"; +static const char glyph_tchehmeeminitialarabic[] = "tchehmeeminitialarabic"; +static const char glyph_tcircle[] = "tcircle"; +static const char glyph_tcircumflexbelow[] = "tcircumflexbelow"; +static const char glyph_tcommaaccent[] = "tcommaaccent"; +static const char glyph_tdieresis[] = "tdieresis"; +static const char glyph_tdotaccent[] = "tdotaccent"; +static const char glyph_tdotbelow[] = "tdotbelow"; +static const char glyph_tecyrillic[] = "tecyrillic"; +static const char glyph_tedescendercyrillic[] = "tedescendercyrillic"; +static const char glyph_teharabic[] = "teharabic"; +static const char glyph_tehfinalarabic[] = "tehfinalarabic"; +static const char glyph_tehhahinitialarabic[] = "tehhahinitialarabic"; +static const char glyph_tehhahisolatedarabic[] = "tehhahisolatedarabic"; +static const char glyph_tehinitialarabic[] = "tehinitialarabic"; +static const char glyph_tehiragana[] = "tehiragana"; +static const char glyph_tehjeeminitialarabic[] = "tehjeeminitialarabic"; +static const char glyph_tehjeemisolatedarabic[] = "tehjeemisolatedarabic"; +static const char glyph_tehmarbutaarabic[] = "tehmarbutaarabic"; +static const char glyph_tehmarbutafinalarabic[] = "tehmarbutafinalarabic"; +static const char glyph_tehmedialarabic[] = "tehmedialarabic"; +static const char glyph_tehmeeminitialarabic[] = "tehmeeminitialarabic"; +static const char glyph_tehmeemisolatedarabic[] = "tehmeemisolatedarabic"; +static const char glyph_tehnoonfinalarabic[] = "tehnoonfinalarabic"; +static const char glyph_tekatakana[] = "tekatakana"; +static const char glyph_tekatakanahalfwidth[] = "tekatakanahalfwidth"; +static const char glyph_telephone[] = "telephone"; +static const char glyph_telephoneblack[] = "telephoneblack"; +static const char glyph_telishagedolahebrew[] = "telishagedolahebrew"; +static const char glyph_telishaqetanahebrew[] = "telishaqetanahebrew"; +static const char glyph_tencircle[] = "tencircle"; +static const char glyph_tenideographicparen[] = "tenideographicparen"; +static const char glyph_tenparen[] = "tenparen"; +static const char glyph_tenperiod[] = "tenperiod"; +static const char glyph_tenroman[] = "tenroman"; +static const char glyph_tesh[] = "tesh"; +static const char glyph_tet[] = "tet"; +static const char glyph_tetdagesh[] = "tetdagesh"; +static const char glyph_tetdageshhebrew[] = "tetdageshhebrew"; +static const char glyph_tethebrew[] = "tethebrew"; +static const char glyph_tetsecyrillic[] = "tetsecyrillic"; +static const char glyph_tevirhebrew[] = "tevirhebrew"; +static const char glyph_tevirlefthebrew[] = "tevirlefthebrew"; +static const char glyph_thabengali[] = "thabengali"; +static const char glyph_thadeva[] = "thadeva"; +static const char glyph_thagujarati[] = "thagujarati"; +static const char glyph_thagurmukhi[] = "thagurmukhi"; +static const char glyph_thalarabic[] = "thalarabic"; +static const char glyph_thalfinalarabic[] = "thalfinalarabic"; +static const char glyph_thanthakhatlowleftthai[] = "thanthakhatlowleftthai"; +static const char glyph_thanthakhatlowrightthai[] = "thanthakhatlowrightthai"; +static const char glyph_thanthakhatthai[] = "thanthakhatthai"; +static const char glyph_thanthakhatupperleftthai[] = +"thanthakhatupperleftthai"; +static const char glyph_theharabic[] = "theharabic"; +static const char glyph_thehfinalarabic[] = "thehfinalarabic"; +static const char glyph_thehinitialarabic[] = "thehinitialarabic"; +static const char glyph_thehmedialarabic[] = "thehmedialarabic"; +static const char glyph_thereexists[] = "thereexists"; +static const char glyph_therefore[] = "therefore"; +static const char glyph_theta[] = "theta"; +static const char glyph_theta1[] = "theta1"; +static const char glyph_thetasymbolgreek[] = "thetasymbolgreek"; +static const char glyph_thieuthacirclekorean[] = "thieuthacirclekorean"; +static const char glyph_thieuthaparenkorean[] = "thieuthaparenkorean"; +static const char glyph_thieuthcirclekorean[] = "thieuthcirclekorean"; +static const char glyph_thieuthkorean[] = "thieuthkorean"; +static const char glyph_thieuthparenkorean[] = "thieuthparenkorean"; +static const char glyph_thirteencircle[] = "thirteencircle"; +static const char glyph_thirteenparen[] = "thirteenparen"; +static const char glyph_thirteenperiod[] = "thirteenperiod"; +static const char glyph_thonangmonthothai[] = "thonangmonthothai"; +static const char glyph_thook[] = "thook"; +static const char glyph_thophuthaothai[] = "thophuthaothai"; +static const char glyph_thorn[] = "thorn"; +static const char glyph_thothahanthai[] = "thothahanthai"; +static const char glyph_thothanthai[] = "thothanthai"; +static const char glyph_thothongthai[] = "thothongthai"; +static const char glyph_thothungthai[] = "thothungthai"; +static const char glyph_thousandcyrillic[] = "thousandcyrillic"; +static const char glyph_thousandsseparatorarabic[] = +"thousandsseparatorarabic"; +static const char glyph_thousandsseparatorpersian[] = +"thousandsseparatorpersian"; +static const char glyph_three[] = "three"; +static const char glyph_threearabic[] = "threearabic"; +static const char glyph_threebengali[] = "threebengali"; +static const char glyph_threecircle[] = "threecircle"; +static const char glyph_threecircleinversesansserif[] = +"threecircleinversesansserif"; +static const char glyph_threedeva[] = "threedeva"; +static const char glyph_threeeighths[] = "threeeighths"; +static const char glyph_threegujarati[] = "threegujarati"; +static const char glyph_threegurmukhi[] = "threegurmukhi"; +static const char glyph_threehackarabic[] = "threehackarabic"; +static const char glyph_threehangzhou[] = "threehangzhou"; +static const char glyph_threeideographicparen[] = "threeideographicparen"; +static const char glyph_threeinferior[] = "threeinferior"; +static const char glyph_threemonospace[] = "threemonospace"; +static const char glyph_threenumeratorbengali[] = "threenumeratorbengali"; +static const char glyph_threeoldstyle[] = "threeoldstyle"; +static const char glyph_threeparen[] = "threeparen"; +static const char glyph_threeperiod[] = "threeperiod"; +static const char glyph_threepersian[] = "threepersian"; +static const char glyph_threequarters[] = "threequarters"; +static const char glyph_threequartersemdash[] = "threequartersemdash"; +static const char glyph_threeroman[] = "threeroman"; +static const char glyph_threesuperior[] = "threesuperior"; +static const char glyph_threethai[] = "threethai"; +static const char glyph_thzsquare[] = "thzsquare"; +static const char glyph_tihiragana[] = "tihiragana"; +static const char glyph_tikatakana[] = "tikatakana"; +static const char glyph_tikatakanahalfwidth[] = "tikatakanahalfwidth"; +static const char glyph_tikeutacirclekorean[] = "tikeutacirclekorean"; +static const char glyph_tikeutaparenkorean[] = "tikeutaparenkorean"; +static const char glyph_tikeutcirclekorean[] = "tikeutcirclekorean"; +static const char glyph_tikeutkorean[] = "tikeutkorean"; +static const char glyph_tikeutparenkorean[] = "tikeutparenkorean"; +static const char glyph_tilde[] = "tilde"; +static const char glyph_tildebelowcmb[] = "tildebelowcmb"; +static const char glyph_tildecmb[] = "tildecmb"; +static const char glyph_tildecomb[] = "tildecomb"; +static const char glyph_tildedoublecmb[] = "tildedoublecmb"; +static const char glyph_tildeoperator[] = "tildeoperator"; +static const char glyph_tildeoverlaycmb[] = "tildeoverlaycmb"; +static const char glyph_tildeverticalcmb[] = "tildeverticalcmb"; +static const char glyph_timescircle[] = "timescircle"; +static const char glyph_tipehahebrew[] = "tipehahebrew"; +static const char glyph_tipehalefthebrew[] = "tipehalefthebrew"; +static const char glyph_tippigurmukhi[] = "tippigurmukhi"; +static const char glyph_titlocyrilliccmb[] = "titlocyrilliccmb"; +static const char glyph_tiwnarmenian[] = "tiwnarmenian"; +static const char glyph_tlinebelow[] = "tlinebelow"; +static const char glyph_tmonospace[] = "tmonospace"; +static const char glyph_toarmenian[] = "toarmenian"; +static const char glyph_tohiragana[] = "tohiragana"; +static const char glyph_tokatakana[] = "tokatakana"; +static const char glyph_tokatakanahalfwidth[] = "tokatakanahalfwidth"; +static const char glyph_tonebarextrahighmod[] = "tonebarextrahighmod"; +static const char glyph_tonebarextralowmod[] = "tonebarextralowmod"; +static const char glyph_tonebarhighmod[] = "tonebarhighmod"; +static const char glyph_tonebarlowmod[] = "tonebarlowmod"; +static const char glyph_tonebarmidmod[] = "tonebarmidmod"; +static const char glyph_tonefive[] = "tonefive"; +static const char glyph_tonesix[] = "tonesix"; +static const char glyph_tonetwo[] = "tonetwo"; +static const char glyph_tonos[] = "tonos"; +static const char glyph_tonsquare[] = "tonsquare"; +static const char glyph_topatakthai[] = "topatakthai"; +static const char glyph_tortoiseshellbracketleft[] = +"tortoiseshellbracketleft"; +static const char glyph_tortoiseshellbracketleftsmall[] = +"tortoiseshellbracketleftsmall"; +static const char glyph_tortoiseshellbracketleftvertical[] = +"tortoiseshellbracketleftvertical"; +static const char glyph_tortoiseshellbracketright[] = +"tortoiseshellbracketright"; +static const char glyph_tortoiseshellbracketrightsmall[] = +"tortoiseshellbracketrightsmall"; +static const char glyph_tortoiseshellbracketrightvertical[] = +"tortoiseshellbracketrightvertical"; +static const char glyph_totaothai[] = "totaothai"; +static const char glyph_tpalatalhook[] = "tpalatalhook"; +static const char glyph_tparen[] = "tparen"; +static const char glyph_trademark[] = "trademark"; +static const char glyph_trademarksans[] = "trademarksans"; +static const char glyph_trademarkserif[] = "trademarkserif"; +static const char glyph_tretroflexhook[] = "tretroflexhook"; +static const char glyph_triagdn[] = "triagdn"; +static const char glyph_triaglf[] = "triaglf"; +static const char glyph_triagrt[] = "triagrt"; +static const char glyph_triagup[] = "triagup"; +static const char glyph_ts[] = "ts"; +static const char glyph_tsadi[] = "tsadi"; +static const char glyph_tsadidagesh[] = "tsadidagesh"; +static const char glyph_tsadidageshhebrew[] = "tsadidageshhebrew"; +static const char glyph_tsadihebrew[] = "tsadihebrew"; +static const char glyph_tsecyrillic[] = "tsecyrillic"; +static const char glyph_tsere[] = "tsere"; +static const char glyph_tsere12[] = "tsere12"; +static const char glyph_tsere1e[] = "tsere1e"; +static const char glyph_tsere2b[] = "tsere2b"; +static const char glyph_tserehebrew[] = "tserehebrew"; +static const char glyph_tserenarrowhebrew[] = "tserenarrowhebrew"; +static const char glyph_tserequarterhebrew[] = "tserequarterhebrew"; +static const char glyph_tserewidehebrew[] = "tserewidehebrew"; +static const char glyph_tshecyrillic[] = "tshecyrillic"; +static const char glyph_tsuperior[] = "tsuperior"; +static const char glyph_ttabengali[] = "ttabengali"; +static const char glyph_ttadeva[] = "ttadeva"; +static const char glyph_ttagujarati[] = "ttagujarati"; +static const char glyph_ttagurmukhi[] = "ttagurmukhi"; +static const char glyph_tteharabic[] = "tteharabic"; +static const char glyph_ttehfinalarabic[] = "ttehfinalarabic"; +static const char glyph_ttehinitialarabic[] = "ttehinitialarabic"; +static const char glyph_ttehmedialarabic[] = "ttehmedialarabic"; +static const char glyph_tthabengali[] = "tthabengali"; +static const char glyph_tthadeva[] = "tthadeva"; +static const char glyph_tthagujarati[] = "tthagujarati"; +static const char glyph_tthagurmukhi[] = "tthagurmukhi"; +static const char glyph_tturned[] = "tturned"; +static const char glyph_tuhiragana[] = "tuhiragana"; +static const char glyph_tukatakana[] = "tukatakana"; +static const char glyph_tukatakanahalfwidth[] = "tukatakanahalfwidth"; +static const char glyph_tusmallhiragana[] = "tusmallhiragana"; +static const char glyph_tusmallkatakana[] = "tusmallkatakana"; +static const char glyph_tusmallkatakanahalfwidth[] = +"tusmallkatakanahalfwidth"; +static const char glyph_twelvecircle[] = "twelvecircle"; +static const char glyph_twelveparen[] = "twelveparen"; +static const char glyph_twelveperiod[] = "twelveperiod"; +static const char glyph_twelveroman[] = "twelveroman"; +static const char glyph_twentycircle[] = "twentycircle"; +static const char glyph_twentyhangzhou[] = "twentyhangzhou"; +static const char glyph_twentyparen[] = "twentyparen"; +static const char glyph_twentyperiod[] = "twentyperiod"; +static const char glyph_two[] = "two"; +static const char glyph_twoarabic[] = "twoarabic"; +static const char glyph_twobengali[] = "twobengali"; +static const char glyph_twocircle[] = "twocircle"; +static const char glyph_twocircleinversesansserif[] = +"twocircleinversesansserif"; +static const char glyph_twodeva[] = "twodeva"; +static const char glyph_twodotenleader[] = "twodotenleader"; +static const char glyph_twodotleader[] = "twodotleader"; +static const char glyph_twodotleadervertical[] = "twodotleadervertical"; +static const char glyph_twogujarati[] = "twogujarati"; +static const char glyph_twogurmukhi[] = "twogurmukhi"; +static const char glyph_twohackarabic[] = "twohackarabic"; +static const char glyph_twohangzhou[] = "twohangzhou"; +static const char glyph_twoideographicparen[] = "twoideographicparen"; +static const char glyph_twoinferior[] = "twoinferior"; +static const char glyph_twomonospace[] = "twomonospace"; +static const char glyph_twonumeratorbengali[] = "twonumeratorbengali"; +static const char glyph_twooldstyle[] = "twooldstyle"; +static const char glyph_twoparen[] = "twoparen"; +static const char glyph_twoperiod[] = "twoperiod"; +static const char glyph_twopersian[] = "twopersian"; +static const char glyph_tworoman[] = "tworoman"; +static const char glyph_twostroke[] = "twostroke"; +static const char glyph_twosuperior[] = "twosuperior"; +static const char glyph_twothai[] = "twothai"; +static const char glyph_twothirds[] = "twothirds"; +static const char glyph_u[] = "u"; +static const char glyph_uacute[] = "uacute"; +static const char glyph_ubar[] = "ubar"; +static const char glyph_ubengali[] = "ubengali"; +static const char glyph_ubopomofo[] = "ubopomofo"; +static const char glyph_ubreve[] = "ubreve"; +static const char glyph_ucaron[] = "ucaron"; +static const char glyph_ucircle[] = "ucircle"; +static const char glyph_ucircumflex[] = "ucircumflex"; +static const char glyph_ucircumflexbelow[] = "ucircumflexbelow"; +static const char glyph_ucyrillic[] = "ucyrillic"; +static const char glyph_udattadeva[] = "udattadeva"; +static const char glyph_udblacute[] = "udblacute"; +static const char glyph_udblgrave[] = "udblgrave"; +static const char glyph_udeva[] = "udeva"; +static const char glyph_udieresis[] = "udieresis"; +static const char glyph_udieresisacute[] = "udieresisacute"; +static const char glyph_udieresisbelow[] = "udieresisbelow"; +static const char glyph_udieresiscaron[] = "udieresiscaron"; +static const char glyph_udieresiscyrillic[] = "udieresiscyrillic"; +static const char glyph_udieresisgrave[] = "udieresisgrave"; +static const char glyph_udieresismacron[] = "udieresismacron"; +static const char glyph_udotbelow[] = "udotbelow"; +static const char glyph_ugrave[] = "ugrave"; +static const char glyph_ugujarati[] = "ugujarati"; +static const char glyph_ugurmukhi[] = "ugurmukhi"; +static const char glyph_uhiragana[] = "uhiragana"; +static const char glyph_uhookabove[] = "uhookabove"; +static const char glyph_uhorn[] = "uhorn"; +static const char glyph_uhornacute[] = "uhornacute"; +static const char glyph_uhorndotbelow[] = "uhorndotbelow"; +static const char glyph_uhorngrave[] = "uhorngrave"; +static const char glyph_uhornhookabove[] = "uhornhookabove"; +static const char glyph_uhorntilde[] = "uhorntilde"; +static const char glyph_uhungarumlaut[] = "uhungarumlaut"; +static const char glyph_uhungarumlautcyrillic[] = "uhungarumlautcyrillic"; +static const char glyph_uinvertedbreve[] = "uinvertedbreve"; +static const char glyph_ukatakana[] = "ukatakana"; +static const char glyph_ukatakanahalfwidth[] = "ukatakanahalfwidth"; +static const char glyph_ukcyrillic[] = "ukcyrillic"; +static const char glyph_ukorean[] = "ukorean"; +static const char glyph_umacron[] = "umacron"; +static const char glyph_umacroncyrillic[] = "umacroncyrillic"; +static const char glyph_umacrondieresis[] = "umacrondieresis"; +static const char glyph_umatragurmukhi[] = "umatragurmukhi"; +static const char glyph_umonospace[] = "umonospace"; +static const char glyph_underscore[] = "underscore"; +static const char glyph_underscoredbl[] = "underscoredbl"; +static const char glyph_underscoremonospace[] = "underscoremonospace"; +static const char glyph_underscorevertical[] = "underscorevertical"; +static const char glyph_underscorewavy[] = "underscorewavy"; +static const char glyph_union[] = "union"; +static const char glyph_universal[] = "universal"; +static const char glyph_uogonek[] = "uogonek"; +static const char glyph_uparen[] = "uparen"; +static const char glyph_upblock[] = "upblock"; +static const char glyph_upperdothebrew[] = "upperdothebrew"; +static const char glyph_upsilon[] = "upsilon"; +static const char glyph_upsilondieresis[] = "upsilondieresis"; +static const char glyph_upsilondieresistonos[] = "upsilondieresistonos"; +static const char glyph_upsilonlatin[] = "upsilonlatin"; +static const char glyph_upsilontonos[] = "upsilontonos"; +static const char glyph_uptackbelowcmb[] = "uptackbelowcmb"; +static const char glyph_uptackmod[] = "uptackmod"; +static const char glyph_uragurmukhi[] = "uragurmukhi"; +static const char glyph_uring[] = "uring"; +static const char glyph_ushortcyrillic[] = "ushortcyrillic"; +static const char glyph_usmallhiragana[] = "usmallhiragana"; +static const char glyph_usmallkatakana[] = "usmallkatakana"; +static const char glyph_usmallkatakanahalfwidth[] = "usmallkatakanahalfwidth"; +static const char glyph_ustraightcyrillic[] = "ustraightcyrillic"; +static const char glyph_ustraightstrokecyrillic[] = "ustraightstrokecyrillic"; +static const char glyph_utilde[] = "utilde"; +static const char glyph_utildeacute[] = "utildeacute"; +static const char glyph_utildebelow[] = "utildebelow"; +static const char glyph_uubengali[] = "uubengali"; +static const char glyph_uudeva[] = "uudeva"; +static const char glyph_uugujarati[] = "uugujarati"; +static const char glyph_uugurmukhi[] = "uugurmukhi"; +static const char glyph_uumatragurmukhi[] = "uumatragurmukhi"; +static const char glyph_uuvowelsignbengali[] = "uuvowelsignbengali"; +static const char glyph_uuvowelsigndeva[] = "uuvowelsigndeva"; +static const char glyph_uuvowelsigngujarati[] = "uuvowelsigngujarati"; +static const char glyph_uvowelsignbengali[] = "uvowelsignbengali"; +static const char glyph_uvowelsigndeva[] = "uvowelsigndeva"; +static const char glyph_uvowelsigngujarati[] = "uvowelsigngujarati"; +static const char glyph_v[] = "v"; +static const char glyph_vadeva[] = "vadeva"; +static const char glyph_vagujarati[] = "vagujarati"; +static const char glyph_vagurmukhi[] = "vagurmukhi"; +static const char glyph_vakatakana[] = "vakatakana"; +static const char glyph_vav[] = "vav"; +static const char glyph_vavdagesh[] = "vavdagesh"; +static const char glyph_vavdagesh65[] = "vavdagesh65"; +static const char glyph_vavdageshhebrew[] = "vavdageshhebrew"; +static const char glyph_vavhebrew[] = "vavhebrew"; +static const char glyph_vavholam[] = "vavholam"; +static const char glyph_vavholamhebrew[] = "vavholamhebrew"; +static const char glyph_vavvavhebrew[] = "vavvavhebrew"; +static const char glyph_vavyodhebrew[] = "vavyodhebrew"; +static const char glyph_vcircle[] = "vcircle"; +static const char glyph_vdotbelow[] = "vdotbelow"; +static const char glyph_vecyrillic[] = "vecyrillic"; +static const char glyph_veharabic[] = "veharabic"; +static const char glyph_vehfinalarabic[] = "vehfinalarabic"; +static const char glyph_vehinitialarabic[] = "vehinitialarabic"; +static const char glyph_vehmedialarabic[] = "vehmedialarabic"; +static const char glyph_vekatakana[] = "vekatakana"; +static const char glyph_venus[] = "venus"; +static const char glyph_verticalbar[] = "verticalbar"; +static const char glyph_verticallineabovecmb[] = "verticallineabovecmb"; +static const char glyph_verticallinebelowcmb[] = "verticallinebelowcmb"; +static const char glyph_verticallinelowmod[] = "verticallinelowmod"; +static const char glyph_verticallinemod[] = "verticallinemod"; +static const char glyph_vewarmenian[] = "vewarmenian"; +static const char glyph_vhook[] = "vhook"; +static const char glyph_vikatakana[] = "vikatakana"; +static const char glyph_viramabengali[] = "viramabengali"; +static const char glyph_viramadeva[] = "viramadeva"; +static const char glyph_viramagujarati[] = "viramagujarati"; +static const char glyph_visargabengali[] = "visargabengali"; +static const char glyph_visargadeva[] = "visargadeva"; +static const char glyph_visargagujarati[] = "visargagujarati"; +static const char glyph_vmonospace[] = "vmonospace"; +static const char glyph_voarmenian[] = "voarmenian"; +static const char glyph_voicediterationhiragana[] = "voicediterationhiragana"; +static const char glyph_voicediterationkatakana[] = "voicediterationkatakana"; +static const char glyph_voicedmarkkana[] = "voicedmarkkana"; +static const char glyph_voicedmarkkanahalfwidth[] = "voicedmarkkanahalfwidth"; +static const char glyph_vokatakana[] = "vokatakana"; +static const char glyph_vparen[] = "vparen"; +static const char glyph_vtilde[] = "vtilde"; +static const char glyph_vturned[] = "vturned"; +static const char glyph_vuhiragana[] = "vuhiragana"; +static const char glyph_vukatakana[] = "vukatakana"; +static const char glyph_w[] = "w"; +static const char glyph_wacute[] = "wacute"; +static const char glyph_waekorean[] = "waekorean"; +static const char glyph_wahiragana[] = "wahiragana"; +static const char glyph_wakatakana[] = "wakatakana"; +static const char glyph_wakatakanahalfwidth[] = "wakatakanahalfwidth"; +static const char glyph_wakorean[] = "wakorean"; +static const char glyph_wasmallhiragana[] = "wasmallhiragana"; +static const char glyph_wasmallkatakana[] = "wasmallkatakana"; +static const char glyph_wattosquare[] = "wattosquare"; +static const char glyph_wavedash[] = "wavedash"; +static const char glyph_wavyunderscorevertical[] = "wavyunderscorevertical"; +static const char glyph_wawarabic[] = "wawarabic"; +static const char glyph_wawfinalarabic[] = "wawfinalarabic"; +static const char glyph_wawhamzaabovearabic[] = "wawhamzaabovearabic"; +static const char glyph_wawhamzaabovefinalarabic[] = +"wawhamzaabovefinalarabic"; +static const char glyph_wbsquare[] = "wbsquare"; +static const char glyph_wcircle[] = "wcircle"; +static const char glyph_wcircumflex[] = "wcircumflex"; +static const char glyph_wdieresis[] = "wdieresis"; +static const char glyph_wdotaccent[] = "wdotaccent"; +static const char glyph_wdotbelow[] = "wdotbelow"; +static const char glyph_wehiragana[] = "wehiragana"; +static const char glyph_weierstrass[] = "weierstrass"; +static const char glyph_wekatakana[] = "wekatakana"; +static const char glyph_wekorean[] = "wekorean"; +static const char glyph_weokorean[] = "weokorean"; +static const char glyph_wgrave[] = "wgrave"; +static const char glyph_whitebullet[] = "whitebullet"; +static const char glyph_whitecircle[] = "whitecircle"; +static const char glyph_whitecircleinverse[] = "whitecircleinverse"; +static const char glyph_whitecornerbracketleft[] = +"whitecornerbracketleft"; +static const char glyph_whitecornerbracketleftvertical[] = +"whitecornerbracketleftvertical"; +static const char glyph_whitecornerbracketright[] = +"whitecornerbracketright"; +static const char glyph_whitecornerbracketrightvertical[] = +"whitecornerbracketrightvertical"; +static const char glyph_whitediamond[] = "whitediamond"; +static const char glyph_whitediamondcontainingblacksmalldiamond[] = +"whitediamondcontainingblacksmalldiamond"; +static const char glyph_whitedownpointingsmalltriangle[] = +"whitedownpointingsmalltriangle"; +static const char glyph_whitedownpointingtriangle[] = +"whitedownpointingtriangle"; +static const char glyph_whiteleftpointingsmalltriangle[] = +"whiteleftpointingsmalltriangle"; +static const char glyph_whiteleftpointingtriangle[] = +"whiteleftpointingtriangle"; +static const char glyph_whitelenticularbracketleft[] = +"whitelenticularbracketleft"; +static const char glyph_whitelenticularbracketright[] = +"whitelenticularbracketright"; +static const char glyph_whiterightpointingsmalltriangle[] = +"whiterightpointingsmalltriangle"; +static const char glyph_whiterightpointingtriangle[] = +"whiterightpointingtriangle"; +static const char glyph_whitesmallsquare[] = "whitesmallsquare"; +static const char glyph_whitesmilingface[] = "whitesmilingface"; +static const char glyph_whitesquare[] = "whitesquare"; +static const char glyph_whitestar[] = "whitestar"; +static const char glyph_whitetelephone[] = "whitetelephone"; +static const char glyph_whitetortoiseshellbracketleft[] = +"whitetortoiseshellbracketleft"; +static const char glyph_whitetortoiseshellbracketright[] = +"whitetortoiseshellbracketright"; +static const char glyph_whiteuppointingsmalltriangle[] = +"whiteuppointingsmalltriangle"; +static const char glyph_whiteuppointingtriangle[] = "whiteuppointingtriangle"; +static const char glyph_wihiragana[] = "wihiragana"; +static const char glyph_wikatakana[] = "wikatakana"; +static const char glyph_wikorean[] = "wikorean"; +static const char glyph_wmonospace[] = "wmonospace"; +static const char glyph_wohiragana[] = "wohiragana"; +static const char glyph_wokatakana[] = "wokatakana"; +static const char glyph_wokatakanahalfwidth[] = "wokatakanahalfwidth"; +static const char glyph_won[] = "won"; +static const char glyph_wonmonospace[] = "wonmonospace"; +static const char glyph_wowaenthai[] = "wowaenthai"; +static const char glyph_wparen[] = "wparen"; +static const char glyph_wring[] = "wring"; +static const char glyph_wsuperior[] = "wsuperior"; +static const char glyph_wturned[] = "wturned"; +static const char glyph_wynn[] = "wynn"; +static const char glyph_x[] = "x"; +static const char glyph_xabovecmb[] = "xabovecmb"; +static const char glyph_xbopomofo[] = "xbopomofo"; +static const char glyph_xcircle[] = "xcircle"; +static const char glyph_xdieresis[] = "xdieresis"; +static const char glyph_xdotaccent[] = "xdotaccent"; +static const char glyph_xeharmenian[] = "xeharmenian"; +static const char glyph_xi[] = "xi"; +static const char glyph_xmonospace[] = "xmonospace"; +static const char glyph_xparen[] = "xparen"; +static const char glyph_xsuperior[] = "xsuperior"; +static const char glyph_y[] = "y"; +static const char glyph_yaadosquare[] = "yaadosquare"; +static const char glyph_yabengali[] = "yabengali"; +static const char glyph_yacute[] = "yacute"; +static const char glyph_yadeva[] = "yadeva"; +static const char glyph_yaekorean[] = "yaekorean"; +static const char glyph_yagujarati[] = "yagujarati"; +static const char glyph_yagurmukhi[] = "yagurmukhi"; +static const char glyph_yahiragana[] = "yahiragana"; +static const char glyph_yakatakana[] = "yakatakana"; +static const char glyph_yakatakanahalfwidth[] = "yakatakanahalfwidth"; +static const char glyph_yakorean[] = "yakorean"; +static const char glyph_yamakkanthai[] = "yamakkanthai"; +static const char glyph_yasmallhiragana[] = "yasmallhiragana"; +static const char glyph_yasmallkatakana[] = "yasmallkatakana"; +static const char glyph_yasmallkatakanahalfwidth[] = +"yasmallkatakanahalfwidth"; +static const char glyph_yatcyrillic[] = "yatcyrillic"; +static const char glyph_ycircle[] = "ycircle"; +static const char glyph_ycircumflex[] = "ycircumflex"; +static const char glyph_ydieresis[] = "ydieresis"; +static const char glyph_ydotaccent[] = "ydotaccent"; +static const char glyph_ydotbelow[] = "ydotbelow"; +static const char glyph_yeharabic[] = "yeharabic"; +static const char glyph_yehbarreearabic[] = "yehbarreearabic"; +static const char glyph_yehbarreefinalarabic[] = "yehbarreefinalarabic"; +static const char glyph_yehfinalarabic[] = "yehfinalarabic"; +static const char glyph_yehhamzaabovearabic[] = "yehhamzaabovearabic"; +static const char glyph_yehhamzaabovefinalarabic[] = +"yehhamzaabovefinalarabic"; +static const char glyph_yehhamzaaboveinitialarabic[] = +"yehhamzaaboveinitialarabic"; +static const char glyph_yehhamzaabovemedialarabic[] = +"yehhamzaabovemedialarabic"; +static const char glyph_yehinitialarabic[] = "yehinitialarabic"; +static const char glyph_yehmedialarabic[] = "yehmedialarabic"; +static const char glyph_yehmeeminitialarabic[] = "yehmeeminitialarabic"; +static const char glyph_yehmeemisolatedarabic[] = "yehmeemisolatedarabic"; +static const char glyph_yehnoonfinalarabic[] = "yehnoonfinalarabic"; +static const char glyph_yehthreedotsbelowarabic[] = "yehthreedotsbelowarabic"; +static const char glyph_yekorean[] = "yekorean"; +static const char glyph_yen[] = "yen"; +static const char glyph_yenmonospace[] = "yenmonospace"; +static const char glyph_yeokorean[] = "yeokorean"; +static const char glyph_yeorinhieuhkorean[] = "yeorinhieuhkorean"; +static const char glyph_yerahbenyomohebrew[] = "yerahbenyomohebrew"; +static const char glyph_yerahbenyomolefthebrew[] = "yerahbenyomolefthebrew"; +static const char glyph_yericyrillic[] = "yericyrillic"; +static const char glyph_yerudieresiscyrillic[] = "yerudieresiscyrillic"; +static const char glyph_yesieungkorean[] = "yesieungkorean"; +static const char glyph_yesieungpansioskorean[] = "yesieungpansioskorean"; +static const char glyph_yesieungsioskorean[] = "yesieungsioskorean"; +static const char glyph_yetivhebrew[] = "yetivhebrew"; +static const char glyph_ygrave[] = "ygrave"; +static const char glyph_yhook[] = "yhook"; +static const char glyph_yhookabove[] = "yhookabove"; +static const char glyph_yiarmenian[] = "yiarmenian"; +static const char glyph_yicyrillic[] = "yicyrillic"; +static const char glyph_yikorean[] = "yikorean"; +static const char glyph_yinyang[] = "yinyang"; +static const char glyph_yiwnarmenian[] = "yiwnarmenian"; +static const char glyph_ymonospace[] = "ymonospace"; +static const char glyph_yod[] = "yod"; +static const char glyph_yoddagesh[] = "yoddagesh"; +static const char glyph_yoddageshhebrew[] = "yoddageshhebrew"; +static const char glyph_yodhebrew[] = "yodhebrew"; +static const char glyph_yodyodhebrew[] = "yodyodhebrew"; +static const char glyph_yodyodpatahhebrew[] = "yodyodpatahhebrew"; +static const char glyph_yohiragana[] = "yohiragana"; +static const char glyph_yoikorean[] = "yoikorean"; +static const char glyph_yokatakana[] = "yokatakana"; +static const char glyph_yokatakanahalfwidth[] = "yokatakanahalfwidth"; +static const char glyph_yokorean[] = "yokorean"; +static const char glyph_yosmallhiragana[] = "yosmallhiragana"; +static const char glyph_yosmallkatakana[] = "yosmallkatakana"; +static const char glyph_yosmallkatakanahalfwidth[] = +"yosmallkatakanahalfwidth"; +static const char glyph_yotgreek[] = "yotgreek"; +static const char glyph_yoyaekorean[] = "yoyaekorean"; +static const char glyph_yoyakorean[] = "yoyakorean"; +static const char glyph_yoyakthai[] = "yoyakthai"; +static const char glyph_yoyingthai[] = "yoyingthai"; +static const char glyph_yparen[] = "yparen"; +static const char glyph_ypogegrammeni[] = "ypogegrammeni"; +static const char glyph_ypogegrammenigreekcmb[] = "ypogegrammenigreekcmb"; +static const char glyph_yr[] = "yr"; +static const char glyph_yring[] = "yring"; +static const char glyph_ysuperior[] = "ysuperior"; +static const char glyph_ytilde[] = "ytilde"; +static const char glyph_yturned[] = "yturned"; +static const char glyph_yuhiragana[] = "yuhiragana"; +static const char glyph_yuikorean[] = "yuikorean"; +static const char glyph_yukatakana[] = "yukatakana"; +static const char glyph_yukatakanahalfwidth[] = "yukatakanahalfwidth"; +static const char glyph_yukorean[] = "yukorean"; +static const char glyph_yusbigcyrillic[] = "yusbigcyrillic"; +static const char glyph_yusbigiotifiedcyrillic[] = "yusbigiotifiedcyrillic"; +static const char glyph_yuslittlecyrillic[] = "yuslittlecyrillic"; +static const char glyph_yuslittleiotifiedcyrillic[] = +"yuslittleiotifiedcyrillic"; +static const char glyph_yusmallhiragana[] = "yusmallhiragana"; +static const char glyph_yusmallkatakana[] = "yusmallkatakana"; +static const char glyph_yusmallkatakanahalfwidth[] = +"yusmallkatakanahalfwidth"; +static const char glyph_yuyekorean[] = "yuyekorean"; +static const char glyph_yuyeokorean[] = "yuyeokorean"; +static const char glyph_yyabengali[] = "yyabengali"; +static const char glyph_yyadeva[] = "yyadeva"; +static const char glyph_z[] = "z"; +static const char glyph_zaarmenian[] = "zaarmenian"; +static const char glyph_zacute[] = "zacute"; +static const char glyph_zadeva[] = "zadeva"; +static const char glyph_zagurmukhi[] = "zagurmukhi"; +static const char glyph_zaharabic[] = "zaharabic"; +static const char glyph_zahfinalarabic[] = "zahfinalarabic"; +static const char glyph_zahinitialarabic[] = "zahinitialarabic"; +static const char glyph_zahiragana[] = "zahiragana"; +static const char glyph_zahmedialarabic[] = "zahmedialarabic"; +static const char glyph_zainarabic[] = "zainarabic"; +static const char glyph_zainfinalarabic[] = "zainfinalarabic"; +static const char glyph_zakatakana[] = "zakatakana"; +static const char glyph_zaqefgadolhebrew[] = "zaqefgadolhebrew"; +static const char glyph_zaqefqatanhebrew[] = "zaqefqatanhebrew"; +static const char glyph_zarqahebrew[] = "zarqahebrew"; +static const char glyph_zayin[] = "zayin"; +static const char glyph_zayindagesh[] = "zayindagesh"; +static const char glyph_zayindageshhebrew[] = "zayindageshhebrew"; +static const char glyph_zayinhebrew[] = "zayinhebrew"; +static const char glyph_zbopomofo[] = "zbopomofo"; +static const char glyph_zcaron[] = "zcaron"; +static const char glyph_zcircle[] = "zcircle"; +static const char glyph_zcircumflex[] = "zcircumflex"; +static const char glyph_zcurl[] = "zcurl"; +static const char glyph_zdot[] = "zdot"; +static const char glyph_zdotaccent[] = "zdotaccent"; +static const char glyph_zdotbelow[] = "zdotbelow"; +static const char glyph_zecyrillic[] = "zecyrillic"; +static const char glyph_zedescendercyrillic[] = "zedescendercyrillic"; +static const char glyph_zedieresiscyrillic[] = "zedieresiscyrillic"; +static const char glyph_zehiragana[] = "zehiragana"; +static const char glyph_zekatakana[] = "zekatakana"; +static const char glyph_zero[] = "zero"; +static const char glyph_zeroarabic[] = "zeroarabic"; +static const char glyph_zerobengali[] = "zerobengali"; +static const char glyph_zerodeva[] = "zerodeva"; +static const char glyph_zerogujarati[] = "zerogujarati"; +static const char glyph_zerogurmukhi[] = "zerogurmukhi"; +static const char glyph_zerohackarabic[] = "zerohackarabic"; +static const char glyph_zeroinferior[] = "zeroinferior"; +static const char glyph_zeromonospace[] = "zeromonospace"; +static const char glyph_zerooldstyle[] = "zerooldstyle"; +static const char glyph_zeropersian[] = "zeropersian"; +static const char glyph_zerosuperior[] = "zerosuperior"; +static const char glyph_zerothai[] = "zerothai"; +static const char glyph_zerowidthjoiner[] = "zerowidthjoiner"; +static const char glyph_zerowidthnonjoiner[] = "zerowidthnonjoiner"; +static const char glyph_zerowidthspace[] = "zerowidthspace"; +static const char glyph_zeta[] = "zeta"; +static const char glyph_zhbopomofo[] = "zhbopomofo"; +static const char glyph_zhearmenian[] = "zhearmenian"; +static const char glyph_zhebrevecyrillic[] = "zhebrevecyrillic"; +static const char glyph_zhecyrillic[] = "zhecyrillic"; +static const char glyph_zhedescendercyrillic[] = "zhedescendercyrillic"; +static const char glyph_zhedieresiscyrillic[] = "zhedieresiscyrillic"; +static const char glyph_zihiragana[] = "zihiragana"; +static const char glyph_zikatakana[] = "zikatakana"; +static const char glyph_zinorhebrew[] = "zinorhebrew"; +static const char glyph_zlinebelow[] = "zlinebelow"; +static const char glyph_zmonospace[] = "zmonospace"; +static const char glyph_zohiragana[] = "zohiragana"; +static const char glyph_zokatakana[] = "zokatakana"; +static const char glyph_zparen[] = "zparen"; +static const char glyph_zretroflexhook[] = "zretroflexhook"; +static const char glyph_zstroke[] = "zstroke"; +static const char glyph_zuhiragana[] = "zuhiragana"; +static const char glyph_zukatakana[] = "zukatakana"; + + +/* Glyph names of ZapfDingbats font */ +static const char glyph_a100[] = "a100"; +static const char glyph_a101[] = "a101"; +static const char glyph_a102[] = "a102"; +static const char glyph_a103[] = "a103"; +static const char glyph_a104[] = "a104"; +static const char glyph_a105[] = "a105"; +static const char glyph_a106[] = "a106"; +static const char glyph_a107[] = "a107"; +static const char glyph_a108[] = "a108"; +static const char glyph_a109[] = "a109"; +static const char glyph_a10[] = "a10"; +static const char glyph_a110[] = "a110"; +static const char glyph_a111[] = "a111"; +static const char glyph_a112[] = "a112"; +static const char glyph_a117[] = "a117"; +static const char glyph_a118[] = "a118"; +static const char glyph_a119[] = "a119"; +static const char glyph_a11[] = "a11"; +static const char glyph_a120[] = "a120"; +static const char glyph_a121[] = "a121"; +static const char glyph_a122[] = "a122"; +static const char glyph_a123[] = "a123"; +static const char glyph_a124[] = "a124"; +static const char glyph_a125[] = "a125"; +static const char glyph_a126[] = "a126"; +static const char glyph_a127[] = "a127"; +static const char glyph_a128[] = "a128"; +static const char glyph_a129[] = "a129"; +static const char glyph_a12[] = "a12"; +static const char glyph_a130[] = "a130"; +static const char glyph_a131[] = "a131"; +static const char glyph_a132[] = "a132"; +static const char glyph_a133[] = "a133"; +static const char glyph_a134[] = "a134"; +static const char glyph_a135[] = "a135"; +static const char glyph_a136[] = "a136"; +static const char glyph_a137[] = "a137"; +static const char glyph_a138[] = "a138"; +static const char glyph_a139[] = "a139"; +static const char glyph_a13[] = "a13"; +static const char glyph_a140[] = "a140"; +static const char glyph_a141[] = "a141"; +static const char glyph_a142[] = "a142"; +static const char glyph_a143[] = "a143"; +static const char glyph_a144[] = "a144"; +static const char glyph_a145[] = "a145"; +static const char glyph_a146[] = "a146"; +static const char glyph_a147[] = "a147"; +static const char glyph_a148[] = "a148"; +static const char glyph_a149[] = "a149"; +static const char glyph_a14[] = "a14"; +static const char glyph_a150[] = "a150"; +static const char glyph_a151[] = "a151"; +static const char glyph_a152[] = "a152"; +static const char glyph_a153[] = "a153"; +static const char glyph_a154[] = "a154"; +static const char glyph_a155[] = "a155"; +static const char glyph_a156[] = "a156"; +static const char glyph_a157[] = "a157"; +static const char glyph_a158[] = "a158"; +static const char glyph_a159[] = "a159"; +static const char glyph_a15[] = "a15"; +static const char glyph_a160[] = "a160"; +static const char glyph_a161[] = "a161"; +static const char glyph_a162[] = "a162"; +static const char glyph_a163[] = "a163"; +static const char glyph_a164[] = "a164"; +static const char glyph_a165[] = "a165"; +static const char glyph_a166[] = "a166"; +static const char glyph_a167[] = "a167"; +static const char glyph_a168[] = "a168"; +static const char glyph_a169[] = "a169"; +static const char glyph_a16[] = "a16"; +static const char glyph_a170[] = "a170"; +static const char glyph_a171[] = "a171"; +static const char glyph_a172[] = "a172"; +static const char glyph_a173[] = "a173"; +static const char glyph_a174[] = "a174"; +static const char glyph_a175[] = "a175"; +static const char glyph_a176[] = "a176"; +static const char glyph_a177[] = "a177"; +static const char glyph_a178[] = "a178"; +static const char glyph_a179[] = "a179"; +static const char glyph_a17[] = "a17"; +static const char glyph_a180[] = "a180"; +static const char glyph_a181[] = "a181"; +static const char glyph_a182[] = "a182"; +static const char glyph_a183[] = "a183"; +static const char glyph_a184[] = "a184"; +static const char glyph_a185[] = "a185"; +static const char glyph_a186[] = "a186"; +static const char glyph_a187[] = "a187"; +static const char glyph_a188[] = "a188"; +static const char glyph_a189[] = "a189"; +static const char glyph_a18[] = "a18"; +static const char glyph_a190[] = "a190"; +static const char glyph_a191[] = "a191"; +static const char glyph_a192[] = "a192"; +static const char glyph_a193[] = "a193"; +static const char glyph_a194[] = "a194"; +static const char glyph_a195[] = "a195"; +static const char glyph_a196[] = "a196"; +static const char glyph_a197[] = "a197"; +static const char glyph_a198[] = "a198"; +static const char glyph_a199[] = "a199"; +static const char glyph_a19[] = "a19"; +static const char glyph_a1[] = "a1"; +static const char glyph_a200[] = "a200"; +static const char glyph_a201[] = "a201"; +static const char glyph_a202[] = "a202"; +static const char glyph_a203[] = "a203"; +static const char glyph_a204[] = "a204"; +static const char glyph_a205[] = "a205"; +static const char glyph_a206[] = "a206"; +static const char glyph_a20[] = "a20"; +static const char glyph_a21[] = "a21"; +static const char glyph_a22[] = "a22"; +static const char glyph_a23[] = "a23"; +static const char glyph_a24[] = "a24"; +static const char glyph_a25[] = "a25"; +static const char glyph_a26[] = "a26"; +static const char glyph_a27[] = "a27"; +static const char glyph_a28[] = "a28"; +static const char glyph_a29[] = "a29"; +static const char glyph_a2[] = "a2"; +static const char glyph_a30[] = "a30"; +static const char glyph_a31[] = "a31"; +static const char glyph_a32[] = "a32"; +static const char glyph_a33[] = "a33"; +static const char glyph_a34[] = "a34"; +static const char glyph_a35[] = "a35"; +static const char glyph_a36[] = "a36"; +static const char glyph_a37[] = "a37"; +static const char glyph_a38[] = "a38"; +static const char glyph_a39[] = "a39"; +static const char glyph_a3[] = "a3"; +static const char glyph_a40[] = "a40"; +static const char glyph_a41[] = "a41"; +static const char glyph_a42[] = "a42"; +static const char glyph_a43[] = "a43"; +static const char glyph_a44[] = "a44"; +static const char glyph_a45[] = "a45"; +static const char glyph_a46[] = "a46"; +static const char glyph_a47[] = "a47"; +static const char glyph_a48[] = "a48"; +static const char glyph_a49[] = "a49"; +static const char glyph_a4[] = "a4"; +static const char glyph_a50[] = "a50"; +static const char glyph_a51[] = "a51"; +static const char glyph_a52[] = "a52"; +static const char glyph_a53[] = "a53"; +static const char glyph_a54[] = "a54"; +static const char glyph_a55[] = "a55"; +static const char glyph_a56[] = "a56"; +static const char glyph_a57[] = "a57"; +static const char glyph_a58[] = "a58"; +static const char glyph_a59[] = "a59"; +static const char glyph_a5[] = "a5"; +static const char glyph_a60[] = "a60"; +static const char glyph_a61[] = "a61"; +static const char glyph_a62[] = "a62"; +static const char glyph_a63[] = "a63"; +static const char glyph_a64[] = "a64"; +static const char glyph_a65[] = "a65"; +static const char glyph_a66[] = "a66"; +static const char glyph_a67[] = "a67"; +static const char glyph_a68[] = "a68"; +static const char glyph_a69[] = "a69"; +static const char glyph_a6[] = "a6"; +static const char glyph_a70[] = "a70"; +static const char glyph_a71[] = "a71"; +static const char glyph_a72[] = "a72"; +static const char glyph_a73[] = "a73"; +static const char glyph_a74[] = "a74"; +static const char glyph_a75[] = "a75"; +static const char glyph_a76[] = "a76"; +static const char glyph_a77[] = "a77"; +static const char glyph_a78[] = "a78"; +static const char glyph_a79[] = "a79"; +static const char glyph_a7[] = "a7"; +static const char glyph_a81[] = "a81"; +static const char glyph_a82[] = "a82"; +static const char glyph_a83[] = "a83"; +static const char glyph_a84[] = "a84"; +static const char glyph_a85[] = "a85"; +static const char glyph_a86[] = "a86"; +static const char glyph_a87[] = "a87"; +static const char glyph_a88[] = "a88"; +static const char glyph_a89[] = "a89"; +static const char glyph_a8[] = "a8"; +static const char glyph_a90[] = "a90"; +static const char glyph_a91[] = "a91"; +static const char glyph_a92[] = "a92"; +static const char glyph_a93[] = "a93"; +static const char glyph_a94[] = "a94"; +static const char glyph_a95[] = "a95"; +static const char glyph_a96[] = "a96"; +static const char glyph_a97[] = "a97"; +static const char glyph_a98[] = "a98"; +static const char glyph_a99[] = "a99"; +static const char glyph_a9[] = "a9"; + + +/* + * Adobe Glyph List (AGL) version 1.2' - sorted by names + * + * Version 1.2' means: + * Version 1.2 + resolved double-mappings by following + * glyph names defined in AGL version 2.0: + * + * Deltagreek (Delta) + * Omegagreek (Omega) + * Tcedilla (Tcommaaccent) + * bulletoperator (periodcentered) + * divisionslash (fraction) + * firsttonechinese (macron) + * mugreek (mu) + * nbspace (space) + * sfthyphen (hyphen) + * tcedilla (tcommaaccent) + * + * (cf. table 'tab_double_mappping' below and + * function 'pdc_get_alter_glyphname') + * + */ + +static const pdc_glyph_tab tab_agl2uni[] = +{ +#ifndef PDFLIB_EBCDIC + { 0x0000, glyph__notdef }, + { 0x0041, glyph_A }, + { 0x00C6, glyph_AE }, + { 0x01FC, glyph_AEacute }, + { 0xF7E6, glyph_AEsmall }, + { 0x00C1, glyph_Aacute }, + { 0xF7E1, glyph_Aacutesmall }, + { 0x0102, glyph_Abreve }, + { 0x00C2, glyph_Acircumflex }, + { 0xF7E2, glyph_Acircumflexsmall }, + { 0xF6C9, glyph_Acute }, + { 0xF7B4, glyph_Acutesmall }, + { 0x00C4, glyph_Adieresis }, + { 0xF7E4, glyph_Adieresissmall }, + { 0x00C0, glyph_Agrave }, + { 0xF7E0, glyph_Agravesmall }, + { 0x0391, glyph_Alpha }, + { 0x0386, glyph_Alphatonos }, + { 0x0100, glyph_Amacron }, + { 0x0104, glyph_Aogonek }, + { 0x00C5, glyph_Aring }, + { 0x01FA, glyph_Aringacute }, + { 0xF7E5, glyph_Aringsmall }, + { 0xF761, glyph_Asmall }, + { 0x00C3, glyph_Atilde }, + { 0xF7E3, glyph_Atildesmall }, + { 0x0042, glyph_B }, + { 0x0392, glyph_Beta }, + { 0xF6F4, glyph_Brevesmall }, + { 0xF762, glyph_Bsmall }, + { 0x0043, glyph_C }, + { 0x0106, glyph_Cacute }, + { 0xF6CA, glyph_Caron }, + { 0xF6F5, glyph_Caronsmall }, + { 0x010C, glyph_Ccaron }, + { 0x00C7, glyph_Ccedilla }, + { 0xF7E7, glyph_Ccedillasmall }, + { 0x0108, glyph_Ccircumflex }, + { 0x010A, glyph_Cdotaccent }, + { 0xF7B8, glyph_Cedillasmall }, + { 0x03A7, glyph_Chi }, + { 0xF6F6, glyph_Circumflexsmall }, + { 0xF763, glyph_Csmall }, + { 0x0044, glyph_D }, + { 0x010E, glyph_Dcaron }, + { 0x0110, glyph_Dcroat }, + { 0x2206, glyph_Delta }, + { 0x0394, glyph_Deltagreek }, + { 0xF6CB, glyph_Dieresis }, + { 0xF6CC, glyph_DieresisAcute }, + { 0xF6CD, glyph_DieresisGrave }, + { 0xF7A8, glyph_Dieresissmall }, + { 0xF6F7, glyph_Dotaccentsmall }, + { 0xF764, glyph_Dsmall }, + { 0x0045, glyph_E }, + { 0x00C9, glyph_Eacute }, + { 0xF7E9, glyph_Eacutesmall }, + { 0x0114, glyph_Ebreve }, + { 0x011A, glyph_Ecaron }, + { 0x00CA, glyph_Ecircumflex }, + { 0xF7EA, glyph_Ecircumflexsmall }, + { 0x00CB, glyph_Edieresis }, + { 0xF7EB, glyph_Edieresissmall }, + { 0x0116, glyph_Edotaccent }, + { 0x00C8, glyph_Egrave }, + { 0xF7E8, glyph_Egravesmall }, + { 0x0112, glyph_Emacron }, + { 0x014A, glyph_Eng }, + { 0x0118, glyph_Eogonek }, + { 0x0395, glyph_Epsilon }, + { 0x0388, glyph_Epsilontonos }, + { 0xF765, glyph_Esmall }, + { 0x0397, glyph_Eta }, + { 0x0389, glyph_Etatonos }, + { 0x00D0, glyph_Eth }, + { 0xF7F0, glyph_Ethsmall }, + { 0x20AC, glyph_Euro }, + { 0x0046, glyph_F }, + { 0xF766, glyph_Fsmall }, + { 0x0047, glyph_G }, + { 0x0393, glyph_Gamma }, + { 0x011E, glyph_Gbreve }, + { 0x01E6, glyph_Gcaron }, + { 0x011C, glyph_Gcircumflex }, + { 0x0122, glyph_Gcommaaccent }, + { 0x0120, glyph_Gdotaccent }, + { 0xF6CE, glyph_Grave }, + { 0xF760, glyph_Gravesmall }, + { 0xF767, glyph_Gsmall }, + { 0x0048, glyph_H }, + { 0x25CF, glyph_H18533 }, + { 0x25AA, glyph_H18543 }, + { 0x25AB, glyph_H18551 }, + { 0x25A1, glyph_H22073 }, + { 0x0126, glyph_Hbar }, + { 0x0124, glyph_Hcircumflex }, + { 0xF768, glyph_Hsmall }, + { 0xF6CF, glyph_Hungarumlaut }, + { 0xF6F8, glyph_Hungarumlautsmall }, + { 0x0049, glyph_I }, + { 0x0132, glyph_IJ }, + { 0x00CD, glyph_Iacute }, + { 0xF7ED, glyph_Iacutesmall }, + { 0x012C, glyph_Ibreve }, + { 0x00CE, glyph_Icircumflex }, + { 0xF7EE, glyph_Icircumflexsmall }, + { 0x00CF, glyph_Idieresis }, + { 0xF7EF, glyph_Idieresissmall }, + { 0x0130, glyph_Idotaccent }, + { 0x2111, glyph_Ifraktur }, + { 0x00CC, glyph_Igrave }, + { 0xF7EC, glyph_Igravesmall }, + { 0x012A, glyph_Imacron }, + { 0x012E, glyph_Iogonek }, + { 0x0399, glyph_Iota }, + { 0x03AA, glyph_Iotadieresis }, + { 0x038A, glyph_Iotatonos }, + { 0xF769, glyph_Ismall }, + { 0x0128, glyph_Itilde }, + { 0x004A, glyph_J }, + { 0x0134, glyph_Jcircumflex }, + { 0xF76A, glyph_Jsmall }, + { 0x004B, glyph_K }, + { 0x039A, glyph_Kappa }, + { 0x0136, glyph_Kcommaaccent }, + { 0xF76B, glyph_Ksmall }, + { 0x004C, glyph_L }, + { 0xF6BF, glyph_LL }, + { 0x0139, glyph_Lacute }, + { 0x039B, glyph_Lambda }, + { 0x013D, glyph_Lcaron }, + { 0x013B, glyph_Lcommaaccent }, + { 0x013F, glyph_Ldot }, + { 0x0141, glyph_Lslash }, + { 0xF6F9, glyph_Lslashsmall }, + { 0xF76C, glyph_Lsmall }, + { 0x004D, glyph_M }, + { 0xF6D0, glyph_Macron }, + { 0xF7AF, glyph_Macronsmall }, + { 0xF76D, glyph_Msmall }, + { 0x039C, glyph_Mu }, + { 0x004E, glyph_N }, + { 0x0143, glyph_Nacute }, + { 0x0147, glyph_Ncaron }, + { 0x0145, glyph_Ncommaaccent }, + { 0xF76E, glyph_Nsmall }, + { 0x00D1, glyph_Ntilde }, + { 0xF7F1, glyph_Ntildesmall }, + { 0x039D, glyph_Nu }, + { 0x004F, glyph_O }, + { 0x0152, glyph_OE }, + { 0xF6FA, glyph_OEsmall }, + { 0x00D3, glyph_Oacute }, + { 0xF7F3, glyph_Oacutesmall }, + { 0x014E, glyph_Obreve }, + { 0x00D4, glyph_Ocircumflex }, + { 0xF7F4, glyph_Ocircumflexsmall }, + { 0x00D6, glyph_Odieresis }, + { 0xF7F6, glyph_Odieresissmall }, + { 0xF6FB, glyph_Ogoneksmall }, + { 0x00D2, glyph_Ograve }, + { 0xF7F2, glyph_Ogravesmall }, + { 0x01A0, glyph_Ohorn }, + { 0x0150, glyph_Ohungarumlaut }, + { 0x014C, glyph_Omacron }, + { 0x2126, glyph_Omega }, + { 0x03A9, glyph_Omegagreek }, + { 0x038F, glyph_Omegatonos }, + { 0x039F, glyph_Omicron }, + { 0x038C, glyph_Omicrontonos }, + { 0x00D8, glyph_Oslash }, + { 0x01FE, glyph_Oslashacute }, + { 0xF7F8, glyph_Oslashsmall }, + { 0xF76F, glyph_Osmall }, + { 0x00D5, glyph_Otilde }, + { 0xF7F5, glyph_Otildesmall }, + { 0x0050, glyph_P }, + { 0x03A6, glyph_Phi }, + { 0x03A0, glyph_Pi }, + { 0x03A8, glyph_Psi }, + { 0xF770, glyph_Psmall }, + { 0x0051, glyph_Q }, + { 0xF771, glyph_Qsmall }, + { 0x0052, glyph_R }, + { 0x0154, glyph_Racute }, + { 0x0158, glyph_Rcaron }, + { 0x0156, glyph_Rcommaaccent }, + { 0x211C, glyph_Rfraktur }, + { 0x03A1, glyph_Rho }, + { 0xF6FC, glyph_Ringsmall }, + { 0xF772, glyph_Rsmall }, + { 0x0053, glyph_S }, + { 0x250C, glyph_SF010000 }, + { 0x2514, glyph_SF020000 }, + { 0x2510, glyph_SF030000 }, + { 0x2518, glyph_SF040000 }, + { 0x253C, glyph_SF050000 }, + { 0x252C, glyph_SF060000 }, + { 0x2534, glyph_SF070000 }, + { 0x251C, glyph_SF080000 }, + { 0x2524, glyph_SF090000 }, + { 0x2500, glyph_SF100000 }, + { 0x2502, glyph_SF110000 }, + { 0x2561, glyph_SF190000 }, + { 0x2562, glyph_SF200000 }, + { 0x2556, glyph_SF210000 }, + { 0x2555, glyph_SF220000 }, + { 0x2563, glyph_SF230000 }, + { 0x2551, glyph_SF240000 }, + { 0x2557, glyph_SF250000 }, + { 0x255D, glyph_SF260000 }, + { 0x255C, glyph_SF270000 }, + { 0x255B, glyph_SF280000 }, + { 0x255E, glyph_SF360000 }, + { 0x255F, glyph_SF370000 }, + { 0x255A, glyph_SF380000 }, + { 0x2554, glyph_SF390000 }, + { 0x2569, glyph_SF400000 }, + { 0x2566, glyph_SF410000 }, + { 0x2560, glyph_SF420000 }, + { 0x2550, glyph_SF430000 }, + { 0x256C, glyph_SF440000 }, + { 0x2567, glyph_SF450000 }, + { 0x2568, glyph_SF460000 }, + { 0x2564, glyph_SF470000 }, + { 0x2565, glyph_SF480000 }, + { 0x2559, glyph_SF490000 }, + { 0x2558, glyph_SF500000 }, + { 0x2552, glyph_SF510000 }, + { 0x2553, glyph_SF520000 }, + { 0x256B, glyph_SF530000 }, + { 0x256A, glyph_SF540000 }, + { 0x015A, glyph_Sacute }, + { 0x0160, glyph_Scaron }, + { 0xF6FD, glyph_Scaronsmall }, + { 0x015E, glyph_Scedilla }, + { 0x015C, glyph_Scircumflex }, + { 0x0218, glyph_Scommaaccent }, + { 0x03A3, glyph_Sigma }, + { 0xF773, glyph_Ssmall }, + { 0x0054, glyph_T }, + { 0x03A4, glyph_Tau }, + { 0x0166, glyph_Tbar }, + { 0x0164, glyph_Tcaron }, + { 0x0162, glyph_Tcedilla }, + { 0x021A, glyph_Tcommaaccent }, + { 0x0398, glyph_Theta }, + { 0x00DE, glyph_Thorn }, + { 0xF7FE, glyph_Thornsmall }, + { 0xF6FE, glyph_Tildesmall }, + { 0xF774, glyph_Tsmall }, + { 0x0055, glyph_U }, + { 0x00DA, glyph_Uacute }, + { 0xF7FA, glyph_Uacutesmall }, + { 0x016C, glyph_Ubreve }, + { 0x00DB, glyph_Ucircumflex }, + { 0xF7FB, glyph_Ucircumflexsmall }, + { 0x00DC, glyph_Udieresis }, + { 0xF7FC, glyph_Udieresissmall }, + { 0x00D9, glyph_Ugrave }, + { 0xF7F9, glyph_Ugravesmall }, + { 0x01AF, glyph_Uhorn }, + { 0x0170, glyph_Uhungarumlaut }, + { 0x016A, glyph_Umacron }, + { 0x0172, glyph_Uogonek }, + { 0x03A5, glyph_Upsilon }, + { 0x03D2, glyph_Upsilon1 }, + { 0x03AB, glyph_Upsilondieresis }, + { 0x038E, glyph_Upsilontonos }, + { 0x016E, glyph_Uring }, + { 0xF775, glyph_Usmall }, + { 0x0168, glyph_Utilde }, + { 0x0056, glyph_V }, + { 0xF776, glyph_Vsmall }, + { 0x0057, glyph_W }, + { 0x1E82, glyph_Wacute }, + { 0x0174, glyph_Wcircumflex }, + { 0x1E84, glyph_Wdieresis }, + { 0x1E80, glyph_Wgrave }, + { 0xF777, glyph_Wsmall }, + { 0x0058, glyph_X }, + { 0x039E, glyph_Xi }, + { 0xF778, glyph_Xsmall }, + { 0x0059, glyph_Y }, + { 0x00DD, glyph_Yacute }, + { 0xF7FD, glyph_Yacutesmall }, + { 0x0176, glyph_Ycircumflex }, + { 0x0178, glyph_Ydieresis }, + { 0xF7FF, glyph_Ydieresissmall }, + { 0x1EF2, glyph_Ygrave }, + { 0xF779, glyph_Ysmall }, + { 0x005A, glyph_Z }, + { 0x0179, glyph_Zacute }, + { 0x017D, glyph_Zcaron }, + { 0xF6FF, glyph_Zcaronsmall }, + { 0x017B, glyph_Zdotaccent }, + { 0x0396, glyph_Zeta }, + { 0xF77A, glyph_Zsmall }, + { 0x0061, glyph_a }, + { 0x00E1, glyph_aacute }, + { 0x0103, glyph_abreve }, + { 0x00E2, glyph_acircumflex }, + { 0x00B4, glyph_acute }, + { 0x0301, glyph_acutecomb }, + { 0x00E4, glyph_adieresis }, + { 0x00E6, glyph_ae }, + { 0x01FD, glyph_aeacute }, + { 0x2015, glyph_afii00208 }, + { 0x0410, glyph_afii10017 }, + { 0x0411, glyph_afii10018 }, + { 0x0412, glyph_afii10019 }, + { 0x0413, glyph_afii10020 }, + { 0x0414, glyph_afii10021 }, + { 0x0415, glyph_afii10022 }, + { 0x0401, glyph_afii10023 }, + { 0x0416, glyph_afii10024 }, + { 0x0417, glyph_afii10025 }, + { 0x0418, glyph_afii10026 }, + { 0x0419, glyph_afii10027 }, + { 0x041A, glyph_afii10028 }, + { 0x041B, glyph_afii10029 }, + { 0x041C, glyph_afii10030 }, + { 0x041D, glyph_afii10031 }, + { 0x041E, glyph_afii10032 }, + { 0x041F, glyph_afii10033 }, + { 0x0420, glyph_afii10034 }, + { 0x0421, glyph_afii10035 }, + { 0x0422, glyph_afii10036 }, + { 0x0423, glyph_afii10037 }, + { 0x0424, glyph_afii10038 }, + { 0x0425, glyph_afii10039 }, + { 0x0426, glyph_afii10040 }, + { 0x0427, glyph_afii10041 }, + { 0x0428, glyph_afii10042 }, + { 0x0429, glyph_afii10043 }, + { 0x042A, glyph_afii10044 }, + { 0x042B, glyph_afii10045 }, + { 0x042C, glyph_afii10046 }, + { 0x042D, glyph_afii10047 }, + { 0x042E, glyph_afii10048 }, + { 0x042F, glyph_afii10049 }, + { 0x0490, glyph_afii10050 }, + { 0x0402, glyph_afii10051 }, + { 0x0403, glyph_afii10052 }, + { 0x0404, glyph_afii10053 }, + { 0x0405, glyph_afii10054 }, + { 0x0406, glyph_afii10055 }, + { 0x0407, glyph_afii10056 }, + { 0x0408, glyph_afii10057 }, + { 0x0409, glyph_afii10058 }, + { 0x040A, glyph_afii10059 }, + { 0x040B, glyph_afii10060 }, + { 0x040C, glyph_afii10061 }, + { 0x040E, glyph_afii10062 }, + { 0xF6C4, glyph_afii10063 }, + { 0xF6C5, glyph_afii10064 }, + { 0x0430, glyph_afii10065 }, + { 0x0431, glyph_afii10066 }, + { 0x0432, glyph_afii10067 }, + { 0x0433, glyph_afii10068 }, + { 0x0434, glyph_afii10069 }, + { 0x0435, glyph_afii10070 }, + { 0x0451, glyph_afii10071 }, + { 0x0436, glyph_afii10072 }, + { 0x0437, glyph_afii10073 }, + { 0x0438, glyph_afii10074 }, + { 0x0439, glyph_afii10075 }, + { 0x043A, glyph_afii10076 }, + { 0x043B, glyph_afii10077 }, + { 0x043C, glyph_afii10078 }, + { 0x043D, glyph_afii10079 }, + { 0x043E, glyph_afii10080 }, + { 0x043F, glyph_afii10081 }, + { 0x0440, glyph_afii10082 }, + { 0x0441, glyph_afii10083 }, + { 0x0442, glyph_afii10084 }, + { 0x0443, glyph_afii10085 }, + { 0x0444, glyph_afii10086 }, + { 0x0445, glyph_afii10087 }, + { 0x0446, glyph_afii10088 }, + { 0x0447, glyph_afii10089 }, + { 0x0448, glyph_afii10090 }, + { 0x0449, glyph_afii10091 }, + { 0x044A, glyph_afii10092 }, + { 0x044B, glyph_afii10093 }, + { 0x044C, glyph_afii10094 }, + { 0x044D, glyph_afii10095 }, + { 0x044E, glyph_afii10096 }, + { 0x044F, glyph_afii10097 }, + { 0x0491, glyph_afii10098 }, + { 0x0452, glyph_afii10099 }, + { 0x0453, glyph_afii10100 }, + { 0x0454, glyph_afii10101 }, + { 0x0455, glyph_afii10102 }, + { 0x0456, glyph_afii10103 }, + { 0x0457, glyph_afii10104 }, + { 0x0458, glyph_afii10105 }, + { 0x0459, glyph_afii10106 }, + { 0x045A, glyph_afii10107 }, + { 0x045B, glyph_afii10108 }, + { 0x045C, glyph_afii10109 }, + { 0x045E, glyph_afii10110 }, + { 0x040F, glyph_afii10145 }, + { 0x0462, glyph_afii10146 }, + { 0x0472, glyph_afii10147 }, + { 0x0474, glyph_afii10148 }, + { 0xF6C6, glyph_afii10192 }, + { 0x045F, glyph_afii10193 }, + { 0x0463, glyph_afii10194 }, + { 0x0473, glyph_afii10195 }, + { 0x0475, glyph_afii10196 }, + { 0xF6C7, glyph_afii10831 }, + { 0xF6C8, glyph_afii10832 }, + { 0x04D9, glyph_afii10846 }, + { 0x200E, glyph_afii299 }, + { 0x200F, glyph_afii300 }, + { 0x200D, glyph_afii301 }, + { 0x066A, glyph_afii57381 }, + { 0x060C, glyph_afii57388 }, + { 0x0660, glyph_afii57392 }, + { 0x0661, glyph_afii57393 }, + { 0x0662, glyph_afii57394 }, + { 0x0663, glyph_afii57395 }, + { 0x0664, glyph_afii57396 }, + { 0x0665, glyph_afii57397 }, + { 0x0666, glyph_afii57398 }, + { 0x0667, glyph_afii57399 }, + { 0x0668, glyph_afii57400 }, + { 0x0669, glyph_afii57401 }, + { 0x061B, glyph_afii57403 }, + { 0x061F, glyph_afii57407 }, + { 0x0621, glyph_afii57409 }, + { 0x0622, glyph_afii57410 }, + { 0x0623, glyph_afii57411 }, + { 0x0624, glyph_afii57412 }, + { 0x0625, glyph_afii57413 }, + { 0x0626, glyph_afii57414 }, + { 0x0627, glyph_afii57415 }, + { 0x0628, glyph_afii57416 }, + { 0x0629, glyph_afii57417 }, + { 0x062A, glyph_afii57418 }, + { 0x062B, glyph_afii57419 }, + { 0x062C, glyph_afii57420 }, + { 0x062D, glyph_afii57421 }, + { 0x062E, glyph_afii57422 }, + { 0x062F, glyph_afii57423 }, + { 0x0630, glyph_afii57424 }, + { 0x0631, glyph_afii57425 }, + { 0x0632, glyph_afii57426 }, + { 0x0633, glyph_afii57427 }, + { 0x0634, glyph_afii57428 }, + { 0x0635, glyph_afii57429 }, + { 0x0636, glyph_afii57430 }, + { 0x0637, glyph_afii57431 }, + { 0x0638, glyph_afii57432 }, + { 0x0639, glyph_afii57433 }, + { 0x063A, glyph_afii57434 }, + { 0x0640, glyph_afii57440 }, + { 0x0641, glyph_afii57441 }, + { 0x0642, glyph_afii57442 }, + { 0x0643, glyph_afii57443 }, + { 0x0644, glyph_afii57444 }, + { 0x0645, glyph_afii57445 }, + { 0x0646, glyph_afii57446 }, + { 0x0648, glyph_afii57448 }, + { 0x0649, glyph_afii57449 }, + { 0x064A, glyph_afii57450 }, + { 0x064B, glyph_afii57451 }, + { 0x064C, glyph_afii57452 }, + { 0x064D, glyph_afii57453 }, + { 0x064E, glyph_afii57454 }, + { 0x064F, glyph_afii57455 }, + { 0x0650, glyph_afii57456 }, + { 0x0651, glyph_afii57457 }, + { 0x0652, glyph_afii57458 }, + { 0x0647, glyph_afii57470 }, + { 0x06A4, glyph_afii57505 }, + { 0x067E, glyph_afii57506 }, + { 0x0686, glyph_afii57507 }, + { 0x0698, glyph_afii57508 }, + { 0x06AF, glyph_afii57509 }, + { 0x0679, glyph_afii57511 }, + { 0x0688, glyph_afii57512 }, + { 0x0691, glyph_afii57513 }, + { 0x06BA, glyph_afii57514 }, + { 0x06D2, glyph_afii57519 }, + { 0x06D5, glyph_afii57534 }, + { 0x20AA, glyph_afii57636 }, + { 0x05BE, glyph_afii57645 }, + { 0x05C3, glyph_afii57658 }, + { 0x05D0, glyph_afii57664 }, + { 0x05D1, glyph_afii57665 }, + { 0x05D2, glyph_afii57666 }, + { 0x05D3, glyph_afii57667 }, + { 0x05D4, glyph_afii57668 }, + { 0x05D5, glyph_afii57669 }, + { 0x05D6, glyph_afii57670 }, + { 0x05D7, glyph_afii57671 }, + { 0x05D8, glyph_afii57672 }, + { 0x05D9, glyph_afii57673 }, + { 0x05DA, glyph_afii57674 }, + { 0x05DB, glyph_afii57675 }, + { 0x05DC, glyph_afii57676 }, + { 0x05DD, glyph_afii57677 }, + { 0x05DE, glyph_afii57678 }, + { 0x05DF, glyph_afii57679 }, + { 0x05E0, glyph_afii57680 }, + { 0x05E1, glyph_afii57681 }, + { 0x05E2, glyph_afii57682 }, + { 0x05E3, glyph_afii57683 }, + { 0x05E4, glyph_afii57684 }, + { 0x05E5, glyph_afii57685 }, + { 0x05E6, glyph_afii57686 }, + { 0x05E7, glyph_afii57687 }, + { 0x05E8, glyph_afii57688 }, + { 0x05E9, glyph_afii57689 }, + { 0x05EA, glyph_afii57690 }, + { 0xFB2A, glyph_afii57694 }, + { 0xFB2B, glyph_afii57695 }, + { 0xFB4B, glyph_afii57700 }, + { 0xFB1F, glyph_afii57705 }, + { 0x05F0, glyph_afii57716 }, + { 0x05F1, glyph_afii57717 }, + { 0x05F2, glyph_afii57718 }, + { 0xFB35, glyph_afii57723 }, + { 0x05B4, glyph_afii57793 }, + { 0x05B5, glyph_afii57794 }, + { 0x05B6, glyph_afii57795 }, + { 0x05BB, glyph_afii57796 }, + { 0x05B8, glyph_afii57797 }, + { 0x05B7, glyph_afii57798 }, + { 0x05B0, glyph_afii57799 }, + { 0x05B2, glyph_afii57800 }, + { 0x05B1, glyph_afii57801 }, + { 0x05B3, glyph_afii57802 }, + { 0x05C2, glyph_afii57803 }, + { 0x05C1, glyph_afii57804 }, + { 0x05B9, glyph_afii57806 }, + { 0x05BC, glyph_afii57807 }, + { 0x05BD, glyph_afii57839 }, + { 0x05BF, glyph_afii57841 }, + { 0x05C0, glyph_afii57842 }, + { 0x02BC, glyph_afii57929 }, + { 0x2105, glyph_afii61248 }, + { 0x2113, glyph_afii61289 }, + { 0x2116, glyph_afii61352 }, + { 0x202C, glyph_afii61573 }, + { 0x202D, glyph_afii61574 }, + { 0x202E, glyph_afii61575 }, + { 0x200C, glyph_afii61664 }, + { 0x066D, glyph_afii63167 }, + { 0x02BD, glyph_afii64937 }, + { 0x00E0, glyph_agrave }, + { 0x2135, glyph_aleph }, + { 0x03B1, glyph_alpha }, + { 0x03AC, glyph_alphatonos }, + { 0x0101, glyph_amacron }, + { 0x0026, glyph_ampersand }, + { 0xF726, glyph_ampersandsmall }, + { 0x2220, glyph_angle }, + { 0x2329, glyph_angleleft }, + { 0x232A, glyph_angleright }, + { 0x0387, glyph_anoteleia }, + { 0x0105, glyph_aogonek }, + { 0xF8FF, glyph_apple }, + { 0x2248, glyph_approxequal }, + { 0x00E5, glyph_aring }, + { 0x01FB, glyph_aringacute }, + { 0x2194, glyph_arrowboth }, + { 0x21D4, glyph_arrowdblboth }, + { 0x21D3, glyph_arrowdbldown }, + { 0x21D0, glyph_arrowdblleft }, + { 0x21D2, glyph_arrowdblright }, + { 0x21D1, glyph_arrowdblup }, + { 0x2193, glyph_arrowdown }, + { 0xF8E7, glyph_arrowhorizex }, + { 0x2190, glyph_arrowleft }, + { 0x2192, glyph_arrowright }, + { 0x2191, glyph_arrowup }, + { 0x2195, glyph_arrowupdn }, + { 0x21A8, glyph_arrowupdnbse }, + { 0xF8E6, glyph_arrowvertex }, + { 0x005E, glyph_asciicircum }, + { 0x007E, glyph_asciitilde }, + { 0x002A, glyph_asterisk }, + { 0x2217, glyph_asteriskmath }, + { 0xF6E9, glyph_asuperior }, + { 0x0040, glyph_at }, + { 0x00E3, glyph_atilde }, + { 0x0062, glyph_b }, + { 0x005C, glyph_backslash }, + { 0x007C, glyph_bar }, + { 0x03B2, glyph_beta }, + { 0x2588, glyph_block }, + { 0xF8F4, glyph_braceex }, + { 0x007B, glyph_braceleft }, + { 0xF8F3, glyph_braceleftbt }, + { 0xF8F2, glyph_braceleftmid }, + { 0xF8F1, glyph_bracelefttp }, + { 0x007D, glyph_braceright }, + { 0xF8FE, glyph_bracerightbt }, + { 0xF8FD, glyph_bracerightmid }, + { 0xF8FC, glyph_bracerighttp }, + { 0x005B, glyph_bracketleft }, + { 0xF8F0, glyph_bracketleftbt }, + { 0xF8EF, glyph_bracketleftex }, + { 0xF8EE, glyph_bracketlefttp }, + { 0x005D, glyph_bracketright }, + { 0xF8FB, glyph_bracketrightbt }, + { 0xF8FA, glyph_bracketrightex }, + { 0xF8F9, glyph_bracketrighttp }, + { 0x02D8, glyph_breve }, + { 0x00A6, glyph_brokenbar }, + { 0xF6EA, glyph_bsuperior }, + { 0x2022, glyph_bullet }, + { 0x2219, glyph_bulletoperator }, + { 0x0063, glyph_c }, + { 0x0107, glyph_cacute }, + { 0x02C7, glyph_caron }, + { 0x21B5, glyph_carriagereturn }, + { 0x010D, glyph_ccaron }, + { 0x00E7, glyph_ccedilla }, + { 0x0109, glyph_ccircumflex }, + { 0x010B, glyph_cdotaccent }, + { 0x00B8, glyph_cedilla }, + { 0x00A2, glyph_cent }, + { 0xF6DF, glyph_centinferior }, + { 0xF7A2, glyph_centoldstyle }, + { 0xF6E0, glyph_centsuperior }, + { 0x03C7, glyph_chi }, + { 0x25CB, glyph_circle }, + { 0x2297, glyph_circlemultiply }, + { 0x2295, glyph_circleplus }, + { 0x02C6, glyph_circumflex }, + { 0x2663, glyph_club }, + { 0x003A, glyph_colon }, + { 0x20A1, glyph_colonmonetary }, + { 0x002C, glyph_comma }, + { 0xF6C3, glyph_commaaccent }, + { 0xF6E1, glyph_commainferior }, + { 0xF6E2, glyph_commasuperior }, + { 0x2245, glyph_congruent }, + { 0x00A9, glyph_copyright }, + { 0xF8E9, glyph_copyrightsans }, + { 0xF6D9, glyph_copyrightserif }, + { 0x00A4, glyph_currency }, + { 0xF6D1, glyph_cyrBreve }, + { 0xF6D2, glyph_cyrFlex }, + { 0xF6D4, glyph_cyrbreve }, + { 0xF6D5, glyph_cyrflex }, + { 0x0064, glyph_d }, + { 0x2020, glyph_dagger }, + { 0x2021, glyph_daggerdbl }, + { 0xF6D3, glyph_dblGrave }, + { 0xF6D6, glyph_dblgrave }, + { 0x010F, glyph_dcaron }, + { 0x0111, glyph_dcroat }, + { 0x00B0, glyph_degree }, + { 0x03B4, glyph_delta }, + { 0x2666, glyph_diamond }, + { 0x00A8, glyph_dieresis }, + { 0xF6D7, glyph_dieresisacute }, + { 0xF6D8, glyph_dieresisgrave }, + { 0x0385, glyph_dieresistonos }, + { 0x00F7, glyph_divide }, + { 0x2215, glyph_divisionslash }, + { 0x2593, glyph_dkshade }, + { 0x2584, glyph_dnblock }, + { 0x0024, glyph_dollar }, + { 0xF6E3, glyph_dollarinferior }, + { 0xF724, glyph_dollaroldstyle }, + { 0xF6E4, glyph_dollarsuperior }, + { 0x20AB, glyph_dong }, + { 0x02D9, glyph_dotaccent }, + { 0x0323, glyph_dotbelowcomb }, + { 0x0131, glyph_dotlessi }, + { 0xF6BE, glyph_dotlessj }, + { 0x22C5, glyph_dotmath }, + { 0xF6EB, glyph_dsuperior }, + { 0x0065, glyph_e }, + { 0x00E9, glyph_eacute }, + { 0x0115, glyph_ebreve }, + { 0x011B, glyph_ecaron }, + { 0x00EA, glyph_ecircumflex }, + { 0x00EB, glyph_edieresis }, + { 0x0117, glyph_edotaccent }, + { 0x00E8, glyph_egrave }, + { 0x0038, glyph_eight }, + { 0x2088, glyph_eightinferior }, + { 0xF738, glyph_eightoldstyle }, + { 0x2078, glyph_eightsuperior }, + { 0x2208, glyph_element }, + { 0x2026, glyph_ellipsis }, + { 0x0113, glyph_emacron }, + { 0x2014, glyph_emdash }, + { 0x2205, glyph_emptyset }, + { 0x2013, glyph_endash }, + { 0x014B, glyph_eng }, + { 0x0119, glyph_eogonek }, + { 0x03B5, glyph_epsilon }, + { 0x03AD, glyph_epsilontonos }, + { 0x003D, glyph_equal }, + { 0x2261, glyph_equivalence }, + { 0x212E, glyph_estimated }, + { 0xF6EC, glyph_esuperior }, + { 0x03B7, glyph_eta }, + { 0x03AE, glyph_etatonos }, + { 0x00F0, glyph_eth }, + { 0x0021, glyph_exclam }, + { 0x203C, glyph_exclamdbl }, + { 0x00A1, glyph_exclamdown }, + { 0xF7A1, glyph_exclamdownsmall }, + { 0xF721, glyph_exclamsmall }, + { 0x2203, glyph_existential }, + { 0x0066, glyph_f }, + { 0x2640, glyph_female }, + { 0xFB00, glyph_ff }, + { 0xFB03, glyph_ffi }, + { 0xFB04, glyph_ffl }, + { 0xFB01, glyph_fi }, + { 0x2012, glyph_figuredash }, + { 0x25A0, glyph_filledbox }, + { 0x25AC, glyph_filledrect }, + { 0x02C9, glyph_firsttonechinese }, + { 0x0035, glyph_five }, + { 0x215D, glyph_fiveeighths }, + { 0x2085, glyph_fiveinferior }, + { 0xF735, glyph_fiveoldstyle }, + { 0x2075, glyph_fivesuperior }, + { 0xFB02, glyph_fl }, + { 0x0192, glyph_florin }, + { 0x0034, glyph_four }, + { 0x2084, glyph_fourinferior }, + { 0xF734, glyph_fouroldstyle }, + { 0x2074, glyph_foursuperior }, + { 0x2044, glyph_fraction }, + { 0x20A3, glyph_franc }, + { 0x0067, glyph_g }, + { 0x03B3, glyph_gamma }, + { 0x011F, glyph_gbreve }, + { 0x01E7, glyph_gcaron }, + { 0x011D, glyph_gcircumflex }, + { 0x0123, glyph_gcommaaccent }, + { 0x0121, glyph_gdotaccent }, + { 0x00DF, glyph_germandbls }, + { 0x2207, glyph_gradient }, + { 0x0060, glyph_grave }, + { 0x0300, glyph_gravecomb }, + { 0x003E, glyph_greater }, + { 0x2265, glyph_greaterequal }, + { 0x00AB, glyph_guillemotleft }, + { 0x00BB, glyph_guillemotright }, + { 0x2039, glyph_guilsinglleft }, + { 0x203A, glyph_guilsinglright }, + { 0x0068, glyph_h }, + { 0x0127, glyph_hbar }, + { 0x0125, glyph_hcircumflex }, + { 0x2665, glyph_heart }, + { 0x0309, glyph_hookabovecomb }, + { 0x2302, glyph_house }, + { 0x02DD, glyph_hungarumlaut }, + { 0x002D, glyph_hyphen }, + { 0xF6E5, glyph_hypheninferior }, + { 0xF6E6, glyph_hyphensuperior }, + { 0x0069, glyph_i }, + { 0x00ED, glyph_iacute }, + { 0x012D, glyph_ibreve }, + { 0x00EE, glyph_icircumflex }, + { 0x00EF, glyph_idieresis }, + { 0x00EC, glyph_igrave }, + { 0x0133, glyph_ij }, + { 0x012B, glyph_imacron }, + { 0x221E, glyph_infinity }, + { 0x222B, glyph_integral }, + { 0x2321, glyph_integralbt }, + { 0xF8F5, glyph_integralex }, + { 0x2320, glyph_integraltp }, + { 0x2229, glyph_intersection }, + { 0x25D8, glyph_invbullet }, + { 0x25D9, glyph_invcircle }, + { 0x263B, glyph_invsmileface }, + { 0x012F, glyph_iogonek }, + { 0x03B9, glyph_iota }, + { 0x03CA, glyph_iotadieresis }, + { 0x0390, glyph_iotadieresistonos }, + { 0x03AF, glyph_iotatonos }, + { 0xF6ED, glyph_isuperior }, + { 0x0129, glyph_itilde }, + { 0x006A, glyph_j }, + { 0x0135, glyph_jcircumflex }, + { 0x006B, glyph_k }, + { 0x03BA, glyph_kappa }, + { 0x0137, glyph_kcommaaccent }, + { 0x0138, glyph_kgreenlandic }, + { 0x006C, glyph_l }, + { 0x013A, glyph_lacute }, + { 0x03BB, glyph_lambda }, + { 0x013E, glyph_lcaron }, + { 0x013C, glyph_lcommaaccent }, + { 0x0140, glyph_ldot }, + { 0x003C, glyph_less }, + { 0x2264, glyph_lessequal }, + { 0x258C, glyph_lfblock }, + { 0x20A4, glyph_lira }, + { 0xF6C0, glyph_ll }, + { 0x2227, glyph_logicaland }, + { 0x00AC, glyph_logicalnot }, + { 0x2228, glyph_logicalor }, + { 0x017F, glyph_longs }, + { 0x25CA, glyph_lozenge }, + { 0x0142, glyph_lslash }, + { 0xF6EE, glyph_lsuperior }, + { 0x2591, glyph_ltshade }, + { 0x006D, glyph_m }, + { 0x00AF, glyph_macron }, + { 0x2642, glyph_male }, + { 0x2212, glyph_minus }, + { 0x2032, glyph_minute }, + { 0xF6EF, glyph_msuperior }, + { 0x00B5, glyph_mu }, + { 0x03BC, glyph_mugreek }, + { 0x00D7, glyph_multiply }, + { 0x266A, glyph_musicalnote }, + { 0x266B, glyph_musicalnotedbl }, + { 0x006E, glyph_n }, + { 0x0144, glyph_nacute }, + { 0x0149, glyph_napostrophe }, + { 0x00A0, glyph_nbspace }, + { 0x0148, glyph_ncaron }, + { 0x0146, glyph_ncommaaccent }, + { 0x0039, glyph_nine }, + { 0x2089, glyph_nineinferior }, + { 0xF739, glyph_nineoldstyle }, + { 0x2079, glyph_ninesuperior }, + { 0x2209, glyph_notelement }, + { 0x2260, glyph_notequal }, + { 0x2284, glyph_notsubset }, + { 0x207F, glyph_nsuperior }, + { 0x00F1, glyph_ntilde }, + { 0x03BD, glyph_nu }, + { 0x0023, glyph_numbersign }, + { 0x006F, glyph_o }, + { 0x00F3, glyph_oacute }, + { 0x014F, glyph_obreve }, + { 0x00F4, glyph_ocircumflex }, + { 0x00F6, glyph_odieresis }, + { 0x0153, glyph_oe }, + { 0x02DB, glyph_ogonek }, + { 0x00F2, glyph_ograve }, + { 0x01A1, glyph_ohorn }, + { 0x0151, glyph_ohungarumlaut }, + { 0x014D, glyph_omacron }, + { 0x03C9, glyph_omega }, + { 0x03D6, glyph_omega1 }, + { 0x03CE, glyph_omegatonos }, + { 0x03BF, glyph_omicron }, + { 0x03CC, glyph_omicrontonos }, + { 0x0031, glyph_one }, + { 0x2024, glyph_onedotenleader }, + { 0x215B, glyph_oneeighth }, + { 0xF6DC, glyph_onefitted }, + { 0x00BD, glyph_onehalf }, + { 0x2081, glyph_oneinferior }, + { 0xF731, glyph_oneoldstyle }, + { 0x00BC, glyph_onequarter }, + { 0x00B9, glyph_onesuperior }, + { 0x2153, glyph_onethird }, + { 0x25E6, glyph_openbullet }, + { 0x00AA, glyph_ordfeminine }, + { 0x00BA, glyph_ordmasculine }, + { 0x221F, glyph_orthogonal }, + { 0x00F8, glyph_oslash }, + { 0x01FF, glyph_oslashacute }, + { 0xF6F0, glyph_osuperior }, + { 0x00F5, glyph_otilde }, + { 0x0070, glyph_p }, + { 0x00B6, glyph_paragraph }, + { 0x0028, glyph_parenleft }, + { 0xF8ED, glyph_parenleftbt }, + { 0xF8EC, glyph_parenleftex }, + { 0x208D, glyph_parenleftinferior }, + { 0x207D, glyph_parenleftsuperior }, + { 0xF8EB, glyph_parenlefttp }, + { 0x0029, glyph_parenright }, + { 0xF8F8, glyph_parenrightbt }, + { 0xF8F7, glyph_parenrightex }, + { 0x208E, glyph_parenrightinferior }, + { 0x207E, glyph_parenrightsuperior }, + { 0xF8F6, glyph_parenrighttp }, + { 0x2202, glyph_partialdiff }, + { 0x0025, glyph_percent }, + { 0x002E, glyph_period }, + { 0x00B7, glyph_periodcentered }, + { 0xF6E7, glyph_periodinferior }, + { 0xF6E8, glyph_periodsuperior }, + { 0x22A5, glyph_perpendicular }, + { 0x2030, glyph_perthousand }, + { 0x20A7, glyph_peseta }, + { 0x03C6, glyph_phi }, + { 0x03D5, glyph_phi1 }, + { 0x03C0, glyph_pi }, + { 0x002B, glyph_plus }, + { 0x00B1, glyph_plusminus }, + { 0x211E, glyph_prescription }, + { 0x220F, glyph_product }, + { 0x2282, glyph_propersubset }, + { 0x2283, glyph_propersuperset }, + { 0x221D, glyph_proportional }, + { 0x03C8, glyph_psi }, + { 0x0071, glyph_q }, + { 0x003F, glyph_question }, + { 0x00BF, glyph_questiondown }, + { 0xF7BF, glyph_questiondownsmall }, + { 0xF73F, glyph_questionsmall }, + { 0x0022, glyph_quotedbl }, + { 0x201E, glyph_quotedblbase }, + { 0x201C, glyph_quotedblleft }, + { 0x201D, glyph_quotedblright }, + { 0x2018, glyph_quoteleft }, + { 0x201B, glyph_quotereversed }, + { 0x2019, glyph_quoteright }, + { 0x201A, glyph_quotesinglbase }, + { 0x0027, glyph_quotesingle }, + { 0x0072, glyph_r }, + { 0x0155, glyph_racute }, + { 0x221A, glyph_radical }, + { 0xF8E5, glyph_radicalex }, + { 0x0159, glyph_rcaron }, + { 0x0157, glyph_rcommaaccent }, + { 0x2286, glyph_reflexsubset }, + { 0x2287, glyph_reflexsuperset }, + { 0x00AE, glyph_registered }, + { 0xF8E8, glyph_registersans }, + { 0xF6DA, glyph_registerserif }, + { 0x2310, glyph_revlogicalnot }, + { 0x03C1, glyph_rho }, + { 0x02DA, glyph_ring }, + { 0xF6F1, glyph_rsuperior }, + { 0x2590, glyph_rtblock }, + { 0xF6DD, glyph_rupiah }, + { 0x0073, glyph_s }, + { 0x015B, glyph_sacute }, + { 0x0161, glyph_scaron }, + { 0x015F, glyph_scedilla }, + { 0x015D, glyph_scircumflex }, + { 0x0219, glyph_scommaaccent }, + { 0x2033, glyph_second }, + { 0x00A7, glyph_section }, + { 0x003B, glyph_semicolon }, + { 0x0037, glyph_seven }, + { 0x215E, glyph_seveneighths }, + { 0x2087, glyph_seveninferior }, + { 0xF737, glyph_sevenoldstyle }, + { 0x2077, glyph_sevensuperior }, + { 0x00AD, glyph_sfthyphen }, + { 0x2592, glyph_shade }, + { 0x03C3, glyph_sigma }, + { 0x03C2, glyph_sigma1 }, + { 0x223C, glyph_similar }, + { 0x0036, glyph_six }, + { 0x2086, glyph_sixinferior }, + { 0xF736, glyph_sixoldstyle }, + { 0x2076, glyph_sixsuperior }, + { 0x002F, glyph_slash }, + { 0x263A, glyph_smileface }, + { 0x0020, glyph_space }, + { 0x2660, glyph_spade }, + { 0xF6F2, glyph_ssuperior }, + { 0x00A3, glyph_sterling }, + { 0x220B, glyph_suchthat }, + { 0x2211, glyph_summation }, + { 0x263C, glyph_sun }, + { 0x0074, glyph_t }, + { 0x03C4, glyph_tau }, + { 0x0167, glyph_tbar }, + { 0x0165, glyph_tcaron }, + { 0x0163, glyph_tcedilla }, + { 0x021B, glyph_tcommaaccent }, + { 0x2234, glyph_therefore }, + { 0x03B8, glyph_theta }, + { 0x03D1, glyph_theta1 }, + { 0x00FE, glyph_thorn }, + { 0x0033, glyph_three }, + { 0x215C, glyph_threeeighths }, + { 0x2083, glyph_threeinferior }, + { 0xF733, glyph_threeoldstyle }, + { 0x00BE, glyph_threequarters }, + { 0xF6DE, glyph_threequartersemdash }, + { 0x00B3, glyph_threesuperior }, + { 0x02DC, glyph_tilde }, + { 0x0303, glyph_tildecomb }, + { 0x0384, glyph_tonos }, + { 0x2122, glyph_trademark }, + { 0xF8EA, glyph_trademarksans }, + { 0xF6DB, glyph_trademarkserif }, + { 0x25BC, glyph_triagdn }, + { 0x25C4, glyph_triaglf }, + { 0x25BA, glyph_triagrt }, + { 0x25B2, glyph_triagup }, + { 0xF6F3, glyph_tsuperior }, + { 0x0032, glyph_two }, + { 0x2025, glyph_twodotenleader }, + { 0x2082, glyph_twoinferior }, + { 0xF732, glyph_twooldstyle }, + { 0x00B2, glyph_twosuperior }, + { 0x2154, glyph_twothirds }, + { 0x0075, glyph_u }, + { 0x00FA, glyph_uacute }, + { 0x016D, glyph_ubreve }, + { 0x00FB, glyph_ucircumflex }, + { 0x00FC, glyph_udieresis }, + { 0x00F9, glyph_ugrave }, + { 0x01B0, glyph_uhorn }, + { 0x0171, glyph_uhungarumlaut }, + { 0x016B, glyph_umacron }, + { 0x005F, glyph_underscore }, + { 0x2017, glyph_underscoredbl }, + { 0x222A, glyph_union }, + { 0x2200, glyph_universal }, + { 0x0173, glyph_uogonek }, + { 0x2580, glyph_upblock }, + { 0x03C5, glyph_upsilon }, + { 0x03CB, glyph_upsilondieresis }, + { 0x03B0, glyph_upsilondieresistonos }, + { 0x03CD, glyph_upsilontonos }, + { 0x016F, glyph_uring }, + { 0x0169, glyph_utilde }, + { 0x0076, glyph_v }, + { 0x0077, glyph_w }, + { 0x1E83, glyph_wacute }, + { 0x0175, glyph_wcircumflex }, + { 0x1E85, glyph_wdieresis }, + { 0x2118, glyph_weierstrass }, + { 0x1E81, glyph_wgrave }, + { 0x0078, glyph_x }, + { 0x03BE, glyph_xi }, + { 0x0079, glyph_y }, + { 0x00FD, glyph_yacute }, + { 0x0177, glyph_ycircumflex }, + { 0x00FF, glyph_ydieresis }, + { 0x00A5, glyph_yen }, + { 0x1EF3, glyph_ygrave }, + { 0x007A, glyph_z }, + { 0x017A, glyph_zacute }, + { 0x017E, glyph_zcaron }, + { 0x017C, glyph_zdotaccent }, + { 0x0030, glyph_zero }, + { 0x2080, glyph_zeroinferior }, + { 0xF730, glyph_zerooldstyle }, + { 0x2070, glyph_zerosuperior }, + { 0x03B6, glyph_zeta }, +#else +#endif +}; /* tab_agl2uni */ + +/* + * Adobe Glyph List (AGL) version 1.2 - sorted by Unicode values + */ +static const pdc_glyph_tab tab_uni2agl[] = +{ + { 0x0020, glyph_space }, + { 0x0021, glyph_exclam }, + { 0x0022, glyph_quotedbl }, + { 0x0023, glyph_numbersign }, + { 0x0024, glyph_dollar }, + { 0x0025, glyph_percent }, + { 0x0026, glyph_ampersand }, + { 0x0027, glyph_quotesingle }, + { 0x0028, glyph_parenleft }, + { 0x0029, glyph_parenright }, + { 0x002A, glyph_asterisk }, + { 0x002B, glyph_plus }, + { 0x002C, glyph_comma }, + { 0x002D, glyph_hyphen }, + { 0x002E, glyph_period }, + { 0x002F, glyph_slash }, + { 0x0030, glyph_zero }, + { 0x0031, glyph_one }, + { 0x0032, glyph_two }, + { 0x0033, glyph_three }, + { 0x0034, glyph_four }, + { 0x0035, glyph_five }, + { 0x0036, glyph_six }, + { 0x0037, glyph_seven }, + { 0x0038, glyph_eight }, + { 0x0039, glyph_nine }, + { 0x003A, glyph_colon }, + { 0x003B, glyph_semicolon }, + { 0x003C, glyph_less }, + { 0x003D, glyph_equal }, + { 0x003E, glyph_greater }, + { 0x003F, glyph_question }, + { 0x0040, glyph_at }, + { 0x0041, glyph_A }, + { 0x0042, glyph_B }, + { 0x0043, glyph_C }, + { 0x0044, glyph_D }, + { 0x0045, glyph_E }, + { 0x0046, glyph_F }, + { 0x0047, glyph_G }, + { 0x0048, glyph_H }, + { 0x0049, glyph_I }, + { 0x004A, glyph_J }, + { 0x004B, glyph_K }, + { 0x004C, glyph_L }, + { 0x004D, glyph_M }, + { 0x004E, glyph_N }, + { 0x004F, glyph_O }, + { 0x0050, glyph_P }, + { 0x0051, glyph_Q }, + { 0x0052, glyph_R }, + { 0x0053, glyph_S }, + { 0x0054, glyph_T }, + { 0x0055, glyph_U }, + { 0x0056, glyph_V }, + { 0x0057, glyph_W }, + { 0x0058, glyph_X }, + { 0x0059, glyph_Y }, + { 0x005A, glyph_Z }, + { 0x005B, glyph_bracketleft }, + { 0x005C, glyph_backslash }, + { 0x005D, glyph_bracketright }, + { 0x005E, glyph_asciicircum }, + { 0x005F, glyph_underscore }, + { 0x0060, glyph_grave }, + { 0x0061, glyph_a }, + { 0x0062, glyph_b }, + { 0x0063, glyph_c }, + { 0x0064, glyph_d }, + { 0x0065, glyph_e }, + { 0x0066, glyph_f }, + { 0x0067, glyph_g }, + { 0x0068, glyph_h }, + { 0x0069, glyph_i }, + { 0x006A, glyph_j }, + { 0x006B, glyph_k }, + { 0x006C, glyph_l }, + { 0x006D, glyph_m }, + { 0x006E, glyph_n }, + { 0x006F, glyph_o }, + { 0x0070, glyph_p }, + { 0x0071, glyph_q }, + { 0x0072, glyph_r }, + { 0x0073, glyph_s }, + { 0x0074, glyph_t }, + { 0x0075, glyph_u }, + { 0x0076, glyph_v }, + { 0x0077, glyph_w }, + { 0x0078, glyph_x }, + { 0x0079, glyph_y }, + { 0x007A, glyph_z }, + { 0x007B, glyph_braceleft }, + { 0x007C, glyph_bar }, + { 0x007D, glyph_braceright }, + { 0x007E, glyph_asciitilde }, + { 0x00A0, glyph_nbspace }, + { 0x00A1, glyph_exclamdown }, + { 0x00A2, glyph_cent }, + { 0x00A3, glyph_sterling }, + { 0x00A4, glyph_currency }, + { 0x00A5, glyph_yen }, + { 0x00A6, glyph_brokenbar }, + { 0x00A7, glyph_section }, + { 0x00A8, glyph_dieresis }, + { 0x00A9, glyph_copyright }, + { 0x00AA, glyph_ordfeminine }, + { 0x00AB, glyph_guillemotleft }, + { 0x00AC, glyph_logicalnot }, + { 0x00AD, glyph_sfthyphen }, + { 0x00AE, glyph_registered }, + { 0x00AF, glyph_macron }, + { 0x00B0, glyph_degree }, + { 0x00B1, glyph_plusminus }, + { 0x00B2, glyph_twosuperior }, + { 0x00B3, glyph_threesuperior }, + { 0x00B4, glyph_acute }, + { 0x00B5, glyph_mu }, + { 0x00B6, glyph_paragraph }, + { 0x00B7, glyph_periodcentered }, + { 0x00B8, glyph_cedilla }, + { 0x00B9, glyph_onesuperior }, + { 0x00BA, glyph_ordmasculine }, + { 0x00BB, glyph_guillemotright }, + { 0x00BC, glyph_onequarter }, + { 0x00BD, glyph_onehalf }, + { 0x00BE, glyph_threequarters }, + { 0x00BF, glyph_questiondown }, + { 0x00C0, glyph_Agrave }, + { 0x00C1, glyph_Aacute }, + { 0x00C2, glyph_Acircumflex }, + { 0x00C3, glyph_Atilde }, + { 0x00C4, glyph_Adieresis }, + { 0x00C5, glyph_Aring }, + { 0x00C6, glyph_AE }, + { 0x00C7, glyph_Ccedilla }, + { 0x00C8, glyph_Egrave }, + { 0x00C9, glyph_Eacute }, + { 0x00CA, glyph_Ecircumflex }, + { 0x00CB, glyph_Edieresis }, + { 0x00CC, glyph_Igrave }, + { 0x00CD, glyph_Iacute }, + { 0x00CE, glyph_Icircumflex }, + { 0x00CF, glyph_Idieresis }, + { 0x00D0, glyph_Eth }, + { 0x00D1, glyph_Ntilde }, + { 0x00D2, glyph_Ograve }, + { 0x00D3, glyph_Oacute }, + { 0x00D4, glyph_Ocircumflex }, + { 0x00D5, glyph_Otilde }, + { 0x00D6, glyph_Odieresis }, + { 0x00D7, glyph_multiply }, + { 0x00D8, glyph_Oslash }, + { 0x00D9, glyph_Ugrave }, + { 0x00DA, glyph_Uacute }, + { 0x00DB, glyph_Ucircumflex }, + { 0x00DC, glyph_Udieresis }, + { 0x00DD, glyph_Yacute }, + { 0x00DE, glyph_Thorn }, + { 0x00DF, glyph_germandbls }, + { 0x00E0, glyph_agrave }, + { 0x00E1, glyph_aacute }, + { 0x00E2, glyph_acircumflex }, + { 0x00E3, glyph_atilde }, + { 0x00E4, glyph_adieresis }, + { 0x00E5, glyph_aring }, + { 0x00E6, glyph_ae }, + { 0x00E7, glyph_ccedilla }, + { 0x00E8, glyph_egrave }, + { 0x00E9, glyph_eacute }, + { 0x00EA, glyph_ecircumflex }, + { 0x00EB, glyph_edieresis }, + { 0x00EC, glyph_igrave }, + { 0x00ED, glyph_iacute }, + { 0x00EE, glyph_icircumflex }, + { 0x00EF, glyph_idieresis }, + { 0x00F0, glyph_eth }, + { 0x00F1, glyph_ntilde }, + { 0x00F2, glyph_ograve }, + { 0x00F3, glyph_oacute }, + { 0x00F4, glyph_ocircumflex }, + { 0x00F5, glyph_otilde }, + { 0x00F6, glyph_odieresis }, + { 0x00F7, glyph_divide }, + { 0x00F8, glyph_oslash }, + { 0x00F9, glyph_ugrave }, + { 0x00FA, glyph_uacute }, + { 0x00FB, glyph_ucircumflex }, + { 0x00FC, glyph_udieresis }, + { 0x00FD, glyph_yacute }, + { 0x00FE, glyph_thorn }, + { 0x00FF, glyph_ydieresis }, + { 0x0100, glyph_Amacron }, + { 0x0101, glyph_amacron }, + { 0x0102, glyph_Abreve }, + { 0x0103, glyph_abreve }, + { 0x0104, glyph_Aogonek }, + { 0x0105, glyph_aogonek }, + { 0x0106, glyph_Cacute }, + { 0x0107, glyph_cacute }, + { 0x0108, glyph_Ccircumflex }, + { 0x0109, glyph_ccircumflex }, + { 0x010A, glyph_Cdotaccent }, + { 0x010B, glyph_cdotaccent }, + { 0x010C, glyph_Ccaron }, + { 0x010D, glyph_ccaron }, + { 0x010E, glyph_Dcaron }, + { 0x010F, glyph_dcaron }, + { 0x0110, glyph_Dcroat }, + { 0x0111, glyph_dcroat }, + { 0x0112, glyph_Emacron }, + { 0x0113, glyph_emacron }, + { 0x0114, glyph_Ebreve }, + { 0x0115, glyph_ebreve }, + { 0x0116, glyph_Edotaccent }, + { 0x0117, glyph_edotaccent }, + { 0x0118, glyph_Eogonek }, + { 0x0119, glyph_eogonek }, + { 0x011A, glyph_Ecaron }, + { 0x011B, glyph_ecaron }, + { 0x011C, glyph_Gcircumflex }, + { 0x011D, glyph_gcircumflex }, + { 0x011E, glyph_Gbreve }, + { 0x011F, glyph_gbreve }, + { 0x0120, glyph_Gdotaccent }, + { 0x0121, glyph_gdotaccent }, + { 0x0122, glyph_Gcommaaccent }, + { 0x0123, glyph_gcommaaccent }, + { 0x0124, glyph_Hcircumflex }, + { 0x0125, glyph_hcircumflex }, + { 0x0126, glyph_Hbar }, + { 0x0127, glyph_hbar }, + { 0x0128, glyph_Itilde }, + { 0x0129, glyph_itilde }, + { 0x012A, glyph_Imacron }, + { 0x012B, glyph_imacron }, + { 0x012C, glyph_Ibreve }, + { 0x012D, glyph_ibreve }, + { 0x012E, glyph_Iogonek }, + { 0x012F, glyph_iogonek }, + { 0x0130, glyph_Idotaccent }, + { 0x0131, glyph_dotlessi }, + { 0x0132, glyph_IJ }, + { 0x0133, glyph_ij }, + { 0x0134, glyph_Jcircumflex }, + { 0x0135, glyph_jcircumflex }, + { 0x0136, glyph_Kcommaaccent }, + { 0x0137, glyph_kcommaaccent }, + { 0x0138, glyph_kgreenlandic }, + { 0x0139, glyph_Lacute }, + { 0x013A, glyph_lacute }, + { 0x013B, glyph_Lcommaaccent }, + { 0x013C, glyph_lcommaaccent }, + { 0x013D, glyph_Lcaron }, + { 0x013E, glyph_lcaron }, + { 0x013F, glyph_Ldot }, + { 0x0140, glyph_ldot }, + { 0x0141, glyph_Lslash }, + { 0x0142, glyph_lslash }, + { 0x0143, glyph_Nacute }, + { 0x0144, glyph_nacute }, + { 0x0145, glyph_Ncommaaccent }, + { 0x0146, glyph_ncommaaccent }, + { 0x0147, glyph_Ncaron }, + { 0x0148, glyph_ncaron }, + { 0x0149, glyph_napostrophe }, + { 0x014A, glyph_Eng }, + { 0x014B, glyph_eng }, + { 0x014C, glyph_Omacron }, + { 0x014D, glyph_omacron }, + { 0x014E, glyph_Obreve }, + { 0x014F, glyph_obreve }, + { 0x0150, glyph_Ohungarumlaut }, + { 0x0151, glyph_ohungarumlaut }, + { 0x0152, glyph_OE }, + { 0x0153, glyph_oe }, + { 0x0154, glyph_Racute }, + { 0x0155, glyph_racute }, + { 0x0156, glyph_Rcommaaccent }, + { 0x0157, glyph_rcommaaccent }, + { 0x0158, glyph_Rcaron }, + { 0x0159, glyph_rcaron }, + { 0x015A, glyph_Sacute }, + { 0x015B, glyph_sacute }, + { 0x015C, glyph_Scircumflex }, + { 0x015D, glyph_scircumflex }, + { 0x015E, glyph_Scedilla }, + { 0x015F, glyph_scedilla }, + { 0x0160, glyph_Scaron }, + { 0x0161, glyph_scaron }, + { 0x0162, glyph_Tcedilla }, + { 0x0163, glyph_tcedilla }, + { 0x0164, glyph_Tcaron }, + { 0x0165, glyph_tcaron }, + { 0x0166, glyph_Tbar }, + { 0x0167, glyph_tbar }, + { 0x0168, glyph_Utilde }, + { 0x0169, glyph_utilde }, + { 0x016A, glyph_Umacron }, + { 0x016B, glyph_umacron }, + { 0x016C, glyph_Ubreve }, + { 0x016D, glyph_ubreve }, + { 0x016E, glyph_Uring }, + { 0x016F, glyph_uring }, + { 0x0170, glyph_Uhungarumlaut }, + { 0x0171, glyph_uhungarumlaut }, + { 0x0172, glyph_Uogonek }, + { 0x0173, glyph_uogonek }, + { 0x0174, glyph_Wcircumflex }, + { 0x0175, glyph_wcircumflex }, + { 0x0176, glyph_Ycircumflex }, + { 0x0177, glyph_ycircumflex }, + { 0x0178, glyph_Ydieresis }, + { 0x0179, glyph_Zacute }, + { 0x017A, glyph_zacute }, + { 0x017B, glyph_Zdotaccent }, + { 0x017C, glyph_zdotaccent }, + { 0x017D, glyph_Zcaron }, + { 0x017E, glyph_zcaron }, + { 0x017F, glyph_longs }, + { 0x0192, glyph_florin }, + { 0x01A0, glyph_Ohorn }, + { 0x01A1, glyph_ohorn }, + { 0x01AF, glyph_Uhorn }, + { 0x01B0, glyph_uhorn }, + { 0x01E6, glyph_Gcaron }, + { 0x01E7, glyph_gcaron }, + { 0x01FA, glyph_Aringacute }, + { 0x01FB, glyph_aringacute }, + { 0x01FC, glyph_AEacute }, + { 0x01FD, glyph_aeacute }, + { 0x01FE, glyph_Oslashacute }, + { 0x01FF, glyph_oslashacute }, + { 0x0218, glyph_Scommaaccent }, + { 0x0219, glyph_scommaaccent }, + { 0x021A, glyph_Tcommaaccent }, + { 0x021B, glyph_tcommaaccent }, + { 0x02BC, glyph_afii57929 }, + { 0x02BD, glyph_afii64937 }, + { 0x02C6, glyph_circumflex }, + { 0x02C7, glyph_caron }, + { 0x02C9, glyph_firsttonechinese }, + { 0x02D8, glyph_breve }, + { 0x02D9, glyph_dotaccent }, + { 0x02DA, glyph_ring }, + { 0x02DB, glyph_ogonek }, + { 0x02DC, glyph_tilde }, + { 0x02DD, glyph_hungarumlaut }, + { 0x0300, glyph_gravecomb }, + { 0x0301, glyph_acutecomb }, + { 0x0303, glyph_tildecomb }, + { 0x0309, glyph_hookabovecomb }, + { 0x0323, glyph_dotbelowcomb }, + { 0x0384, glyph_tonos }, + { 0x0385, glyph_dieresistonos }, + { 0x0386, glyph_Alphatonos }, + { 0x0387, glyph_anoteleia }, + { 0x0388, glyph_Epsilontonos }, + { 0x0389, glyph_Etatonos }, + { 0x038A, glyph_Iotatonos }, + { 0x038C, glyph_Omicrontonos }, + { 0x038E, glyph_Upsilontonos }, + { 0x038F, glyph_Omegatonos }, + { 0x0390, glyph_iotadieresistonos }, + { 0x0391, glyph_Alpha }, + { 0x0392, glyph_Beta }, + { 0x0393, glyph_Gamma }, + { 0x0394, glyph_Deltagreek }, + { 0x0395, glyph_Epsilon }, + { 0x0396, glyph_Zeta }, + { 0x0397, glyph_Eta }, + { 0x0398, glyph_Theta }, + { 0x0399, glyph_Iota }, + { 0x039A, glyph_Kappa }, + { 0x039B, glyph_Lambda }, + { 0x039C, glyph_Mu }, + { 0x039D, glyph_Nu }, + { 0x039E, glyph_Xi }, + { 0x039F, glyph_Omicron }, + { 0x03A0, glyph_Pi }, + { 0x03A1, glyph_Rho }, + { 0x03A3, glyph_Sigma }, + { 0x03A4, glyph_Tau }, + { 0x03A5, glyph_Upsilon }, + { 0x03A6, glyph_Phi }, + { 0x03A7, glyph_Chi }, + { 0x03A8, glyph_Psi }, + { 0x03A9, glyph_Omegagreek }, + { 0x03AA, glyph_Iotadieresis }, + { 0x03AB, glyph_Upsilondieresis }, + { 0x03AC, glyph_alphatonos }, + { 0x03AD, glyph_epsilontonos }, + { 0x03AE, glyph_etatonos }, + { 0x03AF, glyph_iotatonos }, + { 0x03B0, glyph_upsilondieresistonos }, + { 0x03B1, glyph_alpha }, + { 0x03B2, glyph_beta }, + { 0x03B3, glyph_gamma }, + { 0x03B4, glyph_delta }, + { 0x03B5, glyph_epsilon }, + { 0x03B6, glyph_zeta }, + { 0x03B7, glyph_eta }, + { 0x03B8, glyph_theta }, + { 0x03B9, glyph_iota }, + { 0x03BA, glyph_kappa }, + { 0x03BB, glyph_lambda }, + { 0x03BC, glyph_mugreek }, + { 0x03BD, glyph_nu }, + { 0x03BE, glyph_xi }, + { 0x03BF, glyph_omicron }, + { 0x03C0, glyph_pi }, + { 0x03C1, glyph_rho }, + { 0x03C2, glyph_sigma1 }, + { 0x03C3, glyph_sigma }, + { 0x03C4, glyph_tau }, + { 0x03C5, glyph_upsilon }, + { 0x03C6, glyph_phi }, + { 0x03C7, glyph_chi }, + { 0x03C8, glyph_psi }, + { 0x03C9, glyph_omega }, + { 0x03CA, glyph_iotadieresis }, + { 0x03CB, glyph_upsilondieresis }, + { 0x03CC, glyph_omicrontonos }, + { 0x03CD, glyph_upsilontonos }, + { 0x03CE, glyph_omegatonos }, + { 0x03D1, glyph_theta1 }, + { 0x03D2, glyph_Upsilon1 }, + { 0x03D5, glyph_phi1 }, + { 0x03D6, glyph_omega1 }, + { 0x0401, glyph_afii10023 }, + { 0x0402, glyph_afii10051 }, + { 0x0403, glyph_afii10052 }, + { 0x0404, glyph_afii10053 }, + { 0x0405, glyph_afii10054 }, + { 0x0406, glyph_afii10055 }, + { 0x0407, glyph_afii10056 }, + { 0x0408, glyph_afii10057 }, + { 0x0409, glyph_afii10058 }, + { 0x040A, glyph_afii10059 }, + { 0x040B, glyph_afii10060 }, + { 0x040C, glyph_afii10061 }, + { 0x040E, glyph_afii10062 }, + { 0x040F, glyph_afii10145 }, + { 0x0410, glyph_afii10017 }, + { 0x0411, glyph_afii10018 }, + { 0x0412, glyph_afii10019 }, + { 0x0413, glyph_afii10020 }, + { 0x0414, glyph_afii10021 }, + { 0x0415, glyph_afii10022 }, + { 0x0416, glyph_afii10024 }, + { 0x0417, glyph_afii10025 }, + { 0x0418, glyph_afii10026 }, + { 0x0419, glyph_afii10027 }, + { 0x041A, glyph_afii10028 }, + { 0x041B, glyph_afii10029 }, + { 0x041C, glyph_afii10030 }, + { 0x041D, glyph_afii10031 }, + { 0x041E, glyph_afii10032 }, + { 0x041F, glyph_afii10033 }, + { 0x0420, glyph_afii10034 }, + { 0x0421, glyph_afii10035 }, + { 0x0422, glyph_afii10036 }, + { 0x0423, glyph_afii10037 }, + { 0x0424, glyph_afii10038 }, + { 0x0425, glyph_afii10039 }, + { 0x0426, glyph_afii10040 }, + { 0x0427, glyph_afii10041 }, + { 0x0428, glyph_afii10042 }, + { 0x0429, glyph_afii10043 }, + { 0x042A, glyph_afii10044 }, + { 0x042B, glyph_afii10045 }, + { 0x042C, glyph_afii10046 }, + { 0x042D, glyph_afii10047 }, + { 0x042E, glyph_afii10048 }, + { 0x042F, glyph_afii10049 }, + { 0x0430, glyph_afii10065 }, + { 0x0431, glyph_afii10066 }, + { 0x0432, glyph_afii10067 }, + { 0x0433, glyph_afii10068 }, + { 0x0434, glyph_afii10069 }, + { 0x0435, glyph_afii10070 }, + { 0x0436, glyph_afii10072 }, + { 0x0437, glyph_afii10073 }, + { 0x0438, glyph_afii10074 }, + { 0x0439, glyph_afii10075 }, + { 0x043A, glyph_afii10076 }, + { 0x043B, glyph_afii10077 }, + { 0x043C, glyph_afii10078 }, + { 0x043D, glyph_afii10079 }, + { 0x043E, glyph_afii10080 }, + { 0x043F, glyph_afii10081 }, + { 0x0440, glyph_afii10082 }, + { 0x0441, glyph_afii10083 }, + { 0x0442, glyph_afii10084 }, + { 0x0443, glyph_afii10085 }, + { 0x0444, glyph_afii10086 }, + { 0x0445, glyph_afii10087 }, + { 0x0446, glyph_afii10088 }, + { 0x0447, glyph_afii10089 }, + { 0x0448, glyph_afii10090 }, + { 0x0449, glyph_afii10091 }, + { 0x044A, glyph_afii10092 }, + { 0x044B, glyph_afii10093 }, + { 0x044C, glyph_afii10094 }, + { 0x044D, glyph_afii10095 }, + { 0x044E, glyph_afii10096 }, + { 0x044F, glyph_afii10097 }, + { 0x0451, glyph_afii10071 }, + { 0x0452, glyph_afii10099 }, + { 0x0453, glyph_afii10100 }, + { 0x0454, glyph_afii10101 }, + { 0x0455, glyph_afii10102 }, + { 0x0456, glyph_afii10103 }, + { 0x0457, glyph_afii10104 }, + { 0x0458, glyph_afii10105 }, + { 0x0459, glyph_afii10106 }, + { 0x045A, glyph_afii10107 }, + { 0x045B, glyph_afii10108 }, + { 0x045C, glyph_afii10109 }, + { 0x045E, glyph_afii10110 }, + { 0x045F, glyph_afii10193 }, + { 0x0462, glyph_afii10146 }, + { 0x0463, glyph_afii10194 }, + { 0x0472, glyph_afii10147 }, + { 0x0473, glyph_afii10195 }, + { 0x0474, glyph_afii10148 }, + { 0x0475, glyph_afii10196 }, + { 0x0490, glyph_afii10050 }, + { 0x0491, glyph_afii10098 }, + { 0x04D9, glyph_afii10846 }, + { 0x05B0, glyph_afii57799 }, + { 0x05B1, glyph_afii57801 }, + { 0x05B2, glyph_afii57800 }, + { 0x05B3, glyph_afii57802 }, + { 0x05B4, glyph_afii57793 }, + { 0x05B5, glyph_afii57794 }, + { 0x05B6, glyph_afii57795 }, + { 0x05B7, glyph_afii57798 }, + { 0x05B8, glyph_afii57797 }, + { 0x05B9, glyph_afii57806 }, + { 0x05BB, glyph_afii57796 }, + { 0x05BC, glyph_afii57807 }, + { 0x05BD, glyph_afii57839 }, + { 0x05BE, glyph_afii57645 }, + { 0x05BF, glyph_afii57841 }, + { 0x05C0, glyph_afii57842 }, + { 0x05C1, glyph_afii57804 }, + { 0x05C2, glyph_afii57803 }, + { 0x05C3, glyph_afii57658 }, + { 0x05D0, glyph_afii57664 }, + { 0x05D1, glyph_afii57665 }, + { 0x05D2, glyph_afii57666 }, + { 0x05D3, glyph_afii57667 }, + { 0x05D4, glyph_afii57668 }, + { 0x05D5, glyph_afii57669 }, + { 0x05D6, glyph_afii57670 }, + { 0x05D7, glyph_afii57671 }, + { 0x05D8, glyph_afii57672 }, + { 0x05D9, glyph_afii57673 }, + { 0x05DA, glyph_afii57674 }, + { 0x05DB, glyph_afii57675 }, + { 0x05DC, glyph_afii57676 }, + { 0x05DD, glyph_afii57677 }, + { 0x05DE, glyph_afii57678 }, + { 0x05DF, glyph_afii57679 }, + { 0x05E0, glyph_afii57680 }, + { 0x05E1, glyph_afii57681 }, + { 0x05E2, glyph_afii57682 }, + { 0x05E3, glyph_afii57683 }, + { 0x05E4, glyph_afii57684 }, + { 0x05E5, glyph_afii57685 }, + { 0x05E6, glyph_afii57686 }, + { 0x05E7, glyph_afii57687 }, + { 0x05E8, glyph_afii57688 }, + { 0x05E9, glyph_afii57689 }, + { 0x05EA, glyph_afii57690 }, + { 0x05F0, glyph_afii57716 }, + { 0x05F1, glyph_afii57717 }, + { 0x05F2, glyph_afii57718 }, + { 0x060C, glyph_afii57388 }, + { 0x061B, glyph_afii57403 }, + { 0x061F, glyph_afii57407 }, + { 0x0621, glyph_afii57409 }, + { 0x0622, glyph_afii57410 }, + { 0x0623, glyph_afii57411 }, + { 0x0624, glyph_afii57412 }, + { 0x0625, glyph_afii57413 }, + { 0x0626, glyph_afii57414 }, + { 0x0627, glyph_afii57415 }, + { 0x0628, glyph_afii57416 }, + { 0x0629, glyph_afii57417 }, + { 0x062A, glyph_afii57418 }, + { 0x062B, glyph_afii57419 }, + { 0x062C, glyph_afii57420 }, + { 0x062D, glyph_afii57421 }, + { 0x062E, glyph_afii57422 }, + { 0x062F, glyph_afii57423 }, + { 0x0630, glyph_afii57424 }, + { 0x0631, glyph_afii57425 }, + { 0x0632, glyph_afii57426 }, + { 0x0633, glyph_afii57427 }, + { 0x0634, glyph_afii57428 }, + { 0x0635, glyph_afii57429 }, + { 0x0636, glyph_afii57430 }, + { 0x0637, glyph_afii57431 }, + { 0x0638, glyph_afii57432 }, + { 0x0639, glyph_afii57433 }, + { 0x063A, glyph_afii57434 }, + { 0x0640, glyph_afii57440 }, + { 0x0641, glyph_afii57441 }, + { 0x0642, glyph_afii57442 }, + { 0x0643, glyph_afii57443 }, + { 0x0644, glyph_afii57444 }, + { 0x0645, glyph_afii57445 }, + { 0x0646, glyph_afii57446 }, + { 0x0647, glyph_afii57470 }, + { 0x0648, glyph_afii57448 }, + { 0x0649, glyph_afii57449 }, + { 0x064A, glyph_afii57450 }, + { 0x064B, glyph_afii57451 }, + { 0x064C, glyph_afii57452 }, + { 0x064D, glyph_afii57453 }, + { 0x064E, glyph_afii57454 }, + { 0x064F, glyph_afii57455 }, + { 0x0650, glyph_afii57456 }, + { 0x0651, glyph_afii57457 }, + { 0x0652, glyph_afii57458 }, + { 0x0660, glyph_afii57392 }, + { 0x0661, glyph_afii57393 }, + { 0x0662, glyph_afii57394 }, + { 0x0663, glyph_afii57395 }, + { 0x0664, glyph_afii57396 }, + { 0x0665, glyph_afii57397 }, + { 0x0666, glyph_afii57398 }, + { 0x0667, glyph_afii57399 }, + { 0x0668, glyph_afii57400 }, + { 0x0669, glyph_afii57401 }, + { 0x066A, glyph_afii57381 }, + { 0x066D, glyph_afii63167 }, + { 0x0679, glyph_afii57511 }, + { 0x067E, glyph_afii57506 }, + { 0x0686, glyph_afii57507 }, + { 0x0688, glyph_afii57512 }, + { 0x0691, glyph_afii57513 }, + { 0x0698, glyph_afii57508 }, + { 0x06A4, glyph_afii57505 }, + { 0x06AF, glyph_afii57509 }, + { 0x06BA, glyph_afii57514 }, + { 0x06D2, glyph_afii57519 }, + { 0x06D5, glyph_afii57534 }, + { 0x1E80, glyph_Wgrave }, + { 0x1E81, glyph_wgrave }, + { 0x1E82, glyph_Wacute }, + { 0x1E83, glyph_wacute }, + { 0x1E84, glyph_Wdieresis }, + { 0x1E85, glyph_wdieresis }, + { 0x1EF2, glyph_Ygrave }, + { 0x1EF3, glyph_ygrave }, + { 0x200C, glyph_afii61664 }, + { 0x200D, glyph_afii301 }, + { 0x200E, glyph_afii299 }, + { 0x200F, glyph_afii300 }, + { 0x2012, glyph_figuredash }, + { 0x2013, glyph_endash }, + { 0x2014, glyph_emdash }, + { 0x2015, glyph_afii00208 }, + { 0x2017, glyph_underscoredbl }, + { 0x2018, glyph_quoteleft }, + { 0x2019, glyph_quoteright }, + { 0x201A, glyph_quotesinglbase }, + { 0x201B, glyph_quotereversed }, + { 0x201C, glyph_quotedblleft }, + { 0x201D, glyph_quotedblright }, + { 0x201E, glyph_quotedblbase }, + { 0x2020, glyph_dagger }, + { 0x2021, glyph_daggerdbl }, + { 0x2022, glyph_bullet }, + { 0x2024, glyph_onedotenleader }, + { 0x2025, glyph_twodotenleader }, + { 0x2026, glyph_ellipsis }, + { 0x202C, glyph_afii61573 }, + { 0x202D, glyph_afii61574 }, + { 0x202E, glyph_afii61575 }, + { 0x2030, glyph_perthousand }, + { 0x2032, glyph_minute }, + { 0x2033, glyph_second }, + { 0x2039, glyph_guilsinglleft }, + { 0x203A, glyph_guilsinglright }, + { 0x203C, glyph_exclamdbl }, + { 0x2044, glyph_fraction }, + { 0x2070, glyph_zerosuperior }, + { 0x2074, glyph_foursuperior }, + { 0x2075, glyph_fivesuperior }, + { 0x2076, glyph_sixsuperior }, + { 0x2077, glyph_sevensuperior }, + { 0x2078, glyph_eightsuperior }, + { 0x2079, glyph_ninesuperior }, + { 0x207D, glyph_parenleftsuperior }, + { 0x207E, glyph_parenrightsuperior }, + { 0x207F, glyph_nsuperior }, + { 0x2080, glyph_zeroinferior }, + { 0x2081, glyph_oneinferior }, + { 0x2082, glyph_twoinferior }, + { 0x2083, glyph_threeinferior }, + { 0x2084, glyph_fourinferior }, + { 0x2085, glyph_fiveinferior }, + { 0x2086, glyph_sixinferior }, + { 0x2087, glyph_seveninferior }, + { 0x2088, glyph_eightinferior }, + { 0x2089, glyph_nineinferior }, + { 0x208D, glyph_parenleftinferior }, + { 0x208E, glyph_parenrightinferior }, + { 0x20A1, glyph_colonmonetary }, + { 0x20A3, glyph_franc }, + { 0x20A4, glyph_lira }, + { 0x20A7, glyph_peseta }, + { 0x20AA, glyph_afii57636 }, + { 0x20AB, glyph_dong }, + { 0x20AC, glyph_Euro }, + { 0x2105, glyph_afii61248 }, + { 0x2111, glyph_Ifraktur }, + { 0x2113, glyph_afii61289 }, + { 0x2116, glyph_afii61352 }, + { 0x2118, glyph_weierstrass }, + { 0x211C, glyph_Rfraktur }, + { 0x211E, glyph_prescription }, + { 0x2122, glyph_trademark }, + { 0x2126, glyph_Omega }, + { 0x212E, glyph_estimated }, + { 0x2135, glyph_aleph }, + { 0x2153, glyph_onethird }, + { 0x2154, glyph_twothirds }, + { 0x215B, glyph_oneeighth }, + { 0x215C, glyph_threeeighths }, + { 0x215D, glyph_fiveeighths }, + { 0x215E, glyph_seveneighths }, + { 0x2190, glyph_arrowleft }, + { 0x2191, glyph_arrowup }, + { 0x2192, glyph_arrowright }, + { 0x2193, glyph_arrowdown }, + { 0x2194, glyph_arrowboth }, + { 0x2195, glyph_arrowupdn }, + { 0x21A8, glyph_arrowupdnbse }, + { 0x21B5, glyph_carriagereturn }, + { 0x21D0, glyph_arrowdblleft }, + { 0x21D1, glyph_arrowdblup }, + { 0x21D2, glyph_arrowdblright }, + { 0x21D3, glyph_arrowdbldown }, + { 0x21D4, glyph_arrowdblboth }, + { 0x2200, glyph_universal }, + { 0x2202, glyph_partialdiff }, + { 0x2203, glyph_existential }, + { 0x2205, glyph_emptyset }, + { 0x2206, glyph_Delta }, + { 0x2207, glyph_gradient }, + { 0x2208, glyph_element }, + { 0x2209, glyph_notelement }, + { 0x220B, glyph_suchthat }, + { 0x220F, glyph_product }, + { 0x2211, glyph_summation }, + { 0x2212, glyph_minus }, + { 0x2215, glyph_divisionslash }, + { 0x2217, glyph_asteriskmath }, + { 0x2219, glyph_bulletoperator }, + { 0x221A, glyph_radical }, + { 0x221D, glyph_proportional }, + { 0x221E, glyph_infinity }, + { 0x221F, glyph_orthogonal }, + { 0x2220, glyph_angle }, + { 0x2227, glyph_logicaland }, + { 0x2228, glyph_logicalor }, + { 0x2229, glyph_intersection }, + { 0x222A, glyph_union }, + { 0x222B, glyph_integral }, + { 0x2234, glyph_therefore }, + { 0x223C, glyph_similar }, + { 0x2245, glyph_congruent }, + { 0x2248, glyph_approxequal }, + { 0x2260, glyph_notequal }, + { 0x2261, glyph_equivalence }, + { 0x2264, glyph_lessequal }, + { 0x2265, glyph_greaterequal }, + { 0x2282, glyph_propersubset }, + { 0x2283, glyph_propersuperset }, + { 0x2284, glyph_notsubset }, + { 0x2286, glyph_reflexsubset }, + { 0x2287, glyph_reflexsuperset }, + { 0x2295, glyph_circleplus }, + { 0x2297, glyph_circlemultiply }, + { 0x22A5, glyph_perpendicular }, + { 0x22C5, glyph_dotmath }, + { 0x2302, glyph_house }, + { 0x2310, glyph_revlogicalnot }, + { 0x2320, glyph_integraltp }, + { 0x2321, glyph_integralbt }, + { 0x2329, glyph_angleleft }, + { 0x232A, glyph_angleright }, + { 0x2500, glyph_SF100000 }, + { 0x2502, glyph_SF110000 }, + { 0x250C, glyph_SF010000 }, + { 0x2510, glyph_SF030000 }, + { 0x2514, glyph_SF020000 }, + { 0x2518, glyph_SF040000 }, + { 0x251C, glyph_SF080000 }, + { 0x2524, glyph_SF090000 }, + { 0x252C, glyph_SF060000 }, + { 0x2534, glyph_SF070000 }, + { 0x253C, glyph_SF050000 }, + { 0x2550, glyph_SF430000 }, + { 0x2551, glyph_SF240000 }, + { 0x2552, glyph_SF510000 }, + { 0x2553, glyph_SF520000 }, + { 0x2554, glyph_SF390000 }, + { 0x2555, glyph_SF220000 }, + { 0x2556, glyph_SF210000 }, + { 0x2557, glyph_SF250000 }, + { 0x2558, glyph_SF500000 }, + { 0x2559, glyph_SF490000 }, + { 0x255A, glyph_SF380000 }, + { 0x255B, glyph_SF280000 }, + { 0x255C, glyph_SF270000 }, + { 0x255D, glyph_SF260000 }, + { 0x255E, glyph_SF360000 }, + { 0x255F, glyph_SF370000 }, + { 0x2560, glyph_SF420000 }, + { 0x2561, glyph_SF190000 }, + { 0x2562, glyph_SF200000 }, + { 0x2563, glyph_SF230000 }, + { 0x2564, glyph_SF470000 }, + { 0x2565, glyph_SF480000 }, + { 0x2566, glyph_SF410000 }, + { 0x2567, glyph_SF450000 }, + { 0x2568, glyph_SF460000 }, + { 0x2569, glyph_SF400000 }, + { 0x256A, glyph_SF540000 }, + { 0x256B, glyph_SF530000 }, + { 0x256C, glyph_SF440000 }, + { 0x2580, glyph_upblock }, + { 0x2584, glyph_dnblock }, + { 0x2588, glyph_block }, + { 0x258C, glyph_lfblock }, + { 0x2590, glyph_rtblock }, + { 0x2591, glyph_ltshade }, + { 0x2592, glyph_shade }, + { 0x2593, glyph_dkshade }, + { 0x25A0, glyph_filledbox }, + { 0x25A1, glyph_H22073 }, + { 0x25AA, glyph_H18543 }, + { 0x25AB, glyph_H18551 }, + { 0x25AC, glyph_filledrect }, + { 0x25B2, glyph_triagup }, + { 0x25BA, glyph_triagrt }, + { 0x25BC, glyph_triagdn }, + { 0x25C4, glyph_triaglf }, + { 0x25CA, glyph_lozenge }, + { 0x25CB, glyph_circle }, + { 0x25CF, glyph_H18533 }, + { 0x25D8, glyph_invbullet }, + { 0x25D9, glyph_invcircle }, + { 0x25E6, glyph_openbullet }, + { 0x263A, glyph_smileface }, + { 0x263B, glyph_invsmileface }, + { 0x263C, glyph_sun }, + { 0x2640, glyph_female }, + { 0x2642, glyph_male }, + { 0x2660, glyph_spade }, + { 0x2663, glyph_club }, + { 0x2665, glyph_heart }, + { 0x2666, glyph_diamond }, + { 0x266A, glyph_musicalnote }, + { 0x266B, glyph_musicalnotedbl }, + { 0xF6BE, glyph_dotlessj }, + { 0xF6BF, glyph_LL }, + { 0xF6C0, glyph_ll }, + { 0xF6C3, glyph_commaaccent }, + { 0xF6C4, glyph_afii10063 }, + { 0xF6C5, glyph_afii10064 }, + { 0xF6C6, glyph_afii10192 }, + { 0xF6C7, glyph_afii10831 }, + { 0xF6C8, glyph_afii10832 }, + { 0xF6C9, glyph_Acute }, + { 0xF6CA, glyph_Caron }, + { 0xF6CB, glyph_Dieresis }, + { 0xF6CC, glyph_DieresisAcute }, + { 0xF6CD, glyph_DieresisGrave }, + { 0xF6CE, glyph_Grave }, + { 0xF6CF, glyph_Hungarumlaut }, + { 0xF6D0, glyph_Macron }, + { 0xF6D1, glyph_cyrBreve }, + { 0xF6D2, glyph_cyrFlex }, + { 0xF6D3, glyph_dblGrave }, + { 0xF6D4, glyph_cyrbreve }, + { 0xF6D5, glyph_cyrflex }, + { 0xF6D6, glyph_dblgrave }, + { 0xF6D7, glyph_dieresisacute }, + { 0xF6D8, glyph_dieresisgrave }, + { 0xF6D9, glyph_copyrightserif }, + { 0xF6DA, glyph_registerserif }, + { 0xF6DB, glyph_trademarkserif }, + { 0xF6DC, glyph_onefitted }, + { 0xF6DD, glyph_rupiah }, + { 0xF6DE, glyph_threequartersemdash }, + { 0xF6DF, glyph_centinferior }, + { 0xF6E0, glyph_centsuperior }, + { 0xF6E1, glyph_commainferior }, + { 0xF6E2, glyph_commasuperior }, + { 0xF6E3, glyph_dollarinferior }, + { 0xF6E4, glyph_dollarsuperior }, + { 0xF6E5, glyph_hypheninferior }, + { 0xF6E6, glyph_hyphensuperior }, + { 0xF6E7, glyph_periodinferior }, + { 0xF6E8, glyph_periodsuperior }, + { 0xF6E9, glyph_asuperior }, + { 0xF6EA, glyph_bsuperior }, + { 0xF6EB, glyph_dsuperior }, + { 0xF6EC, glyph_esuperior }, + { 0xF6ED, glyph_isuperior }, + { 0xF6EE, glyph_lsuperior }, + { 0xF6EF, glyph_msuperior }, + { 0xF6F0, glyph_osuperior }, + { 0xF6F1, glyph_rsuperior }, + { 0xF6F2, glyph_ssuperior }, + { 0xF6F3, glyph_tsuperior }, + { 0xF6F4, glyph_Brevesmall }, + { 0xF6F5, glyph_Caronsmall }, + { 0xF6F6, glyph_Circumflexsmall }, + { 0xF6F7, glyph_Dotaccentsmall }, + { 0xF6F8, glyph_Hungarumlautsmall }, + { 0xF6F9, glyph_Lslashsmall }, + { 0xF6FA, glyph_OEsmall }, + { 0xF6FB, glyph_Ogoneksmall }, + { 0xF6FC, glyph_Ringsmall }, + { 0xF6FD, glyph_Scaronsmall }, + { 0xF6FE, glyph_Tildesmall }, + { 0xF6FF, glyph_Zcaronsmall }, + { 0xF721, glyph_exclamsmall }, + { 0xF724, glyph_dollaroldstyle }, + { 0xF726, glyph_ampersandsmall }, + { 0xF730, glyph_zerooldstyle }, + { 0xF731, glyph_oneoldstyle }, + { 0xF732, glyph_twooldstyle }, + { 0xF733, glyph_threeoldstyle }, + { 0xF734, glyph_fouroldstyle }, + { 0xF735, glyph_fiveoldstyle }, + { 0xF736, glyph_sixoldstyle }, + { 0xF737, glyph_sevenoldstyle }, + { 0xF738, glyph_eightoldstyle }, + { 0xF739, glyph_nineoldstyle }, + { 0xF73F, glyph_questionsmall }, + { 0xF760, glyph_Gravesmall }, + { 0xF761, glyph_Asmall }, + { 0xF762, glyph_Bsmall }, + { 0xF763, glyph_Csmall }, + { 0xF764, glyph_Dsmall }, + { 0xF765, glyph_Esmall }, + { 0xF766, glyph_Fsmall }, + { 0xF767, glyph_Gsmall }, + { 0xF768, glyph_Hsmall }, + { 0xF769, glyph_Ismall }, + { 0xF76A, glyph_Jsmall }, + { 0xF76B, glyph_Ksmall }, + { 0xF76C, glyph_Lsmall }, + { 0xF76D, glyph_Msmall }, + { 0xF76E, glyph_Nsmall }, + { 0xF76F, glyph_Osmall }, + { 0xF770, glyph_Psmall }, + { 0xF771, glyph_Qsmall }, + { 0xF772, glyph_Rsmall }, + { 0xF773, glyph_Ssmall }, + { 0xF774, glyph_Tsmall }, + { 0xF775, glyph_Usmall }, + { 0xF776, glyph_Vsmall }, + { 0xF777, glyph_Wsmall }, + { 0xF778, glyph_Xsmall }, + { 0xF779, glyph_Ysmall }, + { 0xF77A, glyph_Zsmall }, + { 0xF7A1, glyph_exclamdownsmall }, + { 0xF7A2, glyph_centoldstyle }, + { 0xF7A8, glyph_Dieresissmall }, + { 0xF7AF, glyph_Macronsmall }, + { 0xF7B4, glyph_Acutesmall }, + { 0xF7B8, glyph_Cedillasmall }, + { 0xF7BF, glyph_questiondownsmall }, + { 0xF7E0, glyph_Agravesmall }, + { 0xF7E1, glyph_Aacutesmall }, + { 0xF7E2, glyph_Acircumflexsmall }, + { 0xF7E3, glyph_Atildesmall }, + { 0xF7E4, glyph_Adieresissmall }, + { 0xF7E5, glyph_Aringsmall }, + { 0xF7E6, glyph_AEsmall }, + { 0xF7E7, glyph_Ccedillasmall }, + { 0xF7E8, glyph_Egravesmall }, + { 0xF7E9, glyph_Eacutesmall }, + { 0xF7EA, glyph_Ecircumflexsmall }, + { 0xF7EB, glyph_Edieresissmall }, + { 0xF7EC, glyph_Igravesmall }, + { 0xF7ED, glyph_Iacutesmall }, + { 0xF7EE, glyph_Icircumflexsmall }, + { 0xF7EF, glyph_Idieresissmall }, + { 0xF7F0, glyph_Ethsmall }, + { 0xF7F1, glyph_Ntildesmall }, + { 0xF7F2, glyph_Ogravesmall }, + { 0xF7F3, glyph_Oacutesmall }, + { 0xF7F4, glyph_Ocircumflexsmall }, + { 0xF7F5, glyph_Otildesmall }, + { 0xF7F6, glyph_Odieresissmall }, + { 0xF7F8, glyph_Oslashsmall }, + { 0xF7F9, glyph_Ugravesmall }, + { 0xF7FA, glyph_Uacutesmall }, + { 0xF7FB, glyph_Ucircumflexsmall }, + { 0xF7FC, glyph_Udieresissmall }, + { 0xF7FD, glyph_Yacutesmall }, + { 0xF7FE, glyph_Thornsmall }, + { 0xF7FF, glyph_Ydieresissmall }, + { 0xF8E5, glyph_radicalex }, + { 0xF8E6, glyph_arrowvertex }, + { 0xF8E7, glyph_arrowhorizex }, + { 0xF8E8, glyph_registersans }, + { 0xF8E9, glyph_copyrightsans }, + { 0xF8EA, glyph_trademarksans }, + { 0xF8EB, glyph_parenlefttp }, + { 0xF8EC, glyph_parenleftex }, + { 0xF8ED, glyph_parenleftbt }, + { 0xF8EE, glyph_bracketlefttp }, + { 0xF8EF, glyph_bracketleftex }, + { 0xF8F0, glyph_bracketleftbt }, + { 0xF8F1, glyph_bracelefttp }, + { 0xF8F2, glyph_braceleftmid }, + { 0xF8F3, glyph_braceleftbt }, + { 0xF8F4, glyph_braceex }, + { 0xF8F5, glyph_integralex }, + { 0xF8F6, glyph_parenrighttp }, + { 0xF8F7, glyph_parenrightex }, + { 0xF8F8, glyph_parenrightbt }, + { 0xF8F9, glyph_bracketrighttp }, + { 0xF8FA, glyph_bracketrightex }, + { 0xF8FB, glyph_bracketrightbt }, + { 0xF8FC, glyph_bracerighttp }, + { 0xF8FD, glyph_bracerightmid }, + { 0xF8FE, glyph_bracerightbt }, + { 0xF8FF, glyph_apple }, + { 0xFB00, glyph_ff }, + { 0xFB01, glyph_fi }, + { 0xFB02, glyph_fl }, + { 0xFB03, glyph_ffi }, + { 0xFB04, glyph_ffl }, + { 0xFB1F, glyph_afii57705 }, + { 0xFB2A, glyph_afii57694 }, + { 0xFB2B, glyph_afii57695 }, + { 0xFB35, glyph_afii57723 }, + { 0xFB4B, glyph_afii57700 }, +}; /* tab_uni2agl */ + +/* ZapfDingbats glyphs - sorted by names */ +static const pdc_glyph_tab tab_zadb2uni[] = +{ + { 0x2701, glyph_a1 }, + { 0x2721, glyph_a10 }, + { 0x275E, glyph_a100 }, + { 0x2761, glyph_a101 }, + { 0x2762, glyph_a102 }, + { 0x2763, glyph_a103 }, + { 0x2764, glyph_a104 }, + { 0x2710, glyph_a105 }, + { 0x2765, glyph_a106 }, + { 0x2766, glyph_a107 }, + { 0x2767, glyph_a108 }, + { 0x2660, glyph_a109 }, + { 0x261B, glyph_a11 }, + { 0x2665, glyph_a110 }, + { 0x2666, glyph_a111 }, + { 0x2663, glyph_a112 }, + { 0x2709, glyph_a117 }, + { 0x2708, glyph_a118 }, + { 0x2707, glyph_a119 }, + { 0x261E, glyph_a12 }, + { 0x2460, glyph_a120 }, + { 0x2461, glyph_a121 }, + { 0x2462, glyph_a122 }, + { 0x2463, glyph_a123 }, + { 0x2464, glyph_a124 }, + { 0x2465, glyph_a125 }, + { 0x2466, glyph_a126 }, + { 0x2467, glyph_a127 }, + { 0x2468, glyph_a128 }, + { 0x2469, glyph_a129 }, + { 0x270C, glyph_a13 }, + { 0x2776, glyph_a130 }, + { 0x2777, glyph_a131 }, + { 0x2778, glyph_a132 }, + { 0x2779, glyph_a133 }, + { 0x277A, glyph_a134 }, + { 0x277B, glyph_a135 }, + { 0x277C, glyph_a136 }, + { 0x277D, glyph_a137 }, + { 0x277E, glyph_a138 }, + { 0x277F, glyph_a139 }, + { 0x270D, glyph_a14 }, + { 0x2780, glyph_a140 }, + { 0x2781, glyph_a141 }, + { 0x2782, glyph_a142 }, + { 0x2783, glyph_a143 }, + { 0x2784, glyph_a144 }, + { 0x2785, glyph_a145 }, + { 0x2786, glyph_a146 }, + { 0x2787, glyph_a147 }, + { 0x2788, glyph_a148 }, + { 0x2789, glyph_a149 }, + { 0x270E, glyph_a15 }, + { 0x278A, glyph_a150 }, + { 0x278B, glyph_a151 }, + { 0x278C, glyph_a152 }, + { 0x278D, glyph_a153 }, + { 0x278E, glyph_a154 }, + { 0x278F, glyph_a155 }, + { 0x2790, glyph_a156 }, + { 0x2791, glyph_a157 }, + { 0x2792, glyph_a158 }, + { 0x2793, glyph_a159 }, + { 0x270F, glyph_a16 }, + { 0x2794, glyph_a160 }, + { 0x2192, glyph_a161 }, + { 0x27A3, glyph_a162 }, + { 0x2194, glyph_a163 }, + { 0x2195, glyph_a164 }, + { 0x2799, glyph_a165 }, + { 0x279B, glyph_a166 }, + { 0x279C, glyph_a167 }, + { 0x279D, glyph_a168 }, + { 0x279E, glyph_a169 }, + { 0x2711, glyph_a17 }, + { 0x279F, glyph_a170 }, + { 0x27A0, glyph_a171 }, + { 0x27A1, glyph_a172 }, + { 0x27A2, glyph_a173 }, + { 0x27A4, glyph_a174 }, + { 0x27A5, glyph_a175 }, + { 0x27A6, glyph_a176 }, + { 0x27A7, glyph_a177 }, + { 0x27A8, glyph_a178 }, + { 0x27A9, glyph_a179 }, + { 0x2712, glyph_a18 }, + { 0x27AB, glyph_a180 }, + { 0x27AD, glyph_a181 }, + { 0x27AF, glyph_a182 }, + { 0x27B2, glyph_a183 }, + { 0x27B3, glyph_a184 }, + { 0x27B5, glyph_a185 }, + { 0x27B8, glyph_a186 }, + { 0x27BA, glyph_a187 }, + { 0x27BB, glyph_a188 }, + { 0x27BC, glyph_a189 }, + { 0x2713, glyph_a19 }, + { 0x27BD, glyph_a190 }, + { 0x27BE, glyph_a191 }, + { 0x279A, glyph_a192 }, + { 0x27AA, glyph_a193 }, + { 0x27B6, glyph_a194 }, + { 0x27B9, glyph_a195 }, + { 0x2798, glyph_a196 }, + { 0x27B4, glyph_a197 }, + { 0x27B7, glyph_a198 }, + { 0x27AC, glyph_a199 }, + { 0x2702, glyph_a2 }, + { 0x2714, glyph_a20 }, + { 0x27AE, glyph_a200 }, + { 0x27B1, glyph_a201 }, + { 0x2703, glyph_a202 }, + { 0x2750, glyph_a203 }, + { 0x2752, glyph_a204 }, + { 0x276E, glyph_a205 }, + { 0x2770, glyph_a206 }, + { 0x2715, glyph_a21 }, + { 0x2716, glyph_a22 }, + { 0x2717, glyph_a23 }, + { 0x2718, glyph_a24 }, + { 0x2719, glyph_a25 }, + { 0x271A, glyph_a26 }, + { 0x271B, glyph_a27 }, + { 0x271C, glyph_a28 }, + { 0x2722, glyph_a29 }, + { 0x2704, glyph_a3 }, + { 0x2723, glyph_a30 }, + { 0x2724, glyph_a31 }, + { 0x2725, glyph_a32 }, + { 0x2726, glyph_a33 }, + { 0x2727, glyph_a34 }, + { 0x2605, glyph_a35 }, + { 0x2729, glyph_a36 }, + { 0x272A, glyph_a37 }, + { 0x272B, glyph_a38 }, + { 0x272C, glyph_a39 }, + { 0x260E, glyph_a4 }, + { 0x272D, glyph_a40 }, + { 0x272E, glyph_a41 }, + { 0x272F, glyph_a42 }, + { 0x2730, glyph_a43 }, + { 0x2731, glyph_a44 }, + { 0x2732, glyph_a45 }, + { 0x2733, glyph_a46 }, + { 0x2734, glyph_a47 }, + { 0x2735, glyph_a48 }, + { 0x2736, glyph_a49 }, + { 0x2706, glyph_a5 }, + { 0x2737, glyph_a50 }, + { 0x2738, glyph_a51 }, + { 0x2739, glyph_a52 }, + { 0x273A, glyph_a53 }, + { 0x273B, glyph_a54 }, + { 0x273C, glyph_a55 }, + { 0x273D, glyph_a56 }, + { 0x273E, glyph_a57 }, + { 0x273F, glyph_a58 }, + { 0x2740, glyph_a59 }, + { 0x271D, glyph_a6 }, + { 0x2741, glyph_a60 }, + { 0x2742, glyph_a61 }, + { 0x2743, glyph_a62 }, + { 0x2744, glyph_a63 }, + { 0x2745, glyph_a64 }, + { 0x2746, glyph_a65 }, + { 0x2747, glyph_a66 }, + { 0x2748, glyph_a67 }, + { 0x2749, glyph_a68 }, + { 0x274A, glyph_a69 }, + { 0x271E, glyph_a7 }, + { 0x274B, glyph_a70 }, + { 0x25CF, glyph_a71 }, + { 0x274D, glyph_a72 }, + { 0x25A0, glyph_a73 }, + { 0x274F, glyph_a74 }, + { 0x2751, glyph_a75 }, + { 0x25B2, glyph_a76 }, + { 0x25BC, glyph_a77 }, + { 0x25C6, glyph_a78 }, + { 0x2756, glyph_a79 }, + { 0x271F, glyph_a8 }, + { 0x25D7, glyph_a81 }, + { 0x2758, glyph_a82 }, + { 0x2759, glyph_a83 }, + { 0x275A, glyph_a84 }, + { 0x276F, glyph_a85 }, + { 0x2771, glyph_a86 }, + { 0x2772, glyph_a87 }, + { 0x2773, glyph_a88 }, + { 0x2768, glyph_a89 }, + { 0x2720, glyph_a9 }, + { 0x2769, glyph_a90 }, + { 0x276C, glyph_a91 }, + { 0x276D, glyph_a92 }, + { 0x276A, glyph_a93 }, + { 0x276B, glyph_a94 }, + { 0x2774, glyph_a95 }, + { 0x2775, glyph_a96 }, + { 0x275B, glyph_a97 }, + { 0x275C, glyph_a98 }, + { 0x275D, glyph_a99 }, + { 0x0020, glyph_space }, +}; /* tab_zadb2uni */ + +/* ZapfDingbats glyphs - sorted by unicode values */ +static const pdc_glyph_tab tab_uni2zadb[] = +{ + { 0x0020, glyph_space }, + { 0x2192, glyph_a161 }, + { 0x2194, glyph_a163 }, + { 0x2195, glyph_a164 }, + { 0x2460, glyph_a120 }, + { 0x2461, glyph_a121 }, + { 0x2462, glyph_a122 }, + { 0x2463, glyph_a123 }, + { 0x2464, glyph_a124 }, + { 0x2465, glyph_a125 }, + { 0x2466, glyph_a126 }, + { 0x2467, glyph_a127 }, + { 0x2468, glyph_a128 }, + { 0x2469, glyph_a129 }, + { 0x25A0, glyph_a73 }, + { 0x25B2, glyph_a76 }, + { 0x25BC, glyph_a77 }, + { 0x25C6, glyph_a78 }, + { 0x25CF, glyph_a71 }, + { 0x25D7, glyph_a81 }, + { 0x2605, glyph_a35 }, + { 0x260E, glyph_a4 }, + { 0x261B, glyph_a11 }, + { 0x261E, glyph_a12 }, + { 0x2660, glyph_a109 }, + { 0x2663, glyph_a112 }, + { 0x2665, glyph_a110 }, + { 0x2666, glyph_a111 }, + { 0x2701, glyph_a1 }, + { 0x2702, glyph_a2 }, + { 0x2703, glyph_a202 }, + { 0x2704, glyph_a3 }, + { 0x2706, glyph_a5 }, + { 0x2707, glyph_a119 }, + { 0x2708, glyph_a118 }, + { 0x2709, glyph_a117 }, + { 0x270C, glyph_a13 }, + { 0x270D, glyph_a14 }, + { 0x270E, glyph_a15 }, + { 0x270F, glyph_a16 }, + { 0x2710, glyph_a105 }, + { 0x2711, glyph_a17 }, + { 0x2712, glyph_a18 }, + { 0x2713, glyph_a19 }, + { 0x2714, glyph_a20 }, + { 0x2715, glyph_a21 }, + { 0x2716, glyph_a22 }, + { 0x2717, glyph_a23 }, + { 0x2718, glyph_a24 }, + { 0x2719, glyph_a25 }, + { 0x271A, glyph_a26 }, + { 0x271B, glyph_a27 }, + { 0x271C, glyph_a28 }, + { 0x271D, glyph_a6 }, + { 0x271E, glyph_a7 }, + { 0x271F, glyph_a8 }, + { 0x2720, glyph_a9 }, + { 0x2721, glyph_a10 }, + { 0x2722, glyph_a29 }, + { 0x2723, glyph_a30 }, + { 0x2724, glyph_a31 }, + { 0x2725, glyph_a32 }, + { 0x2726, glyph_a33 }, + { 0x2727, glyph_a34 }, + { 0x2729, glyph_a36 }, + { 0x272A, glyph_a37 }, + { 0x272B, glyph_a38 }, + { 0x272C, glyph_a39 }, + { 0x272D, glyph_a40 }, + { 0x272E, glyph_a41 }, + { 0x272F, glyph_a42 }, + { 0x2730, glyph_a43 }, + { 0x2731, glyph_a44 }, + { 0x2732, glyph_a45 }, + { 0x2733, glyph_a46 }, + { 0x2734, glyph_a47 }, + { 0x2735, glyph_a48 }, + { 0x2736, glyph_a49 }, + { 0x2737, glyph_a50 }, + { 0x2738, glyph_a51 }, + { 0x2739, glyph_a52 }, + { 0x273A, glyph_a53 }, + { 0x273B, glyph_a54 }, + { 0x273C, glyph_a55 }, + { 0x273D, glyph_a56 }, + { 0x273E, glyph_a57 }, + { 0x273F, glyph_a58 }, + { 0x2740, glyph_a59 }, + { 0x2741, glyph_a60 }, + { 0x2742, glyph_a61 }, + { 0x2743, glyph_a62 }, + { 0x2744, glyph_a63 }, + { 0x2745, glyph_a64 }, + { 0x2746, glyph_a65 }, + { 0x2747, glyph_a66 }, + { 0x2748, glyph_a67 }, + { 0x2749, glyph_a68 }, + { 0x274A, glyph_a69 }, + { 0x274B, glyph_a70 }, + { 0x274D, glyph_a72 }, + { 0x274F, glyph_a74 }, + { 0x2750, glyph_a203 }, + { 0x2751, glyph_a75 }, + { 0x2752, glyph_a204 }, + { 0x2756, glyph_a79 }, + { 0x2758, glyph_a82 }, + { 0x2759, glyph_a83 }, + { 0x275A, glyph_a84 }, + { 0x275B, glyph_a97 }, + { 0x275C, glyph_a98 }, + { 0x275D, glyph_a99 }, + { 0x275E, glyph_a100 }, + { 0x2761, glyph_a101 }, + { 0x2762, glyph_a102 }, + { 0x2763, glyph_a103 }, + { 0x2764, glyph_a104 }, + { 0x2765, glyph_a106 }, + { 0x2766, glyph_a107 }, + { 0x2767, glyph_a108 }, + + /* >= Unicode 4.0*/ + { 0x2768, glyph_a89 }, + { 0x2769, glyph_a90 }, + { 0x276A, glyph_a93 }, + { 0x276B, glyph_a94 }, + { 0x276C, glyph_a91 }, + { 0x276D, glyph_a92 }, + { 0x276E, glyph_a205 }, + { 0x276F, glyph_a85 }, + { 0x2770, glyph_a206 }, + { 0x2771, glyph_a86 }, + { 0x2772, glyph_a87 }, + { 0x2773, glyph_a88 }, + { 0x2774, glyph_a95 }, + { 0x2775, glyph_a96 }, + /* ---------------- */ + + { 0x2776, glyph_a130 }, + { 0x2777, glyph_a131 }, + { 0x2778, glyph_a132 }, + { 0x2779, glyph_a133 }, + { 0x277A, glyph_a134 }, + { 0x277B, glyph_a135 }, + { 0x277C, glyph_a136 }, + { 0x277D, glyph_a137 }, + { 0x277E, glyph_a138 }, + { 0x277F, glyph_a139 }, + { 0x2780, glyph_a140 }, + { 0x2781, glyph_a141 }, + { 0x2782, glyph_a142 }, + { 0x2783, glyph_a143 }, + { 0x2784, glyph_a144 }, + { 0x2785, glyph_a145 }, + { 0x2786, glyph_a146 }, + { 0x2787, glyph_a147 }, + { 0x2788, glyph_a148 }, + { 0x2789, glyph_a149 }, + { 0x278A, glyph_a150 }, + { 0x278B, glyph_a151 }, + { 0x278C, glyph_a152 }, + { 0x278D, glyph_a153 }, + { 0x278E, glyph_a154 }, + { 0x278F, glyph_a155 }, + { 0x2790, glyph_a156 }, + { 0x2791, glyph_a157 }, + { 0x2792, glyph_a158 }, + { 0x2793, glyph_a159 }, + { 0x2794, glyph_a160 }, + { 0x2798, glyph_a196 }, + { 0x2799, glyph_a165 }, + { 0x279A, glyph_a192 }, + { 0x279B, glyph_a166 }, + { 0x279C, glyph_a167 }, + { 0x279D, glyph_a168 }, + { 0x279E, glyph_a169 }, + { 0x279F, glyph_a170 }, + { 0x27A0, glyph_a171 }, + { 0x27A1, glyph_a172 }, + { 0x27A2, glyph_a173 }, + { 0x27A3, glyph_a162 }, + { 0x27A4, glyph_a174 }, + { 0x27A5, glyph_a175 }, + { 0x27A6, glyph_a176 }, + { 0x27A7, glyph_a177 }, + { 0x27A8, glyph_a178 }, + { 0x27A9, glyph_a179 }, + { 0x27AA, glyph_a193 }, + { 0x27AB, glyph_a180 }, + { 0x27AC, glyph_a199 }, + { 0x27AD, glyph_a181 }, + { 0x27AE, glyph_a200 }, + { 0x27AF, glyph_a182 }, + { 0x27B1, glyph_a201 }, + { 0x27B2, glyph_a183 }, + { 0x27B3, glyph_a184 }, + { 0x27B4, glyph_a197 }, + { 0x27B5, glyph_a185 }, + { 0x27B6, glyph_a194 }, + { 0x27B7, glyph_a198 }, + { 0x27B8, glyph_a186 }, + { 0x27B9, glyph_a195 }, + { 0x27BA, glyph_a187 }, + { 0x27BB, glyph_a188 }, + { 0x27BC, glyph_a189 }, + { 0x27BD, glyph_a190 }, + { 0x27BE, glyph_a191 }, + + /* < Unicode 4.0 */ + { 0xF8D7, glyph_a89 }, + { 0xF8D8, glyph_a90 }, + { 0xF8D9, glyph_a93 }, + { 0xF8DA, glyph_a94 }, + { 0xF8DB, glyph_a91 }, + { 0xF8DC, glyph_a92 }, + { 0xF8DD, glyph_a205 }, + { 0xF8DE, glyph_a85 }, + { 0xF8DF, glyph_a206 }, + { 0xF8E0, glyph_a86 }, + { 0xF8E1, glyph_a87 }, + { 0xF8E2, glyph_a88 }, + { 0xF8E3, glyph_a95 }, + { 0xF8E4, glyph_a96 }, +}; /* tab_uni2zadb */ + + +/* + * Difference table of AGL version 2.0 - 1.2' - sorted by names + * + */ +static const pdc_glyph_tab tab_diffagl2uni[] = +{ +#ifndef PDFLIB_EBCDIC + + { 0x01E2, glyph_AEmacron }, + { 0x1EAE, glyph_Abreveacute }, + { 0x04D0, glyph_Abrevecyrillic }, + { 0x1EB6, glyph_Abrevedotbelow }, + { 0x1EB0, glyph_Abrevegrave }, + { 0x1EB2, glyph_Abrevehookabove }, + { 0x1EB4, glyph_Abrevetilde }, + { 0x01CD, glyph_Acaron }, + { 0x24B6, glyph_Acircle }, + { 0x1EA4, glyph_Acircumflexacute }, + { 0x1EAC, glyph_Acircumflexdotbelow }, + { 0x1EA6, glyph_Acircumflexgrave }, + { 0x1EA8, glyph_Acircumflexhookabove }, + { 0x1EAA, glyph_Acircumflextilde }, + { 0x0410, glyph_Acyrillic }, + { 0x0200, glyph_Adblgrave }, + { 0x04D2, glyph_Adieresiscyrillic }, + { 0x01DE, glyph_Adieresismacron }, + { 0x1EA0, glyph_Adotbelow }, + { 0x01E0, glyph_Adotmacron }, + { 0x1EA2, glyph_Ahookabove }, + { 0x04D4, glyph_Aiecyrillic }, + { 0x0202, glyph_Ainvertedbreve }, + { 0xFF21, glyph_Amonospace }, + { 0x1E00, glyph_Aringbelow }, + { 0x0531, glyph_Aybarmenian }, + { 0x24B7, glyph_Bcircle }, + { 0x1E02, glyph_Bdotaccent }, + { 0x1E04, glyph_Bdotbelow }, + { 0x0411, glyph_Becyrillic }, + { 0x0532, glyph_Benarmenian }, + { 0x0181, glyph_Bhook }, + { 0x1E06, glyph_Blinebelow }, + { 0xFF22, glyph_Bmonospace }, + { 0x0182, glyph_Btopbar }, + { 0x053E, glyph_Caarmenian }, + { 0x1E08, glyph_Ccedillaacute }, + { 0x24B8, glyph_Ccircle }, + { 0x010A, glyph_Cdot }, + { 0x0549, glyph_Chaarmenian }, + { 0x04BC, glyph_Cheabkhasiancyrillic }, + { 0x0427, glyph_Checyrillic }, + { 0x04BE, glyph_Chedescenderabkhasiancyrillic }, + { 0x04B6, glyph_Chedescendercyrillic }, + { 0x04F4, glyph_Chedieresiscyrillic }, + { 0x0543, glyph_Cheharmenian }, + { 0x04CB, glyph_Chekhakassiancyrillic }, + { 0x04B8, glyph_Cheverticalstrokecyrillic }, + { 0x0187, glyph_Chook }, + { 0xFF23, glyph_Cmonospace }, + { 0x0551, glyph_Coarmenian }, + { 0x01F1, glyph_DZ }, + { 0x01C4, glyph_DZcaron }, + { 0x0534, glyph_Daarmenian }, + { 0x0189, glyph_Dafrican }, + { 0x1E10, glyph_Dcedilla }, + { 0x24B9, glyph_Dcircle }, + { 0x1E12, glyph_Dcircumflexbelow }, + { 0x1E0A, glyph_Ddotaccent }, + { 0x1E0C, glyph_Ddotbelow }, + { 0x0414, glyph_Decyrillic }, + { 0x03EE, glyph_Deicoptic }, + { 0x018A, glyph_Dhook }, + { 0x03DC, glyph_Digammagreek }, + { 0x0402, glyph_Djecyrillic }, + { 0x1E0E, glyph_Dlinebelow }, + { 0xFF24, glyph_Dmonospace }, + { 0x0110, glyph_Dslash }, + { 0x018B, glyph_Dtopbar }, + { 0x01F2, glyph_Dz }, + { 0x01C5, glyph_Dzcaron }, + { 0x04E0, glyph_Dzeabkhasiancyrillic }, + { 0x0405, glyph_Dzecyrillic }, + { 0x040F, glyph_Dzhecyrillic }, + { 0x1E1C, glyph_Ecedillabreve }, + { 0x0535, glyph_Echarmenian }, + { 0x24BA, glyph_Ecircle }, + { 0x1EBE, glyph_Ecircumflexacute }, + { 0x1E18, glyph_Ecircumflexbelow }, + { 0x1EC6, glyph_Ecircumflexdotbelow }, + { 0x1EC0, glyph_Ecircumflexgrave }, + { 0x1EC2, glyph_Ecircumflexhookabove }, + { 0x1EC4, glyph_Ecircumflextilde }, + { 0x0404, glyph_Ecyrillic }, + { 0x0204, glyph_Edblgrave }, + { 0x0116, glyph_Edot }, + { 0x1EB8, glyph_Edotbelow }, + { 0x0424, glyph_Efcyrillic }, + { 0x0537, glyph_Eharmenian }, + { 0x1EBA, glyph_Ehookabove }, + { 0x2167, glyph_Eightroman }, + { 0x0206, glyph_Einvertedbreve }, + { 0x0464, glyph_Eiotifiedcyrillic }, + { 0x041B, glyph_Elcyrillic }, + { 0x216A, glyph_Elevenroman }, + { 0x1E16, glyph_Emacronacute }, + { 0x1E14, glyph_Emacrongrave }, + { 0x041C, glyph_Emcyrillic }, + { 0xFF25, glyph_Emonospace }, + { 0x041D, glyph_Encyrillic }, + { 0x04A2, glyph_Endescendercyrillic }, + { 0x04A4, glyph_Enghecyrillic }, + { 0x04C7, glyph_Enhookcyrillic }, + { 0x0190, glyph_Eopen }, + { 0x0420, glyph_Ercyrillic }, + { 0x018E, glyph_Ereversed }, + { 0x042D, glyph_Ereversedcyrillic }, + { 0x0421, glyph_Escyrillic }, + { 0x04AA, glyph_Esdescendercyrillic }, + { 0x01A9, glyph_Esh }, + { 0x0538, glyph_Etarmenian }, + { 0x1EBC, glyph_Etilde }, + { 0x1E1A, glyph_Etildebelow }, + { 0x01B7, glyph_Ezh }, + { 0x01EE, glyph_Ezhcaron }, + { 0x01B8, glyph_Ezhreversed }, + { 0x24BB, glyph_Fcircle }, + { 0x1E1E, glyph_Fdotaccent }, + { 0x0556, glyph_Feharmenian }, + { 0x03E4, glyph_Feicoptic }, + { 0x0191, glyph_Fhook }, + { 0x0472, glyph_Fitacyrillic }, + { 0x2164, glyph_Fiveroman }, + { 0xFF26, glyph_Fmonospace }, + { 0x2163, glyph_Fourroman }, + { 0x3387, glyph_GBsquare }, + { 0x01F4, glyph_Gacute }, + { 0x0194, glyph_Gammaafrican }, + { 0x03EA, glyph_Gangiacoptic }, + { 0x0122, glyph_Gcedilla }, + { 0x24BC, glyph_Gcircle }, + { 0x0120, glyph_Gdot }, + { 0x0413, glyph_Gecyrillic }, + { 0x0542, glyph_Ghadarmenian }, + { 0x0494, glyph_Ghemiddlehookcyrillic }, + { 0x0492, glyph_Ghestrokecyrillic }, + { 0x0490, glyph_Gheupturncyrillic }, + { 0x0193, glyph_Ghook }, + { 0x0533, glyph_Gimarmenian }, + { 0x0403, glyph_Gjecyrillic }, + { 0x1E20, glyph_Gmacron }, + { 0xFF27, glyph_Gmonospace }, + { 0x029B, glyph_Gsmallhook }, + { 0x01E4, glyph_Gstroke }, + { 0x33CB, glyph_HPsquare }, + { 0x04A8, glyph_Haabkhasiancyrillic }, + { 0x04B2, glyph_Hadescendercyrillic }, + { 0x042A, glyph_Hardsigncyrillic }, + { 0x1E2A, glyph_Hbrevebelow }, + { 0x1E28, glyph_Hcedilla }, + { 0x24BD, glyph_Hcircle }, + { 0x1E26, glyph_Hdieresis }, + { 0x1E22, glyph_Hdotaccent }, + { 0x1E24, glyph_Hdotbelow }, + { 0xFF28, glyph_Hmonospace }, + { 0x0540, glyph_Hoarmenian }, + { 0x03E8, glyph_Horicoptic }, + { 0x3390, glyph_Hzsquare }, + { 0x042F, glyph_IAcyrillic }, + { 0x042E, glyph_IUcyrillic }, + { 0x01CF, glyph_Icaron }, + { 0x24BE, glyph_Icircle }, + { 0x0406, glyph_Icyrillic }, + { 0x0208, glyph_Idblgrave }, + { 0x1E2E, glyph_Idieresisacute }, + { 0x04E4, glyph_Idieresiscyrillic }, + { 0x0130, glyph_Idot }, + { 0x1ECA, glyph_Idotbelow }, + { 0x04D6, glyph_Iebrevecyrillic }, + { 0x0415, glyph_Iecyrillic }, + { 0x1EC8, glyph_Ihookabove }, + { 0x0418, glyph_Iicyrillic }, + { 0x020A, glyph_Iinvertedbreve }, + { 0x0419, glyph_Iishortcyrillic }, + { 0x04E2, glyph_Imacroncyrillic }, + { 0xFF29, glyph_Imonospace }, + { 0x053B, glyph_Iniarmenian }, + { 0x0401, glyph_Iocyrillic }, + { 0x0196, glyph_Iotaafrican }, + { 0x0197, glyph_Istroke }, + { 0x1E2C, glyph_Itildebelow }, + { 0x0474, glyph_Izhitsacyrillic }, + { 0x0476, glyph_Izhitsadblgravecyrillic }, + { 0x0541, glyph_Jaarmenian }, + { 0x24BF, glyph_Jcircle }, + { 0x0408, glyph_Jecyrillic }, + { 0x054B, glyph_Jheharmenian }, + { 0xFF2A, glyph_Jmonospace }, + { 0x3385, glyph_KBsquare }, + { 0x33CD, glyph_KKsquare }, + { 0x04A0, glyph_Kabashkircyrillic }, + { 0x1E30, glyph_Kacute }, + { 0x041A, glyph_Kacyrillic }, + { 0x049A, glyph_Kadescendercyrillic }, + { 0x04C3, glyph_Kahookcyrillic }, + { 0x049E, glyph_Kastrokecyrillic }, + { 0x049C, glyph_Kaverticalstrokecyrillic }, + { 0x01E8, glyph_Kcaron }, + { 0x0136, glyph_Kcedilla }, + { 0x24C0, glyph_Kcircle }, + { 0x1E32, glyph_Kdotbelow }, + { 0x0554, glyph_Keharmenian }, + { 0x053F, glyph_Kenarmenian }, + { 0x0425, glyph_Khacyrillic }, + { 0x03E6, glyph_Kheicoptic }, + { 0x0198, glyph_Khook }, + { 0x040C, glyph_Kjecyrillic }, + { 0x1E34, glyph_Klinebelow }, + { 0xFF2B, glyph_Kmonospace }, + { 0x0480, glyph_Koppacyrillic }, + { 0x03DE, glyph_Koppagreek }, + { 0x046E, glyph_Ksicyrillic }, + { 0x01C7, glyph_LJ }, + { 0x013B, glyph_Lcedilla }, + { 0x24C1, glyph_Lcircle }, + { 0x1E3C, glyph_Lcircumflexbelow }, + { 0x013F, glyph_Ldotaccent }, + { 0x1E36, glyph_Ldotbelow }, + { 0x1E38, glyph_Ldotbelowmacron }, + { 0x053C, glyph_Liwnarmenian }, + { 0x01C8, glyph_Lj }, + { 0x0409, glyph_Ljecyrillic }, + { 0x1E3A, glyph_Llinebelow }, + { 0xFF2C, glyph_Lmonospace }, + { 0x3386, glyph_MBsquare }, + { 0x1E3E, glyph_Macute }, + { 0x24C2, glyph_Mcircle }, + { 0x1E40, glyph_Mdotaccent }, + { 0x1E42, glyph_Mdotbelow }, + { 0x0544, glyph_Menarmenian }, + { 0xFF2D, glyph_Mmonospace }, + { 0x019C, glyph_Mturned }, + { 0x01CA, glyph_NJ }, + { 0x0145, glyph_Ncedilla }, + { 0x24C3, glyph_Ncircle }, + { 0x1E4A, glyph_Ncircumflexbelow }, + { 0x1E44, glyph_Ndotaccent }, + { 0x1E46, glyph_Ndotbelow }, + { 0x019D, glyph_Nhookleft }, + { 0x2168, glyph_Nineroman }, + { 0x01CB, glyph_Nj }, + { 0x040A, glyph_Njecyrillic }, + { 0x1E48, glyph_Nlinebelow }, + { 0xFF2E, glyph_Nmonospace }, + { 0x0546, glyph_Nowarmenian }, + { 0x04E8, glyph_Obarredcyrillic }, + { 0x04EA, glyph_Obarreddieresiscyrillic }, + { 0x01D1, glyph_Ocaron }, + { 0x019F, glyph_Ocenteredtilde }, + { 0x24C4, glyph_Ocircle }, + { 0x1ED0, glyph_Ocircumflexacute }, + { 0x1ED8, glyph_Ocircumflexdotbelow }, + { 0x1ED2, glyph_Ocircumflexgrave }, + { 0x1ED4, glyph_Ocircumflexhookabove }, + { 0x1ED6, glyph_Ocircumflextilde }, + { 0x041E, glyph_Ocyrillic }, + { 0x0150, glyph_Odblacute }, + { 0x020C, glyph_Odblgrave }, + { 0x04E6, glyph_Odieresiscyrillic }, + { 0x1ECC, glyph_Odotbelow }, + { 0x0555, glyph_Oharmenian }, + { 0x2126, glyph_Ohm }, + { 0x1ECE, glyph_Ohookabove }, + { 0x1EDA, glyph_Ohornacute }, + { 0x1EE2, glyph_Ohorndotbelow }, + { 0x1EDC, glyph_Ohorngrave }, + { 0x1EDE, glyph_Ohornhookabove }, + { 0x1EE0, glyph_Ohorntilde }, + { 0x01A2, glyph_Oi }, + { 0x020E, glyph_Oinvertedbreve }, + { 0x1E52, glyph_Omacronacute }, + { 0x1E50, glyph_Omacrongrave }, + { 0x0460, glyph_Omegacyrillic }, + { 0x047A, glyph_Omegaroundcyrillic }, + { 0x047C, glyph_Omegatitlocyrillic }, + { 0xFF2F, glyph_Omonospace }, + { 0x2160, glyph_Oneroman }, + { 0x01EA, glyph_Oogonek }, + { 0x01EC, glyph_Oogonekmacron }, + { 0x0186, glyph_Oopen }, + { 0x01FE, glyph_Ostrokeacute }, + { 0x047E, glyph_Otcyrillic }, + { 0x1E4C, glyph_Otildeacute }, + { 0x1E4E, glyph_Otildedieresis }, + { 0x1E54, glyph_Pacute }, + { 0x24C5, glyph_Pcircle }, + { 0x1E56, glyph_Pdotaccent }, + { 0x041F, glyph_Pecyrillic }, + { 0x054A, glyph_Peharmenian }, + { 0x04A6, glyph_Pemiddlehookcyrillic }, + { 0x01A4, glyph_Phook }, + { 0x0553, glyph_Piwrarmenian }, + { 0xFF30, glyph_Pmonospace }, + { 0x0470, glyph_Psicyrillic }, + { 0x24C6, glyph_Qcircle }, + { 0xFF31, glyph_Qmonospace }, + { 0x054C, glyph_Raarmenian }, + { 0x0156, glyph_Rcedilla }, + { 0x24C7, glyph_Rcircle }, + { 0x0210, glyph_Rdblgrave }, + { 0x1E58, glyph_Rdotaccent }, + { 0x1E5A, glyph_Rdotbelow }, + { 0x1E5C, glyph_Rdotbelowmacron }, + { 0x0550, glyph_Reharmenian }, + { 0x0212, glyph_Rinvertedbreve }, + { 0x1E5E, glyph_Rlinebelow }, + { 0xFF32, glyph_Rmonospace }, + { 0x0281, glyph_Rsmallinverted }, + { 0x02B6, glyph_Rsmallinvertedsuperior }, + { 0x1E64, glyph_Sacutedotaccent }, + { 0x03E0, glyph_Sampigreek }, + { 0x1E66, glyph_Scarondotaccent }, + { 0x018F, glyph_Schwa }, + { 0x04D8, glyph_Schwacyrillic }, + { 0x04DA, glyph_Schwadieresiscyrillic }, + { 0x24C8, glyph_Scircle }, + { 0x1E60, glyph_Sdotaccent }, + { 0x1E62, glyph_Sdotbelow }, + { 0x1E68, glyph_Sdotbelowdotaccent }, + { 0x054D, glyph_Seharmenian }, + { 0x2166, glyph_Sevenroman }, + { 0x0547, glyph_Shaarmenian }, + { 0x0428, glyph_Shacyrillic }, + { 0x0429, glyph_Shchacyrillic }, + { 0x03E2, glyph_Sheicoptic }, + { 0x04BA, glyph_Shhacyrillic }, + { 0x03EC, glyph_Shimacoptic }, + { 0x2165, glyph_Sixroman }, + { 0xFF33, glyph_Smonospace }, + { 0x042C, glyph_Softsigncyrillic }, + { 0x03DA, glyph_Stigmagreek }, + { 0x24C9, glyph_Tcircle }, + { 0x1E70, glyph_Tcircumflexbelow }, + { 0x1E6A, glyph_Tdotaccent }, + { 0x1E6C, glyph_Tdotbelow }, + { 0x0422, glyph_Tecyrillic }, + { 0x04AC, glyph_Tedescendercyrillic }, + { 0x2169, glyph_Tenroman }, + { 0x04B4, glyph_Tetsecyrillic }, + { 0x01AC, glyph_Thook }, + { 0x2162, glyph_Threeroman }, + { 0x054F, glyph_Tiwnarmenian }, + { 0x1E6E, glyph_Tlinebelow }, + { 0xFF34, glyph_Tmonospace }, + { 0x0539, glyph_Toarmenian }, + { 0x01BC, glyph_Tonefive }, + { 0x0184, glyph_Tonesix }, + { 0x01A7, glyph_Tonetwo }, + { 0x01AE, glyph_Tretroflexhook }, + { 0x0426, glyph_Tsecyrillic }, + { 0x040B, glyph_Tshecyrillic }, + { 0x216B, glyph_Twelveroman }, + { 0x2161, glyph_Tworoman }, + { 0x01D3, glyph_Ucaron }, + { 0x24CA, glyph_Ucircle }, + { 0x1E76, glyph_Ucircumflexbelow }, + { 0x0423, glyph_Ucyrillic }, + { 0x0170, glyph_Udblacute }, + { 0x0214, glyph_Udblgrave }, + { 0x01D7, glyph_Udieresisacute }, + { 0x1E72, glyph_Udieresisbelow }, + { 0x01D9, glyph_Udieresiscaron }, + { 0x04F0, glyph_Udieresiscyrillic }, + { 0x01DB, glyph_Udieresisgrave }, + { 0x01D5, glyph_Udieresismacron }, + { 0x1EE4, glyph_Udotbelow }, + { 0x1EE6, glyph_Uhookabove }, + { 0x1EE8, glyph_Uhornacute }, + { 0x1EF0, glyph_Uhorndotbelow }, + { 0x1EEA, glyph_Uhorngrave }, + { 0x1EEC, glyph_Uhornhookabove }, + { 0x1EEE, glyph_Uhorntilde }, + { 0x04F2, glyph_Uhungarumlautcyrillic }, + { 0x0216, glyph_Uinvertedbreve }, + { 0x0478, glyph_Ukcyrillic }, + { 0x04EE, glyph_Umacroncyrillic }, + { 0x1E7A, glyph_Umacrondieresis }, + { 0xFF35, glyph_Umonospace }, + { 0x03D3, glyph_Upsilonacutehooksymbolgreek }, + { 0x01B1, glyph_Upsilonafrican }, + { 0x03D4, glyph_Upsilondieresishooksymbolgreek }, + { 0x03D2, glyph_Upsilonhooksymbol }, + { 0x040E, glyph_Ushortcyrillic }, + { 0x04AE, glyph_Ustraightcyrillic }, + { 0x04B0, glyph_Ustraightstrokecyrillic }, + { 0x1E78, glyph_Utildeacute }, + { 0x1E74, glyph_Utildebelow }, + { 0x24CB, glyph_Vcircle }, + { 0x1E7E, glyph_Vdotbelow }, + { 0x0412, glyph_Vecyrillic }, + { 0x054E, glyph_Vewarmenian }, + { 0x01B2, glyph_Vhook }, + { 0xFF36, glyph_Vmonospace }, + { 0x0548, glyph_Voarmenian }, + { 0x1E7C, glyph_Vtilde }, + { 0x24CC, glyph_Wcircle }, + { 0x1E86, glyph_Wdotaccent }, + { 0x1E88, glyph_Wdotbelow }, + { 0xFF37, glyph_Wmonospace }, + { 0x24CD, glyph_Xcircle }, + { 0x1E8C, glyph_Xdieresis }, + { 0x1E8A, glyph_Xdotaccent }, + { 0x053D, glyph_Xeharmenian }, + { 0xFF38, glyph_Xmonospace }, + { 0x0462, glyph_Yatcyrillic }, + { 0x24CE, glyph_Ycircle }, + { 0x1E8E, glyph_Ydotaccent }, + { 0x1EF4, glyph_Ydotbelow }, + { 0x042B, glyph_Yericyrillic }, + { 0x04F8, glyph_Yerudieresiscyrillic }, + { 0x01B3, glyph_Yhook }, + { 0x1EF6, glyph_Yhookabove }, + { 0x0545, glyph_Yiarmenian }, + { 0x0407, glyph_Yicyrillic }, + { 0x0552, glyph_Yiwnarmenian }, + { 0xFF39, glyph_Ymonospace }, + { 0x1EF8, glyph_Ytilde }, + { 0x046A, glyph_Yusbigcyrillic }, + { 0x046C, glyph_Yusbigiotifiedcyrillic }, + { 0x0466, glyph_Yuslittlecyrillic }, + { 0x0468, glyph_Yuslittleiotifiedcyrillic }, + { 0x0536, glyph_Zaarmenian }, + { 0x24CF, glyph_Zcircle }, + { 0x1E90, glyph_Zcircumflex }, + { 0x017B, glyph_Zdot }, + { 0x1E92, glyph_Zdotbelow }, + { 0x0417, glyph_Zecyrillic }, + { 0x0498, glyph_Zedescendercyrillic }, + { 0x04DE, glyph_Zedieresiscyrillic }, + { 0x053A, glyph_Zhearmenian }, + { 0x04C1, glyph_Zhebrevecyrillic }, + { 0x0416, glyph_Zhecyrillic }, + { 0x0496, glyph_Zhedescendercyrillic }, + { 0x04DC, glyph_Zhedieresiscyrillic }, + { 0x1E94, glyph_Zlinebelow }, + { 0xFF3A, glyph_Zmonospace }, + { 0x01B5, glyph_Zstroke }, + { 0x0986, glyph_aabengali }, + { 0x0906, glyph_aadeva }, + { 0x0A86, glyph_aagujarati }, + { 0x0A06, glyph_aagurmukhi }, + { 0x0A3E, glyph_aamatragurmukhi }, + { 0x3303, glyph_aarusquare }, + { 0x09BE, glyph_aavowelsignbengali }, + { 0x093E, glyph_aavowelsigndeva }, + { 0x0ABE, glyph_aavowelsigngujarati }, + { 0x055F, glyph_abbreviationmarkarmenian }, + { 0x0970, glyph_abbreviationsigndeva }, + { 0x0985, glyph_abengali }, + { 0x311A, glyph_abopomofo }, + { 0x1EAF, glyph_abreveacute }, + { 0x04D1, glyph_abrevecyrillic }, + { 0x1EB7, glyph_abrevedotbelow }, + { 0x1EB1, glyph_abrevegrave }, + { 0x1EB3, glyph_abrevehookabove }, + { 0x1EB5, glyph_abrevetilde }, + { 0x01CE, glyph_acaron }, + { 0x24D0, glyph_acircle }, + { 0x1EA5, glyph_acircumflexacute }, + { 0x1EAD, glyph_acircumflexdotbelow }, + { 0x1EA7, glyph_acircumflexgrave }, + { 0x1EA9, glyph_acircumflexhookabove }, + { 0x1EAB, glyph_acircumflextilde }, + { 0x0317, glyph_acutebelowcmb }, + { 0x0301, glyph_acutecmb }, + { 0x0954, glyph_acutedeva }, + { 0x02CF, glyph_acutelowmod }, + { 0x0341, glyph_acutetonecmb }, + { 0x0430, glyph_acyrillic }, + { 0x0201, glyph_adblgrave }, + { 0x0A71, glyph_addakgurmukhi }, + { 0x0905, glyph_adeva }, + { 0x04D3, glyph_adieresiscyrillic }, + { 0x01DF, glyph_adieresismacron }, + { 0x1EA1, glyph_adotbelow }, + { 0x01E1, glyph_adotmacron }, + { 0x3150, glyph_aekorean }, + { 0x01E3, glyph_aemacron }, + { 0x20A4, glyph_afii08941 }, + { 0x0A85, glyph_agujarati }, + { 0x0A05, glyph_agurmukhi }, + { 0x3042, glyph_ahiragana }, + { 0x1EA3, glyph_ahookabove }, + { 0x0990, glyph_aibengali }, + { 0x311E, glyph_aibopomofo }, + { 0x0910, glyph_aideva }, + { 0x04D5, glyph_aiecyrillic }, + { 0x0A90, glyph_aigujarati }, + { 0x0A10, glyph_aigurmukhi }, + { 0x0A48, glyph_aimatragurmukhi }, + { 0x0639, glyph_ainarabic }, + { 0xFECA, glyph_ainfinalarabic }, + { 0xFECB, glyph_aininitialarabic }, + { 0xFECC, glyph_ainmedialarabic }, + { 0x0203, glyph_ainvertedbreve }, + { 0x09C8, glyph_aivowelsignbengali }, + { 0x0948, glyph_aivowelsigndeva }, + { 0x0AC8, glyph_aivowelsigngujarati }, + { 0x30A2, glyph_akatakana }, + { 0xFF71, glyph_akatakanahalfwidth }, + { 0x314F, glyph_akorean }, + { 0x05D0, glyph_alef }, + { 0x0627, glyph_alefarabic }, + { 0xFB30, glyph_alefdageshhebrew }, + { 0xFE8E, glyph_aleffinalarabic }, + { 0x0623, glyph_alefhamzaabovearabic }, + { 0xFE84, glyph_alefhamzaabovefinalarabic }, + { 0x0625, glyph_alefhamzabelowarabic }, + { 0xFE88, glyph_alefhamzabelowfinalarabic }, + { 0x05D0, glyph_alefhebrew }, + { 0xFB4F, glyph_aleflamedhebrew }, + { 0x0622, glyph_alefmaddaabovearabic }, + { 0xFE82, glyph_alefmaddaabovefinalarabic }, + { 0x0649, glyph_alefmaksuraarabic }, + { 0xFEF0, glyph_alefmaksurafinalarabic }, + { 0xFEF3, glyph_alefmaksurainitialarabic }, + { 0xFEF4, glyph_alefmaksuramedialarabic }, + { 0xFB2E, glyph_alefpatahhebrew }, + { 0xFB2F, glyph_alefqamatshebrew }, + { 0x224C, glyph_allequal }, + { 0xFF41, glyph_amonospace }, + { 0xFF06, glyph_ampersandmonospace }, + { 0x33C2, glyph_amsquare }, + { 0x3122, glyph_anbopomofo }, + { 0x3124, glyph_angbopomofo }, + { 0x0E5A, glyph_angkhankhuthai }, + { 0x3008, glyph_anglebracketleft }, + { 0xFE3F, glyph_anglebracketleftvertical }, + { 0x3009, glyph_anglebracketright }, + { 0xFE40, glyph_anglebracketrightvertical }, + { 0x212B, glyph_angstrom }, + { 0x0952, glyph_anudattadeva }, + { 0x0982, glyph_anusvarabengali }, + { 0x0902, glyph_anusvaradeva }, + { 0x0A82, glyph_anusvaragujarati }, + { 0x3300, glyph_apaatosquare }, + { 0x249C, glyph_aparen }, + { 0x055A, glyph_apostrophearmenian }, + { 0x02BC, glyph_apostrophemod }, + { 0x2250, glyph_approaches }, + { 0x2252, glyph_approxequalorimage }, + { 0x2245, glyph_approximatelyequal }, + { 0x318E, glyph_araeaekorean }, + { 0x318D, glyph_araeakorean }, + { 0x2312, glyph_arc }, + { 0x1E9A, glyph_arighthalfring }, + { 0x1E01, glyph_aringbelow }, + { 0x21E3, glyph_arrowdashdown }, + { 0x21E0, glyph_arrowdashleft }, + { 0x21E2, glyph_arrowdashright }, + { 0x21E1, glyph_arrowdashup }, + { 0x2199, glyph_arrowdownleft }, + { 0x2198, glyph_arrowdownright }, + { 0x21E9, glyph_arrowdownwhite }, + { 0x02C5, glyph_arrowheaddownmod }, + { 0x02C2, glyph_arrowheadleftmod }, + { 0x02C3, glyph_arrowheadrightmod }, + { 0x02C4, glyph_arrowheadupmod }, + { 0x21D0, glyph_arrowleftdbl }, + { 0x21CD, glyph_arrowleftdblstroke }, + { 0x21C6, glyph_arrowleftoverright }, + { 0x21E6, glyph_arrowleftwhite }, + { 0x21CF, glyph_arrowrightdblstroke }, + { 0x279E, glyph_arrowrightheavy }, + { 0x21C4, glyph_arrowrightoverleft }, + { 0x21E8, glyph_arrowrightwhite }, + { 0x21E4, glyph_arrowtableft }, + { 0x21E5, glyph_arrowtabright }, + { 0x21A8, glyph_arrowupdownbase }, + { 0x2196, glyph_arrowupleft }, + { 0x21C5, glyph_arrowupleftofdown }, + { 0x2197, glyph_arrowupright }, + { 0x21E7, glyph_arrowupwhite }, + { 0xFF3E, glyph_asciicircummonospace }, + { 0xFF5E, glyph_asciitildemonospace }, + { 0x0251, glyph_ascript }, + { 0x0252, glyph_ascriptturned }, + { 0x3041, glyph_asmallhiragana }, + { 0x30A1, glyph_asmallkatakana }, + { 0xFF67, glyph_asmallkatakanahalfwidth }, + { 0x066D, glyph_asteriskaltonearabic }, + { 0x066D, glyph_asteriskarabic }, + { 0xFF0A, glyph_asteriskmonospace }, + { 0xFE61, glyph_asterisksmall }, + { 0x2042, glyph_asterism }, + { 0x2243, glyph_asymptoticallyequal }, + { 0xFF20, glyph_atmonospace }, + { 0xFE6B, glyph_atsmall }, + { 0x0250, glyph_aturned }, + { 0x0994, glyph_aubengali }, + { 0x3120, glyph_aubopomofo }, + { 0x0914, glyph_audeva }, + { 0x0A94, glyph_augujarati }, + { 0x0A14, glyph_augurmukhi }, + { 0x09D7, glyph_aulengthmarkbengali }, + { 0x0A4C, glyph_aumatragurmukhi }, + { 0x09CC, glyph_auvowelsignbengali }, + { 0x094C, glyph_auvowelsigndeva }, + { 0x0ACC, glyph_auvowelsigngujarati }, + { 0x093D, glyph_avagrahadeva }, + { 0x0561, glyph_aybarmenian }, + { 0x05E2, glyph_ayin }, + { 0xFB20, glyph_ayinaltonehebrew }, + { 0x05E2, glyph_ayinhebrew }, + { 0x09AC, glyph_babengali }, + { 0xFF3C, glyph_backslashmonospace }, + { 0x092C, glyph_badeva }, + { 0x0AAC, glyph_bagujarati }, + { 0x0A2C, glyph_bagurmukhi }, + { 0x3070, glyph_bahiragana }, + { 0x0E3F, glyph_bahtthai }, + { 0x30D0, glyph_bakatakana }, + { 0xFF5C, glyph_barmonospace }, + { 0x3105, glyph_bbopomofo }, + { 0x24D1, glyph_bcircle }, + { 0x1E03, glyph_bdotaccent }, + { 0x1E05, glyph_bdotbelow }, + { 0x266C, glyph_beamedsixteenthnotes }, + { 0x2235, glyph_because }, + { 0x0431, glyph_becyrillic }, + { 0x0628, glyph_beharabic }, + { 0xFE90, glyph_behfinalarabic }, + { 0xFE91, glyph_behinitialarabic }, + { 0x3079, glyph_behiragana }, + { 0xFE92, glyph_behmedialarabic }, + { 0xFC9F, glyph_behmeeminitialarabic }, + { 0xFC08, glyph_behmeemisolatedarabic }, + { 0xFC6D, glyph_behnoonfinalarabic }, + { 0x30D9, glyph_bekatakana }, + { 0x0562, glyph_benarmenian }, + { 0x05D1, glyph_bet }, + { 0x03D0, glyph_betasymbolgreek }, + { 0xFB31, glyph_betdagesh }, + { 0xFB31, glyph_betdageshhebrew }, + { 0x05D1, glyph_bethebrew }, + { 0xFB4C, glyph_betrafehebrew }, + { 0x09AD, glyph_bhabengali }, + { 0x092D, glyph_bhadeva }, + { 0x0AAD, glyph_bhagujarati }, + { 0x0A2D, glyph_bhagurmukhi }, + { 0x0253, glyph_bhook }, + { 0x3073, glyph_bihiragana }, + { 0x30D3, glyph_bikatakana }, + { 0x0298, glyph_bilabialclick }, + { 0x0A02, glyph_bindigurmukhi }, + { 0x3331, glyph_birusquare }, + { 0x25CF, glyph_blackcircle }, + { 0x25C6, glyph_blackdiamond }, + { 0x25BC, glyph_blackdownpointingtriangle }, + { 0x25C4, glyph_blackleftpointingpointer }, + { 0x25C0, glyph_blackleftpointingtriangle }, + { 0x3010, glyph_blacklenticularbracketleft }, + { 0xFE3B, glyph_blacklenticularbracketleftvertical }, + { 0x3011, glyph_blacklenticularbracketright }, + { 0xFE3C, glyph_blacklenticularbracketrightvertical }, + { 0x25E3, glyph_blacklowerlefttriangle }, + { 0x25E2, glyph_blacklowerrighttriangle }, + { 0x25AC, glyph_blackrectangle }, + { 0x25BA, glyph_blackrightpointingpointer }, + { 0x25B6, glyph_blackrightpointingtriangle }, + { 0x25AA, glyph_blacksmallsquare }, + { 0x263B, glyph_blacksmilingface }, + { 0x25A0, glyph_blacksquare }, + { 0x2605, glyph_blackstar }, + { 0x25E4, glyph_blackupperlefttriangle }, + { 0x25E5, glyph_blackupperrighttriangle }, + { 0x25B4, glyph_blackuppointingsmalltriangle }, + { 0x25B2, glyph_blackuppointingtriangle }, + { 0x2423, glyph_blank }, + { 0x1E07, glyph_blinebelow }, + { 0xFF42, glyph_bmonospace }, + { 0x0E1A, glyph_bobaimaithai }, + { 0x307C, glyph_bohiragana }, + { 0x30DC, glyph_bokatakana }, + { 0x249D, glyph_bparen }, + { 0x33C3, glyph_bqsquare }, + { 0xFF5B, glyph_braceleftmonospace }, + { 0xFE5B, glyph_braceleftsmall }, + { 0xFE37, glyph_braceleftvertical }, + { 0xFF5D, glyph_bracerightmonospace }, + { 0xFE5C, glyph_bracerightsmall }, + { 0xFE38, glyph_bracerightvertical }, + { 0xFF3B, glyph_bracketleftmonospace }, + { 0xFF3D, glyph_bracketrightmonospace }, + { 0x032E, glyph_brevebelowcmb }, + { 0x0306, glyph_brevecmb }, + { 0x032F, glyph_breveinvertedbelowcmb }, + { 0x0311, glyph_breveinvertedcmb }, + { 0x0361, glyph_breveinverteddoublecmb }, + { 0x032A, glyph_bridgebelowcmb }, + { 0x033A, glyph_bridgeinvertedbelowcmb }, + { 0x0180, glyph_bstroke }, + { 0x0183, glyph_btopbar }, + { 0x3076, glyph_buhiragana }, + { 0x30D6, glyph_bukatakana }, + { 0x25D8, glyph_bulletinverse }, + { 0x25CE, glyph_bullseye }, + { 0x056E, glyph_caarmenian }, + { 0x099A, glyph_cabengali }, + { 0x091A, glyph_cadeva }, + { 0x0A9A, glyph_cagujarati }, + { 0x0A1A, glyph_cagurmukhi }, + { 0x3388, glyph_calsquare }, + { 0x0981, glyph_candrabindubengali }, + { 0x0310, glyph_candrabinducmb }, + { 0x0901, glyph_candrabindudeva }, + { 0x0A81, glyph_candrabindugujarati }, + { 0x21EA, glyph_capslock }, + { 0x2105, glyph_careof }, + { 0x032C, glyph_caronbelowcmb }, + { 0x030C, glyph_caroncmb }, + { 0x3118, glyph_cbopomofo }, + { 0x1E09, glyph_ccedillaacute }, + { 0x24D2, glyph_ccircle }, + { 0x0255, glyph_ccurl }, + { 0x010B, glyph_cdot }, + { 0x33C5, glyph_cdsquare }, + { 0x0327, glyph_cedillacmb }, + { 0x2103, glyph_centigrade }, + { 0xFFE0, glyph_centmonospace }, + { 0x0579, glyph_chaarmenian }, + { 0x099B, glyph_chabengali }, + { 0x091B, glyph_chadeva }, + { 0x0A9B, glyph_chagujarati }, + { 0x0A1B, glyph_chagurmukhi }, + { 0x3114, glyph_chbopomofo }, + { 0x04BD, glyph_cheabkhasiancyrillic }, + { 0x2713, glyph_checkmark }, + { 0x0447, glyph_checyrillic }, + { 0x04BF, glyph_chedescenderabkhasiancyrillic }, + { 0x04B7, glyph_chedescendercyrillic }, + { 0x04F5, glyph_chedieresiscyrillic }, + { 0x0573, glyph_cheharmenian }, + { 0x04CC, glyph_chekhakassiancyrillic }, + { 0x04B9, glyph_cheverticalstrokecyrillic }, + { 0x3277, glyph_chieuchacirclekorean }, + { 0x3217, glyph_chieuchaparenkorean }, + { 0x3269, glyph_chieuchcirclekorean }, + { 0x314A, glyph_chieuchkorean }, + { 0x3209, glyph_chieuchparenkorean }, + { 0x0E0A, glyph_chochangthai }, + { 0x0E08, glyph_chochanthai }, + { 0x0E09, glyph_chochingthai }, + { 0x0E0C, glyph_chochoethai }, + { 0x0188, glyph_chook }, + { 0x3276, glyph_cieucacirclekorean }, + { 0x3216, glyph_cieucaparenkorean }, + { 0x3268, glyph_cieuccirclekorean }, + { 0x3148, glyph_cieuckorean }, + { 0x3208, glyph_cieucparenkorean }, + { 0x321C, glyph_cieucuparenkorean }, + { 0x2299, glyph_circleot }, + { 0x3036, glyph_circlepostalmark }, + { 0x25D0, glyph_circlewithlefthalfblack }, + { 0x25D1, glyph_circlewithrighthalfblack }, + { 0x032D, glyph_circumflexbelowcmb }, + { 0x0302, glyph_circumflexcmb }, + { 0x2327, glyph_clear }, + { 0x01C2, glyph_clickalveolar }, + { 0x01C0, glyph_clickdental }, + { 0x01C1, glyph_clicklateral }, + { 0x01C3, glyph_clickretroflex }, + { 0x2663, glyph_clubsuitblack }, + { 0x2667, glyph_clubsuitwhite }, + { 0x33A4, glyph_cmcubedsquare }, + { 0xFF43, glyph_cmonospace }, + { 0x33A0, glyph_cmsquaredsquare }, + { 0x0581, glyph_coarmenian }, + { 0xFF1A, glyph_colonmonospace }, + { 0x20A1, glyph_colonsign }, + { 0xFE55, glyph_colonsmall }, + { 0x02D1, glyph_colontriangularhalfmod }, + { 0x02D0, glyph_colontriangularmod }, + { 0x0313, glyph_commaabovecmb }, + { 0x0315, glyph_commaaboverightcmb }, + { 0x060C, glyph_commaarabic }, + { 0x055D, glyph_commaarmenian }, + { 0xFF0C, glyph_commamonospace }, + { 0x0314, glyph_commareversedabovecmb }, + { 0x02BD, glyph_commareversedmod }, + { 0xFE50, glyph_commasmall }, + { 0x0312, glyph_commaturnedabovecmb }, + { 0x02BB, glyph_commaturnedmod }, + { 0x263C, glyph_compass }, + { 0x222E, glyph_contourintegral }, + { 0x2303, glyph_control }, + { 0x0006, glyph_controlACK }, + { 0x0007, glyph_controlBEL }, + { 0x0008, glyph_controlBS }, + { 0x0018, glyph_controlCAN }, + { 0x000D, glyph_controlCR }, + { 0x0011, glyph_controlDC1 }, + { 0x0012, glyph_controlDC2 }, + { 0x0013, glyph_controlDC3 }, + { 0x0014, glyph_controlDC4 }, + { 0x007F, glyph_controlDEL }, + { 0x0010, glyph_controlDLE }, + { 0x0019, glyph_controlEM }, + { 0x0005, glyph_controlENQ }, + { 0x0004, glyph_controlEOT }, + { 0x001B, glyph_controlESC }, + { 0x0017, glyph_controlETB }, + { 0x0003, glyph_controlETX }, + { 0x000C, glyph_controlFF }, + { 0x001C, glyph_controlFS }, + { 0x001D, glyph_controlGS }, + { 0x0009, glyph_controlHT }, + { 0x000A, glyph_controlLF }, + { 0x0015, glyph_controlNAK }, + { 0x001E, glyph_controlRS }, + { 0x000F, glyph_controlSI }, + { 0x000E, glyph_controlSO }, + { 0x0002, glyph_controlSOT }, + { 0x0001, glyph_controlSTX }, + { 0x001A, glyph_controlSUB }, + { 0x0016, glyph_controlSYN }, + { 0x001F, glyph_controlUS }, + { 0x000B, glyph_controlVT }, + { 0x300C, glyph_cornerbracketleft }, + { 0xFF62, glyph_cornerbracketlefthalfwidth }, + { 0xFE41, glyph_cornerbracketleftvertical }, + { 0x300D, glyph_cornerbracketright }, + { 0xFF63, glyph_cornerbracketrighthalfwidth }, + { 0xFE42, glyph_cornerbracketrightvertical }, + { 0x337F, glyph_corporationsquare }, + { 0x33C7, glyph_cosquare }, + { 0x33C6, glyph_coverkgsquare }, + { 0x249E, glyph_cparen }, + { 0x20A2, glyph_cruzeiro }, + { 0x0297, glyph_cstretched }, + { 0x22CF, glyph_curlyand }, + { 0x22CE, glyph_curlyor }, + { 0x0564, glyph_daarmenian }, + { 0x09A6, glyph_dabengali }, + { 0x0636, glyph_dadarabic }, + { 0x0926, glyph_dadeva }, + { 0xFEBE, glyph_dadfinalarabic }, + { 0xFEBF, glyph_dadinitialarabic }, + { 0xFEC0, glyph_dadmedialarabic }, + { 0x05BC, glyph_dagesh }, + { 0x05BC, glyph_dageshhebrew }, + { 0x0AA6, glyph_dagujarati }, + { 0x0A26, glyph_dagurmukhi }, + { 0x3060, glyph_dahiragana }, + { 0x30C0, glyph_dakatakana }, + { 0x062F, glyph_dalarabic }, + { 0x05D3, glyph_dalet }, + { 0xFB33, glyph_daletdagesh }, + { 0xFB33, glyph_daletdageshhebrew }, + { 0x05D3, glyph_dalethatafpatah }, + { 0x05B2, glyph_dalethatafpatah }, + { 0x05D3, glyph_dalethatafpatahhebrew }, + { 0x05B2, glyph_dalethatafpatahhebrew }, + { 0x05D3, glyph_dalethatafsegol }, + { 0x05B1, glyph_dalethatafsegol }, + { 0x05D3, glyph_dalethatafsegolhebrew }, + { 0x05B1, glyph_dalethatafsegolhebrew }, + { 0x05D3, glyph_dalethebrew }, + { 0x05D3, glyph_dalethiriq }, + { 0x05B4, glyph_dalethiriq }, + { 0x05D3, glyph_dalethiriqhebrew }, + { 0x05B4, glyph_dalethiriqhebrew }, + { 0x05D3, glyph_daletholam }, + { 0x05B9, glyph_daletholam }, + { 0x05D3, glyph_daletholamhebrew }, + { 0x05B9, glyph_daletholamhebrew }, + { 0x05D3, glyph_daletpatah }, + { 0x05B7, glyph_daletpatah }, + { 0x05D3, glyph_daletpatahhebrew }, + { 0x05B7, glyph_daletpatahhebrew }, + { 0x05D3, glyph_daletqamats }, + { 0x05B8, glyph_daletqamats }, + { 0x05D3, glyph_daletqamatshebrew }, + { 0x05B8, glyph_daletqamatshebrew }, + { 0x05D3, glyph_daletqubuts }, + { 0x05BB, glyph_daletqubuts }, + { 0x05D3, glyph_daletqubutshebrew }, + { 0x05BB, glyph_daletqubutshebrew }, + { 0x05D3, glyph_daletsegol }, + { 0x05B6, glyph_daletsegol }, + { 0x05D3, glyph_daletsegolhebrew }, + { 0x05B6, glyph_daletsegolhebrew }, + { 0x05D3, glyph_daletsheva }, + { 0x05B0, glyph_daletsheva }, + { 0x05D3, glyph_daletshevahebrew }, + { 0x05B0, glyph_daletshevahebrew }, + { 0x05D3, glyph_dalettsere }, + { 0x05B5, glyph_dalettsere }, + { 0x05D3, glyph_dalettserehebrew }, + { 0x05B5, glyph_dalettserehebrew }, + { 0xFEAA, glyph_dalfinalarabic }, + { 0x064F, glyph_dammaarabic }, + { 0x064F, glyph_dammalowarabic }, + { 0x064C, glyph_dammatanaltonearabic }, + { 0x064C, glyph_dammatanarabic }, + { 0x0964, glyph_danda }, + { 0x05A7, glyph_dargahebrew }, + { 0x05A7, glyph_dargalefthebrew }, + { 0x0485, glyph_dasiapneumatacyrilliccmb }, + { 0x300A, glyph_dblanglebracketleft }, + { 0xFE3D, glyph_dblanglebracketleftvertical }, + { 0x300B, glyph_dblanglebracketright }, + { 0xFE3E, glyph_dblanglebracketrightvertical }, + { 0x032B, glyph_dblarchinvertedbelowcmb }, + { 0x21D4, glyph_dblarrowleft }, + { 0x21D2, glyph_dblarrowright }, + { 0x0965, glyph_dbldanda }, + { 0x030F, glyph_dblgravecmb }, + { 0x222C, glyph_dblintegral }, + { 0x2017, glyph_dbllowline }, + { 0x0333, glyph_dbllowlinecmb }, + { 0x033F, glyph_dbloverlinecmb }, + { 0x02BA, glyph_dblprimemod }, + { 0x2016, glyph_dblverticalbar }, + { 0x030E, glyph_dblverticallineabovecmb }, + { 0x3109, glyph_dbopomofo }, + { 0x33C8, glyph_dbsquare }, + { 0x1E11, glyph_dcedilla }, + { 0x24D3, glyph_dcircle }, + { 0x1E13, glyph_dcircumflexbelow }, + { 0x09A1, glyph_ddabengali }, + { 0x0921, glyph_ddadeva }, + { 0x0AA1, glyph_ddagujarati }, + { 0x0A21, glyph_ddagurmukhi }, + { 0x0688, glyph_ddalarabic }, + { 0xFB89, glyph_ddalfinalarabic }, + { 0x095C, glyph_dddhadeva }, + { 0x09A2, glyph_ddhabengali }, + { 0x0922, glyph_ddhadeva }, + { 0x0AA2, glyph_ddhagujarati }, + { 0x0A22, glyph_ddhagurmukhi }, + { 0x1E0B, glyph_ddotaccent }, + { 0x1E0D, glyph_ddotbelow }, + { 0x066B, glyph_decimalseparatorarabic }, + { 0x066B, glyph_decimalseparatorpersian }, + { 0x0434, glyph_decyrillic }, + { 0x05AD, glyph_dehihebrew }, + { 0x3067, glyph_dehiragana }, + { 0x03EF, glyph_deicoptic }, + { 0x30C7, glyph_dekatakana }, + { 0x232B, glyph_deleteleft }, + { 0x2326, glyph_deleteright }, + { 0x018D, glyph_deltaturned }, + { 0x09F8, glyph_denominatorminusonenumeratorbengali }, + { 0x02A4, glyph_dezh }, + { 0x09A7, glyph_dhabengali }, + { 0x0927, glyph_dhadeva }, + { 0x0AA7, glyph_dhagujarati }, + { 0x0A27, glyph_dhagurmukhi }, + { 0x0257, glyph_dhook }, + { 0x0385, glyph_dialytikatonos }, + { 0x0344, glyph_dialytikatonoscmb }, + { 0x2662, glyph_diamondsuitwhite }, + { 0x0324, glyph_dieresisbelowcmb }, + { 0x0308, glyph_dieresiscmb }, + { 0x3062, glyph_dihiragana }, + { 0x30C2, glyph_dikatakana }, + { 0x3003, glyph_dittomark }, + { 0x2223, glyph_divides }, + { 0x0452, glyph_djecyrillic }, + { 0x1E0F, glyph_dlinebelow }, + { 0x3397, glyph_dlsquare }, + { 0x0111, glyph_dmacron }, + { 0xFF44, glyph_dmonospace }, + { 0x0E0E, glyph_dochadathai }, + { 0x0E14, glyph_dodekthai }, + { 0x3069, glyph_dohiragana }, + { 0x30C9, glyph_dokatakana }, + { 0xFF04, glyph_dollarmonospace }, + { 0xFE69, glyph_dollarsmall }, + { 0x3326, glyph_dorusquare }, + { 0x0307, glyph_dotaccentcmb }, + { 0x0323, glyph_dotbelowcmb }, + { 0x30FB, glyph_dotkatakana }, + { 0x0284, glyph_dotlessjstrokehook }, + { 0x25CC, glyph_dottedcircle }, + { 0xFB1F, glyph_doubleyodpatah }, + { 0xFB1F, glyph_doubleyodpatahhebrew }, + { 0x031E, glyph_downtackbelowcmb }, + { 0x02D5, glyph_downtackmod }, + { 0x249F, glyph_dparen }, + { 0x0256, glyph_dtail }, + { 0x018C, glyph_dtopbar }, + { 0x3065, glyph_duhiragana }, + { 0x30C5, glyph_dukatakana }, + { 0x01F3, glyph_dz }, + { 0x02A3, glyph_dzaltone }, + { 0x01C6, glyph_dzcaron }, + { 0x02A5, glyph_dzcurl }, + { 0x04E1, glyph_dzeabkhasiancyrillic }, + { 0x0455, glyph_dzecyrillic }, + { 0x045F, glyph_dzhecyrillic }, + { 0x2641, glyph_earth }, + { 0x098F, glyph_ebengali }, + { 0x311C, glyph_ebopomofo }, + { 0x090D, glyph_ecandradeva }, + { 0x0A8D, glyph_ecandragujarati }, + { 0x0945, glyph_ecandravowelsigndeva }, + { 0x0AC5, glyph_ecandravowelsigngujarati }, + { 0x1E1D, glyph_ecedillabreve }, + { 0x0565, glyph_echarmenian }, + { 0x0587, glyph_echyiwnarmenian }, + { 0x24D4, glyph_ecircle }, + { 0x1EBF, glyph_ecircumflexacute }, + { 0x1E19, glyph_ecircumflexbelow }, + { 0x1EC7, glyph_ecircumflexdotbelow }, + { 0x1EC1, glyph_ecircumflexgrave }, + { 0x1EC3, glyph_ecircumflexhookabove }, + { 0x1EC5, glyph_ecircumflextilde }, + { 0x0454, glyph_ecyrillic }, + { 0x0205, glyph_edblgrave }, + { 0x090F, glyph_edeva }, + { 0x0117, glyph_edot }, + { 0x1EB9, glyph_edotbelow }, + { 0x0A0F, glyph_eegurmukhi }, + { 0x0A47, glyph_eematragurmukhi }, + { 0x0444, glyph_efcyrillic }, + { 0x0A8F, glyph_egujarati }, + { 0x0567, glyph_eharmenian }, + { 0x311D, glyph_ehbopomofo }, + { 0x3048, glyph_ehiragana }, + { 0x1EBB, glyph_ehookabove }, + { 0x311F, glyph_eibopomofo }, + { 0x0668, glyph_eightarabic }, + { 0x09EE, glyph_eightbengali }, + { 0x2467, glyph_eightcircle }, + { 0x2791, glyph_eightcircleinversesansserif }, + { 0x096E, glyph_eightdeva }, + { 0x2471, glyph_eighteencircle }, + { 0x2485, glyph_eighteenparen }, + { 0x2499, glyph_eighteenperiod }, + { 0x0AEE, glyph_eightgujarati }, + { 0x0A6E, glyph_eightgurmukhi }, + { 0x0668, glyph_eighthackarabic }, + { 0x3028, glyph_eighthangzhou }, + { 0x266B, glyph_eighthnotebeamed }, + { 0x3227, glyph_eightideographicparen }, + { 0xFF18, glyph_eightmonospace }, + { 0x247B, glyph_eightparen }, + { 0x248F, glyph_eightperiod }, + { 0x06F8, glyph_eightpersian }, + { 0x2177, glyph_eightroman }, + { 0x0E58, glyph_eightthai }, + { 0x0207, glyph_einvertedbreve }, + { 0x0465, glyph_eiotifiedcyrillic }, + { 0x30A8, glyph_ekatakana }, + { 0xFF74, glyph_ekatakanahalfwidth }, + { 0x0A74, glyph_ekonkargurmukhi }, + { 0x3154, glyph_ekorean }, + { 0x043B, glyph_elcyrillic }, + { 0x246A, glyph_elevencircle }, + { 0x247E, glyph_elevenparen }, + { 0x2492, glyph_elevenperiod }, + { 0x217A, glyph_elevenroman }, + { 0x22EE, glyph_ellipsisvertical }, + { 0x1E17, glyph_emacronacute }, + { 0x1E15, glyph_emacrongrave }, + { 0x043C, glyph_emcyrillic }, + { 0xFE31, glyph_emdashvertical }, + { 0xFF45, glyph_emonospace }, + { 0x055B, glyph_emphasismarkarmenian }, + { 0x3123, glyph_enbopomofo }, + { 0x043D, glyph_encyrillic }, + { 0xFE32, glyph_endashvertical }, + { 0x04A3, glyph_endescendercyrillic }, + { 0x3125, glyph_engbopomofo }, + { 0x04A5, glyph_enghecyrillic }, + { 0x04C8, glyph_enhookcyrillic }, + { 0x2002, glyph_enspace }, + { 0x3153, glyph_eokorean }, + { 0x025B, glyph_eopen }, + { 0x029A, glyph_eopenclosed }, + { 0x025C, glyph_eopenreversed }, + { 0x025E, glyph_eopenreversedclosed }, + { 0x025D, glyph_eopenreversedhook }, + { 0x24A0, glyph_eparen }, + { 0xFF1D, glyph_equalmonospace }, + { 0xFE66, glyph_equalsmall }, + { 0x207C, glyph_equalsuperior }, + { 0x3126, glyph_erbopomofo }, + { 0x0440, glyph_ercyrillic }, + { 0x0258, glyph_ereversed }, + { 0x044D, glyph_ereversedcyrillic }, + { 0x0441, glyph_escyrillic }, + { 0x04AB, glyph_esdescendercyrillic }, + { 0x0283, glyph_esh }, + { 0x0286, glyph_eshcurl }, + { 0x090E, glyph_eshortdeva }, + { 0x0946, glyph_eshortvowelsigndeva }, + { 0x01AA, glyph_eshreversedloop }, + { 0x0285, glyph_eshsquatreversed }, + { 0x3047, glyph_esmallhiragana }, + { 0x30A7, glyph_esmallkatakana }, + { 0xFF6A, glyph_esmallkatakanahalfwidth }, + { 0x0568, glyph_etarmenian }, + { 0x1EBD, glyph_etilde }, + { 0x1E1B, glyph_etildebelow }, + { 0x0591, glyph_etnahtafoukhhebrew }, + { 0x0591, glyph_etnahtafoukhlefthebrew }, + { 0x0591, glyph_etnahtahebrew }, + { 0x0591, glyph_etnahtalefthebrew }, + { 0x01DD, glyph_eturned }, + { 0x3161, glyph_eukorean }, + { 0x20AC, glyph_euro }, + { 0x09C7, glyph_evowelsignbengali }, + { 0x0947, glyph_evowelsigndeva }, + { 0x0AC7, glyph_evowelsigngujarati }, + { 0x055C, glyph_exclamarmenian }, + { 0xFF01, glyph_exclammonospace }, + { 0x0292, glyph_ezh }, + { 0x01EF, glyph_ezhcaron }, + { 0x0293, glyph_ezhcurl }, + { 0x01B9, glyph_ezhreversed }, + { 0x01BA, glyph_ezhtail }, + { 0x095E, glyph_fadeva }, + { 0x0A5E, glyph_fagurmukhi }, + { 0x2109, glyph_fahrenheit }, + { 0x064E, glyph_fathaarabic }, + { 0x064E, glyph_fathalowarabic }, + { 0x064B, glyph_fathatanarabic }, + { 0x3108, glyph_fbopomofo }, + { 0x24D5, glyph_fcircle }, + { 0x1E1F, glyph_fdotaccent }, + { 0x0641, glyph_feharabic }, + { 0x0586, glyph_feharmenian }, + { 0xFED2, glyph_fehfinalarabic }, + { 0xFED3, glyph_fehinitialarabic }, + { 0xFED4, glyph_fehmedialarabic }, + { 0x03E5, glyph_feicoptic }, + { 0x246E, glyph_fifteencircle }, + { 0x2482, glyph_fifteenparen }, + { 0x2496, glyph_fifteenperiod }, + { 0x05DA, glyph_finalkaf }, + { 0xFB3A, glyph_finalkafdagesh }, + { 0xFB3A, glyph_finalkafdageshhebrew }, + { 0x05DA, glyph_finalkafhebrew }, + { 0x05DA, glyph_finalkafqamats }, + { 0x05B8, glyph_finalkafqamats }, + { 0x05DA, glyph_finalkafqamatshebrew }, + { 0x05B8, glyph_finalkafqamatshebrew }, + { 0x05DA, glyph_finalkafsheva }, + { 0x05B0, glyph_finalkafsheva }, + { 0x05DA, glyph_finalkafshevahebrew }, + { 0x05B0, glyph_finalkafshevahebrew }, + { 0x05DD, glyph_finalmem }, + { 0x05DD, glyph_finalmemhebrew }, + { 0x05DF, glyph_finalnun }, + { 0x05DF, glyph_finalnunhebrew }, + { 0x05E3, glyph_finalpe }, + { 0x05E3, glyph_finalpehebrew }, + { 0x05E5, glyph_finaltsadi }, + { 0x05E5, glyph_finaltsadihebrew }, + { 0x25C9, glyph_fisheye }, + { 0x0473, glyph_fitacyrillic }, + { 0x0665, glyph_fivearabic }, + { 0x09EB, glyph_fivebengali }, + { 0x2464, glyph_fivecircle }, + { 0x278E, glyph_fivecircleinversesansserif }, + { 0x096B, glyph_fivedeva }, + { 0x0AEB, glyph_fivegujarati }, + { 0x0A6B, glyph_fivegurmukhi }, + { 0x0665, glyph_fivehackarabic }, + { 0x3025, glyph_fivehangzhou }, + { 0x3224, glyph_fiveideographicparen }, + { 0xFF15, glyph_fivemonospace }, + { 0x2478, glyph_fiveparen }, + { 0x248C, glyph_fiveperiod }, + { 0x06F5, glyph_fivepersian }, + { 0x2174, glyph_fiveroman }, + { 0x0E55, glyph_fivethai }, + { 0xFF46, glyph_fmonospace }, + { 0x3399, glyph_fmsquare }, + { 0x0E1F, glyph_fofanthai }, + { 0x0E1D, glyph_fofathai }, + { 0x0E4F, glyph_fongmanthai }, + { 0x2200, glyph_forall }, + { 0x0664, glyph_fourarabic }, + { 0x09EA, glyph_fourbengali }, + { 0x2463, glyph_fourcircle }, + { 0x278D, glyph_fourcircleinversesansserif }, + { 0x096A, glyph_fourdeva }, + { 0x0AEA, glyph_fourgujarati }, + { 0x0A6A, glyph_fourgurmukhi }, + { 0x0664, glyph_fourhackarabic }, + { 0x3024, glyph_fourhangzhou }, + { 0x3223, glyph_fourideographicparen }, + { 0xFF14, glyph_fourmonospace }, + { 0x09F7, glyph_fournumeratorbengali }, + { 0x2477, glyph_fourparen }, + { 0x248B, glyph_fourperiod }, + { 0x06F4, glyph_fourpersian }, + { 0x2173, glyph_fourroman }, + { 0x246D, glyph_fourteencircle }, + { 0x2481, glyph_fourteenparen }, + { 0x2495, glyph_fourteenperiod }, + { 0x0E54, glyph_fourthai }, + { 0x02CB, glyph_fourthtonechinese }, + { 0x24A1, glyph_fparen }, + { 0x0997, glyph_gabengali }, + { 0x01F5, glyph_gacute }, + { 0x0917, glyph_gadeva }, + { 0x06AF, glyph_gafarabic }, + { 0xFB93, glyph_gaffinalarabic }, + { 0xFB94, glyph_gafinitialarabic }, + { 0xFB95, glyph_gafmedialarabic }, + { 0x0A97, glyph_gagujarati }, + { 0x0A17, glyph_gagurmukhi }, + { 0x304C, glyph_gahiragana }, + { 0x30AC, glyph_gakatakana }, + { 0x0263, glyph_gammalatinsmall }, + { 0x02E0, glyph_gammasuperior }, + { 0x03EB, glyph_gangiacoptic }, + { 0x310D, glyph_gbopomofo }, + { 0x0123, glyph_gcedilla }, + { 0x24D6, glyph_gcircle }, + { 0x0121, glyph_gdot }, + { 0x0433, glyph_gecyrillic }, + { 0x3052, glyph_gehiragana }, + { 0x30B2, glyph_gekatakana }, + { 0x2251, glyph_geometricallyequal }, + { 0x059C, glyph_gereshaccenthebrew }, + { 0x05F3, glyph_gereshhebrew }, + { 0x059D, glyph_gereshmuqdamhebrew }, + { 0x059E, glyph_gershayimaccenthebrew }, + { 0x05F4, glyph_gershayimhebrew }, + { 0x3013, glyph_getamark }, + { 0x0998, glyph_ghabengali }, + { 0x0572, glyph_ghadarmenian }, + { 0x0918, glyph_ghadeva }, + { 0x0A98, glyph_ghagujarati }, + { 0x0A18, glyph_ghagurmukhi }, + { 0x063A, glyph_ghainarabic }, + { 0xFECE, glyph_ghainfinalarabic }, + { 0xFECF, glyph_ghaininitialarabic }, + { 0xFED0, glyph_ghainmedialarabic }, + { 0x0495, glyph_ghemiddlehookcyrillic }, + { 0x0493, glyph_ghestrokecyrillic }, + { 0x0491, glyph_gheupturncyrillic }, + { 0x095A, glyph_ghhadeva }, + { 0x0A5A, glyph_ghhagurmukhi }, + { 0x0260, glyph_ghook }, + { 0x3393, glyph_ghzsquare }, + { 0x304E, glyph_gihiragana }, + { 0x30AE, glyph_gikatakana }, + { 0x0563, glyph_gimarmenian }, + { 0x05D2, glyph_gimel }, + { 0xFB32, glyph_gimeldagesh }, + { 0xFB32, glyph_gimeldageshhebrew }, + { 0x05D2, glyph_gimelhebrew }, + { 0x0453, glyph_gjecyrillic }, + { 0x01BE, glyph_glottalinvertedstroke }, + { 0x0294, glyph_glottalstop }, + { 0x0296, glyph_glottalstopinverted }, + { 0x02C0, glyph_glottalstopmod }, + { 0x0295, glyph_glottalstopreversed }, + { 0x02C1, glyph_glottalstopreversedmod }, + { 0x02E4, glyph_glottalstopreversedsuperior }, + { 0x02A1, glyph_glottalstopstroke }, + { 0x02A2, glyph_glottalstopstrokereversed }, + { 0x1E21, glyph_gmacron }, + { 0xFF47, glyph_gmonospace }, + { 0x3054, glyph_gohiragana }, + { 0x30B4, glyph_gokatakana }, + { 0x24A2, glyph_gparen }, + { 0x33AC, glyph_gpasquare }, + { 0x0316, glyph_gravebelowcmb }, + { 0x0300, glyph_gravecmb }, + { 0x0953, glyph_gravedeva }, + { 0x02CE, glyph_gravelowmod }, + { 0xFF40, glyph_gravemonospace }, + { 0x0340, glyph_gravetonecmb }, + { 0x22DB, glyph_greaterequalorless }, + { 0xFF1E, glyph_greatermonospace }, + { 0x2273, glyph_greaterorequivalent }, + { 0x2277, glyph_greaterorless }, + { 0x2267, glyph_greateroverequal }, + { 0xFE65, glyph_greatersmall }, + { 0x0261, glyph_gscript }, + { 0x01E5, glyph_gstroke }, + { 0x3050, glyph_guhiragana }, + { 0x30B0, glyph_gukatakana }, + { 0x3318, glyph_guramusquare }, + { 0x33C9, glyph_gysquare }, + { 0x04A9, glyph_haabkhasiancyrillic }, + { 0x06C1, glyph_haaltonearabic }, + { 0x09B9, glyph_habengali }, + { 0x04B3, glyph_hadescendercyrillic }, + { 0x0939, glyph_hadeva }, + { 0x0AB9, glyph_hagujarati }, + { 0x0A39, glyph_hagurmukhi }, + { 0x062D, glyph_haharabic }, + { 0xFEA2, glyph_hahfinalarabic }, + { 0xFEA3, glyph_hahinitialarabic }, + { 0x306F, glyph_hahiragana }, + { 0xFEA4, glyph_hahmedialarabic }, + { 0x332A, glyph_haitusquare }, + { 0x30CF, glyph_hakatakana }, + { 0xFF8A, glyph_hakatakanahalfwidth }, + { 0x0A4D, glyph_halantgurmukhi }, + { 0x0621, glyph_hamzaarabic }, + { 0x0621, glyph_hamzadammaarabic }, + { 0x064F, glyph_hamzadammaarabic }, + { 0x0621, glyph_hamzadammatanarabic }, + { 0x064C, glyph_hamzadammatanarabic }, + { 0x0621, glyph_hamzafathaarabic }, + { 0x064E, glyph_hamzafathaarabic }, + { 0x0621, glyph_hamzafathatanarabic }, + { 0x064B, glyph_hamzafathatanarabic }, + { 0x0621, glyph_hamzalowarabic }, + { 0x0621, glyph_hamzalowkasraarabic }, + { 0x0650, glyph_hamzalowkasraarabic }, + { 0x0621, glyph_hamzalowkasratanarabic }, + { 0x064D, glyph_hamzalowkasratanarabic }, + { 0x0621, glyph_hamzasukunarabic }, + { 0x0652, glyph_hamzasukunarabic }, + { 0x3164, glyph_hangulfiller }, + { 0x044A, glyph_hardsigncyrillic }, + { 0x21BC, glyph_harpoonleftbarbup }, + { 0x21C0, glyph_harpoonrightbarbup }, + { 0x33CA, glyph_hasquare }, + { 0x05B2, glyph_hatafpatah }, + { 0x05B2, glyph_hatafpatah16 }, + { 0x05B2, glyph_hatafpatah23 }, + { 0x05B2, glyph_hatafpatah2f }, + { 0x05B2, glyph_hatafpatahhebrew }, + { 0x05B2, glyph_hatafpatahnarrowhebrew }, + { 0x05B2, glyph_hatafpatahquarterhebrew }, + { 0x05B2, glyph_hatafpatahwidehebrew }, + { 0x05B3, glyph_hatafqamats }, + { 0x05B3, glyph_hatafqamats1b }, + { 0x05B3, glyph_hatafqamats28 }, + { 0x05B3, glyph_hatafqamats34 }, + { 0x05B3, glyph_hatafqamatshebrew }, + { 0x05B3, glyph_hatafqamatsnarrowhebrew }, + { 0x05B3, glyph_hatafqamatsquarterhebrew }, + { 0x05B3, glyph_hatafqamatswidehebrew }, + { 0x05B1, glyph_hatafsegol }, + { 0x05B1, glyph_hatafsegol17 }, + { 0x05B1, glyph_hatafsegol24 }, + { 0x05B1, glyph_hatafsegol30 }, + { 0x05B1, glyph_hatafsegolhebrew }, + { 0x05B1, glyph_hatafsegolnarrowhebrew }, + { 0x05B1, glyph_hatafsegolquarterhebrew }, + { 0x05B1, glyph_hatafsegolwidehebrew }, + { 0x310F, glyph_hbopomofo }, + { 0x1E2B, glyph_hbrevebelow }, + { 0x1E29, glyph_hcedilla }, + { 0x24D7, glyph_hcircle }, + { 0x1E27, glyph_hdieresis }, + { 0x1E23, glyph_hdotaccent }, + { 0x1E25, glyph_hdotbelow }, + { 0x05D4, glyph_he }, + { 0x2665, glyph_heartsuitblack }, + { 0x2661, glyph_heartsuitwhite }, + { 0xFB34, glyph_hedagesh }, + { 0xFB34, glyph_hedageshhebrew }, + { 0x06C1, glyph_hehaltonearabic }, + { 0x0647, glyph_heharabic }, + { 0x05D4, glyph_hehebrew }, + { 0xFBA7, glyph_hehfinalaltonearabic }, + { 0xFEEA, glyph_hehfinalalttwoarabic }, + { 0xFEEA, glyph_hehfinalarabic }, + { 0xFBA5, glyph_hehhamzaabovefinalarabic }, + { 0xFBA4, glyph_hehhamzaaboveisolatedarabic }, + { 0xFBA8, glyph_hehinitialaltonearabic }, + { 0xFEEB, glyph_hehinitialarabic }, + { 0x3078, glyph_hehiragana }, + { 0xFBA9, glyph_hehmedialaltonearabic }, + { 0xFEEC, glyph_hehmedialarabic }, + { 0x337B, glyph_heiseierasquare }, + { 0x30D8, glyph_hekatakana }, + { 0xFF8D, glyph_hekatakanahalfwidth }, + { 0x3336, glyph_hekutaarusquare }, + { 0x0267, glyph_henghook }, + { 0x3339, glyph_herutusquare }, + { 0x05D7, glyph_het }, + { 0x05D7, glyph_hethebrew }, + { 0x0266, glyph_hhook }, + { 0x02B1, glyph_hhooksuperior }, + { 0x327B, glyph_hieuhacirclekorean }, + { 0x321B, glyph_hieuhaparenkorean }, + { 0x326D, glyph_hieuhcirclekorean }, + { 0x314E, glyph_hieuhkorean }, + { 0x320D, glyph_hieuhparenkorean }, + { 0x3072, glyph_hihiragana }, + { 0x30D2, glyph_hikatakana }, + { 0xFF8B, glyph_hikatakanahalfwidth }, + { 0x05B4, glyph_hiriq }, + { 0x05B4, glyph_hiriq14 }, + { 0x05B4, glyph_hiriq21 }, + { 0x05B4, glyph_hiriq2d }, + { 0x05B4, glyph_hiriqhebrew }, + { 0x05B4, glyph_hiriqnarrowhebrew }, + { 0x05B4, glyph_hiriqquarterhebrew }, + { 0x05B4, glyph_hiriqwidehebrew }, + { 0x1E96, glyph_hlinebelow }, + { 0xFF48, glyph_hmonospace }, + { 0x0570, glyph_hoarmenian }, + { 0x0E2B, glyph_hohipthai }, + { 0x307B, glyph_hohiragana }, + { 0x30DB, glyph_hokatakana }, + { 0xFF8E, glyph_hokatakanahalfwidth }, + { 0x05B9, glyph_holam }, + { 0x05B9, glyph_holam19 }, + { 0x05B9, glyph_holam26 }, + { 0x05B9, glyph_holam32 }, + { 0x05B9, glyph_holamhebrew }, + { 0x05B9, glyph_holamnarrowhebrew }, + { 0x05B9, glyph_holamquarterhebrew }, + { 0x05B9, glyph_holamwidehebrew }, + { 0x0E2E, glyph_honokhukthai }, + { 0x0309, glyph_hookcmb }, + { 0x0321, glyph_hookpalatalizedbelowcmb }, + { 0x0322, glyph_hookretroflexbelowcmb }, + { 0x3342, glyph_hoonsquare }, + { 0x03E9, glyph_horicoptic }, + { 0x2015, glyph_horizontalbar }, + { 0x031B, glyph_horncmb }, + { 0x2668, glyph_hotsprings }, + { 0x24A3, glyph_hparen }, + { 0x02B0, glyph_hsuperior }, + { 0x0265, glyph_hturned }, + { 0x3075, glyph_huhiragana }, + { 0x3333, glyph_huiitosquare }, + { 0x30D5, glyph_hukatakana }, + { 0xFF8C, glyph_hukatakanahalfwidth }, + { 0x030B, glyph_hungarumlautcmb }, + { 0x0195, glyph_hv }, + { 0xFF0D, glyph_hyphenmonospace }, + { 0xFE63, glyph_hyphensmall }, + { 0x2010, glyph_hyphentwo }, + { 0x044F, glyph_iacyrillic }, + { 0x0987, glyph_ibengali }, + { 0x3127, glyph_ibopomofo }, + { 0x01D0, glyph_icaron }, + { 0x24D8, glyph_icircle }, + { 0x0456, glyph_icyrillic }, + { 0x0209, glyph_idblgrave }, + { 0x328F, glyph_ideographearthcircle }, + { 0x328B, glyph_ideographfirecircle }, + { 0x323F, glyph_ideographicallianceparen }, + { 0x323A, glyph_ideographiccallparen }, + { 0x32A5, glyph_ideographiccentrecircle }, + { 0x3006, glyph_ideographicclose }, + { 0x3001, glyph_ideographiccomma }, + { 0xFF64, glyph_ideographiccommaleft }, + { 0x3237, glyph_ideographiccongratulationparen }, + { 0x32A3, glyph_ideographiccorrectcircle }, + { 0x322F, glyph_ideographicearthparen }, + { 0x323D, glyph_ideographicenterpriseparen }, + { 0x329D, glyph_ideographicexcellentcircle }, + { 0x3240, glyph_ideographicfestivalparen }, + { 0x3296, glyph_ideographicfinancialcircle }, + { 0x3236, glyph_ideographicfinancialparen }, + { 0x322B, glyph_ideographicfireparen }, + { 0x3232, glyph_ideographichaveparen }, + { 0x32A4, glyph_ideographichighcircle }, + { 0x3005, glyph_ideographiciterationmark }, + { 0x3298, glyph_ideographiclaborcircle }, + { 0x3238, glyph_ideographiclaborparen }, + { 0x32A7, glyph_ideographicleftcircle }, + { 0x32A6, glyph_ideographiclowcircle }, + { 0x32A9, glyph_ideographicmedicinecircle }, + { 0x322E, glyph_ideographicmetalparen }, + { 0x322A, glyph_ideographicmoonparen }, + { 0x3234, glyph_ideographicnameparen }, + { 0x3002, glyph_ideographicperiod }, + { 0x329E, glyph_ideographicprintcircle }, + { 0x3243, glyph_ideographicreachparen }, + { 0x3239, glyph_ideographicrepresentparen }, + { 0x323E, glyph_ideographicresourceparen }, + { 0x32A8, glyph_ideographicrightcircle }, + { 0x3299, glyph_ideographicsecretcircle }, + { 0x3242, glyph_ideographicselfparen }, + { 0x3233, glyph_ideographicsocietyparen }, + { 0x3000, glyph_ideographicspace }, + { 0x3235, glyph_ideographicspecialparen }, + { 0x3231, glyph_ideographicstockparen }, + { 0x323B, glyph_ideographicstudyparen }, + { 0x3230, glyph_ideographicsunparen }, + { 0x323C, glyph_ideographicsuperviseparen }, + { 0x322C, glyph_ideographicwaterparen }, + { 0x322D, glyph_ideographicwoodparen }, + { 0x3007, glyph_ideographiczero }, + { 0x328E, glyph_ideographmetalcircle }, + { 0x328A, glyph_ideographmooncircle }, + { 0x3294, glyph_ideographnamecircle }, + { 0x3290, glyph_ideographsuncircle }, + { 0x328C, glyph_ideographwatercircle }, + { 0x328D, glyph_ideographwoodcircle }, + { 0x0907, glyph_ideva }, + { 0x1E2F, glyph_idieresisacute }, + { 0x04E5, glyph_idieresiscyrillic }, + { 0x1ECB, glyph_idotbelow }, + { 0x04D7, glyph_iebrevecyrillic }, + { 0x0435, glyph_iecyrillic }, + { 0x3275, glyph_ieungacirclekorean }, + { 0x3215, glyph_ieungaparenkorean }, + { 0x3267, glyph_ieungcirclekorean }, + { 0x3147, glyph_ieungkorean }, + { 0x3207, glyph_ieungparenkorean }, + { 0x0A87, glyph_igujarati }, + { 0x0A07, glyph_igurmukhi }, + { 0x3044, glyph_ihiragana }, + { 0x1EC9, glyph_ihookabove }, + { 0x0988, glyph_iibengali }, + { 0x0438, glyph_iicyrillic }, + { 0x0908, glyph_iideva }, + { 0x0A88, glyph_iigujarati }, + { 0x0A08, glyph_iigurmukhi }, + { 0x0A40, glyph_iimatragurmukhi }, + { 0x020B, glyph_iinvertedbreve }, + { 0x0439, glyph_iishortcyrillic }, + { 0x09C0, glyph_iivowelsignbengali }, + { 0x0940, glyph_iivowelsigndeva }, + { 0x0AC0, glyph_iivowelsigngujarati }, + { 0x30A4, glyph_ikatakana }, + { 0xFF72, glyph_ikatakanahalfwidth }, + { 0x3163, glyph_ikorean }, + { 0x02DC, glyph_ilde }, + { 0x05AC, glyph_iluyhebrew }, + { 0x04E3, glyph_imacroncyrillic }, + { 0x2253, glyph_imageorapproximatelyequal }, + { 0x0A3F, glyph_imatragurmukhi }, + { 0xFF49, glyph_imonospace }, + { 0x2206, glyph_increment }, + { 0x056B, glyph_iniarmenian }, + { 0x2321, glyph_integralbottom }, + { 0x2320, glyph_integraltop }, + { 0x3305, glyph_intisquare }, + { 0x0451, glyph_iocyrillic }, + { 0x0269, glyph_iotalatin }, + { 0x24A4, glyph_iparen }, + { 0x0A72, glyph_irigurmukhi }, + { 0x3043, glyph_ismallhiragana }, + { 0x30A3, glyph_ismallkatakana }, + { 0xFF68, glyph_ismallkatakanahalfwidth }, + { 0x09FA, glyph_issharbengali }, + { 0x0268, glyph_istroke }, + { 0x309D, glyph_iterationhiragana }, + { 0x30FD, glyph_iterationkatakana }, + { 0x1E2D, glyph_itildebelow }, + { 0x3129, glyph_iubopomofo }, + { 0x044E, glyph_iucyrillic }, + { 0x09BF, glyph_ivowelsignbengali }, + { 0x093F, glyph_ivowelsigndeva }, + { 0x0ABF, glyph_ivowelsigngujarati }, + { 0x0475, glyph_izhitsacyrillic }, + { 0x0477, glyph_izhitsadblgravecyrillic }, + { 0x0571, glyph_jaarmenian }, + { 0x099C, glyph_jabengali }, + { 0x091C, glyph_jadeva }, + { 0x0A9C, glyph_jagujarati }, + { 0x0A1C, glyph_jagurmukhi }, + { 0x3110, glyph_jbopomofo }, + { 0x01F0, glyph_jcaron }, + { 0x24D9, glyph_jcircle }, + { 0x029D, glyph_jcrossedtail }, + { 0x025F, glyph_jdotlessstroke }, + { 0x0458, glyph_jecyrillic }, + { 0x062C, glyph_jeemarabic }, + { 0xFE9E, glyph_jeemfinalarabic }, + { 0xFE9F, glyph_jeeminitialarabic }, + { 0xFEA0, glyph_jeemmedialarabic }, + { 0x0698, glyph_jeharabic }, + { 0xFB8B, glyph_jehfinalarabic }, + { 0x099D, glyph_jhabengali }, + { 0x091D, glyph_jhadeva }, + { 0x0A9D, glyph_jhagujarati }, + { 0x0A1D, glyph_jhagurmukhi }, + { 0x057B, glyph_jheharmenian }, + { 0x3004, glyph_jis }, + { 0xFF4A, glyph_jmonospace }, + { 0x24A5, glyph_jparen }, + { 0x02B2, glyph_jsuperior }, + { 0x04A1, glyph_kabashkircyrillic }, + { 0x0995, glyph_kabengali }, + { 0x1E31, glyph_kacute }, + { 0x043A, glyph_kacyrillic }, + { 0x049B, glyph_kadescendercyrillic }, + { 0x0915, glyph_kadeva }, + { 0x05DB, glyph_kaf }, + { 0x0643, glyph_kafarabic }, + { 0xFB3B, glyph_kafdagesh }, + { 0xFB3B, glyph_kafdageshhebrew }, + { 0xFEDA, glyph_kaffinalarabic }, + { 0x05DB, glyph_kafhebrew }, + { 0xFEDB, glyph_kafinitialarabic }, + { 0xFEDC, glyph_kafmedialarabic }, + { 0xFB4D, glyph_kafrafehebrew }, + { 0x0A95, glyph_kagujarati }, + { 0x0A15, glyph_kagurmukhi }, + { 0x304B, glyph_kahiragana }, + { 0x04C4, glyph_kahookcyrillic }, + { 0x30AB, glyph_kakatakana }, + { 0xFF76, glyph_kakatakanahalfwidth }, + { 0x03F0, glyph_kappasymbolgreek }, + { 0x3171, glyph_kapyeounmieumkorean }, + { 0x3184, glyph_kapyeounphieuphkorean }, + { 0x3178, glyph_kapyeounpieupkorean }, + { 0x3179, glyph_kapyeounssangpieupkorean }, + { 0x330D, glyph_karoriisquare }, + { 0x0640, glyph_kashidaautoarabic }, + { 0x0640, glyph_kashidaautonosidebearingarabic }, + { 0x30F5, glyph_kasmallkatakana }, + { 0x3384, glyph_kasquare }, + { 0x0650, glyph_kasraarabic }, + { 0x064D, glyph_kasratanarabic }, + { 0x049F, glyph_kastrokecyrillic }, + { 0xFF70, glyph_katahiraprolongmarkhalfwidth }, + { 0x049D, glyph_kaverticalstrokecyrillic }, + { 0x310E, glyph_kbopomofo }, + { 0x3389, glyph_kcalsquare }, + { 0x01E9, glyph_kcaron }, + { 0x0137, glyph_kcedilla }, + { 0x24DA, glyph_kcircle }, + { 0x1E33, glyph_kdotbelow }, + { 0x0584, glyph_keharmenian }, + { 0x3051, glyph_kehiragana }, + { 0x30B1, glyph_kekatakana }, + { 0xFF79, glyph_kekatakanahalfwidth }, + { 0x056F, glyph_kenarmenian }, + { 0x30F6, glyph_kesmallkatakana }, + { 0x0996, glyph_khabengali }, + { 0x0445, glyph_khacyrillic }, + { 0x0916, glyph_khadeva }, + { 0x0A96, glyph_khagujarati }, + { 0x0A16, glyph_khagurmukhi }, + { 0x062E, glyph_khaharabic }, + { 0xFEA6, glyph_khahfinalarabic }, + { 0xFEA7, glyph_khahinitialarabic }, + { 0xFEA8, glyph_khahmedialarabic }, + { 0x03E7, glyph_kheicoptic }, + { 0x0959, glyph_khhadeva }, + { 0x0A59, glyph_khhagurmukhi }, + { 0x3278, glyph_khieukhacirclekorean }, + { 0x3218, glyph_khieukhaparenkorean }, + { 0x326A, glyph_khieukhcirclekorean }, + { 0x314B, glyph_khieukhkorean }, + { 0x320A, glyph_khieukhparenkorean }, + { 0x0E02, glyph_khokhaithai }, + { 0x0E05, glyph_khokhonthai }, + { 0x0E03, glyph_khokhuatthai }, + { 0x0E04, glyph_khokhwaithai }, + { 0x0E5B, glyph_khomutthai }, + { 0x0199, glyph_khook }, + { 0x0E06, glyph_khorakhangthai }, + { 0x3391, glyph_khzsquare }, + { 0x304D, glyph_kihiragana }, + { 0x30AD, glyph_kikatakana }, + { 0xFF77, glyph_kikatakanahalfwidth }, + { 0x3315, glyph_kiroguramusquare }, + { 0x3316, glyph_kiromeetorusquare }, + { 0x3314, glyph_kirosquare }, + { 0x326E, glyph_kiyeokacirclekorean }, + { 0x320E, glyph_kiyeokaparenkorean }, + { 0x3260, glyph_kiyeokcirclekorean }, + { 0x3131, glyph_kiyeokkorean }, + { 0x3200, glyph_kiyeokparenkorean }, + { 0x3133, glyph_kiyeoksioskorean }, + { 0x045C, glyph_kjecyrillic }, + { 0x1E35, glyph_klinebelow }, + { 0x3398, glyph_klsquare }, + { 0x33A6, glyph_kmcubedsquare }, + { 0xFF4B, glyph_kmonospace }, + { 0x33A2, glyph_kmsquaredsquare }, + { 0x3053, glyph_kohiragana }, + { 0x33C0, glyph_kohmsquare }, + { 0x0E01, glyph_kokaithai }, + { 0x30B3, glyph_kokatakana }, + { 0xFF7A, glyph_kokatakanahalfwidth }, + { 0x331E, glyph_kooposquare }, + { 0x0481, glyph_koppacyrillic }, + { 0x327F, glyph_koreanstandardsymbol }, + { 0x0343, glyph_koroniscmb }, + { 0x24A6, glyph_kparen }, + { 0x33AA, glyph_kpasquare }, + { 0x046F, glyph_ksicyrillic }, + { 0x33CF, glyph_ktsquare }, + { 0x029E, glyph_kturned }, + { 0x304F, glyph_kuhiragana }, + { 0x30AF, glyph_kukatakana }, + { 0xFF78, glyph_kukatakanahalfwidth }, + { 0x33B8, glyph_kvsquare }, + { 0x33BE, glyph_kwsquare }, + { 0x09B2, glyph_labengali }, + { 0x0932, glyph_ladeva }, + { 0x0AB2, glyph_lagujarati }, + { 0x0A32, glyph_lagurmukhi }, + { 0x0E45, glyph_lakkhangyaothai }, + { 0xFEFC, glyph_lamaleffinalarabic }, + { 0xFEF8, glyph_lamalefhamzaabovefinalarabic }, + { 0xFEF7, glyph_lamalefhamzaaboveisolatedarabic }, + { 0xFEFA, glyph_lamalefhamzabelowfinalarabic }, + { 0xFEF9, glyph_lamalefhamzabelowisolatedarabic }, + { 0xFEFB, glyph_lamalefisolatedarabic }, + { 0xFEF6, glyph_lamalefmaddaabovefinalarabic }, + { 0xFEF5, glyph_lamalefmaddaaboveisolatedarabic }, + { 0x0644, glyph_lamarabic }, + { 0x019B, glyph_lambdastroke }, + { 0x05DC, glyph_lamed }, + { 0xFB3C, glyph_lameddagesh }, + { 0xFB3C, glyph_lameddageshhebrew }, + { 0x05DC, glyph_lamedhebrew }, + { 0x05DC, glyph_lamedholam }, + { 0x05B9, glyph_lamedholam }, + { 0x05DC, glyph_lamedholamdagesh }, + { 0x05B9, glyph_lamedholamdagesh }, + { 0x05BC, glyph_lamedholamdagesh }, + { 0x05DC, glyph_lamedholamdageshhebrew }, + { 0x05B9, glyph_lamedholamdageshhebrew }, + { 0x05BC, glyph_lamedholamdageshhebrew }, + { 0x05DC, glyph_lamedholamhebrew }, + { 0x05B9, glyph_lamedholamhebrew }, + { 0xFEDE, glyph_lamfinalarabic }, + { 0xFCCA, glyph_lamhahinitialarabic }, + { 0xFEDF, glyph_laminitialarabic }, + { 0xFCC9, glyph_lamjeeminitialarabic }, + { 0xFCCB, glyph_lamkhahinitialarabic }, + { 0xFDF2, glyph_lamlamhehisolatedarabic }, + { 0xFEE0, glyph_lammedialarabic }, + { 0xFD88, glyph_lammeemhahinitialarabic }, + { 0xFCCC, glyph_lammeeminitialarabic }, + { 0xFEDF, glyph_lammeemjeeminitialarabic }, + { 0xFEE4, glyph_lammeemjeeminitialarabic }, + { 0xFEA0, glyph_lammeemjeeminitialarabic }, + { 0xFEDF, glyph_lammeemkhahinitialarabic }, + { 0xFEE4, glyph_lammeemkhahinitialarabic }, + { 0xFEA8, glyph_lammeemkhahinitialarabic }, + { 0x25EF, glyph_largecircle }, + { 0x019A, glyph_lbar }, + { 0x026C, glyph_lbelt }, + { 0x310C, glyph_lbopomofo }, + { 0x013C, glyph_lcedilla }, + { 0x24DB, glyph_lcircle }, + { 0x1E3D, glyph_lcircumflexbelow }, + { 0x0140, glyph_ldotaccent }, + { 0x1E37, glyph_ldotbelow }, + { 0x1E39, glyph_ldotbelowmacron }, + { 0x031A, glyph_leftangleabovecmb }, + { 0x0318, glyph_lefttackbelowcmb }, + { 0x22DA, glyph_lessequalorgreater }, + { 0xFF1C, glyph_lessmonospace }, + { 0x2272, glyph_lessorequivalent }, + { 0x2276, glyph_lessorgreater }, + { 0x2266, glyph_lessoverequal }, + { 0xFE64, glyph_lesssmall }, + { 0x026E, glyph_lezh }, + { 0x026D, glyph_lhookretroflex }, + { 0x056C, glyph_liwnarmenian }, + { 0x01C9, glyph_lj }, + { 0x0459, glyph_ljecyrillic }, + { 0x0933, glyph_lladeva }, + { 0x0AB3, glyph_llagujarati }, + { 0x1E3B, glyph_llinebelow }, + { 0x0934, glyph_llladeva }, + { 0x09E1, glyph_llvocalicbengali }, + { 0x0961, glyph_llvocalicdeva }, + { 0x09E3, glyph_llvocalicvowelsignbengali }, + { 0x0963, glyph_llvocalicvowelsigndeva }, + { 0x026B, glyph_lmiddletilde }, + { 0xFF4C, glyph_lmonospace }, + { 0x33D0, glyph_lmsquare }, + { 0x0E2C, glyph_lochulathai }, + { 0x2310, glyph_logicalnotreversed }, + { 0x0E25, glyph_lolingthai }, + { 0xFE4E, glyph_lowlinecenterline }, + { 0x0332, glyph_lowlinecmb }, + { 0xFE4D, glyph_lowlinedashed }, + { 0x24A7, glyph_lparen }, + { 0x2113, glyph_lsquare }, + { 0x0E26, glyph_luthai }, + { 0x098C, glyph_lvocalicbengali }, + { 0x090C, glyph_lvocalicdeva }, + { 0x09E2, glyph_lvocalicvowelsignbengali }, + { 0x0962, glyph_lvocalicvowelsigndeva }, + { 0x33D3, glyph_lxsquare }, + { 0x09AE, glyph_mabengali }, + { 0x0331, glyph_macronbelowcmb }, + { 0x0304, glyph_macroncmb }, + { 0x02CD, glyph_macronlowmod }, + { 0xFFE3, glyph_macronmonospace }, + { 0x1E3F, glyph_macute }, + { 0x092E, glyph_madeva }, + { 0x0AAE, glyph_magujarati }, + { 0x0A2E, glyph_magurmukhi }, + { 0x05A4, glyph_mahapakhhebrew }, + { 0x05A4, glyph_mahapakhlefthebrew }, + { 0x307E, glyph_mahiragana }, + { 0xF895, glyph_maichattawalowleftthai }, + { 0xF894, glyph_maichattawalowrightthai }, + { 0x0E4B, glyph_maichattawathai }, + { 0xF893, glyph_maichattawaupperleftthai }, + { 0xF88C, glyph_maieklowleftthai }, + { 0xF88B, glyph_maieklowrightthai }, + { 0x0E48, glyph_maiekthai }, + { 0xF88A, glyph_maiekupperleftthai }, + { 0xF884, glyph_maihanakatleftthai }, + { 0x0E31, glyph_maihanakatthai }, + { 0xF889, glyph_maitaikhuleftthai }, + { 0x0E47, glyph_maitaikhuthai }, + { 0xF88F, glyph_maitholowleftthai }, + { 0xF88E, glyph_maitholowrightthai }, + { 0x0E49, glyph_maithothai }, + { 0xF88D, glyph_maithoupperleftthai }, + { 0xF892, glyph_maitrilowleftthai }, + { 0xF891, glyph_maitrilowrightthai }, + { 0x0E4A, glyph_maitrithai }, + { 0xF890, glyph_maitriupperleftthai }, + { 0x0E46, glyph_maiyamokthai }, + { 0x30DE, glyph_makatakana }, + { 0xFF8F, glyph_makatakanahalfwidth }, + { 0x3347, glyph_mansyonsquare }, + { 0x05BE, glyph_maqafhebrew }, + { 0x2642, glyph_mars }, + { 0x05AF, glyph_masoracirclehebrew }, + { 0x3383, glyph_masquare }, + { 0x3107, glyph_mbopomofo }, + { 0x33D4, glyph_mbsquare }, + { 0x24DC, glyph_mcircle }, + { 0x33A5, glyph_mcubedsquare }, + { 0x1E41, glyph_mdotaccent }, + { 0x1E43, glyph_mdotbelow }, + { 0x0645, glyph_meemarabic }, + { 0xFEE2, glyph_meemfinalarabic }, + { 0xFEE3, glyph_meeminitialarabic }, + { 0xFEE4, glyph_meemmedialarabic }, + { 0xFCD1, glyph_meemmeeminitialarabic }, + { 0xFC48, glyph_meemmeemisolatedarabic }, + { 0x334D, glyph_meetorusquare }, + { 0x3081, glyph_mehiragana }, + { 0x337E, glyph_meizierasquare }, + { 0x30E1, glyph_mekatakana }, + { 0xFF92, glyph_mekatakanahalfwidth }, + { 0x05DE, glyph_mem }, + { 0xFB3E, glyph_memdagesh }, + { 0xFB3E, glyph_memdageshhebrew }, + { 0x05DE, glyph_memhebrew }, + { 0x0574, glyph_menarmenian }, + { 0x05A5, glyph_merkhahebrew }, + { 0x05A6, glyph_merkhakefulahebrew }, + { 0x05A6, glyph_merkhakefulalefthebrew }, + { 0x05A5, glyph_merkhalefthebrew }, + { 0x0271, glyph_mhook }, + { 0x3392, glyph_mhzsquare }, + { 0xFF65, glyph_middledotkatakanahalfwidth }, + { 0x00B7, glyph_middot }, + { 0x3272, glyph_mieumacirclekorean }, + { 0x3212, glyph_mieumaparenkorean }, + { 0x3264, glyph_mieumcirclekorean }, + { 0x3141, glyph_mieumkorean }, + { 0x3170, glyph_mieumpansioskorean }, + { 0x3204, glyph_mieumparenkorean }, + { 0x316E, glyph_mieumpieupkorean }, + { 0x316F, glyph_mieumsioskorean }, + { 0x307F, glyph_mihiragana }, + { 0x30DF, glyph_mikatakana }, + { 0xFF90, glyph_mikatakanahalfwidth }, + { 0x0320, glyph_minusbelowcmb }, + { 0x2296, glyph_minuscircle }, + { 0x02D7, glyph_minusmod }, + { 0x2213, glyph_minusplus }, + { 0x334A, glyph_miribaarusquare }, + { 0x3349, glyph_mirisquare }, + { 0x0270, glyph_mlonglegturned }, + { 0x3396, glyph_mlsquare }, + { 0x33A3, glyph_mmcubedsquare }, + { 0xFF4D, glyph_mmonospace }, + { 0x339F, glyph_mmsquaredsquare }, + { 0x3082, glyph_mohiragana }, + { 0x33C1, glyph_mohmsquare }, + { 0x30E2, glyph_mokatakana }, + { 0xFF93, glyph_mokatakanahalfwidth }, + { 0x33D6, glyph_molsquare }, + { 0x0E21, glyph_momathai }, + { 0x33A7, glyph_moverssquare }, + { 0x33A8, glyph_moverssquaredsquare }, + { 0x24A8, glyph_mparen }, + { 0x33AB, glyph_mpasquare }, + { 0x33B3, glyph_mssquare }, + { 0x026F, glyph_mturned }, + { 0x00B5, glyph_mu1 }, + { 0x3382, glyph_muasquare }, + { 0x226B, glyph_muchgreater }, + { 0x226A, glyph_muchless }, + { 0x338C, glyph_mufsquare }, + { 0x338D, glyph_mugsquare }, + { 0x3080, glyph_muhiragana }, + { 0x30E0, glyph_mukatakana }, + { 0xFF91, glyph_mukatakanahalfwidth }, + { 0x3395, glyph_mulsquare }, + { 0x339B, glyph_mumsquare }, + { 0x05A3, glyph_munahhebrew }, + { 0x05A3, glyph_munahlefthebrew }, + { 0x266D, glyph_musicflatsign }, + { 0x266F, glyph_musicsharpsign }, + { 0x33B2, glyph_mussquare }, + { 0x33B6, glyph_muvsquare }, + { 0x33BC, glyph_muwsquare }, + { 0x33B9, glyph_mvmegasquare }, + { 0x33B7, glyph_mvsquare }, + { 0x33BF, glyph_mwmegasquare }, + { 0x33BD, glyph_mwsquare }, + { 0x09A8, glyph_nabengali }, + { 0x2207, glyph_nabla }, + { 0x0928, glyph_nadeva }, + { 0x0AA8, glyph_nagujarati }, + { 0x0A28, glyph_nagurmukhi }, + { 0x306A, glyph_nahiragana }, + { 0x30CA, glyph_nakatakana }, + { 0xFF85, glyph_nakatakanahalfwidth }, + { 0x3381, glyph_nasquare }, + { 0x310B, glyph_nbopomofo }, + { 0x0146, glyph_ncedilla }, + { 0x24DD, glyph_ncircle }, + { 0x1E4B, glyph_ncircumflexbelow }, + { 0x1E45, glyph_ndotaccent }, + { 0x1E47, glyph_ndotbelow }, + { 0x306D, glyph_nehiragana }, + { 0x30CD, glyph_nekatakana }, + { 0xFF88, glyph_nekatakanahalfwidth }, + { 0x20AA, glyph_newsheqelsign }, + { 0x338B, glyph_nfsquare }, + { 0x0999, glyph_ngabengali }, + { 0x0919, glyph_ngadeva }, + { 0x0A99, glyph_ngagujarati }, + { 0x0A19, glyph_ngagurmukhi }, + { 0x0E07, glyph_ngonguthai }, + { 0x3093, glyph_nhiragana }, + { 0x0272, glyph_nhookleft }, + { 0x0273, glyph_nhookretroflex }, + { 0x326F, glyph_nieunacirclekorean }, + { 0x320F, glyph_nieunaparenkorean }, + { 0x3135, glyph_nieuncieuckorean }, + { 0x3261, glyph_nieuncirclekorean }, + { 0x3136, glyph_nieunhieuhkorean }, + { 0x3134, glyph_nieunkorean }, + { 0x3168, glyph_nieunpansioskorean }, + { 0x3201, glyph_nieunparenkorean }, + { 0x3167, glyph_nieunsioskorean }, + { 0x3166, glyph_nieuntikeutkorean }, + { 0x306B, glyph_nihiragana }, + { 0x30CB, glyph_nikatakana }, + { 0xFF86, glyph_nikatakanahalfwidth }, + { 0xF899, glyph_nikhahitleftthai }, + { 0x0E4D, glyph_nikhahitthai }, + { 0x0669, glyph_ninearabic }, + { 0x09EF, glyph_ninebengali }, + { 0x2468, glyph_ninecircle }, + { 0x2792, glyph_ninecircleinversesansserif }, + { 0x096F, glyph_ninedeva }, + { 0x0AEF, glyph_ninegujarati }, + { 0x0A6F, glyph_ninegurmukhi }, + { 0x0669, glyph_ninehackarabic }, + { 0x3029, glyph_ninehangzhou }, + { 0x3228, glyph_nineideographicparen }, + { 0xFF19, glyph_ninemonospace }, + { 0x247C, glyph_nineparen }, + { 0x2490, glyph_nineperiod }, + { 0x06F9, glyph_ninepersian }, + { 0x2178, glyph_nineroman }, + { 0x2472, glyph_nineteencircle }, + { 0x2486, glyph_nineteenparen }, + { 0x249A, glyph_nineteenperiod }, + { 0x0E59, glyph_ninethai }, + { 0x01CC, glyph_nj }, + { 0x045A, glyph_njecyrillic }, + { 0x30F3, glyph_nkatakana }, + { 0xFF9D, glyph_nkatakanahalfwidth }, + { 0x019E, glyph_nlegrightlong }, + { 0x1E49, glyph_nlinebelow }, + { 0xFF4E, glyph_nmonospace }, + { 0x339A, glyph_nmsquare }, + { 0x09A3, glyph_nnabengali }, + { 0x0923, glyph_nnadeva }, + { 0x0AA3, glyph_nnagujarati }, + { 0x0A23, glyph_nnagurmukhi }, + { 0x0929, glyph_nnnadeva }, + { 0x306E, glyph_nohiragana }, + { 0x30CE, glyph_nokatakana }, + { 0xFF89, glyph_nokatakanahalfwidth }, + { 0x00A0, glyph_nonbreakingspace }, + { 0x0E13, glyph_nonenthai }, + { 0x0E19, glyph_nonuthai }, + { 0x0646, glyph_noonarabic }, + { 0xFEE6, glyph_noonfinalarabic }, + { 0x06BA, glyph_noonghunnaarabic }, + { 0xFB9F, glyph_noonghunnafinalarabic }, + { 0xFEE7, glyph_noonhehinitialarabic }, + { 0xFEEC, glyph_noonhehinitialarabic }, + { 0xFEE7, glyph_nooninitialarabic }, + { 0xFCD2, glyph_noonjeeminitialarabic }, + { 0xFC4B, glyph_noonjeemisolatedarabic }, + { 0xFEE8, glyph_noonmedialarabic }, + { 0xFCD5, glyph_noonmeeminitialarabic }, + { 0xFC4E, glyph_noonmeemisolatedarabic }, + { 0xFC8D, glyph_noonnoonfinalarabic }, + { 0x220C, glyph_notcontains }, + { 0x2209, glyph_notelementof }, + { 0x226F, glyph_notgreater }, + { 0x2271, glyph_notgreaternorequal }, + { 0x2279, glyph_notgreaternorless }, + { 0x2262, glyph_notidentical }, + { 0x226E, glyph_notless }, + { 0x2270, glyph_notlessnorequal }, + { 0x2226, glyph_notparallel }, + { 0x2280, glyph_notprecedes }, + { 0x2281, glyph_notsucceeds }, + { 0x2285, glyph_notsuperset }, + { 0x0576, glyph_nowarmenian }, + { 0x24A9, glyph_nparen }, + { 0x33B1, glyph_nssquare }, + { 0x306C, glyph_nuhiragana }, + { 0x30CC, glyph_nukatakana }, + { 0xFF87, glyph_nukatakanahalfwidth }, + { 0x09BC, glyph_nuktabengali }, + { 0x093C, glyph_nuktadeva }, + { 0x0ABC, glyph_nuktagujarati }, + { 0x0A3C, glyph_nuktagurmukhi }, + { 0xFF03, glyph_numbersignmonospace }, + { 0xFE5F, glyph_numbersignsmall }, + { 0x0374, glyph_numeralsigngreek }, + { 0x0375, glyph_numeralsignlowergreek }, + { 0x2116, glyph_numero }, + { 0x05E0, glyph_nun }, + { 0xFB40, glyph_nundagesh }, + { 0xFB40, glyph_nundageshhebrew }, + { 0x05E0, glyph_nunhebrew }, + { 0x33B5, glyph_nvsquare }, + { 0x33BB, glyph_nwsquare }, + { 0x099E, glyph_nyabengali }, + { 0x091E, glyph_nyadeva }, + { 0x0A9E, glyph_nyagujarati }, + { 0x0A1E, glyph_nyagurmukhi }, + { 0x0E2D, glyph_oangthai }, + { 0x0275, glyph_obarred }, + { 0x04E9, glyph_obarredcyrillic }, + { 0x04EB, glyph_obarreddieresiscyrillic }, + { 0x0993, glyph_obengali }, + { 0x311B, glyph_obopomofo }, + { 0x0911, glyph_ocandradeva }, + { 0x0A91, glyph_ocandragujarati }, + { 0x0949, glyph_ocandravowelsigndeva }, + { 0x0AC9, glyph_ocandravowelsigngujarati }, + { 0x01D2, glyph_ocaron }, + { 0x24DE, glyph_ocircle }, + { 0x1ED1, glyph_ocircumflexacute }, + { 0x1ED9, glyph_ocircumflexdotbelow }, + { 0x1ED3, glyph_ocircumflexgrave }, + { 0x1ED5, glyph_ocircumflexhookabove }, + { 0x1ED7, glyph_ocircumflextilde }, + { 0x043E, glyph_ocyrillic }, + { 0x0151, glyph_odblacute }, + { 0x020D, glyph_odblgrave }, + { 0x0913, glyph_odeva }, + { 0x04E7, glyph_odieresiscyrillic }, + { 0x1ECD, glyph_odotbelow }, + { 0x315A, glyph_oekorean }, + { 0x0328, glyph_ogonekcmb }, + { 0x0A93, glyph_ogujarati }, + { 0x0585, glyph_oharmenian }, + { 0x304A, glyph_ohiragana }, + { 0x1ECF, glyph_ohookabove }, + { 0x1EDB, glyph_ohornacute }, + { 0x1EE3, glyph_ohorndotbelow }, + { 0x1EDD, glyph_ohorngrave }, + { 0x1EDF, glyph_ohornhookabove }, + { 0x1EE1, glyph_ohorntilde }, + { 0x01A3, glyph_oi }, + { 0x020F, glyph_oinvertedbreve }, + { 0x30AA, glyph_okatakana }, + { 0xFF75, glyph_okatakanahalfwidth }, + { 0x3157, glyph_okorean }, + { 0x05AB, glyph_olehebrew }, + { 0x1E53, glyph_omacronacute }, + { 0x1E51, glyph_omacrongrave }, + { 0x0950, glyph_omdeva }, + { 0x0461, glyph_omegacyrillic }, + { 0x0277, glyph_omegalatinclosed }, + { 0x047B, glyph_omegaroundcyrillic }, + { 0x047D, glyph_omegatitlocyrillic }, + { 0x0AD0, glyph_omgujarati }, + { 0xFF4F, glyph_omonospace }, + { 0x0661, glyph_onearabic }, + { 0x09E7, glyph_onebengali }, + { 0x2460, glyph_onecircle }, + { 0x278A, glyph_onecircleinversesansserif }, + { 0x0967, glyph_onedeva }, + { 0x0AE7, glyph_onegujarati }, + { 0x0A67, glyph_onegurmukhi }, + { 0x0661, glyph_onehackarabic }, + { 0x3021, glyph_onehangzhou }, + { 0x3220, glyph_oneideographicparen }, + { 0xFF11, glyph_onemonospace }, + { 0x09F4, glyph_onenumeratorbengali }, + { 0x2474, glyph_oneparen }, + { 0x2488, glyph_oneperiod }, + { 0x06F1, glyph_onepersian }, + { 0x2170, glyph_oneroman }, + { 0x0E51, glyph_onethai }, + { 0x01EB, glyph_oogonek }, + { 0x01ED, glyph_oogonekmacron }, + { 0x0A13, glyph_oogurmukhi }, + { 0x0A4B, glyph_oomatragurmukhi }, + { 0x0254, glyph_oopen }, + { 0x24AA, glyph_oparen }, + { 0x2325, glyph_option }, + { 0x0912, glyph_oshortdeva }, + { 0x094A, glyph_oshortvowelsigndeva }, + { 0x3049, glyph_osmallhiragana }, + { 0x30A9, glyph_osmallkatakana }, + { 0xFF6B, glyph_osmallkatakanahalfwidth }, + { 0x01FF, glyph_ostrokeacute }, + { 0x047F, glyph_otcyrillic }, + { 0x1E4D, glyph_otildeacute }, + { 0x1E4F, glyph_otildedieresis }, + { 0x3121, glyph_oubopomofo }, + { 0x203E, glyph_overline }, + { 0xFE4A, glyph_overlinecenterline }, + { 0x0305, glyph_overlinecmb }, + { 0xFE49, glyph_overlinedashed }, + { 0xFE4C, glyph_overlinedblwavy }, + { 0xFE4B, glyph_overlinewavy }, + { 0x00AF, glyph_overscore }, + { 0x09CB, glyph_ovowelsignbengali }, + { 0x094B, glyph_ovowelsigndeva }, + { 0x0ACB, glyph_ovowelsigngujarati }, + { 0x3380, glyph_paampssquare }, + { 0x332B, glyph_paasentosquare }, + { 0x09AA, glyph_pabengali }, + { 0x1E55, glyph_pacute }, + { 0x092A, glyph_padeva }, + { 0x21DF, glyph_pagedown }, + { 0x21DE, glyph_pageup }, + { 0x0AAA, glyph_pagujarati }, + { 0x0A2A, glyph_pagurmukhi }, + { 0x3071, glyph_pahiragana }, + { 0x0E2F, glyph_paiyannoithai }, + { 0x30D1, glyph_pakatakana }, + { 0x0484, glyph_palatalizationcyrilliccmb }, + { 0x04C0, glyph_palochkacyrillic }, + { 0x317F, glyph_pansioskorean }, + { 0x2225, glyph_parallel }, + { 0xFD3E, glyph_parenleftaltonearabic }, + { 0xFF08, glyph_parenleftmonospace }, + { 0xFE59, glyph_parenleftsmall }, + { 0xFE35, glyph_parenleftvertical }, + { 0xFD3F, glyph_parenrightaltonearabic }, + { 0xFF09, glyph_parenrightmonospace }, + { 0xFE5A, glyph_parenrightsmall }, + { 0xFE36, glyph_parenrightvertical }, + { 0x05C0, glyph_paseqhebrew }, + { 0x0599, glyph_pashtahebrew }, + { 0x33A9, glyph_pasquare }, + { 0x05B7, glyph_patah }, + { 0x05B7, glyph_patah11 }, + { 0x05B7, glyph_patah1d }, + { 0x05B7, glyph_patah2a }, + { 0x05B7, glyph_patahhebrew }, + { 0x05B7, glyph_patahnarrowhebrew }, + { 0x05B7, glyph_patahquarterhebrew }, + { 0x05B7, glyph_patahwidehebrew }, + { 0x05A1, glyph_pazerhebrew }, + { 0x3106, glyph_pbopomofo }, + { 0x24DF, glyph_pcircle }, + { 0x1E57, glyph_pdotaccent }, + { 0x05E4, glyph_pe }, + { 0x043F, glyph_pecyrillic }, + { 0xFB44, glyph_pedagesh }, + { 0xFB44, glyph_pedageshhebrew }, + { 0x333B, glyph_peezisquare }, + { 0xFB43, glyph_pefinaldageshhebrew }, + { 0x067E, glyph_peharabic }, + { 0x057A, glyph_peharmenian }, + { 0x05E4, glyph_pehebrew }, + { 0xFB57, glyph_pehfinalarabic }, + { 0xFB58, glyph_pehinitialarabic }, + { 0x307A, glyph_pehiragana }, + { 0xFB59, glyph_pehmedialarabic }, + { 0x30DA, glyph_pekatakana }, + { 0x04A7, glyph_pemiddlehookcyrillic }, + { 0xFB4E, glyph_perafehebrew }, + { 0x066A, glyph_percentarabic }, + { 0xFF05, glyph_percentmonospace }, + { 0xFE6A, glyph_percentsmall }, + { 0x0589, glyph_periodarmenian }, + { 0xFF61, glyph_periodhalfwidth }, + { 0xFF0E, glyph_periodmonospace }, + { 0xFE52, glyph_periodsmall }, + { 0x0342, glyph_perispomenigreekcmb }, + { 0x338A, glyph_pfsquare }, + { 0x09AB, glyph_phabengali }, + { 0x092B, glyph_phadeva }, + { 0x0AAB, glyph_phagujarati }, + { 0x0A2B, glyph_phagurmukhi }, + { 0x327A, glyph_phieuphacirclekorean }, + { 0x321A, glyph_phieuphaparenkorean }, + { 0x326C, glyph_phieuphcirclekorean }, + { 0x314D, glyph_phieuphkorean }, + { 0x320C, glyph_phieuphparenkorean }, + { 0x0278, glyph_philatin }, + { 0x0E3A, glyph_phinthuthai }, + { 0x03D5, glyph_phisymbolgreek }, + { 0x01A5, glyph_phook }, + { 0x0E1E, glyph_phophanthai }, + { 0x0E1C, glyph_phophungthai }, + { 0x0E20, glyph_phosamphaothai }, + { 0x3273, glyph_pieupacirclekorean }, + { 0x3213, glyph_pieupaparenkorean }, + { 0x3176, glyph_pieupcieuckorean }, + { 0x3265, glyph_pieupcirclekorean }, + { 0x3172, glyph_pieupkiyeokkorean }, + { 0x3142, glyph_pieupkorean }, + { 0x3205, glyph_pieupparenkorean }, + { 0x3174, glyph_pieupsioskiyeokkorean }, + { 0x3144, glyph_pieupsioskorean }, + { 0x3175, glyph_pieupsiostikeutkorean }, + { 0x3177, glyph_pieupthieuthkorean }, + { 0x3173, glyph_pieuptikeutkorean }, + { 0x3074, glyph_pihiragana }, + { 0x30D4, glyph_pikatakana }, + { 0x03D6, glyph_pisymbolgreek }, + { 0x0583, glyph_piwrarmenian }, + { 0x031F, glyph_plusbelowcmb }, + { 0x2295, glyph_pluscircle }, + { 0x02D6, glyph_plusmod }, + { 0xFF0B, glyph_plusmonospace }, + { 0xFE62, glyph_plussmall }, + { 0x207A, glyph_plussuperior }, + { 0xFF50, glyph_pmonospace }, + { 0x33D8, glyph_pmsquare }, + { 0x307D, glyph_pohiragana }, + { 0x261F, glyph_pointingindexdownwhite }, + { 0x261C, glyph_pointingindexleftwhite }, + { 0x261E, glyph_pointingindexrightwhite }, + { 0x261D, glyph_pointingindexupwhite }, + { 0x30DD, glyph_pokatakana }, + { 0x0E1B, glyph_poplathai }, + { 0x3012, glyph_postalmark }, + { 0x3020, glyph_postalmarkface }, + { 0x24AB, glyph_pparen }, + { 0x227A, glyph_precedes }, + { 0x02B9, glyph_primemod }, + { 0x2035, glyph_primereversed }, + { 0x2305, glyph_projective }, + { 0x30FC, glyph_prolongedkana }, + { 0x2318, glyph_propellor }, + { 0x2237, glyph_proportion }, + { 0x0471, glyph_psicyrillic }, + { 0x0486, glyph_psilipneumatacyrilliccmb }, + { 0x33B0, glyph_pssquare }, + { 0x3077, glyph_puhiragana }, + { 0x30D7, glyph_pukatakana }, + { 0x33B4, glyph_pvsquare }, + { 0x33BA, glyph_pwsquare }, + { 0x0958, glyph_qadeva }, + { 0x05A8, glyph_qadmahebrew }, + { 0x0642, glyph_qafarabic }, + { 0xFED6, glyph_qaffinalarabic }, + { 0xFED7, glyph_qafinitialarabic }, + { 0xFED8, glyph_qafmedialarabic }, + { 0x05B8, glyph_qamats }, + { 0x05B8, glyph_qamats10 }, + { 0x05B8, glyph_qamats1a }, + { 0x05B8, glyph_qamats1c }, + { 0x05B8, glyph_qamats27 }, + { 0x05B8, glyph_qamats29 }, + { 0x05B8, glyph_qamats33 }, + { 0x05B8, glyph_qamatsde }, + { 0x05B8, glyph_qamatshebrew }, + { 0x05B8, glyph_qamatsnarrowhebrew }, + { 0x05B8, glyph_qamatsqatanhebrew }, + { 0x05B8, glyph_qamatsqatannarrowhebrew }, + { 0x05B8, glyph_qamatsqatanquarterhebrew }, + { 0x05B8, glyph_qamatsqatanwidehebrew }, + { 0x05B8, glyph_qamatsquarterhebrew }, + { 0x05B8, glyph_qamatswidehebrew }, + { 0x059F, glyph_qarneyparahebrew }, + { 0x3111, glyph_qbopomofo }, + { 0x24E0, glyph_qcircle }, + { 0x02A0, glyph_qhook }, + { 0xFF51, glyph_qmonospace }, + { 0x05E7, glyph_qof }, + { 0xFB47, glyph_qofdagesh }, + { 0xFB47, glyph_qofdageshhebrew }, + { 0x05E7, glyph_qofhatafpatah }, + { 0x05B2, glyph_qofhatafpatah }, + { 0x05E7, glyph_qofhatafpatahhebrew }, + { 0x05B2, glyph_qofhatafpatahhebrew }, + { 0x05E7, glyph_qofhatafsegol }, + { 0x05B1, glyph_qofhatafsegol }, + { 0x05E7, glyph_qofhatafsegolhebrew }, + { 0x05B1, glyph_qofhatafsegolhebrew }, + { 0x05E7, glyph_qofhebrew }, + { 0x05E7, glyph_qofhiriq }, + { 0x05B4, glyph_qofhiriq }, + { 0x05E7, glyph_qofhiriqhebrew }, + { 0x05B4, glyph_qofhiriqhebrew }, + { 0x05E7, glyph_qofholam }, + { 0x05B9, glyph_qofholam }, + { 0x05E7, glyph_qofholamhebrew }, + { 0x05B9, glyph_qofholamhebrew }, + { 0x05E7, glyph_qofpatah }, + { 0x05B7, glyph_qofpatah }, + { 0x05E7, glyph_qofpatahhebrew }, + { 0x05B7, glyph_qofpatahhebrew }, + { 0x05E7, glyph_qofqamats }, + { 0x05B8, glyph_qofqamats }, + { 0x05E7, glyph_qofqamatshebrew }, + { 0x05B8, glyph_qofqamatshebrew }, + { 0x05E7, glyph_qofqubuts }, + { 0x05BB, glyph_qofqubuts }, + { 0x05E7, glyph_qofqubutshebrew }, + { 0x05BB, glyph_qofqubutshebrew }, + { 0x05E7, glyph_qofsegol }, + { 0x05B6, glyph_qofsegol }, + { 0x05E7, glyph_qofsegolhebrew }, + { 0x05B6, glyph_qofsegolhebrew }, + { 0x05E7, glyph_qofsheva }, + { 0x05B0, glyph_qofsheva }, + { 0x05E7, glyph_qofshevahebrew }, + { 0x05B0, glyph_qofshevahebrew }, + { 0x05E7, glyph_qoftsere }, + { 0x05B5, glyph_qoftsere }, + { 0x05E7, glyph_qoftserehebrew }, + { 0x05B5, glyph_qoftserehebrew }, + { 0x24AC, glyph_qparen }, + { 0x2669, glyph_quarternote }, + { 0x05BB, glyph_qubuts }, + { 0x05BB, glyph_qubuts18 }, + { 0x05BB, glyph_qubuts25 }, + { 0x05BB, glyph_qubuts31 }, + { 0x05BB, glyph_qubutshebrew }, + { 0x05BB, glyph_qubutsnarrowhebrew }, + { 0x05BB, glyph_qubutsquarterhebrew }, + { 0x05BB, glyph_qubutswidehebrew }, + { 0x061F, glyph_questionarabic }, + { 0x055E, glyph_questionarmenian }, + { 0x037E, glyph_questiongreek }, + { 0xFF1F, glyph_questionmonospace }, + { 0xFF02, glyph_quotedblmonospace }, + { 0x301E, glyph_quotedblprime }, + { 0x301D, glyph_quotedblprimereversed }, + { 0x201B, glyph_quoteleftreversed }, + { 0x0149, glyph_quoterightn }, + { 0xFF07, glyph_quotesinglemonospace }, + { 0x057C, glyph_raarmenian }, + { 0x09B0, glyph_rabengali }, + { 0x0930, glyph_radeva }, + { 0x33AE, glyph_radoverssquare }, + { 0x33AF, glyph_radoverssquaredsquare }, + { 0x33AD, glyph_radsquare }, + { 0x05BF, glyph_rafe }, + { 0x05BF, glyph_rafehebrew }, + { 0x0AB0, glyph_ragujarati }, + { 0x0A30, glyph_ragurmukhi }, + { 0x3089, glyph_rahiragana }, + { 0x30E9, glyph_rakatakana }, + { 0xFF97, glyph_rakatakanahalfwidth }, + { 0x09F1, glyph_ralowerdiagonalbengali }, + { 0x09F0, glyph_ramiddlediagonalbengali }, + { 0x0264, glyph_ramshorn }, + { 0x2236, glyph_ratio }, + { 0x3116, glyph_rbopomofo }, + { 0x0157, glyph_rcedilla }, + { 0x24E1, glyph_rcircle }, + { 0x0211, glyph_rdblgrave }, + { 0x1E59, glyph_rdotaccent }, + { 0x1E5B, glyph_rdotbelow }, + { 0x1E5D, glyph_rdotbelowmacron }, + { 0x203B, glyph_referencemark }, + { 0x0631, glyph_reharabic }, + { 0x0580, glyph_reharmenian }, + { 0xFEAE, glyph_rehfinalarabic }, + { 0x308C, glyph_rehiragana }, + { 0x0631, glyph_rehyehaleflamarabic }, + { 0xFEF3, glyph_rehyehaleflamarabic }, + { 0xFE8E, glyph_rehyehaleflamarabic }, + { 0x0644, glyph_rehyehaleflamarabic }, + { 0x30EC, glyph_rekatakana }, + { 0xFF9A, glyph_rekatakanahalfwidth }, + { 0x05E8, glyph_resh }, + { 0xFB48, glyph_reshdageshhebrew }, + { 0x05E8, glyph_reshhatafpatah }, + { 0x05B2, glyph_reshhatafpatah }, + { 0x05E8, glyph_reshhatafpatahhebrew }, + { 0x05B2, glyph_reshhatafpatahhebrew }, + { 0x05E8, glyph_reshhatafsegol }, + { 0x05B1, glyph_reshhatafsegol }, + { 0x05E8, glyph_reshhatafsegolhebrew }, + { 0x05B1, glyph_reshhatafsegolhebrew }, + { 0x05E8, glyph_reshhebrew }, + { 0x05E8, glyph_reshhiriq }, + { 0x05B4, glyph_reshhiriq }, + { 0x05E8, glyph_reshhiriqhebrew }, + { 0x05B4, glyph_reshhiriqhebrew }, + { 0x05E8, glyph_reshholam }, + { 0x05B9, glyph_reshholam }, + { 0x05E8, glyph_reshholamhebrew }, + { 0x05B9, glyph_reshholamhebrew }, + { 0x05E8, glyph_reshpatah }, + { 0x05B7, glyph_reshpatah }, + { 0x05E8, glyph_reshpatahhebrew }, + { 0x05B7, glyph_reshpatahhebrew }, + { 0x05E8, glyph_reshqamats }, + { 0x05B8, glyph_reshqamats }, + { 0x05E8, glyph_reshqamatshebrew }, + { 0x05B8, glyph_reshqamatshebrew }, + { 0x05E8, glyph_reshqubuts }, + { 0x05BB, glyph_reshqubuts }, + { 0x05E8, glyph_reshqubutshebrew }, + { 0x05BB, glyph_reshqubutshebrew }, + { 0x05E8, glyph_reshsegol }, + { 0x05B6, glyph_reshsegol }, + { 0x05E8, glyph_reshsegolhebrew }, + { 0x05B6, glyph_reshsegolhebrew }, + { 0x05E8, glyph_reshsheva }, + { 0x05B0, glyph_reshsheva }, + { 0x05E8, glyph_reshshevahebrew }, + { 0x05B0, glyph_reshshevahebrew }, + { 0x05E8, glyph_reshtsere }, + { 0x05B5, glyph_reshtsere }, + { 0x05E8, glyph_reshtserehebrew }, + { 0x05B5, glyph_reshtserehebrew }, + { 0x223D, glyph_reversedtilde }, + { 0x0597, glyph_reviahebrew }, + { 0x0597, glyph_reviamugrashhebrew }, + { 0x027E, glyph_rfishhook }, + { 0x027F, glyph_rfishhookreversed }, + { 0x09DD, glyph_rhabengali }, + { 0x095D, glyph_rhadeva }, + { 0x027D, glyph_rhook }, + { 0x027B, glyph_rhookturned }, + { 0x02B5, glyph_rhookturnedsuperior }, + { 0x03F1, glyph_rhosymbolgreek }, + { 0x02DE, glyph_rhotichookmod }, + { 0x3271, glyph_rieulacirclekorean }, + { 0x3211, glyph_rieulaparenkorean }, + { 0x3263, glyph_rieulcirclekorean }, + { 0x3140, glyph_rieulhieuhkorean }, + { 0x313A, glyph_rieulkiyeokkorean }, + { 0x3169, glyph_rieulkiyeoksioskorean }, + { 0x3139, glyph_rieulkorean }, + { 0x313B, glyph_rieulmieumkorean }, + { 0x316C, glyph_rieulpansioskorean }, + { 0x3203, glyph_rieulparenkorean }, + { 0x313F, glyph_rieulphieuphkorean }, + { 0x313C, glyph_rieulpieupkorean }, + { 0x316B, glyph_rieulpieupsioskorean }, + { 0x313D, glyph_rieulsioskorean }, + { 0x313E, glyph_rieulthieuthkorean }, + { 0x316A, glyph_rieultikeutkorean }, + { 0x316D, glyph_rieulyeorinhieuhkorean }, + { 0x221F, glyph_rightangle }, + { 0x0319, glyph_righttackbelowcmb }, + { 0x22BF, glyph_righttriangle }, + { 0x308A, glyph_rihiragana }, + { 0x30EA, glyph_rikatakana }, + { 0xFF98, glyph_rikatakanahalfwidth }, + { 0x0325, glyph_ringbelowcmb }, + { 0x030A, glyph_ringcmb }, + { 0x02BF, glyph_ringhalfleft }, + { 0x0559, glyph_ringhalfleftarmenian }, + { 0x031C, glyph_ringhalfleftbelowcmb }, + { 0x02D3, glyph_ringhalfleftcentered }, + { 0x02BE, glyph_ringhalfright }, + { 0x0339, glyph_ringhalfrightbelowcmb }, + { 0x02D2, glyph_ringhalfrightcentered }, + { 0x0213, glyph_rinvertedbreve }, + { 0x3351, glyph_rittorusquare }, + { 0x1E5F, glyph_rlinebelow }, + { 0x027C, glyph_rlongleg }, + { 0x027A, glyph_rlonglegturned }, + { 0xFF52, glyph_rmonospace }, + { 0x308D, glyph_rohiragana }, + { 0x30ED, glyph_rokatakana }, + { 0xFF9B, glyph_rokatakanahalfwidth }, + { 0x0E23, glyph_roruathai }, + { 0x24AD, glyph_rparen }, + { 0x09DC, glyph_rrabengali }, + { 0x0931, glyph_rradeva }, + { 0x0A5C, glyph_rragurmukhi }, + { 0x0691, glyph_rreharabic }, + { 0xFB8D, glyph_rrehfinalarabic }, + { 0x09E0, glyph_rrvocalicbengali }, + { 0x0960, glyph_rrvocalicdeva }, + { 0x0AE0, glyph_rrvocalicgujarati }, + { 0x09C4, glyph_rrvocalicvowelsignbengali }, + { 0x0944, glyph_rrvocalicvowelsigndeva }, + { 0x0AC4, glyph_rrvocalicvowelsigngujarati }, + { 0x0279, glyph_rturned }, + { 0x02B4, glyph_rturnedsuperior }, + { 0x308B, glyph_ruhiragana }, + { 0x30EB, glyph_rukatakana }, + { 0xFF99, glyph_rukatakanahalfwidth }, + { 0x09F2, glyph_rupeemarkbengali }, + { 0x09F3, glyph_rupeesignbengali }, + { 0x0E24, glyph_ruthai }, + { 0x098B, glyph_rvocalicbengali }, + { 0x090B, glyph_rvocalicdeva }, + { 0x0A8B, glyph_rvocalicgujarati }, + { 0x09C3, glyph_rvocalicvowelsignbengali }, + { 0x0943, glyph_rvocalicvowelsigndeva }, + { 0x0AC3, glyph_rvocalicvowelsigngujarati }, + { 0x09B8, glyph_sabengali }, + { 0x1E65, glyph_sacutedotaccent }, + { 0x0635, glyph_sadarabic }, + { 0x0938, glyph_sadeva }, + { 0xFEBA, glyph_sadfinalarabic }, + { 0xFEBB, glyph_sadinitialarabic }, + { 0xFEBC, glyph_sadmedialarabic }, + { 0x0AB8, glyph_sagujarati }, + { 0x0A38, glyph_sagurmukhi }, + { 0x3055, glyph_sahiragana }, + { 0x30B5, glyph_sakatakana }, + { 0xFF7B, glyph_sakatakanahalfwidth }, + { 0xFDFA, glyph_sallallahoualayhewasallamarabic }, + { 0x05E1, glyph_samekh }, + { 0xFB41, glyph_samekhdagesh }, + { 0xFB41, glyph_samekhdageshhebrew }, + { 0x05E1, glyph_samekhhebrew }, + { 0x0E32, glyph_saraaathai }, + { 0x0E41, glyph_saraaethai }, + { 0x0E44, glyph_saraaimaimalaithai }, + { 0x0E43, glyph_saraaimaimuanthai }, + { 0x0E33, glyph_saraamthai }, + { 0x0E30, glyph_saraathai }, + { 0x0E40, glyph_saraethai }, + { 0xF886, glyph_saraiileftthai }, + { 0x0E35, glyph_saraiithai }, + { 0xF885, glyph_saraileftthai }, + { 0x0E34, glyph_saraithai }, + { 0x0E42, glyph_saraothai }, + { 0xF888, glyph_saraueeleftthai }, + { 0x0E37, glyph_saraueethai }, + { 0xF887, glyph_saraueleftthai }, + { 0x0E36, glyph_sarauethai }, + { 0x0E38, glyph_sarauthai }, + { 0x0E39, glyph_sarauuthai }, + { 0x3119, glyph_sbopomofo }, + { 0x1E67, glyph_scarondotaccent }, + { 0x0259, glyph_schwa }, + { 0x04D9, glyph_schwacyrillic }, + { 0x04DB, glyph_schwadieresiscyrillic }, + { 0x025A, glyph_schwahook }, + { 0x24E2, glyph_scircle }, + { 0x1E61, glyph_sdotaccent }, + { 0x1E63, glyph_sdotbelow }, + { 0x1E69, glyph_sdotbelowdotaccent }, + { 0x033C, glyph_seagullbelowcmb }, + { 0x02CA, glyph_secondtonechinese }, + { 0x0633, glyph_seenarabic }, + { 0xFEB2, glyph_seenfinalarabic }, + { 0xFEB3, glyph_seeninitialarabic }, + { 0xFEB4, glyph_seenmedialarabic }, + { 0x05B6, glyph_segol }, + { 0x05B6, glyph_segol13 }, + { 0x05B6, glyph_segol1f }, + { 0x05B6, glyph_segol2c }, + { 0x05B6, glyph_segolhebrew }, + { 0x05B6, glyph_segolnarrowhebrew }, + { 0x05B6, glyph_segolquarterhebrew }, + { 0x0592, glyph_segoltahebrew }, + { 0x05B6, glyph_segolwidehebrew }, + { 0x057D, glyph_seharmenian }, + { 0x305B, glyph_sehiragana }, + { 0x30BB, glyph_sekatakana }, + { 0xFF7E, glyph_sekatakanahalfwidth }, + { 0x061B, glyph_semicolonarabic }, + { 0xFF1B, glyph_semicolonmonospace }, + { 0xFE54, glyph_semicolonsmall }, + { 0x309C, glyph_semivoicedmarkkana }, + { 0xFF9F, glyph_semivoicedmarkkanahalfwidth }, + { 0x3322, glyph_sentisquare }, + { 0x3323, glyph_sentosquare }, + { 0x0667, glyph_sevenarabic }, + { 0x09ED, glyph_sevenbengali }, + { 0x2466, glyph_sevencircle }, + { 0x2790, glyph_sevencircleinversesansserif }, + { 0x096D, glyph_sevendeva }, + { 0x0AED, glyph_sevengujarati }, + { 0x0A6D, glyph_sevengurmukhi }, + { 0x0667, glyph_sevenhackarabic }, + { 0x3027, glyph_sevenhangzhou }, + { 0x3226, glyph_sevenideographicparen }, + { 0xFF17, glyph_sevenmonospace }, + { 0x247A, glyph_sevenparen }, + { 0x248E, glyph_sevenperiod }, + { 0x06F7, glyph_sevenpersian }, + { 0x2176, glyph_sevenroman }, + { 0x2470, glyph_seventeencircle }, + { 0x2484, glyph_seventeenparen }, + { 0x2498, glyph_seventeenperiod }, + { 0x0E57, glyph_seventhai }, + { 0x0577, glyph_shaarmenian }, + { 0x09B6, glyph_shabengali }, + { 0x0448, glyph_shacyrillic }, + { 0x0651, glyph_shaddaarabic }, + { 0xFC61, glyph_shaddadammaarabic }, + { 0xFC5E, glyph_shaddadammatanarabic }, + { 0xFC60, glyph_shaddafathaarabic }, + { 0x0651, glyph_shaddafathatanarabic }, + { 0x064B, glyph_shaddafathatanarabic }, + { 0xFC62, glyph_shaddakasraarabic }, + { 0xFC5F, glyph_shaddakasratanarabic }, + { 0x2593, glyph_shadedark }, + { 0x2591, glyph_shadelight }, + { 0x2592, glyph_shademedium }, + { 0x0936, glyph_shadeva }, + { 0x0AB6, glyph_shagujarati }, + { 0x0A36, glyph_shagurmukhi }, + { 0x0593, glyph_shalshelethebrew }, + { 0x3115, glyph_shbopomofo }, + { 0x0449, glyph_shchacyrillic }, + { 0x0634, glyph_sheenarabic }, + { 0xFEB6, glyph_sheenfinalarabic }, + { 0xFEB7, glyph_sheeninitialarabic }, + { 0xFEB8, glyph_sheenmedialarabic }, + { 0x03E3, glyph_sheicoptic }, + { 0x20AA, glyph_sheqel }, + { 0x20AA, glyph_sheqelhebrew }, + { 0x05B0, glyph_sheva }, + { 0x05B0, glyph_sheva115 }, + { 0x05B0, glyph_sheva15 }, + { 0x05B0, glyph_sheva22 }, + { 0x05B0, glyph_sheva2e }, + { 0x05B0, glyph_shevahebrew }, + { 0x05B0, glyph_shevanarrowhebrew }, + { 0x05B0, glyph_shevaquarterhebrew }, + { 0x05B0, glyph_shevawidehebrew }, + { 0x04BB, glyph_shhacyrillic }, + { 0x03ED, glyph_shimacoptic }, + { 0x05E9, glyph_shin }, + { 0xFB49, glyph_shindagesh }, + { 0xFB49, glyph_shindageshhebrew }, + { 0xFB2C, glyph_shindageshshindot }, + { 0xFB2C, glyph_shindageshshindothebrew }, + { 0xFB2D, glyph_shindageshsindot }, + { 0xFB2D, glyph_shindageshsindothebrew }, + { 0x05C1, glyph_shindothebrew }, + { 0x05E9, glyph_shinhebrew }, + { 0xFB2A, glyph_shinshindot }, + { 0xFB2A, glyph_shinshindothebrew }, + { 0xFB2B, glyph_shinsindot }, + { 0xFB2B, glyph_shinsindothebrew }, + { 0x0282, glyph_shook }, + { 0x03C2, glyph_sigmafinal }, + { 0x03F2, glyph_sigmalunatesymbolgreek }, + { 0x3057, glyph_sihiragana }, + { 0x30B7, glyph_sikatakana }, + { 0xFF7C, glyph_sikatakanahalfwidth }, + { 0x05BD, glyph_siluqhebrew }, + { 0x05BD, glyph_siluqlefthebrew }, + { 0x05C2, glyph_sindothebrew }, + { 0x3274, glyph_siosacirclekorean }, + { 0x3214, glyph_siosaparenkorean }, + { 0x317E, glyph_sioscieuckorean }, + { 0x3266, glyph_sioscirclekorean }, + { 0x317A, glyph_sioskiyeokkorean }, + { 0x3145, glyph_sioskorean }, + { 0x317B, glyph_siosnieunkorean }, + { 0x3206, glyph_siosparenkorean }, + { 0x317D, glyph_siospieupkorean }, + { 0x317C, glyph_siostikeutkorean }, + { 0x0666, glyph_sixarabic }, + { 0x09EC, glyph_sixbengali }, + { 0x2465, glyph_sixcircle }, + { 0x278F, glyph_sixcircleinversesansserif }, + { 0x096C, glyph_sixdeva }, + { 0x0AEC, glyph_sixgujarati }, + { 0x0A6C, glyph_sixgurmukhi }, + { 0x0666, glyph_sixhackarabic }, + { 0x3026, glyph_sixhangzhou }, + { 0x3225, glyph_sixideographicparen }, + { 0xFF16, glyph_sixmonospace }, + { 0x2479, glyph_sixparen }, + { 0x248D, glyph_sixperiod }, + { 0x06F6, glyph_sixpersian }, + { 0x2175, glyph_sixroman }, + { 0x246F, glyph_sixteencircle }, + { 0x09F9, glyph_sixteencurrencydenominatorbengali }, + { 0x2483, glyph_sixteenparen }, + { 0x2497, glyph_sixteenperiod }, + { 0x0E56, glyph_sixthai }, + { 0xFF0F, glyph_slashmonospace }, + { 0x017F, glyph_slong }, + { 0x1E9B, glyph_slongdotaccent }, + { 0xFF53, glyph_smonospace }, + { 0x05C3, glyph_sofpasuqhebrew }, + { 0x00AD, glyph_softhyphen }, + { 0x044C, glyph_softsigncyrillic }, + { 0x305D, glyph_sohiragana }, + { 0x30BD, glyph_sokatakana }, + { 0xFF7F, glyph_sokatakanahalfwidth }, + { 0x0338, glyph_soliduslongoverlaycmb }, + { 0x0337, glyph_solidusshortoverlaycmb }, + { 0x0E29, glyph_sorusithai }, + { 0x0E28, glyph_sosalathai }, + { 0x0E0B, glyph_sosothai }, + { 0x0E2A, glyph_sosuathai }, + { 0x0020, glyph_spacehackarabic }, + { 0x2660, glyph_spadesuitblack }, + { 0x2664, glyph_spadesuitwhite }, + { 0x24AE, glyph_sparen }, + { 0x033B, glyph_squarebelowcmb }, + { 0x33C4, glyph_squarecc }, + { 0x339D, glyph_squarecm }, + { 0x25A9, glyph_squarediagonalcrosshatchfill }, + { 0x25A4, glyph_squarehorizontalfill }, + { 0x338F, glyph_squarekg }, + { 0x339E, glyph_squarekm }, + { 0x33CE, glyph_squarekmcapital }, + { 0x33D1, glyph_squareln }, + { 0x33D2, glyph_squarelog }, + { 0x338E, glyph_squaremg }, + { 0x33D5, glyph_squaremil }, + { 0x339C, glyph_squaremm }, + { 0x33A1, glyph_squaremsquared }, + { 0x25A6, glyph_squareorthogonalcrosshatchfill }, + { 0x25A7, glyph_squareupperlefttolowerrightfill }, + { 0x25A8, glyph_squareupperrighttolowerleftfill }, + { 0x25A5, glyph_squareverticalfill }, + { 0x25A3, glyph_squarewhitewithsmallblack }, + { 0x33DB, glyph_srsquare }, + { 0x09B7, glyph_ssabengali }, + { 0x0937, glyph_ssadeva }, + { 0x0AB7, glyph_ssagujarati }, + { 0x3149, glyph_ssangcieuckorean }, + { 0x3185, glyph_ssanghieuhkorean }, + { 0x3180, glyph_ssangieungkorean }, + { 0x3132, glyph_ssangkiyeokkorean }, + { 0x3165, glyph_ssangnieunkorean }, + { 0x3143, glyph_ssangpieupkorean }, + { 0x3146, glyph_ssangsioskorean }, + { 0x3138, glyph_ssangtikeutkorean }, + { 0xFFE1, glyph_sterlingmonospace }, + { 0x0336, glyph_strokelongoverlaycmb }, + { 0x0335, glyph_strokeshortoverlaycmb }, + { 0x2282, glyph_subset }, + { 0x228A, glyph_subsetnotequal }, + { 0x2286, glyph_subsetorequal }, + { 0x227B, glyph_succeeds }, + { 0x3059, glyph_suhiragana }, + { 0x30B9, glyph_sukatakana }, + { 0xFF7D, glyph_sukatakanahalfwidth }, + { 0x0652, glyph_sukunarabic }, + { 0x2283, glyph_superset }, + { 0x228B, glyph_supersetnotequal }, + { 0x2287, glyph_supersetorequal }, + { 0x33DC, glyph_svsquare }, + { 0x337C, glyph_syouwaerasquare }, + { 0x09A4, glyph_tabengali }, + { 0x22A4, glyph_tackdown }, + { 0x22A3, glyph_tackleft }, + { 0x0924, glyph_tadeva }, + { 0x0AA4, glyph_tagujarati }, + { 0x0A24, glyph_tagurmukhi }, + { 0x0637, glyph_taharabic }, + { 0xFEC2, glyph_tahfinalarabic }, + { 0xFEC3, glyph_tahinitialarabic }, + { 0x305F, glyph_tahiragana }, + { 0xFEC4, glyph_tahmedialarabic }, + { 0x337D, glyph_taisyouerasquare }, + { 0x30BF, glyph_takatakana }, + { 0xFF80, glyph_takatakanahalfwidth }, + { 0x0640, glyph_tatweelarabic }, + { 0x05EA, glyph_tav }, + { 0xFB4A, glyph_tavdages }, + { 0xFB4A, glyph_tavdagesh }, + { 0xFB4A, glyph_tavdageshhebrew }, + { 0x05EA, glyph_tavhebrew }, + { 0x310A, glyph_tbopomofo }, + { 0x02A8, glyph_tccurl }, + { 0x0686, glyph_tcheharabic }, + { 0xFB7B, glyph_tchehfinalarabic }, + { 0xFB7C, glyph_tchehinitialarabic }, + { 0xFB7D, glyph_tchehmedialarabic }, + { 0xFB7C, glyph_tchehmeeminitialarabic }, + { 0xFEE4, glyph_tchehmeeminitialarabic }, + { 0x24E3, glyph_tcircle }, + { 0x1E71, glyph_tcircumflexbelow }, + { 0x1E97, glyph_tdieresis }, + { 0x1E6B, glyph_tdotaccent }, + { 0x1E6D, glyph_tdotbelow }, + { 0x0442, glyph_tecyrillic }, + { 0x04AD, glyph_tedescendercyrillic }, + { 0x062A, glyph_teharabic }, + { 0xFE96, glyph_tehfinalarabic }, + { 0xFCA2, glyph_tehhahinitialarabic }, + { 0xFC0C, glyph_tehhahisolatedarabic }, + { 0xFE97, glyph_tehinitialarabic }, + { 0x3066, glyph_tehiragana }, + { 0xFCA1, glyph_tehjeeminitialarabic }, + { 0xFC0B, glyph_tehjeemisolatedarabic }, + { 0x0629, glyph_tehmarbutaarabic }, + { 0xFE94, glyph_tehmarbutafinalarabic }, + { 0xFE98, glyph_tehmedialarabic }, + { 0xFCA4, glyph_tehmeeminitialarabic }, + { 0xFC0E, glyph_tehmeemisolatedarabic }, + { 0xFC73, glyph_tehnoonfinalarabic }, + { 0x30C6, glyph_tekatakana }, + { 0xFF83, glyph_tekatakanahalfwidth }, + { 0x2121, glyph_telephone }, + { 0x260E, glyph_telephoneblack }, + { 0x05A0, glyph_telishagedolahebrew }, + { 0x05A9, glyph_telishaqetanahebrew }, + { 0x2469, glyph_tencircle }, + { 0x3229, glyph_tenideographicparen }, + { 0x247D, glyph_tenparen }, + { 0x2491, glyph_tenperiod }, + { 0x2179, glyph_tenroman }, + { 0x02A7, glyph_tesh }, + { 0x05D8, glyph_tet }, + { 0xFB38, glyph_tetdagesh }, + { 0xFB38, glyph_tetdageshhebrew }, + { 0x05D8, glyph_tethebrew }, + { 0x04B5, glyph_tetsecyrillic }, + { 0x059B, glyph_tevirhebrew }, + { 0x059B, glyph_tevirlefthebrew }, + { 0x09A5, glyph_thabengali }, + { 0x0925, glyph_thadeva }, + { 0x0AA5, glyph_thagujarati }, + { 0x0A25, glyph_thagurmukhi }, + { 0x0630, glyph_thalarabic }, + { 0xFEAC, glyph_thalfinalarabic }, + { 0xF898, glyph_thanthakhatlowleftthai }, + { 0xF897, glyph_thanthakhatlowrightthai }, + { 0x0E4C, glyph_thanthakhatthai }, + { 0xF896, glyph_thanthakhatupperleftthai }, + { 0x062B, glyph_theharabic }, + { 0xFE9A, glyph_thehfinalarabic }, + { 0xFE9B, glyph_thehinitialarabic }, + { 0xFE9C, glyph_thehmedialarabic }, + { 0x2203, glyph_thereexists }, + { 0x03D1, glyph_thetasymbolgreek }, + { 0x3279, glyph_thieuthacirclekorean }, + { 0x3219, glyph_thieuthaparenkorean }, + { 0x326B, glyph_thieuthcirclekorean }, + { 0x314C, glyph_thieuthkorean }, + { 0x320B, glyph_thieuthparenkorean }, + { 0x246C, glyph_thirteencircle }, + { 0x2480, glyph_thirteenparen }, + { 0x2494, glyph_thirteenperiod }, + { 0x0E11, glyph_thonangmonthothai }, + { 0x01AD, glyph_thook }, + { 0x0E12, glyph_thophuthaothai }, + { 0x0E17, glyph_thothahanthai }, + { 0x0E10, glyph_thothanthai }, + { 0x0E18, glyph_thothongthai }, + { 0x0E16, glyph_thothungthai }, + { 0x0482, glyph_thousandcyrillic }, + { 0x066C, glyph_thousandsseparatorarabic }, + { 0x066C, glyph_thousandsseparatorpersian }, + { 0x0663, glyph_threearabic }, + { 0x09E9, glyph_threebengali }, + { 0x2462, glyph_threecircle }, + { 0x278C, glyph_threecircleinversesansserif }, + { 0x0969, glyph_threedeva }, + { 0x0AE9, glyph_threegujarati }, + { 0x0A69, glyph_threegurmukhi }, + { 0x0663, glyph_threehackarabic }, + { 0x3023, glyph_threehangzhou }, + { 0x3222, glyph_threeideographicparen }, + { 0xFF13, glyph_threemonospace }, + { 0x09F6, glyph_threenumeratorbengali }, + { 0x2476, glyph_threeparen }, + { 0x248A, glyph_threeperiod }, + { 0x06F3, glyph_threepersian }, + { 0x2172, glyph_threeroman }, + { 0x0E53, glyph_threethai }, + { 0x3394, glyph_thzsquare }, + { 0x3061, glyph_tihiragana }, + { 0x30C1, glyph_tikatakana }, + { 0xFF81, glyph_tikatakanahalfwidth }, + { 0x3270, glyph_tikeutacirclekorean }, + { 0x3210, glyph_tikeutaparenkorean }, + { 0x3262, glyph_tikeutcirclekorean }, + { 0x3137, glyph_tikeutkorean }, + { 0x3202, glyph_tikeutparenkorean }, + { 0x0330, glyph_tildebelowcmb }, + { 0x0303, glyph_tildecmb }, + { 0x0360, glyph_tildedoublecmb }, + { 0x223C, glyph_tildeoperator }, + { 0x0334, glyph_tildeoverlaycmb }, + { 0x033E, glyph_tildeverticalcmb }, + { 0x2297, glyph_timescircle }, + { 0x0596, glyph_tipehahebrew }, + { 0x0596, glyph_tipehalefthebrew }, + { 0x0A70, glyph_tippigurmukhi }, + { 0x0483, glyph_titlocyrilliccmb }, + { 0x057F, glyph_tiwnarmenian }, + { 0x1E6F, glyph_tlinebelow }, + { 0xFF54, glyph_tmonospace }, + { 0x0569, glyph_toarmenian }, + { 0x3068, glyph_tohiragana }, + { 0x30C8, glyph_tokatakana }, + { 0xFF84, glyph_tokatakanahalfwidth }, + { 0x02E5, glyph_tonebarextrahighmod }, + { 0x02E9, glyph_tonebarextralowmod }, + { 0x02E6, glyph_tonebarhighmod }, + { 0x02E8, glyph_tonebarlowmod }, + { 0x02E7, glyph_tonebarmidmod }, + { 0x01BD, glyph_tonefive }, + { 0x0185, glyph_tonesix }, + { 0x01A8, glyph_tonetwo }, + { 0x3327, glyph_tonsquare }, + { 0x0E0F, glyph_topatakthai }, + { 0x3014, glyph_tortoiseshellbracketleft }, + { 0xFE5D, glyph_tortoiseshellbracketleftsmall }, + { 0xFE39, glyph_tortoiseshellbracketleftvertical }, + { 0x3015, glyph_tortoiseshellbracketright }, + { 0xFE5E, glyph_tortoiseshellbracketrightsmall }, + { 0xFE3A, glyph_tortoiseshellbracketrightvertical }, + { 0x0E15, glyph_totaothai }, + { 0x01AB, glyph_tpalatalhook }, + { 0x24AF, glyph_tparen }, + { 0x0288, glyph_tretroflexhook }, + { 0x02A6, glyph_ts }, + { 0x05E6, glyph_tsadi }, + { 0xFB46, glyph_tsadidagesh }, + { 0xFB46, glyph_tsadidageshhebrew }, + { 0x05E6, glyph_tsadihebrew }, + { 0x0446, glyph_tsecyrillic }, + { 0x05B5, glyph_tsere }, + { 0x05B5, glyph_tsere12 }, + { 0x05B5, glyph_tsere1e }, + { 0x05B5, glyph_tsere2b }, + { 0x05B5, glyph_tserehebrew }, + { 0x05B5, glyph_tserenarrowhebrew }, + { 0x05B5, glyph_tserequarterhebrew }, + { 0x05B5, glyph_tserewidehebrew }, + { 0x045B, glyph_tshecyrillic }, + { 0x099F, glyph_ttabengali }, + { 0x091F, glyph_ttadeva }, + { 0x0A9F, glyph_ttagujarati }, + { 0x0A1F, glyph_ttagurmukhi }, + { 0x0679, glyph_tteharabic }, + { 0xFB67, glyph_ttehfinalarabic }, + { 0xFB68, glyph_ttehinitialarabic }, + { 0xFB69, glyph_ttehmedialarabic }, + { 0x09A0, glyph_tthabengali }, + { 0x0920, glyph_tthadeva }, + { 0x0AA0, glyph_tthagujarati }, + { 0x0A20, glyph_tthagurmukhi }, + { 0x0287, glyph_tturned }, + { 0x3064, glyph_tuhiragana }, + { 0x30C4, glyph_tukatakana }, + { 0xFF82, glyph_tukatakanahalfwidth }, + { 0x3063, glyph_tusmallhiragana }, + { 0x30C3, glyph_tusmallkatakana }, + { 0xFF6F, glyph_tusmallkatakanahalfwidth }, + { 0x246B, glyph_twelvecircle }, + { 0x247F, glyph_twelveparen }, + { 0x2493, glyph_twelveperiod }, + { 0x217B, glyph_twelveroman }, + { 0x2473, glyph_twentycircle }, + { 0x5344, glyph_twentyhangzhou }, + { 0x2487, glyph_twentyparen }, + { 0x249B, glyph_twentyperiod }, + { 0x0662, glyph_twoarabic }, + { 0x09E8, glyph_twobengali }, + { 0x2461, glyph_twocircle }, + { 0x278B, glyph_twocircleinversesansserif }, + { 0x0968, glyph_twodeva }, + { 0x2025, glyph_twodotleader }, + { 0xFE30, glyph_twodotleadervertical }, + { 0x0AE8, glyph_twogujarati }, + { 0x0A68, glyph_twogurmukhi }, + { 0x0662, glyph_twohackarabic }, + { 0x3022, glyph_twohangzhou }, + { 0x3221, glyph_twoideographicparen }, + { 0xFF12, glyph_twomonospace }, + { 0x09F5, glyph_twonumeratorbengali }, + { 0x2475, glyph_twoparen }, + { 0x2489, glyph_twoperiod }, + { 0x06F2, glyph_twopersian }, + { 0x2171, glyph_tworoman }, + { 0x01BB, glyph_twostroke }, + { 0x0E52, glyph_twothai }, + { 0x0289, glyph_ubar }, + { 0x0989, glyph_ubengali }, + { 0x3128, glyph_ubopomofo }, + { 0x01D4, glyph_ucaron }, + { 0x24E4, glyph_ucircle }, + { 0x1E77, glyph_ucircumflexbelow }, + { 0x0443, glyph_ucyrillic }, + { 0x0951, glyph_udattadeva }, + { 0x0171, glyph_udblacute }, + { 0x0215, glyph_udblgrave }, + { 0x0909, glyph_udeva }, + { 0x01D8, glyph_udieresisacute }, + { 0x1E73, glyph_udieresisbelow }, + { 0x01DA, glyph_udieresiscaron }, + { 0x04F1, glyph_udieresiscyrillic }, + { 0x01DC, glyph_udieresisgrave }, + { 0x01D6, glyph_udieresismacron }, + { 0x1EE5, glyph_udotbelow }, + { 0x0A89, glyph_ugujarati }, + { 0x0A09, glyph_ugurmukhi }, + { 0x3046, glyph_uhiragana }, + { 0x1EE7, glyph_uhookabove }, + { 0x1EE9, glyph_uhornacute }, + { 0x1EF1, glyph_uhorndotbelow }, + { 0x1EEB, glyph_uhorngrave }, + { 0x1EED, glyph_uhornhookabove }, + { 0x1EEF, glyph_uhorntilde }, + { 0x04F3, glyph_uhungarumlautcyrillic }, + { 0x0217, glyph_uinvertedbreve }, + { 0x30A6, glyph_ukatakana }, + { 0xFF73, glyph_ukatakanahalfwidth }, + { 0x0479, glyph_ukcyrillic }, + { 0x315C, glyph_ukorean }, + { 0x04EF, glyph_umacroncyrillic }, + { 0x1E7B, glyph_umacrondieresis }, + { 0x0A41, glyph_umatragurmukhi }, + { 0xFF55, glyph_umonospace }, + { 0xFF3F, glyph_underscoremonospace }, + { 0xFE33, glyph_underscorevertical }, + { 0xFE4F, glyph_underscorewavy }, + { 0x24B0, glyph_uparen }, + { 0x05C4, glyph_upperdothebrew }, + { 0x028A, glyph_upsilonlatin }, + { 0x031D, glyph_uptackbelowcmb }, + { 0x02D4, glyph_uptackmod }, + { 0x0A73, glyph_uragurmukhi }, + { 0x045E, glyph_ushortcyrillic }, + { 0x3045, glyph_usmallhiragana }, + { 0x30A5, glyph_usmallkatakana }, + { 0xFF69, glyph_usmallkatakanahalfwidth }, + { 0x04AF, glyph_ustraightcyrillic }, + { 0x04B1, glyph_ustraightstrokecyrillic }, + { 0x1E79, glyph_utildeacute }, + { 0x1E75, glyph_utildebelow }, + { 0x098A, glyph_uubengali }, + { 0x090A, glyph_uudeva }, + { 0x0A8A, glyph_uugujarati }, + { 0x0A0A, glyph_uugurmukhi }, + { 0x0A42, glyph_uumatragurmukhi }, + { 0x09C2, glyph_uuvowelsignbengali }, + { 0x0942, glyph_uuvowelsigndeva }, + { 0x0AC2, glyph_uuvowelsigngujarati }, + { 0x09C1, glyph_uvowelsignbengali }, + { 0x0941, glyph_uvowelsigndeva }, + { 0x0AC1, glyph_uvowelsigngujarati }, + { 0x0935, glyph_vadeva }, + { 0x0AB5, glyph_vagujarati }, + { 0x0A35, glyph_vagurmukhi }, + { 0x30F7, glyph_vakatakana }, + { 0x05D5, glyph_vav }, + { 0xFB35, glyph_vavdagesh }, + { 0xFB35, glyph_vavdagesh65 }, + { 0xFB35, glyph_vavdageshhebrew }, + { 0x05D5, glyph_vavhebrew }, + { 0xFB4B, glyph_vavholam }, + { 0xFB4B, glyph_vavholamhebrew }, + { 0x05F0, glyph_vavvavhebrew }, + { 0x05F1, glyph_vavyodhebrew }, + { 0x24E5, glyph_vcircle }, + { 0x1E7F, glyph_vdotbelow }, + { 0x0432, glyph_vecyrillic }, + { 0x06A4, glyph_veharabic }, + { 0xFB6B, glyph_vehfinalarabic }, + { 0xFB6C, glyph_vehinitialarabic }, + { 0xFB6D, glyph_vehmedialarabic }, + { 0x30F9, glyph_vekatakana }, + { 0x2640, glyph_venus }, + { 0x007C, glyph_verticalbar }, + { 0x030D, glyph_verticallineabovecmb }, + { 0x0329, glyph_verticallinebelowcmb }, + { 0x02CC, glyph_verticallinelowmod }, + { 0x02C8, glyph_verticallinemod }, + { 0x057E, glyph_vewarmenian }, + { 0x028B, glyph_vhook }, + { 0x30F8, glyph_vikatakana }, + { 0x09CD, glyph_viramabengali }, + { 0x094D, glyph_viramadeva }, + { 0x0ACD, glyph_viramagujarati }, + { 0x0983, glyph_visargabengali }, + { 0x0903, glyph_visargadeva }, + { 0x0A83, glyph_visargagujarati }, + { 0xFF56, glyph_vmonospace }, + { 0x0578, glyph_voarmenian }, + { 0x309E, glyph_voicediterationhiragana }, + { 0x30FE, glyph_voicediterationkatakana }, + { 0x309B, glyph_voicedmarkkana }, + { 0xFF9E, glyph_voicedmarkkanahalfwidth }, + { 0x30FA, glyph_vokatakana }, + { 0x24B1, glyph_vparen }, + { 0x1E7D, glyph_vtilde }, + { 0x028C, glyph_vturned }, + { 0x3094, glyph_vuhiragana }, + { 0x30F4, glyph_vukatakana }, + { 0x3159, glyph_waekorean }, + { 0x308F, glyph_wahiragana }, + { 0x30EF, glyph_wakatakana }, + { 0xFF9C, glyph_wakatakanahalfwidth }, + { 0x3158, glyph_wakorean }, + { 0x308E, glyph_wasmallhiragana }, + { 0x30EE, glyph_wasmallkatakana }, + { 0x3357, glyph_wattosquare }, + { 0x301C, glyph_wavedash }, + { 0xFE34, glyph_wavyunderscorevertical }, + { 0x0648, glyph_wawarabic }, + { 0xFEEE, glyph_wawfinalarabic }, + { 0x0624, glyph_wawhamzaabovearabic }, + { 0xFE86, glyph_wawhamzaabovefinalarabic }, + { 0x33DD, glyph_wbsquare }, + { 0x24E6, glyph_wcircle }, + { 0x1E87, glyph_wdotaccent }, + { 0x1E89, glyph_wdotbelow }, + { 0x3091, glyph_wehiragana }, + { 0x30F1, glyph_wekatakana }, + { 0x315E, glyph_wekorean }, + { 0x315D, glyph_weokorean }, + { 0x25E6, glyph_whitebullet }, + { 0x25CB, glyph_whitecircle }, + { 0x25D9, glyph_whitecircleinverse }, + { 0x300E, glyph_whitecornerbracketleft }, + { 0xFE43, glyph_whitecornerbracketleftvertical }, + { 0x300F, glyph_whitecornerbracketright }, + { 0xFE44, glyph_whitecornerbracketrightvertical }, + { 0x25C7, glyph_whitediamond }, + { 0x25C8, glyph_whitediamondcontainingblacksmalldiamond }, + { 0x25BF, glyph_whitedownpointingsmalltriangle }, + { 0x25BD, glyph_whitedownpointingtriangle }, + { 0x25C3, glyph_whiteleftpointingsmalltriangle }, + { 0x25C1, glyph_whiteleftpointingtriangle }, + { 0x3016, glyph_whitelenticularbracketleft }, + { 0x3017, glyph_whitelenticularbracketright }, + { 0x25B9, glyph_whiterightpointingsmalltriangle }, + { 0x25B7, glyph_whiterightpointingtriangle }, + { 0x25AB, glyph_whitesmallsquare }, + { 0x263A, glyph_whitesmilingface }, + { 0x25A1, glyph_whitesquare }, + { 0x2606, glyph_whitestar }, + { 0x260F, glyph_whitetelephone }, + { 0x3018, glyph_whitetortoiseshellbracketleft }, + { 0x3019, glyph_whitetortoiseshellbracketright }, + { 0x25B5, glyph_whiteuppointingsmalltriangle }, + { 0x25B3, glyph_whiteuppointingtriangle }, + { 0x3090, glyph_wihiragana }, + { 0x30F0, glyph_wikatakana }, + { 0x315F, glyph_wikorean }, + { 0xFF57, glyph_wmonospace }, + { 0x3092, glyph_wohiragana }, + { 0x30F2, glyph_wokatakana }, + { 0xFF66, glyph_wokatakanahalfwidth }, + { 0x20A9, glyph_won }, + { 0xFFE6, glyph_wonmonospace }, + { 0x0E27, glyph_wowaenthai }, + { 0x24B2, glyph_wparen }, + { 0x1E98, glyph_wring }, + { 0x02B7, glyph_wsuperior }, + { 0x028D, glyph_wturned }, + { 0x01BF, glyph_wynn }, + { 0x033D, glyph_xabovecmb }, + { 0x3112, glyph_xbopomofo }, + { 0x24E7, glyph_xcircle }, + { 0x1E8D, glyph_xdieresis }, + { 0x1E8B, glyph_xdotaccent }, + { 0x056D, glyph_xeharmenian }, + { 0xFF58, glyph_xmonospace }, + { 0x24B3, glyph_xparen }, + { 0x02E3, glyph_xsuperior }, + { 0x334E, glyph_yaadosquare }, + { 0x09AF, glyph_yabengali }, + { 0x092F, glyph_yadeva }, + { 0x3152, glyph_yaekorean }, + { 0x0AAF, glyph_yagujarati }, + { 0x0A2F, glyph_yagurmukhi }, + { 0x3084, glyph_yahiragana }, + { 0x30E4, glyph_yakatakana }, + { 0xFF94, glyph_yakatakanahalfwidth }, + { 0x3151, glyph_yakorean }, + { 0x0E4E, glyph_yamakkanthai }, + { 0x3083, glyph_yasmallhiragana }, + { 0x30E3, glyph_yasmallkatakana }, + { 0xFF6C, glyph_yasmallkatakanahalfwidth }, + { 0x0463, glyph_yatcyrillic }, + { 0x24E8, glyph_ycircle }, + { 0x1E8F, glyph_ydotaccent }, + { 0x1EF5, glyph_ydotbelow }, + { 0x064A, glyph_yeharabic }, + { 0x06D2, glyph_yehbarreearabic }, + { 0xFBAF, glyph_yehbarreefinalarabic }, + { 0xFEF2, glyph_yehfinalarabic }, + { 0x0626, glyph_yehhamzaabovearabic }, + { 0xFE8A, glyph_yehhamzaabovefinalarabic }, + { 0xFE8B, glyph_yehhamzaaboveinitialarabic }, + { 0xFE8C, glyph_yehhamzaabovemedialarabic }, + { 0xFEF3, glyph_yehinitialarabic }, + { 0xFEF4, glyph_yehmedialarabic }, + { 0xFCDD, glyph_yehmeeminitialarabic }, + { 0xFC58, glyph_yehmeemisolatedarabic }, + { 0xFC94, glyph_yehnoonfinalarabic }, + { 0x06D1, glyph_yehthreedotsbelowarabic }, + { 0x3156, glyph_yekorean }, + { 0xFFE5, glyph_yenmonospace }, + { 0x3155, glyph_yeokorean }, + { 0x3186, glyph_yeorinhieuhkorean }, + { 0x05AA, glyph_yerahbenyomohebrew }, + { 0x05AA, glyph_yerahbenyomolefthebrew }, + { 0x044B, glyph_yericyrillic }, + { 0x04F9, glyph_yerudieresiscyrillic }, + { 0x3181, glyph_yesieungkorean }, + { 0x3183, glyph_yesieungpansioskorean }, + { 0x3182, glyph_yesieungsioskorean }, + { 0x059A, glyph_yetivhebrew }, + { 0x01B4, glyph_yhook }, + { 0x1EF7, glyph_yhookabove }, + { 0x0575, glyph_yiarmenian }, + { 0x0457, glyph_yicyrillic }, + { 0x3162, glyph_yikorean }, + { 0x262F, glyph_yinyang }, + { 0x0582, glyph_yiwnarmenian }, + { 0xFF59, glyph_ymonospace }, + { 0x05D9, glyph_yod }, + { 0xFB39, glyph_yoddagesh }, + { 0xFB39, glyph_yoddageshhebrew }, + { 0x05D9, glyph_yodhebrew }, + { 0x05F2, glyph_yodyodhebrew }, + { 0xFB1F, glyph_yodyodpatahhebrew }, + { 0x3088, glyph_yohiragana }, + { 0x3189, glyph_yoikorean }, + { 0x30E8, glyph_yokatakana }, + { 0xFF96, glyph_yokatakanahalfwidth }, + { 0x315B, glyph_yokorean }, + { 0x3087, glyph_yosmallhiragana }, + { 0x30E7, glyph_yosmallkatakana }, + { 0xFF6E, glyph_yosmallkatakanahalfwidth }, + { 0x03F3, glyph_yotgreek }, + { 0x3188, glyph_yoyaekorean }, + { 0x3187, glyph_yoyakorean }, + { 0x0E22, glyph_yoyakthai }, + { 0x0E0D, glyph_yoyingthai }, + { 0x24B4, glyph_yparen }, + { 0x037A, glyph_ypogegrammeni }, + { 0x0345, glyph_ypogegrammenigreekcmb }, + { 0x01A6, glyph_yr }, + { 0x1E99, glyph_yring }, + { 0x02B8, glyph_ysuperior }, + { 0x1EF9, glyph_ytilde }, + { 0x028E, glyph_yturned }, + { 0x3086, glyph_yuhiragana }, + { 0x318C, glyph_yuikorean }, + { 0x30E6, glyph_yukatakana }, + { 0xFF95, glyph_yukatakanahalfwidth }, + { 0x3160, glyph_yukorean }, + { 0x046B, glyph_yusbigcyrillic }, + { 0x046D, glyph_yusbigiotifiedcyrillic }, + { 0x0467, glyph_yuslittlecyrillic }, + { 0x0469, glyph_yuslittleiotifiedcyrillic }, + { 0x3085, glyph_yusmallhiragana }, + { 0x30E5, glyph_yusmallkatakana }, + { 0xFF6D, glyph_yusmallkatakanahalfwidth }, + { 0x318B, glyph_yuyekorean }, + { 0x318A, glyph_yuyeokorean }, + { 0x09DF, glyph_yyabengali }, + { 0x095F, glyph_yyadeva }, + { 0x0566, glyph_zaarmenian }, + { 0x095B, glyph_zadeva }, + { 0x0A5B, glyph_zagurmukhi }, + { 0x0638, glyph_zaharabic }, + { 0xFEC6, glyph_zahfinalarabic }, + { 0xFEC7, glyph_zahinitialarabic }, + { 0x3056, glyph_zahiragana }, + { 0xFEC8, glyph_zahmedialarabic }, + { 0x0632, glyph_zainarabic }, + { 0xFEB0, glyph_zainfinalarabic }, + { 0x30B6, glyph_zakatakana }, + { 0x0595, glyph_zaqefgadolhebrew }, + { 0x0594, glyph_zaqefqatanhebrew }, + { 0x0598, glyph_zarqahebrew }, + { 0x05D6, glyph_zayin }, + { 0xFB36, glyph_zayindagesh }, + { 0xFB36, glyph_zayindageshhebrew }, + { 0x05D6, glyph_zayinhebrew }, + { 0x3117, glyph_zbopomofo }, + { 0x24E9, glyph_zcircle }, + { 0x1E91, glyph_zcircumflex }, + { 0x0291, glyph_zcurl }, + { 0x017C, glyph_zdot }, + { 0x1E93, glyph_zdotbelow }, + { 0x0437, glyph_zecyrillic }, + { 0x0499, glyph_zedescendercyrillic }, + { 0x04DF, glyph_zedieresiscyrillic }, + { 0x305C, glyph_zehiragana }, + { 0x30BC, glyph_zekatakana }, + { 0x0660, glyph_zeroarabic }, + { 0x09E6, glyph_zerobengali }, + { 0x0966, glyph_zerodeva }, + { 0x0AE6, glyph_zerogujarati }, + { 0x0A66, glyph_zerogurmukhi }, + { 0x0660, glyph_zerohackarabic }, + { 0xFF10, glyph_zeromonospace }, + { 0x06F0, glyph_zeropersian }, + { 0x0E50, glyph_zerothai }, + { 0xFEFF, glyph_zerowidthjoiner }, + { 0x200C, glyph_zerowidthnonjoiner }, + { 0x200B, glyph_zerowidthspace }, + { 0x3113, glyph_zhbopomofo }, + { 0x056A, glyph_zhearmenian }, + { 0x04C2, glyph_zhebrevecyrillic }, + { 0x0436, glyph_zhecyrillic }, + { 0x0497, glyph_zhedescendercyrillic }, + { 0x04DD, glyph_zhedieresiscyrillic }, + { 0x3058, glyph_zihiragana }, + { 0x30B8, glyph_zikatakana }, + { 0x05AE, glyph_zinorhebrew }, + { 0x1E95, glyph_zlinebelow }, + { 0xFF5A, glyph_zmonospace }, + { 0x305E, glyph_zohiragana }, + { 0x30BE, glyph_zokatakana }, + { 0x24B5, glyph_zparen }, + { 0x0290, glyph_zretroflexhook }, + { 0x01B6, glyph_zstroke }, + { 0x305A, glyph_zuhiragana }, + { 0x30BA, glyph_zukatakana }, +#else +#endif +}; /* tab_diffagl2uni */ + +/* + * Difference table of AGL version 2.0 - 1.2' - sorted by Unicode values + * + * Without Unicode values which map to multiple glyph names or which is + * contained in a Unicode sequence mapping to a single glyph name. + * This means, that all n:m entries are ignored! + * + * The multiple named Unicode values are listed in an extra table below. + * + */ +static const pdc_glyph_tab tab_uni2diffagl[] = +{ + { 0x0001, glyph_controlSTX }, + { 0x0002, glyph_controlSOT }, + { 0x0003, glyph_controlETX }, + { 0x0004, glyph_controlEOT }, + { 0x0005, glyph_controlENQ }, + { 0x0006, glyph_controlACK }, + { 0x0007, glyph_controlBEL }, + { 0x0008, glyph_controlBS }, + { 0x0009, glyph_controlHT }, + { 0x000A, glyph_controlLF }, + { 0x000B, glyph_controlVT }, + { 0x000C, glyph_controlFF }, + { 0x000D, glyph_controlCR }, + { 0x000E, glyph_controlSO }, + { 0x000F, glyph_controlSI }, + { 0x0010, glyph_controlDLE }, + { 0x0011, glyph_controlDC1 }, + { 0x0012, glyph_controlDC2 }, + { 0x0013, glyph_controlDC3 }, + { 0x0014, glyph_controlDC4 }, + { 0x0015, glyph_controlNAK }, + { 0x0016, glyph_controlSYN }, + { 0x0017, glyph_controlETB }, + { 0x0018, glyph_controlCAN }, + { 0x0019, glyph_controlEM }, + { 0x001A, glyph_controlSUB }, + { 0x001B, glyph_controlESC }, + { 0x001C, glyph_controlFS }, + { 0x001D, glyph_controlGS }, + { 0x001E, glyph_controlRS }, + { 0x001F, glyph_controlUS }, + { 0x0020, glyph_spacehackarabic }, + { 0x007C, glyph_verticalbar }, + { 0x007F, glyph_controlDEL }, + { 0x00A0, glyph_nonbreakingspace }, + { 0x00AD, glyph_softhyphen }, + { 0x00AF, glyph_overscore }, + { 0x00B5, glyph_mu1 }, + { 0x00B7, glyph_middot }, + { 0x010A, glyph_Cdot }, + { 0x010B, glyph_cdot }, + { 0x0110, glyph_Dslash }, + { 0x0111, glyph_dmacron }, + { 0x0116, glyph_Edot }, + { 0x0117, glyph_edot }, + { 0x0120, glyph_Gdot }, + { 0x0121, glyph_gdot }, + { 0x0122, glyph_Gcedilla }, + { 0x0123, glyph_gcedilla }, + { 0x0130, glyph_Idot }, + { 0x0136, glyph_Kcedilla }, + { 0x0137, glyph_kcedilla }, + { 0x013B, glyph_Lcedilla }, + { 0x013C, glyph_lcedilla }, + { 0x013F, glyph_Ldotaccent }, + { 0x0140, glyph_ldotaccent }, + { 0x0145, glyph_Ncedilla }, + { 0x0146, glyph_ncedilla }, + { 0x0149, glyph_quoterightn }, + { 0x0150, glyph_Odblacute }, + { 0x0151, glyph_odblacute }, + { 0x0156, glyph_Rcedilla }, + { 0x0157, glyph_rcedilla }, + { 0x0162, glyph_Tcedilla }, + { 0x0163, glyph_tcedilla }, + { 0x0170, glyph_Udblacute }, + { 0x0171, glyph_udblacute }, + { 0x017B, glyph_Zdot }, + { 0x017C, glyph_zdot }, + { 0x017F, glyph_slong }, + { 0x0180, glyph_bstroke }, + { 0x0181, glyph_Bhook }, + { 0x0182, glyph_Btopbar }, + { 0x0183, glyph_btopbar }, + { 0x0184, glyph_Tonesix }, + { 0x0185, glyph_tonesix }, + { 0x0186, glyph_Oopen }, + { 0x0187, glyph_Chook }, + { 0x0188, glyph_chook }, + { 0x0189, glyph_Dafrican }, + { 0x018A, glyph_Dhook }, + { 0x018B, glyph_Dtopbar }, + { 0x018C, glyph_dtopbar }, + { 0x018D, glyph_deltaturned }, + { 0x018E, glyph_Ereversed }, + { 0x018F, glyph_Schwa }, + { 0x0190, glyph_Eopen }, + { 0x0191, glyph_Fhook }, + { 0x0193, glyph_Ghook }, + { 0x0194, glyph_Gammaafrican }, + { 0x0195, glyph_hv }, + { 0x0196, glyph_Iotaafrican }, + { 0x0197, glyph_Istroke }, + { 0x0198, glyph_Khook }, + { 0x0199, glyph_khook }, + { 0x019A, glyph_lbar }, + { 0x019B, glyph_lambdastroke }, + { 0x019C, glyph_Mturned }, + { 0x019D, glyph_Nhookleft }, + { 0x019E, glyph_nlegrightlong }, + { 0x019F, glyph_Ocenteredtilde }, + { 0x01A2, glyph_Oi }, + { 0x01A3, glyph_oi }, + { 0x01A4, glyph_Phook }, + { 0x01A5, glyph_phook }, + { 0x01A6, glyph_yr }, + { 0x01A7, glyph_Tonetwo }, + { 0x01A8, glyph_tonetwo }, + { 0x01A9, glyph_Esh }, + { 0x01AA, glyph_eshreversedloop }, + { 0x01AB, glyph_tpalatalhook }, + { 0x01AC, glyph_Thook }, + { 0x01AD, glyph_thook }, + { 0x01AE, glyph_Tretroflexhook }, + { 0x01B1, glyph_Upsilonafrican }, + { 0x01B2, glyph_Vhook }, + { 0x01B3, glyph_Yhook }, + { 0x01B4, glyph_yhook }, + { 0x01B5, glyph_Zstroke }, + { 0x01B6, glyph_zstroke }, + { 0x01B7, glyph_Ezh }, + { 0x01B8, glyph_Ezhreversed }, + { 0x01B9, glyph_ezhreversed }, + { 0x01BA, glyph_ezhtail }, + { 0x01BB, glyph_twostroke }, + { 0x01BC, glyph_Tonefive }, + { 0x01BD, glyph_tonefive }, + { 0x01BE, glyph_glottalinvertedstroke }, + { 0x01BF, glyph_wynn }, + { 0x01C0, glyph_clickdental }, + { 0x01C1, glyph_clicklateral }, + { 0x01C2, glyph_clickalveolar }, + { 0x01C3, glyph_clickretroflex }, + { 0x01C4, glyph_DZcaron }, + { 0x01C5, glyph_Dzcaron }, + { 0x01C6, glyph_dzcaron }, + { 0x01C7, glyph_LJ }, + { 0x01C8, glyph_Lj }, + { 0x01C9, glyph_lj }, + { 0x01CA, glyph_NJ }, + { 0x01CB, glyph_Nj }, + { 0x01CC, glyph_nj }, + { 0x01CD, glyph_Acaron }, + { 0x01CE, glyph_acaron }, + { 0x01CF, glyph_Icaron }, + { 0x01D0, glyph_icaron }, + { 0x01D1, glyph_Ocaron }, + { 0x01D2, glyph_ocaron }, + { 0x01D3, glyph_Ucaron }, + { 0x01D4, glyph_ucaron }, + { 0x01D5, glyph_Udieresismacron }, + { 0x01D6, glyph_udieresismacron }, + { 0x01D7, glyph_Udieresisacute }, + { 0x01D8, glyph_udieresisacute }, + { 0x01D9, glyph_Udieresiscaron }, + { 0x01DA, glyph_udieresiscaron }, + { 0x01DB, glyph_Udieresisgrave }, + { 0x01DC, glyph_udieresisgrave }, + { 0x01DD, glyph_eturned }, + { 0x01DE, glyph_Adieresismacron }, + { 0x01DF, glyph_adieresismacron }, + { 0x01E0, glyph_Adotmacron }, + { 0x01E1, glyph_adotmacron }, + { 0x01E2, glyph_AEmacron }, + { 0x01E3, glyph_aemacron }, + { 0x01E4, glyph_Gstroke }, + { 0x01E5, glyph_gstroke }, + { 0x01E8, glyph_Kcaron }, + { 0x01E9, glyph_kcaron }, + { 0x01EA, glyph_Oogonek }, + { 0x01EB, glyph_oogonek }, + { 0x01EC, glyph_Oogonekmacron }, + { 0x01ED, glyph_oogonekmacron }, + { 0x01EE, glyph_Ezhcaron }, + { 0x01EF, glyph_ezhcaron }, + { 0x01F0, glyph_jcaron }, + { 0x01F1, glyph_DZ }, + { 0x01F2, glyph_Dz }, + { 0x01F3, glyph_dz }, + { 0x01F4, glyph_Gacute }, + { 0x01F5, glyph_gacute }, + { 0x01FE, glyph_Ostrokeacute }, + { 0x01FF, glyph_ostrokeacute }, + { 0x0200, glyph_Adblgrave }, + { 0x0201, glyph_adblgrave }, + { 0x0202, glyph_Ainvertedbreve }, + { 0x0203, glyph_ainvertedbreve }, + { 0x0204, glyph_Edblgrave }, + { 0x0205, glyph_edblgrave }, + { 0x0206, glyph_Einvertedbreve }, + { 0x0207, glyph_einvertedbreve }, + { 0x0208, glyph_Idblgrave }, + { 0x0209, glyph_idblgrave }, + { 0x020A, glyph_Iinvertedbreve }, + { 0x020B, glyph_iinvertedbreve }, + { 0x020C, glyph_Odblgrave }, + { 0x020D, glyph_odblgrave }, + { 0x020E, glyph_Oinvertedbreve }, + { 0x020F, glyph_oinvertedbreve }, + { 0x0210, glyph_Rdblgrave }, + { 0x0211, glyph_rdblgrave }, + { 0x0212, glyph_Rinvertedbreve }, + { 0x0213, glyph_rinvertedbreve }, + { 0x0214, glyph_Udblgrave }, + { 0x0215, glyph_udblgrave }, + { 0x0216, glyph_Uinvertedbreve }, + { 0x0217, glyph_uinvertedbreve }, + { 0x0250, glyph_aturned }, + { 0x0251, glyph_ascript }, + { 0x0252, glyph_ascriptturned }, + { 0x0253, glyph_bhook }, + { 0x0254, glyph_oopen }, + { 0x0255, glyph_ccurl }, + { 0x0256, glyph_dtail }, + { 0x0257, glyph_dhook }, + { 0x0258, glyph_ereversed }, + { 0x0259, glyph_schwa }, + { 0x025A, glyph_schwahook }, + { 0x025B, glyph_eopen }, + { 0x025C, glyph_eopenreversed }, + { 0x025D, glyph_eopenreversedhook }, + { 0x025E, glyph_eopenreversedclosed }, + { 0x025F, glyph_jdotlessstroke }, + { 0x0260, glyph_ghook }, + { 0x0261, glyph_gscript }, + { 0x0263, glyph_gammalatinsmall }, + { 0x0264, glyph_ramshorn }, + { 0x0265, glyph_hturned }, + { 0x0266, glyph_hhook }, + { 0x0267, glyph_henghook }, + { 0x0268, glyph_istroke }, + { 0x0269, glyph_iotalatin }, + { 0x026B, glyph_lmiddletilde }, + { 0x026C, glyph_lbelt }, + { 0x026D, glyph_lhookretroflex }, + { 0x026E, glyph_lezh }, + { 0x026F, glyph_mturned }, + { 0x0270, glyph_mlonglegturned }, + { 0x0271, glyph_mhook }, + { 0x0272, glyph_nhookleft }, + { 0x0273, glyph_nhookretroflex }, + { 0x0275, glyph_obarred }, + { 0x0277, glyph_omegalatinclosed }, + { 0x0278, glyph_philatin }, + { 0x0279, glyph_rturned }, + { 0x027A, glyph_rlonglegturned }, + { 0x027B, glyph_rhookturned }, + { 0x027C, glyph_rlongleg }, + { 0x027D, glyph_rhook }, + { 0x027E, glyph_rfishhook }, + { 0x027F, glyph_rfishhookreversed }, + { 0x0281, glyph_Rsmallinverted }, + { 0x0282, glyph_shook }, + { 0x0283, glyph_esh }, + { 0x0284, glyph_dotlessjstrokehook }, + { 0x0285, glyph_eshsquatreversed }, + { 0x0286, glyph_eshcurl }, + { 0x0287, glyph_tturned }, + { 0x0288, glyph_tretroflexhook }, + { 0x0289, glyph_ubar }, + { 0x028A, glyph_upsilonlatin }, + { 0x028B, glyph_vhook }, + { 0x028C, glyph_vturned }, + { 0x028D, glyph_wturned }, + { 0x028E, glyph_yturned }, + { 0x0290, glyph_zretroflexhook }, + { 0x0291, glyph_zcurl }, + { 0x0292, glyph_ezh }, + { 0x0293, glyph_ezhcurl }, + { 0x0294, glyph_glottalstop }, + { 0x0295, glyph_glottalstopreversed }, + { 0x0296, glyph_glottalstopinverted }, + { 0x0297, glyph_cstretched }, + { 0x0298, glyph_bilabialclick }, + { 0x029A, glyph_eopenclosed }, + { 0x029B, glyph_Gsmallhook }, + { 0x029D, glyph_jcrossedtail }, + { 0x029E, glyph_kturned }, + { 0x02A0, glyph_qhook }, + { 0x02A1, glyph_glottalstopstroke }, + { 0x02A2, glyph_glottalstopstrokereversed }, + { 0x02A3, glyph_dzaltone }, + { 0x02A4, glyph_dezh }, + { 0x02A5, glyph_dzcurl }, + { 0x02A6, glyph_ts }, + { 0x02A7, glyph_tesh }, + { 0x02A8, glyph_tccurl }, + { 0x02B0, glyph_hsuperior }, + { 0x02B1, glyph_hhooksuperior }, + { 0x02B2, glyph_jsuperior }, + { 0x02B4, glyph_rturnedsuperior }, + { 0x02B5, glyph_rhookturnedsuperior }, + { 0x02B6, glyph_Rsmallinvertedsuperior }, + { 0x02B7, glyph_wsuperior }, + { 0x02B8, glyph_ysuperior }, + { 0x02B9, glyph_primemod }, + { 0x02BA, glyph_dblprimemod }, + { 0x02BB, glyph_commaturnedmod }, + { 0x02BC, glyph_apostrophemod }, + { 0x02BD, glyph_commareversedmod }, + { 0x02BE, glyph_ringhalfright }, + { 0x02BF, glyph_ringhalfleft }, + { 0x02C0, glyph_glottalstopmod }, + { 0x02C1, glyph_glottalstopreversedmod }, + { 0x02C2, glyph_arrowheadleftmod }, + { 0x02C3, glyph_arrowheadrightmod }, + { 0x02C4, glyph_arrowheadupmod }, + { 0x02C5, glyph_arrowheaddownmod }, + { 0x02C8, glyph_verticallinemod }, + { 0x02CA, glyph_secondtonechinese }, + { 0x02CB, glyph_fourthtonechinese }, + { 0x02CC, glyph_verticallinelowmod }, + { 0x02CD, glyph_macronlowmod }, + { 0x02CE, glyph_gravelowmod }, + { 0x02CF, glyph_acutelowmod }, + { 0x02D0, glyph_colontriangularmod }, + { 0x02D1, glyph_colontriangularhalfmod }, + { 0x02D2, glyph_ringhalfrightcentered }, + { 0x02D3, glyph_ringhalfleftcentered }, + { 0x02D4, glyph_uptackmod }, + { 0x02D5, glyph_downtackmod }, + { 0x02D6, glyph_plusmod }, + { 0x02D7, glyph_minusmod }, + { 0x02DC, glyph_ilde }, + { 0x02DE, glyph_rhotichookmod }, + { 0x02E0, glyph_gammasuperior }, + { 0x02E3, glyph_xsuperior }, + { 0x02E4, glyph_glottalstopreversedsuperior }, + { 0x02E5, glyph_tonebarextrahighmod }, + { 0x02E6, glyph_tonebarhighmod }, + { 0x02E7, glyph_tonebarmidmod }, + { 0x02E8, glyph_tonebarlowmod }, + { 0x02E9, glyph_tonebarextralowmod }, + { 0x0300, glyph_gravecmb }, + { 0x0301, glyph_acutecmb }, + { 0x0302, glyph_circumflexcmb }, + { 0x0303, glyph_tildecmb }, + { 0x0304, glyph_macroncmb }, + { 0x0305, glyph_overlinecmb }, + { 0x0306, glyph_brevecmb }, + { 0x0307, glyph_dotaccentcmb }, + { 0x0308, glyph_dieresiscmb }, + { 0x0309, glyph_hookcmb }, + { 0x030A, glyph_ringcmb }, + { 0x030B, glyph_hungarumlautcmb }, + { 0x030C, glyph_caroncmb }, + { 0x030D, glyph_verticallineabovecmb }, + { 0x030E, glyph_dblverticallineabovecmb }, + { 0x030F, glyph_dblgravecmb }, + { 0x0310, glyph_candrabinducmb }, + { 0x0311, glyph_breveinvertedcmb }, + { 0x0312, glyph_commaturnedabovecmb }, + { 0x0313, glyph_commaabovecmb }, + { 0x0314, glyph_commareversedabovecmb }, + { 0x0315, glyph_commaaboverightcmb }, + { 0x0316, glyph_gravebelowcmb }, + { 0x0317, glyph_acutebelowcmb }, + { 0x0318, glyph_lefttackbelowcmb }, + { 0x0319, glyph_righttackbelowcmb }, + { 0x031A, glyph_leftangleabovecmb }, + { 0x031B, glyph_horncmb }, + { 0x031C, glyph_ringhalfleftbelowcmb }, + { 0x031D, glyph_uptackbelowcmb }, + { 0x031E, glyph_downtackbelowcmb }, + { 0x031F, glyph_plusbelowcmb }, + { 0x0320, glyph_minusbelowcmb }, + { 0x0321, glyph_hookpalatalizedbelowcmb }, + { 0x0322, glyph_hookretroflexbelowcmb }, + { 0x0323, glyph_dotbelowcmb }, + { 0x0324, glyph_dieresisbelowcmb }, + { 0x0325, glyph_ringbelowcmb }, + { 0x0327, glyph_cedillacmb }, + { 0x0328, glyph_ogonekcmb }, + { 0x0329, glyph_verticallinebelowcmb }, + { 0x032A, glyph_bridgebelowcmb }, + { 0x032B, glyph_dblarchinvertedbelowcmb }, + { 0x032C, glyph_caronbelowcmb }, + { 0x032D, glyph_circumflexbelowcmb }, + { 0x032E, glyph_brevebelowcmb }, + { 0x032F, glyph_breveinvertedbelowcmb }, + { 0x0330, glyph_tildebelowcmb }, + { 0x0331, glyph_macronbelowcmb }, + { 0x0332, glyph_lowlinecmb }, + { 0x0333, glyph_dbllowlinecmb }, + { 0x0334, glyph_tildeoverlaycmb }, + { 0x0335, glyph_strokeshortoverlaycmb }, + { 0x0336, glyph_strokelongoverlaycmb }, + { 0x0337, glyph_solidusshortoverlaycmb }, + { 0x0338, glyph_soliduslongoverlaycmb }, + { 0x0339, glyph_ringhalfrightbelowcmb }, + { 0x033A, glyph_bridgeinvertedbelowcmb }, + { 0x033B, glyph_squarebelowcmb }, + { 0x033C, glyph_seagullbelowcmb }, + { 0x033D, glyph_xabovecmb }, + { 0x033E, glyph_tildeverticalcmb }, + { 0x033F, glyph_dbloverlinecmb }, + { 0x0340, glyph_gravetonecmb }, + { 0x0341, glyph_acutetonecmb }, + { 0x0342, glyph_perispomenigreekcmb }, + { 0x0343, glyph_koroniscmb }, + { 0x0344, glyph_dialytikatonoscmb }, + { 0x0345, glyph_ypogegrammenigreekcmb }, + { 0x0360, glyph_tildedoublecmb }, + { 0x0361, glyph_breveinverteddoublecmb }, + { 0x0374, glyph_numeralsigngreek }, + { 0x0375, glyph_numeralsignlowergreek }, + { 0x037A, glyph_ypogegrammeni }, + { 0x037E, glyph_questiongreek }, + { 0x0385, glyph_dialytikatonos }, + { 0x03C2, glyph_sigmafinal }, + { 0x03D0, glyph_betasymbolgreek }, + { 0x03D1, glyph_thetasymbolgreek }, + { 0x03D2, glyph_Upsilonhooksymbol }, + { 0x03D3, glyph_Upsilonacutehooksymbolgreek }, + { 0x03D4, glyph_Upsilondieresishooksymbolgreek }, + { 0x03D5, glyph_phisymbolgreek }, + { 0x03D6, glyph_pisymbolgreek }, + { 0x03DA, glyph_Stigmagreek }, + { 0x03DC, glyph_Digammagreek }, + { 0x03DE, glyph_Koppagreek }, + { 0x03E0, glyph_Sampigreek }, + { 0x03E2, glyph_Sheicoptic }, + { 0x03E3, glyph_sheicoptic }, + { 0x03E4, glyph_Feicoptic }, + { 0x03E5, glyph_feicoptic }, + { 0x03E6, glyph_Kheicoptic }, + { 0x03E7, glyph_kheicoptic }, + { 0x03E8, glyph_Horicoptic }, + { 0x03E9, glyph_horicoptic }, + { 0x03EA, glyph_Gangiacoptic }, + { 0x03EB, glyph_gangiacoptic }, + { 0x03EC, glyph_Shimacoptic }, + { 0x03ED, glyph_shimacoptic }, + { 0x03EE, glyph_Deicoptic }, + { 0x03EF, glyph_deicoptic }, + { 0x03F0, glyph_kappasymbolgreek }, + { 0x03F1, glyph_rhosymbolgreek }, + { 0x03F2, glyph_sigmalunatesymbolgreek }, + { 0x03F3, glyph_yotgreek }, + { 0x0401, glyph_Iocyrillic }, + { 0x0402, glyph_Djecyrillic }, + { 0x0403, glyph_Gjecyrillic }, + { 0x0404, glyph_Ecyrillic }, + { 0x0405, glyph_Dzecyrillic }, + { 0x0406, glyph_Icyrillic }, + { 0x0407, glyph_Yicyrillic }, + { 0x0408, glyph_Jecyrillic }, + { 0x0409, glyph_Ljecyrillic }, + { 0x040A, glyph_Njecyrillic }, + { 0x040B, glyph_Tshecyrillic }, + { 0x040C, glyph_Kjecyrillic }, + { 0x040E, glyph_Ushortcyrillic }, + { 0x040F, glyph_Dzhecyrillic }, + { 0x0410, glyph_Acyrillic }, + { 0x0411, glyph_Becyrillic }, + { 0x0412, glyph_Vecyrillic }, + { 0x0413, glyph_Gecyrillic }, + { 0x0414, glyph_Decyrillic }, + { 0x0415, glyph_Iecyrillic }, + { 0x0416, glyph_Zhecyrillic }, + { 0x0417, glyph_Zecyrillic }, + { 0x0418, glyph_Iicyrillic }, + { 0x0419, glyph_Iishortcyrillic }, + { 0x041A, glyph_Kacyrillic }, + { 0x041B, glyph_Elcyrillic }, + { 0x041C, glyph_Emcyrillic }, + { 0x041D, glyph_Encyrillic }, + { 0x041E, glyph_Ocyrillic }, + { 0x041F, glyph_Pecyrillic }, + { 0x0420, glyph_Ercyrillic }, + { 0x0421, glyph_Escyrillic }, + { 0x0422, glyph_Tecyrillic }, + { 0x0423, glyph_Ucyrillic }, + { 0x0424, glyph_Efcyrillic }, + { 0x0425, glyph_Khacyrillic }, + { 0x0426, glyph_Tsecyrillic }, + { 0x0427, glyph_Checyrillic }, + { 0x0428, glyph_Shacyrillic }, + { 0x0429, glyph_Shchacyrillic }, + { 0x042A, glyph_Hardsigncyrillic }, + { 0x042B, glyph_Yericyrillic }, + { 0x042C, glyph_Softsigncyrillic }, + { 0x042D, glyph_Ereversedcyrillic }, + { 0x042E, glyph_IUcyrillic }, + { 0x042F, glyph_IAcyrillic }, + { 0x0430, glyph_acyrillic }, + { 0x0431, glyph_becyrillic }, + { 0x0432, glyph_vecyrillic }, + { 0x0433, glyph_gecyrillic }, + { 0x0434, glyph_decyrillic }, + { 0x0435, glyph_iecyrillic }, + { 0x0436, glyph_zhecyrillic }, + { 0x0437, glyph_zecyrillic }, + { 0x0438, glyph_iicyrillic }, + { 0x0439, glyph_iishortcyrillic }, + { 0x043A, glyph_kacyrillic }, + { 0x043B, glyph_elcyrillic }, + { 0x043C, glyph_emcyrillic }, + { 0x043D, glyph_encyrillic }, + { 0x043E, glyph_ocyrillic }, + { 0x043F, glyph_pecyrillic }, + { 0x0440, glyph_ercyrillic }, + { 0x0441, glyph_escyrillic }, + { 0x0442, glyph_tecyrillic }, + { 0x0443, glyph_ucyrillic }, + { 0x0444, glyph_efcyrillic }, + { 0x0445, glyph_khacyrillic }, + { 0x0446, glyph_tsecyrillic }, + { 0x0447, glyph_checyrillic }, + { 0x0448, glyph_shacyrillic }, + { 0x0449, glyph_shchacyrillic }, + { 0x044A, glyph_hardsigncyrillic }, + { 0x044B, glyph_yericyrillic }, + { 0x044C, glyph_softsigncyrillic }, + { 0x044D, glyph_ereversedcyrillic }, + { 0x044E, glyph_iucyrillic }, + { 0x044F, glyph_iacyrillic }, + { 0x0451, glyph_iocyrillic }, + { 0x0452, glyph_djecyrillic }, + { 0x0453, glyph_gjecyrillic }, + { 0x0454, glyph_ecyrillic }, + { 0x0455, glyph_dzecyrillic }, + { 0x0456, glyph_icyrillic }, + { 0x0457, glyph_yicyrillic }, + { 0x0458, glyph_jecyrillic }, + { 0x0459, glyph_ljecyrillic }, + { 0x045A, glyph_njecyrillic }, + { 0x045B, glyph_tshecyrillic }, + { 0x045C, glyph_kjecyrillic }, + { 0x045E, glyph_ushortcyrillic }, + { 0x045F, glyph_dzhecyrillic }, + { 0x0460, glyph_Omegacyrillic }, + { 0x0461, glyph_omegacyrillic }, + { 0x0462, glyph_Yatcyrillic }, + { 0x0463, glyph_yatcyrillic }, + { 0x0464, glyph_Eiotifiedcyrillic }, + { 0x0465, glyph_eiotifiedcyrillic }, + { 0x0466, glyph_Yuslittlecyrillic }, + { 0x0467, glyph_yuslittlecyrillic }, + { 0x0468, glyph_Yuslittleiotifiedcyrillic }, + { 0x0469, glyph_yuslittleiotifiedcyrillic }, + { 0x046A, glyph_Yusbigcyrillic }, + { 0x046B, glyph_yusbigcyrillic }, + { 0x046C, glyph_Yusbigiotifiedcyrillic }, + { 0x046D, glyph_yusbigiotifiedcyrillic }, + { 0x046E, glyph_Ksicyrillic }, + { 0x046F, glyph_ksicyrillic }, + { 0x0470, glyph_Psicyrillic }, + { 0x0471, glyph_psicyrillic }, + { 0x0472, glyph_Fitacyrillic }, + { 0x0473, glyph_fitacyrillic }, + { 0x0474, glyph_Izhitsacyrillic }, + { 0x0475, glyph_izhitsacyrillic }, + { 0x0476, glyph_Izhitsadblgravecyrillic }, + { 0x0477, glyph_izhitsadblgravecyrillic }, + { 0x0478, glyph_Ukcyrillic }, + { 0x0479, glyph_ukcyrillic }, + { 0x047A, glyph_Omegaroundcyrillic }, + { 0x047B, glyph_omegaroundcyrillic }, + { 0x047C, glyph_Omegatitlocyrillic }, + { 0x047D, glyph_omegatitlocyrillic }, + { 0x047E, glyph_Otcyrillic }, + { 0x047F, glyph_otcyrillic }, + { 0x0480, glyph_Koppacyrillic }, + { 0x0481, glyph_koppacyrillic }, + { 0x0482, glyph_thousandcyrillic }, + { 0x0483, glyph_titlocyrilliccmb }, + { 0x0484, glyph_palatalizationcyrilliccmb }, + { 0x0485, glyph_dasiapneumatacyrilliccmb }, + { 0x0486, glyph_psilipneumatacyrilliccmb }, + { 0x0490, glyph_Gheupturncyrillic }, + { 0x0491, glyph_gheupturncyrillic }, + { 0x0492, glyph_Ghestrokecyrillic }, + { 0x0493, glyph_ghestrokecyrillic }, + { 0x0494, glyph_Ghemiddlehookcyrillic }, + { 0x0495, glyph_ghemiddlehookcyrillic }, + { 0x0496, glyph_Zhedescendercyrillic }, + { 0x0497, glyph_zhedescendercyrillic }, + { 0x0498, glyph_Zedescendercyrillic }, + { 0x0499, glyph_zedescendercyrillic }, + { 0x049A, glyph_Kadescendercyrillic }, + { 0x049B, glyph_kadescendercyrillic }, + { 0x049C, glyph_Kaverticalstrokecyrillic }, + { 0x049D, glyph_kaverticalstrokecyrillic }, + { 0x049E, glyph_Kastrokecyrillic }, + { 0x049F, glyph_kastrokecyrillic }, + { 0x04A0, glyph_Kabashkircyrillic }, + { 0x04A1, glyph_kabashkircyrillic }, + { 0x04A2, glyph_Endescendercyrillic }, + { 0x04A3, glyph_endescendercyrillic }, + { 0x04A4, glyph_Enghecyrillic }, + { 0x04A5, glyph_enghecyrillic }, + { 0x04A6, glyph_Pemiddlehookcyrillic }, + { 0x04A7, glyph_pemiddlehookcyrillic }, + { 0x04A8, glyph_Haabkhasiancyrillic }, + { 0x04A9, glyph_haabkhasiancyrillic }, + { 0x04AA, glyph_Esdescendercyrillic }, + { 0x04AB, glyph_esdescendercyrillic }, + { 0x04AC, glyph_Tedescendercyrillic }, + { 0x04AD, glyph_tedescendercyrillic }, + { 0x04AE, glyph_Ustraightcyrillic }, + { 0x04AF, glyph_ustraightcyrillic }, + { 0x04B0, glyph_Ustraightstrokecyrillic }, + { 0x04B1, glyph_ustraightstrokecyrillic }, + { 0x04B2, glyph_Hadescendercyrillic }, + { 0x04B3, glyph_hadescendercyrillic }, + { 0x04B4, glyph_Tetsecyrillic }, + { 0x04B5, glyph_tetsecyrillic }, + { 0x04B6, glyph_Chedescendercyrillic }, + { 0x04B7, glyph_chedescendercyrillic }, + { 0x04B8, glyph_Cheverticalstrokecyrillic }, + { 0x04B9, glyph_cheverticalstrokecyrillic }, + { 0x04BA, glyph_Shhacyrillic }, + { 0x04BB, glyph_shhacyrillic }, + { 0x04BC, glyph_Cheabkhasiancyrillic }, + { 0x04BD, glyph_cheabkhasiancyrillic }, + { 0x04BE, glyph_Chedescenderabkhasiancyrillic }, + { 0x04BF, glyph_chedescenderabkhasiancyrillic }, + { 0x04C0, glyph_palochkacyrillic }, + { 0x04C1, glyph_Zhebrevecyrillic }, + { 0x04C2, glyph_zhebrevecyrillic }, + { 0x04C3, glyph_Kahookcyrillic }, + { 0x04C4, glyph_kahookcyrillic }, + { 0x04C7, glyph_Enhookcyrillic }, + { 0x04C8, glyph_enhookcyrillic }, + { 0x04CB, glyph_Chekhakassiancyrillic }, + { 0x04CC, glyph_chekhakassiancyrillic }, + { 0x04D0, glyph_Abrevecyrillic }, + { 0x04D1, glyph_abrevecyrillic }, + { 0x04D2, glyph_Adieresiscyrillic }, + { 0x04D3, glyph_adieresiscyrillic }, + { 0x04D4, glyph_Aiecyrillic }, + { 0x04D5, glyph_aiecyrillic }, + { 0x04D6, glyph_Iebrevecyrillic }, + { 0x04D7, glyph_iebrevecyrillic }, + { 0x04D8, glyph_Schwacyrillic }, + { 0x04D9, glyph_schwacyrillic }, + { 0x04DA, glyph_Schwadieresiscyrillic }, + { 0x04DB, glyph_schwadieresiscyrillic }, + { 0x04DC, glyph_Zhedieresiscyrillic }, + { 0x04DD, glyph_zhedieresiscyrillic }, + { 0x04DE, glyph_Zedieresiscyrillic }, + { 0x04DF, glyph_zedieresiscyrillic }, + { 0x04E0, glyph_Dzeabkhasiancyrillic }, + { 0x04E1, glyph_dzeabkhasiancyrillic }, + { 0x04E2, glyph_Imacroncyrillic }, + { 0x04E3, glyph_imacroncyrillic }, + { 0x04E4, glyph_Idieresiscyrillic }, + { 0x04E5, glyph_idieresiscyrillic }, + { 0x04E6, glyph_Odieresiscyrillic }, + { 0x04E7, glyph_odieresiscyrillic }, + { 0x04E8, glyph_Obarredcyrillic }, + { 0x04E9, glyph_obarredcyrillic }, + { 0x04EA, glyph_Obarreddieresiscyrillic }, + { 0x04EB, glyph_obarreddieresiscyrillic }, + { 0x04EE, glyph_Umacroncyrillic }, + { 0x04EF, glyph_umacroncyrillic }, + { 0x04F0, glyph_Udieresiscyrillic }, + { 0x04F1, glyph_udieresiscyrillic }, + { 0x04F2, glyph_Uhungarumlautcyrillic }, + { 0x04F3, glyph_uhungarumlautcyrillic }, + { 0x04F4, glyph_Chedieresiscyrillic }, + { 0x04F5, glyph_chedieresiscyrillic }, + { 0x04F8, glyph_Yerudieresiscyrillic }, + { 0x04F9, glyph_yerudieresiscyrillic }, + { 0x0531, glyph_Aybarmenian }, + { 0x0532, glyph_Benarmenian }, + { 0x0533, glyph_Gimarmenian }, + { 0x0534, glyph_Daarmenian }, + { 0x0535, glyph_Echarmenian }, + { 0x0536, glyph_Zaarmenian }, + { 0x0537, glyph_Eharmenian }, + { 0x0538, glyph_Etarmenian }, + { 0x0539, glyph_Toarmenian }, + { 0x053A, glyph_Zhearmenian }, + { 0x053B, glyph_Iniarmenian }, + { 0x053C, glyph_Liwnarmenian }, + { 0x053D, glyph_Xeharmenian }, + { 0x053E, glyph_Caarmenian }, + { 0x053F, glyph_Kenarmenian }, + { 0x0540, glyph_Hoarmenian }, + { 0x0541, glyph_Jaarmenian }, + { 0x0542, glyph_Ghadarmenian }, + { 0x0543, glyph_Cheharmenian }, + { 0x0544, glyph_Menarmenian }, + { 0x0545, glyph_Yiarmenian }, + { 0x0546, glyph_Nowarmenian }, + { 0x0547, glyph_Shaarmenian }, + { 0x0548, glyph_Voarmenian }, + { 0x0549, glyph_Chaarmenian }, + { 0x054A, glyph_Peharmenian }, + { 0x054B, glyph_Jheharmenian }, + { 0x054C, glyph_Raarmenian }, + { 0x054D, glyph_Seharmenian }, + { 0x054E, glyph_Vewarmenian }, + { 0x054F, glyph_Tiwnarmenian }, + { 0x0550, glyph_Reharmenian }, + { 0x0551, glyph_Coarmenian }, + { 0x0552, glyph_Yiwnarmenian }, + { 0x0553, glyph_Piwrarmenian }, + { 0x0554, glyph_Keharmenian }, + { 0x0555, glyph_Oharmenian }, + { 0x0556, glyph_Feharmenian }, + { 0x0559, glyph_ringhalfleftarmenian }, + { 0x055A, glyph_apostrophearmenian }, + { 0x055B, glyph_emphasismarkarmenian }, + { 0x055C, glyph_exclamarmenian }, + { 0x055D, glyph_commaarmenian }, + { 0x055E, glyph_questionarmenian }, + { 0x055F, glyph_abbreviationmarkarmenian }, + { 0x0561, glyph_aybarmenian }, + { 0x0562, glyph_benarmenian }, + { 0x0563, glyph_gimarmenian }, + { 0x0564, glyph_daarmenian }, + { 0x0565, glyph_echarmenian }, + { 0x0566, glyph_zaarmenian }, + { 0x0567, glyph_eharmenian }, + { 0x0568, glyph_etarmenian }, + { 0x0569, glyph_toarmenian }, + { 0x056A, glyph_zhearmenian }, + { 0x056B, glyph_iniarmenian }, + { 0x056C, glyph_liwnarmenian }, + { 0x056D, glyph_xeharmenian }, + { 0x056E, glyph_caarmenian }, + { 0x056F, glyph_kenarmenian }, + { 0x0570, glyph_hoarmenian }, + { 0x0571, glyph_jaarmenian }, + { 0x0572, glyph_ghadarmenian }, + { 0x0573, glyph_cheharmenian }, + { 0x0574, glyph_menarmenian }, + { 0x0575, glyph_yiarmenian }, + { 0x0576, glyph_nowarmenian }, + { 0x0577, glyph_shaarmenian }, + { 0x0578, glyph_voarmenian }, + { 0x0579, glyph_chaarmenian }, + { 0x057A, glyph_peharmenian }, + { 0x057B, glyph_jheharmenian }, + { 0x057C, glyph_raarmenian }, + { 0x057D, glyph_seharmenian }, + { 0x057E, glyph_vewarmenian }, + { 0x057F, glyph_tiwnarmenian }, + { 0x0580, glyph_reharmenian }, + { 0x0581, glyph_coarmenian }, + { 0x0582, glyph_yiwnarmenian }, + { 0x0583, glyph_piwrarmenian }, + { 0x0584, glyph_keharmenian }, + { 0x0585, glyph_oharmenian }, + { 0x0586, glyph_feharmenian }, + { 0x0587, glyph_echyiwnarmenian }, + { 0x0589, glyph_periodarmenian }, + { 0x0592, glyph_segoltahebrew }, + { 0x0593, glyph_shalshelethebrew }, + { 0x0594, glyph_zaqefqatanhebrew }, + { 0x0595, glyph_zaqefgadolhebrew }, + { 0x0598, glyph_zarqahebrew }, + { 0x0599, glyph_pashtahebrew }, + { 0x059A, glyph_yetivhebrew }, + { 0x059C, glyph_gereshaccenthebrew }, + { 0x059D, glyph_gereshmuqdamhebrew }, + { 0x059E, glyph_gershayimaccenthebrew }, + { 0x059F, glyph_qarneyparahebrew }, + { 0x05A0, glyph_telishagedolahebrew }, + { 0x05A1, glyph_pazerhebrew }, + { 0x05A8, glyph_qadmahebrew }, + { 0x05A9, glyph_telishaqetanahebrew }, + { 0x05AB, glyph_olehebrew }, + { 0x05AC, glyph_iluyhebrew }, + { 0x05AD, glyph_dehihebrew }, + { 0x05AE, glyph_zinorhebrew }, + { 0x05AF, glyph_masoracirclehebrew }, + { 0x05BE, glyph_maqafhebrew }, + { 0x05C0, glyph_paseqhebrew }, + { 0x05C1, glyph_shindothebrew }, + { 0x05C2, glyph_sindothebrew }, + { 0x05C3, glyph_sofpasuqhebrew }, + { 0x05C4, glyph_upperdothebrew }, + { 0x05F0, glyph_vavvavhebrew }, + { 0x05F1, glyph_vavyodhebrew }, + { 0x05F2, glyph_yodyodhebrew }, + { 0x05F3, glyph_gereshhebrew }, + { 0x05F4, glyph_gershayimhebrew }, + { 0x060C, glyph_commaarabic }, + { 0x061B, glyph_semicolonarabic }, + { 0x061F, glyph_questionarabic }, + { 0x0622, glyph_alefmaddaabovearabic }, + { 0x0623, glyph_alefhamzaabovearabic }, + { 0x0624, glyph_wawhamzaabovearabic }, + { 0x0625, glyph_alefhamzabelowarabic }, + { 0x0626, glyph_yehhamzaabovearabic }, + { 0x0627, glyph_alefarabic }, + { 0x0628, glyph_beharabic }, + { 0x0629, glyph_tehmarbutaarabic }, + { 0x062A, glyph_teharabic }, + { 0x062B, glyph_theharabic }, + { 0x062C, glyph_jeemarabic }, + { 0x062D, glyph_haharabic }, + { 0x062E, glyph_khaharabic }, + { 0x062F, glyph_dalarabic }, + { 0x0630, glyph_thalarabic }, + { 0x0631, glyph_reharabic }, + { 0x0632, glyph_zainarabic }, + { 0x0633, glyph_seenarabic }, + { 0x0634, glyph_sheenarabic }, + { 0x0635, glyph_sadarabic }, + { 0x0636, glyph_dadarabic }, + { 0x0637, glyph_taharabic }, + { 0x0638, glyph_zaharabic }, + { 0x0639, glyph_ainarabic }, + { 0x063A, glyph_ghainarabic }, + { 0x0641, glyph_feharabic }, + { 0x0642, glyph_qafarabic }, + { 0x0643, glyph_kafarabic }, + { 0x0644, glyph_lamarabic }, + { 0x0645, glyph_meemarabic }, + { 0x0646, glyph_noonarabic }, + { 0x0647, glyph_heharabic }, + { 0x0648, glyph_wawarabic }, + { 0x0649, glyph_alefmaksuraarabic }, + { 0x064A, glyph_yeharabic }, + { 0x064B, glyph_fathatanarabic }, + { 0x064D, glyph_kasratanarabic }, + { 0x0650, glyph_kasraarabic }, + { 0x0651, glyph_shaddaarabic }, + { 0x0652, glyph_sukunarabic }, + { 0x066A, glyph_percentarabic }, + { 0x0679, glyph_tteharabic }, + { 0x067E, glyph_peharabic }, + { 0x0686, glyph_tcheharabic }, + { 0x0688, glyph_ddalarabic }, + { 0x0691, glyph_rreharabic }, + { 0x0698, glyph_jeharabic }, + { 0x06A4, glyph_veharabic }, + { 0x06AF, glyph_gafarabic }, + { 0x06BA, glyph_noonghunnaarabic }, + { 0x06D1, glyph_yehthreedotsbelowarabic }, + { 0x06D2, glyph_yehbarreearabic }, + { 0x06F0, glyph_zeropersian }, + { 0x06F1, glyph_onepersian }, + { 0x06F2, glyph_twopersian }, + { 0x06F3, glyph_threepersian }, + { 0x06F4, glyph_fourpersian }, + { 0x06F5, glyph_fivepersian }, + { 0x06F6, glyph_sixpersian }, + { 0x06F7, glyph_sevenpersian }, + { 0x06F8, glyph_eightpersian }, + { 0x06F9, glyph_ninepersian }, + { 0x0901, glyph_candrabindudeva }, + { 0x0902, glyph_anusvaradeva }, + { 0x0903, glyph_visargadeva }, + { 0x0905, glyph_adeva }, + { 0x0906, glyph_aadeva }, + { 0x0907, glyph_ideva }, + { 0x0908, glyph_iideva }, + { 0x0909, glyph_udeva }, + { 0x090A, glyph_uudeva }, + { 0x090B, glyph_rvocalicdeva }, + { 0x090C, glyph_lvocalicdeva }, + { 0x090D, glyph_ecandradeva }, + { 0x090E, glyph_eshortdeva }, + { 0x090F, glyph_edeva }, + { 0x0910, glyph_aideva }, + { 0x0911, glyph_ocandradeva }, + { 0x0912, glyph_oshortdeva }, + { 0x0913, glyph_odeva }, + { 0x0914, glyph_audeva }, + { 0x0915, glyph_kadeva }, + { 0x0916, glyph_khadeva }, + { 0x0917, glyph_gadeva }, + { 0x0918, glyph_ghadeva }, + { 0x0919, glyph_ngadeva }, + { 0x091A, glyph_cadeva }, + { 0x091B, glyph_chadeva }, + { 0x091C, glyph_jadeva }, + { 0x091D, glyph_jhadeva }, + { 0x091E, glyph_nyadeva }, + { 0x091F, glyph_ttadeva }, + { 0x0920, glyph_tthadeva }, + { 0x0921, glyph_ddadeva }, + { 0x0922, glyph_ddhadeva }, + { 0x0923, glyph_nnadeva }, + { 0x0924, glyph_tadeva }, + { 0x0925, glyph_thadeva }, + { 0x0926, glyph_dadeva }, + { 0x0927, glyph_dhadeva }, + { 0x0928, glyph_nadeva }, + { 0x0929, glyph_nnnadeva }, + { 0x092A, glyph_padeva }, + { 0x092B, glyph_phadeva }, + { 0x092C, glyph_badeva }, + { 0x092D, glyph_bhadeva }, + { 0x092E, glyph_madeva }, + { 0x092F, glyph_yadeva }, + { 0x0930, glyph_radeva }, + { 0x0931, glyph_rradeva }, + { 0x0932, glyph_ladeva }, + { 0x0933, glyph_lladeva }, + { 0x0934, glyph_llladeva }, + { 0x0935, glyph_vadeva }, + { 0x0936, glyph_shadeva }, + { 0x0937, glyph_ssadeva }, + { 0x0938, glyph_sadeva }, + { 0x0939, glyph_hadeva }, + { 0x093C, glyph_nuktadeva }, + { 0x093D, glyph_avagrahadeva }, + { 0x093E, glyph_aavowelsigndeva }, + { 0x093F, glyph_ivowelsigndeva }, + { 0x0940, glyph_iivowelsigndeva }, + { 0x0941, glyph_uvowelsigndeva }, + { 0x0942, glyph_uuvowelsigndeva }, + { 0x0943, glyph_rvocalicvowelsigndeva }, + { 0x0944, glyph_rrvocalicvowelsigndeva }, + { 0x0945, glyph_ecandravowelsigndeva }, + { 0x0946, glyph_eshortvowelsigndeva }, + { 0x0947, glyph_evowelsigndeva }, + { 0x0948, glyph_aivowelsigndeva }, + { 0x0949, glyph_ocandravowelsigndeva }, + { 0x094A, glyph_oshortvowelsigndeva }, + { 0x094B, glyph_ovowelsigndeva }, + { 0x094C, glyph_auvowelsigndeva }, + { 0x094D, glyph_viramadeva }, + { 0x0950, glyph_omdeva }, + { 0x0951, glyph_udattadeva }, + { 0x0952, glyph_anudattadeva }, + { 0x0953, glyph_gravedeva }, + { 0x0954, glyph_acutedeva }, + { 0x0958, glyph_qadeva }, + { 0x0959, glyph_khhadeva }, + { 0x095A, glyph_ghhadeva }, + { 0x095B, glyph_zadeva }, + { 0x095C, glyph_dddhadeva }, + { 0x095D, glyph_rhadeva }, + { 0x095E, glyph_fadeva }, + { 0x095F, glyph_yyadeva }, + { 0x0960, glyph_rrvocalicdeva }, + { 0x0961, glyph_llvocalicdeva }, + { 0x0962, glyph_lvocalicvowelsigndeva }, + { 0x0963, glyph_llvocalicvowelsigndeva }, + { 0x0964, glyph_danda }, + { 0x0965, glyph_dbldanda }, + { 0x0966, glyph_zerodeva }, + { 0x0967, glyph_onedeva }, + { 0x0968, glyph_twodeva }, + { 0x0969, glyph_threedeva }, + { 0x096A, glyph_fourdeva }, + { 0x096B, glyph_fivedeva }, + { 0x096C, glyph_sixdeva }, + { 0x096D, glyph_sevendeva }, + { 0x096E, glyph_eightdeva }, + { 0x096F, glyph_ninedeva }, + { 0x0970, glyph_abbreviationsigndeva }, + { 0x0981, glyph_candrabindubengali }, + { 0x0982, glyph_anusvarabengali }, + { 0x0983, glyph_visargabengali }, + { 0x0985, glyph_abengali }, + { 0x0986, glyph_aabengali }, + { 0x0987, glyph_ibengali }, + { 0x0988, glyph_iibengali }, + { 0x0989, glyph_ubengali }, + { 0x098A, glyph_uubengali }, + { 0x098B, glyph_rvocalicbengali }, + { 0x098C, glyph_lvocalicbengali }, + { 0x098F, glyph_ebengali }, + { 0x0990, glyph_aibengali }, + { 0x0993, glyph_obengali }, + { 0x0994, glyph_aubengali }, + { 0x0995, glyph_kabengali }, + { 0x0996, glyph_khabengali }, + { 0x0997, glyph_gabengali }, + { 0x0998, glyph_ghabengali }, + { 0x0999, glyph_ngabengali }, + { 0x099A, glyph_cabengali }, + { 0x099B, glyph_chabengali }, + { 0x099C, glyph_jabengali }, + { 0x099D, glyph_jhabengali }, + { 0x099E, glyph_nyabengali }, + { 0x099F, glyph_ttabengali }, + { 0x09A0, glyph_tthabengali }, + { 0x09A1, glyph_ddabengali }, + { 0x09A2, glyph_ddhabengali }, + { 0x09A3, glyph_nnabengali }, + { 0x09A4, glyph_tabengali }, + { 0x09A5, glyph_thabengali }, + { 0x09A6, glyph_dabengali }, + { 0x09A7, glyph_dhabengali }, + { 0x09A8, glyph_nabengali }, + { 0x09AA, glyph_pabengali }, + { 0x09AB, glyph_phabengali }, + { 0x09AC, glyph_babengali }, + { 0x09AD, glyph_bhabengali }, + { 0x09AE, glyph_mabengali }, + { 0x09AF, glyph_yabengali }, + { 0x09B0, glyph_rabengali }, + { 0x09B2, glyph_labengali }, + { 0x09B6, glyph_shabengali }, + { 0x09B7, glyph_ssabengali }, + { 0x09B8, glyph_sabengali }, + { 0x09B9, glyph_habengali }, + { 0x09BC, glyph_nuktabengali }, + { 0x09BE, glyph_aavowelsignbengali }, + { 0x09BF, glyph_ivowelsignbengali }, + { 0x09C0, glyph_iivowelsignbengali }, + { 0x09C1, glyph_uvowelsignbengali }, + { 0x09C2, glyph_uuvowelsignbengali }, + { 0x09C3, glyph_rvocalicvowelsignbengali }, + { 0x09C4, glyph_rrvocalicvowelsignbengali }, + { 0x09C7, glyph_evowelsignbengali }, + { 0x09C8, glyph_aivowelsignbengali }, + { 0x09CB, glyph_ovowelsignbengali }, + { 0x09CC, glyph_auvowelsignbengali }, + { 0x09CD, glyph_viramabengali }, + { 0x09D7, glyph_aulengthmarkbengali }, + { 0x09DC, glyph_rrabengali }, + { 0x09DD, glyph_rhabengali }, + { 0x09DF, glyph_yyabengali }, + { 0x09E0, glyph_rrvocalicbengali }, + { 0x09E1, glyph_llvocalicbengali }, + { 0x09E2, glyph_lvocalicvowelsignbengali }, + { 0x09E3, glyph_llvocalicvowelsignbengali }, + { 0x09E6, glyph_zerobengali }, + { 0x09E7, glyph_onebengali }, + { 0x09E8, glyph_twobengali }, + { 0x09E9, glyph_threebengali }, + { 0x09EA, glyph_fourbengali }, + { 0x09EB, glyph_fivebengali }, + { 0x09EC, glyph_sixbengali }, + { 0x09ED, glyph_sevenbengali }, + { 0x09EE, glyph_eightbengali }, + { 0x09EF, glyph_ninebengali }, + { 0x09F0, glyph_ramiddlediagonalbengali }, + { 0x09F1, glyph_ralowerdiagonalbengali }, + { 0x09F2, glyph_rupeemarkbengali }, + { 0x09F3, glyph_rupeesignbengali }, + { 0x09F4, glyph_onenumeratorbengali }, + { 0x09F5, glyph_twonumeratorbengali }, + { 0x09F6, glyph_threenumeratorbengali }, + { 0x09F7, glyph_fournumeratorbengali }, + { 0x09F8, glyph_denominatorminusonenumeratorbengali }, + { 0x09F9, glyph_sixteencurrencydenominatorbengali }, + { 0x09FA, glyph_issharbengali }, + { 0x0A02, glyph_bindigurmukhi }, + { 0x0A05, glyph_agurmukhi }, + { 0x0A06, glyph_aagurmukhi }, + { 0x0A07, glyph_igurmukhi }, + { 0x0A08, glyph_iigurmukhi }, + { 0x0A09, glyph_ugurmukhi }, + { 0x0A0A, glyph_uugurmukhi }, + { 0x0A0F, glyph_eegurmukhi }, + { 0x0A10, glyph_aigurmukhi }, + { 0x0A13, glyph_oogurmukhi }, + { 0x0A14, glyph_augurmukhi }, + { 0x0A15, glyph_kagurmukhi }, + { 0x0A16, glyph_khagurmukhi }, + { 0x0A17, glyph_gagurmukhi }, + { 0x0A18, glyph_ghagurmukhi }, + { 0x0A19, glyph_ngagurmukhi }, + { 0x0A1A, glyph_cagurmukhi }, + { 0x0A1B, glyph_chagurmukhi }, + { 0x0A1C, glyph_jagurmukhi }, + { 0x0A1D, glyph_jhagurmukhi }, + { 0x0A1E, glyph_nyagurmukhi }, + { 0x0A1F, glyph_ttagurmukhi }, + { 0x0A20, glyph_tthagurmukhi }, + { 0x0A21, glyph_ddagurmukhi }, + { 0x0A22, glyph_ddhagurmukhi }, + { 0x0A23, glyph_nnagurmukhi }, + { 0x0A24, glyph_tagurmukhi }, + { 0x0A25, glyph_thagurmukhi }, + { 0x0A26, glyph_dagurmukhi }, + { 0x0A27, glyph_dhagurmukhi }, + { 0x0A28, glyph_nagurmukhi }, + { 0x0A2A, glyph_pagurmukhi }, + { 0x0A2B, glyph_phagurmukhi }, + { 0x0A2C, glyph_bagurmukhi }, + { 0x0A2D, glyph_bhagurmukhi }, + { 0x0A2E, glyph_magurmukhi }, + { 0x0A2F, glyph_yagurmukhi }, + { 0x0A30, glyph_ragurmukhi }, + { 0x0A32, glyph_lagurmukhi }, + { 0x0A35, glyph_vagurmukhi }, + { 0x0A36, glyph_shagurmukhi }, + { 0x0A38, glyph_sagurmukhi }, + { 0x0A39, glyph_hagurmukhi }, + { 0x0A3C, glyph_nuktagurmukhi }, + { 0x0A3E, glyph_aamatragurmukhi }, + { 0x0A3F, glyph_imatragurmukhi }, + { 0x0A40, glyph_iimatragurmukhi }, + { 0x0A41, glyph_umatragurmukhi }, + { 0x0A42, glyph_uumatragurmukhi }, + { 0x0A47, glyph_eematragurmukhi }, + { 0x0A48, glyph_aimatragurmukhi }, + { 0x0A4B, glyph_oomatragurmukhi }, + { 0x0A4C, glyph_aumatragurmukhi }, + { 0x0A4D, glyph_halantgurmukhi }, + { 0x0A59, glyph_khhagurmukhi }, + { 0x0A5A, glyph_ghhagurmukhi }, + { 0x0A5B, glyph_zagurmukhi }, + { 0x0A5C, glyph_rragurmukhi }, + { 0x0A5E, glyph_fagurmukhi }, + { 0x0A66, glyph_zerogurmukhi }, + { 0x0A67, glyph_onegurmukhi }, + { 0x0A68, glyph_twogurmukhi }, + { 0x0A69, glyph_threegurmukhi }, + { 0x0A6A, glyph_fourgurmukhi }, + { 0x0A6B, glyph_fivegurmukhi }, + { 0x0A6C, glyph_sixgurmukhi }, + { 0x0A6D, glyph_sevengurmukhi }, + { 0x0A6E, glyph_eightgurmukhi }, + { 0x0A6F, glyph_ninegurmukhi }, + { 0x0A70, glyph_tippigurmukhi }, + { 0x0A71, glyph_addakgurmukhi }, + { 0x0A72, glyph_irigurmukhi }, + { 0x0A73, glyph_uragurmukhi }, + { 0x0A74, glyph_ekonkargurmukhi }, + { 0x0A81, glyph_candrabindugujarati }, + { 0x0A82, glyph_anusvaragujarati }, + { 0x0A83, glyph_visargagujarati }, + { 0x0A85, glyph_agujarati }, + { 0x0A86, glyph_aagujarati }, + { 0x0A87, glyph_igujarati }, + { 0x0A88, glyph_iigujarati }, + { 0x0A89, glyph_ugujarati }, + { 0x0A8A, glyph_uugujarati }, + { 0x0A8B, glyph_rvocalicgujarati }, + { 0x0A8D, glyph_ecandragujarati }, + { 0x0A8F, glyph_egujarati }, + { 0x0A90, glyph_aigujarati }, + { 0x0A91, glyph_ocandragujarati }, + { 0x0A93, glyph_ogujarati }, + { 0x0A94, glyph_augujarati }, + { 0x0A95, glyph_kagujarati }, + { 0x0A96, glyph_khagujarati }, + { 0x0A97, glyph_gagujarati }, + { 0x0A98, glyph_ghagujarati }, + { 0x0A99, glyph_ngagujarati }, + { 0x0A9A, glyph_cagujarati }, + { 0x0A9B, glyph_chagujarati }, + { 0x0A9C, glyph_jagujarati }, + { 0x0A9D, glyph_jhagujarati }, + { 0x0A9E, glyph_nyagujarati }, + { 0x0A9F, glyph_ttagujarati }, + { 0x0AA0, glyph_tthagujarati }, + { 0x0AA1, glyph_ddagujarati }, + { 0x0AA2, glyph_ddhagujarati }, + { 0x0AA3, glyph_nnagujarati }, + { 0x0AA4, glyph_tagujarati }, + { 0x0AA5, glyph_thagujarati }, + { 0x0AA6, glyph_dagujarati }, + { 0x0AA7, glyph_dhagujarati }, + { 0x0AA8, glyph_nagujarati }, + { 0x0AAA, glyph_pagujarati }, + { 0x0AAB, glyph_phagujarati }, + { 0x0AAC, glyph_bagujarati }, + { 0x0AAD, glyph_bhagujarati }, + { 0x0AAE, glyph_magujarati }, + { 0x0AAF, glyph_yagujarati }, + { 0x0AB0, glyph_ragujarati }, + { 0x0AB2, glyph_lagujarati }, + { 0x0AB3, glyph_llagujarati }, + { 0x0AB5, glyph_vagujarati }, + { 0x0AB6, glyph_shagujarati }, + { 0x0AB7, glyph_ssagujarati }, + { 0x0AB8, glyph_sagujarati }, + { 0x0AB9, glyph_hagujarati }, + { 0x0ABC, glyph_nuktagujarati }, + { 0x0ABE, glyph_aavowelsigngujarati }, + { 0x0ABF, glyph_ivowelsigngujarati }, + { 0x0AC0, glyph_iivowelsigngujarati }, + { 0x0AC1, glyph_uvowelsigngujarati }, + { 0x0AC2, glyph_uuvowelsigngujarati }, + { 0x0AC3, glyph_rvocalicvowelsigngujarati }, + { 0x0AC4, glyph_rrvocalicvowelsigngujarati }, + { 0x0AC5, glyph_ecandravowelsigngujarati }, + { 0x0AC7, glyph_evowelsigngujarati }, + { 0x0AC8, glyph_aivowelsigngujarati }, + { 0x0AC9, glyph_ocandravowelsigngujarati }, + { 0x0ACB, glyph_ovowelsigngujarati }, + { 0x0ACC, glyph_auvowelsigngujarati }, + { 0x0ACD, glyph_viramagujarati }, + { 0x0AD0, glyph_omgujarati }, + { 0x0AE0, glyph_rrvocalicgujarati }, + { 0x0AE6, glyph_zerogujarati }, + { 0x0AE7, glyph_onegujarati }, + { 0x0AE8, glyph_twogujarati }, + { 0x0AE9, glyph_threegujarati }, + { 0x0AEA, glyph_fourgujarati }, + { 0x0AEB, glyph_fivegujarati }, + { 0x0AEC, glyph_sixgujarati }, + { 0x0AED, glyph_sevengujarati }, + { 0x0AEE, glyph_eightgujarati }, + { 0x0AEF, glyph_ninegujarati }, + { 0x0E01, glyph_kokaithai }, + { 0x0E02, glyph_khokhaithai }, + { 0x0E03, glyph_khokhuatthai }, + { 0x0E04, glyph_khokhwaithai }, + { 0x0E05, glyph_khokhonthai }, + { 0x0E06, glyph_khorakhangthai }, + { 0x0E07, glyph_ngonguthai }, + { 0x0E08, glyph_chochanthai }, + { 0x0E09, glyph_chochingthai }, + { 0x0E0A, glyph_chochangthai }, + { 0x0E0B, glyph_sosothai }, + { 0x0E0C, glyph_chochoethai }, + { 0x0E0D, glyph_yoyingthai }, + { 0x0E0E, glyph_dochadathai }, + { 0x0E0F, glyph_topatakthai }, + { 0x0E10, glyph_thothanthai }, + { 0x0E11, glyph_thonangmonthothai }, + { 0x0E12, glyph_thophuthaothai }, + { 0x0E13, glyph_nonenthai }, + { 0x0E14, glyph_dodekthai }, + { 0x0E15, glyph_totaothai }, + { 0x0E16, glyph_thothungthai }, + { 0x0E17, glyph_thothahanthai }, + { 0x0E18, glyph_thothongthai }, + { 0x0E19, glyph_nonuthai }, + { 0x0E1A, glyph_bobaimaithai }, + { 0x0E1B, glyph_poplathai }, + { 0x0E1C, glyph_phophungthai }, + { 0x0E1D, glyph_fofathai }, + { 0x0E1E, glyph_phophanthai }, + { 0x0E1F, glyph_fofanthai }, + { 0x0E20, glyph_phosamphaothai }, + { 0x0E21, glyph_momathai }, + { 0x0E22, glyph_yoyakthai }, + { 0x0E23, glyph_roruathai }, + { 0x0E24, glyph_ruthai }, + { 0x0E25, glyph_lolingthai }, + { 0x0E26, glyph_luthai }, + { 0x0E27, glyph_wowaenthai }, + { 0x0E28, glyph_sosalathai }, + { 0x0E29, glyph_sorusithai }, + { 0x0E2A, glyph_sosuathai }, + { 0x0E2B, glyph_hohipthai }, + { 0x0E2C, glyph_lochulathai }, + { 0x0E2D, glyph_oangthai }, + { 0x0E2E, glyph_honokhukthai }, + { 0x0E2F, glyph_paiyannoithai }, + { 0x0E30, glyph_saraathai }, + { 0x0E31, glyph_maihanakatthai }, + { 0x0E32, glyph_saraaathai }, + { 0x0E33, glyph_saraamthai }, + { 0x0E34, glyph_saraithai }, + { 0x0E35, glyph_saraiithai }, + { 0x0E36, glyph_sarauethai }, + { 0x0E37, glyph_saraueethai }, + { 0x0E38, glyph_sarauthai }, + { 0x0E39, glyph_sarauuthai }, + { 0x0E3A, glyph_phinthuthai }, + { 0x0E3F, glyph_bahtthai }, + { 0x0E40, glyph_saraethai }, + { 0x0E41, glyph_saraaethai }, + { 0x0E42, glyph_saraothai }, + { 0x0E43, glyph_saraaimaimuanthai }, + { 0x0E44, glyph_saraaimaimalaithai }, + { 0x0E45, glyph_lakkhangyaothai }, + { 0x0E46, glyph_maiyamokthai }, + { 0x0E47, glyph_maitaikhuthai }, + { 0x0E48, glyph_maiekthai }, + { 0x0E49, glyph_maithothai }, + { 0x0E4A, glyph_maitrithai }, + { 0x0E4B, glyph_maichattawathai }, + { 0x0E4C, glyph_thanthakhatthai }, + { 0x0E4D, glyph_nikhahitthai }, + { 0x0E4E, glyph_yamakkanthai }, + { 0x0E4F, glyph_fongmanthai }, + { 0x0E50, glyph_zerothai }, + { 0x0E51, glyph_onethai }, + { 0x0E52, glyph_twothai }, + { 0x0E53, glyph_threethai }, + { 0x0E54, glyph_fourthai }, + { 0x0E55, glyph_fivethai }, + { 0x0E56, glyph_sixthai }, + { 0x0E57, glyph_seventhai }, + { 0x0E58, glyph_eightthai }, + { 0x0E59, glyph_ninethai }, + { 0x0E5A, glyph_angkhankhuthai }, + { 0x0E5B, glyph_khomutthai }, + { 0x1E00, glyph_Aringbelow }, + { 0x1E01, glyph_aringbelow }, + { 0x1E02, glyph_Bdotaccent }, + { 0x1E03, glyph_bdotaccent }, + { 0x1E04, glyph_Bdotbelow }, + { 0x1E05, glyph_bdotbelow }, + { 0x1E06, glyph_Blinebelow }, + { 0x1E07, glyph_blinebelow }, + { 0x1E08, glyph_Ccedillaacute }, + { 0x1E09, glyph_ccedillaacute }, + { 0x1E0A, glyph_Ddotaccent }, + { 0x1E0B, glyph_ddotaccent }, + { 0x1E0C, glyph_Ddotbelow }, + { 0x1E0D, glyph_ddotbelow }, + { 0x1E0E, glyph_Dlinebelow }, + { 0x1E0F, glyph_dlinebelow }, + { 0x1E10, glyph_Dcedilla }, + { 0x1E11, glyph_dcedilla }, + { 0x1E12, glyph_Dcircumflexbelow }, + { 0x1E13, glyph_dcircumflexbelow }, + { 0x1E14, glyph_Emacrongrave }, + { 0x1E15, glyph_emacrongrave }, + { 0x1E16, glyph_Emacronacute }, + { 0x1E17, glyph_emacronacute }, + { 0x1E18, glyph_Ecircumflexbelow }, + { 0x1E19, glyph_ecircumflexbelow }, + { 0x1E1A, glyph_Etildebelow }, + { 0x1E1B, glyph_etildebelow }, + { 0x1E1C, glyph_Ecedillabreve }, + { 0x1E1D, glyph_ecedillabreve }, + { 0x1E1E, glyph_Fdotaccent }, + { 0x1E1F, glyph_fdotaccent }, + { 0x1E20, glyph_Gmacron }, + { 0x1E21, glyph_gmacron }, + { 0x1E22, glyph_Hdotaccent }, + { 0x1E23, glyph_hdotaccent }, + { 0x1E24, glyph_Hdotbelow }, + { 0x1E25, glyph_hdotbelow }, + { 0x1E26, glyph_Hdieresis }, + { 0x1E27, glyph_hdieresis }, + { 0x1E28, glyph_Hcedilla }, + { 0x1E29, glyph_hcedilla }, + { 0x1E2A, glyph_Hbrevebelow }, + { 0x1E2B, glyph_hbrevebelow }, + { 0x1E2C, glyph_Itildebelow }, + { 0x1E2D, glyph_itildebelow }, + { 0x1E2E, glyph_Idieresisacute }, + { 0x1E2F, glyph_idieresisacute }, + { 0x1E30, glyph_Kacute }, + { 0x1E31, glyph_kacute }, + { 0x1E32, glyph_Kdotbelow }, + { 0x1E33, glyph_kdotbelow }, + { 0x1E34, glyph_Klinebelow }, + { 0x1E35, glyph_klinebelow }, + { 0x1E36, glyph_Ldotbelow }, + { 0x1E37, glyph_ldotbelow }, + { 0x1E38, glyph_Ldotbelowmacron }, + { 0x1E39, glyph_ldotbelowmacron }, + { 0x1E3A, glyph_Llinebelow }, + { 0x1E3B, glyph_llinebelow }, + { 0x1E3C, glyph_Lcircumflexbelow }, + { 0x1E3D, glyph_lcircumflexbelow }, + { 0x1E3E, glyph_Macute }, + { 0x1E3F, glyph_macute }, + { 0x1E40, glyph_Mdotaccent }, + { 0x1E41, glyph_mdotaccent }, + { 0x1E42, glyph_Mdotbelow }, + { 0x1E43, glyph_mdotbelow }, + { 0x1E44, glyph_Ndotaccent }, + { 0x1E45, glyph_ndotaccent }, + { 0x1E46, glyph_Ndotbelow }, + { 0x1E47, glyph_ndotbelow }, + { 0x1E48, glyph_Nlinebelow }, + { 0x1E49, glyph_nlinebelow }, + { 0x1E4A, glyph_Ncircumflexbelow }, + { 0x1E4B, glyph_ncircumflexbelow }, + { 0x1E4C, glyph_Otildeacute }, + { 0x1E4D, glyph_otildeacute }, + { 0x1E4E, glyph_Otildedieresis }, + { 0x1E4F, glyph_otildedieresis }, + { 0x1E50, glyph_Omacrongrave }, + { 0x1E51, glyph_omacrongrave }, + { 0x1E52, glyph_Omacronacute }, + { 0x1E53, glyph_omacronacute }, + { 0x1E54, glyph_Pacute }, + { 0x1E55, glyph_pacute }, + { 0x1E56, glyph_Pdotaccent }, + { 0x1E57, glyph_pdotaccent }, + { 0x1E58, glyph_Rdotaccent }, + { 0x1E59, glyph_rdotaccent }, + { 0x1E5A, glyph_Rdotbelow }, + { 0x1E5B, glyph_rdotbelow }, + { 0x1E5C, glyph_Rdotbelowmacron }, + { 0x1E5D, glyph_rdotbelowmacron }, + { 0x1E5E, glyph_Rlinebelow }, + { 0x1E5F, glyph_rlinebelow }, + { 0x1E60, glyph_Sdotaccent }, + { 0x1E61, glyph_sdotaccent }, + { 0x1E62, glyph_Sdotbelow }, + { 0x1E63, glyph_sdotbelow }, + { 0x1E64, glyph_Sacutedotaccent }, + { 0x1E65, glyph_sacutedotaccent }, + { 0x1E66, glyph_Scarondotaccent }, + { 0x1E67, glyph_scarondotaccent }, + { 0x1E68, glyph_Sdotbelowdotaccent }, + { 0x1E69, glyph_sdotbelowdotaccent }, + { 0x1E6A, glyph_Tdotaccent }, + { 0x1E6B, glyph_tdotaccent }, + { 0x1E6C, glyph_Tdotbelow }, + { 0x1E6D, glyph_tdotbelow }, + { 0x1E6E, glyph_Tlinebelow }, + { 0x1E6F, glyph_tlinebelow }, + { 0x1E70, glyph_Tcircumflexbelow }, + { 0x1E71, glyph_tcircumflexbelow }, + { 0x1E72, glyph_Udieresisbelow }, + { 0x1E73, glyph_udieresisbelow }, + { 0x1E74, glyph_Utildebelow }, + { 0x1E75, glyph_utildebelow }, + { 0x1E76, glyph_Ucircumflexbelow }, + { 0x1E77, glyph_ucircumflexbelow }, + { 0x1E78, glyph_Utildeacute }, + { 0x1E79, glyph_utildeacute }, + { 0x1E7A, glyph_Umacrondieresis }, + { 0x1E7B, glyph_umacrondieresis }, + { 0x1E7C, glyph_Vtilde }, + { 0x1E7D, glyph_vtilde }, + { 0x1E7E, glyph_Vdotbelow }, + { 0x1E7F, glyph_vdotbelow }, + { 0x1E86, glyph_Wdotaccent }, + { 0x1E87, glyph_wdotaccent }, + { 0x1E88, glyph_Wdotbelow }, + { 0x1E89, glyph_wdotbelow }, + { 0x1E8A, glyph_Xdotaccent }, + { 0x1E8B, glyph_xdotaccent }, + { 0x1E8C, glyph_Xdieresis }, + { 0x1E8D, glyph_xdieresis }, + { 0x1E8E, glyph_Ydotaccent }, + { 0x1E8F, glyph_ydotaccent }, + { 0x1E90, glyph_Zcircumflex }, + { 0x1E91, glyph_zcircumflex }, + { 0x1E92, glyph_Zdotbelow }, + { 0x1E93, glyph_zdotbelow }, + { 0x1E94, glyph_Zlinebelow }, + { 0x1E95, glyph_zlinebelow }, + { 0x1E96, glyph_hlinebelow }, + { 0x1E97, glyph_tdieresis }, + { 0x1E98, glyph_wring }, + { 0x1E99, glyph_yring }, + { 0x1E9A, glyph_arighthalfring }, + { 0x1E9B, glyph_slongdotaccent }, + { 0x1EA0, glyph_Adotbelow }, + { 0x1EA1, glyph_adotbelow }, + { 0x1EA2, glyph_Ahookabove }, + { 0x1EA3, glyph_ahookabove }, + { 0x1EA4, glyph_Acircumflexacute }, + { 0x1EA5, glyph_acircumflexacute }, + { 0x1EA6, glyph_Acircumflexgrave }, + { 0x1EA7, glyph_acircumflexgrave }, + { 0x1EA8, glyph_Acircumflexhookabove }, + { 0x1EA9, glyph_acircumflexhookabove }, + { 0x1EAA, glyph_Acircumflextilde }, + { 0x1EAB, glyph_acircumflextilde }, + { 0x1EAC, glyph_Acircumflexdotbelow }, + { 0x1EAD, glyph_acircumflexdotbelow }, + { 0x1EAE, glyph_Abreveacute }, + { 0x1EAF, glyph_abreveacute }, + { 0x1EB0, glyph_Abrevegrave }, + { 0x1EB1, glyph_abrevegrave }, + { 0x1EB2, glyph_Abrevehookabove }, + { 0x1EB3, glyph_abrevehookabove }, + { 0x1EB4, glyph_Abrevetilde }, + { 0x1EB5, glyph_abrevetilde }, + { 0x1EB6, glyph_Abrevedotbelow }, + { 0x1EB7, glyph_abrevedotbelow }, + { 0x1EB8, glyph_Edotbelow }, + { 0x1EB9, glyph_edotbelow }, + { 0x1EBA, glyph_Ehookabove }, + { 0x1EBB, glyph_ehookabove }, + { 0x1EBC, glyph_Etilde }, + { 0x1EBD, glyph_etilde }, + { 0x1EBE, glyph_Ecircumflexacute }, + { 0x1EBF, glyph_ecircumflexacute }, + { 0x1EC0, glyph_Ecircumflexgrave }, + { 0x1EC1, glyph_ecircumflexgrave }, + { 0x1EC2, glyph_Ecircumflexhookabove }, + { 0x1EC3, glyph_ecircumflexhookabove }, + { 0x1EC4, glyph_Ecircumflextilde }, + { 0x1EC5, glyph_ecircumflextilde }, + { 0x1EC6, glyph_Ecircumflexdotbelow }, + { 0x1EC7, glyph_ecircumflexdotbelow }, + { 0x1EC8, glyph_Ihookabove }, + { 0x1EC9, glyph_ihookabove }, + { 0x1ECA, glyph_Idotbelow }, + { 0x1ECB, glyph_idotbelow }, + { 0x1ECC, glyph_Odotbelow }, + { 0x1ECD, glyph_odotbelow }, + { 0x1ECE, glyph_Ohookabove }, + { 0x1ECF, glyph_ohookabove }, + { 0x1ED0, glyph_Ocircumflexacute }, + { 0x1ED1, glyph_ocircumflexacute }, + { 0x1ED2, glyph_Ocircumflexgrave }, + { 0x1ED3, glyph_ocircumflexgrave }, + { 0x1ED4, glyph_Ocircumflexhookabove }, + { 0x1ED5, glyph_ocircumflexhookabove }, + { 0x1ED6, glyph_Ocircumflextilde }, + { 0x1ED7, glyph_ocircumflextilde }, + { 0x1ED8, glyph_Ocircumflexdotbelow }, + { 0x1ED9, glyph_ocircumflexdotbelow }, + { 0x1EDA, glyph_Ohornacute }, + { 0x1EDB, glyph_ohornacute }, + { 0x1EDC, glyph_Ohorngrave }, + { 0x1EDD, glyph_ohorngrave }, + { 0x1EDE, glyph_Ohornhookabove }, + { 0x1EDF, glyph_ohornhookabove }, + { 0x1EE0, glyph_Ohorntilde }, + { 0x1EE1, glyph_ohorntilde }, + { 0x1EE2, glyph_Ohorndotbelow }, + { 0x1EE3, glyph_ohorndotbelow }, + { 0x1EE4, glyph_Udotbelow }, + { 0x1EE5, glyph_udotbelow }, + { 0x1EE6, glyph_Uhookabove }, + { 0x1EE7, glyph_uhookabove }, + { 0x1EE8, glyph_Uhornacute }, + { 0x1EE9, glyph_uhornacute }, + { 0x1EEA, glyph_Uhorngrave }, + { 0x1EEB, glyph_uhorngrave }, + { 0x1EEC, glyph_Uhornhookabove }, + { 0x1EED, glyph_uhornhookabove }, + { 0x1EEE, glyph_Uhorntilde }, + { 0x1EEF, glyph_uhorntilde }, + { 0x1EF0, glyph_Uhorndotbelow }, + { 0x1EF1, glyph_uhorndotbelow }, + { 0x1EF4, glyph_Ydotbelow }, + { 0x1EF5, glyph_ydotbelow }, + { 0x1EF6, glyph_Yhookabove }, + { 0x1EF7, glyph_yhookabove }, + { 0x1EF8, glyph_Ytilde }, + { 0x1EF9, glyph_ytilde }, + { 0x2002, glyph_enspace }, + { 0x200B, glyph_zerowidthspace }, + { 0x200C, glyph_zerowidthnonjoiner }, + { 0x2010, glyph_hyphentwo }, + { 0x2015, glyph_horizontalbar }, + { 0x2016, glyph_dblverticalbar }, + { 0x2017, glyph_dbllowline }, + { 0x201B, glyph_quoteleftreversed }, + { 0x2025, glyph_twodotleader }, + { 0x2035, glyph_primereversed }, + { 0x203B, glyph_referencemark }, + { 0x203E, glyph_overline }, + { 0x2042, glyph_asterism }, + { 0x207A, glyph_plussuperior }, + { 0x207C, glyph_equalsuperior }, + { 0x20A1, glyph_colonsign }, + { 0x20A2, glyph_cruzeiro }, + { 0x20A4, glyph_afii08941 }, + { 0x20A9, glyph_won }, + { 0x20AC, glyph_euro }, + { 0x2103, glyph_centigrade }, + { 0x2105, glyph_careof }, + { 0x2109, glyph_fahrenheit }, + { 0x2113, glyph_lsquare }, + { 0x2116, glyph_numero }, + { 0x2121, glyph_telephone }, + { 0x2126, glyph_Ohm }, + { 0x212B, glyph_angstrom }, + { 0x2160, glyph_Oneroman }, + { 0x2161, glyph_Tworoman }, + { 0x2162, glyph_Threeroman }, + { 0x2163, glyph_Fourroman }, + { 0x2164, glyph_Fiveroman }, + { 0x2165, glyph_Sixroman }, + { 0x2166, glyph_Sevenroman }, + { 0x2167, glyph_Eightroman }, + { 0x2168, glyph_Nineroman }, + { 0x2169, glyph_Tenroman }, + { 0x216A, glyph_Elevenroman }, + { 0x216B, glyph_Twelveroman }, + { 0x2170, glyph_oneroman }, + { 0x2171, glyph_tworoman }, + { 0x2172, glyph_threeroman }, + { 0x2173, glyph_fourroman }, + { 0x2174, glyph_fiveroman }, + { 0x2175, glyph_sixroman }, + { 0x2176, glyph_sevenroman }, + { 0x2177, glyph_eightroman }, + { 0x2178, glyph_nineroman }, + { 0x2179, glyph_tenroman }, + { 0x217A, glyph_elevenroman }, + { 0x217B, glyph_twelveroman }, + { 0x2196, glyph_arrowupleft }, + { 0x2197, glyph_arrowupright }, + { 0x2198, glyph_arrowdownright }, + { 0x2199, glyph_arrowdownleft }, + { 0x21A8, glyph_arrowupdownbase }, + { 0x21BC, glyph_harpoonleftbarbup }, + { 0x21C0, glyph_harpoonrightbarbup }, + { 0x21C4, glyph_arrowrightoverleft }, + { 0x21C5, glyph_arrowupleftofdown }, + { 0x21C6, glyph_arrowleftoverright }, + { 0x21CD, glyph_arrowleftdblstroke }, + { 0x21CF, glyph_arrowrightdblstroke }, + { 0x21D0, glyph_arrowleftdbl }, + { 0x21D2, glyph_dblarrowright }, + { 0x21D4, glyph_dblarrowleft }, + { 0x21DE, glyph_pageup }, + { 0x21DF, glyph_pagedown }, + { 0x21E0, glyph_arrowdashleft }, + { 0x21E1, glyph_arrowdashup }, + { 0x21E2, glyph_arrowdashright }, + { 0x21E3, glyph_arrowdashdown }, + { 0x21E4, glyph_arrowtableft }, + { 0x21E5, glyph_arrowtabright }, + { 0x21E6, glyph_arrowleftwhite }, + { 0x21E7, glyph_arrowupwhite }, + { 0x21E8, glyph_arrowrightwhite }, + { 0x21E9, glyph_arrowdownwhite }, + { 0x21EA, glyph_capslock }, + { 0x2200, glyph_forall }, + { 0x2203, glyph_thereexists }, + { 0x2206, glyph_increment }, + { 0x2207, glyph_nabla }, + { 0x2209, glyph_notelementof }, + { 0x220C, glyph_notcontains }, + { 0x2213, glyph_minusplus }, + { 0x221F, glyph_rightangle }, + { 0x2223, glyph_divides }, + { 0x2225, glyph_parallel }, + { 0x2226, glyph_notparallel }, + { 0x222C, glyph_dblintegral }, + { 0x222E, glyph_contourintegral }, + { 0x2235, glyph_because }, + { 0x2236, glyph_ratio }, + { 0x2237, glyph_proportion }, + { 0x223C, glyph_tildeoperator }, + { 0x223D, glyph_reversedtilde }, + { 0x2243, glyph_asymptoticallyequal }, + { 0x2245, glyph_approximatelyequal }, + { 0x224C, glyph_allequal }, + { 0x2250, glyph_approaches }, + { 0x2251, glyph_geometricallyequal }, + { 0x2252, glyph_approxequalorimage }, + { 0x2253, glyph_imageorapproximatelyequal }, + { 0x2262, glyph_notidentical }, + { 0x2266, glyph_lessoverequal }, + { 0x2267, glyph_greateroverequal }, + { 0x226A, glyph_muchless }, + { 0x226B, glyph_muchgreater }, + { 0x226E, glyph_notless }, + { 0x226F, glyph_notgreater }, + { 0x2270, glyph_notlessnorequal }, + { 0x2271, glyph_notgreaternorequal }, + { 0x2272, glyph_lessorequivalent }, + { 0x2273, glyph_greaterorequivalent }, + { 0x2276, glyph_lessorgreater }, + { 0x2277, glyph_greaterorless }, + { 0x2279, glyph_notgreaternorless }, + { 0x227A, glyph_precedes }, + { 0x227B, glyph_succeeds }, + { 0x2280, glyph_notprecedes }, + { 0x2281, glyph_notsucceeds }, + { 0x2282, glyph_subset }, + { 0x2283, glyph_superset }, + { 0x2285, glyph_notsuperset }, + { 0x2286, glyph_subsetorequal }, + { 0x2287, glyph_supersetorequal }, + { 0x228A, glyph_subsetnotequal }, + { 0x228B, glyph_supersetnotequal }, + { 0x2295, glyph_pluscircle }, + { 0x2296, glyph_minuscircle }, + { 0x2297, glyph_timescircle }, + { 0x2299, glyph_circleot }, + { 0x22A3, glyph_tackleft }, + { 0x22A4, glyph_tackdown }, + { 0x22BF, glyph_righttriangle }, + { 0x22CE, glyph_curlyor }, + { 0x22CF, glyph_curlyand }, + { 0x22DA, glyph_lessequalorgreater }, + { 0x22DB, glyph_greaterequalorless }, + { 0x22EE, glyph_ellipsisvertical }, + { 0x2303, glyph_control }, + { 0x2305, glyph_projective }, + { 0x2310, glyph_logicalnotreversed }, + { 0x2312, glyph_arc }, + { 0x2318, glyph_propellor }, + { 0x2320, glyph_integraltop }, + { 0x2321, glyph_integralbottom }, + { 0x2325, glyph_option }, + { 0x2326, glyph_deleteright }, + { 0x2327, glyph_clear }, + { 0x232B, glyph_deleteleft }, + { 0x2423, glyph_blank }, + { 0x2460, glyph_onecircle }, + { 0x2461, glyph_twocircle }, + { 0x2462, glyph_threecircle }, + { 0x2463, glyph_fourcircle }, + { 0x2464, glyph_fivecircle }, + { 0x2465, glyph_sixcircle }, + { 0x2466, glyph_sevencircle }, + { 0x2467, glyph_eightcircle }, + { 0x2468, glyph_ninecircle }, + { 0x2469, glyph_tencircle }, + { 0x246A, glyph_elevencircle }, + { 0x246B, glyph_twelvecircle }, + { 0x246C, glyph_thirteencircle }, + { 0x246D, glyph_fourteencircle }, + { 0x246E, glyph_fifteencircle }, + { 0x246F, glyph_sixteencircle }, + { 0x2470, glyph_seventeencircle }, + { 0x2471, glyph_eighteencircle }, + { 0x2472, glyph_nineteencircle }, + { 0x2473, glyph_twentycircle }, + { 0x2474, glyph_oneparen }, + { 0x2475, glyph_twoparen }, + { 0x2476, glyph_threeparen }, + { 0x2477, glyph_fourparen }, + { 0x2478, glyph_fiveparen }, + { 0x2479, glyph_sixparen }, + { 0x247A, glyph_sevenparen }, + { 0x247B, glyph_eightparen }, + { 0x247C, glyph_nineparen }, + { 0x247D, glyph_tenparen }, + { 0x247E, glyph_elevenparen }, + { 0x247F, glyph_twelveparen }, + { 0x2480, glyph_thirteenparen }, + { 0x2481, glyph_fourteenparen }, + { 0x2482, glyph_fifteenparen }, + { 0x2483, glyph_sixteenparen }, + { 0x2484, glyph_seventeenparen }, + { 0x2485, glyph_eighteenparen }, + { 0x2486, glyph_nineteenparen }, + { 0x2487, glyph_twentyparen }, + { 0x2488, glyph_oneperiod }, + { 0x2489, glyph_twoperiod }, + { 0x248A, glyph_threeperiod }, + { 0x248B, glyph_fourperiod }, + { 0x248C, glyph_fiveperiod }, + { 0x248D, glyph_sixperiod }, + { 0x248E, glyph_sevenperiod }, + { 0x248F, glyph_eightperiod }, + { 0x2490, glyph_nineperiod }, + { 0x2491, glyph_tenperiod }, + { 0x2492, glyph_elevenperiod }, + { 0x2493, glyph_twelveperiod }, + { 0x2494, glyph_thirteenperiod }, + { 0x2495, glyph_fourteenperiod }, + { 0x2496, glyph_fifteenperiod }, + { 0x2497, glyph_sixteenperiod }, + { 0x2498, glyph_seventeenperiod }, + { 0x2499, glyph_eighteenperiod }, + { 0x249A, glyph_nineteenperiod }, + { 0x249B, glyph_twentyperiod }, + { 0x249C, glyph_aparen }, + { 0x249D, glyph_bparen }, + { 0x249E, glyph_cparen }, + { 0x249F, glyph_dparen }, + { 0x24A0, glyph_eparen }, + { 0x24A1, glyph_fparen }, + { 0x24A2, glyph_gparen }, + { 0x24A3, glyph_hparen }, + { 0x24A4, glyph_iparen }, + { 0x24A5, glyph_jparen }, + { 0x24A6, glyph_kparen }, + { 0x24A7, glyph_lparen }, + { 0x24A8, glyph_mparen }, + { 0x24A9, glyph_nparen }, + { 0x24AA, glyph_oparen }, + { 0x24AB, glyph_pparen }, + { 0x24AC, glyph_qparen }, + { 0x24AD, glyph_rparen }, + { 0x24AE, glyph_sparen }, + { 0x24AF, glyph_tparen }, + { 0x24B0, glyph_uparen }, + { 0x24B1, glyph_vparen }, + { 0x24B2, glyph_wparen }, + { 0x24B3, glyph_xparen }, + { 0x24B4, glyph_yparen }, + { 0x24B5, glyph_zparen }, + { 0x24B6, glyph_Acircle }, + { 0x24B7, glyph_Bcircle }, + { 0x24B8, glyph_Ccircle }, + { 0x24B9, glyph_Dcircle }, + { 0x24BA, glyph_Ecircle }, + { 0x24BB, glyph_Fcircle }, + { 0x24BC, glyph_Gcircle }, + { 0x24BD, glyph_Hcircle }, + { 0x24BE, glyph_Icircle }, + { 0x24BF, glyph_Jcircle }, + { 0x24C0, glyph_Kcircle }, + { 0x24C1, glyph_Lcircle }, + { 0x24C2, glyph_Mcircle }, + { 0x24C3, glyph_Ncircle }, + { 0x24C4, glyph_Ocircle }, + { 0x24C5, glyph_Pcircle }, + { 0x24C6, glyph_Qcircle }, + { 0x24C7, glyph_Rcircle }, + { 0x24C8, glyph_Scircle }, + { 0x24C9, glyph_Tcircle }, + { 0x24CA, glyph_Ucircle }, + { 0x24CB, glyph_Vcircle }, + { 0x24CC, glyph_Wcircle }, + { 0x24CD, glyph_Xcircle }, + { 0x24CE, glyph_Ycircle }, + { 0x24CF, glyph_Zcircle }, + { 0x24D0, glyph_acircle }, + { 0x24D1, glyph_bcircle }, + { 0x24D2, glyph_ccircle }, + { 0x24D3, glyph_dcircle }, + { 0x24D4, glyph_ecircle }, + { 0x24D5, glyph_fcircle }, + { 0x24D6, glyph_gcircle }, + { 0x24D7, glyph_hcircle }, + { 0x24D8, glyph_icircle }, + { 0x24D9, glyph_jcircle }, + { 0x24DA, glyph_kcircle }, + { 0x24DB, glyph_lcircle }, + { 0x24DC, glyph_mcircle }, + { 0x24DD, glyph_ncircle }, + { 0x24DE, glyph_ocircle }, + { 0x24DF, glyph_pcircle }, + { 0x24E0, glyph_qcircle }, + { 0x24E1, glyph_rcircle }, + { 0x24E2, glyph_scircle }, + { 0x24E3, glyph_tcircle }, + { 0x24E4, glyph_ucircle }, + { 0x24E5, glyph_vcircle }, + { 0x24E6, glyph_wcircle }, + { 0x24E7, glyph_xcircle }, + { 0x24E8, glyph_ycircle }, + { 0x24E9, glyph_zcircle }, + { 0x2591, glyph_shadelight }, + { 0x2592, glyph_shademedium }, + { 0x2593, glyph_shadedark }, + { 0x25A0, glyph_blacksquare }, + { 0x25A1, glyph_whitesquare }, + { 0x25A3, glyph_squarewhitewithsmallblack }, + { 0x25A4, glyph_squarehorizontalfill }, + { 0x25A5, glyph_squareverticalfill }, + { 0x25A6, glyph_squareorthogonalcrosshatchfill }, + { 0x25A7, glyph_squareupperlefttolowerrightfill }, + { 0x25A8, glyph_squareupperrighttolowerleftfill }, + { 0x25A9, glyph_squarediagonalcrosshatchfill }, + { 0x25AA, glyph_blacksmallsquare }, + { 0x25AB, glyph_whitesmallsquare }, + { 0x25AC, glyph_blackrectangle }, + { 0x25B2, glyph_blackuppointingtriangle }, + { 0x25B3, glyph_whiteuppointingtriangle }, + { 0x25B4, glyph_blackuppointingsmalltriangle }, + { 0x25B5, glyph_whiteuppointingsmalltriangle }, + { 0x25B6, glyph_blackrightpointingtriangle }, + { 0x25B7, glyph_whiterightpointingtriangle }, + { 0x25B9, glyph_whiterightpointingsmalltriangle }, + { 0x25BA, glyph_blackrightpointingpointer }, + { 0x25BC, glyph_blackdownpointingtriangle }, + { 0x25BD, glyph_whitedownpointingtriangle }, + { 0x25BF, glyph_whitedownpointingsmalltriangle }, + { 0x25C0, glyph_blackleftpointingtriangle }, + { 0x25C1, glyph_whiteleftpointingtriangle }, + { 0x25C3, glyph_whiteleftpointingsmalltriangle }, + { 0x25C4, glyph_blackleftpointingpointer }, + { 0x25C6, glyph_blackdiamond }, + { 0x25C7, glyph_whitediamond }, + { 0x25C8, glyph_whitediamondcontainingblacksmalldiamond }, + { 0x25C9, glyph_fisheye }, + { 0x25CB, glyph_whitecircle }, + { 0x25CC, glyph_dottedcircle }, + { 0x25CE, glyph_bullseye }, + { 0x25CF, glyph_blackcircle }, + { 0x25D0, glyph_circlewithlefthalfblack }, + { 0x25D1, glyph_circlewithrighthalfblack }, + { 0x25D8, glyph_bulletinverse }, + { 0x25D9, glyph_whitecircleinverse }, + { 0x25E2, glyph_blacklowerrighttriangle }, + { 0x25E3, glyph_blacklowerlefttriangle }, + { 0x25E4, glyph_blackupperlefttriangle }, + { 0x25E5, glyph_blackupperrighttriangle }, + { 0x25E6, glyph_whitebullet }, + { 0x25EF, glyph_largecircle }, + { 0x2605, glyph_blackstar }, + { 0x2606, glyph_whitestar }, + { 0x260E, glyph_telephoneblack }, + { 0x260F, glyph_whitetelephone }, + { 0x261C, glyph_pointingindexleftwhite }, + { 0x261D, glyph_pointingindexupwhite }, + { 0x261E, glyph_pointingindexrightwhite }, + { 0x261F, glyph_pointingindexdownwhite }, + { 0x262F, glyph_yinyang }, + { 0x263A, glyph_whitesmilingface }, + { 0x263B, glyph_blacksmilingface }, + { 0x263C, glyph_compass }, + { 0x2640, glyph_venus }, + { 0x2641, glyph_earth }, + { 0x2642, glyph_mars }, + { 0x2660, glyph_spadesuitblack }, + { 0x2661, glyph_heartsuitwhite }, + { 0x2662, glyph_diamondsuitwhite }, + { 0x2663, glyph_clubsuitblack }, + { 0x2664, glyph_spadesuitwhite }, + { 0x2665, glyph_heartsuitblack }, + { 0x2667, glyph_clubsuitwhite }, + { 0x2668, glyph_hotsprings }, + { 0x2669, glyph_quarternote }, + { 0x266B, glyph_eighthnotebeamed }, + { 0x266C, glyph_beamedsixteenthnotes }, + { 0x266D, glyph_musicflatsign }, + { 0x266F, glyph_musicsharpsign }, + { 0x2713, glyph_checkmark }, + { 0x278A, glyph_onecircleinversesansserif }, + { 0x278B, glyph_twocircleinversesansserif }, + { 0x278C, glyph_threecircleinversesansserif }, + { 0x278D, glyph_fourcircleinversesansserif }, + { 0x278E, glyph_fivecircleinversesansserif }, + { 0x278F, glyph_sixcircleinversesansserif }, + { 0x2790, glyph_sevencircleinversesansserif }, + { 0x2791, glyph_eightcircleinversesansserif }, + { 0x2792, glyph_ninecircleinversesansserif }, + { 0x279E, glyph_arrowrightheavy }, + { 0x3000, glyph_ideographicspace }, + { 0x3001, glyph_ideographiccomma }, + { 0x3002, glyph_ideographicperiod }, + { 0x3003, glyph_dittomark }, + { 0x3004, glyph_jis }, + { 0x3005, glyph_ideographiciterationmark }, + { 0x3006, glyph_ideographicclose }, + { 0x3007, glyph_ideographiczero }, + { 0x3008, glyph_anglebracketleft }, + { 0x3009, glyph_anglebracketright }, + { 0x300A, glyph_dblanglebracketleft }, + { 0x300B, glyph_dblanglebracketright }, + { 0x300C, glyph_cornerbracketleft }, + { 0x300D, glyph_cornerbracketright }, + { 0x300E, glyph_whitecornerbracketleft }, + { 0x300F, glyph_whitecornerbracketright }, + { 0x3010, glyph_blacklenticularbracketleft }, + { 0x3011, glyph_blacklenticularbracketright }, + { 0x3012, glyph_postalmark }, + { 0x3013, glyph_getamark }, + { 0x3014, glyph_tortoiseshellbracketleft }, + { 0x3015, glyph_tortoiseshellbracketright }, + { 0x3016, glyph_whitelenticularbracketleft }, + { 0x3017, glyph_whitelenticularbracketright }, + { 0x3018, glyph_whitetortoiseshellbracketleft }, + { 0x3019, glyph_whitetortoiseshellbracketright }, + { 0x301C, glyph_wavedash }, + { 0x301D, glyph_quotedblprimereversed }, + { 0x301E, glyph_quotedblprime }, + { 0x3020, glyph_postalmarkface }, + { 0x3021, glyph_onehangzhou }, + { 0x3022, glyph_twohangzhou }, + { 0x3023, glyph_threehangzhou }, + { 0x3024, glyph_fourhangzhou }, + { 0x3025, glyph_fivehangzhou }, + { 0x3026, glyph_sixhangzhou }, + { 0x3027, glyph_sevenhangzhou }, + { 0x3028, glyph_eighthangzhou }, + { 0x3029, glyph_ninehangzhou }, + { 0x3036, glyph_circlepostalmark }, + { 0x3041, glyph_asmallhiragana }, + { 0x3042, glyph_ahiragana }, + { 0x3043, glyph_ismallhiragana }, + { 0x3044, glyph_ihiragana }, + { 0x3045, glyph_usmallhiragana }, + { 0x3046, glyph_uhiragana }, + { 0x3047, glyph_esmallhiragana }, + { 0x3048, glyph_ehiragana }, + { 0x3049, glyph_osmallhiragana }, + { 0x304A, glyph_ohiragana }, + { 0x304B, glyph_kahiragana }, + { 0x304C, glyph_gahiragana }, + { 0x304D, glyph_kihiragana }, + { 0x304E, glyph_gihiragana }, + { 0x304F, glyph_kuhiragana }, + { 0x3050, glyph_guhiragana }, + { 0x3051, glyph_kehiragana }, + { 0x3052, glyph_gehiragana }, + { 0x3053, glyph_kohiragana }, + { 0x3054, glyph_gohiragana }, + { 0x3055, glyph_sahiragana }, + { 0x3056, glyph_zahiragana }, + { 0x3057, glyph_sihiragana }, + { 0x3058, glyph_zihiragana }, + { 0x3059, glyph_suhiragana }, + { 0x305A, glyph_zuhiragana }, + { 0x305B, glyph_sehiragana }, + { 0x305C, glyph_zehiragana }, + { 0x305D, glyph_sohiragana }, + { 0x305E, glyph_zohiragana }, + { 0x305F, glyph_tahiragana }, + { 0x3060, glyph_dahiragana }, + { 0x3061, glyph_tihiragana }, + { 0x3062, glyph_dihiragana }, + { 0x3063, glyph_tusmallhiragana }, + { 0x3064, glyph_tuhiragana }, + { 0x3065, glyph_duhiragana }, + { 0x3066, glyph_tehiragana }, + { 0x3067, glyph_dehiragana }, + { 0x3068, glyph_tohiragana }, + { 0x3069, glyph_dohiragana }, + { 0x306A, glyph_nahiragana }, + { 0x306B, glyph_nihiragana }, + { 0x306C, glyph_nuhiragana }, + { 0x306D, glyph_nehiragana }, + { 0x306E, glyph_nohiragana }, + { 0x306F, glyph_hahiragana }, + { 0x3070, glyph_bahiragana }, + { 0x3071, glyph_pahiragana }, + { 0x3072, glyph_hihiragana }, + { 0x3073, glyph_bihiragana }, + { 0x3074, glyph_pihiragana }, + { 0x3075, glyph_huhiragana }, + { 0x3076, glyph_buhiragana }, + { 0x3077, glyph_puhiragana }, + { 0x3078, glyph_hehiragana }, + { 0x3079, glyph_behiragana }, + { 0x307A, glyph_pehiragana }, + { 0x307B, glyph_hohiragana }, + { 0x307C, glyph_bohiragana }, + { 0x307D, glyph_pohiragana }, + { 0x307E, glyph_mahiragana }, + { 0x307F, glyph_mihiragana }, + { 0x3080, glyph_muhiragana }, + { 0x3081, glyph_mehiragana }, + { 0x3082, glyph_mohiragana }, + { 0x3083, glyph_yasmallhiragana }, + { 0x3084, glyph_yahiragana }, + { 0x3085, glyph_yusmallhiragana }, + { 0x3086, glyph_yuhiragana }, + { 0x3087, glyph_yosmallhiragana }, + { 0x3088, glyph_yohiragana }, + { 0x3089, glyph_rahiragana }, + { 0x308A, glyph_rihiragana }, + { 0x308B, glyph_ruhiragana }, + { 0x308C, glyph_rehiragana }, + { 0x308D, glyph_rohiragana }, + { 0x308E, glyph_wasmallhiragana }, + { 0x308F, glyph_wahiragana }, + { 0x3090, glyph_wihiragana }, + { 0x3091, glyph_wehiragana }, + { 0x3092, glyph_wohiragana }, + { 0x3093, glyph_nhiragana }, + { 0x3094, glyph_vuhiragana }, + { 0x309B, glyph_voicedmarkkana }, + { 0x309C, glyph_semivoicedmarkkana }, + { 0x309D, glyph_iterationhiragana }, + { 0x309E, glyph_voicediterationhiragana }, + { 0x30A1, glyph_asmallkatakana }, + { 0x30A2, glyph_akatakana }, + { 0x30A3, glyph_ismallkatakana }, + { 0x30A4, glyph_ikatakana }, + { 0x30A5, glyph_usmallkatakana }, + { 0x30A6, glyph_ukatakana }, + { 0x30A7, glyph_esmallkatakana }, + { 0x30A8, glyph_ekatakana }, + { 0x30A9, glyph_osmallkatakana }, + { 0x30AA, glyph_okatakana }, + { 0x30AB, glyph_kakatakana }, + { 0x30AC, glyph_gakatakana }, + { 0x30AD, glyph_kikatakana }, + { 0x30AE, glyph_gikatakana }, + { 0x30AF, glyph_kukatakana }, + { 0x30B0, glyph_gukatakana }, + { 0x30B1, glyph_kekatakana }, + { 0x30B2, glyph_gekatakana }, + { 0x30B3, glyph_kokatakana }, + { 0x30B4, glyph_gokatakana }, + { 0x30B5, glyph_sakatakana }, + { 0x30B6, glyph_zakatakana }, + { 0x30B7, glyph_sikatakana }, + { 0x30B8, glyph_zikatakana }, + { 0x30B9, glyph_sukatakana }, + { 0x30BA, glyph_zukatakana }, + { 0x30BB, glyph_sekatakana }, + { 0x30BC, glyph_zekatakana }, + { 0x30BD, glyph_sokatakana }, + { 0x30BE, glyph_zokatakana }, + { 0x30BF, glyph_takatakana }, + { 0x30C0, glyph_dakatakana }, + { 0x30C1, glyph_tikatakana }, + { 0x30C2, glyph_dikatakana }, + { 0x30C3, glyph_tusmallkatakana }, + { 0x30C4, glyph_tukatakana }, + { 0x30C5, glyph_dukatakana }, + { 0x30C6, glyph_tekatakana }, + { 0x30C7, glyph_dekatakana }, + { 0x30C8, glyph_tokatakana }, + { 0x30C9, glyph_dokatakana }, + { 0x30CA, glyph_nakatakana }, + { 0x30CB, glyph_nikatakana }, + { 0x30CC, glyph_nukatakana }, + { 0x30CD, glyph_nekatakana }, + { 0x30CE, glyph_nokatakana }, + { 0x30CF, glyph_hakatakana }, + { 0x30D0, glyph_bakatakana }, + { 0x30D1, glyph_pakatakana }, + { 0x30D2, glyph_hikatakana }, + { 0x30D3, glyph_bikatakana }, + { 0x30D4, glyph_pikatakana }, + { 0x30D5, glyph_hukatakana }, + { 0x30D6, glyph_bukatakana }, + { 0x30D7, glyph_pukatakana }, + { 0x30D8, glyph_hekatakana }, + { 0x30D9, glyph_bekatakana }, + { 0x30DA, glyph_pekatakana }, + { 0x30DB, glyph_hokatakana }, + { 0x30DC, glyph_bokatakana }, + { 0x30DD, glyph_pokatakana }, + { 0x30DE, glyph_makatakana }, + { 0x30DF, glyph_mikatakana }, + { 0x30E0, glyph_mukatakana }, + { 0x30E1, glyph_mekatakana }, + { 0x30E2, glyph_mokatakana }, + { 0x30E3, glyph_yasmallkatakana }, + { 0x30E4, glyph_yakatakana }, + { 0x30E5, glyph_yusmallkatakana }, + { 0x30E6, glyph_yukatakana }, + { 0x30E7, glyph_yosmallkatakana }, + { 0x30E8, glyph_yokatakana }, + { 0x30E9, glyph_rakatakana }, + { 0x30EA, glyph_rikatakana }, + { 0x30EB, glyph_rukatakana }, + { 0x30EC, glyph_rekatakana }, + { 0x30ED, glyph_rokatakana }, + { 0x30EE, glyph_wasmallkatakana }, + { 0x30EF, glyph_wakatakana }, + { 0x30F0, glyph_wikatakana }, + { 0x30F1, glyph_wekatakana }, + { 0x30F2, glyph_wokatakana }, + { 0x30F3, glyph_nkatakana }, + { 0x30F4, glyph_vukatakana }, + { 0x30F5, glyph_kasmallkatakana }, + { 0x30F6, glyph_kesmallkatakana }, + { 0x30F7, glyph_vakatakana }, + { 0x30F8, glyph_vikatakana }, + { 0x30F9, glyph_vekatakana }, + { 0x30FA, glyph_vokatakana }, + { 0x30FB, glyph_dotkatakana }, + { 0x30FC, glyph_prolongedkana }, + { 0x30FD, glyph_iterationkatakana }, + { 0x30FE, glyph_voicediterationkatakana }, + { 0x3105, glyph_bbopomofo }, + { 0x3106, glyph_pbopomofo }, + { 0x3107, glyph_mbopomofo }, + { 0x3108, glyph_fbopomofo }, + { 0x3109, glyph_dbopomofo }, + { 0x310A, glyph_tbopomofo }, + { 0x310B, glyph_nbopomofo }, + { 0x310C, glyph_lbopomofo }, + { 0x310D, glyph_gbopomofo }, + { 0x310E, glyph_kbopomofo }, + { 0x310F, glyph_hbopomofo }, + { 0x3110, glyph_jbopomofo }, + { 0x3111, glyph_qbopomofo }, + { 0x3112, glyph_xbopomofo }, + { 0x3113, glyph_zhbopomofo }, + { 0x3114, glyph_chbopomofo }, + { 0x3115, glyph_shbopomofo }, + { 0x3116, glyph_rbopomofo }, + { 0x3117, glyph_zbopomofo }, + { 0x3118, glyph_cbopomofo }, + { 0x3119, glyph_sbopomofo }, + { 0x311A, glyph_abopomofo }, + { 0x311B, glyph_obopomofo }, + { 0x311C, glyph_ebopomofo }, + { 0x311D, glyph_ehbopomofo }, + { 0x311E, glyph_aibopomofo }, + { 0x311F, glyph_eibopomofo }, + { 0x3120, glyph_aubopomofo }, + { 0x3121, glyph_oubopomofo }, + { 0x3122, glyph_anbopomofo }, + { 0x3123, glyph_enbopomofo }, + { 0x3124, glyph_angbopomofo }, + { 0x3125, glyph_engbopomofo }, + { 0x3126, glyph_erbopomofo }, + { 0x3127, glyph_ibopomofo }, + { 0x3128, glyph_ubopomofo }, + { 0x3129, glyph_iubopomofo }, + { 0x3131, glyph_kiyeokkorean }, + { 0x3132, glyph_ssangkiyeokkorean }, + { 0x3133, glyph_kiyeoksioskorean }, + { 0x3134, glyph_nieunkorean }, + { 0x3135, glyph_nieuncieuckorean }, + { 0x3136, glyph_nieunhieuhkorean }, + { 0x3137, glyph_tikeutkorean }, + { 0x3138, glyph_ssangtikeutkorean }, + { 0x3139, glyph_rieulkorean }, + { 0x313A, glyph_rieulkiyeokkorean }, + { 0x313B, glyph_rieulmieumkorean }, + { 0x313C, glyph_rieulpieupkorean }, + { 0x313D, glyph_rieulsioskorean }, + { 0x313E, glyph_rieulthieuthkorean }, + { 0x313F, glyph_rieulphieuphkorean }, + { 0x3140, glyph_rieulhieuhkorean }, + { 0x3141, glyph_mieumkorean }, + { 0x3142, glyph_pieupkorean }, + { 0x3143, glyph_ssangpieupkorean }, + { 0x3144, glyph_pieupsioskorean }, + { 0x3145, glyph_sioskorean }, + { 0x3146, glyph_ssangsioskorean }, + { 0x3147, glyph_ieungkorean }, + { 0x3148, glyph_cieuckorean }, + { 0x3149, glyph_ssangcieuckorean }, + { 0x314A, glyph_chieuchkorean }, + { 0x314B, glyph_khieukhkorean }, + { 0x314C, glyph_thieuthkorean }, + { 0x314D, glyph_phieuphkorean }, + { 0x314E, glyph_hieuhkorean }, + { 0x314F, glyph_akorean }, + { 0x3150, glyph_aekorean }, + { 0x3151, glyph_yakorean }, + { 0x3152, glyph_yaekorean }, + { 0x3153, glyph_eokorean }, + { 0x3154, glyph_ekorean }, + { 0x3155, glyph_yeokorean }, + { 0x3156, glyph_yekorean }, + { 0x3157, glyph_okorean }, + { 0x3158, glyph_wakorean }, + { 0x3159, glyph_waekorean }, + { 0x315A, glyph_oekorean }, + { 0x315B, glyph_yokorean }, + { 0x315C, glyph_ukorean }, + { 0x315D, glyph_weokorean }, + { 0x315E, glyph_wekorean }, + { 0x315F, glyph_wikorean }, + { 0x3160, glyph_yukorean }, + { 0x3161, glyph_eukorean }, + { 0x3162, glyph_yikorean }, + { 0x3163, glyph_ikorean }, + { 0x3164, glyph_hangulfiller }, + { 0x3165, glyph_ssangnieunkorean }, + { 0x3166, glyph_nieuntikeutkorean }, + { 0x3167, glyph_nieunsioskorean }, + { 0x3168, glyph_nieunpansioskorean }, + { 0x3169, glyph_rieulkiyeoksioskorean }, + { 0x316A, glyph_rieultikeutkorean }, + { 0x316B, glyph_rieulpieupsioskorean }, + { 0x316C, glyph_rieulpansioskorean }, + { 0x316D, glyph_rieulyeorinhieuhkorean }, + { 0x316E, glyph_mieumpieupkorean }, + { 0x316F, glyph_mieumsioskorean }, + { 0x3170, glyph_mieumpansioskorean }, + { 0x3171, glyph_kapyeounmieumkorean }, + { 0x3172, glyph_pieupkiyeokkorean }, + { 0x3173, glyph_pieuptikeutkorean }, + { 0x3174, glyph_pieupsioskiyeokkorean }, + { 0x3175, glyph_pieupsiostikeutkorean }, + { 0x3176, glyph_pieupcieuckorean }, + { 0x3177, glyph_pieupthieuthkorean }, + { 0x3178, glyph_kapyeounpieupkorean }, + { 0x3179, glyph_kapyeounssangpieupkorean }, + { 0x317A, glyph_sioskiyeokkorean }, + { 0x317B, glyph_siosnieunkorean }, + { 0x317C, glyph_siostikeutkorean }, + { 0x317D, glyph_siospieupkorean }, + { 0x317E, glyph_sioscieuckorean }, + { 0x317F, glyph_pansioskorean }, + { 0x3180, glyph_ssangieungkorean }, + { 0x3181, glyph_yesieungkorean }, + { 0x3182, glyph_yesieungsioskorean }, + { 0x3183, glyph_yesieungpansioskorean }, + { 0x3184, glyph_kapyeounphieuphkorean }, + { 0x3185, glyph_ssanghieuhkorean }, + { 0x3186, glyph_yeorinhieuhkorean }, + { 0x3187, glyph_yoyakorean }, + { 0x3188, glyph_yoyaekorean }, + { 0x3189, glyph_yoikorean }, + { 0x318A, glyph_yuyeokorean }, + { 0x318B, glyph_yuyekorean }, + { 0x318C, glyph_yuikorean }, + { 0x318D, glyph_araeakorean }, + { 0x318E, glyph_araeaekorean }, + { 0x3200, glyph_kiyeokparenkorean }, + { 0x3201, glyph_nieunparenkorean }, + { 0x3202, glyph_tikeutparenkorean }, + { 0x3203, glyph_rieulparenkorean }, + { 0x3204, glyph_mieumparenkorean }, + { 0x3205, glyph_pieupparenkorean }, + { 0x3206, glyph_siosparenkorean }, + { 0x3207, glyph_ieungparenkorean }, + { 0x3208, glyph_cieucparenkorean }, + { 0x3209, glyph_chieuchparenkorean }, + { 0x320A, glyph_khieukhparenkorean }, + { 0x320B, glyph_thieuthparenkorean }, + { 0x320C, glyph_phieuphparenkorean }, + { 0x320D, glyph_hieuhparenkorean }, + { 0x320E, glyph_kiyeokaparenkorean }, + { 0x320F, glyph_nieunaparenkorean }, + { 0x3210, glyph_tikeutaparenkorean }, + { 0x3211, glyph_rieulaparenkorean }, + { 0x3212, glyph_mieumaparenkorean }, + { 0x3213, glyph_pieupaparenkorean }, + { 0x3214, glyph_siosaparenkorean }, + { 0x3215, glyph_ieungaparenkorean }, + { 0x3216, glyph_cieucaparenkorean }, + { 0x3217, glyph_chieuchaparenkorean }, + { 0x3218, glyph_khieukhaparenkorean }, + { 0x3219, glyph_thieuthaparenkorean }, + { 0x321A, glyph_phieuphaparenkorean }, + { 0x321B, glyph_hieuhaparenkorean }, + { 0x321C, glyph_cieucuparenkorean }, + { 0x3220, glyph_oneideographicparen }, + { 0x3221, glyph_twoideographicparen }, + { 0x3222, glyph_threeideographicparen }, + { 0x3223, glyph_fourideographicparen }, + { 0x3224, glyph_fiveideographicparen }, + { 0x3225, glyph_sixideographicparen }, + { 0x3226, glyph_sevenideographicparen }, + { 0x3227, glyph_eightideographicparen }, + { 0x3228, glyph_nineideographicparen }, + { 0x3229, glyph_tenideographicparen }, + { 0x322A, glyph_ideographicmoonparen }, + { 0x322B, glyph_ideographicfireparen }, + { 0x322C, glyph_ideographicwaterparen }, + { 0x322D, glyph_ideographicwoodparen }, + { 0x322E, glyph_ideographicmetalparen }, + { 0x322F, glyph_ideographicearthparen }, + { 0x3230, glyph_ideographicsunparen }, + { 0x3231, glyph_ideographicstockparen }, + { 0x3232, glyph_ideographichaveparen }, + { 0x3233, glyph_ideographicsocietyparen }, + { 0x3234, glyph_ideographicnameparen }, + { 0x3235, glyph_ideographicspecialparen }, + { 0x3236, glyph_ideographicfinancialparen }, + { 0x3237, glyph_ideographiccongratulationparen }, + { 0x3238, glyph_ideographiclaborparen }, + { 0x3239, glyph_ideographicrepresentparen }, + { 0x323A, glyph_ideographiccallparen }, + { 0x323B, glyph_ideographicstudyparen }, + { 0x323C, glyph_ideographicsuperviseparen }, + { 0x323D, glyph_ideographicenterpriseparen }, + { 0x323E, glyph_ideographicresourceparen }, + { 0x323F, glyph_ideographicallianceparen }, + { 0x3240, glyph_ideographicfestivalparen }, + { 0x3242, glyph_ideographicselfparen }, + { 0x3243, glyph_ideographicreachparen }, + { 0x3260, glyph_kiyeokcirclekorean }, + { 0x3261, glyph_nieuncirclekorean }, + { 0x3262, glyph_tikeutcirclekorean }, + { 0x3263, glyph_rieulcirclekorean }, + { 0x3264, glyph_mieumcirclekorean }, + { 0x3265, glyph_pieupcirclekorean }, + { 0x3266, glyph_sioscirclekorean }, + { 0x3267, glyph_ieungcirclekorean }, + { 0x3268, glyph_cieuccirclekorean }, + { 0x3269, glyph_chieuchcirclekorean }, + { 0x326A, glyph_khieukhcirclekorean }, + { 0x326B, glyph_thieuthcirclekorean }, + { 0x326C, glyph_phieuphcirclekorean }, + { 0x326D, glyph_hieuhcirclekorean }, + { 0x326E, glyph_kiyeokacirclekorean }, + { 0x326F, glyph_nieunacirclekorean }, + { 0x3270, glyph_tikeutacirclekorean }, + { 0x3271, glyph_rieulacirclekorean }, + { 0x3272, glyph_mieumacirclekorean }, + { 0x3273, glyph_pieupacirclekorean }, + { 0x3274, glyph_siosacirclekorean }, + { 0x3275, glyph_ieungacirclekorean }, + { 0x3276, glyph_cieucacirclekorean }, + { 0x3277, glyph_chieuchacirclekorean }, + { 0x3278, glyph_khieukhacirclekorean }, + { 0x3279, glyph_thieuthacirclekorean }, + { 0x327A, glyph_phieuphacirclekorean }, + { 0x327B, glyph_hieuhacirclekorean }, + { 0x327F, glyph_koreanstandardsymbol }, + { 0x328A, glyph_ideographmooncircle }, + { 0x328B, glyph_ideographfirecircle }, + { 0x328C, glyph_ideographwatercircle }, + { 0x328D, glyph_ideographwoodcircle }, + { 0x328E, glyph_ideographmetalcircle }, + { 0x328F, glyph_ideographearthcircle }, + { 0x3290, glyph_ideographsuncircle }, + { 0x3294, glyph_ideographnamecircle }, + { 0x3296, glyph_ideographicfinancialcircle }, + { 0x3298, glyph_ideographiclaborcircle }, + { 0x3299, glyph_ideographicsecretcircle }, + { 0x329D, glyph_ideographicexcellentcircle }, + { 0x329E, glyph_ideographicprintcircle }, + { 0x32A3, glyph_ideographiccorrectcircle }, + { 0x32A4, glyph_ideographichighcircle }, + { 0x32A5, glyph_ideographiccentrecircle }, + { 0x32A6, glyph_ideographiclowcircle }, + { 0x32A7, glyph_ideographicleftcircle }, + { 0x32A8, glyph_ideographicrightcircle }, + { 0x32A9, glyph_ideographicmedicinecircle }, + { 0x3300, glyph_apaatosquare }, + { 0x3303, glyph_aarusquare }, + { 0x3305, glyph_intisquare }, + { 0x330D, glyph_karoriisquare }, + { 0x3314, glyph_kirosquare }, + { 0x3315, glyph_kiroguramusquare }, + { 0x3316, glyph_kiromeetorusquare }, + { 0x3318, glyph_guramusquare }, + { 0x331E, glyph_kooposquare }, + { 0x3322, glyph_sentisquare }, + { 0x3323, glyph_sentosquare }, + { 0x3326, glyph_dorusquare }, + { 0x3327, glyph_tonsquare }, + { 0x332A, glyph_haitusquare }, + { 0x332B, glyph_paasentosquare }, + { 0x3331, glyph_birusquare }, + { 0x3333, glyph_huiitosquare }, + { 0x3336, glyph_hekutaarusquare }, + { 0x3339, glyph_herutusquare }, + { 0x333B, glyph_peezisquare }, + { 0x3342, glyph_hoonsquare }, + { 0x3347, glyph_mansyonsquare }, + { 0x3349, glyph_mirisquare }, + { 0x334A, glyph_miribaarusquare }, + { 0x334D, glyph_meetorusquare }, + { 0x334E, glyph_yaadosquare }, + { 0x3351, glyph_rittorusquare }, + { 0x3357, glyph_wattosquare }, + { 0x337B, glyph_heiseierasquare }, + { 0x337C, glyph_syouwaerasquare }, + { 0x337D, glyph_taisyouerasquare }, + { 0x337E, glyph_meizierasquare }, + { 0x337F, glyph_corporationsquare }, + { 0x3380, glyph_paampssquare }, + { 0x3381, glyph_nasquare }, + { 0x3382, glyph_muasquare }, + { 0x3383, glyph_masquare }, + { 0x3384, glyph_kasquare }, + { 0x3385, glyph_KBsquare }, + { 0x3386, glyph_MBsquare }, + { 0x3387, glyph_GBsquare }, + { 0x3388, glyph_calsquare }, + { 0x3389, glyph_kcalsquare }, + { 0x338A, glyph_pfsquare }, + { 0x338B, glyph_nfsquare }, + { 0x338C, glyph_mufsquare }, + { 0x338D, glyph_mugsquare }, + { 0x338E, glyph_squaremg }, + { 0x338F, glyph_squarekg }, + { 0x3390, glyph_Hzsquare }, + { 0x3391, glyph_khzsquare }, + { 0x3392, glyph_mhzsquare }, + { 0x3393, glyph_ghzsquare }, + { 0x3394, glyph_thzsquare }, + { 0x3395, glyph_mulsquare }, + { 0x3396, glyph_mlsquare }, + { 0x3397, glyph_dlsquare }, + { 0x3398, glyph_klsquare }, + { 0x3399, glyph_fmsquare }, + { 0x339A, glyph_nmsquare }, + { 0x339B, glyph_mumsquare }, + { 0x339C, glyph_squaremm }, + { 0x339D, glyph_squarecm }, + { 0x339E, glyph_squarekm }, + { 0x339F, glyph_mmsquaredsquare }, + { 0x33A0, glyph_cmsquaredsquare }, + { 0x33A1, glyph_squaremsquared }, + { 0x33A2, glyph_kmsquaredsquare }, + { 0x33A3, glyph_mmcubedsquare }, + { 0x33A4, glyph_cmcubedsquare }, + { 0x33A5, glyph_mcubedsquare }, + { 0x33A6, glyph_kmcubedsquare }, + { 0x33A7, glyph_moverssquare }, + { 0x33A8, glyph_moverssquaredsquare }, + { 0x33A9, glyph_pasquare }, + { 0x33AA, glyph_kpasquare }, + { 0x33AB, glyph_mpasquare }, + { 0x33AC, glyph_gpasquare }, + { 0x33AD, glyph_radsquare }, + { 0x33AE, glyph_radoverssquare }, + { 0x33AF, glyph_radoverssquaredsquare }, + { 0x33B0, glyph_pssquare }, + { 0x33B1, glyph_nssquare }, + { 0x33B2, glyph_mussquare }, + { 0x33B3, glyph_mssquare }, + { 0x33B4, glyph_pvsquare }, + { 0x33B5, glyph_nvsquare }, + { 0x33B6, glyph_muvsquare }, + { 0x33B7, glyph_mvsquare }, + { 0x33B8, glyph_kvsquare }, + { 0x33B9, glyph_mvmegasquare }, + { 0x33BA, glyph_pwsquare }, + { 0x33BB, glyph_nwsquare }, + { 0x33BC, glyph_muwsquare }, + { 0x33BD, glyph_mwsquare }, + { 0x33BE, glyph_kwsquare }, + { 0x33BF, glyph_mwmegasquare }, + { 0x33C0, glyph_kohmsquare }, + { 0x33C1, glyph_mohmsquare }, + { 0x33C2, glyph_amsquare }, + { 0x33C3, glyph_bqsquare }, + { 0x33C4, glyph_squarecc }, + { 0x33C5, glyph_cdsquare }, + { 0x33C6, glyph_coverkgsquare }, + { 0x33C7, glyph_cosquare }, + { 0x33C8, glyph_dbsquare }, + { 0x33C9, glyph_gysquare }, + { 0x33CA, glyph_hasquare }, + { 0x33CB, glyph_HPsquare }, + { 0x33CD, glyph_KKsquare }, + { 0x33CE, glyph_squarekmcapital }, + { 0x33CF, glyph_ktsquare }, + { 0x33D0, glyph_lmsquare }, + { 0x33D1, glyph_squareln }, + { 0x33D2, glyph_squarelog }, + { 0x33D3, glyph_lxsquare }, + { 0x33D4, glyph_mbsquare }, + { 0x33D5, glyph_squaremil }, + { 0x33D6, glyph_molsquare }, + { 0x33D8, glyph_pmsquare }, + { 0x33DB, glyph_srsquare }, + { 0x33DC, glyph_svsquare }, + { 0x33DD, glyph_wbsquare }, + { 0x5344, glyph_twentyhangzhou }, + { 0xF884, glyph_maihanakatleftthai }, + { 0xF885, glyph_saraileftthai }, + { 0xF886, glyph_saraiileftthai }, + { 0xF887, glyph_saraueleftthai }, + { 0xF888, glyph_saraueeleftthai }, + { 0xF889, glyph_maitaikhuleftthai }, + { 0xF88A, glyph_maiekupperleftthai }, + { 0xF88B, glyph_maieklowrightthai }, + { 0xF88C, glyph_maieklowleftthai }, + { 0xF88D, glyph_maithoupperleftthai }, + { 0xF88E, glyph_maitholowrightthai }, + { 0xF88F, glyph_maitholowleftthai }, + { 0xF890, glyph_maitriupperleftthai }, + { 0xF891, glyph_maitrilowrightthai }, + { 0xF892, glyph_maitrilowleftthai }, + { 0xF893, glyph_maichattawaupperleftthai }, + { 0xF894, glyph_maichattawalowrightthai }, + { 0xF895, glyph_maichattawalowleftthai }, + { 0xF896, glyph_thanthakhatupperleftthai }, + { 0xF897, glyph_thanthakhatlowrightthai }, + { 0xF898, glyph_thanthakhatlowleftthai }, + { 0xF899, glyph_nikhahitleftthai }, + { 0xFB20, glyph_ayinaltonehebrew }, + { 0xFB2E, glyph_alefpatahhebrew }, + { 0xFB2F, glyph_alefqamatshebrew }, + { 0xFB30, glyph_alefdageshhebrew }, + { 0xFB43, glyph_pefinaldageshhebrew }, + { 0xFB48, glyph_reshdageshhebrew }, + { 0xFB4C, glyph_betrafehebrew }, + { 0xFB4D, glyph_kafrafehebrew }, + { 0xFB4E, glyph_perafehebrew }, + { 0xFB4F, glyph_aleflamedhebrew }, + { 0xFB57, glyph_pehfinalarabic }, + { 0xFB58, glyph_pehinitialarabic }, + { 0xFB59, glyph_pehmedialarabic }, + { 0xFB67, glyph_ttehfinalarabic }, + { 0xFB68, glyph_ttehinitialarabic }, + { 0xFB69, glyph_ttehmedialarabic }, + { 0xFB6B, glyph_vehfinalarabic }, + { 0xFB6C, glyph_vehinitialarabic }, + { 0xFB6D, glyph_vehmedialarabic }, + { 0xFB7B, glyph_tchehfinalarabic }, + { 0xFB7C, glyph_tchehinitialarabic }, + { 0xFB7D, glyph_tchehmedialarabic }, + { 0xFB89, glyph_ddalfinalarabic }, + { 0xFB8B, glyph_jehfinalarabic }, + { 0xFB8D, glyph_rrehfinalarabic }, + { 0xFB93, glyph_gaffinalarabic }, + { 0xFB94, glyph_gafinitialarabic }, + { 0xFB95, glyph_gafmedialarabic }, + { 0xFB9F, glyph_noonghunnafinalarabic }, + { 0xFBA4, glyph_hehhamzaaboveisolatedarabic }, + { 0xFBA5, glyph_hehhamzaabovefinalarabic }, + { 0xFBA7, glyph_hehfinalaltonearabic }, + { 0xFBA8, glyph_hehinitialaltonearabic }, + { 0xFBA9, glyph_hehmedialaltonearabic }, + { 0xFBAF, glyph_yehbarreefinalarabic }, + { 0xFC08, glyph_behmeemisolatedarabic }, + { 0xFC0B, glyph_tehjeemisolatedarabic }, + { 0xFC0C, glyph_tehhahisolatedarabic }, + { 0xFC0E, glyph_tehmeemisolatedarabic }, + { 0xFC48, glyph_meemmeemisolatedarabic }, + { 0xFC4B, glyph_noonjeemisolatedarabic }, + { 0xFC4E, glyph_noonmeemisolatedarabic }, + { 0xFC58, glyph_yehmeemisolatedarabic }, + { 0xFC5E, glyph_shaddadammatanarabic }, + { 0xFC5F, glyph_shaddakasratanarabic }, + { 0xFC60, glyph_shaddafathaarabic }, + { 0xFC61, glyph_shaddadammaarabic }, + { 0xFC62, glyph_shaddakasraarabic }, + { 0xFC6D, glyph_behnoonfinalarabic }, + { 0xFC73, glyph_tehnoonfinalarabic }, + { 0xFC8D, glyph_noonnoonfinalarabic }, + { 0xFC94, glyph_yehnoonfinalarabic }, + { 0xFC9F, glyph_behmeeminitialarabic }, + { 0xFCA1, glyph_tehjeeminitialarabic }, + { 0xFCA2, glyph_tehhahinitialarabic }, + { 0xFCA4, glyph_tehmeeminitialarabic }, + { 0xFCC9, glyph_lamjeeminitialarabic }, + { 0xFCCA, glyph_lamhahinitialarabic }, + { 0xFCCB, glyph_lamkhahinitialarabic }, + { 0xFCCC, glyph_lammeeminitialarabic }, + { 0xFCD1, glyph_meemmeeminitialarabic }, + { 0xFCD2, glyph_noonjeeminitialarabic }, + { 0xFCD5, glyph_noonmeeminitialarabic }, + { 0xFCDD, glyph_yehmeeminitialarabic }, + { 0xFD3E, glyph_parenleftaltonearabic }, + { 0xFD3F, glyph_parenrightaltonearabic }, + { 0xFD88, glyph_lammeemhahinitialarabic }, + { 0xFDF2, glyph_lamlamhehisolatedarabic }, + { 0xFDFA, glyph_sallallahoualayhewasallamarabic }, + { 0xFE30, glyph_twodotleadervertical }, + { 0xFE31, glyph_emdashvertical }, + { 0xFE32, glyph_endashvertical }, + { 0xFE33, glyph_underscorevertical }, + { 0xFE34, glyph_wavyunderscorevertical }, + { 0xFE35, glyph_parenleftvertical }, + { 0xFE36, glyph_parenrightvertical }, + { 0xFE37, glyph_braceleftvertical }, + { 0xFE38, glyph_bracerightvertical }, + { 0xFE39, glyph_tortoiseshellbracketleftvertical }, + { 0xFE3A, glyph_tortoiseshellbracketrightvertical }, + { 0xFE3B, glyph_blacklenticularbracketleftvertical }, + { 0xFE3C, glyph_blacklenticularbracketrightvertical }, + { 0xFE3D, glyph_dblanglebracketleftvertical }, + { 0xFE3E, glyph_dblanglebracketrightvertical }, + { 0xFE3F, glyph_anglebracketleftvertical }, + { 0xFE40, glyph_anglebracketrightvertical }, + { 0xFE41, glyph_cornerbracketleftvertical }, + { 0xFE42, glyph_cornerbracketrightvertical }, + { 0xFE43, glyph_whitecornerbracketleftvertical }, + { 0xFE44, glyph_whitecornerbracketrightvertical }, + { 0xFE49, glyph_overlinedashed }, + { 0xFE4A, glyph_overlinecenterline }, + { 0xFE4B, glyph_overlinewavy }, + { 0xFE4C, glyph_overlinedblwavy }, + { 0xFE4D, glyph_lowlinedashed }, + { 0xFE4E, glyph_lowlinecenterline }, + { 0xFE4F, glyph_underscorewavy }, + { 0xFE50, glyph_commasmall }, + { 0xFE52, glyph_periodsmall }, + { 0xFE54, glyph_semicolonsmall }, + { 0xFE55, glyph_colonsmall }, + { 0xFE59, glyph_parenleftsmall }, + { 0xFE5A, glyph_parenrightsmall }, + { 0xFE5B, glyph_braceleftsmall }, + { 0xFE5C, glyph_bracerightsmall }, + { 0xFE5D, glyph_tortoiseshellbracketleftsmall }, + { 0xFE5E, glyph_tortoiseshellbracketrightsmall }, + { 0xFE5F, glyph_numbersignsmall }, + { 0xFE61, glyph_asterisksmall }, + { 0xFE62, glyph_plussmall }, + { 0xFE63, glyph_hyphensmall }, + { 0xFE64, glyph_lesssmall }, + { 0xFE65, glyph_greatersmall }, + { 0xFE66, glyph_equalsmall }, + { 0xFE69, glyph_dollarsmall }, + { 0xFE6A, glyph_percentsmall }, + { 0xFE6B, glyph_atsmall }, + { 0xFE82, glyph_alefmaddaabovefinalarabic }, + { 0xFE84, glyph_alefhamzaabovefinalarabic }, + { 0xFE86, glyph_wawhamzaabovefinalarabic }, + { 0xFE88, glyph_alefhamzabelowfinalarabic }, + { 0xFE8A, glyph_yehhamzaabovefinalarabic }, + { 0xFE8B, glyph_yehhamzaaboveinitialarabic }, + { 0xFE8C, glyph_yehhamzaabovemedialarabic }, + { 0xFE8E, glyph_aleffinalarabic }, + { 0xFE90, glyph_behfinalarabic }, + { 0xFE91, glyph_behinitialarabic }, + { 0xFE92, glyph_behmedialarabic }, + { 0xFE94, glyph_tehmarbutafinalarabic }, + { 0xFE96, glyph_tehfinalarabic }, + { 0xFE97, glyph_tehinitialarabic }, + { 0xFE98, glyph_tehmedialarabic }, + { 0xFE9A, glyph_thehfinalarabic }, + { 0xFE9B, glyph_thehinitialarabic }, + { 0xFE9C, glyph_thehmedialarabic }, + { 0xFE9E, glyph_jeemfinalarabic }, + { 0xFE9F, glyph_jeeminitialarabic }, + { 0xFEA0, glyph_jeemmedialarabic }, + { 0xFEA2, glyph_hahfinalarabic }, + { 0xFEA3, glyph_hahinitialarabic }, + { 0xFEA4, glyph_hahmedialarabic }, + { 0xFEA6, glyph_khahfinalarabic }, + { 0xFEA7, glyph_khahinitialarabic }, + { 0xFEA8, glyph_khahmedialarabic }, + { 0xFEAA, glyph_dalfinalarabic }, + { 0xFEAC, glyph_thalfinalarabic }, + { 0xFEAE, glyph_rehfinalarabic }, + { 0xFEB0, glyph_zainfinalarabic }, + { 0xFEB2, glyph_seenfinalarabic }, + { 0xFEB3, glyph_seeninitialarabic }, + { 0xFEB4, glyph_seenmedialarabic }, + { 0xFEB6, glyph_sheenfinalarabic }, + { 0xFEB7, glyph_sheeninitialarabic }, + { 0xFEB8, glyph_sheenmedialarabic }, + { 0xFEBA, glyph_sadfinalarabic }, + { 0xFEBB, glyph_sadinitialarabic }, + { 0xFEBC, glyph_sadmedialarabic }, + { 0xFEBE, glyph_dadfinalarabic }, + { 0xFEBF, glyph_dadinitialarabic }, + { 0xFEC0, glyph_dadmedialarabic }, + { 0xFEC2, glyph_tahfinalarabic }, + { 0xFEC3, glyph_tahinitialarabic }, + { 0xFEC4, glyph_tahmedialarabic }, + { 0xFEC6, glyph_zahfinalarabic }, + { 0xFEC7, glyph_zahinitialarabic }, + { 0xFEC8, glyph_zahmedialarabic }, + { 0xFECA, glyph_ainfinalarabic }, + { 0xFECB, glyph_aininitialarabic }, + { 0xFECC, glyph_ainmedialarabic }, + { 0xFECE, glyph_ghainfinalarabic }, + { 0xFECF, glyph_ghaininitialarabic }, + { 0xFED0, glyph_ghainmedialarabic }, + { 0xFED2, glyph_fehfinalarabic }, + { 0xFED3, glyph_fehinitialarabic }, + { 0xFED4, glyph_fehmedialarabic }, + { 0xFED6, glyph_qaffinalarabic }, + { 0xFED7, glyph_qafinitialarabic }, + { 0xFED8, glyph_qafmedialarabic }, + { 0xFEDA, glyph_kaffinalarabic }, + { 0xFEDB, glyph_kafinitialarabic }, + { 0xFEDC, glyph_kafmedialarabic }, + { 0xFEDE, glyph_lamfinalarabic }, + { 0xFEDF, glyph_laminitialarabic }, + { 0xFEE0, glyph_lammedialarabic }, + { 0xFEE2, glyph_meemfinalarabic }, + { 0xFEE3, glyph_meeminitialarabic }, + { 0xFEE4, glyph_meemmedialarabic }, + { 0xFEE6, glyph_noonfinalarabic }, + { 0xFEE7, glyph_nooninitialarabic }, + { 0xFEE8, glyph_noonmedialarabic }, + { 0xFEEB, glyph_hehinitialarabic }, + { 0xFEEC, glyph_hehmedialarabic }, + { 0xFEEE, glyph_wawfinalarabic }, + { 0xFEF0, glyph_alefmaksurafinalarabic }, + { 0xFEF2, glyph_yehfinalarabic }, + { 0xFEF5, glyph_lamalefmaddaaboveisolatedarabic }, + { 0xFEF6, glyph_lamalefmaddaabovefinalarabic }, + { 0xFEF7, glyph_lamalefhamzaaboveisolatedarabic }, + { 0xFEF8, glyph_lamalefhamzaabovefinalarabic }, + { 0xFEF9, glyph_lamalefhamzabelowisolatedarabic }, + { 0xFEFA, glyph_lamalefhamzabelowfinalarabic }, + { 0xFEFB, glyph_lamalefisolatedarabic }, + { 0xFEFC, glyph_lamaleffinalarabic }, + { 0xFEFF, glyph_zerowidthjoiner }, + { 0xFF01, glyph_exclammonospace }, + { 0xFF02, glyph_quotedblmonospace }, + { 0xFF03, glyph_numbersignmonospace }, + { 0xFF04, glyph_dollarmonospace }, + { 0xFF05, glyph_percentmonospace }, + { 0xFF06, glyph_ampersandmonospace }, + { 0xFF07, glyph_quotesinglemonospace }, + { 0xFF08, glyph_parenleftmonospace }, + { 0xFF09, glyph_parenrightmonospace }, + { 0xFF0A, glyph_asteriskmonospace }, + { 0xFF0B, glyph_plusmonospace }, + { 0xFF0C, glyph_commamonospace }, + { 0xFF0D, glyph_hyphenmonospace }, + { 0xFF0E, glyph_periodmonospace }, + { 0xFF0F, glyph_slashmonospace }, + { 0xFF10, glyph_zeromonospace }, + { 0xFF11, glyph_onemonospace }, + { 0xFF12, glyph_twomonospace }, + { 0xFF13, glyph_threemonospace }, + { 0xFF14, glyph_fourmonospace }, + { 0xFF15, glyph_fivemonospace }, + { 0xFF16, glyph_sixmonospace }, + { 0xFF17, glyph_sevenmonospace }, + { 0xFF18, glyph_eightmonospace }, + { 0xFF19, glyph_ninemonospace }, + { 0xFF1A, glyph_colonmonospace }, + { 0xFF1B, glyph_semicolonmonospace }, + { 0xFF1C, glyph_lessmonospace }, + { 0xFF1D, glyph_equalmonospace }, + { 0xFF1E, glyph_greatermonospace }, + { 0xFF1F, glyph_questionmonospace }, + { 0xFF20, glyph_atmonospace }, + { 0xFF21, glyph_Amonospace }, + { 0xFF22, glyph_Bmonospace }, + { 0xFF23, glyph_Cmonospace }, + { 0xFF24, glyph_Dmonospace }, + { 0xFF25, glyph_Emonospace }, + { 0xFF26, glyph_Fmonospace }, + { 0xFF27, glyph_Gmonospace }, + { 0xFF28, glyph_Hmonospace }, + { 0xFF29, glyph_Imonospace }, + { 0xFF2A, glyph_Jmonospace }, + { 0xFF2B, glyph_Kmonospace }, + { 0xFF2C, glyph_Lmonospace }, + { 0xFF2D, glyph_Mmonospace }, + { 0xFF2E, glyph_Nmonospace }, + { 0xFF2F, glyph_Omonospace }, + { 0xFF30, glyph_Pmonospace }, + { 0xFF31, glyph_Qmonospace }, + { 0xFF32, glyph_Rmonospace }, + { 0xFF33, glyph_Smonospace }, + { 0xFF34, glyph_Tmonospace }, + { 0xFF35, glyph_Umonospace }, + { 0xFF36, glyph_Vmonospace }, + { 0xFF37, glyph_Wmonospace }, + { 0xFF38, glyph_Xmonospace }, + { 0xFF39, glyph_Ymonospace }, + { 0xFF3A, glyph_Zmonospace }, + { 0xFF3B, glyph_bracketleftmonospace }, + { 0xFF3C, glyph_backslashmonospace }, + { 0xFF3D, glyph_bracketrightmonospace }, + { 0xFF3E, glyph_asciicircummonospace }, + { 0xFF3F, glyph_underscoremonospace }, + { 0xFF40, glyph_gravemonospace }, + { 0xFF41, glyph_amonospace }, + { 0xFF42, glyph_bmonospace }, + { 0xFF43, glyph_cmonospace }, + { 0xFF44, glyph_dmonospace }, + { 0xFF45, glyph_emonospace }, + { 0xFF46, glyph_fmonospace }, + { 0xFF47, glyph_gmonospace }, + { 0xFF48, glyph_hmonospace }, + { 0xFF49, glyph_imonospace }, + { 0xFF4A, glyph_jmonospace }, + { 0xFF4B, glyph_kmonospace }, + { 0xFF4C, glyph_lmonospace }, + { 0xFF4D, glyph_mmonospace }, + { 0xFF4E, glyph_nmonospace }, + { 0xFF4F, glyph_omonospace }, + { 0xFF50, glyph_pmonospace }, + { 0xFF51, glyph_qmonospace }, + { 0xFF52, glyph_rmonospace }, + { 0xFF53, glyph_smonospace }, + { 0xFF54, glyph_tmonospace }, + { 0xFF55, glyph_umonospace }, + { 0xFF56, glyph_vmonospace }, + { 0xFF57, glyph_wmonospace }, + { 0xFF58, glyph_xmonospace }, + { 0xFF59, glyph_ymonospace }, + { 0xFF5A, glyph_zmonospace }, + { 0xFF5B, glyph_braceleftmonospace }, + { 0xFF5C, glyph_barmonospace }, + { 0xFF5D, glyph_bracerightmonospace }, + { 0xFF5E, glyph_asciitildemonospace }, + { 0xFF61, glyph_periodhalfwidth }, + { 0xFF62, glyph_cornerbracketlefthalfwidth }, + { 0xFF63, glyph_cornerbracketrighthalfwidth }, + { 0xFF64, glyph_ideographiccommaleft }, + { 0xFF65, glyph_middledotkatakanahalfwidth }, + { 0xFF66, glyph_wokatakanahalfwidth }, + { 0xFF67, glyph_asmallkatakanahalfwidth }, + { 0xFF68, glyph_ismallkatakanahalfwidth }, + { 0xFF69, glyph_usmallkatakanahalfwidth }, + { 0xFF6A, glyph_esmallkatakanahalfwidth }, + { 0xFF6B, glyph_osmallkatakanahalfwidth }, + { 0xFF6C, glyph_yasmallkatakanahalfwidth }, + { 0xFF6D, glyph_yusmallkatakanahalfwidth }, + { 0xFF6E, glyph_yosmallkatakanahalfwidth }, + { 0xFF6F, glyph_tusmallkatakanahalfwidth }, + { 0xFF70, glyph_katahiraprolongmarkhalfwidth }, + { 0xFF71, glyph_akatakanahalfwidth }, + { 0xFF72, glyph_ikatakanahalfwidth }, + { 0xFF73, glyph_ukatakanahalfwidth }, + { 0xFF74, glyph_ekatakanahalfwidth }, + { 0xFF75, glyph_okatakanahalfwidth }, + { 0xFF76, glyph_kakatakanahalfwidth }, + { 0xFF77, glyph_kikatakanahalfwidth }, + { 0xFF78, glyph_kukatakanahalfwidth }, + { 0xFF79, glyph_kekatakanahalfwidth }, + { 0xFF7A, glyph_kokatakanahalfwidth }, + { 0xFF7B, glyph_sakatakanahalfwidth }, + { 0xFF7C, glyph_sikatakanahalfwidth }, + { 0xFF7D, glyph_sukatakanahalfwidth }, + { 0xFF7E, glyph_sekatakanahalfwidth }, + { 0xFF7F, glyph_sokatakanahalfwidth }, + { 0xFF80, glyph_takatakanahalfwidth }, + { 0xFF81, glyph_tikatakanahalfwidth }, + { 0xFF82, glyph_tukatakanahalfwidth }, + { 0xFF83, glyph_tekatakanahalfwidth }, + { 0xFF84, glyph_tokatakanahalfwidth }, + { 0xFF85, glyph_nakatakanahalfwidth }, + { 0xFF86, glyph_nikatakanahalfwidth }, + { 0xFF87, glyph_nukatakanahalfwidth }, + { 0xFF88, glyph_nekatakanahalfwidth }, + { 0xFF89, glyph_nokatakanahalfwidth }, + { 0xFF8A, glyph_hakatakanahalfwidth }, + { 0xFF8B, glyph_hikatakanahalfwidth }, + { 0xFF8C, glyph_hukatakanahalfwidth }, + { 0xFF8D, glyph_hekatakanahalfwidth }, + { 0xFF8E, glyph_hokatakanahalfwidth }, + { 0xFF8F, glyph_makatakanahalfwidth }, + { 0xFF90, glyph_mikatakanahalfwidth }, + { 0xFF91, glyph_mukatakanahalfwidth }, + { 0xFF92, glyph_mekatakanahalfwidth }, + { 0xFF93, glyph_mokatakanahalfwidth }, + { 0xFF94, glyph_yakatakanahalfwidth }, + { 0xFF95, glyph_yukatakanahalfwidth }, + { 0xFF96, glyph_yokatakanahalfwidth }, + { 0xFF97, glyph_rakatakanahalfwidth }, + { 0xFF98, glyph_rikatakanahalfwidth }, + { 0xFF99, glyph_rukatakanahalfwidth }, + { 0xFF9A, glyph_rekatakanahalfwidth }, + { 0xFF9B, glyph_rokatakanahalfwidth }, + { 0xFF9C, glyph_wakatakanahalfwidth }, + { 0xFF9D, glyph_nkatakanahalfwidth }, + { 0xFF9E, glyph_voicedmarkkanahalfwidth }, + { 0xFF9F, glyph_semivoicedmarkkanahalfwidth }, + { 0xFFE0, glyph_centmonospace }, + { 0xFFE1, glyph_sterlingmonospace }, + { 0xFFE3, glyph_macronmonospace }, + { 0xFFE5, glyph_yenmonospace }, + { 0xFFE6, glyph_wonmonospace }, +}; /* tab_uni2diffagl */ + +/* List of all ambiguous AGL version 1.2 glyph names + * (see chapter 4.c. Double-mappings in + * http://partners.adobe.com/asn/tech/type/unicodegn-old.jsp) + */ + +static const pdc_glyph_tab tab_double_mappping[] = +{ +#ifndef PDFLIB_EBCDIC + { 0x0394, glyph_Delta }, /* Deltagreek */ + { 0x03A9, glyph_Omega }, /* Omegagreek */ + { 0xF6C1, glyph_Scedilla }, /* (CUS) */ + { 0x0162, glyph_Tcommaaccent }, /* (wrong mapping) */ + { 0x2215, glyph_fraction }, /* divisionslash */ + { 0x00AD, glyph_hyphen }, /* sfthyphen */ + { 0x02C9, glyph_macron }, /* firsttonechinese */ + { 0x03BC, glyph_mu }, /* mugreek */ + { 0x2219, glyph_periodcentered }, /* bulletoperator */ + { 0xF6C2, glyph_scedilla }, /* (CUS) */ + { 0x00A0, glyph_space }, /* nbspace */ + { 0x0163, glyph_tcommaaccent }, /* (wrong mapping) */ +#else +#endif +}; + + +/* This is the list of all character names of the Adobe + * standard Latin character set and the set of named characters + * in the Symbol font, documented in Appendix D of PDF Reference. + */ + +static const char *pc_standard_latin_charset[] = +{ +#ifndef PDFLIB_EBCDIC + glyph_A, + glyph_AE, + glyph_Aacute, + glyph_Acircumflex, + glyph_Adieresis, + glyph_Agrave, + glyph_Alpha, + glyph_Aring, + glyph_Atilde, + glyph_B, + glyph_Beta, + glyph_C, + glyph_Ccedilla, + glyph_Chi, + glyph_D, + glyph_Delta, + glyph_E, + glyph_Eacute, + glyph_Ecircumflex, + glyph_Edieresis, + glyph_Egrave, + glyph_Epsilon, + glyph_Eta, + glyph_Eth, + glyph_Euro, + glyph_F, + glyph_G, + glyph_Gamma, + glyph_H, + glyph_I, + glyph_Iacute, + glyph_Icircumflex, + glyph_Idieresis, + glyph_Ifraktur, + glyph_Igrave, + glyph_Iota, + glyph_J, + glyph_K, + glyph_Kappa, + glyph_L, + glyph_Lambda, + glyph_Lslash, + glyph_M, + glyph_Mu, + glyph_N, + glyph_Ntilde, + glyph_Nu, + glyph_O, + glyph_OE, + glyph_Oacute, + glyph_Ocircumflex, + glyph_Odieresis, + glyph_Ograve, + glyph_Omega, + glyph_Omicron, + glyph_Oslash, + glyph_Otilde, + glyph_P, + glyph_Phi, + glyph_Pi, + glyph_Psi, + glyph_Q, + glyph_R, + glyph_Rfraktur, + glyph_Rho, + glyph_S, + glyph_Scaron, + glyph_Sigma, + glyph_T, + glyph_Tau, + glyph_Theta, + glyph_Thorn, + glyph_U, + glyph_Uacute, + glyph_Ucircumflex, + glyph_Udieresis, + glyph_Ugrave, + glyph_Upsilon, + glyph_Upsilon1, + glyph_V, + glyph_W, + glyph_X, + glyph_Xi, + glyph_Y, + glyph_Yacute, + glyph_Ydieresis, + glyph_Z, + glyph_Zcaron, + glyph_Zeta, + glyph_a, + glyph_aacute, + glyph_acircumflex, + glyph_acute, + glyph_adieresis, + glyph_ae, + glyph_agrave, + glyph_aleph, + glyph_alpha, + glyph_ampersand, + glyph_angle, + glyph_angleleft, + glyph_angleright, + glyph_approxequal, + glyph_aring, + glyph_arrowboth, + glyph_arrowdblboth, + glyph_arrowdbldown, + glyph_arrowdblleft, + glyph_arrowdblright, + glyph_arrowdblup, + glyph_arrowdown, + glyph_arrowhorizex, + glyph_arrowleft, + glyph_arrowright, + glyph_arrowup, + glyph_arrowvertex, + glyph_asciicircum, + glyph_asciitilde, + glyph_asterisk, + glyph_asteriskmath, + glyph_at, + glyph_atilde, + glyph_b, + glyph_backslash, + glyph_bar, + glyph_beta, + glyph_braceex, + glyph_braceleft, + glyph_braceleftbt, + glyph_braceleftmid, + glyph_bracelefttp, + glyph_braceright, + glyph_bracerightbt, + glyph_bracerightmid, + glyph_bracerighttp, + glyph_bracketleft, + glyph_bracketleftbt, + glyph_bracketleftex, + glyph_bracketlefttp, + glyph_bracketright, + glyph_bracketrightbt, + glyph_bracketrightex, + glyph_bracketrighttp, + glyph_breve, + glyph_brokenbar, + glyph_bullet, + glyph_c, + glyph_caron, + glyph_carriagereturn, + glyph_ccedilla, + glyph_cedilla, + glyph_cent, + glyph_chi, + glyph_circlemultiply, + glyph_circleplus, + glyph_circumflex, + glyph_club, + glyph_colon, + glyph_comma, + glyph_congruent, + glyph_copyright, + glyph_copyrightsans, + glyph_copyrightserif, + glyph_currency, + glyph_d, + glyph_dagger, + glyph_daggerdbl, + glyph_degree, + glyph_delta, + glyph_diamond, + glyph_dieresis, + glyph_divide, + glyph_dollar, + glyph_dotaccent, + glyph_dotlessi, + glyph_dotmath, + glyph_e, + glyph_eacute, + glyph_ecircumflex, + glyph_edieresis, + glyph_egrave, + glyph_eight, + glyph_element, + glyph_ellipsis, + glyph_emdash, + glyph_emptyset, + glyph_endash, + glyph_epsilon, + glyph_equal, + glyph_equivalence, + glyph_eta, + glyph_eth, + glyph_exclam, + glyph_exclamdown, + glyph_existential, + glyph_f, + glyph_fi, + glyph_five, + glyph_fl, + glyph_florin, + glyph_four, + glyph_fraction, + glyph_g, + glyph_gamma, + glyph_germandbls, + glyph_gradient, + glyph_grave, + glyph_greater, + glyph_greaterequal, + glyph_guillemotleft, + glyph_guillemotright, + glyph_guilsinglleft, + glyph_guilsinglright, + glyph_h, + glyph_heart, + glyph_hungarumlaut, + glyph_hyphen, + glyph_i, + glyph_iacute, + glyph_icircumflex, + glyph_idieresis, + glyph_igrave, + glyph_infinity, + glyph_integral, + glyph_integralbt, + glyph_integralex, + glyph_integraltp, + glyph_intersection, + glyph_iota, + glyph_j, + glyph_k, + glyph_kappa, + glyph_l, + glyph_lambda, + glyph_less, + glyph_lessequal, + glyph_logicaland, + glyph_logicalnot, + glyph_logicalor, + glyph_lozenge, + glyph_lslash, + glyph_m, + glyph_macron, + glyph_minus, + glyph_minute, + glyph_mu, + glyph_multiply, + glyph_n, + glyph_nine, + glyph_notelement, + glyph_notequal, + glyph_notsubset, + glyph_ntilde, + glyph_nu, + glyph_numbersign, + glyph_o, + glyph_oacute, + glyph_ocircumflex, + glyph_odieresis, + glyph_oe, + glyph_ogonek, + glyph_ograve, + glyph_omega, + glyph_omega1, + glyph_omicron, + glyph_one, + glyph_onehalf, + glyph_onequarter, + glyph_onesuperior, + glyph_ordfeminine, + glyph_ordmasculine, + glyph_oslash, + glyph_otilde, + glyph_p, + glyph_paragraph, + glyph_parenleft, + glyph_parenleftbt, + glyph_parenleftex, + glyph_parenlefttp, + glyph_parenright, + glyph_parenrightbt, + glyph_parenrightex, + glyph_parenrighttp, + glyph_partialdiff, + glyph_percent, + glyph_period, + glyph_periodcentered, + glyph_perpendicular, + glyph_perthousand, + glyph_phi, + glyph_phi1, + glyph_pi, + glyph_plus, + glyph_plusminus, + glyph_product, + glyph_propersubset, + glyph_propersuperset, + glyph_proportional, + glyph_psi, + glyph_q, + glyph_question, + glyph_questiondown, + glyph_quotedbl, + glyph_quotedblbase, + glyph_quotedblleft, + glyph_quotedblright, + glyph_quoteleft, + glyph_quoteright, + glyph_quotesinglbase, + glyph_quotesingle, + glyph_r, + glyph_radical, + glyph_radicalex, + glyph_reflexsubset, + glyph_reflexsuperset, + glyph_registered, + glyph_registersans, + glyph_registerserif, + glyph_rho, + glyph_ring, + glyph_s, + glyph_scaron, + glyph_second, + glyph_section, + glyph_semicolon, + glyph_seven, + glyph_sigma, + glyph_sigma1, + glyph_similar, + glyph_six, + glyph_slash, + glyph_space, + glyph_spade, + glyph_sterling, + glyph_suchthat, + glyph_summation, + glyph_t, + glyph_tau, + glyph_therefore, + glyph_theta, + glyph_theta1, + glyph_thorn, + glyph_three, + glyph_threequarters, + glyph_threesuperior, + glyph_tilde, + glyph_trademark, + glyph_trademarksans, + glyph_trademarkserif, + glyph_two, + glyph_twosuperior, + glyph_u, + glyph_uacute, + glyph_ucircumflex, + glyph_udieresis, + glyph_ugrave, + glyph_underscore, + glyph_union, + glyph_universal, + glyph_upsilon, + glyph_v, + glyph_w, + glyph_weierstrass, + glyph_x, + glyph_xi, + glyph_y, + glyph_yacute, + glyph_ydieresis, + glyph_yen, + glyph_z, + glyph_zcaron, + glyph_zero, + glyph_zeta, +#else +#endif +}; + + +/* --------------------------------- TET tables ---------------------------- */ + + +#endif /* PC_CHARTABS_H */ diff --git a/src/pdflib/pdcore/pc_classic.h b/src/pdflib/pdcore/pc_classic.h new file mode 100644 index 0000000..cd6c22c --- /dev/null +++ b/src/pdflib/pdcore/pc_classic.h @@ -0,0 +1,24 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_classic.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Header for CodeWarrior to activate Classic builds (without CarbonLib). + * + */ + +/* + * This must only be set for Classic builds. It is not used for the + * standard build which is based on CarbonLib. + */ + +#define PDF_TARGET_API_MAC_CLASSIC diff --git a/src/pdflib/pdcore/pc_config.h b/src/pdflib/pdcore/pc_config.h new file mode 100644 index 0000000..945c9d1 --- /dev/null +++ b/src/pdflib/pdcore/pc_config.h @@ -0,0 +1,388 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_config.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib portability and configuration definitions + * + */ + +#ifndef PC_CONFIG_H +#define PC_CONFIG_H + +/* ------------------------ feature configuration ------------------- */ + +/* zlib compression support */ +#define HAVE_LIBZ + +/* ---------------------------- platform definitions ------------------------ */ + +/* #undef this if your platform doesn't support environment variables */ +#define HAVE_ENVVARS + +/* Compilers which are not strictly ANSI conforming can set PDF_VOLATILE + * to an empty value. + */ +#ifndef PDF_VOLATILE +#define PDF_VOLATILE volatile +#endif + +/* + * Byte order + * WORDS_BIGENDIAN will be set by the configure script on most platforms. + * Only on platforms where there is no configure script we must set the + * endianness explicitly (most importantly CodeWarrior on the Mac) + */ +#undef PDC_ISBIGENDIAN +#if defined(WORDS_BIGENDIAN) || defined(__POWERPC__) || defined(__MC68K__) +#define PDC_ISBIGENDIAN 1 +#if !defined(WORDS_BIGENDIAN) +#define WORDS_BIGENDIAN +#endif +#else +#define PDC_ISBIGENDIAN 0 +#endif + +/* + * Define for compiler supporting file open function _wfopen + * for Unicode filenames. + */ +#undef PDC_UNICODE_FILENAME + +/* + * Define whether function char *strerror(int errnum) + * is available in the C runtime system + */ +#define PDC_HAS_STRERROR + + +/* ---------------------------------- WIN32 -------------------------------- */ + +/* try to identify Windows compilers */ + +#if (defined _WIN32 || defined __WATCOMC__ || defined __BORLANDC__ || \ + (defined(__MWERKS__) && defined(__INTEL__))) && !defined WIN32 +#define WIN32 +#endif /* && !defined WIN32 */ + +#ifdef WIN32 +#define WRITEMODE "wb" +#define APPENDMODE "ab" + +#ifdef _MSC_VER +#define _LARGEFILE_SOURCE +#endif + +#undef PDC_PATHSEP +#define PDC_PATHSEP "\\" + +#if defined(_WIN32_WCE) && (_WIN32_WCE >= 300) +#define PDF_PLATFORM "Windows CE" +#define WINCE +#undef HAVE_SETLOCALE +#undef HAVE_ENVVARS +#else +#if defined(WIN64) +#define PDF_PLATFORM "Win64" +#else +#define PDF_PLATFORM "Win32" +#endif +#endif + +#define PDC_TMPDIR_ENV "TMP" + +/* file open function "_wfopen" for Unicode filenames is available. +**/ +#if defined(_MSC_VER) && !defined(PDF_WIN98) +#define PDC_UNICODE_FILENAME +#endif + +#endif /* WIN32 */ + +/* some standard C library functions (eg. localtime()) are not reentrant +** and must be replaced with their "_r" equivalent (eg. localtime_r()). +*/ +#if !defined(WIN32) && !defined(__MVS__) && !defined(OS_ZOS_SASC) &&\ + !(defined(__MWERKS__) && (defined(__POWERPC__) || defined(__MC68K__))) +#define PDC_NEEDS_R_FUNCTIONS +#endif + +/* --------------------------------- Cygnus -------------------------------- */ + +#ifdef __CYGWIN__ +#define WRITEMODE "wb" +#define APPENDMODE "ab" +#ifdef DLL_EXPORT + #define PDFLIB_EXPORTS +#endif + +#endif /* __CYGWIN__ */ + +/* ---------------------------------- DJGPP -------------------------------- */ + +#ifdef __DJGPP__ +#define WRITEMODE "wb" +#define APPENDMODE "ab" +#define PDF_PLATFORM "Win32/DJGPP" +#endif /* __DJGPP__ */ + +/* ----------------------------------- OS/2 -------------------------------- */ + +/* + * Try to identify OS/2 compilers. + */ + +#if (defined __OS2__ || defined __EMX__) && !defined OS2 +#define OS2 +#endif + +#ifdef OS2 +#define WRITEMODE "wb" +#define APPENDMODE "ab" +#define PDF_PLATFORM "OS/2" +#endif /* OS2 */ + +/* --------------------------------- Mac OS X ------------------------------- */ + +/* try to identify the Mac OS X command line compiler */ + +#if (defined(__ppc__) && defined(__APPLE__)) \ + || (defined(__i386__) && defined(__APPLE__)) + +/* #define MACOSX CDPDF */ + +/* Mac OS X 10.2 (Jaguar) defines this, but we use it for Mac OS 9 below */ +#undef MAC + +#ifndef PDF_PLATFORM +#define PDF_PLATFORM "Mac OS X" +#endif +#endif /* Mac OS X */ + +/* --------------------------------- Mac OS 9 ------------------------------- */ + +/* try to identify Mac OS 9 compilers */ + +#if (defined macintosh || defined __POWERPC__ || defined __CFM68K__) && \ + !defined MAC && !defined MACOSX && !defined __BEOS__ +#define MAC +#endif + +#undef MAC /* CDPDF */ +#undef MACOSX /* CDPDF */ + +#ifdef MAC +#define WRITEMODE "wb" +#define APPENDMODE "ab" +#define PDC_PATHSEP ":" + +#undef HAVE_ENVVARS + +#define PDF_PLATFORM "Mac OS 9" +#endif /* MAC */ + +/* ------------------ Carbon Handling for both Mac OS 9 and X --------------- */ + +#if defined(MAC) || defined(MACOSX) +/* + * By default we always build a carbonized version of the library, + * but allow non-Carbon builds to be triggered by setting the + * PDF_TARGET_API_MAC_CLASSIC symbol externally. + */ + +#ifdef PDF_TARGET_API_MAC_CLASSIC +#undef PDF_TYPE1_HOSTFONT_SUPPORTED +#else +#define PDF_TARGET_API_MAC_CARBON +#endif + +#if defined(PDF_TARGET_API_MAC_CARBON) && !defined(TARGET_API_MAC_CARBON) +#define TARGET_API_MAC_CARBON 1 +#endif + +#endif /* MAC */ + +/* ----------------------------------- BeOS --------------------------------- */ + +#ifdef __BEOS__ +#define PDF_PLATFORM "BeOS" +#endif /* __BEOS__ */ + +/* --------------------------------- AS/400 --------------------------------- */ + +/* try to identify the AS/400 compiler */ + +#if defined __ILEC400__ && !defined AS400 +#define AS400 +#endif + +#ifdef AS400 + +#pragma comment(copyright, \ + "(C) PDFlib GmbH, Muenchen, Germany (www.pdflib.com)") + +#if (_OS400_TGTVRM__>440) +# ifndef _LARGE_FILE_API + #error You need to compile this module with DEFINE(_LARGE_FILE_API) +# endif +# ifndef __TERASPACE__ + #error You need to compile this module with TERASPACE(*YES *TSIFC) +STGMDL(*TERASPACE) +# endif +#endif + +#define READTMODE "rb" +#define WRITEMODE "wb" +#define APPENDMODE "ab" + +#define PDF_PLATFORM "iSeries" + +#define WORDS_BIGENDIAN +#undef PDC_ISBIGENDIAN +#define PDC_ISBIGENDIAN 1 + +#endif /* AS400 */ + +/* --------------------- S/390 with Unix System Services -------------------- */ + +#ifdef OS390 + +#define WRITEMODE "wb" +#define APPENDMODE "ab" + +#undef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#undef PDC_ISBIGENDIAN +#define PDC_ISBIGENDIAN 1 + +#define PDC_NO_VSNPRINTF + +#endif /* OS390 */ + +/* -------------------------------- S/390 with MVS -------------------------- */ + +/* try to identify MVS (__MVS__ is #defined on USS and MVS!) + * I370 is used by SAS C + */ + +#if !defined(OS390) && (defined __MVS__ || defined I370) && !defined MVS +#define MVS +#endif + +#ifdef MVS + +#if defined(I370) +#define PDC_FILEQUOT "" +#else +#define READBMODE "rb,byteseek" +#define READBMODE_PLUS "rb+,byteseek" +#define PDC_FILEQUOT "'" +#endif +#define WRITEMODE "wb" +#define WRITEMODE_V "wb,recfm=v" +#define APPENDMODE "ab" + +#undef PDC_PATHSEP +#define PDC_PATHSEP "(" + +#undef PDC_PATHTERM +#define PDC_PATHTERM ")" + +#define PDF_PLATFORM "zSeries MVS" +#define PDF_OS390_MVS_RESOURCE + +#define WORDS_BIGENDIAN +#undef PDC_ISBIGENDIAN +#define PDC_ISBIGENDIAN 1 + +#define PDC_NO_VSNPRINTF + +#endif /* MVS */ + +/* ------------------------------------ VMS --------------------------------- */ + +/* No special handling required */ + +#ifdef VMS +/* Usually this will come from the build process */ +#ifndef PDF_PLATFORM +#define PDF_PLATFORM "VMS" +#endif +#define PDC_TMPDIR_ENV "SYS$SCRATCH" +#define PDC_PATHSEP_LOG ":" + +#define PDC_NO_VSNPRINTF + +#endif /* VMS */ + +/* --------------------------------- Defaults ------------------------------- */ + +/* CDPDF */ +#ifndef PDF_PLATFORM +#define PDF_PLATFORM "Default" +#endif /* !PDF_PLATFORM */ + +/* boolean for function fileno() exists +*/ +#ifndef PDC_FILENO_EXISTS +#define PDC_FILENO_EXISTS 1 +#endif /* !PDC_FILENO_EXISTS */ + +#ifndef READTMODE +#define READTMODE "r" +#endif /* !READTMODE */ + +#ifndef READBMODE +#define READBMODE "rb" +#endif /* !READBMODE */ + +#ifndef READBMODE_PLUS +#define READBMODE_PLUS "rb+" +#endif /* !READBMODE_PLUS */ + +#ifndef WRITEMODE +#define WRITEMODE "wb" +#endif /* !WRITEMODE */ + +#ifndef APPENDMODE +#define APPENDMODE "ab" +#endif /* !APPENDMODE */ + +#ifndef PDC_PATHSEP +#define PDC_PATHSEP "/" +#endif /* !PDC_PATHSEP */ + +#ifndef PDC_TMPDIR_ENV +#define PDC_TMPDIR_ENV "TMPDIR" +#endif /* !PDC_TMPDIR_ENV */ + +#ifdef _DEBUG +#define DEBUG +#endif /* _DEBUG */ + +#ifdef DEBUG +#define PDC_DEBUG +#endif /* DEBUG */ + +#define PDC_SCHAR_MIN (-128) +#define PDC_SCHAR_MAX 127 +#define PDC_UCHAR_MAX 255 +#define PDC_SHRT_MIN (-32768) +#define PDC_SHRT_MAX 32767 +#define PDC_USHRT_MAX 65535 +#define PDC_INT_MIN (-PDC_INT_MAX - 1) +#define PDC_INT_MAX 2147483647 +#define PDC_UINT_MAX 4294967295U + +#define PDC_OFFSET(type, field) ((unsigned int) &(((type *)NULL)->field)) + +#endif /* PC_CONFIG_H */ diff --git a/src/pdflib/pdcore/pc_contain.c b/src/pdflib/pdcore/pc_contain.c new file mode 100644 index 0000000..6a3cdfc --- /dev/null +++ b/src/pdflib/pdcore/pc_contain.c @@ -0,0 +1,518 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_contain.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib generic container classes + * + */ + +#include "pc_util.h" +#include "pc_contain.h" + + +/**************************** avl tree class ****************************/ + +typedef struct avl_node_s avl_node; + +struct avl_node_s +{ + const char *name; + int balance; + avl_node * left; + avl_node * right; +}; + +#undef COMMENT +#ifdef COMMENT + +before single rotate right; after insertion of X. + + root(-2) + + / \ + + lc(-1) +------+ + | rc | + / \ | | + | | + +------+ +------+ | | + | llc | | rlc | | n | + | | | | +------+ + | | | | + | | | | + | n | | n | + +------+ +------+ + + | + + X + + +after single rotate right. + + lc(0) + + / \ + + +------+ root(0) + | llc | + | | / \ + | | + | | +------+ +------+ + | n | | rlc | | rc | + +------+ | | | | + | | | | + | | | | | + | n | | n | + X +------+ +------+ + + + +before double rotate right; after insertion of X/Y. + + root(-2) + + / \ + + lc(+1) +------+ + | rc | + / \ | | + | | + +------+ rlc(-1/+1) | | + | llc | | | + | | / \ | | + | | | | + | | +------+ +------+ | n | + | | | lrlc | | rrlc | +------+ + | | | | | | + | | | | | | + | n | | n-1 | | n-1 | + +------+ +------+ +------+ + + | | + + X Y + + +after double rotate right: + + rlc(0) + + / \ + + lc(0/-1) root(+1/0) + + / \ / \ + + +------+ +------+ +------+ +------+ + | llc | | lrlc | | rrlc | | rc | + | | | | | | | | + | | | | | | | | + | | | n-1 | | n-1 | | | + | | +------+ +------+ | | + | | | | + | | | | | | + | n | | n | + +------+ X Y +------+ + + +avl_node * +avl_insert(avl_node *root, const char *name, pdc_bool *change_parent_balance) +{ + pdc_bool change_balance = pdc_false; + + if (root == 0) + { + avl_node *result = (avl_node *) malloc(sizeof (avl_node)); + + result->name = name; + result->balance = 0; + result->left = (avl_node *) 0; + result->right = (avl_node *) 0; + *change_parent_balance = pdc_true; + return result; + } + + if (strcmp(name, root->name) < 0) + { + root->left = avl_insert(root->left, name, &change_balance); + + if (change_balance && --root->balance < 0) + { + if (root->balance == -1) + { + *change_parent_balance = pdc_true; + } + else /* root->balance == -2 */ + { + avl_node *lc = root->left; /* left child */ + avl_node *rlc = lc->right; /* right of left child */ + + if (lc->balance == -1) /* single rotate right */ + { + root->left = rlc; + lc->right = root; + lc->balance = root->balance = 0; + return lc; + } + else /* double rotate right */ + { + root->balance = (rlc->balance == -1) ? +1 : 0; + lc->balance = (rlc->balance == +1) ? -1 : 0; + rlc->balance = 0; + lc->right = rlc->left; + rlc->left = lc; + root->left = rlc->right; + rlc->right = root; + return rlc; + } + } + } + } + else + { + root->right = avl_insert(root->right, name, &change_balance); + + if (change_balance && ++root->balance > 0) + { + if (root->balance == +1) + { + *change_parent_balance = pdc_true; + } + else /* root->balance == +2 */ + { + avl_node *rc = root->right; /* right child */ + avl_node *lrc = rc->left; /* left of right child */ + + if (rc->balance == +1) /* single rotate left */ + { + root->right = lrc; + rc->left = root; + rc->balance = root->balance = 0; + return rc; + } + else /* double rotate left */ + { + root->balance = (lrc->balance == +1) ? -1 : 0; + rc->balance = (lrc->balance == -1) ? +1 : 0; + lrc->balance = 0; + rc->left = lrc->right; + lrc->right = rc; + root->right = lrc->left; + lrc->left = root; + return lrc; + } + } + } + } + + return root; +} + +#endif /* COMMENT */ + +/***************************** vector class *****************************/ + +struct pdc_vtr_s +{ + pdc_core * pdc; + + pdc_ced ced; /* container entry descriptor */ + void * context; /* client context */ + + char ** ctab; /* chunk table */ + int ctab_size; /* current # of slots */ + int ctab_incr; + int chunk_size; /* # of items per chunk */ + int size; /* current # of items total */ +}; + + +static const pdc_vtr_parms vtr_dflt_parms = +{ + 0, /* init_size */ + 100, /* chunk_size */ + 10 /* ctab_incr */ +}; + +void +pdc_vtr_dflt_parms(pdc_vtr_parms *vp) +{ + *vp = vtr_dflt_parms; +} + + +static void +pdc_vtr_grow_ctab(pdc_vtr *v, int new_size) +{ + static const char fn[] = "pdc_vtr_grow_ctab"; + + int i; + + v->ctab = (char **) + pdc_realloc(v->pdc, v->ctab, (size_t) (new_size * sizeof (char *)), fn); + + for (i = v->ctab_size; i < new_size; ++i) + v->ctab[i] = (char *) 0; + + v->ctab_size = new_size; +} /* pdc_vtr_grow_ctab */ + + +pdc_vtr * +pdc_vtr_new( + pdc_core *pdc, + const pdc_ced *ced, + void *context, + const pdc_vtr_parms *parms) +{ + static const char fn[] = "pdc_vtr_new"; + + pdc_vtr *v = (pdc_vtr *) pdc_malloc(pdc, sizeof (pdc_vtr), fn); + + if (!parms) + parms = &vtr_dflt_parms; + + v->pdc = pdc; + v->ced = *ced; + v->context = context ? context : pdc; + + v->ctab = (char **) 0; + v->ctab_size = 0; + v->ctab_incr = parms->ctab_incr; + v->chunk_size = parms->chunk_size; + v->size = 0; + + if (parms->init_size != 0) + { + PDC_TRY (pdc) + { + pdc_vtr_resize(v, parms->init_size); + } + PDC_CATCH (pdc) + { + pdc_vtr_delete(v); + PDC_RETHROW(pdc); + } + } + + return v; +} /* pdc_vtr_new */ + + +void +pdc_vtr_delete(pdc_vtr *v) +{ + int cs = v->chunk_size; + int i; + + if (v->size != 0 && v->ced.release) + { + for (i = 0; i < v->size; ++i) + { + v->ced.release(v->context, (void *) + &v->ctab[i / cs][(i % cs) * v->ced.size]); + } + } + + for (i = 0; i < v->ctab_size && v->ctab[i] != (char *) 0; ++i) + { + pdc_free(v->pdc, v->ctab[i]); + } + + if (v->ctab) + pdc_free(v->pdc, v->ctab); + + pdc_free(v->pdc, v); +} /* pdc_vtr_delete */ + + +int +pdc_vtr_size(const pdc_vtr *v) +{ + return (int) v->size; +} /* pdc_vtr_size */ + + +void +pdc_vtr_resize(pdc_vtr *v, int new_size) +{ + static const char fn[] = "pdc_vtr_resize"; + + int cs = v->chunk_size; + + PDC_ASSERT(v->pdc, 0 <= new_size); + + if (new_size < v->size) + { + if (!v->ced.release) + { + v->size = new_size; + } + else + { + do + { + --v->size; + + v->ced.release(v->context, (void *) + &v->ctab[v->size / cs][(v->size % cs) * v->ced.size]); + } while (new_size < v->size); + } + + /* TODO: free chunks if possible? */ + } + else if (new_size > v->size) + { + int curr_slot = v->size / cs; + int new_ctsize = (new_size + cs - 1) / cs; + int i; + + if (v->ctab_size < new_ctsize) + pdc_vtr_grow_ctab(v, new_ctsize); + + for (i = curr_slot; i < new_ctsize; ++i) + { + if (v->ctab[i] == (char *) 0) + { + v->ctab[i] = (char *) + pdc_malloc(v->pdc, (size_t) (cs * v->ced.size), fn); + } + } + + if (v->ced.reclaim) + { + for (i = v->size; i < new_size; ++i) + { + v->ced.reclaim((void *) &v->ctab[i/cs][(i%cs) * v->ced.size]); + } + } + + v->size = new_size; + } +} /* pdc_vtr_resize */ + + +void * +pdc__vtr_at(const pdc_vtr *v, int idx) +{ + static const char fn[] = "pdc__vtr_at"; + + int cs = v->chunk_size; + + if (idx < 0 || v->size <= idx) + pdc_error(v->pdc, PDC_E_INT_ARRIDX, + pdc_errprintf(v->pdc, "%d", idx), fn, 0, 0); + /* TODO: "%u" */ + + return (void *) (&v->ctab[idx / cs][(idx % cs) * v->ced.size]); +} /* pdc__vtr_at */ + + +#if 0 +const void * +pdc__vtr_at_c(const pdc_vtr *v, int idx) +{ + static const char fn[] = "pdc__vtr_at_c"; + + int cs = v->chunk_size; + + if (idx < 0 || v->size <= idx) + pdc_error(v->pdc, PDC_E_INT_ARRIDX, + pdc_errprintf(v->pdc, "%d", idx), fn, 0, 0); + /* TODO: "%u" */ + + return (const void *) (&v->ctab[idx / cs][(idx % cs) * v->ced.size]); +} /* pdc__vtr_at_c */ +#endif + + +void * +pdc__vtr_top(const pdc_vtr *v) +{ + int cs = v->chunk_size; + int idx; + + if (v->size == 0) + return (void *) 0; + + idx = v->size - 1; + return (void *) (&v->ctab[idx / cs][(idx % cs) * v->ced.size]); +} /* pdc__vtr_top */ + + +#if 0 +const void * +pdc__vtr_top_c(const pdc_vtr *v) +{ + int cs = v->chunk_size; + int idx; + + if (v->size == 0) + return (void *) 0; + + idx = v->size - 1; + return (const void *) (&v->ctab[idx / cs][(idx % cs) * v->ced.size]); +} /* pdc__vtr_top_c */ +#endif + + +void * +pdc__vtr_push(pdc_vtr *v) +{ + static char fn[] = "pdc__vtr_push"; + + int cs = v->chunk_size; + int idx = v->size; + int slot = idx / cs; + char *target; + + if (v->ctab_size <= slot) + pdc_vtr_grow_ctab(v, v->ctab_size + v->ctab_incr); + + if (v->ctab[slot] == (char *) 0) + { + v->ctab[slot] = (char *) + pdc_malloc(v->pdc, (size_t) (cs * v->ced.size), fn); + } + + ++v->size; + target = &v->ctab[slot][(idx % cs) * v->ced.size]; + + if (v->ced.reclaim) + { + v->ced.reclaim((void *) target); + } + + return (void *) target; +} /* pdc__vtr_push */ + + +void +pdc_vtr_pop(pdc_vtr *v) +{ + static char fn[] = "pdc_vtr_pop"; + + int cs = v->chunk_size; + + if (v->size == 0) + pdc_error(v->pdc, PDC_E_INT_STACK_UNDER, fn, 0, 0, 0); + + --v->size; + + if (v->ced.release) + { + v->ced.release(v->context, (void *) + &v->ctab[v->size / cs][(v->size % cs) * v->ced.size]); + } +} /* pdc_vtr_pop */ diff --git a/src/pdflib/pdcore/pc_contain.h b/src/pdflib/pdcore/pc_contain.h new file mode 100644 index 0000000..007bfd0 --- /dev/null +++ b/src/pdflib/pdcore/pc_contain.h @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_contain.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib generic container classes + * + */ + +#ifndef PC_CONTAIN_H +#define PC_CONTAIN_H + +/* container entry descriptor +*/ +typedef struct +{ + size_t size; + + void (*reclaim)(void *item); + void (*release)(void *context, void *item); + int (*compare)(const void *lhs, const void *rhs); +} pdc_ced; + + +/* callback functions for the "for_each" methods +*/ +typedef void (*pdc_for_each_cb)(void *context, void *item); + + +/**************************** avl tree class ****************************/ + +typedef struct pdc_avl_s pdc_avl; + +pdc_avl * pdc_avl_new(pdc_core *pdc, const pdc_ced *ced, void *context); +void pdc_avl_delete(pdc_avl *t); +int pdc_avl_size(const pdc_avl *t); +void * pdc_avl_insert(pdc_avl *t, const void *item); +void pdc_avl_for_each(const pdc_avl *t, pdc_for_each_cb cb); + + +/***************************** vector class *****************************/ + +typedef struct pdc_vtr_s pdc_vtr; + +typedef struct +{ + int init_size; + int chunk_size; + int ctab_incr; +} pdc_vtr_parms; + +void pdc_vtr_dflt_parms(pdc_vtr_parms *vp); + +pdc_vtr * pdc_vtr_new(pdc_core *pdc, const pdc_ced *ced, void *context, + const pdc_vtr_parms *parms); + +void pdc_vtr_delete(pdc_vtr *v); +int pdc_vtr_size(const pdc_vtr *v); +void pdc_vtr_resize(pdc_vtr *v, int size); +void pdc_vtr_pop(pdc_vtr *v); + +/* don't use the pdc__vtr_xxx() functions directly. +** use the respective pdc_vtr_xxx() macros below. +*/ +void * pdc__vtr_at(const pdc_vtr *v, int idx); +void * pdc__vtr_top(const pdc_vtr *v); +void * pdc__vtr_push(pdc_vtr *v); + + +/* pdc_vtr_at(const pdc_vtr *v, int idx, ); +** +** () v[idx] +*/ +#define pdc_vtr_at(v, idx, type) \ + (*((type *) pdc__vtr_at(v, idx))) + + +/* pdc_vtr_top(const pdc_vtr *v, ); +** +** () v[vsize-1] +*/ +#define pdc_vtr_top(v, type) \ + (*((type *) pdc__vtr_top(v))) + + +/* void pdc_vtr_push(pdc_vtr *v, item, ); +** +** () v[vsize++] = item +*/ +#define pdc_vtr_push(v, item, type) \ + (*((type *) pdc__vtr_push(v)) = item) + + +/* * pdc_vtr_incr(pdc_vtr *v, ); +** +** ( *) &v[vsize++] +*/ +#define pdc_vtr_incr(v, type) \ + ((type *) pdc__vtr_push(v)) + +#endif /* PC_CONTAIN_H */ diff --git a/src/pdflib/pdcore/pc_core.c b/src/pdflib/pdcore/pc_core.c new file mode 100644 index 0000000..4617aec --- /dev/null +++ b/src/pdflib/pdcore/pc_core.c @@ -0,0 +1,1190 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_core.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib core services + * + */ + +#include "pc_util.h" +#include "pc_string.h" +#include "pc_ctype.h" + +#define PDF_UnknownError 12 + +#if defined(__ia64__) && defined (__linux__) +#define PDC_ALIGN16 +#endif + +/* TODO: how to make this dynamic? +** exception during pdc_core_init(): +** - out of memory in pdc_bs_new() +*/ +#define PDC_ERRPARM_SIZE 2048 +#define PDC_ERRBUF_SIZE (5 * PDC_ERRPARM_SIZE) +#define PDC_XSTACK_INISIZE 10 + +#define PDC_CLASSLIST_SIZE 32 + +#define N_ERRTABS (PDC_ET_LAST / 1000) + +/* temporary free store. +*/ +typedef struct +{ + void * mem; + pdc_destructor destr; + void * opaque; +} pdc_tmpmem; + +typedef struct +{ + pdc_tmpmem * tmpmem; + int capacity; + int size; +} pdc_tmpmem_list; + + +/* exception handling frame. +*/ +typedef struct +{ + pdc_jmpbuf jbuf; +} pdc_xframe; + +typedef struct +{ + const pdc_error_info * ei; + int n_entries; +} error_table; + + +/* ------------------------ the core private structure ---------------------- */ + +struct pdc_core_priv_s +{ + /* ------------ try/catch ------------ */ + pdc_xframe * x_stack; +#ifdef PDC_ALIGN16 + char * x_alias; +#endif + int x_ssize; + int x_sp; /* exception stack pointer */ + int x_sp0; /* exception stack pointer at */ + /* the time of pdc_enter_api() */ + + /* ------------ error handling ------------ */ + pdc_bool in_error; + char * premsg; + char errbuf[PDC_ERRBUF_SIZE]; + char errparms[4][PDC_ERRPARM_SIZE]; + int epcount; + int errnum; + pdc_bool x_thrown; /* exception thrown and not caught */ + char apiname[32]; + pdc_error_fp errorhandler; /* client error handler */ + void * opaque; /* client specific, opaque data */ + + error_table err_tables[N_ERRTABS]; + +#ifdef PDC_DEBUG + pdc_bool hexdump; /* hexdump feature enabled? */ +#endif /* PDC_DEBUG */ + + /* ------------ memory management ------------ */ + pdc_alloc_fp allocproc; + pdc_realloc_fp reallocproc; + pdc_free_fp freeproc; + pdc_tmpmem_list tm_list; +}; + + +/* ----------- default memory management & error handling ----------- */ + +static void * +default_malloc(void *opaque, size_t size, const char *caller) +{ + (void) opaque; + (void) caller; + + return malloc(size); +} + +static void * +default_realloc(void *opaque, void *mem, size_t size, const char *caller) +{ + (void) opaque; + (void) caller; + + return realloc(mem, size); +} + +static void +default_free(void *opaque, void *mem) +{ + (void) opaque; + + free(mem); +} + +static void +default_errorhandler(void *opaque, int errnum, const char *msg) +{ + (void) opaque; + (void) errnum; + + fprintf(stderr, "fatal exception: %s\n", msg); + exit(99); +} + +pdc_bool +pdc_enter_api(pdc_core *pdc, const char *apiname) +{ + char *name = NULL; + + if (pdc->pr->in_error) + return pdc_false; + + if (pdc->objorient) + name = (char *) strchr(apiname, '_'); + if (name) + name++; + else + name = (char *) apiname; + if (name[0] == '\n') + name++; + + strcpy(pdc->pr->apiname, name); + + if (pdc->binding != NULL) + { + size_t len = strlen(pdc->pr->apiname); + len--; + if (len && pdc->pr->apiname[len] == '2') + pdc->pr->apiname[len] = 0; + } + + pdc->pr->errnum = 0; + pdc->pr->x_sp0 = pdc->pr->x_sp; + return pdc_true; +} + +pdc_bool +pdc_in_error(pdc_core *pdc) +{ + return pdc->pr->in_error; +} + + +/* --------------------- error table management --------------------- */ + +static pdc_error_info core_errors[] = +{ +#define pdc_genInfo 1 +#include "pc_generr.h" +}; + +#define N_CORE_ERRORS (sizeof core_errors / sizeof (pdc_error_info)) + + +static void +pdc_panic(pdc_core *pdc, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + pdc_vsnprintf(pdc->pr->errbuf, PDC_ERRPARM_SIZE, fmt, ap); + va_end(ap); + + (*pdc->pr->errorhandler)(pdc->pr->opaque, PDF_UnknownError, + pdc->pr->errbuf); +} /* pdc_panic */ + + +static void +check_parms(pdc_core *pdc, const pdc_error_info *ei) +{ + const char *msg = ei->errmsg; + const char *dollar; + + while ((dollar = strchr(msg, '$')) != (char *) 0) + { + if (pdc_isdigit(dollar[1])) + { + int n = dollar[1] - '0'; + + if (ei->nparms < n || n < 1) + pdc_panic(pdc, "illegal parameter '$%d' in error message %d", + n, ei->errnum); + } + else if (dollar[1] != '$') + { + pdc_panic(pdc, + "illegal '$' in error message %d", ei->errnum); + } + + msg = dollar + 1; + } +} /* check_parms */ + + +void +pdc_register_errtab( + pdc_core *pdc, + int et, + const pdc_error_info *ei, + int n_entries) +{ + int i; + int n = (et / 1000) - 1; + + if (n < 0 || N_ERRTABS <= n || et % 1000 != 0) + pdc_panic(pdc, "tried to register unknown error table %d", et); + + /* ignore multiple registrations of the same table. + */ + if (pdc->pr->err_tables[n].ei != (pdc_error_info *) 0) + return; + + pdc->pr->err_tables[n].ei = ei; + pdc->pr->err_tables[n].n_entries = n_entries; + + check_parms(pdc, &ei[0]); + + for (i = 1; i < n_entries; ++i) + { + if (ei[i].errnum <= ei[i-1].errnum) + { + pdc_panic(pdc, + "duplicate or misplaced error number %d", ei[i].errnum); + } + + /* an error table may span several blocks. + */ + if ((ei[i].errnum / 1000) - 1 > n) + { + pdc->pr->err_tables[n].n_entries = i; /* correct old block size */ + + n = (ei[i].errnum / 1000) - 1; /* new block number */ + + if (N_ERRTABS <= n) + pdc_panic(pdc, "invalid error number %d", ei[i].errnum); + + ei += i; /* start of new block */ + n_entries -= i; /* size of new block */ + i = 0; + pdc->pr->err_tables[n].ei = ei; + pdc->pr->err_tables[n].n_entries = n_entries; + } + + check_parms(pdc, &ei[i]); + } +} /* pdc_register_errtab */ + + +/* pdc_new_core() never throws exceptions. +** it returns NULL if there's not enough memory. +*/ +pdc_core * +pdc_new_core( + pdc_error_fp errorhandler, + pdc_alloc_fp allocproc, + pdc_realloc_fp reallocproc, + pdc_free_fp freeproc, + void *opaque, + const char *prodname, + const char *version) +{ + static const char fn[] = "pdc_new_core"; + + pdc_core_priv *pdc_pr; + pdc_core *pdc; + int i; + + /* if allocproc is NULL, we use pdc's default memory handling. + */ + if (allocproc == (pdc_alloc_fp) 0) + { + allocproc = default_malloc; + reallocproc = default_realloc; + freeproc = default_free; + } + + if (errorhandler == (pdc_error_fp) 0) + errorhandler = default_errorhandler; + + pdc_pr = (pdc_core_priv *) + (*allocproc)(opaque, sizeof (pdc_core_priv), fn); + + if (pdc_pr == (pdc_core_priv *) 0) + return (pdc_core *) 0; + + pdc = (pdc_core *) + (*allocproc)(opaque, sizeof (pdc_core), fn); + + if (pdc == (pdc_core *) 0) + return (pdc_core *) 0; + + pdc->pr = pdc_pr; + + /* initialize client members + */ + pdc->reslist = NULL; + pdc->filesystem = NULL; + pdc->logg = NULL; + pdc->loggenv = pdc_false; + pdc->encstack = NULL; + pdc->pglyphtab = NULL; + pdc->bstr_pool = NULL; + pdc->ustr_pool = NULL; + pdc->last_rand = 1; + pdc->prodname = prodname; + pdc->version = version; + pdc->binding = NULL; + pdc->unicaplang = pdc_false; + pdc->objorient = pdc_false; + pdc->hastobepos = pdc_false; + pdc->ptfrun = pdc_false; + pdc->smokerun = pdc_false; + pdc->charref = pdc_false; + pdc->escapesequ = pdc_false; + pdc->honorlang = pdc_false; + pdc->compatibility = PDC_X_X_LAST; + pdc->floatdigits = 4; + pdc->uniqueno = 0; + + +#ifdef PDC_DEBUG + pdc->pr->hexdump = pdc_true; +#endif + + /* set diverse handlers + */ + pdc->pr->errorhandler = errorhandler; + pdc->pr->allocproc = allocproc; + pdc->pr->reallocproc = reallocproc; + pdc->pr->freeproc = freeproc; + pdc->pr->opaque = opaque; + + /* initialize error & exception handling. + */ + pdc->pr->in_error = pdc_false; + pdc->pr->x_thrown = pdc_false; + pdc->pr->epcount = 0; + pdc->pr->errnum = 0; + pdc->pr->premsg = NULL; + pdc->pr->apiname[0] = 0; + pdc->pr->x_sp = -1; + pdc->pr->x_ssize = PDC_XSTACK_INISIZE; + +#ifdef PDC_ALIGN16 + pdc->pr->x_alias = (char *) + (*allocproc)(opaque, 16 + pdc->pr->x_ssize * sizeof (pdc_xframe), fn); + + if (pdc->pr->x_alias == (char *) 0) + pdc->pr->x_stack = (pdc_xframe *) 0; + else + pdc->pr->x_stack = (pdc_xframe *) + (((unsigned long) pdc->pr->x_alias + 16) & 0xFFFFFFFFFFFFFFF0); +#else + pdc->pr->x_stack = (pdc_xframe *) + (*allocproc)(opaque, pdc->pr->x_ssize * sizeof (pdc_xframe), fn); +#endif + + if (pdc->pr->x_stack == (pdc_xframe *) 0) + { + (*freeproc)(opaque, pdc); + return (pdc_core *) 0; + } + + pdc_tmlist_init(pdc); + + /* initialize error tables. + */ + for (i = 0; i < N_ERRTABS; ++i) + pdc->pr->err_tables[i].ei = (pdc_error_info *) 0; + + pdc_register_errtab(pdc, PDC_ET_CORE, core_errors, N_CORE_ERRORS); + pdc_init_strings(pdc); + + return pdc; +} + +void +pdc_delete_core(pdc_core *pdc) +{ + pdc_free_fp freeproc = pdc->pr->freeproc; + void *opaque = pdc->pr->opaque; + pdc_time ltime; + + pdc_localtime(<ime); + pdc_logg(pdc, "[%04d-%02d-%02d %02d:%02d:%02d]\n", + ltime.year + 1900, ltime.month + 1, ltime.mday, + ltime.hour, ltime.minute, ltime.second); + + pdc_delete_reslist(pdc); + pdc_delete_filesystem(pdc); + pdc_delete_encodingstack(pdc); + pdc_delete_pglyphtab(pdc); + + pdc_cleanup_strings(pdc); + + if (pdc->binding) + pdc_free(pdc, pdc->binding); + + pdc_pop_errmsg(pdc); + + pdc_tmlist_cleanup(pdc); + + if (pdc->pr->tm_list.capacity != 0) + pdc_free(pdc, pdc->pr->tm_list.tmpmem); + +#ifdef PDC_ALIGN16 + pdc_free(pdc, pdc->pr->x_alias); +#else + pdc_free(pdc, pdc->pr->x_stack); +#endif + + pdc_delete_logg(pdc); + + (*freeproc)(opaque, pdc->pr); + (*freeproc)(opaque, pdc); +} + +/* --------------------------- memory management --------------------------- */ + +void * +pdc_malloc(pdc_core *pdc, size_t size, const char *caller) +{ + void *ret; + pdc_bool logg1 = pdc_logg_is_enabled(pdc, 1, trc_memory); + + if (logg1) + pdc_logg(pdc, "\ttry to malloc %ld bytes\n", size); + + + /* the behavior of malloc(0) is undefined in ANSI C, and may + * result in a NULL pointer return value which makes PDFlib bail out. + */ + if (size == (size_t) 0 || (long) size < 0L) { + size = (size_t) 1; + pdc_error(pdc, PDC_E_INT_ALLOC0, caller, 0, 0, 0); + } + + if ((ret = (*pdc->pr->allocproc)(pdc->pr->opaque, size, caller)) == + (void *) 0) + { + pdc_error(pdc, PDC_E_MEM_OUT, caller, 0, 0, 0); + } + + if (logg1) + pdc_logg(pdc, "\t%p malloced, size=%ld, called from \"%s\"\n", + ret, size, caller); + + return ret; +} + +/* We cook up our own calloc routine, using the caller-supplied + * malloc and memset. + */ +void * +pdc_calloc(pdc_core *pdc, size_t size, const char *caller) +{ + void *ret; + pdc_bool logg1 = pdc_logg_is_enabled(pdc, 1, trc_memory); + + if (logg1) + pdc_logg(pdc, "\ttry to calloc %ld bytes\n", size); + + if (size == (size_t) 0 || (long) size < 0L) { + size = (size_t) 1; + pdc_error(pdc, PDC_E_INT_ALLOC0, caller, 0, 0, 0); + } + + if ((ret = (*pdc->pr->allocproc)(pdc->pr->opaque, size, caller)) == + (void *) 0) + { + pdc_error(pdc, PDC_E_MEM_OUT, caller, 0, 0, 0); + } + + if (logg1) + pdc_logg(pdc, "\t%p calloced, size=%ld, called from \"%s\"\n", + ret, size, caller); + + memset(ret, 0, size); + return ret; +} + +void * +pdc_realloc(pdc_core *pdc, void *mem, size_t size, const char *caller) +{ + void *ret; + pdc_bool logg1 = pdc_logg_is_enabled(pdc, 1, trc_memory); + + if (logg1) + pdc_logg(pdc, "\ttry to realloc %p to %ld bytes\n", mem, size); + + if (size == (size_t) 0 || (long) size < 0L) { + size = (size_t) 1; + pdc_error(pdc, PDC_E_INT_ALLOC0, caller, 0, 0, 0); + } + + ret = (mem == (void *) 0) ? + (*pdc->pr->allocproc)(pdc->pr->opaque, size, caller) : + (*pdc->pr->reallocproc)(pdc->pr->opaque, mem, size, caller); + + if (ret == (void *) 0) + pdc_error(pdc, PDC_E_MEM_OUT, caller, 0, 0, 0); + + pdc_logg_cond(pdc, 1, trc_memory, + "\t%p realloced to\n" + "\t%p new, size=%ld, called from \"%s\"\n", + mem, ret, size, caller); + + return ret; +} + +void +pdc_free(pdc_core *pdc, void *mem) +{ + pdc_logg_cond(pdc, 1, trc_memory, "\t%p freed\n", mem); + + /* just in case the freeproc() isn't that ANSI compatible... + */ + if (mem != NULL) + (*pdc->pr->freeproc)(pdc->pr->opaque, mem); +} + +/* -------------------- temporary free store management -------------------- */ + +void +pdc_tmlist_init(pdc_core *pdc) +{ + pdc->pr->tm_list.size = pdc->pr->tm_list.capacity = 0; +} + +static void +pdc_tmlist_grow(pdc_core *pdc) +{ + static const char fn[] = "pdc_tmlist_grow"; + pdc_tmpmem_list *tm_list = &pdc->pr->tm_list; + static const int chunksize = 20; + + if (tm_list->capacity == 0) + { + tm_list->capacity = chunksize; + tm_list->tmpmem = (pdc_tmpmem *) pdc_malloc(pdc, + (size_t) (tm_list->capacity * sizeof (pdc_tmpmem)), fn); + } + else + { + tm_list->capacity += chunksize; + tm_list->tmpmem = (pdc_tmpmem *) pdc_realloc(pdc, tm_list->tmpmem, + (size_t) (tm_list->capacity * sizeof (pdc_tmpmem)), fn); + } +} + +void +pdc_tmlist_cleanup(pdc_core *pdc) +{ + pdc_tmpmem_list *tm_list = &pdc->pr->tm_list; + int i; + + for (i = 0; i < tm_list->size; ++i) + { + if (tm_list->tmpmem[i].destr) + tm_list->tmpmem[i].destr(tm_list->tmpmem[i].opaque, + tm_list->tmpmem[i].mem); + + pdc_free(pdc, tm_list->tmpmem[i].mem); + } + + tm_list->size = 0; +} + +void +pdc_insert_mem_tmp( + pdc_core * pdc, + void * memory, + void * opaque, + pdc_destructor destr) +{ + pdc_tmpmem_list *tm_list = &pdc->pr->tm_list; + + if (tm_list->size == tm_list->capacity) + pdc_tmlist_grow(pdc); + + pdc_logg_cond(pdc, 2, trc_memory, + "\tTemporary memory %p was created\n", memory); + + tm_list->tmpmem[tm_list->size].mem = memory; + tm_list->tmpmem[tm_list->size].destr = destr; + tm_list->tmpmem[tm_list->size].opaque = opaque; + ++tm_list->size; +} + +void * +pdc_malloc_tmp( + pdc_core * pdc, + size_t size, + const char * caller, + void * opaque, + pdc_destructor destr) +{ + void *memory = pdc_malloc(pdc, size, caller); + + pdc_insert_mem_tmp(pdc, memory, opaque, destr); + + return memory; +} + +void * +pdc_calloc_tmp( + pdc_core * pdc, + size_t size, + const char * caller, + void * opaque, + pdc_destructor destr) +{ + void *memory = pdc_calloc(pdc, size, caller); + + pdc_insert_mem_tmp(pdc, memory, opaque, destr); + + return memory; +} + +void * +pdc_realloc_tmp(pdc_core *pdc, void *mem, size_t size, const char *caller) +{ + pdc_tmpmem_list *tm_list = &pdc->pr->tm_list; + int i; + + for (i = tm_list->size - 1; 0 <= i; --i) + if (tm_list->tmpmem[i].mem == mem) + return tm_list->tmpmem[i].mem = pdc_realloc(pdc, mem, size, caller); + + pdc_error(pdc, PDC_E_INT_REALLOC_TMP, caller, 0, 0, 0); + return (void *) 0; +} + +void +pdc_free_tmp(pdc_core *pdc, void *mem) +{ + pdc_tmpmem_list *tm_list = &pdc->pr->tm_list; + int i, j; + + pdc_logg_cond(pdc, 2, trc_memory, + "\tTemporary memory %p to be freed\n", mem); + + /* we search the list backwards since chances are good + ** that the most recently allocated items are freed first. + */ + for (i = tm_list->size - 1; 0 <= i; --i) + { + if (tm_list->tmpmem[i].mem == mem) + { + if (tm_list->tmpmem[i].destr) + tm_list->tmpmem[i].destr( + tm_list->tmpmem[i].opaque, tm_list->tmpmem[i].mem); + + pdc_free(pdc, tm_list->tmpmem[i].mem); + tm_list->tmpmem[i].mem = (void *) 0; + + --tm_list->size; + for (j = i; j < tm_list->size; j++) + tm_list->tmpmem[j] = tm_list->tmpmem[j + 1]; + + return; + } + } + + pdc_error(pdc, PDC_E_INT_FREE_TMP, 0, 0, 0, 0); +} + + +/* --------------------------- exception handling --------------------------- */ + +const char *pdc_errprintf(pdc_core *pdc, const char *fmt, ...) +{ + va_list ap; + + if (pdc->pr->epcount < 0 || pdc->pr->epcount > 3) + pdc->pr->epcount = 0; + + va_start(ap, fmt); + pdc_vsnprintf(pdc->pr->errparms[pdc->pr->epcount], PDC_ERRPARM_SIZE, + fmt, ap); + va_end(ap); + + return pdc->pr->errparms[pdc->pr->epcount++]; +} + +static const pdc_error_info * +get_error_info(pdc_core *pdc, int errnum) +{ + int n = (errnum / 1000) - 1; + + if (0 <= n && n < N_ERRTABS && pdc->pr->err_tables[n].ei != 0) + { + error_table *etab = &pdc->pr->err_tables[n]; + int i; + + /* LATER: binary search. */ + for (i = 0; i < etab->n_entries; ++i) + { + if (etab->ei[i].errnum == errnum) + return &etab->ei[i]; + } + } + + pdc_panic(pdc, "Internal error: unknown error number %d", errnum); + + return (pdc_error_info *) 0; /* for the compiler */ +} /* get_error_info */ + + +static void +make_errmsg( + pdc_core * pdc, + const pdc_error_info *ei, + const char * parm1, + const char * parm2, + const char * parm3, + const char * parm4, + pdc_bool popmsg) +{ + const char *src = ei->ce_msg ? ei->ce_msg : ei->errmsg; + char * dst = pdc->pr->errbuf; + const char *dollar; + + if (pdc->pr->premsg != NULL) + { + strcpy(dst, pdc->pr->premsg); + dst += strlen(pdc->pr->premsg); + if (popmsg) + pdc_pop_errmsg(pdc); + } + + pdc->pr->epcount = 0; + + /* copy *src to *dst, replacing "$N" with *parmN. + */ + while ((dollar = strchr(src, '$')) != (char *) 0) + { + const char *parm = (const char *) 0; + + memcpy(dst, src, (size_t) (dollar - src)); + dst += dollar - src; + src = dollar + 1; + + switch (*src) + { + case '1': parm = (parm1 ? parm1 : "?"); break; + case '2': parm = (parm2 ? parm2 : "?"); break; + case '3': parm = (parm3 ? parm3 : "?"); break; + case '4': parm = (parm4 ? parm4 : "?"); break; + + case 0: break; + + default: *(dst++) = *(src++); + break; + } + + if (parm != (const char *) 0) + { + ++src; + strcpy(dst, parm); + dst += strlen(parm); + } + } + + strcpy(dst, src); + +} /* make_errmsg */ + +void +pdc_pop_errmsg(pdc_core *pdc) +{ + if (pdc->pr->premsg) + { + pdc_free(pdc, pdc->pr->premsg); + pdc->pr->premsg = NULL; + } +} /* pdc_pop_errmsg */ + +void +pdc_push_errmsg( + pdc_core * pdc, + int errnum, + const char *parm1, + const char *parm2, + const char *parm3, + const char *parm4) +{ + static const char fn[] = "pdc_push_errmsg"; + const pdc_error_info *ei = get_error_info(pdc, errnum); + + pdc_pop_errmsg(pdc); + + make_errmsg(pdc, ei, parm1, parm2, parm3, parm4, pdc_false); + + pdc->pr->premsg = pdc_strdup_ext(pdc, pdc->pr->errbuf, 0, fn); + +} /* pdc_push_errmsg */ + +void +pdc_set_errmsg( + pdc_core * pdc, + int errnum, + const char *parm1, + const char *parm2, + const char *parm3, + const char *parm4) +{ + const pdc_error_info *ei = get_error_info(pdc, errnum); + + make_errmsg(pdc, ei, parm1, parm2, parm3, parm4, pdc_false); + + pdc->pr->errnum = errnum; + + pdc_logg_cond(pdc, 2, trc_warning, + "[Reason for error message %d: \"%s\"]\n", + pdc->pr->errnum, pdc->pr->errbuf); + +} /* pdc_set_errmsg */ + +void +pdc_set_warnmsg( + pdc_core * pdc, + int errnum, + const char *parm1, + const char *parm2, + const char *parm3, + const char *parm4) +{ + char errbuf[PDC_ERRBUF_SIZE]; + + strcpy(errbuf, pdc->pr->errbuf); + + if (errnum != -1) + { + const pdc_error_info *ei = get_error_info(pdc, errnum); + + make_errmsg(pdc, ei, parm1, parm2, parm3, parm4, pdc_false); + } + + pdc_logg_cond(pdc, 1, trc_warning, + "\n[Warning message %d: \"%s\"]\n", + errnum, pdc->pr->errbuf); + + strcpy(pdc->pr->errbuf, errbuf); + +} /* pdc_set_warnmsg */ + + +void +pdc_error( + pdc_core * pdc, + int errnum, + const char *parm1, + const char *parm2, + const char *parm3, + const char *parm4) +{ + const char *logmsg; + + /* avoid recursive errors, but allow rethrow. + */ + if (errnum != -1 && pdc->pr->in_error) + return; + + pdc->pr->in_error = pdc_true; + pdc->pr->x_thrown = pdc_true; + + if (errnum != -1) + { + const pdc_error_info *ei = get_error_info(pdc, errnum); + + make_errmsg(pdc, ei, parm1, parm2, parm3, parm4, pdc_true); + pdc->pr->errnum = errnum; + } + + if (pdc->pr->x_sp > pdc->pr->x_sp0) + { + logmsg = "\n[/// Exception %d in %s ]"; + } + else + { + logmsg = "\n[+++ Exception %d in %s ]"; + } + + pdc_logg(pdc, logmsg, pdc->pr->errnum, + (pdc->pr->errnum == 0 || !pdc->pr->apiname) ? "" : pdc->pr->apiname, + pdc->pr->x_sp0 + 1, pdc->pr->x_sp - pdc->pr->x_sp0); + + pdc_logg(pdc, "[\"%s\"]\n\n", pdc->pr->errbuf); + + if (pdc->pr->x_sp == -1) + { + char errbuf[PDC_ERRBUF_SIZE]; + const char *apiname = pdc_get_apiname(pdc); + const char *errmsg = pdc->pr->errbuf; + + if (strlen(apiname)) + { + sprintf(errbuf, "[%d] %s: %s", pdc->pr->errnum, apiname, errmsg); + errmsg = errbuf; + } + + (*pdc->pr->errorhandler)(pdc->pr->opaque, PDF_UnknownError, errmsg); + + /* + * The error handler must never return. If it does, it is severely + * broken. We cannot remedy this, so we exit. + */ + exit(99); + + } + else + { + longjmp(pdc->pr->x_stack[pdc->pr->x_sp].jbuf.jbuf, 1); + } + +} /* pdc_error */ + +pdc_jmpbuf * +pdc_jbuf(pdc_core *pdc) +{ + static const char fn[] = "pdc_jbuf"; + + if (++pdc->pr->x_sp == pdc->pr->x_ssize) + { + pdc_xframe *aux; + +#ifdef PDC_ALIGN16 + char *cp = (char *) (*pdc->pr->allocproc)(pdc->pr->opaque, + 16 + 2 * pdc->pr->x_ssize * sizeof (pdc_xframe), fn); + + if (cp == (char *) 0) + { + aux = (pdc_xframe *) 0; + } + else + { + /* remember the pointer in order to free it only after the memcpy + * below, as pdc->pr->x_stack points into the memory allocated + * to pdc->pr->x_alias + */ + char *free_me_later = pdc->pr->x_alias; + pdc->pr->x_alias = cp; + aux = (pdc_xframe *) + (((unsigned long) cp + 16) & 0xFFFFFFFFFFFFFFF0); + + memcpy(aux, pdc->pr->x_stack, + pdc->pr->x_ssize * sizeof (pdc_xframe)); + pdc_free(pdc, free_me_later); + } +#else + aux = (pdc_xframe *) (*pdc->pr->reallocproc)( + pdc->pr->opaque, pdc->pr->x_stack, + 2 * pdc->pr->x_ssize * sizeof (pdc_xframe), fn); +#endif + + if (aux == (pdc_xframe *) 0) + { + --pdc->pr->x_sp; + pdc->pr->x_thrown = pdc_true; + pdc->pr->in_error = pdc_true; + + pdc->pr->errnum = PDC_E_MEM_OUT; + pdc->pr->apiname[0] = 0; + sprintf(pdc->pr->errbuf, + "Out of memory in TRY function (nesting level: %d)", + pdc->pr->x_sp + 1); + + longjmp(pdc->pr->x_stack[pdc->pr->x_sp].jbuf.jbuf, 1); + } + + pdc->pr->x_stack = aux; + pdc->pr->x_ssize *= 2; + } + + pdc->pr->x_thrown = pdc_false; + return &pdc->pr->x_stack[pdc->pr->x_sp].jbuf; +} /* pdc_jbuf */ + +void +pdc_exit_try(pdc_core *pdc) +{ + if (pdc->pr->x_sp == -1) + { + strcpy(pdc->pr->errbuf, "exception stack underflow"); + pdc->pr->errnum = PDC_E_INT_XSTACK; + (*pdc->pr->errorhandler)(pdc->pr->opaque, PDF_UnknownError, + pdc->pr->errbuf); + } + else + --pdc->pr->x_sp; +} /* pdc_exit_try */ + +int +pdc_catch_intern(pdc_core *pdc) +{ + pdc_bool result; + + if (pdc->pr->x_sp == -1) + { + strcpy(pdc->pr->errbuf, "exception stack underflow"); + pdc->pr->errnum = PDC_E_INT_XSTACK; + (*pdc->pr->errorhandler)(pdc->pr->opaque, PDF_UnknownError, + pdc->pr->errbuf); + } + else + --pdc->pr->x_sp; + + result = pdc->pr->x_thrown; + pdc->pr->in_error = pdc_false; + pdc->pr->x_thrown = pdc_false; + + return result; +} /* pdc_catch_intern */ + +int +pdc_catch_extern(pdc_core *pdc) +{ + pdc_bool result; + + if (pdc->pr->x_sp == -1) + { + strcpy(pdc->pr->errbuf, "exception stack underflow"); + pdc->pr->errnum = PDC_E_INT_XSTACK; + (*pdc->pr->errorhandler)(pdc->pr->opaque, PDF_UnknownError, + pdc->pr->errbuf); + } + else + --pdc->pr->x_sp; + + result = pdc->pr->x_thrown; + pdc->pr->x_thrown = pdc_false; + + return result; +} /* pdc_catch_extern */ + +void +pdc_rethrow(pdc_core *pdc) +{ + pdc_error(pdc, -1, 0, 0, 0, 0); +} /* pdc_rethrow */ + + +/* this function should be called in the PDC_CATCH branch of +** a function before it returns -1. +*/ +void +pdc_check_rethrow(pdc_core *pdc) +{ + if (pdc->pr->errnum == PDC_E_MEM_OUT) + pdc_error(pdc, -1, 0, 0, 0, 0); +} /* pdc_check_rethrow */ + + +int +pdc_get_errnum(pdc_core *pdc) +{ + return pdc->pr->errnum; +} + +const char * +pdc_get_errmsg(pdc_core *pdc) +{ + return (pdc->pr->errnum == 0) ? "" : pdc->pr->errbuf; +} + +const char * +pdc_get_apiname(pdc_core *pdc) +{ + return pdc->pr->apiname; +} + +const char * +pdc_get_errpref(pdc_core *pdc) +{ + return pdc->pr->premsg; +} + +/* ----------- service function to get PDF version string -------------- */ + +const char * +pdc_get_pdfversion(pdc_core *pdc, int compatibility) +{ + return pdc_errprintf(pdc, "%d.%d", compatibility / 10, compatibility % 10); +} + + +#ifdef PDC_DEBUG + +/* --------------------------- debug hexdump --------------------------- */ +void +pdc_enable_hexdump(pdc_core *pdc) +{ + pdc->pr->hexdump = pdc_true; +} + +void +pdc_disable_hexdump(pdc_core *pdc) +{ + pdc->pr->hexdump = pdc_false; +} + +void +pdc_hexdump(pdc_core *pdc, const char *msg, const char *text, int tlen) +{ + if (pdc->pr->hexdump) + { + int i, k; + + if (tlen == 1) + { + printf("%s: %02X '%c'\n", msg, + (unsigned char) text[0], + pdc_isprint(text[0]) ? text[0] : '.'); + } + else + { + printf("%s:\n", msg); + + for (i = 0; i < tlen; i += 16) + { + for (k = 0; k < 16; ++k) + if (i + k < tlen) + printf("%02X ", (unsigned char) text[i + k]); + else + printf(" "); + + printf(" "); + for (k = 0; k < 16; ++k) + if (i + k < tlen) + { + printf("%c", + pdc_isprint(text[i + k]) ? text[i + k] : '.'); + } + else + printf(" "); + + printf("\n"); + } + } + } +} + +#endif /* PDC_DEBUG */ diff --git a/src/pdflib/pdcore/pc_core.h b/src/pdflib/pdcore/pc_core.h new file mode 100644 index 0000000..c758789 --- /dev/null +++ b/src/pdflib/pdcore/pc_core.h @@ -0,0 +1,270 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_core.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib core services: + * - memory management + * - exception handling + * - internal try/catch + */ + +#ifndef PC_CORE_H +#define PC_CORE_H + +/* Built-in metric support */ +#define PDF_BUILTINMETRIC_SUPPORTED + +/* Built-in encoding support */ +#define PDF_BUILTINENCODING_SUPPORTED + +/* TrueType font support */ +#define PDF_TRUETYPE_SUPPORTED + +/* Proportional widths for the standard CJK fonts support */ +#define PDF_CJKFONTWIDTHS_SUPPORTED + + +#define PDF_FEATURE_NOT_PUBLIC + + +/* ------------------------- general ------------------------- */ + +typedef struct pdc_core_priv_s pdc_core_priv; +typedef struct pdc_core_s pdc_core; + +typedef int pdc_bool; +typedef long pdc_id; +typedef char pdc_char; +typedef unsigned char pdc_byte; +typedef unsigned char pdc_uchar; +typedef short pdc_short; +typedef unsigned short pdc_ushort; +typedef long pdc_long; +typedef unsigned long pdc_ulong; +typedef unsigned int pdc_uint; + +typedef unsigned short pdc_ucval; /* unicode value */ + +typedef short pdc_sint16; +typedef unsigned short pdc_uint16; +typedef int pdc_sint32; +typedef unsigned int pdc_uint32; + +/* TODO2GB: this is the signed 64-bit integer type for >2GB files. +** must be platform & compiler specific. +*/ +#if defined(_LARGEFILE_SOURCE) + #if defined(WIN32) + typedef __int64 pdc_off_t; + #else +#include + typedef off_t pdc_off_t; + #endif +#else + typedef long pdc_off_t; +#endif + +/* use this one for casts from "off_t" to "long" - so we can "grep" +** for critical places. +*/ +typedef long pdc_off_t1; + + +#define pdc_undef -1 +#define pdc_false 0 +#define pdc_true 1 + +#define PDC_1_1 11 /* PDF 1.1 = Acrobat 2 */ +#define PDC_1_2 12 /* PDF 1.2 = Acrobat 3 */ +#define PDC_1_3 13 /* PDF 1.3 = Acrobat 4 */ +#define PDC_1_4 14 /* PDF 1.4 = Acrobat 5 */ +#define PDC_1_5 15 /* PDF 1.5 = Acrobat 6 */ +#define PDC_1_6 16 /* PDF 1.6 = Acrobat 7 */ +#define PDC_1_7 17 /* PDF 1.7 = Acrobat 8 */ +#define PDC_X_X_LAST 17 + +/* Acrobat limit for page dimensions */ +#define PDF_ACRO_MINPAGE (3.0) /* 1/24 inch = 0.106 cm */ +#define PDF_ACRO_MAXPAGE (14400.0) /* 200 inch = 508 cm */ + + + +typedef void (*pdc_error_fp)(void *opaque, int type, const char *msg); +typedef void* (*pdc_alloc_fp)(void *opaque, size_t size, const char *caller); +typedef void* (*pdc_realloc_fp)(void *opaque, void *mem, size_t size, + const char *caller); +typedef void (*pdc_free_fp)(void *opaque, void *mem); + +pdc_core *pdc_new_core(pdc_error_fp errorhandler, pdc_alloc_fp allocproc, + pdc_realloc_fp reallocproc, pdc_free_fp freeproc, void *opaque, + const char *appname, const char *version); + +void pdc_delete_core(pdc_core *pdc); + +typedef enum +{ + pdc_pbox_none, + pdc_pbox_art, + pdc_pbox_bleed, + pdc_pbox_crop, + pdc_pbox_media, + pdc_pbox_trim +} pdc_pagebox; + +/* ------------------------- memory management ------------------------- */ + +void *pdc_malloc(pdc_core *pdc, size_t size, const char *caller); +void *pdc_realloc(pdc_core *pdc, void *mem, size_t size, const char *caller); +void *pdc_calloc(pdc_core *pdc, size_t size, const char *caller); +void pdc_free(pdc_core *pdc, void *mem); + +#define PDC_TMPMEM 1 + +typedef void (*pdc_destructor)(void *opaque, void *mem); + +void pdc_insert_mem_tmp(pdc_core *pdc, void *memory, void *opaque, + pdc_destructor destr); +void *pdc_malloc_tmp(pdc_core *pdc, size_t size, const char *caller, + void *opaque, pdc_destructor destr); +void *pdc_realloc_tmp(pdc_core *pdc, void *mem, size_t size, + const char *caller); +void *pdc_calloc_tmp(pdc_core *pdc, size_t size, const char *caller, + void *opaque, pdc_destructor destr); +void pdc_free_tmp(pdc_core *pdc, void *mem); + +void pdc_tmlist_init(pdc_core *pdc); +void pdc_tmlist_cleanup(pdc_core *pdc); + + +/* --------------------------- exception handling --------------------------- */ + +#define PDC_ASSERT(pdc, expr) \ + ((expr) ? (void) 0 : pdc_error((pdc), PDC_E_INT_ASSERT, \ + __FILE__, pdc_errprintf((pdc), "%d", __LINE__), 0, 0)) + +/* maximal length of strings for %.*s in pdc_errprintf format +*/ +#define PDC_ERR_MAXSTRLEN 256 + +/* per-library error table base numbers. +*/ +#define PDC_ET_CORE 1000 +#define PDC_ET_PDFLIB 2000 +#define PDC_ET_PDI 4000 +#define PDC_ET_PLOP 5000 +#define PDC_ET_PDPAGE 6000 +#define PDC_ET_FONT 7000 +#define PDC_ET_TET 8000 +#define PDC_ET_PCOS 9000 + +#define PDC_ET_LAST 9000 + +/* core error numbers. +*/ +enum +{ +#define pdc_genNames 1 +#include "pc_generr.h" + + PDC_E_dummy +}; + +typedef struct +{ + int nparms; /* number of error parameters */ + int errnum; /* error number */ + const char *errmsg; /* default error message */ + const char *ce_msg; /* custom error message */ +} pdc_error_info; + +void pdc_register_errtab(pdc_core *pdc, int et, + const pdc_error_info *ei, int n_entries); + +pdc_bool pdc_enter_api(pdc_core *pdc, const char *apiname); +pdc_bool pdc_in_error(pdc_core *pdc); + +const char * pdc_errprintf(pdc_core *pdc, const char *format, ...); + +void pdc_pop_errmsg(pdc_core *pdc); + +void pdc_push_errmsg(pdc_core *pdc, int errnum, const char *parm1, + const char *parm2, const char *parm3, const char *parm4); + +void pdc_set_errmsg(pdc_core *pdc, int errnum, const char *parm1, + const char *parm2, const char *parm3, const char *parm4); + +void pdc_set_warnmsg(pdc_core *pdc, int errnum, const char *parm1, + const char *parm2, const char *parm3, const char *parm4); + +void pdc_error(pdc_core *pdc, int errnum, const char *parm1, + const char *parm2, const char *parm3, const char *parm4); + +int pdc_get_errnum(pdc_core *pdc); +const char * pdc_get_errmsg(pdc_core *pdc); +const char * pdc_get_apiname(pdc_core *pdc); +const char * pdc_get_errpref(pdc_core *pdc); + +/* ----------------------------- try/catch ---------------------------- */ + +#include + +typedef struct +{ + jmp_buf jbuf; +} pdc_jmpbuf; + +pdc_jmpbuf * pdc_jbuf(pdc_core *pdc); +void pdc_exit_try(pdc_core *pdc); +int pdc_catch_intern(pdc_core *pdc); +int pdc_catch_extern(pdc_core *pdc); +void pdc_check_rethrow(pdc_core *pdc); +void pdc_rethrow(pdc_core *pdc); + +#define PDC_TRY(pdc) if (setjmp(pdc_jbuf(pdc)->jbuf) == 0) + +#define PDC_EXIT_TRY(pdc) pdc_exit_try(pdc) + +#define PDC_CATCH(pdc) if (pdc_catch_intern(pdc)) + +#define PDC_RETHROW(pdc) pdc_rethrow(pdc) + + +/* ----------- service function to get PDF version string -------------- */ + +const char *pdc_get_pdfversion(pdc_core *pdc, int compatibility); + + +/* --------------------------- debug hexdump --------------------------- */ + +#ifdef PDC_DEBUG +void pdc_enable_hexdump(pdc_core *pdc); +void pdc_disable_hexdump(pdc_core *pdc); +void pdc_hexdump(pdc_core *pdc, const char *msg, const char *text, int tlen); +#endif /* PDC_DEBUG */ + +/* --------------------------- scope --------------------------- */ + +/* + * An arbitrary number used for sanity checks. + * Actually, we use the hex representation of pi in order to avoid + * the more common patterns. + */ + +#define PDC_MAGIC ((unsigned long) 0x126960A1) + +/* environment variable name for license file +*/ +#define PDC_LICFILE_ENV "PDFLIBLICENSEFILE" + + +#endif /* PC_CORE_H */ diff --git a/src/pdflib/pdcore/pc_crypt.c b/src/pdflib/pdcore/pc_crypt.c new file mode 100644 index 0000000..bcc404b --- /dev/null +++ b/src/pdflib/pdcore/pc_crypt.c @@ -0,0 +1,27 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_crypt.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Routines for PDF encryption and decryption + * + */ + +#include "time.h" + +#include "pc_util.h" +#include "pc_md5.h" +#include "pc_crypt.h" + + +static void pdc_pd_crypt_c(void) {} + diff --git a/src/pdflib/pdcore/pc_crypt.h b/src/pdflib/pdcore/pc_crypt.h new file mode 100644 index 0000000..585f22c --- /dev/null +++ b/src/pdflib/pdcore/pc_crypt.h @@ -0,0 +1,27 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_crypt.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Crypto routines + * + */ + +#ifndef PC_CRYPT_H +#define PC_CRYPT_H + +#include "pc_util.h" +#include "pc_arc4.h" +#include "pc_aes.h" + + +#endif /* PC_CRYPT_H */ diff --git a/src/pdflib/pdcore/pc_ctype.c b/src/pdflib/pdcore/pc_ctype.c new file mode 100644 index 0000000..658f82f --- /dev/null +++ b/src/pdflib/pdcore/pc_ctype.c @@ -0,0 +1,309 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 PDFlib GmbH. All rights reserved. | + *---------------------------------------------------------------------------* + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_ctype.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ */ + +#include "pc_ctype.h" + + +#undef LOWER +#undef UPPER +#undef DIGIT +#undef PUNCT +#undef SPACE + +#undef OCT +#undef HEX +#undef DELIM +#undef NUM0 +#undef PDFSP + +#define LOWER 0x0001 +#define UPPER 0x0002 +#define DIGIT 0x0004 +#define PUNCT 0x0008 +#define SPACE 0x0010 + +#define OCT 0x0100 +#define HEX 0x0200 +#define DELIM 0x0400 +#define NUM0 0x0800 /* '+' '-' '.' '0'..'9' */ +#define PDFSP 0x1000 /* ' ' NUL HT NL CR FF */ + + +static const unsigned short pdc_ctype[256] = +{ + PDFSP, /* 0x00 = NUL */ + + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x01 .. 0x08 */ + + SPACE | PDFSP, /* 0x09 = HT */ + SPACE | PDFSP, /* 0x0A = NL */ + SPACE, /* 0x0B = VT */ + SPACE | PDFSP, /* 0x0C = FF */ + SPACE | PDFSP, /* 0x0D = CR */ + 0, /* 0x0E */ + 0, /* 0x0F */ + + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 .. 0x17 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x18 .. 0x1F */ + + SPACE | PDFSP, /* 0x20 = ' ' */ + PUNCT, /* 0x21 = '!' */ + PUNCT, /* 0x22 = '"' */ + PUNCT, /* 0x23 = '#' */ + PUNCT, /* 0x24 = '$' */ + PUNCT | DELIM, /* 0x25 = '%' */ + PUNCT, /* 0x26 = '&' */ + PUNCT, /* 0x27 = ''' */ + PUNCT | DELIM, /* 0x28 = '(' */ + PUNCT | DELIM, /* 0x29 = ')' */ + PUNCT, /* 0x2A = '*' */ + PUNCT | NUM0, /* 0x2B = '+' */ + PUNCT, /* 0x2C = ',' */ + PUNCT | NUM0, /* 0x2D = '-' */ + PUNCT | NUM0, /* 0x2E = '.' */ + PUNCT | DELIM, /* 0x2F = '/' */ + + DIGIT | NUM0 | HEX | OCT, /* 0x30 = '0' */ + DIGIT | NUM0 | HEX | OCT, /* 0x31 = '1' */ + DIGIT | NUM0 | HEX | OCT, /* 0x32 = '2' */ + DIGIT | NUM0 | HEX | OCT, /* 0x33 = '3' */ + DIGIT | NUM0 | HEX | OCT, /* 0x34 = '4' */ + DIGIT | NUM0 | HEX | OCT, /* 0x35 = '5' */ + DIGIT | NUM0 | HEX | OCT, /* 0x36 = '6' */ + DIGIT | NUM0 | HEX | OCT, /* 0x37 = '7' */ + DIGIT | NUM0 | HEX, /* 0x38 = '8' */ + DIGIT | NUM0 | HEX, /* 0x39 = '9' */ + + PUNCT, /* 0x3A = ':' */ + PUNCT, /* 0x3B = ';' */ + PUNCT | DELIM, /* 0x3C = '<' */ + PUNCT, /* 0x3D = '=' */ + PUNCT | DELIM, /* 0x3E = '>' */ + PUNCT, /* 0x3F = '?' */ + PUNCT, /* 0x40 = '@' */ + + UPPER | HEX, /* 0x41 = 'A' */ + UPPER | HEX, /* 0x42 = 'B' */ + UPPER | HEX, /* 0x43 = 'C' */ + UPPER | HEX, /* 0x44 = 'D' */ + UPPER | HEX, /* 0x45 = 'E' */ + UPPER | HEX, /* 0x46 = 'F' */ + UPPER, /* 0x47 = 'G' */ + UPPER, /* 0x48 = 'H' */ + UPPER, /* 0x49 = 'I' */ + UPPER, /* 0x4A = 'J' */ + UPPER, /* 0x4B = 'K' */ + UPPER, /* 0x4C = 'L' */ + UPPER, /* 0x4D = 'M' */ + UPPER, /* 0x4E = 'N' */ + UPPER, /* 0x4F = 'O' */ + + UPPER, /* 0x50 = 'P' */ + UPPER, /* 0x51 = 'Q' */ + UPPER, /* 0x52 = 'R' */ + UPPER, /* 0x53 = 'S' */ + UPPER, /* 0x54 = 'T' */ + UPPER, /* 0x55 = 'U' */ + UPPER, /* 0x56 = 'V' */ + UPPER, /* 0x57 = 'W' */ + UPPER, /* 0x58 = 'X' */ + UPPER, /* 0x59 = 'Y' */ + UPPER, /* 0x5A = 'Z' */ + + PUNCT | DELIM, /* 0x5B = '[' */ + PUNCT, /* 0x5C = '\' */ + PUNCT | DELIM, /* 0x5D = ']' */ + PUNCT, /* 0x5E = '^' */ + PUNCT, /* 0x5F = '_' */ + PUNCT, /* 0x60 = '`' */ + + LOWER | HEX, /* 0x61 = 'a' */ + LOWER | HEX, /* 0x62 = 'b' */ + LOWER | HEX, /* 0x63 = 'c' */ + LOWER | HEX, /* 0x64 = 'd' */ + LOWER | HEX, /* 0x65 = 'e' */ + LOWER | HEX, /* 0x66 = 'f' */ + LOWER, /* 0x67 = 'g' */ + LOWER, /* 0x68 = 'h' */ + LOWER, /* 0x69 = 'i' */ + LOWER, /* 0x6A = 'j' */ + LOWER, /* 0x6B = 'k' */ + LOWER, /* 0x6C = 'l' */ + LOWER, /* 0x6D = 'm' */ + LOWER, /* 0x6E = 'n' */ + LOWER, /* 0x6F = 'o' */ + + LOWER, /* 0x70 = 'p' */ + LOWER, /* 0x71 = 'q' */ + LOWER, /* 0x72 = 'r' */ + LOWER, /* 0x73 = 's' */ + LOWER, /* 0x74 = 't' */ + LOWER, /* 0x75 = 'u' */ + LOWER, /* 0x76 = 'v' */ + LOWER, /* 0x77 = 'w' */ + LOWER, /* 0x78 = 'x' */ + LOWER, /* 0x79 = 'y' */ + LOWER, /* 0x7A = 'z' */ + + PUNCT | DELIM, /* 0x7B = '{' */ + PUNCT, /* 0x7C = '|' */ + PUNCT | DELIM, /* 0x7D = '}' */ + PUNCT, /* 0x7E = '~' */ + 0, /* 0x7F */ + + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 .. 0x87 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x88 .. 0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 .. 0x97 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x98 .. 0x9F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 .. 0xA7 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA8 .. 0xAF */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 .. 0xB7 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB8 .. 0xBF */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 .. 0xC7 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC8 .. 0xCF */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 .. 0xD7 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD8 .. 0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 .. 0xE7 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE8 .. 0xEF */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0 .. 0xF7 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF8 .. 0xFF */ +}; /* pdc_ctype */ + + +pdc_bool pdc__isalnum(pdc_byte c) +{ + + return (pdc_ctype[c] & (LOWER | UPPER | DIGIT)) != 0; +} + +pdc_bool pdc__isalpha(pdc_byte c) +{ + + return (pdc_ctype[c] & (LOWER | UPPER)) != 0; +} + +pdc_bool pdc__isdigit(pdc_byte c) +{ + + return (pdc_ctype[c] & DIGIT) != 0; +} + +pdc_bool pdc__islower(pdc_byte c) +{ + + return (pdc_ctype[c] & LOWER) != 0; +} + +pdc_bool pdc__isprint(pdc_byte c) +{ + + if (c == 0x20) + return pdc_true; + + return (pdc_ctype[c] & (LOWER | UPPER | DIGIT | PUNCT)) != 0; +} + +pdc_bool pdc__ispunct(pdc_byte c) +{ + + return (pdc_ctype[c] & PUNCT) != 0; +} + +pdc_bool pdc__isspace(pdc_byte c) +{ + + return (pdc_ctype[c] & SPACE) != 0; +} + +pdc_bool pdc__isupper(pdc_byte c) +{ + + return (pdc_ctype[c] & UPPER) != 0; +} + +pdc_bool pdc__isxdigit(pdc_byte c) +{ + + return (pdc_ctype[c] & HEX) != 0; +} + +pdc_byte pdc__tolower(pdc_byte c) +{ + if (!pdc_isupper(c)) + { + return c; + } + else + { + return (pdc_byte) (c + 0x20); + } +} + +pdc_byte pdc__toupper(pdc_byte c) +{ + if (!pdc_islower(c)) + { + return c; + } + else + { + return (pdc_byte) (c - 0x20); + } +} + +pdc_bool pdc__isalpha_a(pdc_byte c) +{ + return (pdc_ctype[c] & (LOWER | UPPER)) != 0; +} + +pdc_bool pdc__isdecdt_a(pdc_byte c) +{ + return (pdc_ctype[c] & DIGIT) != 0; +} + +pdc_bool pdc__isdelim_a(pdc_byte c) +{ + return (pdc_ctype[c] & DELIM) != 0; +} + +pdc_bool pdc__ishexdt_a(pdc_byte c) +{ + return (pdc_ctype[c] & HEX) != 0; +} + +pdc_bool pdc__islower_a(pdc_byte c) +{ + return (pdc_ctype[c] & LOWER) != 0; +} + +pdc_bool pdc__isnum0_a(pdc_byte c) +{ + return (pdc_ctype[c] & NUM0) != 0; +} + +pdc_bool pdc__isoctdt_a(pdc_byte c) +{ + return (pdc_ctype[c] & OCT) != 0; +} + +pdc_bool pdc__isspace_a(pdc_byte c) +{ + return (pdc_ctype[c] & PDFSP) != 0; +} + +pdc_bool pdc__isspecial_a(pdc_byte c) +{ + return (pdc_ctype[c] & (PDFSP | DELIM)) != 0; +} + +pdc_bool pdc__isupper_a(pdc_byte c) +{ + return (pdc_ctype[c] & UPPER) != 0; +} diff --git a/src/pdflib/pdcore/pc_ctype.h b/src/pdflib/pdcore/pc_ctype.h new file mode 100644 index 0000000..5aebcb4 --- /dev/null +++ b/src/pdflib/pdcore/pc_ctype.h @@ -0,0 +1,77 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 PDFlib GmbH. All rights reserved. | + *---------------------------------------------------------------------------* + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_ctype.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ */ + +#ifndef PC_CTYPE_H_INCLUDED +#define PC_CTYPE_H_INCLUDED + +#include "pc_util.h" + +/* these are the locale-free replacements for the standard library +** isXXX() functions. use the macros below, DO NOT use the pdc__isXXX() +** functions directly. +*/ +#define pdc_isalnum(c) pdc__isalnum((pdc_byte) (c)) +#define pdc_isalpha(c) pdc__isalpha((pdc_byte) (c)) +#define pdc_isdigit(c) pdc__isdigit((pdc_byte) (c)) +#define pdc_islower(c) pdc__islower((pdc_byte) (c)) +#define pdc_isprint(c) pdc__isprint((pdc_byte) (c)) +#define pdc_ispunct(c) pdc__ispunct((pdc_byte) (c)) +#define pdc_isspace(c) pdc__isspace((pdc_byte) (c)) +#define pdc_isupper(c) pdc__isupper((pdc_byte) (c)) +#define pdc_isxdigit(c) pdc__isxdigit((pdc_byte) (c)) + +#define pdc_tolower(c) pdc__tolower((pdc_byte) (c)) +#define pdc_toupper(c) pdc__toupper((pdc_byte) (c)) + +pdc_bool pdc__isalnum(pdc_byte c); +pdc_bool pdc__isalpha(pdc_byte c); +pdc_bool pdc__isdigit(pdc_byte c); +pdc_bool pdc__islower(pdc_byte c); +pdc_bool pdc__isprint(pdc_byte c); +pdc_bool pdc__ispunct(pdc_byte c); +pdc_bool pdc__isspace(pdc_byte c); +pdc_bool pdc__isupper(pdc_byte c); +pdc_bool pdc__isxdigit(pdc_byte c); + +pdc_byte pdc__tolower(pdc_byte c); +pdc_byte pdc__toupper(pdc_byte c); + + +/* these macros are for the various flavors of the token scanner. they +** expect ASCII input even on EBCDIC platforms (thus the "_a" suffix), +** and they implement special rules for PDF character classification. +*/ +#define pdc_isalpha_a(c) pdc__isalpha_a((pdc_byte) (c)) +#define pdc_isdecdt_a(c) pdc__isdecdt_a((pdc_byte) (c)) +#define pdc_isdelim_a(c) pdc__isdelim_a((pdc_byte) (c)) +#define pdc_ishexdt_a(c) pdc__ishexdt_a((pdc_byte) (c)) +#define pdc_islower_a(c) pdc__islower_a((pdc_byte) (c)) +#define pdc_isnum0_a(c) pdc__isnum0_a((pdc_byte) (c)) +#define pdc_isoctdt_a(c) pdc__isoctdt_a((pdc_byte) (c)) + +#define pdc_isregular_a(c) \ + ((c) != -1 && !pdc__isspecial_a((pdc_byte) (c))) + +#define pdc_isspace_a(c) pdc__isspace_a((pdc_byte) (c)) +#define pdc_isspecial_a(c) pdc__isspecial_a((pdc_byte) (c)) +#define pdc_isupper_a(c) pdc__isupper_a((pdc_byte) (c)) + +pdc_bool pdc__isalpha_a(pdc_byte c); +pdc_bool pdc__isdecdt_a(pdc_byte c); +pdc_bool pdc__isdelim_a(pdc_byte c); +pdc_bool pdc__ishexdt_a(pdc_byte c); +pdc_bool pdc__islower_a(pdc_byte c); +pdc_bool pdc__isnum0_a(pdc_byte c); +pdc_bool pdc__isoctdt_a(pdc_byte c); +pdc_bool pdc__isspace_a(pdc_byte c); +pdc_bool pdc__isspecial_a(pdc_byte c); +pdc_bool pdc__isupper_a(pdc_byte c); + +#endif /* PC_CTYPE_H_INCLUDED */ diff --git a/src/pdflib/pdcore/pc_digsig.c b/src/pdflib/pdcore/pc_digsig.c new file mode 100644 index 0000000..de2916e --- /dev/null +++ b/src/pdflib/pdcore/pc_digsig.c @@ -0,0 +1,20 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 2006 PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_digsig.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + */ + + +/* ANSI C forbids an empty source file */ +void pdc_dummy_digsig_c(void); +void pdc_dummy_digsig_c() {} + diff --git a/src/pdflib/pdcore/pc_digsig.h b/src/pdflib/pdcore/pc_digsig.h new file mode 100644 index 0000000..caaa3c7 --- /dev/null +++ b/src/pdflib/pdcore/pc_digsig.h @@ -0,0 +1,17 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 2006 PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_digsig.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Digital Signature hashing/signing routines + * + */ diff --git a/src/pdflib/pdcore/pc_ebcdic.c b/src/pdflib/pdcore/pc_ebcdic.c new file mode 100644 index 0000000..cf87c5d --- /dev/null +++ b/src/pdflib/pdcore/pc_ebcdic.c @@ -0,0 +1,27 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_ebcdic.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * EBCDIC conversion routines + * + */ + +#include "pc_util.h" + + +void +pdc_ebcdic2ascii(char *s) +{ + (void) s; +} + diff --git a/src/pdflib/pdcore/pc_ebcdic.h b/src/pdflib/pdcore/pc_ebcdic.h new file mode 100644 index 0000000..5f8993f --- /dev/null +++ b/src/pdflib/pdcore/pc_ebcdic.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_ebcdic.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * EBCDIC conversion routines + * + */ + +#ifndef PC_EBCDIC_H +#define PC_EBCDIC_H + + +void pdc_ebcdic2ascii(char *s); +void pdc_ebcdic2ascii_len(char *s, size_t len); +void pdc_ascii2ebcdic_len(char *s, size_t len); +void pdc_ascii2ebcdic(char *s); +void pdc_ascii2ebcdic_char(char *c); +void pdc_ascii2ebcdic_int(int *i); +void pdc_ebcdic2ascii_int(int *i); +void pdc_ebcdic2ascii_byte(pdc_byte *c); +void pdc_ebcdic2pdfascii(char *s); +void pdc_ebcdic2pdfascii_len(char *s, size_t len); + +#endif /* PC_EBCDIC_H */ + diff --git a/src/pdflib/pdcore/pc_encoding.c b/src/pdflib/pdcore/pc_encoding.c new file mode 100644 index 0000000..3dfa390 --- /dev/null +++ b/src/pdflib/pdcore/pc_encoding.c @@ -0,0 +1,2549 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_encoding.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib in-core encodings and basic encoding functions + * + */ + +#define PC_ENCODING_C + +#include "pc_util.h" +#include "pc_file.h" +#include "pc_ctype.h" + +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#endif /* WIN32 */ + + +typedef struct pdc_unicodeslot_s +{ + pdc_ushort code; /* unicode value */ + pdc_ushort slot; /* slot for this value */ +} +pdc_unicodeslot; + +typedef struct pdc_core_encvector_s +{ + char *apiname; /* PDFlib's name of the encoding at the API */ + int isstdlatin; /* character names are all Adobe standard */ + pdc_ushort codes[256]; /* unicode values */ +} +pdc_core_encvector; + +static const pdc_core_encvector pdc_core_enc_winansi = +{ + "winansi", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, + } +}; + +static const pdc_core_encvector pdc_core_enc_macroman = +{ + "macroman", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x0000, + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x0000, 0x00C6, 0x00D8, + 0x0000, 0x00B1, 0x0000, 0x0000, 0x00A5, 0x00B5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00AA, 0x00BA, 0x0000, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x0000, 0x0192, 0x0000, 0x0000, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x0000, + 0x00FF, 0x0178, 0x2044, 0x00A4, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0x0000, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7, + } +}; + +static const pdc_core_encvector pdc_core_enc_macroman_apple = +{ + "macroman_apple", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x0000, + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x2126, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7, + } +}; + +static const pdc_core_encvector pdc_core_enc_ebcdic = +{ + "ebcdic", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, + 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x000A, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0017, 0x001B, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A, + 0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5, + 0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, + 0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF, + 0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E, + 0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5, + 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F, + 0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, + 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, + 0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1, + 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, + 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4, + 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x005B, 0x00DE, 0x00AE, + 0x00AC, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, + 0x00BD, 0x00BE, 0x00DD, 0x00A8, 0x00AF, 0x005D, 0x00B4, 0x00D7, + 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5, + 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF, + 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F, + } +}; + +static const pdc_core_encvector pdc_core_enc_ebcdic_37 = +{ + "ebcdic_37", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, + 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A, + 0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5, + 0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, + 0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF, + 0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC, + 0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5, + 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F, + 0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, + 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, + 0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1, + 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, + 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4, + 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE, + 0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, + 0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7, + 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5, + 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF, + 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F, + } +}; + +static const pdc_core_encvector pdc_core_enc_ebcdic_winansi = +{ + "ebcdic_winansi", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0153, 0x0009, 0x2020, 0x007F, + 0x2014, 0x0000, 0x017D, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0000, 0x000A, 0x0008, 0x2021, + 0x0018, 0x0019, 0x2019, 0x0000, 0x001C, 0x001D, 0x001E, 0x001F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x0017, 0x001B, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0005, 0x0006, 0x0007, + 0x0000, 0x2018, 0x0016, 0x201C, 0x201D, 0x2022, 0x2013, 0x0004, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0014, 0x0015, 0x017E, 0x001A, + 0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5, + 0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, + 0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF, + 0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E, + 0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5, + 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F, + 0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, + 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, + 0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1, + 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, + 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4, + 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x005B, 0x00DE, 0x00AE, + 0x00AC, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, + 0x00BD, 0x00BE, 0x00DD, 0x00A8, 0x00AF, 0x005D, 0x00B4, 0x00D7, + 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5, + 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF, + 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x0178, + } +}; + +static const pdc_core_encvector pdc_core_enc_pdfdoc = +{ + "pdfdoc", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x02D8, 0x02C7, 0x02C6, 0x02D9, 0x02DD, 0x02DB, 0x02DA, 0x02DC, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x0000, + 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, + 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, 0x201D, 0x2018, + 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x0141, 0x0152, 0x0160, + 0x0178, 0x017D, 0x0131, 0x0142, 0x0153, 0x0161, 0x017E, 0x0000, + 0x20AC, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x0000, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, + } +}; + +static const pdc_core_encvector pdc_core_enc_stdenc = +{ + "stdenc", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2019, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x2018, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x0000, 0x00A1, 0x00A2, 0x00A3, 0x2044, 0x00A5, 0x0192, 0x00A7, + 0x00A4, 0x0027, 0x201C, 0x00AB, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x0000, 0x2013, 0x2020, 0x2021, 0x00B7, 0x0000, 0x00B6, 0x2022, + 0x201A, 0x201E, 0x201D, 0x00BB, 0x2026, 0x2030, 0x0000, 0x00BF, + 0x0000, 0x0060, 0x00B4, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, + 0x00A8, 0x0000, 0x02DA, 0x00B8, 0x0000, 0x02DD, 0x02DB, 0x02C7, + 0x2014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x00C6, 0x0000, 0x00AA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0141, 0x00D8, 0x0152, 0x00BA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x00E6, 0x0000, 0x0000, 0x0000, 0x0131, 0x0000, 0x0000, + 0x0142, 0x00F8, 0x0153, 0x00DF, 0x0000, 0x0000, 0x0000, 0x0000, + } +}; + +static const pdc_core_encvector pdc_core_enc_macexpert = +{ + "macexpert", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0xF721, 0xF6F8, 0xF7A2, 0xF724, 0xF6E4, 0xF726, 0xF7B4, + 0x207D, 0x207E, 0x2025, 0x2024, 0x002C, 0x002D, 0x002E, 0x2044, + 0xF730, 0xF731, 0xF732, 0xF733, 0xF734, 0xF735, 0xF736, 0xF737, + 0xF738, 0xF739, 0x003A, 0x003B, 0x0000, 0xF6DE, 0x0000, 0xF73F, + 0x0000, 0x0000, 0x0000, 0x0000, 0xF7F0, 0x0000, 0x0000, 0x00BC, + 0x00BD, 0x00BE, 0x215B, 0x215C, 0x215D, 0x215E, 0x2153, 0x2154, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFB00, 0xFB01, + 0xFB02, 0xFB03, 0xFB04, 0x208D, 0x0000, 0x208E, 0xF6F6, 0xF6E5, + 0xF760, 0xF761, 0xF762, 0xF763, 0xF764, 0xF765, 0xF766, 0xF767, + 0xF768, 0xF769, 0xF76A, 0xF76B, 0xF76C, 0xF76D, 0xF76E, 0xF76F, + 0xF770, 0xF771, 0xF772, 0xF773, 0xF774, 0xF775, 0xF776, 0xF777, + 0xF778, 0xF779, 0xF77A, 0x20A1, 0xF6DC, 0xF6DD, 0xF6FE, 0x0000, + 0x0000, 0xF6E9, 0xF6E0, 0x0000, 0x0000, 0x0000, 0x0000, 0xF7E1, + 0xF7E0, 0xF7E2, 0xF7E4, 0xF7E3, 0xF7E5, 0xF7E7, 0xF7E9, 0xF7E8, + 0xF7EA, 0xF7EB, 0xF7ED, 0xF7EC, 0xF7EE, 0xF7EF, 0xF7F1, 0xF7F3, + 0xF7F2, 0xF7F4, 0xF7F6, 0xF7F5, 0xF7FA, 0xF7F9, 0xF7FB, 0xF7FC, + 0x0000, 0x2078, 0x2084, 0x2083, 0x2086, 0x2088, 0x2087, 0xF6FD, + 0x0000, 0xF6DF, 0x2082, 0x0000, 0xF7A8, 0x0000, 0xF6F5, 0xF6F0, + 0x2085, 0x0000, 0xF6E1, 0xF6E7, 0xF7FD, 0x0000, 0xF6E3, 0x0000, + 0x0000, 0xF7FE, 0x0000, 0x2089, 0x2080, 0xF6FF, 0xF7E6, 0xF7F8, + 0xF7BF, 0x2081, 0xF6F9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xF7B8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF6FA, + 0x2012, 0xF6E6, 0x0000, 0x0000, 0x0000, 0x0000, 0xF7A1, 0x0000, + 0xF7FF, 0x0000, 0x00B9, 0x00B2, 0x00B3, 0x2074, 0x2075, 0x2076, + 0x2077, 0x2079, 0x2070, 0x0000, 0xF6EC, 0xF6F1, 0xF6F3, 0x0000, + 0x0000, 0xF6ED, 0xF6F2, 0xF6EB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xF6EE, 0xF6FB, 0xF6F4, 0xF7AF, 0xF6EA, 0x207F, 0xF6EF, + 0xF6E2, 0xF6E8, 0xF6F7, 0xF6FC, 0x0000, 0x0000, 0x0000, 0x0000, + } +}; + +#ifdef PDF_BUILTINENCODING_SUPPORTED + +static const pdc_core_encvector pdc_core_enc_iso8859_2 = +{ + "iso8859-2", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, + 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, + 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, + 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x00D0, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_3 = +{ + "iso8859-3", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, + 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B, + 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, + 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C, + 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, + 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, + 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_4 = +{ + "iso8859-4", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, + 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, + 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, + 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, + 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, + 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_5 = +{ + "iso8859-5", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_6 = +{ + "iso8859-6", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0000, 0x0000, 0x0000, 0x00A4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x060C, 0x00AD, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x061B, 0x0000, 0x0000, 0x0000, 0x061F, + 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0x0638, 0x0639, 0x063A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, + 0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_7 = +{ + "iso8859-7", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x2018, 0x2019, 0x00A3, 0x0000, 0x0000, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x0000, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_8 = +{ + "iso8859-8", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_9 = +{ + "iso8859-9", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_10 = +{ + "iso8859-10", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, + 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, + 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, + 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, + 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, + 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_13 = +{ + "iso8859-13", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7, + 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_14 = +{ + "iso8859-14", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7, + 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178, + 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56, + 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_15 = +{ + "iso8859-15", 1, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, + 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x2022, + 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, + } +}; + +static const pdc_core_encvector pdc_core_enc_iso8859_16 = +{ + "iso8859-16", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00A7, + 0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B, + 0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7, + 0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A, + 0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B, + 0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1250 = +{ + "cp1250", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, + 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, + 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1251 = +{ + "cp1251", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, + 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, + 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, + 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, + 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, + 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, + 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1253 = +{ + "cp1253", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1254 = +{ + "cp1254", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1255 = +{ + "cp1255", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, + 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, + 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, + 0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1256 = +{ + "cp1256", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, + 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, + 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, + 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, + 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, + 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, + 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1257 = +{ + "cp1257", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, + 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9, + } +}; + +static const pdc_core_encvector pdc_core_enc_cp1258 = +{ + "cp1258", 0, + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF, + } +}; + +#endif /* PDF_BUILTINENCODING_SUPPORTED */ + +static const pdc_core_encvector *pdc_core_encodings[] = { + &pdc_core_enc_winansi, + &pdc_core_enc_macroman, + &pdc_core_enc_macroman_apple, + &pdc_core_enc_ebcdic, + &pdc_core_enc_ebcdic_37, + &pdc_core_enc_ebcdic_winansi, + &pdc_core_enc_pdfdoc, + &pdc_core_enc_stdenc, + &pdc_core_enc_macexpert, +#ifdef PDF_BUILTINENCODING_SUPPORTED + &pdc_core_enc_iso8859_2, + &pdc_core_enc_iso8859_3, + &pdc_core_enc_iso8859_4, + &pdc_core_enc_iso8859_5, + &pdc_core_enc_iso8859_6, + &pdc_core_enc_iso8859_7, + &pdc_core_enc_iso8859_8, + &pdc_core_enc_iso8859_9, + &pdc_core_enc_iso8859_10, + &pdc_core_enc_iso8859_13, + &pdc_core_enc_iso8859_14, + &pdc_core_enc_iso8859_15, + &pdc_core_enc_iso8859_16, + &pdc_core_enc_cp1250, + &pdc_core_enc_cp1251, + &pdc_core_enc_cp1253, + &pdc_core_enc_cp1254, + &pdc_core_enc_cp1255, + &pdc_core_enc_cp1256, + &pdc_core_enc_cp1257, + &pdc_core_enc_cp1258, +#endif /* PDF_BUILTINENCODING_SUPPORTED */ +}; + +static int pdc_enc_numbuiltin = + (int)(sizeof(pdc_core_encodings)/sizeof(pdc_core_encodings[0])); + +pdc_encodingvector * +pdc_copy_core_encoding(pdc_core *pdc, const char *name) +{ + static const char fn[] = "pdc_copy_core_encoding"; + const char *tmpname = name; + const pdc_core_encvector *ev_ic; + pdc_encodingvector *ev = NULL; + int i, slot; + + /* MacRoman encoding with euro sign */ + if (!strcmp(name, "macroman_euro")) + tmpname = "macroman_apple"; + + /* iso8859-1 encoding */ + if (!strcmp(name, "iso8859-1")) + tmpname = "winansi"; + + for (slot = 0; slot < pdc_enc_numbuiltin; slot++) + { + ev_ic = pdc_core_encodings[slot]; + if (!strcmp(tmpname, ev_ic->apiname)) + { + ev = (pdc_encodingvector *) + pdc_malloc(pdc, sizeof(pdc_encodingvector), fn); + + ev->apiname = pdc_strdup(pdc, name); + + for (i = 0; i < 256; i++) + { + ev->codes[i] = ev_ic->codes[i]; + ev->chars[i] = (char *)pdc_unicode2adobe(ev->codes[i]); + ev->given[i] = 1; + } + + if (!strcmp(name, "iso8859-1")) + { + for (i = 0x7E; i < 0xA0; i++) + { + ev->codes[i] = (pdc_ushort) i; + ev->chars[i] = (char *)pdc_unicode2adobe(ev->codes[i]); + } + } + + ev->sortedslots = NULL; + ev->nslots = 0; + ev->flags = PDC_ENC_INCORE; + ev->flags |= PDC_ENC_SETNAMES; + if (ev_ic->isstdlatin) + ev->flags |= PDC_ENC_STDNAMES; + break; + } + } + return ev; +} + + +void +pdc_init_encoding(pdc_core *pdc, pdc_encodingvector *ev, const char *name) +{ + int slot; + + ev->apiname = pdc_strdup(pdc, name); + for (slot = 0; slot < 256; slot++) + { + ev->codes[slot] = 0; + ev->chars[slot] = NULL; + ev->given[slot] = 0; + } + ev->sortedslots = NULL; + ev->nslots = 0; + ev->flags = 0; +} + + +pdc_encodingvector * +pdc_new_encoding(pdc_core *pdc, const char *name) +{ + static const char fn[] = "pdc_new_encoding"; + + pdc_encodingvector *ev = (pdc_encodingvector *) + pdc_malloc(pdc, sizeof(pdc_encodingvector), fn); + if (ev != NULL) + pdc_init_encoding(pdc, ev, name); + return(ev); +} + + +void +pdc_cleanup_encoding(pdc_core *pdc, pdc_encodingvector *ev) +{ + int slot; + + if (ev->apiname) + pdc_free(pdc, ev->apiname); + + if (ev->flags & PDC_ENC_ALLOCCHARS) + { + for (slot = 0; slot < 256; slot++) + if (ev->chars[slot]) + pdc_free(pdc, ev->chars[slot]); + } + + if (ev->sortedslots) + pdc_free(pdc, ev->sortedslots); + + pdc_free(pdc, ev); +} + +pdc_encodingvector * +pdc_copy_encoding(pdc_core *pdc, pdc_encodingvector *evfrom, const char *name) +{ + static const char fn[] = "pdc_copy_encoding"; + + pdc_encodingvector *evto = (pdc_encodingvector *) + pdc_malloc(pdc, sizeof(pdc_encodingvector), fn); + int slot; + + evto->apiname = pdc_strdup(pdc, name); + for (slot = 0; slot < 256; slot++) + { + evto->codes[slot] = evfrom->codes[slot]; + evto->chars[slot] = evfrom->chars[slot]; + evto->given[slot] = 1; + } + evto->sortedslots = NULL; + evto->nslots = 0; + evto->flags = PDC_ENC_SETNAMES; + + return(evto); +} + + +static int +pdc_unicode_compare(const void *a, const void *b) +{ + pdc_unicodeslot *sssa = (pdc_unicodeslot *) a; + pdc_unicodeslot *sssb = (pdc_unicodeslot *) b; + pdc_ushort uva = sssa->code; + pdc_ushort uvb = sssb->code; + return (uva < uvb ? -1 : (uva > uvb ? 1 : 0 )); +} + +int +pdc_get_encoding_bytecode(pdc_core *pdc, pdc_encodingvector *ev, pdc_ushort uv) +{ + static const char fn[] = "pdc_get_encoding_bytecode"; + + if (uv <= PDC_UNICODE_MAXLATIN1 && ev->codes[uv] == uv) + return (int) uv; + + if (uv) + { + pdc_ushort slot; + int i, j, lo, hi; + + if (!ev->sortedslots) + { + int nslots = 1; + pdc_unicodeslot sss[256]; + + sss[0].code = 0; + sss[0].slot = 0; + for (slot = 1; slot < 256; slot++) + { + if (ev->codes[slot]) + { + sss[nslots].code = ev->codes[slot]; + sss[nslots].slot = slot; + nslots++; + } + } + + /* sort unicode values */ + qsort((void *)sss, (size_t) nslots, sizeof(pdc_unicodeslot), + pdc_unicode_compare); + + /* copy slot values */ + ev->sortedslots = + (pdc_byte*)pdc_malloc(pdc, nslots * sizeof(char), fn); + j = 0; + for (i = 0; i < nslots; i++) + { + /* If pairs are identical in unicode values, + * we take the pair with the smaller 8-bit code */ + if (i && sss[i].code == sss[i-1].code) + { + if (sss[i].slot > sss[i-1].slot) + continue; + j--; + } + ev->sortedslots[j] = (pdc_byte) sss[i].slot; + j++; + } + ev->nslots = j; + } + + lo = 0; + hi = ev->nslots; + while (lo < hi) + { + i = (lo + hi) / 2; + slot = (pdc_ushort) ev->sortedslots[i]; + + if (uv == ev->codes[slot]) + return slot; + + if (uv < ev->codes[slot]) + hi = i; + else + lo = i + 1; + } + } + + return -1; +} + +pdc_byte +pdc_transform_bytecode(pdc_core *pdc, pdc_encodingvector *evto, + pdc_encodingvector *evfrom, pdc_byte code) +{ + int tocode = pdc_get_encoding_bytecode(pdc, evto, evfrom->codes[code]); + if (tocode == -1) + tocode = 0; + + return (pdc_byte) tocode; +} + +static const pdc_keyconn pdc_encoding_keytable[] = +{ + {"glyphid", pdc_glyphid}, + {"unicode", pdc_unicode}, + {"builtin", pdc_builtin}, + {"cid", pdc_cid}, + {"winansi", pdc_winansi}, + {"macroman", pdc_macroman}, + {"macroman_apple", pdc_macroman_apple}, + {"ebcdic", pdc_ebcdic}, + {"ebcdic_37", pdc_ebcdic_37}, + {"ebcdic_winansi", pdc_ebcdic_winansi}, + {"pdfdoc", pdc_pdfdoc}, + {"stdenc", pdc_stdenc}, + {"macexpert", pdc_macexpert}, + {NULL, 0}, +}; + +const char * +pdc_get_fixed_encoding_name(pdc_encoding enc) +{ + const char *encname = pdc_get_keyword(enc, pdc_encoding_keytable); + if (encname) + return encname; + return ""; +} + +static const char * +pdc_subst_encoding_name(pdc_core *pdc, const char *encoding, char *buffer) +{ + (void) pdc; + (void) buffer; + + /* special case for the platform-specific host encoding */ + if (!strcmp(encoding, "host") || !strcmp(encoding, "auto")) + { + +#if defined(PDFLIB_EBCDIC) + return PDC_EBCDIC_NAME; + +#elif defined(MAC) + return "macroman"; + +#elif defined(WIN32) + UINT cpident = GetACP(); + if (!strcmp(encoding, "auto")) + { + if (cpident == 10000) + strcpy(buffer, "macroman"); + else if (cpident == 20924) + strcpy(buffer, "ebcdic"); + else if (cpident >= 28590 && cpident <= 28599) + sprintf(buffer, "iso8859-%d", cpident-28590); + else if (cpident >= 28600 && cpident <= 28609) + sprintf(buffer, "iso8859-%d", cpident-28600+10); + else if (cpident == 1200 || cpident == 1201) + strcpy(buffer, "unicode"); + else + sprintf(buffer, "cp%d", cpident); + encoding = buffer; + } + else + { + return "winansi"; + } +#else + return "iso8859-1"; +#endif + } + + /* These encodings will be mapped to winansi */ + if (!strcmp(encoding, "host") || + !strcmp(encoding, "auto") || + !strcmp(encoding, "cp1252")) + return "winansi"; + + return encoding; +} + + +/* + * Try to read an encoding from file. + * + */ + +pdc_encodingvector * +pdc_read_encoding(pdc_core *pdc, const char *encoding, const char *filename, + pdc_bool verbose) +{ + pdc_encodingvector *ev = NULL; + pdc_file *fp; + char **linelist = NULL, **itemlist = NULL; + char *line, *item; + const char *stemp; + int nlines = 0, l, nitems; + pdc_bool isenc = pdc_undef; + pdc_byte code; + pdc_ushort uv; + + fp = pdc_fsearch_fopen(pdc, filename, NULL, "encoding ", PDC_FILE_TEXT); + if (fp == NULL) + { + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + } + else + { + nlines = pdc_read_textfile(pdc, fp, PDC_FILE_BSSUBST, &linelist); + pdc_fclose(fp); + } + if (!nlines) + return NULL; + + ev = pdc_new_encoding(pdc, encoding); + + for (l = 0; l < nlines; l++) + { + line = linelist[l]; + nitems = pdc_split_stringlist(pdc, line, NULL, 0, &itemlist); + if (!nitems) continue; + + /* Glyphname or Unicode value */ + item = itemlist[0]; + if (isenc == pdc_undef) + { + if (!strncmp(item, "0x", 2) || !strncmp(item, "0X", 2)) + isenc = pdc_false; + else + isenc = pdc_true; + } + if (isenc) + { + uv = pdc_insert_glyphname(pdc, item); + if (nitems == 3 && !pdc_str2integer(itemlist[2], + PDC_INT_UNICODE, (pdc_ushort *) &uv)) + goto PDC_ENC_ERROR; + } + else if (!pdc_str2integer(item, PDC_INT_UNICODE, (pdc_ushort *) &uv)) + { + goto PDC_ENC_ERROR; + } + if (nitems < 2) + goto PDC_ENC_ERROR; + + /* Code value */ + if (!pdc_str2integer(itemlist[1], PDC_INT_UNSIGNED | PDC_INT_CHAR, + (pdc_byte *) &code)) + { + if (!pdc_str2integer(itemlist[1], PDC_INT_CODE, (pdc_byte *) &code)) + goto PDC_ENC_ERROR; + } + + /* Saving */ + ev->codes[code] = uv; + if (isenc) + { + ev->chars[code] = pdc_strdup(pdc, item); + ev->given[code] = 1; + } + else + { + ev->chars[code] = (char *) pdc_insert_unicode(pdc, uv); + } + + pdc_cleanup_stringlist(pdc, itemlist); + itemlist = NULL; + } + pdc_cleanup_stringlist(pdc, linelist); + linelist = NULL; + + ev->flags |= PDC_ENC_FILE; + ev->flags |= PDC_ENC_SETNAMES; + if (isenc) + ev->flags |= PDC_ENC_ALLOCCHARS; + + return ev; + + PDC_ENC_ERROR: + stemp = pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, line); + pdc_cleanup_stringlist(pdc, itemlist); + pdc_cleanup_stringlist(pdc, linelist); + pdc_cleanup_encoding(pdc, ev); + if (verbose) + pdc_error(pdc, PDC_E_ENC_BADLINE, filename, stemp, 0, 0); + return NULL; +} + +/* + * Try to generate an encoding from a Unicode code page. + * + * Return value: allocated encoding struct + * NULL: error + */ + +pdc_encodingvector * +pdc_generate_encoding(pdc_core *pdc, const char *encoding) +{ + pdc_encodingvector *ev = NULL; + char **itemlist = NULL, *item; + pdc_ushort uv, uv1 = 0xFFFF, uv2 = 0xFFFF; + int nitems, slot; + + nitems = pdc_split_stringlist(pdc, encoding, " U", 0, &itemlist); + if (nitems && nitems <= 2 && !strncmp(encoding, "U+", 2)) + { + /* first unicode offset */ + item = itemlist[0]; + if (pdc_str2integer(item, PDC_INT_UNICODE, (pdc_ushort *) &uv1)) + { + if (nitems == 2) + { + /* second unicode offset */ + item = itemlist[1]; + if (!pdc_str2integer(item, PDC_INT_UNICODE, + (pdc_ushort *) &uv2)) + uv2 = 0xFFFF; + } + if ((nitems == 1 && uv1 <= 0xFF00) || + (nitems == 2 && uv1 <= 0xFF80 && uv2 <= 0xFF80)) + { + uv = uv1; + ev = pdc_new_encoding(pdc, encoding); + for (slot = 0; slot < 256; slot++) + { + if (slot == 128 && nitems == 2) uv = uv2; + ev->codes[slot] = uv; + ev->chars[slot] = (char *) pdc_insert_unicode(pdc, uv); + uv++; + } + ev->flags |= PDC_ENC_GENERATE; + ev->flags |= PDC_ENC_SETNAMES; + } + } + } + + pdc_cleanup_stringlist(pdc, itemlist); + return ev; +} + + +/* ---------------------- encoding stack ---------------------- */ + +struct pdc_encoding_stack_s +{ + pdc_encoding_info *info; /* all encodings in document */ + int capacity; /* currently allocated size */ + int number; /* next available encoding info slot */ +}; + +pdc_encoding_stack * +pdc_new_encodingstack(pdc_core *pdc) +{ + static const char fn[] = "pdc_new_encodingstack"; + + pdc_encoding_stack *est = + (pdc_encoding_stack *) pdc_malloc(pdc, sizeof(pdc_encoding_stack), fn); + + est->info = NULL; + est->capacity = 0; + est->number = 0; + + pdc->encstack = est; + + return est; +} + +void +pdc_delete_encodingstack(pdc_core *pdc) +{ + pdc_encoding_stack *est = pdc->encstack; + int slot; + + if (est != NULL) + { + for (slot = 0; slot < est->number; slot++) + { + if (est->info != NULL && est->info[slot].ev != NULL) + pdc_cleanup_encoding(pdc, est->info[slot].ev); + } + + if (est->info) + pdc_free(pdc, est->info); + + pdc_free(pdc, est); + pdc->encstack = NULL; + } +} + +static pdc_encoding_stack * +pdc_get_encodingstack(pdc_core *pdc) +{ + pdc_encoding_stack *est = pdc->encstack; + + if (est == NULL) + est = pdc_new_encodingstack(pdc); + + return est; +} + +int +pdc_get_encodingstack_number(pdc_core *pdc) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + return est->number; +} + +static void +pdc_init_encoding_info_mem(pdc_encoding_info *info, pdc_bool withev) +{ + if (withev) + info->ev = NULL; + info->id = PDC_BAD_ID; + info->tounicode_id = PDC_BAD_ID; + info->used_in_formfield = pdc_false; + info->stored = pdc_false; +} + +void +pdc_init_encoding_info_ids(pdc_core *pdc) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + int slot; + + for (slot = 0; slot < est->capacity; slot++) + pdc_init_encoding_info_mem(&est->info[slot], pdc_false); +} + +static void +pdc_init_encoding_info(pdc_core *pdc) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + int slot; + + for (slot = est->number; slot < est->capacity; slot++) + pdc_init_encoding_info_mem(&est->info[slot], pdc_true); +} + +pdc_encoding +pdc_insert_encoding_vector(pdc_core *pdc, pdc_encodingvector *ev) +{ + static const char fn[] = "pdc_insert_encoding_vector"; + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + int slot; + + if (est->number == 0) + { + est->capacity = pdc_firstvarenc + 1; + est->info = (pdc_encoding_info *) pdc_malloc(pdc, + sizeof(pdc_encoding_info) * est->capacity, fn); + + pdc_init_encoding_info(pdc); + + /* we must reserve the first pdc_firstvarenc slots for standard + * encodings, because the program identify their by index of + * encoding stack! (see pdc_find_encoding) + */ + est->number = (int) pdc_firstvarenc; + } + + /* search for free slot */ + for (slot = pdc_firstvarenc; slot < est->capacity; slot++) + if (est->info[slot].ev == NULL) + break; + + if (slot == est->capacity) + { + est->capacity *= 2; + est->info = (pdc_encoding_info *) pdc_realloc(pdc, est->info, + sizeof(pdc_encoding_info) * est->capacity, fn); + + pdc_init_encoding_info(pdc); + } + + if (ev != NULL) + { + est->info[slot].ev = ev; + if (slot == est->number) + (est->number)++; + } + + return (pdc_encoding) slot; +} + +void +pdc_remove_encoding_vector(pdc_core *pdc, int slot) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + + if (est && slot >= 0 && slot < est->number) + { + pdc_encoding_info *info = &est->info[slot]; + + if (info->ev != NULL) + { + pdc_cleanup_encoding(pdc, info->ev); + pdc_init_encoding_info_mem(info, pdc_true); + } + } +} + +pdc_encoding +pdc_find_encoding(pdc_core *pdc, const char *encoding) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + pdc_encodingvector *ev = NULL; + char buffer[PDC_ENCNAME_LEN]; + pdc_encoding_info *info; + int slot; + + /* substituting encoding name */ + encoding = pdc_subst_encoding_name(pdc, encoding, buffer); + + /* search for a fixed encoding */ + for (slot = (pdc_encoding) pdc_invalidenc + 1; + slot < (pdc_encoding) pdc_firstvarenc; slot++) + { + if (!strcmp(encoding, pdc_get_fixed_encoding_name((pdc_encoding) slot))) + { + /* copy in-core encoding at fixed slots */ + if (slot >= 0) + { + if (est->number == 0) + pdc_insert_encoding_vector(pdc, NULL); + info = &est->info[slot]; + if (info->ev == NULL) + info->ev = pdc_copy_core_encoding(pdc, encoding); + } + return((pdc_encoding) slot); + } + } + + /* search for a user defined encoding */ + for (slot = (pdc_encoding) pdc_firstvarenc; + slot < est->number; slot++) + { + info = &est->info[slot]; + if (info->ev != NULL && info->ev->apiname != NULL && + !strcmp(encoding, info->ev->apiname)) + return((pdc_encoding) slot); + } + + /* search for an in-core encoding */ + ev = pdc_copy_core_encoding(pdc, encoding); + if (ev != NULL) + return pdc_insert_encoding_vector(pdc, ev); + + return (pdc_invalidenc); +} + + +pdc_encoding +pdc_insert_encoding(pdc_core *pdc, const char *encoding, int *codepage, + pdc_bool verbose) +{ + const char *filename; + char buffer[PDC_ENCNAME_LEN]; + pdc_encodingvector *ev = NULL; + pdc_encoding enc = pdc_invalidenc; + pdc_bool logg = pdc_true; + + *codepage = 0; + + /* substituting encoding name */ + encoding = pdc_subst_encoding_name(pdc, encoding, buffer); + + /* check for an user-defined encoding */ + filename = pdc_find_resource(pdc, "Encoding", encoding); + if (filename) + ev = pdc_read_encoding(pdc, encoding, filename, verbose); + if (ev == NULL) + { + /* check for a generate encoding */ + ev = pdc_generate_encoding(pdc, encoding); + if (ev == NULL) + { + { + if (!strcmp(encoding, PDC_ENC_TEMPNAME)) + { + ev = pdc_new_encoding(pdc, encoding); + ev->flags |= PDC_ENC_TEMP; + logg = pdc_false; + } + else + { + pdc_set_errmsg(pdc, PDC_E_ENC_NOTFOUND, + encoding, 0, 0, 0); + + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + + return pdc_invalidenc; + } + } + } + } + + if (*codepage) + enc = pdc_unicode; + else + enc = pdc_insert_encoding_vector(pdc, ev); + + if (logg) + pdc_encoding_logg_protocol(pdc, ev); + + return enc; +} + +pdc_encoding +pdc_get_encoding(pdc_core *pdc, const char *encoding, int *codepage, + pdc_bool verbose) +{ + pdc_encoding enc = pdc_invalidenc; + + *codepage = 0; + enc = pdc_find_encoding(pdc, encoding); + if (enc == pdc_invalidenc) + enc = pdc_insert_encoding(pdc, encoding, codepage, verbose); + if (enc == pdc_invalidenc && verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + + return enc; +} + +pdc_encoding_info * +pdc_get_encoding_info(pdc_core *pdc, pdc_encoding enc) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + pdc_encoding_info *info = NULL; + + if (est) + { + if (est->number == 0) + pdc_insert_encoding_vector(pdc, NULL); + if (enc >= 0 && enc < est->number) + { + info = &est->info[enc]; + if (info->ev == NULL) + { + const char *encoding = pdc_get_fixed_encoding_name(enc); + + if (encoding[0] != 0) + { + pdc_find_encoding(pdc, encoding); + info = &est->info[enc]; + } + } + } + } + + return info; +} + +const char * +pdc_get_user_encoding(pdc_core *pdc, pdc_encoding enc) +{ + const char *encoding = pdc_get_fixed_encoding_name(enc); + + if (!encoding[0] && enc >= 0) + { + pdc_encoding_info *info = pdc_get_encoding_info(pdc, enc); + if (info->ev != NULL) + encoding = info->ev->apiname; + } + + return encoding; +} + +pdc_encodingvector * +pdc_get_encoding_vector(pdc_core *pdc, pdc_encoding enc) +{ + pdc_encoding_info *info = pdc_get_encoding_info(pdc, enc); + + return info ? info->ev : NULL; +} + + +pdc_encodingvector * +pdc_get_encoding_vector_direct(pdc_core *pdc, pdc_encoding enc) +{ + return pdc->encstack->info[enc].ev; +} + +void +pdc_set_encoding_glyphnames(pdc_core *pdc, pdc_encoding enc) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + pdc_encodingvector *ev = est->info[enc].ev; + int slot; + pdc_ushort uv; + + if (ev != NULL && !(ev->flags & PDC_ENC_SETNAMES)) + { + ev->flags |= PDC_ENC_SETNAMES; + for (slot = 0; slot < 256; slot++) + { + uv = ev->codes[slot]; + ev->chars[slot] = (char *)pdc_unicode2glyphname(pdc, uv); + } + } +} + +pdc_bool +pdc_get_encoding_isstdflag(pdc_core *pdc, pdc_encoding enc) +{ + pdc_encoding_stack *est = pdc_get_encodingstack(pdc); + pdc_encodingvector *ev = est->info[enc].ev; + int slot; + pdc_bool isstd = pdc_true; + + if (ev != NULL && + !(ev->flags & PDC_ENC_INCORE) && !(ev->flags & PDC_ENC_STDNAMES)) + { + for (slot = 0; slot < 256; slot++) + { + if (!(ev->flags & PDC_ENC_SETNAMES)) + ev->chars[slot] = + (char *) pdc_unicode2glyphname(pdc, ev->codes[slot]); + if (isstd == pdc_true && ev->chars[slot]) + { + isstd = pdc_is_std_charname((char *) ev->chars[slot]); + if (isstd == pdc_false && (ev->flags & PDC_ENC_SETNAMES)) + break; + } + } + ev->flags |= PDC_ENC_SETNAMES; + if (isstd == pdc_true) + ev->flags |= PDC_ENC_STDNAMES; + } + + return (ev->flags & PDC_ENC_STDNAMES) ? pdc_true : pdc_false; +} + +pdc_bool +pdc_is_encoding_subset(pdc_core *pdc, pdc_encodingvector *testev, + pdc_encodingvector *refev) +{ + pdc_ushort uv; + int code; + + for (code = 0; code < 256; code++) + { + uv = testev->codes[code]; + if (pdc_get_encoding_bytecode(pdc, refev, uv) == -1) + { + const char *glyphname = pdc_unicode2adobe(uv); + if (glyphname && strcmp(glyphname, pdc_get_notdef_glyphname())) + { + break; + } + } + } + + return (code == 256) ? pdc_true : pdc_false; +} + +/* ------------------------- PDF encodings ------------------------ */ + +static const pdc_keyconn pdc_pdfencoding_keytable[] = +{ + {"WinAnsiEncoding", pdc_winansi}, + {"MacRomanEncoding", pdc_macroman}, + {"PDFDocEncoding", pdc_pdfdoc}, + {"StandardEncoding", pdc_stdenc}, + {"MacExpertEncoding", pdc_macexpert}, + {NULL, 0}, +}; + +const char * +pdc_get_pdf_encoding_name(int enc) +{ + const char *encname = pdc_get_keyword(enc, pdc_pdfencoding_keytable); + + return encname ? encname : ""; +} + +int +pdc_get_pdf_encoding_code(const char *encname) +{ + int enc = pdc_get_keycode(encname, pdc_pdfencoding_keytable); + + return (enc != PDC_KEY_NOTFOUND) ? enc : pdc_invalidenc; +} + +/* ---------------------- private glyph table ---------------------- */ + +#define PRIVGLYPHS_CHUNKSIZE 256 + + +struct pdc_priv_glyphtab_s +{ + pdc_glyph_tab *unicode2name; /* private unicode to glyphname table */ + pdc_glyph_tab *name2unicode; /* private glyphname to unicode table */ + int glyph_tab_capacity; /* currently allocated size */ + int glyph_tab_size; /* size of glyph tables */ + pdc_ushort next_unicode; /* next available unicode number */ +}; + +pdc_priv_glyphtab * +pdc_new_pglyphtab(pdc_core *pdc) +{ + static const char fn[] = "pdc_new_pglyphtab"; + + pdc_priv_glyphtab *pgt = (pdc_priv_glyphtab *) pdc_malloc(pdc, + sizeof(pdc_priv_glyphtab), fn); + + pgt->next_unicode = (pdc_ushort) PDC_UNICODE_PDFPUA; + pgt->unicode2name = NULL; + pgt->name2unicode = NULL; + pgt->glyph_tab_capacity = 0; + pgt->glyph_tab_size = 0; + + pdc->pglyphtab = pgt; + + return pgt; +} + +void +pdc_delete_pglyphtab(pdc_core *pdc) +{ + pdc_priv_glyphtab *pgt = pdc->pglyphtab; + + if (pgt) + { + int slot; + + if (pgt->unicode2name) + { + for (slot = 0; slot < pgt->glyph_tab_size; slot++) + pdc_free(pdc, (char *)pgt->unicode2name[slot].name); + + if (pgt->unicode2name) + pdc_free(pdc, pgt->unicode2name); + pgt->unicode2name = NULL; + } + + if (pgt->name2unicode) + pdc_free(pdc, pgt->name2unicode); + pgt->name2unicode = NULL; + + + pdc_free(pdc, pgt); + pdc->pglyphtab = NULL; + } +} + +static pdc_priv_glyphtab * +pdc_get_glyphtab(pdc_core *pdc) +{ + pdc_priv_glyphtab *pgt = pdc->pglyphtab; + + if (pgt == NULL) + pgt = pdc_new_pglyphtab(pdc); + + return pgt; +} + +pdc_ushort +pdc_register_glyphname(pdc_core *pdc, const char *glyphname, + pdc_ushort uv, pdc_bool forcepua) +{ + static const char fn[] = "pdc_register_glyphname"; + pdc_priv_glyphtab *pgt = pdc_get_glyphtab(pdc); + char buf[16]; + int i, n, slot, slotname, slotuv; + + /* Re-allocate private glyphname tables */ + if (pgt->glyph_tab_size == pgt->glyph_tab_capacity) + { + if (pgt->glyph_tab_capacity == 0) + { + pgt->glyph_tab_size = 0; + pgt->glyph_tab_capacity = PRIVGLYPHS_CHUNKSIZE; + pgt->unicode2name = (pdc_glyph_tab *) pdc_malloc(pdc, + sizeof(pdc_glyph_tab) * pgt->glyph_tab_capacity, fn); + pgt->name2unicode = (pdc_glyph_tab *) pdc_malloc(pdc, + sizeof(pdc_glyph_tab) * pgt->glyph_tab_capacity, fn); + } + else + { + n = pgt->glyph_tab_capacity + PRIVGLYPHS_CHUNKSIZE; + pgt->unicode2name = (pdc_glyph_tab *) pdc_realloc(pdc, + pgt->unicode2name, n * sizeof(pdc_glyph_tab), fn); + pgt->name2unicode = (pdc_glyph_tab *) pdc_realloc(pdc, + pgt->name2unicode, n * sizeof(pdc_glyph_tab), fn); + pgt->glyph_tab_capacity = n; + } + } + + /* Set reasonable glyph name "unixxxx" */ + if (!glyphname) + { + sprintf(buf, "uni%04X", uv); + glyphname = buf; + } + + /* Set reasonable unicode value in the case of "unixxxx" glyph names. + * Otherwise the next free PDFlib PUA value + */ + if (!uv) + { + if (!forcepua && !strncmp(glyphname, "uni", 3) && + pdc_str2integer(&glyphname[3], PDC_INT_HEXADEC, &i)) + uv = (pdc_ushort) i; + if (!uv) + { + uv = pgt->next_unicode; + pgt->next_unicode = (pdc_ushort) (uv + 1); + } + } + + /* Find slot so that new glyphname is sorted in to name table */ + slotname = pgt->glyph_tab_size; + if (slotname > 0 && + strcmp(glyphname, pgt->name2unicode[slotname-1].name) < 0) + { + for (slot = 0; slot < pgt->glyph_tab_size; slot++) + { + if (strcmp(glyphname, pgt->name2unicode[slot].name) < 0) + break; + } + slotname = slot; + if (slot < pgt->glyph_tab_size) + { + for (slot = pgt->glyph_tab_size; slot > slotname; slot--) + { + pgt->name2unicode[slot].code = pgt->name2unicode[slot-1].code; + pgt->name2unicode[slot].name = pgt->name2unicode[slot-1].name; + } + } + } + + /* Find slot so that new unicode is sorted in to unicode table */ + slotuv = pgt->glyph_tab_size; + if (slotuv > 0 && + uv > pgt->unicode2name[slotuv-1].code) + { + for (slot = 0; slot < pgt->glyph_tab_size; slot++) + { + if (uv < pgt->unicode2name[slot].code) + break; + } + + slotuv = slot; + if (slot < pgt->glyph_tab_size) + { + for (slot = pgt->glyph_tab_size; slot > slotuv; slot--) + { + pgt->unicode2name[slot].code = pgt->unicode2name[slot-1].code; + pgt->unicode2name[slot].name = pgt->unicode2name[slot-1].name; + } + } + } + + pgt->name2unicode[slotname].code = uv; + pgt->name2unicode[slotname].name = pdc_strdup(pdc, glyphname); + pgt->unicode2name[slotuv].code = uv; + pgt->unicode2name[slotuv].name = pgt->name2unicode[slotname].name; + + pgt->glyph_tab_size += 1; + + return uv; +} + +int +pdc_privglyphname2unicode(pdc_core *pdc, const char *glyphname) +{ + pdc_priv_glyphtab *pgt = pdc_get_glyphtab(pdc); + + if (pgt && pgt->glyph_tab_size) + return pdc_glyphname2code(glyphname, pgt->name2unicode, + pgt->glyph_tab_size); + return -1; +} + +int +pdc_glyphname2unicodelist(pdc_core *pdc, const char *glyphname, + pdc_ushort *uvlist) +{ + int nv = 0, retval = -1; + + /* private glyph names */ + retval = pdc_privglyphname2unicode(pdc, glyphname); + if (retval > -1) + { + nv = 1; + uvlist[0] = (pdc_ushort) retval; + } + + if (!nv) + { + /* .notdef */ + if (glyphname == NULL) + glyphname = pdc_get_notdef_glyphname(); + if (!strcmp(glyphname, pdc_get_notdef_glyphname())) + { + nv = 1; + uvlist[0] = 0; + } + else + { + /* Searching for glyph name in AGL, + * ZapfDingbats and misnamed table + */ + retval = pdc_adobe2unicode(glyphname); + if (retval > -1) + { + nv = 1; + uvlist[0] = (pdc_ushort) retval; + } + else + { + nv = pdc_newadobe2unicodelist(glyphname, uvlist); + if (!nv) + { + retval = pdc_zadb2unicode(glyphname); + if (retval > -1) + { + nv = 1; + uvlist[0] = (pdc_ushort) retval; + } + } + } + } + } + + return nv; +} + +int +pdc_glyphname2unicode(pdc_core *pdc, const char *glyphname) +{ + pdc_ushort uvlist[PDC_MAX_UVLIST]; + int nv = pdc_glyphname2unicodelist(pdc, glyphname, uvlist); + + switch (nv) + { + case 0: + return -1; + + case 1: + return (int) uvlist[0]; + + /* we doesn't support glyph names + * with multiple Unicode values */ + default: + return 0; + } +} + +int +pdc_glyphname2utf32(pdc_core *pdc, const char *glyphname) +{ + pdc_ushort uvlist[PDC_MAX_UVLIST]; + int ic = 0, nv, usv; + + nv = pdc_glyphname2unicodelist(pdc, glyphname, uvlist); + usv = pdc_char16_to_char32(pdc, uvlist, &ic, 2, pdc_false); + if (nv <= 2 && usv > -1) + return usv; + + return -1; +} + +const char * +pdc_glyphname2privglyphname(pdc_core *pdc, const char *glyphname) +{ + pdc_priv_glyphtab *pgt = pdc_get_glyphtab(pdc); + + if (pgt && pgt->glyph_tab_size) + return pdc_glyphname2glyphname(glyphname, pgt->name2unicode, + pgt->glyph_tab_size); + return NULL; +} + +const char * +pdc_unicode2glyphname(pdc_core *pdc, pdc_ushort uv) +{ + pdc_priv_glyphtab *pgt = pdc_get_glyphtab(pdc); + const char *retval = NULL; + + /* Private unicode table available */ + if (pgt && pgt->glyph_tab_size) + retval = pdc_code2glyphname(uv, pgt->unicode2name, + pgt->glyph_tab_size); + + /* Searching for unicode value in AGL, ZapfDingbats and misnamed table */ + if (retval == NULL) + { + retval = pdc_unicode2adobe(uv); + if (retval == NULL) + { + retval = pdc_unicode2newadobe(uv); + if (retval == NULL) + { + retval = pdc_unicode2zadb(uv); + } + } + } + return retval; +} + +pdc_ushort +pdc_insert_glyphname(pdc_core *pdc, const char *glyphname) +{ + pdc_ushort uv; + int retval; + + retval = pdc_glyphname2unicode(pdc, glyphname); + if (retval == -1) + uv = pdc_register_glyphname(pdc, glyphname, 0, pdc_false); + else + uv = (pdc_ushort) retval; + return uv; +} + +const char * +pdc_insert_unicode(pdc_core *pdc, pdc_ushort uv) +{ + const char *glyphname; + + glyphname = pdc_unicode2glyphname(pdc, uv); + if (!glyphname) + { + pdc_register_glyphname(pdc, NULL, uv, pdc_false); + glyphname = pdc_unicode2glyphname(pdc, uv); + } + return glyphname; +} + + + +void +pdc_encoding_logg_protocol(pdc_core *pdc, pdc_encodingvector *ev) +{ + if (ev != NULL && + pdc_logg_is_enabled(pdc, 2, trc_encoding)) + { + int slot; + + pdc_logg(pdc, + "\n\t\tEncoding name: \"%s\"\n" + "\t\tCode Unicode Name\n", + ev->apiname); + + for (slot = 0; slot < 256; slot++) + { + pdc_ushort uv = ev->codes[slot]; + + if (!(ev->flags & PDC_ENC_SETNAMES)) + ev->chars[slot] = (char *)pdc_unicode2glyphname(pdc, uv); + + if (uv != 0) + { + pdc_logg(pdc, + "\t\t%4d U+%04X \"%s\"", + slot, uv, ev->chars[slot] ? ev->chars[slot] : ""); + + + pdc_logg(pdc, "\n"); + } + } + + ev->flags |= PDC_ENC_SETNAMES; + } +} diff --git a/src/pdflib/pdcore/pc_encoding.h b/src/pdflib/pdcore/pc_encoding.h new file mode 100644 index 0000000..633e1a7 --- /dev/null +++ b/src/pdflib/pdcore/pc_encoding.h @@ -0,0 +1,295 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_encoding.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Encoding data structures and routines + * + */ + +#ifndef PC_ENCODING_H +#define PC_ENCODING_H + +/* + * Symbolic names for predefined font encodings. 0 and above are used + * as indices in the pdc_encodingvector array. The encodings starting at + * pdc_firstvarenc have no enumeration name, because they are loaded + * dynamically. + * The predefined encodings must not be changed or rearranged. + * The order of encodings here must match that of pdc_core_encodings + * and pdc_fixed_encoding_names in pc_encoding.c. + */ +typedef enum +{ + pdc_invalidenc = -5, + pdc_glyphid = -4, + pdc_unicode = -3, + pdc_builtin = -2, + pdc_cid = -1, + + pdc_winansi = 0, + pdc_macroman = 1, + pdc_macroman_apple = 2, + pdc_ebcdic = 3, + pdc_ebcdic_37 = 4, + pdc_ebcdic_winansi = 5, + pdc_pdfdoc = 6, + pdc_stdenc = 7, + pdc_macexpert = 8, + pdc_firstvarenc = 9, + + pdc_encmax = PDC_INT_MAX +} +pdc_encoding; + +/* Predefined character collections */ +typedef enum +{ + cc_none = 0, + cc_japanese, + cc_simplified_chinese, + cc_traditional_chinese, + cc_korean, + cc_identity, + cc_unknown +} +pdc_charcoll; + +#define PDC_NUMCHARCOLL 4 + +/* treatment of non-resolvable character references */ +typedef enum +{ + text_nocheck = -2, + text_error = -1, + text_replace = 0 +} +pdc_glyphcheck; + + + +#define PDC_EBCDIC_NAME "ebcdic" +#define PDC_EBCDIC_ENC pdc_ebcdic + +typedef struct pdc_charclass_tab_s pdc_charclass_tab; +typedef struct pdc_code_map_s pdc_code_map; +typedef struct pdc_encoding_info_s pdc_encoding_info; +typedef struct pdc_encoding_stack_s pdc_encoding_stack; +typedef struct pdc_encodingvector_s pdc_encodingvector; +typedef struct pdc_priv_glyphtab_s pdc_priv_glyphtab; +typedef struct pdc_glyph_tab_s pdc_glyph_tab; + +struct pdc_encodingvector_s +{ + char *apiname; /* PDFlib's name of the encoding at the API */ + pdc_ushort codes[256]; /* unicode values */ + char *chars[256]; /* character names */ + char given[256]; /* flags for kind of given character name */ + pdc_byte *sortedslots; /* slots for sorted unicode values */ + int nslots; /* number of sorted slots */ + unsigned long flags; /* flags, see PDC_ENC_... */ +}; + +struct pdc_encoding_info_s +{ + pdc_encodingvector *ev; /* encoding vector */ + pdc_id id; /* encoding object id */ + pdc_id tounicode_id; /* tounicode object ids */ + pdc_bool used_in_formfield; /* encoding is in use in form field */ + pdc_bool stored; /* encoding is stored in PDF */ +}; + +struct pdc_code_map_s +{ + pdc_ushort src; /* source code */ + pdc_ushort dst; /* destination code */ +}; + +struct pdc_glyph_tab_s +{ + pdc_ushort code; + const char *name; +}; + + +#define PDC_ENC_INCORE (1L<<0) /* encoding from in-core */ +#define PDC_ENC_FILE (1L<<1) /* encoding from file */ +#define PDC_ENC_HOST (1L<<2) /* encoding from host system */ +#define PDC_ENC_USER (1L<<3) /* encoding from user */ +#define PDC_ENC_FONT (1L<<4) /* encoding from font resp. for a font*/ +#define PDC_ENC_GENERATE (1L<<5) /* encoding generated from Unicode page */ +#define PDC_ENC_USED (1L<<6) /* encoding already used */ +#define PDC_ENC_SETNAMES (1L<<7) /* character names are set */ +#define PDC_ENC_ALLOCCHARS (1L<<8) /* character names are allocated */ +#define PDC_ENC_STDNAMES (1L<<9) /* character names are all Adobe standard */ +#define PDC_ENC_TEMP (1L<<10) /* temporary generated encoding */ + +#define PDC_ENC_MODSEPAR "_" /* separator of modified encoding */ +#define PDC_ENC_MODWINANSI "winansi_" /* prefix of modified winansi enc */ +#define PDC_ENC_MODMACROMAN "macroman_" /* prefix of modified macroman enc */ +#define PDC_ENC_MODEBCDIC "ebcdic_" /* prefix of modified ebcdic enc */ +#define PDC_ENC_ISO8859 "iso8859-" /* begin of iso8859 enc name */ +#define PDC_ENC_CP125 "cp125" /* begin of ANSI enc name */ + +#define PDC_ENC_TEMPNAME "__temp__enc__" /* name of temporary encoding */ + +#define PDC_ENCNAME_LEN PDC_FILENAMELEN + +/* Adobe glyph names can have maximal 7 components */ +#define PDC_MAX_UVLIST 8 + +/* maximal length of glyph names */ +#define PDC_CHARREF_MAXNAMLEN 64 + +/* types of glyph names */ +#define PDC_GLF_ISUNDEF (1<<0) /* is undefined (unknown Unicode(s) */ +#define PDC_GLF_ISAGL12NAME (1<<1) /* is AGL 1.2' name (without ambiguity) */ +#define PDC_GLF_ISAGL20NAME (1<<2) /* is AGL 2.0 and not AGL 1.2' */ +#define PDC_GLF_ISZADBNAME (1<<3) /* is ZapfDingbats name */ +#define PDC_GLF_ISUNINAME (1<<4) /* is a "uni" name (with single Unicode) */ +#define PDC_GLF_ISAMBIG (1<<5) /* is ambiguous name (double mapping) */ +#define PDC_GLF_ISVARIANT (1<<6) /* is glyphic variant (contains period) */ +#define PDC_GLF_ISDECOMP (1<<7) /* is decomposed glyph (contains underscores + * or more than one Unicode values) */ +#define PDC_GLF_ISCUS (1<<8) /* is a glyph from Unicode's Corporate + * Use Subarea (CUS) used by Adobe + * (U+F600 - U+F8FF) */ +#define PDC_GLF_ISLIGATURE (1<<9) /* is a Latin or Armenian ligature glyph */ +#define PDC_GLF_ISSURROGAT (1<<10) /* is a surrogate glyph */ +#define PDC_GLF_ISMISNAMED (1<<11) /* is misnamed (see tab_misnamed2uni) */ +#define PDC_GLF_ISINCORE (1<<12) /* is incore (AGL, ZapfDingabts, misnamed)*/ +#define PDC_GLF_ISPRIVATE (1<<13) /* is private glyph (in supplied glyphtab) + * or a heuristic determined character */ + +#define PDC_GLF_REDVARIANT (1<<0) /* reduce glyphic variant */ +#define PDC_GLF_DECOMPNAME (1<<1) /* decompose glyph name */ +#define PDC_GLF_CONVUNINAME (1<<2) /* convert unixxxx name */ +#define PDC_GLF_RESOLCUS (1<<3) /* resolve CUS value */ +#define PDC_GLF_RESOLLIGAT (1<<4) /* resolve ligature value */ +#define PDC_GLF_ALTGREEKMAP (1<<5) /* take alternative greek mapping */ +#define PDC_GLF_ALTMAPPING (1<<6) /* take alternative mapping */ +#define PDC_GLF_STDTYPE3MAP (1<<7) /* standard Type3 glyph name mapping */ + +/* standard flags */ +#define PDC_GLF_STANDARD1 (PDC_GLF_REDVARIANT | PDC_GLF_DECOMPNAME | \ + PDC_GLF_CONVUNINAME | PDC_GLF_RESOLCUS | \ + PDC_GLF_RESOLLIGAT) + +/* standard flags with keeping standard ligatures and CUS values */ +#define PDC_GLF_STANDARD2 (PDC_GLF_REDVARIANT | PDC_GLF_DECOMPNAME | \ + PDC_GLF_CONVUNINAME) + +/* pc_chartabs.c */ +int pdc_glyphname2codelist(const char *glyphname, const pdc_glyph_tab *glyphtab, + int tabsize, pdc_ushort *codelist); +int pdc_glyphname2code(const char *glyphname, const pdc_glyph_tab *glyphtab, + int tabsize); +const char *pdc_code2glyphname(pdc_ushort code, const pdc_glyph_tab *glyphtab, + int tabsize); +int pdc_code2codelist(pdc_core *pdc, pdc_ushort code, + const pdc_code_map *codemap, int tabsize, pdc_ushort *codelist, + int listsize); +const char *pdc_glyphname2glyphname(const char *glyphname, + const pdc_glyph_tab *glyphtab, int tabsize); + +int pdc_adobe2unicode(const char *glyphname); +const char *pdc_unicode2adobe(pdc_ushort uv); +const char *pdc_get_notdef_glyphname(void); +int pdc_zadb2unicode(const char *glyphname); +const char *pdc_unicode2zadb(pdc_ushort uv); +int pdc_newadobe2unicodelist(const char *glyphname, pdc_ushort *uvlist); +const char *pdc_unicode2newadobe(pdc_ushort uv); +const char *pdc_get_newadobe_glyphname(const char *glyphname); +int pdc_glyphname2altunicode(const char *glyphname); + +pdc_bool pdc_is_std_charname(const char *glyphname); +void pdc_delete_missingglyph_bit(pdc_ushort uv, pdc_ulong *bmask); +pdc_ushort pdc_get_alter_glyphname(pdc_ushort uv, pdc_ulong bmask, + char **glyphname); +int pdc_string2unicode(pdc_core *pdc, const char *text, int i_flags, + const pdc_keyconn *keyconn, pdc_bool verbose); +pdc_bool pdc_is_linebreaking_relchar(pdc_ushort uv); + + + +/* pc_core.c */ +void pdc_set_encodingstack_ptr(pdc_core *pdc, pdc_encoding_stack *encstack); +pdc_encoding_stack *pdc_get_encodingstack_ptr(pdc_core *pdc); +void pdc_set_pglyphtab_ptr(pdc_core *pdc, pdc_priv_glyphtab *pglyphtab); +pdc_priv_glyphtab *pdc_get_pglyphtab_ptr(pdc_core *pdc); + +/* pc_encoding.c */ +void pdc_init_encoding(pdc_core *pdc, pdc_encodingvector *ev, + const char *name); +pdc_encodingvector *pdc_new_encoding(pdc_core *pdc, const char *name); +void pdc_cleanup_encoding(pdc_core *pdc, pdc_encodingvector *ev); +pdc_encodingvector *pdc_copy_encoding(pdc_core *pdc, pdc_encodingvector *evfrom, + const char *name); +int pdc_get_encoding_bytecode(pdc_core *pdc, pdc_encodingvector *ev, + pdc_ushort uv); +pdc_byte pdc_transform_bytecode(pdc_core *pdc, pdc_encodingvector *evto, + pdc_encodingvector *evfrom, pdc_byte code); +pdc_encodingvector *pdc_copy_core_encoding(pdc_core *pdc, const char *encoding); +const char *pdc_get_fixed_encoding_name(pdc_encoding enc); + + +pdc_encodingvector *pdc_read_encoding(pdc_core *pdc, const char *encoding, + const char *filename, pdc_bool verbose); +pdc_encodingvector *pdc_generate_encoding(pdc_core *pdc, const char *encoding); +void pdc_encoding_logg_protocol(pdc_core *pdc, pdc_encodingvector *ev); + +pdc_encoding_stack *pdc_new_encodingstack(pdc_core *pdc); +void pdc_delete_encodingstack(pdc_core *pdc); +pdc_encoding pdc_insert_encoding_vector(pdc_core *pdc, + pdc_encodingvector *ev); +pdc_encoding pdc_get_encoding(pdc_core *pdc, const char *encoding, + int *codepage, pdc_bool verbose); +pdc_encoding pdc_insert_encoding(pdc_core *pdc, const char *encoding, + int *codepage, pdc_bool verbose); +void pdc_remove_encoding_vector(pdc_core *pdc, int slot); +pdc_encoding pdc_find_encoding(pdc_core *pdc, const char *encoding); +void pdc_set_encoding_glyphnames(pdc_core *pdc, pdc_encoding enc); +pdc_bool pdc_get_encoding_isstdflag(pdc_core *pdc, pdc_encoding enc); +pdc_bool pdc_is_encoding_subset(pdc_core *pdc, pdc_encodingvector *testev, + pdc_encodingvector *refev); + +int pdc_get_encodingstack_number(pdc_core *pdc); +pdc_encoding_info *pdc_get_encoding_info(pdc_core *pdc, + pdc_encoding enc); +pdc_encodingvector *pdc_get_encoding_vector(pdc_core *pdc, + pdc_encoding enc); +pdc_encodingvector *pdc_get_encoding_vector_direct(pdc_core *pdc, + pdc_encoding enc); +const char *pdc_get_user_encoding(pdc_core *pdc, pdc_encoding enc); +void pdc_init_encoding_info_ids(pdc_core *pdc); + +const char *pdc_get_pdf_encoding_name(int enc); +int pdc_get_pdf_encoding_code(const char *encname); +pdc_encodingvector *pdc_generate_pdfencoding(pdc_core *pdc, + const char *pdfname); + +pdc_priv_glyphtab *pdc_new_pglyphtab(pdc_core *pdc); +void pdc_delete_pglyphtab(pdc_core *pdc); +pdc_ushort pdc_register_glyphname(pdc_core *pdc, + const char *glyphname, pdc_ushort uv, pdc_bool forcepua); +int pdc_privglyphname2unicode(pdc_core *pdc, const char *glyphname); +int pdc_glyphname2unicodelist(pdc_core *pdc, const char *glyphname, + pdc_ushort *uvlist); +int pdc_glyphname2unicode(pdc_core *pdc, const char *glyphname); +int pdc_glyphname2utf32(pdc_core *pdc, const char *glyphname); +const char *pdc_glyphname2privglyphname(pdc_core *pdc, const char *glyphname); +const char *pdc_unicode2glyphname(pdc_core *pdc, pdc_ushort uv); +pdc_ushort pdc_insert_glyphname(pdc_core *pdc, const char *glyphname); +const char *pdc_insert_unicode(pdc_core *pdc, pdc_ushort uv); + + +#endif /* PC_ENCODING_H */ diff --git a/src/pdflib/pdcore/pc_exports.h b/src/pdflib/pdcore/pc_exports.h new file mode 100644 index 0000000..c062d70 --- /dev/null +++ b/src/pdflib/pdcore/pc_exports.h @@ -0,0 +1,24 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_exports.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Header for CodeWarrior to create a PDFlib DLL + * + */ + +/* + * Force a DLL to be built. + * This is useful as a prefix file when building a DLL with CodeWarrior. + */ + +#define PDFLIB_EXPORTS diff --git a/src/pdflib/pdcore/pc_file.c b/src/pdflib/pdcore/pc_file.c new file mode 100644 index 0000000..35c67ed --- /dev/null +++ b/src/pdflib/pdcore/pc_file.c @@ -0,0 +1,1548 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_file.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Various file routines + * + */ + +#include + +#include "pc_util.h" +#include "pc_md5.h" +#include "pc_file.h" + + +/* headers for getpid() or _getpid(). +*/ +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#else +#if defined(MAC) +#include +#else +#include +#include +#endif +#endif + +#ifndef WINCE +#include +#else +#include +#endif + +#ifdef VMS +#include +#include +#include +#endif + +/* platform independent wrapper functions for 64-bit file handling. +*/ +int +pdc__fseek(FILE *fp, pdc_off_t offset, int whence) +{ +#if defined(_LARGEFILE_SOURCE) + #if defined(WIN32) + switch (whence) + { + case SEEK_SET: + return fsetpos(fp, &offset); + + case SEEK_CUR: + { + pdc_off_t pos; + + fgetpos(fp, &pos); + pos += offset; + return fsetpos(fp, &pos); + } + + case SEEK_END: + { + pdc_off_t pos, len; + + pos = _telli64(fileno(fp)); + _lseeki64(fileno(fp), 0, SEEK_END); + len = _telli64(fileno(fp)); + _lseeki64(fileno(fp), pos, SEEK_SET); + + len += offset; + return fsetpos(fp, &len); + } + + default: + return -1; + } + #else + return fseeko(fp, offset, whence); + #endif +#else + return fseek(fp, offset, whence); +#endif +} + +pdc_off_t +pdc__ftell(FILE *fp) +{ +#if defined(_LARGEFILE_SOURCE) + #if defined(WIN32) + pdc_off_t pos; + + fgetpos(fp, &pos); + return pos; + #else + return ftello(fp); + #endif +#else + return ftell(fp); +#endif +} + +size_t +pdc__fread(void *ptr, size_t size, size_t nmemb, FILE *fp) +{ + return fread(ptr, size, nmemb, fp); +} + +size_t +pdc__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *fp) +{ + return fwrite(ptr, size, nmemb, fp); +} + +int +pdc__fgetc(FILE *fp) +{ + return fgetc(fp); +} + +int +pdc__feof(FILE *fp) +{ + return feof(fp); +} + +struct pdc_file_s +{ + pdc_core *pdc; /* pdcore struct */ + char *filename; /* file name */ + FILE *fp; /* file struct or NULL. Then data != NULL: */ + pdc_bool wrmode; /* writing mode */ + pdc_byte *data; /* file data or NULL. Then fp != NULL */ + pdc_byte *end; /* first byte above data buffer */ + pdc_byte *pos; /* current file position in data buffer */ + pdc_byte *limit; /* limit of file buffer in writing mode */ +}; + +FILE * +pdc_get_fileptr(pdc_file *sfp) +{ + return sfp->fp; +} + +pdc_core * +pdc_get_pdcptr(pdc_file *sfp) +{ + return sfp->pdc; +} + +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma unmanaged +#endif +int +pdc_get_fopen_errnum(pdc_core *pdc, int errnum) +{ + int outnum = errnum, isread; + + (void) pdc; + + isread = (errnum == PDC_E_IO_RDOPEN); + +#if defined(VMS) + /* + * On the vms system, when a system error occurs which is not + * mapped into the unix styled errno values, errno is set EVMSERR + * and a VMS error code is set in vaxc$errno. + */ + switch (errno) + { + case EVMSERR: + { + /* unmapped VMS runtime error - check vaxc$errno */ + switch (vaxc$errno) + { + case 100052: /* old style RMS file specification syntax error */ + outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF; + } + } + return outnum; + } +#endif /* VMS */ + +#if defined(MVS) + + switch (errno) + { + case 49: + outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF; + } + return outnum; + +#elif defined(WIN32) + { + DWORD lasterror = GetLastError(); + switch (lasterror) + { + case ERROR_FILE_NOT_FOUND: + outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF; + break; + + case ERROR_ACCESS_DENIED: + case ERROR_INVALID_PASSWORD: + case ERROR_NETWORK_ACCESS_DENIED: + outnum = isread ? PDC_E_IO_RDOPEN_PD : PDC_E_IO_WROPEN_PD; + break; + + case ERROR_INVALID_NAME: + outnum = isread ? PDC_E_IO_RDOPEN_IS : PDC_E_IO_WROPEN_IS; + break; + + case ERROR_PATH_NOT_FOUND: + case ERROR_INVALID_DRIVE: + case ERROR_BAD_NETPATH: + case ERROR_BAD_UNIT: + outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NP; + break; + + case ERROR_TOO_MANY_OPEN_FILES: + case ERROR_SHARING_BUFFER_EXCEEDED: + outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM; + break; + + case ERROR_BAD_COMMAND: + outnum = isread ? PDC_E_IO_RDOPEN_BC : PDC_E_IO_WROPEN_BC; + break; + + case ERROR_FILE_EXISTS: + outnum = PDC_E_IO_WROPEN_AE; + break; + + case ERROR_BUFFER_OVERFLOW: + outnum = PDC_E_IO_WROPEN_TL; + break; + + case ERROR_WRITE_FAULT: + case ERROR_CANNOT_MAKE: + outnum = PDC_E_IO_WROPEN_NC; + break; + + case ERROR_HANDLE_DISK_FULL: + case ERROR_DISK_FULL: + outnum = PDC_E_IO_WROPEN_NS; + break; + + case ERROR_SHARING_VIOLATION: + outnum = isread ? PDC_E_IO_RDOPEN_SV : PDC_E_IO_WROPEN_SV; + break; + + /* This code arises after opening a existing PDF or log file. + * Because the file could be opened, we can ignore this code. + */ + case ERROR_ALREADY_EXISTS: + lasterror = 0; + outnum = 0; + break; + } + + if (lasterror) + { + errno = (int) lasterror; + return outnum; + } + + /* if lasterror == 0 we must look for errno (see .NET) */ + } + +#endif /* WIN32 */ + + switch (errno) + { +#ifdef EACCES + case EACCES: + outnum = isread ? PDC_E_IO_RDOPEN_PD : PDC_E_IO_WROPEN_PD; + break; +#endif +#ifdef EMACOSERR + case EMACOSERR: +#if defined(MAC) + + switch (__MacOSErrNo) + { + case fnfErr: + case dirNFErr: + case resFNotFound: + case afpDirNotFound: + outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF; + break; + + case permErr: + case wrPermErr: + case wPrErr: + case afpAccessDenied: + case afpVolLocked: + outnum = isread ? PDC_E_IO_RDOPEN_PD : PDC_E_IO_WROPEN_PD; + break; + + case nsvErr: + case afpObjectTypeErr: + outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_IS; + break; + + case tmfoErr: + case afpTooManyFilesOpen: + outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM; + break; + + case opWrErr: + outnum = PDC_E_IO_WROPEN_AE; + break; + + case dirFulErr: + case dskFulErr: + case afpDiskFull: + outnum = PDC_E_IO_WROPEN_NS; + break; + + case fLckdErr: + case afpLockErr: + outnum = isread ? PDC_E_IO_RDOPEN_SV : PDC_E_IO_WROPEN_SV; + break; + + default: + break; + } + + if (__MacOSErrNo) + { + return outnum; + } +#endif + break; +#endif +#ifdef ENOENT + case ENOENT: + outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF; + break; +#endif +#ifdef EMFILE + case EMFILE: + outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM; + break; +#endif +#ifdef ENFILE + case ENFILE: + outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM; + break; +#endif +#ifdef EISDIR + case EISDIR: + outnum = isread ? PDC_E_IO_RDOPEN_ID : PDC_E_IO_WROPEN_ID; + break; +#endif +#ifdef EDQUOT + case EDQUOT: + outnum = isread ? PDC_E_IO_RDOPEN_QU : PDC_E_IO_WROPEN_QU; + break; +#endif +#ifdef EEXIST + case EEXIST: + outnum = PDC_E_IO_WROPEN_AE; + break; +#endif +#ifdef ENAMETOOLONG + case ENAMETOOLONG: + outnum = PDC_E_IO_WROPEN_TL; + break; +#endif +#ifdef ENOSPC + case ENOSPC: + outnum = PDC_E_IO_WROPEN_NS; + break; +#endif + default: + + /* observed on Solaris */ + if (errno == 0) + pdc_error(pdc, PDC_E_INT_BADERRNO, 0, 0, 0, 0); + + outnum = errnum; + break; + } + + return outnum; +} +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma managed +#endif + +void +pdc_set_fopen_errmsg(pdc_core *pdc, int errnum, const char *qualifier, + const char *filename) +{ + const char *stemp1 = NULL; + const char *stemp2 = NULL; + int errno1 = errno; + +#if defined(EMACOSERR) && defined(MAC) + errno1 = (int) __MacOSErrNo; +#endif + + errnum = pdc_get_fopen_errnum(pdc, errnum); + if (errnum == PDC_E_IO_RDOPEN) + errnum = PDC_E_IO_RDOPEN_CODE; + else if (errnum == PDC_E_IO_WROPEN) + errnum = PDC_E_IO_WROPEN_CODE; + if (errnum == PDC_E_IO_RDOPEN_CODE || errnum == PDC_E_IO_WROPEN_CODE) + { + stemp1 = pdc_errprintf(pdc, "%d", errno1); + +#ifdef PDC_HAS_STRERROR + stemp2 = strerror(errno1); + if (stemp2 != NULL) + { + if (errnum == PDC_E_IO_RDOPEN_CODE) + errnum = PDC_E_IO_RDOPEN_CODETEXT; + else if (errnum == PDC_E_IO_WROPEN_CODE) + errnum = PDC_E_IO_WROPEN_CODETEXT; + } +#endif + } + + pdc_set_errmsg(pdc, errnum, qualifier, filename, stemp1, stemp2); +} + +pdc_bool +pdc_check_fopen_errmsg(pdc_core *pdc, pdc_bool requested) +{ + return (requested || pdc_get_errnum(pdc) != PDC_E_IO_RDOPEN_NF) ? + pdc_false : pdc_undef; +} + +static void +pdc_logg_openclose(pdc_core *pdc, FILE *fp, pdc_bool opened) +{ + int errno1 = errno, errno2 = 0; + + if (pdc_logg_is_enabled(pdc, 3, trc_filesearch)) + { +#if defined(WIN32) + errno2 = (int) GetLastError(); +#elif defined(MAC) + errno2 = __MacOSErrNo; +#endif + pdc_logg(pdc, "\t%p", fp); + if (opened) + pdc_logg(pdc, " opened"); + else + pdc_logg(pdc, " closed"); +#if PDC_FILENO_EXISTS + if (fp != NULL && opened) + pdc_logg(pdc, ", fileno=%d", fileno(fp)); +#endif + pdc_logg(pdc, ", errno=%d", errno1); + if (errno2 != 0) + pdc_logg(pdc, ", errno2=%d", errno2); + pdc_logg(pdc, "\n"); + + /* because of logfile IO */ + if (errno != errno1) + errno = errno1; + } +} + +void * +pdc_read_file(pdc_core *pdc, FILE *fp, pdc_off_t *o_filelen, int incore) +{ + static const char fn[] = "pdc_read_file"; + pdc_off_t filelen = 0, len = 0; + char *content = NULL; + + +#if !defined(MVS) || !defined(I370) + + pdc__fseek(fp, 0, SEEK_END); + filelen = pdc__ftell(fp); + pdc__fseek(fp, 0, SEEK_SET); + + if (incore && filelen) + { + content = (char *) pdc_malloc(pdc, (size_t) (filelen + 1), fn); + len = (pdc_off_t) pdc__fread(content, 1, (size_t) filelen, fp); + +/* because pdc__ftell lies! */ +filelen = len; + if (!filelen) + { + pdc_free(pdc, content); + filelen = 0; + content = NULL; + } + } + +#endif + + if (content) content[filelen] = 0; + *o_filelen = filelen; + return (void *) content; +} + + +/* + * In the case of systems which are not capable of Unicode file names: + * + * File name can be converted to Latin-1: The incoming char pointer + * will be deleted and a new char pointer to the Latin-1 string will + * be returned. Otherwise an execption will be thrown. + * + */ +char * +pdc_check_filename(pdc_core *pdc, char *filename) +{ +#if !defined(PDC_UNICODE_FILENAME) + char *ffname = pdc_utf8_to_hostbytes(pdc, pdc->honorlang, filename); + + pdc_free(pdc, filename); + if (ffname == NULL) + pdc_error(pdc, PDC_E_IO_UNSUPP_UNINAME, 0, 0, 0, 0); + filename = (char *) ffname; +#endif + + return filename; +} + +char * +pdc_get_filename(pdc_core *pdc, char *filename) +{ + char *ffname; + +#if defined(PDC_UNICODE_FILENAME) + static const char fn[] = "pdc_get_filename"; + + ffname = pdc_strdup_ext(pdc, filename, 0, fn); +#else + ffname = pdc_hostbytes_to_utf8(pdc, pdc->honorlang, filename); +#endif + + return ffname; +} + +/* + * pdc_convert_filename_ext converts a file name as string of name type + * (see function pdc_convert_name) to a [EBCDIC-]UTF-8 string with or + * without a BOM. If the compiler doesn't allow Unicode filenames + * (see define PDC_UNICODE_FILENAME) the filename is Latin-1 encoded + * if possible or an exception will be thrown. + * + */ +const char * +pdc_convert_filename_ext(pdc_core *pdc, const char *filename, int len, + const char *paramname, pdc_encoding enc, int codepage, + int flags) +{ + char *fname = NULL; + const char *outfilename = NULL; + int i = 0; + + if (filename == NULL) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, paramname, 0, 0, 0); + + fname = pdc_convert_name_ext(pdc, filename, len, enc, codepage, flags); + + if (fname == NULL || *fname == '\0') + pdc_error(pdc, PDC_E_ILLARG_EMPTY, paramname, 0, 0, 0); + + if (pdc_is_utf8_bytecode(fname)) + { +#if defined(PDC_UNICODE_FILENAME) + i = 3; +#else + fname = pdc_check_filename(pdc, fname); +#endif + } + + outfilename = pdc_errprintf(pdc, "%s", &fname[i]); + pdc_free(pdc, fname); + + return outfilename; +} + +const char * +pdc_convert_filename(pdc_core *pdc, const char *filename, int len, + const char *paramname, pdc_bool withbom) +{ + int flags = PDC_CONV_EBCDIC; + + if (withbom) + flags |= PDC_CONV_WITHBOM; + + return pdc_convert_filename_ext(pdc, filename, len, paramname, + pdc_invalidenc, 0, flags); +} + +/* + * pdc_fopen_logg opens a file. The function expects a UTF-8 encoded file name. + * (see function pdc_convert_filename), if define PDC_UNICODE_FILENAME is set. + * + */ +FILE * +pdc_fopen_logg(pdc_core *pdc, const char *filename, const char *mode) +{ + FILE *fp = NULL; + +#if defined(PDC_UNICODE_FILENAME) + + pdc_byte *outfilename = NULL; + pdc_text_format nameformat = PDC_UTF8; + pdc_text_format targetnameformat = pdc_utf16; + int len = (int) strlen(filename); + int outlen = 0; + + /* convert filename from UTF-8 to UTF-16 or Latin-1 */ + pdc_convert_string(pdc, nameformat, 0, NULL, (pdc_byte *) filename, len, + &targetnameformat, NULL, &outfilename, &outlen, + PDC_CONV_TRYBYTES | PDC_CONV_NOBOM, pdc_true); + + if (targetnameformat == pdc_bytes) + { + fp = fopen((const char *) outfilename, mode); + } + else + { + wchar_t wmode[8]; + int i; + + len = (int) strlen(mode); + for (i = 0; i < len; i++) + wmode[i] = (wchar_t) mode[i]; + wmode[len] = 0; + + fp = _wfopen((wchar_t *) outfilename, wmode); + } + + pdc_free(pdc, outfilename); + +#else + (void) pdc; + + fp = fopen(filename, mode); +#endif + + pdc_logg_openclose(pdc, fp, pdc_true); + + return fp; +} + +pdc_file * +pdc_fopen(pdc_core *pdc, const char *filename, const char *qualifier, + const pdc_byte *data, size_t size, int flags) +{ + static const char fn[] = "pdc_fopen"; + pdc_file *sfp; + + sfp = (pdc_file *) pdc_calloc(pdc, sizeof(pdc_file), fn); + + /* initialize */ + sfp->pdc = pdc; + sfp->filename = pdc_strdup_ext(pdc, filename, 0, fn); + + if (flags & PDC_FILE_WRITEMODE || flags & PDC_FILE_APPENDMODE) + sfp->wrmode = pdc_true; + + + if (data != NULL || size > 0) + { + /* virtual file */ + if (sfp->wrmode) + { + sfp->data = (pdc_byte *) pdc_calloc(pdc, size, fn); + if (data != NULL) + { + /* append mode */ + memcpy(sfp->data, data, size); + sfp->pos = sfp->data + size; + } + else + { + sfp->pos = sfp->data; + } + sfp->end = sfp->pos; + sfp->limit = sfp->data + size; + } + else + { + sfp->data = (pdc_byte *) data; + sfp->pos = sfp->data; + sfp->end = sfp->data + size; + } + } + else + { + const char *mode; + + + /* disk file */ + if (flags & PDC_FILE_BINARY) + mode = READBMODE; + else + mode = READTMODE; + if (flags & PDC_FILE_APPENDMODE) + mode = APPENDMODE; + else if (flags & PDC_FILE_WRITEMODE) + mode = WRITEMODE; + + sfp->fp = pdc_fopen_logg(pdc, filename, mode); + if (sfp->fp == NULL) + { + pdc_fclose(sfp); + + if (qualifier == NULL) + qualifier = ""; + pdc_set_fopen_errmsg(pdc, PDC_E_IO_RDOPEN, qualifier, filename); + return NULL; + } + } + + return sfp; +} + +pdc_bool +pdc_file_isvirtual(pdc_file *sfp) +{ + return sfp->fp ? pdc_false : pdc_true; +} + +char * +pdc_file_name(pdc_file *sfp) +{ + return sfp->filename; +} + +pdc_core * +pdc_file_getpdc(pdc_file *sfp) +{ + return sfp->pdc; +} + +pdc_off_t +pdc_file_size(pdc_file *sfp) +{ + pdc_off_t filelen; + + if (sfp->fp) + { + pdc_off_t pos = pdc__ftell(sfp->fp); + + pdc_read_file(sfp->pdc, sfp->fp, &filelen, 0); + pdc__fseek(sfp->fp, pos, SEEK_SET); + } + else + filelen = (pdc_off_t) (sfp->end - sfp->data); + + return filelen; +} + +const void * +pdc_freadall(pdc_file *sfp, size_t *filelen, pdc_bool *ismem) +{ + const void *result = NULL; + + *filelen = 0; + + pdc_logg_cond(sfp->pdc, 1, trc_filesearch, + "\tAttempting to read whole file \"%s\"\n", sfp->filename); + + if (sfp->fp) + { + pdc_off_t flen; /* TODO2GB: >2GB on 32-bit platforms? */ + + result = pdc_read_file(sfp->pdc, sfp->fp, &flen, 1); + + if (ismem) + *ismem = pdc_false; + *filelen = (size_t) flen; + } + else + { + result = sfp->data; + + if (ismem) + *ismem = pdc_true; + *filelen = (size_t) (sfp->end - sfp->data); + } + + pdc_logg_cond(sfp->pdc, 1, trc_filesearch, + "\t%d bytes read from %s file, contents=%p\n", + (int) (*filelen), + (sfp->fp) ? "disk" : "memory", + result); + + return result; +} + +static int +pdc_fgetc_e(pdc_file *sfp) +{ + int c = pdc_fgetc(sfp); + return c; +} + +char * +pdc_fgetline(char *s, int size, pdc_file *sfp) +{ + int i, c; + + c = pdc_fgetc_e(sfp); + if (c == EOF) + return NULL; + + size--; + for (i = 0; i < size; i++) + { + if (c == '\n' || c == '\r' || c == EOF) break; + s[i] = (char) c; + c = pdc_fgetc_e(sfp); + } + s[i] = 0; + + /* Skip windows line end \r\n */ + if (c == '\r') + { + c = pdc_fgetc_e(sfp); + + if (c != '\n' && c != EOF) + { + if (sfp->fp) + ungetc(c, sfp->fp); + else + pdc_fseek(sfp, -1, SEEK_CUR); + } + } + return s; +} + +/* + * Emulation of C file functions - relevant for PDFlib + */ + +pdc_off_t +pdc_ftell(pdc_file *sfp) +{ + if (sfp->fp) + return pdc__ftell(sfp->fp); + + return (pdc_off_t) (sfp->pos - sfp->data); +} + +int +pdc_fseek(pdc_file *sfp, pdc_off_t offset, int whence) +{ + static const char fn[] = "pdc_fseek"; + + if (sfp->fp) + return pdc__fseek(sfp->fp, offset, whence); + + switch (whence) + { + case SEEK_SET: + sfp->pos = sfp->data + offset; + break; + + case SEEK_CUR: + sfp->pos += offset; + break; + + case SEEK_END: + sfp->pos = sfp->end; + break; + } + + if (sfp->pos > sfp->end) + { + /* extend file in writing mode */ + if (sfp->wrmode) + { + size_t nbytes = (size_t) (sfp->pos - sfp->end); + + if (sfp->pos > sfp->limit) + { + size_t size = (size_t) (sfp->pos - sfp->data); + + sfp->data = (pdc_byte *) pdc_realloc(sfp->pdc, sfp->data, size, + fn); + sfp->end = sfp->data + size; + sfp->pos = sfp->end; + sfp->limit = sfp->end; + } + + memset(sfp->pos - nbytes, 0, nbytes); + } + else + { + return -1; + } + } + else if (sfp->pos < sfp->data) + { + return -1; + } + + return 0; +} + +size_t +pdc_fread(void *ptr, size_t size, size_t nmemb, pdc_file *sfp) +{ + size_t nbytes = 0; + + if (sfp->fp) + return pdc__fread(ptr, size, nmemb, sfp->fp); + + nbytes = size * nmemb; + if (sfp->pos + nbytes > sfp->end) + { + nbytes = (size_t) (sfp->end - sfp->pos); + nmemb = nbytes / size; + nbytes = nmemb *size; + } + + if (nbytes) + memcpy(ptr, sfp->pos, nbytes); + sfp->pos += nbytes; + + return nmemb; +} + +size_t +pdc_fwrite(const void *ptr, size_t size, size_t nmemb, pdc_file *sfp) +{ + static const char fn[] = "pdc_fwrite"; + + if (sfp->wrmode) + { + size_t poslen, nbytes = 0; + + if (sfp->fp) + return pdc__fwrite(ptr, size, nmemb, sfp->fp); + + nbytes = size * nmemb; + if (sfp->pos + nbytes > sfp->limit) + { + poslen = (size_t) (sfp->pos - sfp->data); + size = poslen + nbytes; + + sfp->data = (pdc_byte *) pdc_realloc(sfp->pdc, sfp->data, size, fn); + sfp->pos = sfp->data + poslen; + sfp->end = sfp->data + size; + sfp->limit = sfp->end; + } + memcpy(sfp->pos, ptr, nbytes); + sfp->pos += nbytes; + if (sfp->pos > sfp->end) + sfp->end = sfp->pos; + } + else + { + nmemb = 0; + } + + return nmemb; +} + +void +pdc_freset(pdc_file *sfp, size_t size) +{ + static const char fn[] = "pdc_freset"; + + if (sfp->wrmode && !sfp->fp) + { + if (size > (size_t) (sfp->limit - sfp->data)) + { + sfp->data = (pdc_byte *) pdc_realloc(sfp->pdc, sfp->data, size, fn); + sfp->limit = sfp->data + size; + } + + sfp->pos = sfp->data; + sfp->end = sfp->data; + } +} + +int +pdc_fgetc(pdc_file *sfp) +{ + int ch = 0; + + if (sfp->fp) + return pdc__fgetc(sfp->fp); + + if (sfp->pos < sfp->end) + { + ch = (int) *sfp->pos; + sfp->pos++; + } + else + { + ch = EOF; + } + + return ch; +} + +int +pdc_feof(pdc_file *sfp) +{ + if (sfp->fp) + return pdc__feof(sfp->fp); + + return (sfp->pos >= sfp->end) ? 1 : 0; +} + +void +pdc_fclose_logg(pdc_core *pdc, FILE *fp) +{ + fclose(fp); + pdc_logg_openclose(pdc, fp, pdc_false); +} + +void +pdc_fclose(pdc_file *sfp) +{ + if (sfp) + { + if (sfp->fp) + { + pdc_fclose_logg(sfp->pdc, sfp->fp); + sfp->fp = NULL; + } + else if (sfp->wrmode) + { + if (sfp->data) + { + pdc_free(sfp->pdc, sfp->data); + sfp->data = NULL; + } + } + + if (sfp->filename) + { + pdc_free(sfp->pdc, sfp->filename); + sfp->filename = NULL; + } + + pdc_free(sfp->pdc, sfp); + } +} + +/* + * Concatenating a directory name with a file base name to a full valid + * file name. On MVS platforms an extension at the end of basename + * will be discarded. + */ +void +pdc_file_fullname(const char *dirname, const char *basename, char *fullname) +{ + const char *pathsep = PDC_PATHSEP; + +#ifdef MVS + pdc_bool lastterm = pdc_false; +#endif + + if (!dirname || !dirname[0]) + { + strcpy(fullname, basename); + } + else + { + fullname[0] = 0; + +#ifdef MVS + if (strncmp(dirname, PDC_FILEQUOT, 1)) + strcat(fullname, PDC_FILEQUOT); +#endif + + strcat(fullname, dirname); + +#ifdef VMS + /* look for logical name or whose result */ + if(getenv(dirname)) + pathsep = PDC_PATHSEP_LOG; + else if (fullname[strlen(fullname)-1] == ']') + pathsep = ""; +#endif + + strcat(fullname, pathsep); + strcat(fullname, basename); + +#ifdef MVS + lastterm = pdc_true; +#endif + } + +#ifdef MVS + { + int ie, len; + + len = strlen(fullname); + for (ie = len - 1; ie >= 0; ie--) + { + if (fullname[ie] == pathsep[0]) + break; + + if (fullname[ie] == '.') + { + fullname[ie] = 0; + break; + } + } + if (lastterm) + { + strcat(fullname, PDC_PATHTERM); + strcat(fullname, PDC_FILEQUOT); + } + } +#endif +} + +#define EXTRA_SPACE 32 /* extra space for separators, FILEQUOT etc. */ + +char * +pdc_file_fullname_mem(pdc_core *pdc, const char *dirname, const char *basename) +{ + static const char fn[] = "pdc_file_fullname_mem"; + char *fullname; + size_t len; + + len = strlen(basename); + if (dirname && dirname[0]) + len += strlen(dirname); + len += EXTRA_SPACE; + fullname = (char *) pdc_malloc(pdc, len, fn); + + pdc_file_fullname(dirname, basename, fullname); + + return fullname; +} + +/* + * Returns the full specified path name in a new memory. + * The full path name can be concatened by a path name, + * file name and extension (incl. dot). + */ +char * +pdc_file_concat(pdc_core *pdc, const char *dirname, const char *basename, + const char *extension) +{ + static const char fn[] = "pdc_file_concat"; + char *pathname = pdc_file_fullname_mem(pdc, dirname, basename); + size_t len = strlen(pathname) + 1; + + if (extension != NULL) + len += strlen(extension); + + pathname = (char *) pdc_realloc(pdc, pathname, len, fn); + + if (extension != NULL) + strcat(pathname, extension); + + return pathname; +} + +/* + * Returns the file basename of a full specified path name in the same memory. + */ +const char * +pdc_file_strip_dirs(const char *pathname) +{ + const char *scan = pathname + strlen(pathname); + char charsep = PDC_PATHSEP[0]; + + while (pathname <= --scan) + { + if (*scan == charsep) + return scan + 1; + } + + return pathname; +} + + +/* + * Returns the file path of a full specified path name in the same memory. + */ +char * +pdc_file_strip_name(char *pathname) +{ + char *scan = pathname + strlen(pathname); + char charsep = PDC_PATHSEP[0]; + + while (pathname <= --scan) + { + if (*scan == charsep) + { + *scan = 0; + break; + } + } + + return pathname; +} + + +/* + * Returns the file extension of a path name in the same memory. + */ +char * +pdc_file_strip_ext(char *pathname) +{ + char *scan = pathname + strlen(pathname); + + while (pathname <= --scan) + { + if (*scan == '.') + { + *scan = 0; + break; + } + } + + return pathname; +} + + +/* + * Function reads a text file and creates a string list + * of all no-empty and no-comment lines. The strings are stripped + * by leading and trailing white space characters. + * + * The caller is responsible for freeing the resultated string list + * by calling the function pdc_cleanup_stringlist. + * + * Not for unicode strings. + * + * Return value: Number of strings + */ + +#define PDC_ARGV_CHUNKSIZE 256 + +int +pdc_read_textfile(pdc_core *pdc, pdc_file *sfp, int flags, char ***linelist) +{ + static const char fn[] = "pdc_read_textfile"; + char buf[PDC_BUFSIZE]; + char *content = NULL; + char **strlist = NULL; + int nlines = 0; + pdc_off_t filelen; + size_t len = 0, sumlen = 0, maxl = 0; + pdc_bool tocont = pdc_false; + int i, nbs, is = -1; + + /* get file length */ + filelen = pdc_file_size(sfp); + if (filelen) + { + /* allocate content array */ + content = (char *) pdc_calloc(pdc, (size_t) filelen, fn); + + /* read loop */ + while (pdc_fgetline(buf, PDC_BUFSIZE, sfp) != NULL) + { + /* trim white spaces */ + if (tocont) + pdc_strtrim(buf); + else + pdc_str2trim(buf); + + /* skip blank and comment lines */ + if (buf[0] == 0 || buf[0] == '%') + { + tocont = pdc_false; + continue; + } + + /* register new line */ + if (!tocont) + { + if (nlines) + pdc_logg_cond(pdc, 2, trc_filesearch, + "\t\tLine %d; \"%s\"\n", nlines, strlist[nlines - 1]); + + if (nlines >= (int) maxl) + { + maxl += PDC_ARGV_CHUNKSIZE; + strlist = (strlist == NULL) ? + (char **)pdc_malloc(pdc, maxl * sizeof(char *), fn): + (char **)pdc_realloc(pdc, strlist, maxl * + sizeof(char *), fn); + } + + is += sumlen + 1; + strlist[nlines] = &content[is]; + nlines++; + sumlen = 0; + } + + /* process new line */ + nbs = 0; + len = strlen(buf); + for (i = 0; i < (int) len; i++) + { + /* backslash found */ + if (buf[i] == '\\') + { + nbs++; + } + else + { + /* comment sign found */ + if (buf[i] == '%') + { + if (nbs % 2) + { + /* masked */ + memmove(&buf[i-1], &buf[i], (size_t) (len-i)); + len--; + buf[len] = 0; + } + else + { + buf[i] = 0; + len = strlen(buf); + } + } + nbs = 0; + } + } + + /* continuation line */ + tocont = (nbs % 2) ? pdc_true : pdc_false; + if (tocont) + { + if (flags & PDC_FILE_KEEPLF) + buf[len - 1] = '\n'; + else + len--; + } + buf[len] = '\0'; + + /* backslash substitution */ + if (flags & PDC_FILE_BSSUBST) + { + len = (size_t) pdc_subst_backslash(pdc, (pdc_byte *) buf, + (int) len, NULL, pdc_bytes, pdc_true); + } + + /* concatenate line */ + strcat(&content[is], buf); + + sumlen += len; + } + + if (!strlist) pdc_free(pdc, content); + } + + if (nlines) + pdc_logg_cond(pdc, 2, trc_filesearch, + "\t\tLine %d; \"%s\"\n", nlines, strlist[nlines - 1]); + + *linelist = strlist; + return nlines; +} + + +/* generate a temporary file name from the current time, pid, 'dirname', +** and the data in 'inbuf' using MD5. prepend 'dirname' to the file name. +** the result is written to 'outbuf'. if 'outbuf' is NULL, memory will be +** allocated and must be freed by the caller. otherwise, 'pdc' can be set +** to NULL. +** +** if 'dirname' isn't specified the function looks for an environment +** variable via the define PDC_TMPDIR_ENV. This define is set in +** pc_config.h. If the environment variable has a value and if the +** directory exists (check with the temporary file together) the +** directory will be used. +*/ + +#ifdef MVS +#define TMP_NAME_LEN 9 +#define TMP_SUFFIX "" +#define TMP_SUFF_LEN 0 +#else +#define TMP_NAME_LEN 14 +#define TMP_SUFFIX ".TMP" +#define TMP_SUFF_LEN 4 +#endif + +char * +pdc_temppath( + pdc_core *pdc, + char *outbuf, + const char *inbuf, + size_t inlen, + const char *dirname) +{ + char name[TMP_NAME_LEN + TMP_SUFF_LEN + 1]; + MD5_CTX md5; + time_t timer; + unsigned char digest[MD5_DIGEST_LENGTH]; + int i; + size_t dirlen; +#ifdef VMS + char *tmpdir = NULL; +#endif /* VMS */ + +#if defined(WIN32) +#if defined(__BORLANDC__) + int pid = getpid(); +#else + int pid = _getpid(); +#endif +#else +#if !defined(MAC) + pid_t pid = getpid(); +#endif +#endif + +#ifdef PDC_TMPDIR_ENV + if (!dirname) + { + dirname = (char *) getenv(PDC_TMPDIR_ENV); + } +#endif /* !PDC_TMPDIR_ENV */ + + time(&timer); + + MD5_Init(&md5); +#if !defined(MAC) + MD5_Update(&md5, (unsigned char *) &pid, sizeof pid); +#endif + MD5_Update(&md5, (unsigned char *) &timer, sizeof timer); + + if (inlen == 0 && inbuf != (const char *) 0) + inlen = strlen(inbuf); + + if (inlen != 0) + MD5_Update(&md5, (unsigned char *) inbuf, inlen); + + dirlen = dirname ? strlen(dirname) : 0; + if (dirlen) + MD5_Update(&md5, (const unsigned char *) dirname, dirlen); + + MD5_Final(digest, &md5); + + for (i = 0; i < TMP_NAME_LEN - 1; ++i) + name[i] = (char) (PDF_A + digest[i % MD5_DIGEST_LENGTH] % 26); + + name[i] = 0; + strcat(name, TMP_SUFFIX); + + if (!outbuf) + outbuf = pdc_file_fullname_mem(pdc, dirname, name); + else + pdc_file_fullname(dirname, name, outbuf); + return outbuf; +} + +/* Write function depending on pdc->asciifile. + */ +size_t +pdc_fwrite_ascii(pdc_core *pdc, const char *str, size_t len, FILE *fp) +{ + + (void) pdc; + len = fwrite(str, 1, len, fp); + + + return len; +} + +/* Creates a file depending on PDC_FILE_ASCII and pdc->asciifile. +*/ +size_t +pdc_write_file( + pdc_core *pdc, + const char *filename, + const char *qualifier, + const char *content, + size_t len, + int flags) +{ + size_t wlen = 0; + pdc_file *sfp; + + + sfp = pdc_fopen(pdc, filename, qualifier, NULL, 0, flags); + if (sfp != NULL) + { + wlen = pdc_fwrite_ascii(pdc, content, len, sfp->fp); + pdc_fclose(sfp); + if (wlen != len) + { + pdc_set_errmsg(pdc, PDC_E_IO_WRITE, filename, 0, 0, 0); + } + } + + + return wlen; +} + + + +#if defined(MAC) || defined(MACOSX) + +#ifdef PDF_TARGET_API_MAC_CARBON + +/* Construct an FSSpec from a Posix path name. Only required for + * Carbon (host font support and file type/creator). + */ + +OSStatus +FSPathMakeFSSpec(const UInt8 *path, FSSpec *spec) +{ + OSStatus result; + FSRef ref; + + /* convert the POSIX path to an FSRef */ + result = FSPathMakeRef(path, &ref, NULL); + + if (result != noErr) + return result; + + /* and then convert the FSRef to an FSSpec */ + result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL); + + return result; +} + + +#else + + +#endif /* !PDF_TARGET_API_MAC_CARBON */ + +#endif /* (defined(MAC) || defined(MACOSX)) */ + diff --git a/src/pdflib/pdcore/pc_file.h b/src/pdflib/pdcore/pc_file.h new file mode 100644 index 0000000..d1a6163 --- /dev/null +++ b/src/pdflib/pdcore/pc_file.h @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_file.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Definitions for file routines + * + */ + +#ifndef PC_FILE_H +#define PC_FILE_H + +#if (defined(MAC) || defined(MACOSX)) + +#include + +#ifdef PDF_TARGET_API_MAC_CARBON + +OSStatus FSMakePath(SInt16 volRefNum, SInt32 dirID, ConstStr255Param name, + UInt8 *path, UInt32 maxPathSize); + +OSStatus FSPathMakeFSSpec(const UInt8 *path, FSSpec *spec); + +#else + +#include + +OSErr FSpGetFullPath(const FSSpec *spec, short *fullPathLength, + Handle *fullPath); + +OSErr FSpLocationFromFullPath(short fullPathLength, + const void *fullPath, FSSpec *spec); + +#endif /* !PDF_TARGET_API_MAC_CARBON */ +#endif /* (defined(MAC) || defined(MACOSX)) */ + +#define PDC_FILENAMELEN 1024 /* maximum file name length */ + +#define PDC_FILE_TEXT (1L<<0) /* text file - whether ASCII file or not + * depends on pdc->asciifile */ + +#define PDC_FILE_ASCII (1L<<1) /* treat text or binary file as ASCII file + * even on EBCDIC platforms */ + +#define PDC_FILE_BINARY (1L<<2) /* open as binary file, + * otherwise as text file */ + +#define PDC_FILE_WRITEMODE (1L<<10) /* open file in writing mode, + * otherwise in reading mode */ + +#define PDC_FILE_APPENDMODE (1L<<11) /* open file in appending mode */ + + +/* flags for pdc_read_textfile() */ + +#define PDC_FILE_BSSUBST (1<<0) /* backslash substitution */ +#define PDC_FILE_KEEPLF (1<<1) /* keep linefeed at line continuation */ + +#define PDC_BUFSIZE 1024 + +#define PDC_OK_FREAD(file, buffer, len) \ + (pdc_fread(buffer, 1, len, file) == len) + +typedef struct pdc_file_s pdc_file; + +/* pc_file.c */ + +int pdc__fseek(FILE *fp, pdc_off_t offset, int whence); +pdc_off_t pdc__ftell(FILE *fp); +size_t pdc__fread(void *ptr, size_t size, size_t nmemb, FILE *fp); +size_t pdc__fwrite(const void *ptr, size_t size, size_t nmemb, + FILE *fp); +int pdc__fgetc(FILE *fp); +int pdc__feof(FILE *fp); + +FILE *pdc_get_fileptr(pdc_file *sfp); +pdc_core *pdc_get_pdcptr(pdc_file *sfp); +int pdc_get_fopen_errnum(pdc_core *pdc, int errnum); +void pdc_set_fopen_errmsg(pdc_core *pdc, int errnum, const char *qualifier, + const char *filename); +pdc_bool pdc_check_fopen_errmsg(pdc_core *pdc, pdc_bool requested); + +void *pdc_read_file(pdc_core *pdc, FILE *fp, pdc_off_t *o_filelen, + int incore); +int pdc_read_textfile(pdc_core *pdc, pdc_file *sfp, int flags, + char ***linelist); +char * pdc_temppath(pdc_core *pdc, char *outbuf, const char *inbuf, + size_t inlen, const char *dirname); + +char *pdc_check_filename(pdc_core *pdc, char *filename); +char *pdc_get_filename(pdc_core *pdc, char *filename); +const char *pdc_convert_filename_ext(pdc_core *pdc, const char *filename, + int len, const char *paramname, pdc_encoding enc, int codepage, + int flags); +const char *pdc_convert_filename(pdc_core *pdc, const char *filename, int len, + const char *paramname, pdc_bool withbom); +FILE *pdc_fopen_logg(pdc_core *pdc, const char *filename, const char *mode); + +pdc_file * pdc_fopen(pdc_core *pdc, const char *filename, + const char *qualifier, const pdc_byte *data, + size_t size, int flags); +pdc_core * pdc_file_getpdc(pdc_file *sfp); +char * pdc_file_name(pdc_file *sfp); +pdc_off_t pdc_file_size(pdc_file *sfp); +pdc_bool pdc_file_isvirtual(pdc_file *sfp); +char * pdc_fgetline(char *s, int size, pdc_file *sfp); +pdc_off_t pdc_ftell(pdc_file *sfp); +int pdc_fseek(pdc_file *sfp, pdc_off_t offset, int whence); +size_t pdc_fread(void *ptr, size_t size, size_t nmemb, pdc_file *sfp); +const void * pdc_freadall(pdc_file *sfp, size_t *filelen, + pdc_bool *ismem); +size_t pdc_fwrite(const void *ptr, size_t size, size_t nmemb, + pdc_file *sfp); +void pdc_freset(pdc_file *sfp, size_t size); + +int pdc_ungetc(int c, pdc_file *sfp); +int pdc_fgetc(pdc_file *sfp); +int pdc_feof(pdc_file *sfp); +void pdc_fclose(pdc_file *sfp); +void pdc_fclose_logg(pdc_core *pdc, FILE *fp); +void pdc_file_fullname(const char *dirname, const char *basename, + char *fullname); +char *pdc_file_fullname_mem(pdc_core *pdc, const char *dirname, + const char *basename); +char *pdc_file_concat(pdc_core *pdc, const char *dirname, const char *basename, + const char *extension); +const char *pdc_file_strip_dirs(const char *pathname); +char *pdc_file_strip_name(char *pathname); +char *pdc_file_strip_ext(char *pathname); + +size_t pdc_fwrite_ascii(pdc_core *pdc, const char *str, size_t len, FILE *fp); +size_t pdc_write_file(pdc_core *pdc, const char *filename, + const char *qualifier, const char *content, size_t len, int flags); + + +/* pc_resource.c */ + +pdc_file *pdc_fsearch_fopen(pdc_core *pdc, const char *filename, char *fullname, + const char *qualifier, int flags); + +#endif /* PC_FILE_H */ diff --git a/src/pdflib/pdcore/pc_generr.h b/src/pdflib/pdcore/pc_generr.h new file mode 100644 index 0000000..b1651ff --- /dev/null +++ b/src/pdflib/pdcore/pc_generr.h @@ -0,0 +1,444 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_generr.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDCORE error messages + * + */ + +#if pdc_genNames +#define gen(n, num, nam, msg) PDC_E_##nam = num, +#elif pdc_genInfo +#define gen(n, num, nam, msg) { n, num, msg, (const char *) 0 }, + +#else +#error invalid inclusion of generator file +#endif + +/* -------------------------------------------------------------------- */ +/* Configuration, memory, and I/O (10xx) */ +/* -------------------------------------------------------------------- */ + +gen(1, 1000, MEM_OUT, "Out of memory in function $1") + +gen(1, 1008, IO_ILLFILENAME, "Bad file name '$1'") + +gen(4, 1009, IO_RDOPEN_CODETEXT, + "Couldn't open $1file '$2' for reading (system error code $3: $4)") + +gen(2, 1010, IO_RDOPEN, "Couldn't open $1file '$2' for reading") + +gen(3, 1011, IO_RDOPEN_CODE, + "Couldn't open $1file '$2' for reading (system error code $3)") + +gen(2, 1012, IO_WROPEN, "Couldn't open $1file '$2' for writing") + +gen(3, 1013, IO_WROPEN_CODE, + "Couldn't open $1file '$2' for writing (system error code $3)") + +gen(0, 1014, IO_NOWRITE, "Couldn't write output") + +gen(4, 1015, IO_WROPEN_CODETEXT, + "Couldn't open $1file '$2' for writing (system error code $3: $4)") + +gen(2, 1016, IO_RDOPEN_NF, + "Couldn't open $1file '$2' for reading (file not found)") + +gen(2, 1017, IO_RDOPEN_BC, + "Couldn't open $1file '$2' for reading (device (e.g. URL) not supported)") + +gen(2, 1018, IO_WROPEN_NF, + "Couldn't open $1file '$2' for writing (no such directory)") + +gen(2, 1019, IO_WROPEN_BC, + "Couldn't open $1file '$2' for writing (device (e.g. URL) not supported)") + +gen(2, 1020, IO_RDOPEN_PD, + "Couldn't open $1file '$2' for reading (permission denied)") + +gen(2, 1022, IO_WROPEN_PD, + "Couldn't open $1file '$2' for writing (permission denied)") + +gen(2, 1024, IO_RDOPEN_TM, + "Couldn't open $1file '$2' for reading (too many open files)") + +gen(2, 1026, IO_WROPEN_TM, + "Couldn't open $1file '$2' for writing (too many open files)") + +gen(2, 1028, IO_RDOPEN_ID, + "Couldn't open $1file '$2' for reading (is a directory)") + +gen(2, 1030, IO_WROPEN_ID, + "Couldn't open $1file '$2' for writing (is a directory)") + +gen(2, 1032, IO_WROPEN_AE, + "Couldn't open $1file '$2' for writing (file already exists)") + +gen(2, 1034, IO_WROPEN_TL, + "Couldn't open $1file '$2' for writing (file name too long)") + +gen(2, 1036, IO_WROPEN_NS, + "Couldn't open $1file '$2' for writing (no space left on device)") + +gen(2, 1037, IO_RDOPEN_IS, + "Couldn't open $1file '$2' for reading (file name syntax incorrect)") + +gen(2, 1038, IO_WROPEN_IS, + "Couldn't open $1file '$2' for writing (file name syntax incorrect)") + +gen(2, 1040, IO_WROPEN_NC, + "Couldn't open $1file '$2' for writing (file cannot be created)") + +gen(2, 1042, IO_WROPEN_NP, + "Couldn't open $1file '$2' for writing (path not found)") + +gen(2, 1044, IO_RDOPEN_SV, + "Couldn't open $1file '$2' for reading (used by another process)") + +gen(2, 1046, IO_WROPEN_SV, + "Couldn't open $1file '$2' for writing (used by another process)") + +gen(0, 1048, IO_UNSUPP_UNINAME, + "Unicode file names are not supported on this platform") + +gen(1, 1050, IO_COMPRESS, "Compression error ($1)") + +gen(0, 1052, IO_NOBUFFER, "Don't fetch buffer contents when writing to file") + +gen(2, 1054, IO_BADFORMAT, "'$1' does not appear to be a $2 file") + +gen(1, 1056, IO_READ, "Error reading data from file '$1'") + +gen(1, 1057, IO_WRITE, "Error writing data to file '$1'") + +gen(3, 1058, IO_ILLSYNTAX, "$1file '$2': Syntax error in line $3") + +gen(1, 1060, PVF_NAMEEXISTS, + "Couldn't create virtual file '$1' (name already exists)") + +gen(2, 1062, IO_FILE_EMPTY, "$1file '$2' is empty") + +gen(2, 1064, IO_RDOPEN_QU, + "Couldn't open $1file '$2' for reading (quota exceeded)") + +gen(2, 1066, IO_WROPEN_QU, + "Couldn't open $1file '$2' for writing (quota exceeded)") + + + + +/* -------------------------------------------------------------------- */ +/* Invalid arguments (11xx) */ +/* -------------------------------------------------------------------- */ + +gen(1, 1100, ILLARG_EMPTY, "Parameter '$1' is empty") + +gen(2, 1101, ILLARG_FLOAT_ZERO, + "Floating point parameter '$1' has bad value $2 (too close to 0)") + +/* Unused. See 1107 +gen(1, 1102, ILLARG_POSITIVE, "Parameter '$1' must be positive") +*/ + +gen(2, 1104, ILLARG_BOOL, "Boolean parameter '$1' has bad value '$2'") + +gen(2, 1106, ILLARG_INT, "Integer parameter '$1' has bad value $2") + +gen(3, 1107, ILLARG_FLOAT_TOOSMALL, + "Floating point parameter '$1' has bad value $2 (minimum $3)") + +gen(2, 1108, ILLARG_FLOAT, "Floating-point parameter '$1' has bad value $2") + +gen(3, 1109, ILLARG_FLOAT_TOOLARGE, + "Floating point parameter '$1' has bad value $2 (maximum $3)") + +gen(2, 1110, ILLARG_STRING, "String parameter '$1' has bad value '$2'") + +gen(1, 1111, ILLARG_FLOAT_NAN, + "Floating point parameter '$1' has bad value (not a number)") + +/* Unused. See 1504 +gen(1, 1112, ILLARG_UTF, "Illegal UTF-$1 sequence in string") +*/ + +gen(2, 1114, ILLARG_MATRIX, "Matrix [$1] is degenerate") + +gen(2, 1116, ILLARG_TOOLONG, + "String parameter '$1' is limited to $2 characters") + +gen(2, 1118, ILLARG_HANDLE, + "Handle parameter or option of type '$1' has bad value $2") + +/* Unused. See 1107 +gen(1, 1120, ILLARG_NONNEG, "Parameter '$1' must not be negative") +*/ + +gen(1, 1122, ILLARG_LANG_CODE, "Unsupported language code '$1'") + + +/* -------------------------------------------------------------------- */ +/* Parameters and values (12xx) */ +/* -------------------------------------------------------------------- */ + +gen(0, 1200, PAR_EMPTYKEY, "Empty key") + +gen(1, 1202, PAR_UNKNOWNKEY, "Unknown key '$1'") + +gen(0, 1204, PAR_EMPTYVALUE, "Empty parameter value") + +gen(2, 1206, PAR_ILLPARAM, "Bad parameter '$1' for key '$2'") + +gen(2, 1208, PAR_ILLVALUE, "Bad value $1 for key '$2'") + +gen(2, 1210, PAR_SCOPE_GET, "Can't get parameter '$1' in scope '$2'") + +gen(2, 1212, PAR_SCOPE_SET, "Can't set parameter '$1' in scope '$2'") + +gen(2, 1214, PAR_VERSION, "Parameter '$1' requires PDF $2 or above") + +gen(1, 1216, PAR_ILLKEY, "Illegal attempt to set parameter '$1'") + +gen(1, 1217, RES_BADCAT, "Bad resource category '$1'") + +gen(2, 1218, RES_BADRES, "Bad resource specification '$1' for category '$2'") + +gen(3, 1219, RES_BADRES2, + "Bad resource specification '$1 = $2' for category '$3'") + +gen(1, 1220, PAR_UNSUPPKEY, "Unknown or unsupported key '$1'") + +gen(1, 1250, PAR_ILLSECT, "Illegal section '$1'") + + + + +/* -------------------------------------------------------------------- */ +/* Options and values (14xx) */ +/* -------------------------------------------------------------------- */ + +gen(1, 1400, OPT_UNKNOWNKEY, "Unknown option '$1'") + +gen(2, 1402, OPT_TOOFEWVALUES, "Option '$1' has too few values (< $2)") + +gen(2, 1404, OPT_TOOMANYVALUES, "Option '$1' has too many values (> $2)") + +gen(1, 1406, OPT_NOVALUES, "Option '$1' doesn't have a value") + +gen(2, 1408, OPT_ILLBOOLEAN, "Option '$1' has bad boolean value '$2'") + +gen(2, 1410, OPT_ILLINTEGER, "Option '$1' has bad integer value '$2'") + +gen(2, 1412, OPT_ILLNUMBER, "Option '$1' has bad number value '$2'") + +gen(2, 1414, OPT_ILLKEYWORD, "Option '$1' has bad keyword '$2'") + +gen(2, 1415, OPT_ILLCHAR, + "Option '$1' has bad Unicode value or character name '$2'") + +gen(3, 1416, OPT_TOOSMALLVAL, + "Value $2 for option '$1' is too small (minimum $3)") + +gen(2, 1417, OPT_TOOSMALLPERCVAL, + "Value $2% for option '$1' is too small (minimum 0%)") + +gen(3, 1418, OPT_TOOBIGVAL, + "Value $2 for option '$1' is too large (maximum $3)") + +gen(2, 1419, OPT_TOOBIGPERCVAL, + "Value $2% for option '$1' is too large (maximum 100%)") + +gen(2, 1420, OPT_ZEROVAL, "Option '$1' has bad value $2") + +gen(3, 1422, OPT_TOOSHORTSTR, + "String value '$2' for option '$1' is too short (minimum $3)") + +gen(3, 1424, OPT_TOOLONGSTR, + "String value '$2' for option '$1' is too long (maximum $3)") + +gen(2, 1426, OPT_ILLSPACES, + "Option '$1' has bad string value '$2' (contains whitespace)") + +gen(1, 1428, OPT_NOTFOUND, "Required option '$1' is missing") + +gen(1, 1430, OPT_IGNORED, "Option '$1' ignored") + +gen(2, 1432, OPT_VERSION, "Option '$1' is not supported in PDF $2") + +gen(3, 1434, OPT_ILLHANDLE, "Option '$1' has bad $3 handle $2") + +gen(2, 1436, OPT_IGNORE, + "Option '$1' will be ignored (specified option '$2' is dominant)") + +gen(1, 1438, OPT_UNSUPP, "Option '$1' not supported in PDFlib Lite") + +gen(1, 1439, OPT_UNSUPP_CONFIG, + "Option '$1' not supported in this configuration") + +gen(1, 1440, OPT_NOTBAL, "Braces aren't balanced in option list '$1'") + +gen(1, 1442, OPT_ODDNUM, "Option '$1' has odd number of values") + +gen(1, 1444, OPT_EVENNUM, "Option '$1' has even number of values") + +gen(1, 1446, OPT_ILLCOMB, "Option '$1' contains a bad combination of keywords") + +gen(1, 1448, OPT_ILL7BITASCII, "Option '$1' contains bad 7-bit ASCII string") + +gen(2, 1450, OPT_COMBINE, "Option '$1' must not be combined with option '$2'") + +gen(2, 1452, OPT_ILLBOX, "Option '$1' has bad box '$2'") + +gen(2, 1454, OPT_ILLEXP, "Option '$1' has bad expression '$2'") + +gen(1, 1456, OPT_TOOMANYPERCVALS, + "Option '$1' contains too many percentage values (> 32)") + +gen(2, 1458, OPT_ILLPOLYLINE, + "Option '$1' has bad polyline '$2' (too few vertices <= 2)") + + +/* -------------------------------------------------------------------- */ +/* String conversion and encoding functions (15xx) */ +/* -------------------------------------------------------------------- */ + +gen(0, 1500, CONV_ILLUTF16, "Invalid UTF-16 string (odd byte count)") + +gen(2, 1501, CONV_ILLUTF16SUR, "Invalid UTF-16 surrogate pair ") + +gen(0, 1502, CONV_MEMOVERFLOW, "Out of memory in UTF string conversion") + +gen(1, 1504, CONV_ILLUTF, "Invalid UTF-$1 string") + +gen(1, 1505, CONV_ILLUTF32, "Invalid UTF-32 character U+$1") + +gen(1, 1506, CONV_ILL_MBTEXTSTRING, + "Invalid text string according to the current codepage '$1'") + +gen(1, 1508, CONV_UNSUPP_MBTEXTFORM, + "Multi byte text format (codepage $1) not supported on this platform") + +gen(0, 1510, CONV_LIST_MEMOVERFLOW, + "Buffer overflow while converting code to destination code list") + +gen(1, 1520, CONV_CHARREF_TOOLONG, + "Illegal character reference '$1' (too long)") + +gen(1, 1521, CONV_HTML_ILLCODE, + "Illegal HTML character entity '$1' (illegal character code)") + +gen(1, 1522, CONV_HTML_ILLNAME, + "Illegal HTML character entity '$1' (illegal character name)") + +gen(1, 1523, CONV_CHARREF_MISSDELIMIT, + "Illegal character reference '$1' (delimiter ';' missing)") + +gen(1, 1524, CONV_CHARREF_UNKNOWN, + "Illegal character reference '$1' (unknown glyph name)") + +gen(1, 1525, CONV_CHARREF_NOTUNIQUE, + "Illegal character reference '$1' (more than one Unicode value)") + +gen(2, 1550, ENC_TOOLONG, "Encoding name '$1' too long (max. $2)") + +gen(2, 1551, ENC_BADLINE, "Syntax error in encoding file '$1' (line '$2')") + +gen(1, 1552, ENC_NOTFOUND, "Couldn't find encoding '$1'") + +gen(2, 1554, ENC_NOTDEF_UNICODE, "Unicode U+$1 not defined in encoding '$2'") + +gen(2, 1556, ENC_NOTDEF_CODE, "Code $1 has no Unicode value in encoding '$2'") + +gen(1, 1558, ENC_UNSUPP_LANG, + "Codeset '$1' in LANG environment variable not supported") + +gen(2, 1570, GLL_BADLINE, "Syntax error in glyph list file '$1' (line '$2')") + +gen(2, 1572, CDL_BADLINE, "Syntax error in code list file '$1' (line '$2')") + +gen(1, 1574, STR_ILL_ESCSEQ, "Illegal escape sequence '$1'") + +gen(1, 1576, STR_ILL_UNIESCSEQ, + "Illegal UTF-16 escape sequence (character U+$1 > U+00FF)") + + + + + + +/* -------------------------------------------------------------------- */ +/* Internal (19xx) */ +/* -------------------------------------------------------------------- */ + +/* Unused. +gen(1, 1900, INT_NULLARG, "Invalid NULL argument in function $1") +*/ + +gen(0, 1902, INT_XSTACK, "Exception stack underflow") + +gen(1, 1904, INT_UNUSEDOBJ, "Object $1 allocated but not used") + +gen(1, 1906, INT_FLOATTOOLARGE, "Floating point number $1 too large for PDF") + +gen(0, 1907, INT_ILLFLOAT, "Bad floating point number for PDF") + +gen(2, 1908, INT_BADFORMAT, "Unknown vsprintf() format '$1' ($2)") + +gen(1, 1910, INT_ALLOC0, + "Tried to allocate 0 or negative number of bytes in function $1") + +/* Unused. See 1502 +gen(1, 1912, INT_UNICODEMEM, "Too few bytes allocated in Unicode function $1") + */ + +gen(1, 1914, INT_INVMATRIX, "Matrix [$1] not invertible") + +gen(1, 1916, INT_REALLOC_TMP, "Illegal call to realloc_tmp() in function $1") + +gen(0, 1918, INT_FREE_TMP, "Illegal call to free_tmp()") + +gen(2, 1920, INT_ILLSWITCH, "Unexpected switch value $1 in function $2") + +gen(2, 1922, INT_ARRIDX, "Illegal array index $1 in function $2") + +gen(1, 1924, INT_ILLARG, "Invalid argument(s) in function $1") + +gen(2, 1926, INT_ASSERT, + "Internal error: assertion failed in file '$1', line $2") + +gen(1, 1928, INT_STACK_UNDER, "Stack underflow in function $1") + +gen(0, 1930, INT_TOOMUCH_SARE, "Too many save/restore operations") + +gen(1, 1932, INT_TOOMUCH_INDOBJS, "Too many indirect objects (> $1)") + +gen(1, 1934, INT_TOOLONG_TEXTSTR, "Text string too long (> $1)") + +gen(1, 1940, INT_BADERRNO, + "System IO error (file pointer = NULL, errno = 0); " + "contact support@pdflib.com") + +gen(1, 1950, INT_LONGNAME_MISSING, "Long name is missing at index $1") + + + + +#undef gen +#undef pdc_genNames +#undef pdc_genInfo + + + + + + + diff --git a/src/pdflib/pdcore/pc_geom.c b/src/pdflib/pdcore/pc_geom.c new file mode 100644 index 0000000..c52cdf4 --- /dev/null +++ b/src/pdflib/pdcore/pc_geom.c @@ -0,0 +1,681 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_geom.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Various geometry routines + * + */ + +#include "pc_util.h" +#include "pc_geom.h" + + +/* ---------------------- matrix functions ----------------------------- */ + +pdc_bool +pdc_is_identity_matrix(pdc_matrix *m) +{ + return PDC_FLOAT_ISNULL(m->a - 1) && + PDC_FLOAT_ISNULL(m->b) && + PDC_FLOAT_ISNULL(m->c) && + PDC_FLOAT_ISNULL(m->d - 1) && + PDC_FLOAT_ISNULL(m->e) && + PDC_FLOAT_ISNULL(m->f); +} + +/* identity matrix */ +void +pdc_identity_matrix(pdc_matrix *M) +{ + M->a = 1; + M->b = 0; + M->c = 0; + M->d = 1; + M->e = 0; + M->f = 0; +} + +/* translation matrix */ +void +pdc_translation_matrix(pdc_scalar tx, pdc_scalar ty, pdc_matrix *M) +{ + M->a = 1; + M->b = 0; + M->c = 0; + M->d = 1; + M->e = tx; + M->f = ty; +} + +/* scale matrix */ +void +pdc_scale_matrix(pdc_scalar sx, pdc_scalar sy, pdc_matrix *M) +{ + M->a = sx; + M->b = 0; + M->c = 0; + M->d = sy; + M->e = 0; + M->f = 0; +} + +/* rotation matrix */ +void +pdc_rotation_matrix(pdc_scalar alpha, pdc_matrix *M) +{ + pdc_scalar phi, c, s; + + phi = alpha * PDC_DEG2RAD; + c = cos(phi); + s = sin(phi); + + M->a = c; + M->b = s; + M->c = -s; + M->d = c; + M->e = 0; + M->f = 0; +} + +/* skew matrix */ +void +pdc_skew_matrix(pdc_scalar alpha, pdc_scalar beta, pdc_matrix *M) +{ + M->a = 1; + M->b = tan(alpha * PDC_DEG2RAD); + M->c = tan(beta * PDC_DEG2RAD); + M->d = 1; + M->e = 0; + M->f = 0; +} + +/* N = M * N */ +void +pdc_multiply_matrix(const pdc_matrix *M, pdc_matrix *N) +{ + pdc_matrix result; + + result.a = M->a * N->a + M->b * N->c; + result.b = M->a * N->b + M->b * N->d; + result.c = M->c * N->a + M->d * N->c; + result.d = M->c * N->b + M->d * N->d; + + result.e = M->e * N->a + M->f * N->c + N->e; + result.f = M->e * N->b + M->f * N->d + N->f; + + *N = result; +} + +/* L = M * N */ +void +pdc_multiply_matrix3(pdc_matrix *L, const pdc_matrix *M, const pdc_matrix *N) +{ + L->a = M->a * N->a + M->b * N->c; + L->b = M->a * N->b + M->b * N->d; + L->c = M->c * N->a + M->d * N->c; + L->d = M->c * N->b + M->d * N->d; + L->e = M->e * N->a + M->f * N->c + N->e; + L->f = M->e * N->b + M->f * N->d + N->f; +} + +/* M = [a b c d e f] * M; */ +void +pdc_multiply_6s_matrix(pdc_matrix *M, pdc_scalar a, pdc_scalar b, pdc_scalar c, + pdc_scalar d, pdc_scalar e, pdc_scalar f) +{ + pdc_matrix result; + + result.a = a * M->a + b * M->c; + result.b = a * M->b + b * M->d; + result.c = c * M->a + d * M->c; + result.d = c * M->b + d * M->d; + + result.e = e * M->a + f * M->c + M->e; + result.f = e * M->b + f * M->d + M->f; + + *M = result; +} + + +/* invert M and store the result in N */ +void +pdc_invert_matrix(pdc_core *pdc, pdc_matrix *N, pdc_matrix *M) +{ + pdc_scalar det = M->a * M->d - M->b * M->c; + + if (fabs(det) < PDC_SMALLREAL * PDC_SMALLREAL) + pdc_error(pdc, PDC_E_INT_INVMATRIX, + pdc_errprintf(pdc, "%f %f %f %f %f %f", + M->a, M->b, M->c, M->d, M->e, M->f), + 0, 0, 0); + + N->a = M->d/det; + N->b = -M->b/det; + N->c = -M->c/det; + N->d = M->a/det; + N->e = -(M->e * N->a + M->f * N->c); + N->f = -(M->e * N->b + M->f * N->d); +} + +/* debug print */ +void +pdc_print_matrix(const char *name, const pdc_matrix *M) +{ + printf("%s: a=%g, b=%g, c=%g, d=%g, e=%g, f=%g\n", + name, M->a, M->b, M->c, M->d, M->e, M->f); +} + +/* transform scalar */ +pdc_scalar +pdc_transform_scalar(const pdc_matrix *M, pdc_scalar s) +{ + pdc_scalar det = M->a * M->d - M->b * M->c; + + return sqrt(fabs(det)) * s; +} + +/* transform point */ +void +pdc_transform_point(const pdc_matrix *M, pdc_scalar x, pdc_scalar y, + pdc_scalar *tx, pdc_scalar *ty) +{ + *tx = M->a * x + M->c * y + M->e; + *ty = M->b * x + M->d * y + M->f; +} + +/* transform vector */ +void +pdc_transform_vector(const pdc_matrix *M, pdc_vector *v, pdc_vector *tv) +{ + pdc_scalar tx = M->a * v->x + M->c * v->y + M->e; + pdc_scalar ty = M->b * v->x + M->d * v->y + M->f; + if (tv) + { + tv->x = tx; + tv->y = ty; + } + else + { + v->x = tx; + v->y = ty; + } +} + +/* transform relative vector */ +void +pdc_transform_rvector(const pdc_matrix *M, pdc_vector *v, pdc_vector *tv) +{ + pdc_scalar tx = M->a * v->x + M->c * v->y; + pdc_scalar ty = M->b * v->x + M->d * v->y; + if (tv) + { + tv->x = tx; + tv->y = ty; + } + else + { + v->x = tx; + v->y = ty; + } +} + +/* get length of vector */ +pdc_scalar +pdc_get_vector_length(pdc_vector *start, pdc_vector *end) +{ + pdc_scalar dx = end->x - start->x; + pdc_scalar dy = end->y - start->y; + + return sqrt(dx * dx + dy * dy); +} + + +/* ---------------------- utility functions ----------------------------- */ + +void +pdc_place_element(pdc_fitmethod method, pdc_scalar minfscale, + const pdc_box *fitbox, const pdc_vector *fitrelpos, + const pdc_vector *elemsize, const pdc_vector *elemrelpos, + pdc_box *elembox, pdc_vector *scale) +{ + pdc_vector refpos; + pdc_scalar width, height, det, fscale = 1.0; + pdc_bool xscaling = pdc_false; + + /* reference position in fitbox */ + width = fitbox->ur.x - fitbox->ll.x; + height = fitbox->ur.y - fitbox->ll.y; + refpos.x = fitbox->ll.x + fitrelpos->x * width; + refpos.y = fitbox->ll.y + fitrelpos->y * height; + + /* first check */ + switch (method) + { + case pdc_entire: + case pdc_slice: + case pdc_meet: + case pdc_tauto: + if (fabs(width) > PDC_FLOAT_PREC && fabs(height) > PDC_FLOAT_PREC) + { + if (method != pdc_entire) + { + det = elemsize->x * height - elemsize->y * width; + xscaling = (method == pdc_slice && det <= 0) || + ((method == pdc_meet || method == pdc_tauto) && + det > 0) ? pdc_true : pdc_false; + if (xscaling) + fscale = width / elemsize->x; + else + fscale = height / elemsize->y; + } + + if (method == pdc_tauto) + { + if(fscale >= 1.0) + { + method = pdc_nofit; + } + else if (fscale < minfscale) + { + method = pdc_meet; + } + } + } + else + { + method = pdc_nofit; + } + break; + + default: + break; + } + + /* calculation */ + switch (method) + { + /* entire box is covered by entire element */ + case pdc_entire: + *elembox = *fitbox; + scale->x = width / elemsize->x; + scale->y = height / elemsize->y; + return; + + /* fit into and preserve aspect ratio */ + case pdc_slice: + case pdc_meet: + if (xscaling) + height = fscale * elemsize->y; + else + width = fscale * elemsize->x; + scale->x = fscale; + scale->y = fscale; + break; + + /* fit into and doesn't preserve aspect ratio */ + case pdc_tauto: + if (xscaling) + { + height = elemsize->y; + scale->x = fscale; + scale->y = 1.0; + } + else + { + width = elemsize->x; + scale->x = 1.0; + scale->y = fscale; + } + break; + + /* only positioning */ + case pdc_nofit: + case pdc_clip: + width = elemsize->x; + height = elemsize->y; + scale->x = 1.0; + scale->y = 1.0; + break; + } + + /* placed element box */ + elembox->ll.x = refpos.x - elemrelpos->x * width; + elembox->ll.y = refpos.y - elemrelpos->y * height; + elembox->ur.x = refpos.x + (1.0 - elemrelpos->x) * width; + elembox->ur.y = refpos.y + (1.0 - elemrelpos->y) * height; +} + + +void +pdc_box2polyline(const pdc_matrix *M, const pdc_box *box, pdc_vector *polyline) +{ + pdc_scalar x[4], y[4]; + + /* counterclockwise order */ + if (M != NULL) + { + pdc_transform_point(M, box->ll.x, box->ll.y, &x[0], &y[0]); + pdc_transform_point(M, box->ur.x, box->ll.y, &x[1], &y[1]); + pdc_transform_point(M, box->ur.x, box->ur.y, &x[2], &y[2]); + pdc_transform_point(M, box->ll.x, box->ur.y, &x[3], &y[3]); + + polyline[0].x = x[0]; + polyline[0].y = y[0]; + polyline[1].x = x[1]; + polyline[1].y = y[1]; + polyline[2].x = x[2]; + polyline[2].y = y[2]; + polyline[3].x = x[3]; + polyline[3].y = y[3]; + polyline[4] = polyline[0]; + } + else + { + polyline[0].x = box->ll.x; + polyline[0].y = box->ll.y; + polyline[1].x = box->ur.x; + polyline[1].y = box->ll.y; + polyline[2].x = box->ur.x; + polyline[2].y = box->ur.y; + polyline[3].x = box->ll.x; + polyline[3].y = box->ur.y; + polyline[4] = polyline[0]; + } +} + +void * +pdc_delete_polylinelist(pdc_core *pdc, pdc_polyline *polylinelist, int nplines) +{ + int i; + + if (polylinelist != NULL) + { + for (i = 0; i < nplines; i++) + pdc_free(pdc, polylinelist[i].p); + pdc_free(pdc, polylinelist); + } + + return NULL; +} + +void +pdc_init_box(pdc_box *box) +{ + box->ll.x = PDC_FLOAT_MAX; + box->ll.y = PDC_FLOAT_MAX; + box->ur.x = PDC_FLOAT_MIN; + box->ur.y = PDC_FLOAT_MIN; +} + +void +pdc_adapt_box(pdc_box *box, const pdc_vector *v) +{ + if (v->x < box->ll.x) + box->ll.x = v->x; + if (v->y < box->ll.y) + box->ll.y = v->y; + + if (v->x > box->ur.x) + box->ur.x = v->x; + if (v->y > box->ur.y) + box->ur.y = v->y; +} + +void +pdc_normalize_box(pdc_box *box, pdc_scalar ydir) +{ + pdc_scalar sxy; + + if (box->ll.x > box->ur.x) + { + sxy = box->ll.x; + box->ll.x = box->ur.x; + box->ur.x = sxy; + } + + if (ydir * box->ll.y > ydir * box->ur.y) + { + sxy = box->ll.y; + box->ll.y = box->ur.y; + box->ur.y = sxy; + } +} + +void +pdc_transform_box(const pdc_matrix *M, pdc_box *box, pdc_box *tbox) +{ + pdc_vector polyline[5]; + pdc_box tmpbox; + int i; + + pdc_box2polyline(NULL, box, polyline); + + pdc_init_box(&tmpbox); + + for (i = 0; i < 4; i++) + { + pdc_transform_vector(M, &polyline[i], NULL); + pdc_adapt_box(&tmpbox, &polyline[i]); + } + + if (tbox) + *tbox = tmpbox; + else + *box = tmpbox; +} + +/* --------------------------- rectangles --------------------------- */ +pdc_bool +pdc_rect_isnull(const pdc_rectangle *r) +{ + if (!r) + return pdc_true; + + return + (r->llx == 0 && r->lly == 0 && + r->urx == 0 && r->ury == 0); +} + +pdc_bool +pdc_rect_contains(const pdc_rectangle *r1, const pdc_rectangle *r2) +{ + return + (r1->llx <= r2->llx && r1->lly <= r2->lly && + r1->urx >= r2->urx && r1->ury >= r2->ury); +} + +void +pdc_rect_copy(pdc_rectangle *r1, const pdc_rectangle *r2) +{ + r1->llx = r2->llx; + r1->lly = r2->lly; + r1->urx = r2->urx; + r1->ury = r2->ury; +} + +void +pdc_rect_init(pdc_rectangle *r, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury) +{ + r->llx = llx; + r->lly = lly; + r->urx = urx; + r->ury = ury; +} + +pdc_bool +pdc_rect_intersect( + pdc_rectangle *result, + const pdc_rectangle *r1, + const pdc_rectangle *r2) +{ + if (r1->urx <= r2->llx || + r2->urx <= r1->llx || + r1->ury <= r2->lly || + r2->ury <= r1->lly) + { + if (result) + { + result->llx = result->lly = result->urx = result->ury = 0; + } + + return pdc_false; + } + + if (result) + { + result->llx = MAX(r1->llx, r2->llx); + result->urx = MIN(r1->urx, r2->urx); + result->lly = MAX(r1->lly, r2->lly); + result->ury = MIN(r1->ury, r2->ury); + } + + return pdc_true; +} + +void +pdc_rect_transform(const pdc_matrix *M, const pdc_rectangle *r1, + pdc_rectangle *r2) +{ + pdc_scalar x[4], y[4]; + int i; + + pdc_transform_point(M, r1->llx, r1->lly, &x[0], &y[0]); + pdc_transform_point(M, r1->urx, r1->lly, &x[1], &y[1]); + pdc_transform_point(M, r1->urx, r1->ury, &x[2], &y[2]); + pdc_transform_point(M, r1->llx, r1->ury, &x[3], &y[3]); + + pdc_rect_init(r2, PDC_FLOAT_MAX, PDC_FLOAT_MAX, + PDC_FLOAT_MIN, PDC_FLOAT_MIN); + + for (i = 0; i < 4; i++) + { + if (x[i] < r2->llx) + r2->llx = x[i]; + if (y[i] < r2->lly) + r2->lly = y[i]; + + if (x[i] > r2->urx) + r2->urx = x[i]; + if (y[i] > r2->ury) + r2->ury = y[i]; + } +} + +void pdc_rect_normalize(pdc_rectangle *r) +{ + double aux; + + if (r->urx < r->llx) + { + aux = r->llx; r->llx = r->urx; r->urx = aux; + } + + if (r->ury < r->lly) + { + aux = r->lly; r->lly = r->ury; r->ury = aux; + } +} + +void pdc_rect_normalize2(pdc_rectangle *dst, const pdc_rectangle *src) +{ + if (src->llx < src->urx) + { + dst->llx = src->llx; + dst->urx = src->urx; + } + else + { + dst->llx = src->urx; + dst->urx = src->llx; + } + + if (src->lly < src->ury) + { + dst->lly = src->lly; + dst->ury = src->ury; + } + else + { + dst->lly = src->ury; + dst->ury = src->lly; + } +} + +void +pdc_polyline2rect(const pdc_vector *polyline, int np, pdc_rectangle *r) +{ + int i; + + pdc_rect_init(r, PDC_FLOAT_MAX, PDC_FLOAT_MAX, + PDC_FLOAT_MIN, PDC_FLOAT_MIN); + + for (i = 0; i < np; i++) + { + if (polyline[i].x < r->llx) + r->llx = polyline[i].x; + if (polyline[i].y < r->lly) + r->lly = polyline[i].y; + + if (polyline[i].x > r->urx) + r->urx = polyline[i].x; + if (polyline[i].y > r->ury) + r->ury = polyline[i].y; + } +} + +void +pdc_rect2polyline(const pdc_matrix *M, const pdc_rectangle *r, + pdc_vector *polyline) +{ + pdc_scalar x[4], y[4]; + + /* counterclockwise order */ + if (M != NULL) + { + pdc_transform_point(M, r->llx, r->lly, &x[0], &y[0]); + pdc_transform_point(M, r->urx, r->lly, &x[1], &y[1]); + pdc_transform_point(M, r->urx, r->ury, &x[2], &y[2]); + pdc_transform_point(M, r->llx, r->ury, &x[3], &y[3]); + + polyline[0].x = x[0]; + polyline[0].y = y[0]; + polyline[1].x = x[1]; + polyline[1].y = y[1]; + polyline[2].x = x[2]; + polyline[2].y = y[2]; + polyline[3].x = x[3]; + polyline[3].y = y[3]; + polyline[4] = polyline[0]; + } + else + { + polyline[0].x = r->llx; + polyline[0].y = r->lly; + polyline[1].x = r->urx; + polyline[1].y = r->lly; + polyline[2].x = r->urx; + polyline[2].y = r->ury; + polyline[3].x = r->llx; + polyline[3].y = r->ury; + polyline[4] = polyline[0]; + } +} + +/* debug print */ +void +pdc_print_rectangle(const char *name, const pdc_rectangle *r) +{ + printf("%s: llx=%g, lly=%g, urx=%g, ury=%g\n", + name, r->llx, r->lly, r->urx, r->ury); +} diff --git a/src/pdflib/pdcore/pc_geom.h b/src/pdflib/pdcore/pc_geom.h new file mode 100644 index 0000000..629157d --- /dev/null +++ b/src/pdflib/pdcore/pc_geom.h @@ -0,0 +1,116 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_geom.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib core geometry utilities + * + */ + +#ifndef PC_GEOM_H +#define PC_GEOM_H + +/* Unfortunately M_PI causes porting woes, so we use a private name */ +#define PDC_M_PI 3.14159265358979323846 /* pi */ +#define PDC_DEG2RAD 0.0174532925199433 +#define PDC_RAD2DEG 57.2957795130823070 + +/* Conversion factors */ +#define PDC_INCH2METER 0.0254 +#define PDC_METER2INCH 39.3701 + +/* same as PDF_SMALLREAL */ +#define PDC_SMALLREAL (0.000015) + +typedef double pdc_scalar; +typedef struct { pdc_scalar x, y; } pdc_vector; +typedef struct { pdc_vector ll, ur; } pdc_box; +typedef struct { pdc_scalar llx, lly, urx, ury; } pdc_rectangle; +typedef struct { int np; pdc_vector *p; } pdc_polyline; +typedef struct { pdc_scalar a, b, c, d, e, f; } pdc_matrix; + +/* methods for fitting rectangle elements into a box */ +typedef enum +{ + pdc_nofit = 0, /* no fit, only positioning */ + pdc_clip, /* no fit, only positioning with following condition: + * - the parts of element beyond the bounds of box + * are clipped */ + pdc_slice, /* fit into the box with following conditions: + * - aspect ratio of element is preserved + * - entire box is covered by the element + * - the parts of element beyond the bounds of box + * are clipped */ + pdc_meet, /* fit into the box with following conditions: + * - aspect ratio of element is preserved + * - entire element is visible in the box */ + pdc_entire, /* fit into the box with following conditions: + * - entire box is covered by the element + * - entire element is visible in the box */ + pdc_tauto /* automatic fitting. If element extends fit box in + * length, then element is shrinked, if shrink + * factor is greater than a specified value. Otherwise + * pdc_meet is applied. */ +} +pdc_fitmethod; + +pdc_bool pdc_is_identity_matrix(pdc_matrix *m); +void pdc_identity_matrix(pdc_matrix *M); +void pdc_translation_matrix(pdc_scalar tx, pdc_scalar ty, pdc_matrix *M); +void pdc_scale_matrix(pdc_scalar sx, pdc_scalar sy, pdc_matrix *M); +void pdc_rotation_matrix(pdc_scalar angle, pdc_matrix *M); +void pdc_skew_matrix(pdc_scalar alpha, pdc_scalar beta, pdc_matrix *M); +void pdc_multiply_matrix(const pdc_matrix *M, pdc_matrix *N); +void pdc_multiply_matrix3(pdc_matrix *L, const pdc_matrix *M, + const pdc_matrix *N); +void pdc_multiply_6s_matrix(pdc_matrix *M, pdc_scalar a, pdc_scalar b, + pdc_scalar c, pdc_scalar d, pdc_scalar e, pdc_scalar f); +void pdc_invert_matrix(pdc_core *pdc, pdc_matrix *N, pdc_matrix *M); +void pdc_print_matrix(const char *name, const pdc_matrix *M); +pdc_scalar pdc_transform_scalar(const pdc_matrix *M, pdc_scalar s); +void pdc_transform_point(const pdc_matrix *M, + pdc_scalar x, pdc_scalar y, pdc_scalar *tx, pdc_scalar *ty); +void pdc_transform_vector(const pdc_matrix *M, pdc_vector *v, pdc_vector *tv); +void pdc_transform_rvector(const pdc_matrix *M, pdc_vector *v, pdc_vector *tv); +pdc_scalar pdc_get_vector_length(pdc_vector *start, pdc_vector *end); + +void pdc_place_element(pdc_fitmethod method, pdc_scalar minfscale, + const pdc_box *fitbox, const pdc_vector *fitrelpos, + const pdc_vector *elemsize, const pdc_vector *elemrelpos, + pdc_box *elembox, pdc_vector *scale); +void pdc_box2polyline(const pdc_matrix *M, const pdc_box *box, + pdc_vector *polyline); +void *pdc_delete_polylinelist(pdc_core *pdc, pdc_polyline *polylinelist, + int nplines); +void pdc_init_box(pdc_box *box); +void pdc_adapt_box(pdc_box *box, const pdc_vector *v); +void pdc_normalize_box(pdc_box *box, pdc_scalar ydir); +void pdc_transform_box(const pdc_matrix *M, pdc_box *box, pdc_box *tbox); + +pdc_bool pdc_rect_isnull(const pdc_rectangle *r); +pdc_bool pdc_rect_contains(const pdc_rectangle *r1, const pdc_rectangle *r2); +void pdc_rect_copy(pdc_rectangle *r1, const pdc_rectangle *r2); +void pdc_rect_init(pdc_rectangle *r, + pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury); +pdc_bool pdc_rect_intersect(pdc_rectangle *result, + const pdc_rectangle *r1, const pdc_rectangle *r2); +void pdc_rect_transform(const pdc_matrix *M, + const pdc_rectangle *r1, pdc_rectangle *r2); +void pdc_rect_normalize(pdc_rectangle *r); +void pdc_rect_normalize2(pdc_rectangle *dst, const pdc_rectangle *src); +void pdc_rect2polyline(const pdc_matrix *M, const pdc_rectangle *r, + pdc_vector *polyline); +void pdc_polyline2rect(const pdc_vector *polyline, int np, pdc_rectangle *r); +void pdc_print_rectangle(const char *name, const pdc_rectangle *r); + +#endif /* PC_GEOM_H */ + diff --git a/src/pdflib/pdcore/pc_md5.c b/src/pdflib/pdcore/pc_md5.c new file mode 100644 index 0000000..a9d209a --- /dev/null +++ b/src/pdflib/pdcore/pc_md5.c @@ -0,0 +1,307 @@ +/* $Id: pc_md5.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib MD5 message digest routines + * + */ + +/* This is a slightly modified version of the RSA reference + * implementation for MD5, which originally contained + * the following copyright notice: + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. +*/ + +#include + +#include "pc_util.h" +#include "pc_md5.h" + +/* Constants for MD5_Transform routine. + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static unsigned char PADDING[64] = { + 0x80, 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 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + * Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + + +/* Encodes input (MD5_UINT4) into output (unsigned char). Assumes len is + * a multiple of 4. + */ +static void Encode(unsigned char *output, MD5_UINT4 *input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char) (input[i] & 0xff); + output[j+1] = (unsigned char) ((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char) ((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char) ((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (MD5_UINT4). Assumes len is + * a multiple of 4. + */ +static void Decode( + MD5_UINT4 *output, + const unsigned char *input, + unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((MD5_UINT4) input[j]) | + (((MD5_UINT4) input[j+1]) << 8) | + (((MD5_UINT4) input[j+2]) << 16) | + (((MD5_UINT4) input[j+3]) << 24); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5_Transform(MD5_UINT4 state[4], const unsigned char block[64]) +{ + MD5_UINT4 a = state[0]; + MD5_UINT4 b = state[1]; + MD5_UINT4 c = state[2]; + MD5_UINT4 d = state[3]; + MD5_UINT4 x[16]; + + Decode(x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + */ + memset (x, 0, sizeof (x)); +} + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void MD5_Init(MD5_CTX *context) +{ + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. + */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + * operation, processing another message block, and updating the + * context. + */ +void MD5_Update( + MD5_CTX *context, + const unsigned char *input, + unsigned int inputLen) +{ + unsigned int i, idx, partLen; + + /* Compute number of bytes mod 64 */ + idx = (unsigned int) ((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((MD5_UINT4) inputLen << 3)) + < ((MD5_UINT4) inputLen << 3)) + context->count[1]++; + + context->count[1] += ((MD5_UINT4) inputLen >> 29); + + partLen = 64 - idx; + + /* Transform as many times as possible. + */ + if (inputLen >= partLen) { + memcpy(&context->buffer[idx], input, partLen); + MD5_Transform(context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5_Transform (context->state, &input[i]); + + idx = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy(&context->buffer[idx], &input[i], inputLen - i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + * the message digest and zeroizing the context. + */ +void MD5_Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *context) +{ + unsigned char bits[8]; + unsigned int idx, padLen; + + /* Save number of bits */ + Encode(bits, context->count, 8); + + /* Pad out to 56 mod 64. + */ + idx = (unsigned int) ((context->count[0] >> 3) & 0x3f); + padLen = (idx < 56) ? (56 - idx) : (120 - idx); + MD5_Update(context, PADDING, padLen); + + /* Append length (before padding) */ + MD5_Update(context, bits, 8); + + /* Store state in digest */ + Encode(digest, context->state, 16); + + /* Zeroize sensitive information. + */ + memset(context, 0, sizeof (*context)); +} diff --git a/src/pdflib/pdcore/pc_md5.h b/src/pdflib/pdcore/pc_md5.h new file mode 100644 index 0000000..619b47d --- /dev/null +++ b/src/pdflib/pdcore/pc_md5.h @@ -0,0 +1,59 @@ +/* $Id: pc_md5.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Header file for the PDFlib MD5 message digest routines + * + */ + +/* This is a slightly modified version of the RSA reference + * implementation for MD5, which originally contained + * the following copyright notice: + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + + +/* we prefix our MD5 function and structure names with "pdc_", so you can + * link your program with another MD5 lib without troubles. + */ +#define MD5_Init pdc_MD5_Init +#define MD5_Update pdc_MD5_Update +#define MD5_Final pdc_MD5_Final + +#define MD5_CTX pdc_MD5_CTX + +typedef unsigned int MD5_UINT4; + +#define MD5_DIGEST_LENGTH 16 + + +/* MD5 context. */ +typedef struct { + MD5_UINT4 state[4]; /* state (ABCD) */ + MD5_UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +void MD5_Init(MD5_CTX *context); +void MD5_Update( + MD5_CTX *context, const unsigned char *input, unsigned int inputLen); +void MD5_Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *context); diff --git a/src/pdflib/pdcore/pc_optparse.c b/src/pdflib/pdcore/pc_optparse.c new file mode 100644 index 0000000..dee18ad --- /dev/null +++ b/src/pdflib/pdcore/pc_optparse.c @@ -0,0 +1,1383 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_optparse.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Parser options routines + * + */ + +#include "pc_util.h" +#include "pc_geom.h" +#include "pc_ctype.h" + +/* result of an option */ +struct pdc_resopt_s +{ + int numdef; /* number of definitions */ + const pdc_defopt *defopt; /* pointer to option definition */ + int num; /* number of parsed values */ + void *val; /* list of parsed values */ + char *origval; /* original value as string */ + int flags; /* flags */ + int pcmask; /* percentage mask */ + int currind; /* index of current option */ + int lastind; /* index of last option */ + pdc_bool isutf8; /* optionlist UTF-8 encoded */ +}; + +/* sizes of option types. must be parallel to pdc_opttype */ +static const size_t pdc_typesizes[] = +{ + sizeof (pdc_bool), + sizeof (char *), + sizeof (int), + sizeof (int), + sizeof (float), + sizeof (double), + sizeof (pdc_scalar), + sizeof (int), + sizeof (pdc_polyline), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), + sizeof (int), +}; + +static const pdc_keyconn pdc_handletypes[] = +{ + {"3ddata", pdc_3ddatahandle}, + {"3dview", pdc_3dviewhandle}, + {"action", pdc_actionhandle}, + {"bookmark", pdc_bookmarkhandle}, + {"color", pdc_colorhandle}, + {"document", pdc_documenthandle}, + {"font", pdc_fonthandle}, + {"gstate", pdc_gstatehandle}, + {"iccprofile", pdc_iccprofilehandle}, + {"image", pdc_imagehandle}, + {"layer", pdc_layerhandle}, + {"page", pdc_pagehandle}, + {"pattern", pdc_patternhandle}, + {"shading", pdc_shadinghandle}, + {"table", pdc_tablehandle}, + {"template", pdc_templatehandle}, + {"textflow", pdc_textflowhandle}, + {"string", pdc_stringhandle}, + {NULL, 0} +}; + +int +pdc_get_keycode(const char *keyword, const pdc_keyconn *keyconn) +{ + int i; + for (i = 0; keyconn[i].word != 0; i++) + { + if (!strcmp(keyword, keyconn[i].word)) + return keyconn[i].code; + } + return PDC_KEY_NOTFOUND; +} + +int +pdc_get_keycode_ci(const char *keyword, const pdc_keyconn *keyconn) +{ + int i; + for (i = 0; keyconn[i].word != 0; i++) + { + if (!pdc_stricmp(keyword, keyconn[i].word)) + return keyconn[i].code; + } + return PDC_KEY_NOTFOUND; +} + +int +pdc_get_keycode_unique(const char *keyword, const pdc_keyconn *keyconn) +{ + int i, j; + size_t len = strlen(keyword); + + for (i = 0; keyconn[i].word != 0; i++) + { + if (!strncmp(keyword, keyconn[i].word, len)) + { + for (j = i + 1; keyconn[j].word != 0; j++) + if (!strncmp(keyword, keyconn[j].word, len)) + return PDC_KEY_NOTUNIQUE; + return keyconn[i].code; + } + } + return PDC_KEY_NOTFOUND; +} + +int +pdc_get_keymask_ci(pdc_core *pdc, const char *option, + const char *keywordlist, const pdc_keyconn *keyconn) +{ + char **keys = NULL; + int nkeys, i, j, k = 0; + + nkeys = pdc_split_stringlist(pdc, keywordlist, NULL, 0, &keys); + + for (j = 0; j < nkeys; j++) + { + for (i = 0; keyconn[i].word != NULL; i++) + if (!pdc_stricmp(keys[j], keyconn[i].word)) + break; + + if (keyconn[i].word == NULL) + { + const char *stemp = pdc_errprintf(pdc, "%.*s", + PDC_ERR_MAXSTRLEN, keys[j]); + pdc_cleanup_stringlist(pdc, keys); + pdc_set_errmsg(pdc, PDC_E_OPT_ILLKEYWORD, option, stemp, 0, 0); + return PDC_KEY_NOTFOUND; + } + + k |= keyconn[i].code; + } + + pdc_cleanup_stringlist(pdc, keys); + return k; +} + +/* + * flags: PDC_INT_HEXADEC, PDC_INT_CASESENS + */ +int +pdc_get_keycode_num(pdc_core *pdc, const char *option, const char *i_keyword, + int flags, const pdc_keyconn *keyconn, int *o_num) +{ + static const char *fn = "pdc_get_keycode_num"; + char *keyword; + int i, len, keycode; + + keyword = pdc_strdup_ext(pdc, i_keyword, 0, fn); + len = (int) strlen(keyword); + *o_num = -1; + + /* parse number */ + for (i = 0; i < len; i++) + { + if (pdc_isdigit(keyword[i])) + { + if (pdc_str2integer(&keyword[i], flags, o_num)) + { + keyword[i] = 0; + } + else + { + pdc_set_errmsg(pdc, PDC_E_OPT_ILLINTEGER, option, &keyword[i], + 0, 0); + } + break; + } + } + + if (flags & PDC_INT_CASESENS) + keycode = pdc_get_keycode(keyword, keyconn); + else + keycode = pdc_get_keycode_ci(keyword, keyconn); + + if (keycode == PDC_KEY_NOTFOUND) + pdc_set_errmsg(pdc, PDC_E_OPT_ILLKEYWORD, option, keyword, 0, 0); + + pdc_free(pdc, keyword); + + return keycode; +} + +const char * +pdc_get_keyword(int keycode, const pdc_keyconn *keyconn) +{ + int i; + for (i = 0; keyconn[i].word != 0; i++) + { + if (keycode == keyconn[i].code) + return keyconn[i].word; + } + return NULL; +} + +const char * +pdc_get_int_keyword(const char *keyword, const pdc_keyconn *keyconn) +{ + int i; + for (i = 0; keyconn[i].word != 0; i++) + { + if (!pdc_stricmp(keyword, keyconn[i].word)) + return keyconn[i].word; + } + return NULL; +} + +void +pdc_cleanup_optstringlist(pdc_core *pdc, char **stringlist, int ns) +{ + int j; + + for (j = 0; j < ns; j++) + { + if (stringlist[j] != NULL) + pdc_free(pdc, stringlist[j]); + } + pdc_free(pdc, stringlist); +} + +static void +pdc_delete_optvalue(pdc_core *pdc, pdc_resopt *resopt) +{ + if (resopt->val && !(resopt->flags & PDC_OPT_SAVEALL)) + { + int j; + int ja = (resopt->flags & PDC_OPT_SAVE1ELEM) ? 1 : 0; + + if (resopt->defopt->type == pdc_stringlist) + { + char **s = (char **) resopt->val; + for (j = ja; j < resopt->num; j++) + if (s[j] != NULL) + pdc_free(pdc, s[j]); + } + else if (resopt->defopt->type == pdc_polylinelist) + { + pdc_polyline *pl = (pdc_polyline *) resopt->val; + for (j = ja; j < resopt->num; j++) + if (pl[j].p != NULL) + pdc_free(pdc, pl[j].p); + } + pdc_free(pdc, resopt->val); + resopt->val = NULL; + } + if (resopt->origval && !(resopt->flags & PDC_OPT_SAVEORIG)) + { + pdc_free(pdc, resopt->origval); + resopt->origval = NULL; + } + resopt->num = 0; +} + +static int +pdc_optname_compare(const void *a, const void *b) +{ + return (strcmp(((pdc_resopt *)a)->defopt->name, + ((pdc_resopt *)b)->defopt->name)); +} + +/* destructor function for freeing temporary memory */ +static void +pdc_cleanup_optionlist_tmp(void *opaque, void *mem) +{ + if (mem) + { + pdc_core *pdc = (pdc_core *) opaque; + pdc_resopt *resopt = (pdc_resopt *) mem; + int i; + + for (i = 0; i < resopt[0].numdef; i++) + pdc_delete_optvalue(pdc, &resopt[i]); + } +} + +pdc_resopt * +pdc_parse_optionlist(pdc_core *pdc, const char *optlist, + const pdc_defopt *defopt, + const pdc_clientdata *clientdata, pdc_bool verbose) +{ + static const char *fn = "pdc_parse_optionlist"; + pdc_bool logg5 = pdc_logg_is_enabled(pdc, 5, trc_optlist); + const char *stemp1 = NULL, *stemp2 = NULL, *stemp3 = NULL; + char **items = NULL, *keyword = NULL; + char **values = NULL, *value = NULL, **strings = NULL; + int i, j, k, nd, is, iss, it, iv; + int numdef, nitems = 0, nvalues, ncoords = 0, errcode = 0; + void *resval; + double dz, maxval; + int retval, iz; + pdc_sint32 lz = 0; + pdc_uint32 ulz = 0; + size_t len; + const pdc_defopt *dopt = NULL; + pdc_resopt *resopt = NULL; + pdc_bool ignore = pdc_false; + pdc_bool boolval = pdc_false; + pdc_bool tocheck = pdc_false; + pdc_bool issorted = pdc_true; + pdc_bool ishandle = pdc_true; + pdc_bool isutf8 = pdc_false; + + pdc_logg_cond(pdc, 1, trc_optlist, "\n\tOption list: \"%T\"\n", + optlist ? optlist : "", 0); + + /* split option list */ + if (optlist != NULL) + { + nitems = pdc_split_stringlist(pdc, optlist, PDC_OPT_LISTSEPS, + PDC_SPLIT_ISOPTLIST, &items); + isutf8 = pdc_is_utf8_bytecode(optlist); + } + if (nitems < 0) + { + keyword = (char *) optlist; + errcode = PDC_E_OPT_NOTBAL; + goto PDC_OPT_SYNTAXERROR; + } + + /* initialize result list */ + for (numdef = 0; defopt[numdef].name != NULL; numdef++) + { + /* */ ; + } + + /* allocate temporary memory for option parser result struct */ + resopt = (pdc_resopt *) pdc_calloc_tmp(pdc, numdef * sizeof(pdc_resopt), + fn, pdc, pdc_cleanup_optionlist_tmp); + for (i = 0; i < numdef; i++) + { + resopt[i].numdef = numdef; + resopt[i].defopt = &defopt[i]; + + if (defopt[i].flags & PDC_OPT_IGNOREIF1 || + defopt[i].flags & PDC_OPT_IGNOREIF2 || + defopt[i].flags & PDC_OPT_REQUIRIF1 || + defopt[i].flags & PDC_OPT_REQUIRIF2 || + defopt[i].flags & PDC_OPT_REQUIRED) + tocheck = pdc_true; + + if (i && issorted) + issorted = (strcmp(defopt[i-1].name, defopt[i].name) <= 0) ? + pdc_true : pdc_false; + } + + /* loop over all option list elements */ + for (is = 0; is < nitems; is++) + { + /* search keyword */ + boolval = pdc_undef; + keyword = items[is]; + for (it = 0; it < numdef; it++) + { + /* special handling for booleans */ + if (defopt[it].type == pdc_booleanlist) + { + if (!pdc_stricmp(keyword, defopt[it].name) || + (keyword[1] != 0 && + !pdc_stricmp(&keyword[2], defopt[it].name))) + { + iss = is + 1; + if (iss == nitems || + (pdc_stricmp(items[iss], "true") && + pdc_stricmp(items[iss], "false"))) + { + i = pdc_strincmp(defopt[it].name, "no", 2) ? 0 : 2; + if (!pdc_strincmp(&keyword[i], "no", 2)) + { + boolval = pdc_false; + break; + } + else + { + boolval = pdc_true; + break; + } + } + } + } + + if (!pdc_stricmp(keyword, defopt[it].name)) break; + } + + if (logg5) + pdc_logg(pdc, "\t\t\toption \"%s\" specified: ", keyword); + + if (it == numdef) + { + errcode = PDC_E_OPT_UNKNOWNKEY; + goto PDC_OPT_SYNTAXERROR; + } + + /* initialize */ + dopt = &defopt[it]; + ignore = pdc_false; + nvalues = 1; + values = NULL; + ishandle = pdc_true; + + /* compatibility */ + if (clientdata && clientdata->compatibility) + { + int compatibility = clientdata->compatibility; + + for (iv = PDC_1_3; iv <= PDC_X_X_LAST; iv++) + { + if (logg5 && (dopt->flags & (1L<= %s) ", + pdc_get_pdfversion(pdc, iv)); + + if ((dopt->flags & (1L<flags & PDC_OPT_UNSUPP) + { + if (logg5) + pdc_logg(pdc, "(unsupported)\n"); + + keyword = (char *) dopt->name; + errcode = PDC_E_OPT_UNSUPP; + goto PDC_OPT_SYNTAXERROR; + } + + /* parse values */ + if (boolval == pdc_undef) + { + is++; + if (is == nitems) + { + errcode = PDC_E_OPT_NOVALUES; + goto PDC_OPT_SYNTAXERROR; + } + if (!ignore) + { + if (dopt->type == pdc_stringlist && + pdc_is_utf8_bytecode(items[is])) + resopt[it].flags |= PDC_OPT_ISUTF8; + + if (dopt->type != pdc_stringlist || dopt->maxnum > 1) + nvalues = pdc_split_stringlist(pdc, items[is], + (dopt->flags & PDC_OPT_SUBOPTLIST) ? + PDC_OPT_LISTSEPS : NULL, + PDC_SPLIT_ISOPTLIST, &values); + + if (dopt->flags & PDC_OPT_DUPORIGVAL) + resopt[it].origval = pdc_strdup(pdc, items[is]); + } + } + + /* ignore */ + if (ignore) continue; + + /* number of values check */ + if (nvalues < dopt->minnum) + { + stemp2 = pdc_errprintf(pdc, "%d", dopt->minnum); + errcode = PDC_E_OPT_TOOFEWVALUES; + goto PDC_OPT_SYNTAXERROR; + } + else if (nvalues > dopt->maxnum) + { + stemp2 = pdc_errprintf(pdc, "%d", dopt->maxnum); + errcode = PDC_E_OPT_TOOMANYVALUES; + goto PDC_OPT_SYNTAXERROR; + } + + /* number of values must be even */ + if (dopt->flags & PDC_OPT_EVENNUM && (nvalues % 2)) + { + errcode = PDC_E_OPT_ODDNUM; + goto PDC_OPT_SYNTAXERROR; + } + + /* number of values must be odd */ + if (dopt->flags & PDC_OPT_ODDNUM && !(nvalues % 2)) + { + errcode = PDC_E_OPT_EVENNUM; + goto PDC_OPT_SYNTAXERROR; + } + + /* option already exists */ + if (resopt[it].num) + { + pdc_delete_optvalue(pdc, &resopt[it]); + } + + /* no values */ + if (!nvalues ) continue; + + /* maximal value */ + switch (dopt->type) + { + case pdc_3ddatahandle: + maxval = clientdata->max3ddata; + break; + + case pdc_3dviewhandle: + maxval = clientdata->max3dview; + break; + + case pdc_actionhandle: + maxval = clientdata->maxaction; + break; + + case pdc_bookmarkhandle: + maxval = clientdata->maxbookmark; + break; + + case pdc_colorhandle: + maxval = clientdata->maxcolor; + break; + + case pdc_documenthandle: + maxval = clientdata->maxdocument; + break; + + case pdc_fonthandle: + maxval = clientdata->maxfont; + break; + + case pdc_gstatehandle: + maxval = clientdata->maxgstate; + break; + + case pdc_iccprofilehandle: + maxval = clientdata->maxiccprofile; + break; + + case pdc_imagehandle: + maxval = clientdata->maximage; + break; + + case pdc_layerhandle: + maxval = clientdata->maxlayer; + break; + + case pdc_pagehandle: + maxval = clientdata->maxpage; + break; + + case pdc_patternhandle: + maxval = clientdata->maxpattern; + break; + + case pdc_shadinghandle: + maxval = clientdata->maxshading; + break; + + case pdc_tablehandle: + maxval = clientdata->maxtable; + break; + + case pdc_templatehandle: + maxval = clientdata->maxtemplate; + break; + + case pdc_textflowhandle: + maxval = clientdata->maxtextflow; + break; + + case pdc_stringhandle: + maxval = clientdata->maxstring; + break; + + case pdc_polylinelist: + ncoords = 0; + + default: + maxval = dopt->maxval; + ishandle = pdc_false; + break; + } + + /* allocate value array */ + resopt[it].val = pdc_calloc(pdc, + (size_t) (nvalues * pdc_typesizes[dopt->type]), fn); + resopt[it].num = nvalues; + resopt[it].currind = it; + + if (logg5) + pdc_logg(pdc, "{"); + + /* analyze type */ + resval = resopt[it].val; + for (iv = 0; iv < nvalues; iv++) + { + errcode = 0; + if (dopt->maxnum > 1 && nvalues) + value = values[iv]; + else + value = items[is]; + if (logg5) + pdc_logg(pdc, "%s{%T}", iv ? " " : "", value, 0); + switch (dopt->type) + { + /* boolean list */ + case pdc_booleanlist: + if (boolval == pdc_true || !pdc_stricmp(value, "true")) + { + *(pdc_bool *) resval = pdc_true; + } + else if (boolval == pdc_false || !pdc_stricmp(value, "false")) + { + *(pdc_bool *) resval = pdc_false; + } + else + { + errcode = PDC_E_OPT_ILLBOOLEAN; + } + break; + + /* string list */ + case pdc_stringlist: + if (dopt->flags & PDC_OPT_NOSPACES) + { + if (pdc_split_stringlist(pdc, value, NULL, 0, &strings) > 1) + errcode = PDC_E_OPT_ILLSPACES; + pdc_cleanup_stringlist(pdc, strings); + } + if (!errcode) + { + len = strlen(value); + dz = (double) len; + if (dz < dopt->minval) + { + stemp3 = pdc_errprintf(pdc, "%d", (int) dopt->minval); + errcode = PDC_E_OPT_TOOSHORTSTR; + } + else if (dz > maxval) + { + stemp3 = pdc_errprintf(pdc, "%d", (int) maxval); + errcode = PDC_E_OPT_TOOLONGSTR; + } + + if (dopt->flags & PDC_OPT_CONVUTF8) + { + int flags = PDC_CONV_EBCDIC | PDC_CONV_WITHBOM; + + if (isutf8 || (resopt[it].flags & PDC_OPT_ISUTF8)) + flags |= PDC_CONV_ISUTF8; + + *((char **) resval) = + pdc_convert_name(pdc, value, 0, flags); + } + else + { + *((char **) resval) = pdc_strdup(pdc, value); + } + } + break; + + /* keyword list */ + case pdc_keywordlist: + if (dopt->flags & PDC_OPT_CASESENS) + iz = pdc_get_keycode(value, dopt->keylist); + else + iz = pdc_get_keycode_ci(value, dopt->keylist); + if (iz == PDC_KEY_NOTFOUND) + { + errcode = PDC_E_OPT_ILLKEYWORD; + } + else + { + *(int *) resval = iz; + } + break; + + /* character list */ + case pdc_unicharlist: + iz = pdc_string2unicode(pdc, value, dopt->flags, dopt->keylist, + pdc_false); + if (iz < 0) + { + errcode = PDC_E_OPT_ILLCHAR; + break; + } + dz = iz; + if (dz < dopt->minval) + { + stemp3 = pdc_errprintf(pdc, "%g", dopt->minval); + errcode = PDC_E_OPT_TOOSMALLVAL; + } + else if (dz > maxval) + { + stemp3 = pdc_errprintf(pdc, "%g", maxval); + errcode = PDC_E_OPT_TOOBIGVAL; + } + *(int *) resval = iz; + break; + + /* string list */ + case pdc_polylinelist: + { + int np = pdc_split_stringlist(pdc, value, NULL, 0, + &strings); + pdc_polyline *pl = (pdc_polyline *) resval; + + pl->np = np / 2; + pl->p = NULL; + + /* number of coordinates must be even */ + if (np % 2) + { + errcode = PDC_E_OPT_ODDNUM; + np = 0; + } + + /* polyline must be a box */ + else if ((dopt->flags & PDC_OPT_ISBOX) && np != 4) + { + errcode = PDC_E_OPT_ILLBOX; + np = 0; + } + + /* polyline will be closed */ + else if ((dopt->flags & PDC_OPT_CLOSEPOLY) && np <= 4) + { + errcode = PDC_E_OPT_ILLPOLYLINE; + np = 0; + } + + /* polyline not empty */ + if (np) + { + if (dopt->flags & PDC_OPT_CLOSEPOLY) + pl->np += 1; + pl->p = (pdc_vector *) pdc_malloc(pdc, + pl->np * sizeof(pdc_vector), fn); + + iz = PDC_KEY_NOTFOUND; + j = 0; + for (i = 0; i < np; i++) + { + char *sk = strings[i]; + + if (dopt->keylist) + { + /* optional keyword list */ + if (dopt->flags & PDC_OPT_CASESENS) + iz = pdc_get_keycode(sk, dopt->keylist); + else + iz = pdc_get_keycode_ci(sk, dopt->keylist); + } + if (iz == PDC_KEY_NOTFOUND) + { + /* percentage */ + if (dopt->flags & PDC_OPT_PERCENT) + { + k = (int) strlen(sk) - 1; + if (sk[k] == '%') + { + sk[k] = 0; + if (ncoords < 32) + { + resopt[it].pcmask |= (1L <flags & PDC_OPT_PERCRANGE) + { + if (dz < 0) + errcode = PDC_E_OPT_TOOSMALLPERCVAL; + if (dz > 100) + errcode = PDC_E_OPT_TOOBIGPERCVAL; + } + dz /= 100.0; + } + } + else + { + dz = (double) iz; + } + + if (!(i % 2)) + { + pl->p[j].x = dz; + } + else + { + pl->p[j].y = dz; + j++; + } + ncoords++; + } + + if (dopt->flags & PDC_OPT_CLOSEPOLY) + pl->p[pl->np - 1] = pl->p[0]; + } + pdc_cleanup_stringlist(pdc, strings); + } + break; + + /* number list */ + case pdc_3ddatahandle: + case pdc_3dviewhandle: + case pdc_actionhandle: + case pdc_bookmarkhandle: + case pdc_colorhandle: + case pdc_documenthandle: + case pdc_fonthandle: + case pdc_gstatehandle: + case pdc_iccprofilehandle: + case pdc_imagehandle: + case pdc_layerhandle: + case pdc_pagehandle: + case pdc_patternhandle: + case pdc_shadinghandle: + case pdc_tablehandle: + case pdc_templatehandle: + case pdc_textflowhandle: + case pdc_integerlist: + case pdc_floatlist: + case pdc_doublelist: + case pdc_scalarlist: + + if (dopt->keylist && + (!(dopt->flags & PDC_OPT_KEYLIST1) || !iv)) + { + /* optional keyword and/or allowed integer list */ + if (dopt->flags & PDC_OPT_CASESENS) + iz = pdc_get_keycode(value, dopt->keylist); + else + iz = pdc_get_keycode_ci(value, dopt->keylist); + if (iz == PDC_KEY_NOTFOUND) + { + if (dopt->flags & PDC_OPT_INTLIST) + { + errcode = PDC_E_OPT_ILLINTEGER; + break; + } + } + else + { + switch (dopt->type) + { + default: + case pdc_integerlist: + *(int *) resval = iz; + break; + + case pdc_floatlist: + *(float *) resval = (float) iz; + break; + + case pdc_doublelist: + *(double *) resval = (double) iz; + break; + + case pdc_scalarlist: + *(pdc_scalar *) resval = (pdc_scalar) iz; + break; + } + break; + } + } + + /* percentage */ + if (dopt->flags & PDC_OPT_PERCENT) + { + i = (int) strlen(value) - 1; + if (value[i] == '%') + { + value[i] = 0; + if (iv < 32) + { + resopt[it].pcmask |= (1L << iv); + } + else + { + errcode = PDC_E_OPT_TOOMANYPERCVALS; + } + } + else + { + resopt[it].pcmask &= ~(1L << iv); + } + } + + case pdc_stringhandle: + + if (dopt->type == pdc_floatlist || + dopt->type == pdc_doublelist || + dopt->type == pdc_scalarlist) + { + retval = pdc_str2double(value, &dz); + } + else + { + if (dopt->minval >= 0) + { + retval = pdc_str2integer(value, PDC_INT_UNSIGNED, &ulz); + dz = ulz; + } + else + { + retval = pdc_str2integer(value, 0, &lz); + dz = lz; + } + + if (retval && ishandle && pdc->hastobepos && + dopt->type != pdc_bookmarkhandle && + dopt->type != pdc_stringhandle) + { + dz -= 1; + lz = (pdc_sint32) dz; + ulz = (pdc_uint32) dz; + } + } + if (!retval) + { + errcode = PDC_E_OPT_ILLNUMBER; + } + else + { + if (resopt[it].pcmask & (1L << iv)) + { + if (dopt->flags & PDC_OPT_PERCRANGE) + { + if (dz < 0) + errcode = PDC_E_OPT_TOOSMALLPERCVAL; + if (dz > 100) + errcode = PDC_E_OPT_TOOBIGPERCVAL; + } + dz /= 100.0; + } + + if (errcode == 0) + { + if (dz < dopt->minval) + { + if (ishandle) + { + stemp3 = pdc_get_keyword(dopt->type, + pdc_handletypes); + errcode = PDC_E_OPT_ILLHANDLE; + } + else + { + stemp3 = pdc_errprintf(pdc, "%g", dopt->minval); + errcode = PDC_E_OPT_TOOSMALLVAL; + } + } + else if (dz > maxval) + { + if (ishandle) + { + stemp3 = pdc_get_keyword(dopt->type, + pdc_handletypes); + errcode = PDC_E_OPT_ILLHANDLE; + } + else + { + stemp3 = pdc_errprintf(pdc, "%g", maxval); + errcode = PDC_E_OPT_TOOBIGVAL; + } + } + else if (dopt->flags & PDC_OPT_NOZERO && + fabs(dz) < PDC_FLOAT_PREC) + { + errcode = PDC_E_OPT_ZEROVAL; + } + else if (dopt->type == pdc_scalarlist) + { + *(pdc_scalar *) resval = dz; + } + else if (dopt->type == pdc_doublelist) + { + *(double *) resval = dz; + } + else if (dopt->type == pdc_floatlist) + { + *(float *) resval = (float) dz; + } + else + { + if (dopt->minval >= 0) + *(pdc_uint32 *) resval = ulz; + else + *(pdc_sint32 *) resval = lz; + } + } + } + break; + } + + if (errcode) + { + stemp2 = pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, value); + goto PDC_OPT_SYNTAXERROR; + } + + /* increment value pointer */ + resval = (void *) ((char *)(resval) + pdc_typesizes[dopt->type]); + } + pdc_cleanup_stringlist(pdc, values); + values = NULL; + + if (logg5) + pdc_logg(pdc, "}\n"); + + /* build OR bit pattern */ + if (dopt->flags & PDC_OPT_BUILDOR && nvalues > 1) + { + int *bcode = (int *) resopt[it].val; + for (iv = 1; iv < nvalues; iv++) + { + bcode[0] |= bcode[iv]; + } + resopt[it].num = 1; + } + } + pdc_cleanup_stringlist(pdc, items); + items = NULL; + + /* required and to be ignored options */ + for (is = 0; tocheck && is < numdef; is++) + { + /* to be ignored option */ + if (resopt[is].num) + { + nd = 0; + if (defopt[is].flags & PDC_OPT_IGNOREIF1) nd = 1; + if (defopt[is].flags & PDC_OPT_IGNOREIF2) nd = 2; + for (it = is - 1; it >= is - nd && it >= 0; it--) + { + if (resopt[it].num) + { + pdc_delete_optvalue(pdc, &resopt[is]); + if (verbose) + pdc_warning(pdc, PDC_E_OPT_IGNORE, defopt[is].name, + defopt[it].name, 0, 0); + } + } + } + + /* required option */ + if (!resopt[is].num && + ((defopt[is].flags & PDC_OPT_REQUIRED) || + (defopt[is].flags & PDC_OPT_REQUIRIF1 && resopt[is-1].num) || + (defopt[is].flags & PDC_OPT_REQUIRIF2 && + (resopt[is-1].num || resopt[is-2].num)))) + { + keyword = (char *) defopt[is].name; + errcode = PDC_E_OPT_NOTFOUND; + goto PDC_OPT_SYNTAXERROR; + } + } + + /* is no sorted */ + if (!issorted) + { + qsort((void *)resopt, (size_t) numdef, sizeof(pdc_resopt), + pdc_optname_compare); + } + + /* global UTF-8 check after sort */ + if (isutf8) + resopt[0].isutf8 = pdc_true; + + /* index of last got option */ + resopt[0].lastind = -1; + + /* protocol */ + if (pdc_logg_is_enabled(pdc, 1, trc_optlist)) + { + for (is = 0; is < numdef; is++) + { + if (resopt[is].num) + pdc_logg(pdc, "\tOption \"%s\": %d value%s found\n", + resopt[is].defopt->name, resopt[is].num, + resopt[is].num == 1 ? "" : "s"); + else if (logg5) + pdc_logg(pdc, "\t\t\toption \"%s\" not specified\n", + resopt[is].defopt->name); + for (iv = 0; iv < resopt[is].num; iv++) + { + switch (resopt[is].defopt->type) + { + case pdc_booleanlist: + case pdc_keywordlist: + case pdc_integerlist: + case pdc_3ddatahandle: + case pdc_3dviewhandle: + case pdc_actionhandle: + case pdc_bookmarkhandle: + case pdc_colorhandle: + case pdc_documenthandle: + case pdc_fonthandle: + case pdc_gstatehandle: + case pdc_iccprofilehandle: + case pdc_imagehandle: + case pdc_layerhandle: + case pdc_pagehandle: + case pdc_patternhandle: + case pdc_shadinghandle: + case pdc_tablehandle: + case pdc_templatehandle: + case pdc_textflowhandle: + case pdc_stringhandle: + pdc_logg(pdc, "\tValue %d: %d\n", + iv + 1, *((int *) resopt[is].val + iv)); + break; + + case pdc_stringlist: + pdc_logg(pdc, "\tValue %d: \"%T\"\n", + iv + 1, *((char **) resopt[is].val + iv), 0); + break; + + case pdc_floatlist: + pdc_logg(pdc, "\tValue %d: %f\n", + iv + 1, *((float *) resopt[is].val + iv)); + break; + + case pdc_doublelist: + pdc_logg(pdc, "\tValue %d: %f\n", + iv + 1, *((double *) resopt[is].val + iv)); + break; + + case pdc_scalarlist: + pdc_logg(pdc, "\tValue %d: %f\n", + iv + 1, *((pdc_scalar *) resopt[is].val + iv)); + break; + + case pdc_unicharlist: + pdc_logg(pdc, "\tValue %d: %d\n", + iv + 1, *((int *) resopt[is].val + iv)); + break; + + case pdc_polylinelist: + pdc_logg(pdc, "\t\t#%d: ", iv + 1); + { + pdc_polyline *pl = (pdc_polyline *) resopt[is].val + iv; + + for (j = 0; j < pl->np; j++) + pdc_logg(pdc, "%f,%f ", pl->p[j].x, pl->p[j].y); + pdc_logg(pdc, "\n"); + } + break; + } + } + } + } + + return resopt; + + PDC_OPT_SYNTAXERROR: + stemp1 = pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, keyword); + pdc_cleanup_stringlist(pdc, items); + pdc_cleanup_stringlist(pdc, values); + + pdc_set_errmsg(pdc, errcode, stemp1, stemp2, stemp3, 0); + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + + return NULL; +} + +int +pdc_get_optvalues(const char *keyword, pdc_resopt *resopt, + void *lvalues, char ***mvalues) +{ + pdc_resopt *ropt = NULL; + void *values = NULL; + int nvalues = 0; + size_t nbytes; + if (mvalues) *mvalues = NULL; + + if (resopt) + { + int i, cmp; + int lo = 0; + int hi = resopt[0].numdef; + + while (lo < hi) + { + i = (lo + hi) / 2; + cmp = strcmp(keyword, resopt[i].defopt->name); + + /* keyword found */ + if (cmp == 0) + { + ropt = &resopt[i]; + nvalues = ropt->num; + values = ropt->val; + resopt[0].lastind = i; + break; + } + + if (cmp < 0) + hi = i; + else + lo = i + 1; + } + } + + if (nvalues) + { + /* copy values */ + if (lvalues) + { + if (ropt->defopt->type == pdc_stringlist && + ropt->defopt->maxnum == 1) + { + strcpy((char *)lvalues, *((char **) values)); + } + else + { + nbytes = (size_t) (nvalues * pdc_typesizes[ropt->defopt->type]); + memcpy(lvalues, values, nbytes); + } + } + + /* copy pointer */ + if (mvalues) + { + *mvalues = (char **) values; + } + } + + return nvalues; +} + +void * +pdc_save_lastopt(pdc_resopt *resopt, int flags) +{ + int i = resopt[0].lastind; + + if (i > -1 && resopt[i].num) + { + if (flags & PDC_OPT_SAVEALL) + { + resopt[i].flags |= PDC_OPT_SAVEALL; + return resopt[i].val; + } + else if (resopt[i].defopt->type == pdc_stringlist && + (flags & PDC_OPT_SAVE1ELEM)) + { + char **s = (char **) resopt[i].val; + resopt[i].flags |= PDC_OPT_SAVE1ELEM; + return (void *) s[0]; + } + else if (flags & PDC_OPT_SAVEORIG) + { + resopt[i].flags |= PDC_OPT_SAVEORIG; + return (void *) resopt[i].origval; + } + } + + return NULL; +} + +int +pdc_get_lastopt_index(pdc_resopt *resopt) +{ + int i = resopt[0].lastind; + + if (i > -1) + return resopt[i].currind; + else + return -1; +} + +pdc_bool +pdc_is_lastopt_percent(pdc_resopt *resopt, int ind) +{ + int i = resopt[0].lastind; + + if (i > -1 && resopt[i].num < 32) + return (resopt[i].pcmask & (1L << ind)) ? pdc_true : pdc_false; + else + return pdc_false; +} + +pdc_bool +pdc_is_lastopt_utf8(pdc_resopt *resopt) +{ + int i = resopt[0].lastind; + + if (i > -1) + return resopt[0].isutf8 || + ((resopt[i].flags & PDC_OPT_ISUTF8) ? pdc_true : pdc_false); + else + return pdc_false; +} + +int +pdc_get_opt_utf8strings(pdc_core *pdc, const char *keyword, pdc_resopt *resopt, + int flags, char ***strings) +{ + int ns = pdc_get_optvalues(keyword, resopt, NULL, strings); + + if (ns) + { + if (pdc_is_lastopt_utf8(resopt)) + { + int i = resopt[0].lastind; + pdc_resopt *ropt = &resopt[i]; + char **s = (char **) ropt->val; + int j; + + for (j = 0; j < ropt->num; j++) + { + char *sb = pdc_strdup_withbom(pdc, s[j]); + + if (s[j] != NULL) + pdc_free(pdc, s[j]); + s[j] = sb; + } + } + + pdc_save_lastopt(resopt, flags); + } + + return ns; +} + +void +pdc_cleanup_optionlist(pdc_core *pdc, pdc_resopt *resopt) +{ + if (resopt != NULL) + pdc_free_tmp(pdc, resopt); +} + +const char * +pdc_get_handletype(pdc_opttype type) +{ + return pdc_get_keyword(type, pdc_handletypes); +} + diff --git a/src/pdflib/pdcore/pc_optparse.h b/src/pdflib/pdcore/pc_optparse.h new file mode 100644 index 0000000..ac9e6f2 --- /dev/null +++ b/src/pdflib/pdcore/pc_optparse.h @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_optparse.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Definitions for option parser routines + * + */ + +#ifndef PC_OPTPARSE_H +#define PC_OPTPARSE_H + +/* + * Optlist + * ------- + * An optlist is a string containing pairs of the form + * "optionname optionvalue(s)". The separator characters + * are "\f\n\r\t\v =". + * + * There are options of different types (see pdc_opttype): + * + * Boolean (pdc_booleanlist) + * Strings (pdc_stringlist) + * Keywords (pdc_keywordlist) + * Integers (pdc_integerlist) + * Floats (pdc_floatlist) + * Doubles (pdc_doublelist) + * Scalars (pdc_scalarlist) + * Unichars (pdc_unicharlist) + * Polylinelist (pdc_polylinelist) + * Handles (pdc_colorhandle ...) + * + * An option can have one or more values. Boolean options can be + * provided without any value. If an option has more than one value, + * then these values have to be set in braces. Examples: + * + * dasharray {11 22 33} + * + * Strings with white spaces have to be set in braces too. + * Examples: + * + * fullname {Ludwig Wittgenstein} + * composers {{Gustav Mahler}} + * comment {} + * + * The allowed option names and the limitations of their values + * must be defined in an array of enumeration type pdc_defopt + * (see below). Such an option definition specifies (in brackets + * the member name in the pdc_defopt struct) + * + * - the name of the option (name) + * - the type of the option (type) + * - value restrictions by bit flags (flags) + * - the minimal and maximal permitted number of values + * (minnum, maxnum) + * - the minimal and maximal permitted value, or string + * length resp. (minval, maxval) + * - the permitted keywords in a keyword list (is required) or + * the permitted integer numbers in a integer list (is optional), + * resp. (keylist) + * + * Remarks: + * + * - minnum = maxnum = 1: The program expects a single value, + * otherwise an array. If an array consists of only one value + * the braces can be omitted - but not in the case of strings + * with white spaces (see example above). + * - Boolean options have the values "true" or "false". A shorter + * equivalent notation is "name" or "noname". for "name true" + * or "name false", resp. + * - White spaces in strings can be forbidden by the flag + * PDC_OPT_NOSPACES. + * - It's only possible to specify a single number interval (minval, + * maxval) which must contain the number. The flag PDC_OPT_NOZERO + * can forbid zero additionally. + * - Keywords will always be converted to integer numbers (keycodes) + * according to the specified pdc_keyconn array. + * - It is possible to specify keywords for integers, floats and + * doubles additionally by an optional keylist entry. For integers + * it is possible to specify the allowed integer values by an optional + * keylist and by the flag PDC_OPT_INTLIST. + * - If more than one keyword is permitted, then the flag + * PDC_OPT_BUILDOR decides, whether a bit pattern must be + * built by or-ing the single keycodes or not. + * + * Program run: + * + * An optlist is parsed by the function "pdc_parse_optionlist". + * After successfully parsing this function returns a pointer to the + * allocated "pdc_resopt" structures containing the option values. + * These structures must be freed by the function "pdc_cleanup_optionlist". + * + * Values can be fetched by the function "pdc_get_optvalues". This can + * be achieved by specifying a variable pointer (lvalues) or by a pointer + * to a pointer (mvalues). In the first case the variable must be large + * enough to hold the values. In the second case the pointer is the pointer + * to the allocated array with the option values. This pointer will be + * freed in "pdc_cleanup_optionlist". To avoid this you can call the function + * "pdc_save_lastopt" after the call of "pdc_get_optvalues". Function + * "pdc_save_lastopt" returns the pointer which is protected now against + * freeing in "pdc_cleanup_optionlist". In the special case of type = + * pdc_stringlist, you can protect only the first element in the string + * list by calling "pdc_save_lastopt" with the flag PDC_OPT_SAVE1ELEM. + * Flag = PDC_OPT_SAVEALL defines the general case. The caller has the + * responsibility to free the protected pointers after use. + * + * pdc_stringlist: + * maxnum = 1: lvalues: char s[maxval+1] (defined char array) + * maxnum > 1: lvalues: char *s[maxnum] (defined char pointer array) + * mvalues: char **s (pointer to a char pointer array) + * + */ + +typedef struct pdc_keyconn_s pdc_keyconn; +typedef struct pdc_clientdata_s pdc_clientdata; +typedef struct pdc_defopt_s pdc_defopt; +typedef struct pdc_resopt_s pdc_resopt; + +/* types of option values */ +typedef enum +{ + pdc_booleanlist = 0, + pdc_stringlist, + pdc_keywordlist, + pdc_integerlist, + pdc_floatlist, + pdc_doublelist, + pdc_scalarlist, + pdc_unicharlist, + pdc_polylinelist, + + /* correspondig member of pdc_clientdata_s must be specified */ + pdc_3ddatahandle, + pdc_3dviewhandle, + pdc_actionhandle, + pdc_bookmarkhandle, + pdc_colorhandle, + pdc_documenthandle, + pdc_fonthandle, + pdc_gstatehandle, + pdc_iccprofilehandle, + pdc_imagehandle, + pdc_layerhandle, + pdc_pagehandle, + pdc_patternhandle, + pdc_shadinghandle, + pdc_tablehandle, + pdc_templatehandle, + pdc_textflowhandle, + pdc_stringhandle +} +pdc_opttype; + +/* keyword - keycode */ +struct pdc_keyconn_s +{ + char *word; + int code; +}; + +/* client data */ +struct pdc_clientdata_s +{ + int compatibility; + int max3ddata; + int max3dview; + int maxaction; + int maxbookmark; + int maxcolor; + int maxdocument; + int maxfont; + int maxgstate; + int maxiccprofile; + int maximage; + int maxlayer; + int maxpage; + int maxpattern; + int maxshading; + int maxtable; + int maxtemplate; + int maxtextflow; + int maxstring; +}; + +/* definition of an option */ +struct pdc_defopt_s +{ + const char *name; /* name of option keyword */ + pdc_opttype type; /* type of option */ + int flags; /* flags (see below) */ + int minnum; /* permitted minimal number of values */ + int maxnum; /* permitted maximal number of values */ + double minval; /* minimal permitted value / length of string */ + double maxval; /* maximal permitted value / length of string */ + const pdc_keyconn *keylist; /* list of permitted keywords - keycodes */ +}; + +#define PDC_OPT_TERMINATE \ + {NULL, pdc_booleanlist, 0L, 0, 0, 0.0, 0.0, NULL} + +#define PDC_OPT_NONE (0) /* no flag specified */ +#define PDC_OPT_NOZERO (1L<<0) /* zero value not allowed */ +#define PDC_OPT_NOSPACES (1L<<1) /* white spaces in strings not allowed */ +#define PDC_OPT_REQUIRED (1L<<2) /* option is required */ +#define PDC_OPT_BUILDOR (1L<<3) /* build an OR bit pattern by keycodes */ +#define PDC_OPT_INTLIST (1L<<4) /* keylist is list of allowed integers */ +#define PDC_OPT_IGNOREIF1 (1L<<5) /* option is ignored if previous option is + * specified */ +#define PDC_OPT_IGNOREIF2 (1L<<6) /* option is ignored if either of + * previous two options is specified */ +#define PDC_OPT_UNSUPP (1L<<8) /* option is not supported in this + * configuration */ +#define PDC_OPT_REQUIRIF1 (1L<<9) /* option is required if previous option is + * specified */ +#define PDC_OPT_REQUIRIF2 (1L<<10) /* option is required if either of + * previous two options is specified */ +#define PDC_OPT_EVENNUM (1L<<11) /* array has even number of elements */ +#define PDC_OPT_ODDNUM (1L<<12) /* array has odd number of elements */ + +/* member "compatibility" of pdc_clientdata_s must be specified (1L<<13) ... */ +#define PDC_OPT_PDC_1_3 (1L< +#include +#endif + +/* for time_t, timer(). +*/ +#ifndef WINCE +#include +#else +#include +#endif + +#if defined(MAC) || defined (MACOSX) + +/* + * Setting the file type requires either Carbon or InterfaceLib/Classic. + * If we have neither (i.e. a Mach-O build without Carbon) we suppress + * the code for setting the file type and creator. + */ + +#if !defined(MACOSX) || defined(PDF_TARGET_API_MAC_CARBON) +#define PDF_FILETYPE_SUPPORTED +#endif + +#ifdef PDF_FILETYPE_SUPPORTED +#include +#endif + +#endif /* defined(MAC) || defined (MACOSX) */ + +#ifdef HAVE_LIBZ +#include "zlib.h" +#endif + +#ifdef HAVE_LIBZ +#define PDF_DEFAULT_COMPRESSION 6 /* default zlib level */ +#else +#define PDF_DEFAULT_COMPRESSION 0 /* no compression */ +#endif + +#define STREAM_BUFSIZE 65536 /* initial output buffer size */ +#define STREAM_MAXINCR 1048576 /* max. output buffer increment */ +#define ID_CHUNKSIZE 2048 /* object ids */ + +struct pdc_output_s { + pdc_core *pdc; /* core context */ + + pdc_bool open; /* file open */ + pdc_byte *basepos; /* start of this chunk */ + pdc_byte *curpos; /* next write position */ + pdc_byte *maxpos; /* maximum position of chunk */ + int buf_incr; /* current buffer increment */ + pdc_off_t base_offset; /* base offset of this chunk */ + pdc_bool compressing; /* in compression state */ + pdc_flush_state flush; +#ifdef HAVE_LIBZ + z_stream z; /* zlib compression stream */ +#endif + + FILE *fp; /* output file stream */ +#if defined(MVS) || defined(MVS_TEST) + int blocksize; /* file record size */ +#endif + + /* client-supplied data sink procedure */ + size_t (*writeproc)(pdc_output *out, void *data, size_t size); + + int compresslevel; /* zlib compression level */ + pdc_bool compr_changed; /* compress level has been changed */ + pdc_off_t length; /* length of stream */ + + pdc_off_t *file_offset; /* the objects' file offsets */ + int file_offset_capacity; + pdc_id lastobj; /* highest object id */ + + pdc_off_t start_pos; /* stream start position */ + pdc_off_t xref_pos; /* xref table start position */ + + MD5_CTX md5; /* MD5 digest context for file ID */ + unsigned char id[2][MD5_DIGEST_LENGTH]; + void *opaque; /* this will be used to store PDF *p */ +}; + +/* --------------------- PDFlib stream handling ----------------------- */ + +void * +pdc_get_opaque(pdc_output *out) +{ + return out->opaque; +} + +#ifdef HAVE_LIBZ +/* wrapper for pdc_malloc for use in zlib */ +static voidpf +pdc_zlib_alloc(voidpf pdc, uInt items, uInt size) +{ + return (voidpf) pdc_malloc((pdc_core *) pdc, items * size, "zlib"); +} + +#endif /* HAVE_LIBZ */ + +pdc_bool +pdc_stream_not_empty(pdc_output *out) +{ + return (!out->writeproc && out->curpos != out->basepos); +} + +char * +pdc_get_stream_contents(pdc_output *out, pdc_off_t *size) +{ + pdc_core *pdc = out->pdc; + + if (out->writeproc) + pdc_error(pdc, PDC_E_IO_NOBUFFER, 0, 0, 0, 0); + + if (size) + *size = (pdc_off_t) (out->curpos - out->basepos); + + out->base_offset += (out->curpos - out->basepos); + out->curpos = out->basepos; + + return (char *) out->basepos; +} + +static size_t +pdc_writeproc_file(pdc_output *out, void *data, size_t size) +{ + return pdc__fwrite(data, 1, size, out->fp); +} + +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma unmanaged +#endif +static pdc_bool +pdc_init_stream( + pdc_core *pdc, + pdc_output *out, + const char *filename, + FILE *fp, + size_t (*writeproc)(pdc_output *out, void *data, size_t size)) +{ + static const char fn[] = "pdc_init_stream"; + +#if defined(MAC) || defined(MACOSX) +#if !defined(TARGET_API_MAC_CARBON) || defined(__MWERKS__) + FCBPBRec fcbInfo; + Str32 name; +#endif /* TARGET_API_MAC_CARBON */ + FInfo fInfo; + FSSpec fSpec; +#endif /* defined(MAC) || defined(MACOSX) */ + + /* + * This may be left over from the previous run. We deliberately + * don't reuse the previous buffer in order to avoid potentially + * unwanted growth of the allocated buffer due to a single large + * document in a longer series of documents. + */ + if (out->basepos) + pdc_free(pdc, (void *) out->basepos); + + out->basepos = (pdc_byte *) pdc_malloc(pdc, STREAM_BUFSIZE, fn); + out->curpos = out->basepos; + out->maxpos = out->basepos + STREAM_BUFSIZE; + out->buf_incr = STREAM_BUFSIZE; + + out->base_offset = 0; + out->compressing = pdc_false; + +#ifdef HAVE_LIBZ + /* zlib sometimes reads uninitialized memory where it shouldn't... */ + memset(&out->z, 0, sizeof out->z); + + out->z.zalloc = (alloc_func) pdc_zlib_alloc; + out->z.zfree = (free_func) pdc_free; + out->z.opaque = (voidpf) pdc; + + if (deflateInit(&out->z, pdc_get_compresslevel(out)) != Z_OK) + pdc_error(pdc, PDC_E_IO_COMPRESS, "deflateInit", 0, 0, 0); + + out->compr_changed = pdc_false; +#endif + + /* Defaults */ + out->fp = (FILE *) NULL; + out->writeproc = pdc_writeproc_file; + + if (fp) + { + out->fp = fp; + } + else if (writeproc) + { + out->writeproc = writeproc; /* PDF_open_mem */ + } + else if (filename == NULL || *filename == '\0') + { + /* PDF_open_file with in-core output */ + out->writeproc = NULL; + } + else + { + /* PDF_open_file with file output */ +#if !((defined(MAC) || defined (MACOSX)) && defined(__MWERKS__)) + if (filename && !strcmp(filename, "-")) + { + out->fp = stdout; +#if !defined(__MWERKS__) && (defined(WIN32) || defined(OS2)) +#if defined WINCE + _setmode(fileno(stdout), _O_BINARY); +#else + setmode(fileno(stdout), O_BINARY); +#endif /* !WINCE */ +#endif + } + else + { +#endif /* !MAC */ + +#if defined(MVS) || defined(MVS_TEST) + out->fp = pdc_fopen_logg(out->pdc, filename, + (out->blocksize <= 1) ? WRITEMODE_V : WRITEMODE); +#else + out->fp = pdc_fopen_logg(out->pdc, filename, WRITEMODE); +#endif + + if (out->fp == NULL) + return pdc_false; + +#ifdef PDF_FILETYPE_SUPPORTED +#if defined(MAC) || defined(MACOSX) + if (!pdc->ptfrun) + { + /* set the proper type and creator for the output file */ +#if TARGET_API_MAC_CARBON && !defined(__MWERKS__) + + if (FSPathMakeFSSpec((const UInt8 *) filename, &fSpec) == noErr) + { + FSpGetFInfo(&fSpec, &fInfo); + + fInfo.fdType = 'PDF '; + fInfo.fdCreator = 'CARO'; + FSpSetFInfo(&fSpec, &fInfo); + } + +#else + + memset(&fcbInfo, 0, sizeof(FCBPBRec)); + fcbInfo.ioRefNum = (short) out->fp->handle; + fcbInfo.ioNamePtr = name; + + if (!PBGetFCBInfoSync(&fcbInfo) && + FSMakeFSSpec(fcbInfo.ioFCBVRefNum, fcbInfo.ioFCBParID, + name, &fSpec) == noErr) + { + FSpGetFInfo(&fSpec, &fInfo); + fInfo.fdType = 'PDF '; + fInfo.fdCreator = 'CARO'; + FSpSetFInfo(&fSpec, &fInfo); + } +#endif /* !defined(TARGET_API_MAC_CARBON) || defined(__MWERKS__) */ + } +#endif /* defined(MAC) || defined(MACOSX) */ +#endif /* PDF_FILETYPE_SUPPORTED */ + +#if !((defined(MAC) || defined (MACOSX)) && defined(__MWERKS__)) + } +#endif /* !MAC */ + } + + return pdc_true; +} +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma managed +#endif + +/* close the output file, if opened with PDF_open_file(); + * close the output stream if opened + */ + +static void +pdc_close_stream(pdc_output *out) +{ + /* this time we MUST flush the stream - + ** even if (flush == pdc_flush_none) + */ + out->flush = pdc_flush_heavy; + pdc_flush_stream(out); + +#ifdef HAVE_LIBZ + /* + * This is delicate: we must ignore the return value because of the + * following reasoning: We are called in two situations: + * - end of document + * - exception + * In the first case compression is inactive, so deflateEnd() will + * fail only in the second case. However, when an exception occurs + * the document is definitely unusable, so we avoid recursive exceptions + * or an (unallowed) exception in PDF_delete(). + */ + + (void) deflateEnd(&out->z); +#endif + + /* close the output file if writing to file, but do not close the + * in-core output stream since the caller will have to + * fetch the buffer after PDF_close(). + */ + if (out->fp) + { + pdc_fclose_logg(out->pdc, out->fp); + + /* mark fp as dead in case the error handler jumps in later */ + out->fp = NULL; + } +} + +static void +pdc_check_stream(pdc_output *out, size_t len) +{ + size_t newsize; + size_t cur; + pdc_core *pdc = out->pdc; + + if (out->curpos + len <= out->maxpos) + return; + + pdc_flush_stream(out); + + if (out->curpos + len <= out->maxpos) + return; + + do + { + out->maxpos += out->buf_incr; + + if (out->buf_incr < STREAM_MAXINCR) + out->buf_incr *= 2; + } while (out->curpos + len > out->maxpos); + + cur = (size_t) (out->curpos - out->basepos); + newsize = (size_t) (out->maxpos - out->basepos); + + out->basepos = (pdc_byte *) + pdc_realloc(pdc, (void *) out->basepos, newsize, "pdc_check_stream"); + out->maxpos = out->basepos + newsize; + out->curpos = out->basepos + cur; +} + +void +pdc_flush_stream(pdc_output *out) +{ + size_t size; + pdc_core *pdc = out->pdc; + + if (!out->writeproc || out->flush == pdc_flush_none) + return; + + size = (size_t) (out->curpos - out->basepos); + + if (size == 0) + return; + + if (out->writeproc(out, (void *) out->basepos, size) != size) { + pdc_free(pdc, out->basepos); + out->basepos = NULL; + out->writeproc = NULL; + pdc_error(pdc, PDC_E_IO_NOWRITE, 0, 0, 0, 0); + } + + out->base_offset += (out->curpos - out->basepos); + out->curpos = out->basepos; +} + +pdc_off_t +pdc_tell_out(pdc_output *out) +{ + return (out->base_offset + (out->curpos - out->basepos)); +} + +/* --------------------- compression handling ----------------------- */ + +static void +pdc_begin_compress(pdc_output *out) +{ + pdc_core *pdc = out->pdc; + + if (!pdc_get_compresslevel(out)) { + out->compressing = pdc_false; + return; + } + +#ifdef HAVE_LIBZ + if (out->compr_changed) + { + if (deflateEnd(&out->z) != Z_OK) + pdc_error(pdc, PDC_E_IO_COMPRESS, "deflateEnd", 0, 0, 0); + + if (deflateInit(&out->z, pdc_get_compresslevel(out)) != Z_OK) + pdc_error(pdc, PDC_E_IO_COMPRESS, "deflateInit", 0, 0, 0); + + out->compr_changed = pdc_false; + } + else + { + if (deflateReset(&out->z) != Z_OK) + pdc_error(pdc, PDC_E_IO_COMPRESS, "deflateReset", 0, 0, 0); + } + + out->z.avail_in = 0; +#endif /* HAVE_LIBZ */ + + out->compressing = pdc_true; +} + + +static void +pdc_end_compress(pdc_output *out) +{ + int status; + pdc_core *pdc = out->pdc; + + /* this may happen during cleanup triggered by an exception handler */ + if (!out->compressing) + return; + + if (!pdc_get_compresslevel(out)) { + out->compressing = pdc_false; + return; + } + + +#ifdef HAVE_LIBZ + /* Finish the stream */ + do { + pdc_check_stream(out, 128); + out->z.next_out = (Bytef *) out->curpos; + out->z.avail_out = (uInt) (out->maxpos - out->curpos); + + status = deflate(&(out->z), Z_FINISH); + out->curpos = out->z.next_out; + + if (status != Z_STREAM_END && status != Z_OK) + pdc_error(pdc, PDC_E_IO_COMPRESS, "Z_FINISH", 0, 0, 0); + + } while (status != Z_STREAM_END); + + out->compressing = pdc_false; +#endif /* HAVE_LIBZ */ +} + +/* ---------------------- Low-level output function ---------------------- */ +/* + * Write binary data to the output without any modification, + * and apply compression if we are currently in compression mode. + */ + + +void +pdc_write(pdc_output *out, const void *data, size_t size) +{ + int estimate = 0; + pdc_core *pdc = out->pdc; + +#ifdef HAVE_LIBZ + if (out->compressing) { + out->z.avail_in = (uInt) size; + out->z.next_in = (Bytef *) data; + out->z.avail_out = 0; + + while (out->z.avail_in > 0) { + if (out->z.avail_out == 0) { + /* estimate output buffer size */ + estimate = (int) (out->z.avail_in/4 + 16); + pdc_check_stream(out, (size_t) estimate); + out->z.next_out = (Bytef *) out->curpos; + out->z.avail_out = (uInt) (out->maxpos - out->curpos); + } + + if (deflate(&(out->z), Z_NO_FLUSH) != Z_OK) + pdc_error(pdc, PDC_E_IO_COMPRESS, "Z_NO_FLUSH", 0, 0, 0); + + out->curpos = out->z.next_out; + } + } else { +#endif /* HAVE_LIBZ */ + + pdc_check_stream(out, size); + memcpy(out->curpos, data, size); + out->curpos += size; + +#ifdef HAVE_LIBZ + } +#endif /* HAVE_LIBZ */ +} + + +/* --------------------------- Setup --------------------------- */ + +pdc_output * +pdc_boot_output(pdc_core *pdc) +{ + static const char *fn = "pdc_boot_output"; + pdc_output *out; + + out = (pdc_output*)pdc_malloc(pdc, sizeof(pdc_output), fn); + out->pdc = pdc; + + out->file_offset = NULL; + + /* curpos must be initialized here so that the check for empty + * buffer in PDF_delete() also works in the degenerate case of + * no output produced. + */ + out->basepos = out->curpos = NULL; + + out->open = pdc_false; + + return out; +} + +void +pdc_init_outctl(pdc_outctl *oc) +{ + oc->filename = 0; + oc->fp = 0; + oc->writeproc = 0; + oc->flush = pdc_flush_page; +#if defined(MVS) || defined(MVS_TEST) + oc->blocksize = 0; +#endif +} /* pdc_init_outctl */ + +/* + * Initialize the PDF output. + * Note that the caller is responsible for supplying sensible arguments. + */ +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma unmanaged +#endif +pdc_bool +pdc_init_output( + void *opaque, + pdc_output *out, + int compatibility, + pdc_outctl *oc) +{ + static const char *fn = "pdc_init_output"; + pdc_core *pdc = out->pdc; + int i; + + pdc_cleanup_output(out, pdc_false); + + out->opaque = opaque; + out->lastobj = 0; +#if defined(MVS) || defined(MVS_TEST) + out->blocksize = oc->blocksize; +#endif + + if (out->file_offset == NULL) { + out->file_offset_capacity = ID_CHUNKSIZE; + + out->file_offset = (pdc_off_t *) pdc_malloc(pdc, + sizeof(pdc_off_t) * out->file_offset_capacity, fn); + } + + for (i = 1; i < out->file_offset_capacity; ++i) + out->file_offset[i] = PDC_BAD_ID; + + out->compresslevel = PDF_DEFAULT_COMPRESSION; + out->compr_changed = pdc_false; + out->flush = oc->flush; + + memcpy(out->id[0], out->id[1], MD5_DIGEST_LENGTH); + + + if (!pdc_init_stream(pdc, out, oc->filename, oc->fp, oc->writeproc)) + return pdc_false; + { + /* Write the document header */ + pdc_printf(out, "%%PDF-%s\n", pdc_get_pdfversion(pdc, compatibility)); + +#define PDC_MAGIC_BINARY "\045\344\343\317\322\012" + pdc_write(out, PDC_MAGIC_BINARY, sizeof(PDC_MAGIC_BINARY) - 1); + } + + out->open = pdc_true; + + return pdc_true; +} +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma managed +#endif + +void +pdc_close_output(pdc_output *out) +{ + if (out->open) + { + out->open = pdc_false; + + pdc_close_stream(out); + + if (out->file_offset) + { + pdc_free(out->pdc, out->file_offset); + out->file_offset = 0; + } + + } +} + +void +pdc_cleanup_output(pdc_output *out, pdc_bool keep_buf) +{ + pdc_core *pdc = out->pdc; + + if (out->file_offset) + { + pdc_free(pdc, out->file_offset); + out->file_offset = NULL; + } + + + if (!keep_buf && out->basepos) + { + pdc_free(pdc, (void *) out->basepos); + out->basepos = NULL; + out->curpos = NULL; + } + +} + +/* --------------------------- Digest --------------------------- */ + +void +pdc_init_digest(pdc_output *out) +{ + MD5_Init(&out->md5); +} + +void +pdc_update_digest(pdc_output *out, unsigned char *input, + unsigned int len) +{ + MD5_Update(&out->md5, input, len); +} + +void +pdc_finish_digest(pdc_output *out, pdc_bool settime) +{ + if (settime) + { + time_t timer; + + time(&timer); + MD5_Update(&out->md5, (unsigned char *) &timer, sizeof timer); + } + + MD5_Final(out->id[1], &out->md5); +} + +unsigned char * +pdc_get_digest(pdc_output *out) +{ + return out->id[1]; +} + +/* --------------------------- Objects and ids --------------------------- */ + +pdc_id +pdc_begin_obj(pdc_output *out, pdc_id obj_id) +{ + if (obj_id == PDC_NEW_ID) + obj_id = pdc_alloc_id(out); + + out->file_offset[obj_id] = pdc_tell_out(out); + pdc_printf(out, "%ld 0 obj\n", obj_id); + + return obj_id; +} + +pdc_id +pdc_alloc_id(pdc_output *out) +{ + + out->lastobj++; + + if (out->lastobj > PDF_MAXINDOBJS) + pdc_error(out->pdc, PDC_E_INT_TOOMUCH_INDOBJS, + pdc_errprintf(out->pdc, "%d", PDF_MAXINDOBJS), 0, 0, 0); + + if (out->lastobj >= out->file_offset_capacity) { + out->file_offset_capacity *= 2; + out->file_offset = (pdc_off_t *) + pdc_realloc(out->pdc, out->file_offset, + sizeof(pdc_off_t) * out->file_offset_capacity, "pdc_alloc_id"); + } + + /* only needed for verifying obj table in PDF_close() */ + out->file_offset[out->lastobj] = PDC_BAD_ID; + + return out->lastobj; +} + + +/* --------------------------- Strings --------------------------- */ + +void +pdc_put_pdfstring(pdc_output *out, const char *text, int len) +{ + const unsigned char *goal, *s; + + if (!len) + len = (int) strlen(text); + + if (out->pdc->compatibility <= PDC_1_5 && len > PDF_MAXSTRINGSIZE) + pdc_error(out->pdc, PDC_E_INT_TOOLONG_TEXTSTR, + pdc_errprintf(out->pdc, "%d", PDF_MAXSTRINGSIZE), 0, 0, 0); + + + pdc_putc(out, PDF_PARENLEFT); + + goal = (const unsigned char *) text + len; + + for (s = (const unsigned char *) text; s < goal; s++) + { + switch (*s) + { + case PDF_RETURN: + pdc_putc(out, PDF_BACKSLASH); + pdc_putc(out, PDF_r); + break; + + case PDF_NEWLINE: + pdc_putc(out, PDF_BACKSLASH); + pdc_putc(out, PDF_n); + break; + + default: + if (*s == PDF_PARENLEFT || *s == PDF_PARENRIGHT || + *s == PDF_BACKSLASH) + pdc_putc(out, PDF_BACKSLASH); + pdc_putc(out, (char) *s); + } + } + + pdc_putc(out, PDF_PARENRIGHT); +} + +/* normalized file name according PDF specification */ +void +pdc_put_pdffilename(pdc_output *out, const char *text, int len) +{ + static const char *fn = "pdc_put_pdffilename"; + char *ttext; + +#if defined(WIN32) || defined(MAC) + int i, j = 0, k = 0; +#endif + + if (!len) + len = (int) strlen(text); + + ttext = (char *) pdc_malloc(out->pdc, (size_t) (len + 4), fn); + strcpy(ttext, text); + +#if defined(WIN32) + + /* absolute path name */ + if (strchr(ttext, PDF_COLON) != NULL || text[0] == PDF_BACKSLASH) + { + ttext[j] = PDF_SLASH; + j++; + } + for (i = k; i < len; i++) + { + if (text[i] == PDF_BACKSLASH) + ttext[j] = PDF_SLASH; + else if (text[i] == PDF_COLON) + continue; + else + ttext[j] = text[i]; + j++; + } + len = j; + +#elif defined(MAC) + + /* absolute path name */ + if (text[0] != PDF_COLON) + { + ttext[j] = PDF_SLASH; + j++; + } + else + { + k = 1; + } + for (i = k; i < len; i++) + { + if (text[i] == PDF_COLON) + ttext[j] = PDF_SLASH; + else + ttext[j] = text[i]; + j++; + } + len = j; + +#endif + + pdc_put_pdfstring(out, ttext, len); + + pdc_free(out->pdc, ttext); +} + +/* --------------------------- Streams --------------------------- */ + +void +pdc_begin_pdfstream(pdc_output *out) +{ + pdc_puts(out, "stream\n"); + + out->start_pos = pdc_tell_out(out); + + if (out->compresslevel) + pdc_begin_compress(out); +} + +void +pdc_end_pdfstream(pdc_output *out) +{ + if (out->compresslevel) + pdc_end_compress(out); + + out->length = pdc_tell_out(out) - out->start_pos; + + /* some PDF consumers seem to need the additional "\n" before "endstream", + ** the PDF reference allows it, and Acrobat's "repair" feature relies on it. + */ + pdc_puts(out, "\nendstream\n"); +} + +pdc_off_t +pdc_get_pdfstreamlength(pdc_output *out) +{ + return out->length; +} + +void +pdc_put_pdfstreamlength(pdc_output *out, pdc_id length_id) +{ + + pdc_begin_obj(out, length_id); /* Length object */ + pdc_printf(out, "%lld\n", out->length); + pdc_end_obj(out); +} + +void +pdc_set_compresslevel(pdc_output *out, int compresslevel) +{ + out->compresslevel = compresslevel; + out->compr_changed = pdc_true; +} + +int +pdc_get_compresslevel(pdc_output *out) +{ + return out->compresslevel; +} + + +/* --------------------------- Names --------------------------- */ + +/* characters illegal in PDF names: "()<>[]{}/%#" */ +#define PDF_ILL_IN_NAMES "\050\051\074\076\133\135\173\175\057\045\043" + +#define PDF_NEEDS_QUOTE(c) \ + ((c) < 33 || (c) > 126 || strchr(PDF_ILL_IN_NAMES, (c)) != (char *) 0) + +void +pdc_put_pdfname(pdc_output *out, const char *text, size_t len) +{ + const unsigned char *goal, *s; + static const char BinToHex[] = PDF_STRING_0123456789ABCDEF; + + if (!len) + len = strlen(text); + + goal = (const unsigned char *) text + len; + + pdc_putc(out, PDF_SLASH); + + for (s = (const unsigned char *) text; s < goal; s++) { + if (PDF_NEEDS_QUOTE(*s)) { + pdc_putc(out, PDF_HASH); + pdc_putc(out, BinToHex[*s >> 4]); /* first nibble */ + pdc_putc(out, BinToHex[*s & 0x0F]); /* second nibble */ + } else + pdc_putc(out, (char) *s); + } +} + +/* --------------------------- Document sections --------------------------- */ + +void +pdc_mark_free(pdc_output *out, pdc_id obj_id) +{ + out->file_offset[obj_id] = PDC_FREE_ID; +} + + +void +pdc_write_xref(pdc_output *out) +{ + pdc_id start = 1; + pdc_id i; + pdc_id free_id; + pdc_core * pdc = out->pdc; + + /* Don't write any object after this check! */ + + for (i = start; i <= out->lastobj; i++) { + if (out->file_offset[i] == PDC_BAD_ID) { + pdc_warning(pdc, PDC_E_INT_UNUSEDOBJ, + pdc_errprintf(pdc, "%ld", i), 0, 0, 0); + /* write a dummy object */ + pdc_begin_obj(out, i); + pdc_printf(out, "null %% unused object\n"); + pdc_end_obj(out); + } + } + + + out->xref_pos = pdc_tell_out(out); + pdc_puts(out, "xref\n"); + pdc_printf(out, "0 %ld\n", out->lastobj + 1); + + /* find the last free entry in the xref table. + */ + out->file_offset[0] = PDC_FREE_ID; + for (free_id = out->lastobj; + out->file_offset[free_id] != PDC_FREE_ID; + --free_id) + ; + + pdc_printf(out, "%010ld 65535 f \n", free_id); + free_id = 0; + +#define PDF_FLUSH_AFTER_MANY_OBJS 3000 /* ca. 60 KB */ + for (i = 1; i <= out->lastobj; i++) { + /* Avoid spike in memory usage at the end of the document */ + if (i % PDF_FLUSH_AFTER_MANY_OBJS == 0) + pdc_flush_stream(out); + + if (out->file_offset[i] == PDC_FREE_ID) + { + pdc_printf(out, "%010ld 00001 f \n", free_id); + free_id = i; + } + else + { + pdc_printf(out, "%010lld 00000 n \n", out->file_offset[i]); + } + } +} + +void +pdc_write_digest(pdc_output *out) +{ + static const char bin2hex[] = PDF_STRING_0123456789ABCDEF; + + int i; + + pdc_puts(out, "/ID[<"); + for (i = 0; i < MD5_DIGEST_LENGTH; ++i) + { + pdc_putc(out, bin2hex[out->id[0][i] >> 4]); + pdc_putc(out, bin2hex[out->id[0][i] & 0x0F]); + } + pdc_puts(out, "><"); + for (i = 0; i < MD5_DIGEST_LENGTH; ++i) + { + pdc_putc(out, bin2hex[out->id[1][i] >> 4]); + pdc_putc(out, bin2hex[out->id[1][i] & 0x0F]); + } + pdc_puts(out, ">]\n"); +} + +void +pdc_write_eof(pdc_output *out) +{ +#if defined(MVS) || defined(MVS_TEST) + int i, k; + + if (out->blocksize > 1) + { + if ((i = (pdc_tell_out(out) + 6) % out->blocksize) != 0) + { + for (k = 0; k < out->blocksize - i - 1; ++k) + pdc_putc(out, PDF_SPACE); + + pdc_putc(out, PDF_NEWLINE); + } + } +#endif /* MVS */ + pdc_puts(out, "%%EOF\n"); +} + +void +pdc_write_trailer( + pdc_output *out, + pdc_id info_id, + pdc_id root_id, + int root_gen, + long xref_size, + pdc_off_t xref_prev, + pdc_off_t xref_pos) +{ + if (xref_size == -1) + { + xref_size = out->lastobj + 1; + } + + if (xref_pos == -1) + { + xref_pos = out->xref_pos; + } + + /* we've seen PDF consumers that need the linefeed... + */ + pdc_puts(out, "trailer\n"); + + pdc_begin_dict(out); /* trailer */ + pdc_printf(out, "/Size %ld\n", xref_size); + + if (xref_prev != -1) + pdc_printf(out, "/Prev %lld\n", xref_prev); + + pdc_printf(out, "/Root %ld %d R\n", root_id, root_gen); + + if (info_id != PDC_BAD_ID) + pdc_printf(out, "/Info %ld 0 R\n", info_id); + + pdc_write_digest(out); + pdc_end_dict(out); /* trailer */ + + pdc_puts(out, "startxref\n"); + pdc_printf(out, "%lld\n", xref_pos); + pdc_write_eof(out); +} + +/* ---------------------- High-level output functions ---------------------- */ + +#define PDC_LINEBUFLEN 4048 /* len of line output buffer */ + +/* + * Write a native encoded string to the output. + */ + +static void +pdc_puts_internal(pdc_output *out, char *s, pdc_bool tocopy) +{ + char *scp = s; + (void) tocopy; + + pdc_write(out, (void *) scp, strlen(scp)); +} + +void +pdc_puts(pdc_output *out, const char *s) +{ + pdc_puts_internal(out, (char *) s, pdc_true); +} + +/* + * Write a ASCII character to the output. + */ + +void +pdc_putc(pdc_output *out, const char c) +{ + pdc_write(out, (void *) &c, (size_t) 1); +} + +/* + * Write a formatted string (native encoded) to the output. + */ + +void +pdc_printf(pdc_output *out, const char *fmt, ...) +{ + char buf[PDC_LINEBUFLEN]; + va_list ap; + + va_start(ap, fmt); + + pdc_vsprintf(out->pdc, pdc_true, buf, fmt, ap); + pdc_puts_internal(out, buf, pdc_false); + + va_end(ap); +} + diff --git a/src/pdflib/pdcore/pc_output.h b/src/pdflib/pdcore/pc_output.h new file mode 100644 index 0000000..61a5697 --- /dev/null +++ b/src/pdflib/pdcore/pc_output.h @@ -0,0 +1,203 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_output.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib output routines + * + */ + +#ifndef PC_OUTPUT_H +#define PC_OUTPUT_H + +/* --------------------------- General --------------------------- */ + +/* Acrobat viewers change absolute values < 1/65536 to zero */ +#define PDF_SMALLREAL (0.000015) + +/* Acrobat viewers have an upper limit on real and integer numbers */ +#define PDF_BIGREAL (32768.0) +#define PDF_BIGINT (2147483647.0) + +/* maximum capacity of a dictionary, in entries */ +#define PDF_MAXDICTSIZE (4095) + +/* maximum capacity of an array, in elements */ +#define PDF_MAXARRAYSIZE (8191) + +/* maximum capacity of a string, in bytes */ +#define PDF_MAXSTRINGSIZE (65535) + +/* maximum capacity of indirect objects */ +#define PDF_MAXINDOBJS (8388607) + +/* some ASCII characters and strings, deliberately defined as hex/oct codes */ + +#define PDF_NEWLINE ((char) 0x0A) /* ASCII '\n' */ +#define PDF_RETURN ((char) 0x0D) /* ASCII '\r' */ +#define PDF_SPACE ((char) 0x20) /* ASCII ' ' */ +#define PDF_HASH ((char) 0x23) /* ASCII '#' */ +#define PDF_PARENLEFT ((char) 0x28) /* ASCII '(' */ +#define PDF_PARENRIGHT ((char) 0x29) /* ASCII ')' */ +#define PDF_PLUS ((char) 0x2B) /* ASCII '+' */ +#define PDF_SLASH ((char) 0x2F) /* ASCII '/' */ +#define PDF_COLON ((char) 0x3A) /* ASCII ':' */ +#define PDF_BACKSLASH ((char) 0x5C) /* ASCII '\\' */ + +#define PDF_A ((char) 0x41) /* ASCII 'A' */ +#define PDF_n ((char) 0x6E) /* ASCII 'n' */ +#define PDF_r ((char) 0x72) /* ASCII 'r' */ + +#define PDF_STRING_0123456789ABCDEF \ + "\060\061\062\063\064\065\066\067\070\071\101\102\103\104\105\106" + +typedef struct pdc_output_s pdc_output; + +typedef enum +{ + pdc_flush_none = 0, /* end of document */ + pdc_flush_page = 1<<0, /* after page */ + pdc_flush_content = 1<<1, /* font, xobj, annots */ + + /* temporary workaround; see bugzilla #167. + */ + /* pdc_flush_heavy = 1<<4 before realloc attempt */ + pdc_flush_heavy = pdc_flush_page | pdc_flush_content +} +pdc_flush_state; + +/* output control. +*/ +typedef struct +{ + /* exactly one of the members 'filename', 'fp', and 'writeproc' + ** must be supplied, the others must be NULL: + ** + ** filename use supplied file name to create a named output file + ** filename == "" means generate output in-core + ** fp use supplied FILE * to write to file + ** writeproc use supplied procedure to write output data + */ + const char *filename; + FILE * fp; + size_t (*writeproc)(pdc_output *out, void *data, size_t size); + + pdc_flush_state flush; +#if defined(MVS) || defined(MVS_TEST) + int blocksize; /* file record size */ +#endif +} pdc_outctl; + +/* --------------------------- Setup --------------------------- */ + +pdc_output * pdc_boot_output(pdc_core *pdc); +void pdc_init_outctl(pdc_outctl *oc); +pdc_bool pdc_init_output(void *opaque, pdc_output *out, + int compatibility, pdc_outctl *oc); +void pdc_cleanup_output(pdc_output *out, pdc_bool keep_buf); +void * pdc_get_opaque(pdc_output *out); + +/* --------------------------- Digest --------------------------- */ + +void pdc_init_digest(pdc_output *out); +void pdc_update_digest(pdc_output *out, unsigned char *input, + unsigned int len); +void pdc_finish_digest(pdc_output *out, pdc_bool settime); +unsigned char * pdc_get_digest(pdc_output *out); + + +/* --------------------------- Objects and ids --------------------------- */ + +pdc_id pdc_alloc_id(pdc_output *out); +pdc_id pdc_map_id(pdc_output *out, pdc_id old_id); +void pdc_mark_free(pdc_output *out, pdc_id obj_id); + +pdc_id pdc_begin_obj(pdc_output *out, pdc_id obj_id); +#define pdc_end_obj(out) pdc_puts(out, "endobj\n") + +#define PDC_NEW_ID 0L +#define PDC_BAD_ID -1L +#define PDC_FREE_ID -2L + + +/* --------------------------- Strings --------------------------- */ +/* output a string (including parentheses) and quote all required characters */ +void pdc_put_pdfstring(pdc_output *out, const char *text, int len); +void pdc_put_pdffilename(pdc_output *out, const char *text, int len); + + +/* --------------------------- Names --------------------------- */ +/* output a PDF name (including leading slash) and quote all required chars */ +void pdc_put_pdfname(pdc_output *out, const char *text, size_t len); + + +/* --------------------------- Arrays --------------------------- */ +#define pdc_begin_array(out) pdc_puts(out, "[") +#define pdc_end_array(out) pdc_puts(out, "]\n") +#define pdc_end_array_c(out) pdc_puts(out, "]") + + +/* --------------------------- Dictionaries --------------------------- */ +#define pdc_begin_dict(out) pdc_puts(out, "<<") +#define pdc_end_dict(out) pdc_puts(out, ">>\n") +#define pdc_end_dict_c(out) pdc_puts(out, ">>") + + +/* --------------------------- Object References --------------------------- */ +#define pdc_objref(out, name, obj_id) \ + pdc_printf(out, "%s %ld 0 R\n", name, obj_id) + +#define pdc_objref_c(out, obj_id) \ + pdc_printf(out, " %ld 0 R", obj_id) + +#define pdc_objref_c2(out, obj_id, gen_no) \ + pdc_printf(out, " %ld %d R", obj_id, gen_no) + +/* --------------------------- Streams --------------------------- */ +void pdc_begin_pdfstream(pdc_output *out); +void pdc_end_pdfstream(pdc_output *out); +pdc_off_t pdc_get_pdfstreamlength(pdc_output *out); +void pdc_put_pdfstreamlength(pdc_output *out, pdc_id length_id); + +int pdc_get_compresslevel(pdc_output *out); +void pdc_set_compresslevel(pdc_output *out, int compresslevel); + + + +/* --------------------------- Document sections --------------------------- */ +void pdc_write_xref(pdc_output *out); + +void pdc_write_digest(pdc_output *out); +void pdc_write_trailer(pdc_output *out, pdc_id info_id, + pdc_id root_id, int root_gen, long xref_size, + pdc_off_t xref_prev, pdc_off_t xref_pos); +void pdc_write_eof(pdc_output *out); + + +/* --------------------------- Low-level output --------------------------- */ +void pdc_flush_stream(pdc_output *out); +pdc_off_t pdc_tell_out(pdc_output *out); +void pdc_close_output(pdc_output *out); + /* TODO2GB: size_t? */ +char * pdc_get_stream_contents(pdc_output *out, pdc_off_t *size); +int pdc_stream_not_empty(pdc_output *out); + +void pdc_write(pdc_output *out, const void *data, size_t size); +void pdc_puts(pdc_output *out, const char *s); +void pdc_putc(pdc_output *out, const char c); + + +/* ------------------------- High-level output ------------------------- */ +void pdc_printf(pdc_output *out, const char *fmt, ...); + +#endif /* PC_OUTPUT_H */ + diff --git a/src/pdflib/pdcore/pc_prefix.h b/src/pdflib/pdcore/pc_prefix.h new file mode 100644 index 0000000..bcb9135 --- /dev/null +++ b/src/pdflib/pdcore/pc_prefix.h @@ -0,0 +1,17 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_prefix.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDCORE: unique renaming of function names shared by different applications + */ + +#ifndef PC_PREFIX_H +#define PC_PREFIX_H + +#endif /* PC_PREFIX_H */ diff --git a/src/pdflib/pdcore/pc_pstok.h b/src/pdflib/pdcore/pc_pstok.h new file mode 100644 index 0000000..a3a6ca2 --- /dev/null +++ b/src/pdflib/pdcore/pc_pstok.h @@ -0,0 +1,15 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_pstok.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDCORE PostScript token scanner. + * + */ + + diff --git a/src/pdflib/pdcore/pc_resource.c b/src/pdflib/pdcore/pc_resource.c new file mode 100644 index 0000000..727df4e --- /dev/null +++ b/src/pdflib/pdcore/pc_resource.c @@ -0,0 +1,1906 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_resource.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Resource routines + * + */ + +#define PC_RESOURCE_C + +#include + +#include "pc_util.h" +#include "pc_file.h" +#include "pc_resource.h" +#include "pc_ctype.h" + +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#endif + + +/* -------------------------- resource handling ----------------------------- */ + +struct pdc_res_s +{ + char *name; + char *value; + pdc_res *prev; + pdc_res *next; +}; + +struct pdc_category_s +{ + char *category; + pdc_res *kids; + pdc_category *next; +}; + +struct pdc_reslist_s +{ + pdc_category *resources; /* anchor for the category resource list */ + pdc_bool filepending; /* to read resource file is pending */ + char *filename; /* name of the resource file */ +}; + +typedef enum +{ + pdc_FontOutline, + pdc_FontAFM, + pdc_FontPFM, + pdc_HostFont, + pdc_Encoding, + pdc_ICCProfile, + pdc_StandardOutputIntent, + pdc_SearchPath, + pdc_CMap, + pdc_GlyphList, + pdc_CodeList +} +pdc_rescategory; + +static const pdc_keyconn pdc_rescategories[] = +{ + {"FontOutline", pdc_FontOutline}, + {"FontAFM", pdc_FontAFM}, + {"FontPFM", pdc_FontPFM}, + {"HostFont", pdc_HostFont}, + {"Encoding", pdc_Encoding}, + {"ICCProfile", pdc_ICCProfile}, + {"StandardOutputIntent", pdc_StandardOutputIntent}, + {"SearchPath", pdc_SearchPath}, + {"CMap", pdc_CMap}, + {"GlyphList", pdc_GlyphList}, + {"CodeList", pdc_CodeList}, + {NULL, 0} +}; + +#define RESOURCEFILEENVNAME "%sRESOURCEFILE" + +#ifndef MVS +#define DEFAULTRESOURCEFILE "%s.upr" +#else +#define DEFAULTRESOURCEFILE "upr" +#endif + +#ifdef WIN32 +#define REGISTRYKEY "Software\\PDFlib\\%s\\%s" +#endif + +pdc_reslist * +pdc_new_reslist(pdc_core *pdc) +{ + static const char fn[] = "pdc_new_reslist"; + + pdc_reslist *resl = (pdc_reslist *) pdc_malloc(pdc, sizeof(pdc_reslist),fn); + + resl->resources = NULL; + resl->filepending = pdc_true; + resl->filename = NULL; + + pdc->reslist = resl; + + return resl; +} + +static pdc_category * +pdc_delete_rescategory(pdc_core *pdc, pdc_category *prevcat, pdc_category *cat, + pdc_bool empty) +{ + pdc_category *nextcat; + pdc_res *res, *lastres; + + for (res = cat->kids; res != NULL; /* */) + { + lastres = res; + res = lastres->next; + pdc_free(pdc, lastres->name); + lastres->name = NULL; + if (lastres->value) + { + pdc_free(pdc, lastres->value); + lastres->value = NULL; + } + pdc_free(pdc, lastres); + } + nextcat = cat->next; + + if (empty) + { + cat->kids = NULL; + } + else + { + pdc_free(pdc, cat->category); + cat->category = NULL; + pdc_free(pdc, cat); + cat = NULL; + + if (prevcat != NULL) + { + pdc_reslist *resl = pdc->reslist; + + if (prevcat != cat) + prevcat->next = nextcat; + else + resl->resources = nextcat; + } + } + + return nextcat; +} + +void +pdc_delete_reslist(pdc_core *pdc) +{ + pdc_reslist *resl = pdc->reslist; + + if (resl != NULL) + { + pdc_category *cat; + + for (cat = resl->resources; cat != NULL; /* */) + cat = pdc_delete_rescategory(pdc, NULL, cat, pdc_false); + + if (resl->filename) + pdc_free(pdc, resl->filename); + + pdc_free(pdc, resl); + pdc->reslist = NULL; + } +} + +static pdc_reslist * +pdc_get_reslist(pdc_core *pdc) +{ + pdc_reslist *resl = pdc->reslist; + + if (resl == NULL) + resl = pdc_new_reslist(pdc); + + return resl; +} + +void +pdc_set_resourcefile(pdc_core *pdc, const char *filename) +{ + if (filename != NULL && *filename) + { + pdc_reslist *resl = pdc_get_reslist(pdc); + + if (resl->filename) + pdc_free(pdc, resl->filename); + + resl->filename = pdc_strdup(pdc, filename); + resl->filepending = pdc_true; + } +} + +const char * +pdc_get_resourcefile(pdc_core *pdc) +{ + pdc_reslist *resl = pdc_get_reslist(pdc); + + return (resl->filename); +} + +static void +pdc_read_resourcefile(pdc_core *pdc, const char *filename) +{ + pdc_reslist *resl = pdc_get_reslist(pdc); + pdc_file *fp = NULL; + char **linelist; + char *line; + char *category = NULL; + char *uprfilename = NULL; + char tmpname[PDC_FILENAMELEN]; +#if defined(AS400) || defined(WIN32) +#define BUFSIZE 2048 + char buffer[BUFSIZE]; +#ifdef WIN32 + char regkey[128]; + HKEY hKey = NULL; + DWORD size, lType; +#endif +#endif + int il, nlines = 0, nextcat, begin; + + pdc_logg_cond(pdc, 1, trc_resource, + "\n\tSearching for resource file...\n"); + +#ifdef WIN32 + +/* don't add patchlevel's to registry searchpath */ +#define stringiz1(x) #x +#define stringiz(x) stringiz1(x) + + sprintf(regkey, REGISTRYKEY, pdc->prodname, pdc->version); + +#endif /* WIN32 */ + +#ifdef AS400 + pdc_logg_cond(pdc, 1, trc_resource, + "\tSet AS400 default resources\n"); + strcpy (buffer, "/pdflib/"); + strcat (buffer, pdc->version); + il = (int) strlen(buffer); + strcat (buffer, "/fonts"); + pdc_add_resource(pdc, "SearchPath", buffer, ""); + strcpy(&buffer[il], "/bind/data"); + pdc_add_resource(pdc, "SearchPath", buffer, ""); +#endif /* AS400 */ + +#ifdef WIN32 + /* process registry entries */ + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0L, + (REGSAM) KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + pdc_logg_cond(pdc, 1, trc_resource, + "\tRead registry key \"%s\":\n", REGISTRYKEY); + + size = BUFSIZE - 2; + if (RegQueryValueExA(hKey, "searchpath", (LPDWORD) NULL, + &lType, (LPBYTE) buffer, &size) + == ERROR_SUCCESS && *buffer) + { + char **pathlist; + int ip, np; + + np = pdc_split_stringlist(pdc, buffer, ";", 0, &pathlist); + for (ip = 0; ip < np; ip++) + pdc_add_resource(pdc, "SearchPath", pathlist[ip], ""); + pdc_cleanup_stringlist(pdc, pathlist); + } + + RegCloseKey(hKey); + } +#endif /* WIN32 */ + + /* searching for name of upr file */ + uprfilename = (char *)filename; + if (uprfilename == NULL || *uprfilename == '\0') + { + /* upr file name via environment variable */ + sprintf(tmpname, RESOURCEFILEENVNAME, pdc->prodname); + pdc_strtoupper(tmpname); + uprfilename = pdc_getenv(tmpname); + +#ifdef WIN32 + /* registry upr file name */ + if (uprfilename == NULL || *uprfilename == '\0') + { + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0L, + (REGSAM) KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + size = BUFSIZE - 2; + if (RegQueryValueExA(hKey, "resourcefile", (LPDWORD) NULL, + &lType, (LPBYTE) buffer, &size) + == ERROR_SUCCESS && *buffer) + { + uprfilename = buffer; + } + + RegCloseKey(hKey); + } + } +#endif /* WIN32 */ + + /* default upr file name */ + if (uprfilename == NULL || *uprfilename == '\0') + { + sprintf(tmpname, DEFAULTRESOURCEFILE, pdc->prodname); + uprfilename = pdc_strtolower(tmpname); + + /* user-supplied upr file */ + fp = pdc_fsearch_fopen(pdc, uprfilename, NULL, NULL, 0); + if (fp == NULL) + { + uprfilename = NULL; + } + } + } + + if (uprfilename != NULL && *uprfilename != '\0') + { + char *resfilename = resl->filename; + + pdc_logg_cond(pdc, 1, trc_resource, + "\tRead resource file \"%s\":\n", uprfilename); + + resl->filename = pdc_strdup(pdc, uprfilename); + if (resfilename) + pdc_free(pdc, resfilename); + + /* read upr file */ + if (fp == NULL) + { + fp = pdc_fsearch_fopen(pdc, resl->filename, NULL, "UPR ", + PDC_FILE_TEXT); + if (fp == NULL) + pdc_error(pdc, -1, 0, 0, 0, 0); + } + + nlines = pdc_read_textfile(pdc, fp, 0, &linelist); + pdc_fclose(fp); + + if (nlines) + { + /* Lines loop */ + begin = 1; + nextcat = 0; + for (il = 0; il < nlines; il++) + { + line = linelist[il]; + + /* Next category */ + if (line[0] == '.' && strlen(line) == 1) + { + begin = 0; + nextcat = 1; + continue; + } + + /* Skip category list */ + if (begin) continue; + + /* Category expected */ + if (nextcat) + { + /* Ressource Category */ + category = line; + nextcat = 0; + continue; + } + + /* Add resource */ + if (strlen(line)) + pdc_add_resource(pdc, category, line, NULL); + } + + pdc_cleanup_stringlist(pdc, linelist); + } + } +} + +/* + * pdc_add_resource_ext add a new resource to the resource data base + * for specified resource category. + * + * resvalue == NULL: + * resname string has the format "resname [= resvalue]" + * Then string splitting has to be performed. + * [EBCDIC-]UTF-8 must be specified by a BOM: resname = resvalue + * + * Otherwise resname and resvalue are [EBCDIC-]UTF-8 encoded. + * + */ +void +pdc_add_resource_ext(pdc_core *pdc, const char *category, const char *resname, + const char *resvalue, pdc_encoding enc, int codepage) +{ + static const char fn[] = "pdc_add_resource"; + pdc_reslist *resl = pdc_get_reslist(pdc); + pdc_rescategory rescat; + pdc_category *cat = NULL, *lastcat = NULL; + pdc_res *res = NULL, *lastres = NULL; + char *resnamutf8 = NULL; + char *resvalutf8 = NULL; + int resnamflags = PDC_CONV_EBCDIC; + int resvalflags = PDC_CONV_EBCDIC; + int k; + + if (!resvalue || !strlen(resvalue)) + pdc_logg_cond(pdc, 1, trc_resource, + "\tAdd \"%s\" to resource category \"%s\"\n", resname, category); + else + pdc_logg_cond(pdc, 1, trc_resource, + "\tAdd \"%s=%s\" to resource category \"%s\"\n", + resname, resvalue, category); + + /* We no longer raise an error but silently ignore unknown categories */ + k = pdc_get_keycode_ci(category, pdc_rescategories); + if (k == PDC_KEY_NOTFOUND) + { + pdc_warning(pdc, PDC_E_RES_BADCAT, category, 0, 0, 0); + return; + } + rescat = (pdc_rescategory) k; + + /* Read resource configuration file if it is pending */ + if (resl->filepending) + { + resl->filepending = pdc_false; + pdc_read_resourcefile(pdc, resl->filename); + } + + /* Find start of this category's resource list, if the category exists */ + lastcat = resl->resources; + for (cat = lastcat; cat != NULL; cat = cat->next) + { + if (!pdc_stricmp(cat->category, category)) + break; + lastcat = cat; + } + if (cat == NULL) + { + cat = (pdc_category *) pdc_malloc(pdc, sizeof(pdc_category), fn); + cat->category = pdc_strdup(pdc, category); + cat->kids = NULL; + cat->next = NULL; + if (lastcat != NULL) + lastcat->next = cat; + else + resl->resources = cat; + } + + /* resvalue */ + if (resvalue == NULL) + { + char **strlist = NULL; + + /* splitting of resname string */ + int ns = pdc_split_stringlist(pdc, resname, "=", 0, &strlist); + + if (ns >= 1) + pdc_str2trim(strlist[0]); + if (ns == 2) + pdc_str2trim(strlist[1]); + if (ns > 2 || + (rescat != pdc_SearchPath && (ns == 0 || !strlen(strlist[0])))) + { + pdc_cleanup_stringlist(pdc, strlist); + pdc_error(pdc, PDC_E_RES_BADRES, resname, category, 0, 0); + } + + /* resource name */ + if (ns > 0) + { + if (pdc_is_utf8_bytecode(resname)) + resnamflags |= PDC_CONV_ISUTF8; + resnamutf8 = pdc_convert_name_ext(pdc, strlist[0], 0, + enc, codepage, resnamflags); + } + + /* resource value */ + if (ns == 2) + { + resvalflags = resnamflags; + resvalutf8 = pdc_convert_name_ext(pdc, strlist[1], 0, + enc, codepage, resvalflags); + } + else + { + resvalutf8 = pdc_strdup(pdc, ""); + } + pdc_cleanup_stringlist(pdc, strlist); + } + else + { + resnamflags |= PDC_CONV_ISUTF8; + resnamutf8 = pdc_convert_name_ext(pdc, resname, 0, + enc, codepage, resnamflags); + + resvalflags |= PDC_CONV_ISUTF8; + resvalutf8 = pdc_convert_name_ext(pdc, resvalue, 0, + enc, codepage, resvalflags); + } + + switch (rescat) + { + case pdc_FontOutline: + case pdc_FontAFM: + case pdc_FontPFM: + case pdc_HostFont: + case pdc_Encoding: + case pdc_ICCProfile: + case pdc_CMap: + case pdc_GlyphList: + case pdc_CodeList: + { + if (!strlen(resnamutf8) || !strlen(resvalutf8)) + { + pdc_free(pdc, resnamutf8); + pdc_free(pdc, resvalutf8); + if (resvalue == NULL) + pdc_error(pdc, PDC_E_RES_BADRES, resname, category, 0, 0); + else + pdc_error(pdc, PDC_E_RES_BADRES2, resname, resvalue, + category, 0); + } + + /* file name check */ + resvalutf8 = pdc_check_filename(pdc, resvalutf8); + } + break; + + case pdc_SearchPath: + { + if (strlen(resvalutf8)) + { + if (resnamutf8 != NULL) + pdc_free(pdc, resnamutf8); + pdc_free(pdc, resvalutf8); + pdc_error(pdc, PDC_E_RES_BADRES, resname, category, 0, 0); + } + + if (resvalutf8 != NULL) + { + pdc_free(pdc, resvalutf8); + resvalutf8 = NULL; + } + + /* file name check */ + if (resnamutf8 != NULL && strlen(resnamutf8)) + { + resnamutf8 = pdc_check_filename(pdc, resnamutf8); + } + else + { + /* delete all entries */ + if (resnamutf8 != NULL) + pdc_free(pdc, resnamutf8); + pdc_delete_rescategory(pdc, lastcat, cat, pdc_true); + + pdc_logg_cond(pdc, 1, trc_resource, + "\tResource category \"%s\" removed\n", category); + + return; + } + } + break; + + case pdc_StandardOutputIntent: + break; + } + + /* Find resource name in resource list */ + lastres = NULL; + for (res = cat->kids; res != NULL; res = res->next) + { + if (!strcmp(res->name, resnamutf8)) + break; + lastres = res; + } + + /* New resource */ + if (res == NULL) + { + res = (pdc_res *) pdc_calloc(pdc, sizeof(pdc_res), fn); + if (lastres) + lastres->next = res; + else + cat->kids = res; + res->prev = lastres; + res->name = resnamutf8; + } + else + { + pdc_free(pdc, resnamutf8); + } + + /* New value */ + if (res->value) + pdc_free(pdc, res->value); + res->value = resvalutf8; + + if (res->value && strlen(res->value)) + pdc_logg_cond(pdc, 1, trc_resource, + "\tNew category.resource: \"%s.%s = %s\"\n", + category, res->name, res->value); + else + pdc_logg_cond(pdc, 1, trc_resource, + "\tNew category.resource: \"%s.%s\"\n", + category, res->name); +} + +void +pdc_add_resource(pdc_core *pdc, const char *category, const char *resname, + const char *resvalue) +{ + pdc_add_resource_ext(pdc, category, resname, resvalue, pdc_invalidenc, 0); +} + +const char * +pdc_find_resource(pdc_core *pdc, const char *category, const char *name) +{ + pdc_reslist *resl = pdc_get_reslist(pdc); + pdc_category *cat; + pdc_res *res; + + /* Read resource configuration file if it is pending */ + if (resl->filepending) + { + resl->filepending = pdc_false; + pdc_read_resourcefile(pdc, resl->filename); + } + + for (cat = resl->resources; cat != (pdc_category *) NULL; cat = cat->next) + { + if (!pdc_stricmp(cat->category, category)) + { + for (res = cat->kids; res != (pdc_res *)NULL; res = res->next) + { + if (!strcmp(res->name, name)) + { + if (pdc_logg_is_enabled(pdc, 1, trc_resource)) + { + const char *resval = res->name, *separ = ""; + + if (res->value && strlen(res->value)) + { + resval = res->value; + separ = " = "; + } + + pdc_logg(pdc, + "\tFound category.resource: \"%s.%s%s%s\"\n", + category, res->name, separ, resval); + } + + return res->value; + } + } + } + } + + return NULL; +} + +const char * +pdc_find_resource_nr(pdc_core *pdc, const char *category, int nr) +{ + pdc_reslist *resl = pdc_get_reslist(pdc); + pdc_category *cat; + pdc_rescategory rescat; + pdc_res *res; + int n = 0; + + /* Read resource configuration file if it is pending */ + if (resl->filepending) + { + resl->filepending = pdc_false; + pdc_read_resourcefile(pdc, resl->filename); + } + + rescat = (pdc_rescategory) pdc_get_keycode_ci(category, pdc_rescategories); + + for (cat = resl->resources; cat != (pdc_category *) NULL; cat = cat->next) + { + if (!pdc_stricmp(cat->category, category)) + { + for (res = cat->kids; res != (pdc_res *)NULL; res = res->next) + { + n++; + if (n == nr) + { + char *resname = (char *) "", *resval = res->name; + const char *separ = "", *retval; + pdc_bool tobefree = pdc_false; + + if (res->value && strlen(res->value)) + { + resname = res->name; + resval = res->value; + separ = "="; + } + + pdc_logg_cond(pdc, 1, trc_resource, + "\tFound %d. category.resource: " + "\"%s.%s%s%s\"\n", + nr, category, resname, separ, resval); + + /* conversion of host encoded file names back to UTF-8 */ + switch (rescat) + { + case pdc_StandardOutputIntent: + break; + + default: + resval = pdc_get_filename(pdc, resval); + tobefree = pdc_true; + break; + } + + retval = + pdc_errprintf(pdc, "%s%s%s", resname, separ, resval); + + if (tobefree) + pdc_free(pdc, resval); + + return retval; + } + } + } + } + + return ""; +} + + +/* ----------------------- virtual file handling ---------------------------- */ + +struct pdc_virtfile_s +{ + char *name; + const void *data; + size_t size; + pdc_bool iscopy; + int lockcount; + pdc_virtfile *next; +}; + +static pdc_virtfile * +pdc_find_pvf(pdc_core *pdc, const char *filename, pdc_virtfile **lastvfile) +{ + pdc_virtfile *vfile; + pdc_virtfile *filesystem = pdc->filesystem; + + if (lastvfile != NULL) + *lastvfile = NULL; + for (vfile = filesystem; vfile != NULL; vfile = vfile->next) + { + if (!strcmp(vfile->name, filename)) + { + pdc_logg_cond(pdc, 1, trc_filesearch, + "\n\tVirtual file \"%s\" found\n", filename); + return vfile; + } + if (lastvfile != NULL) + *lastvfile = vfile; + } + return NULL; +} + +/* definitions of pvf options */ +static const pdc_defopt pdc_create_pvf_options[] = +{ + {"copy", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + PDC_OPT_TERMINATE +}; + +void +pdc__create_pvf(pdc_core *pdc, const char *filename, + const void *data, size_t size, const char *optlist) +{ + static const char fn[] = "pdc__create_pvf"; + pdc_bool iscopy = pdc_false; + pdc_virtfile *vfile, *lastvfile = NULL; + pdc_resopt *results; + + if (!data) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, "data", 0, 0, 0); + + if (!size) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, "size", 0, 0, 0); + + /* Parse optlist */ + results = pdc_parse_optionlist(pdc, optlist, pdc_create_pvf_options, + NULL, pdc_true); + pdc_get_optvalues("copy", results, &iscopy, NULL); + pdc_cleanup_optionlist(pdc, results); + + /* Find virtual file in file system */ + vfile = pdc_find_pvf(pdc, filename, &lastvfile); + + /* Name already exists */ + if (vfile != NULL) + pdc_error(pdc, PDC_E_PVF_NAMEEXISTS, filename, 0, 0, 0); + + /* New virtual file */ + vfile = (pdc_virtfile *) pdc_calloc(pdc, sizeof(pdc_virtfile), fn); + if (lastvfile) + lastvfile->next = vfile; + else + pdc->filesystem = vfile; + + /* Fill up file struct */ + vfile->name = pdc_strdup(pdc, filename); + if (iscopy == pdc_true) + { + vfile->data = (const void *) pdc_malloc(pdc, size, fn); + memcpy((void *) vfile->data, data, size); + } + else + { + vfile->data = data; + } + vfile->size = size; + vfile->iscopy = iscopy; + vfile->lockcount = 0; + vfile->next = NULL; + + pdc_logg_cond(pdc, 1, trc_filesearch, + "\n\tVirtual file \"%s\" created\n", filename); +} + +int +pdc__delete_pvf(pdc_core *pdc, const char *filename) +{ + pdc_virtfile *vfile, *lastvfile = NULL; + + /* Find virtual file in file system */ + vfile = pdc_find_pvf(pdc, filename, &lastvfile); + if (vfile) + { + /* File exists but locked */ + if (vfile->lockcount > 0) + { + return pdc_undef; + } + + /* Delete */ + if (vfile->iscopy == pdc_true) + { + pdc_free(pdc, (void *) vfile->data); + vfile->data = NULL; + } + pdc_free(pdc, vfile->name); + if (lastvfile) + lastvfile->next = vfile->next; + else + pdc->filesystem = vfile->next; + pdc_free(pdc, vfile); + + pdc_logg_cond(pdc, 1, trc_filesearch, + "\tVirtual file \"%s\" deleted\n", filename); + } + + return pdc_true; +} + +void +pdc_lock_pvf(pdc_core *pdc, const char *filename) +{ + pdc_virtfile *vfile = pdc_find_pvf(pdc, filename, NULL); + if (vfile) + { + (vfile->lockcount)++; + + pdc_logg_cond(pdc, 1, trc_filesearch, + "\tVirtual file \"%s\" locked\n", filename); + } +} + +void +pdc_unlock_pvf(pdc_core *pdc, const char *filename) +{ + pdc_virtfile *vfile = pdc_find_pvf(pdc, filename, NULL); + if (vfile) + { + (vfile->lockcount)--; + + pdc_logg_cond(pdc, 1, trc_filesearch, + "\tVirtual file \"%s\" unlocked\n", filename); + } +} + +void +pdc_delete_filesystem(pdc_core *pdc) +{ + pdc_virtfile *vfile, *nextvfile; + pdc_virtfile *filesystem = pdc->filesystem; + + for (vfile = filesystem; vfile != NULL; /* */) + { + nextvfile = vfile->next; + if (vfile->iscopy == pdc_true && vfile->data) + pdc_free(pdc, (void *) vfile->data); + if (vfile->name) + pdc_free(pdc, vfile->name); + pdc_free(pdc, vfile); + vfile = nextvfile; + } + pdc->filesystem = NULL; +} + + +/* ------------------------ file search handling ---------------------------- */ + +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma unmanaged +#endif +pdc_file * +pdc_fsearch_fopen(pdc_core *pdc, const char *filename, char *fullname, + const char *qualifier, int flags) +{ + pdc_reslist *resl = pdc_get_reslist(pdc); + char fullname_s[PDC_FILENAMELEN]; + const pdc_byte *data = NULL; + pdc_file *sfp = NULL; + size_t size = 0; + pdc_virtfile *vfile; + + if (fullname == NULL) + fullname = fullname_s; + strcpy(fullname, filename); + + vfile = pdc_find_pvf(pdc, filename, NULL); + if (vfile) + { + size = vfile->size; + data = (const pdc_byte *) vfile->data; + sfp = pdc_fopen(pdc, filename, qualifier, data, size, flags); + } + else + { + pdc_category *cat; + + /* Bad filename */ + if (!*filename || !strcmp(filename, ".") || !strcmp(filename, "..")) + { + pdc_set_errmsg(pdc, PDC_E_IO_ILLFILENAME, filename, 0, 0, 0); + return NULL; + } + + + /* Read resource configuration file if it is pending */ + if (resl->filepending) + { + resl->filepending = pdc_false; + pdc_read_resourcefile(pdc, resl->filename); + } + + pdc_logg_cond(pdc, 1, trc_filesearch, + "\n\tSearching for file \"%s\":\n", filename); + + /* Searching resource category */ + for (cat = resl->resources; + cat != (pdc_category *) NULL; + cat = cat->next) + if (!pdc_stricmp(cat->category, "SearchPath")) break; + + if (!cat) + { + /* No resource category */ + sfp = pdc_fopen(pdc, filename, qualifier, NULL, 0, flags); + } + else + { + pdc_res *res = cat->kids; + pdc_res *lastres = cat->kids; + char *pathname = NULL; + FILE *fp = NULL; + int errnum = PDC_E_IO_RDOPEN_NF; + pdc_bool fatal = pdc_false; + + /* Find last SearchPath entry */ + while (res != (pdc_res *) NULL) + { + lastres = res; + res = res->next; + } + + /* First local search and then search with concatenated + * filename with search paths one after another backwards + */ + while (1) + { + /* Test opening */ + pdc_file_fullname(pathname, filename, fullname); + + if (pathname != NULL) + pdc_logg_cond(pdc, 1, trc_filesearch, + "\tin directory \"%s\": \"%s\"\n", pathname, fullname); + + fp = pdc_fopen_logg(pdc, fullname, READBMODE); + if (fp) + { + /* File found */ + pdc_fclose_logg(pdc, fp); + sfp = pdc_fopen(pdc, fullname, qualifier, NULL, 0,flags); + break; + } + errnum = pdc_get_fopen_errnum(pdc, PDC_E_IO_RDOPEN); + if (errno != 0 && errnum != PDC_E_IO_RDOPEN_NF) + { + fatal = pdc_true; + pdc_set_fopen_errmsg(pdc, PDC_E_IO_RDOPEN, + qualifier, fullname); + } + +#if defined(WIN32) + /* file name beginning with a drive letter: 'x:' + * is already full specified. + */ + if (pdc_isalpha(filename[0]) && filename[1] == ':') + break; +#endif + + if (lastres == (pdc_res *) NULL) + break; + + pathname = lastres->name; + lastres = lastres->prev; + } + + if (sfp == NULL && !fatal) + pdc_set_fopen_errmsg(pdc, PDC_E_IO_RDOPEN, + qualifier, filename); + else + filename = fullname; + } + } + + pdc_logg_cond(pdc, 1, trc_filesearch, + "\tFile \"%s\" %sfound\n", fullname, sfp == NULL ? "not " : ""); + return sfp; +} +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma managed +#endif + + +/* ----------------------- logging file handling ---------------------------- */ + +# ifndef DEFAULTLOGFILE +# if defined(MVS) +# define DEFAULTLOGFILE "pdflog" +# elif defined(MAC) || defined(AS400) +# define DEFAULTLOGFILE "/%s.log" +# elif defined(WIN32) +# define DEFAULTLOGFILE "\\%s.log" +# else +# define DEFAULTLOGFILE "/tmp/%s.log" +# endif +# endif + +#define LOGFILEENVNAME "%sLOGFILE" +#define LOGGINGENVNAME "%sLOGGING" + +#define PDC_CLASSLIST_SIZE 32 +#define PDC_CLASSLIST_MAX 10 + +struct pdc_loggdef_s +{ + pdc_bool enabled; /* logging enabled */ + char *filename; /* name of the logging file */ + pdc_bool fromenviron; /* logging file name defined environment */ + pdc_bool header; /* with header and separation line */ + pdc_bool flush; /* logging file will be opened and + * and closed immediately */ + FILE *fp; /* flush = false: file handle */ + pdc_strform_kind strform; /* format for logging strings */ + int maxchar; /* maximal number of characters + * of logging strings */ + int sri; /* first index in classlist for save/restore */ + char classlist[PDC_CLASSLIST_MAX][PDC_CLASSLIST_SIZE]; + /* list array of levels for logging classes */ + pdc_bool classapi; /* only api class has level = 1 + * and warning class has level = 1 */ +}; + +static pdc_loggdef * +pdc_new_logg(pdc_core *pdc) +{ + static const char fn[] = "pdc_new_logg"; + char envname[32]; + const char *envval = NULL; + + pdc_loggdef *logg = (pdc_loggdef *) + pdc_malloc(pdc, sizeof(pdc_loggdef), fn); + + logg->enabled = pdc_false; + logg->filename = NULL; + logg->fromenviron = pdc_false; + logg->header = pdc_true; + logg->flush = pdc_false; + logg->fp = NULL; + logg->strform = strform_readable; + logg->maxchar = 0; + logg->sri = 0; + memset(logg->classlist[0], 0, PDC_CLASSLIST_SIZE); + logg->classlist[0][trc_api] = 1; + logg->classlist[0][trc_warning] = 1; + logg->classapi = pdc_true; + + pdc->logg = logg; + + /* logging file name defined by environment variable */ + sprintf(envname, LOGFILEENVNAME, pdc->prodname); + pdc_strtoupper(envname); + envval = pdc_getenv(envname); + if (envval != NULL) + { + logg->filename = pdc_strdup(pdc, envval); + logg->fromenviron = pdc_true; + } + + return logg; +} + +void +pdc_delete_logg(pdc_core *pdc) +{ + if (pdc->logg != NULL) + { + pdc_loggdef *logg = pdc->logg; + + logg->enabled = pdc_false; + + /* close file */ + if (logg->fp != NULL && logg->fp != stdout && logg->fp != stderr) + { + fclose(logg->fp); + logg->fp = NULL; + } + + if (logg->filename != NULL) + { + pdc_free(pdc, logg->filename); + logg->filename = NULL; + } + + pdc_free(pdc, logg); + pdc->logg = NULL; + } +} + +static pdc_loggdef * +pdc_get_logg(pdc_core *pdc) +{ + pdc_loggdef *logg = pdc->logg; + + if (logg == NULL) + logg = pdc_new_logg(pdc); + + return logg; +} + +static const pdc_keyconn pdc_strform_keylist[] = +{ + {"readable", strform_readable}, + {"readable0", strform_readable0}, + {"octal", strform_octal}, + {"hex", strform_hexa}, + {"java", strform_java}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_protoclass_keylist[] = +{ + {"api", trc_api}, + {"encoding", trc_encoding}, + {"digsig", trc_digsig}, + {"filesearch", trc_filesearch}, + {"font", trc_font}, + {"image", trc_image}, + {"memory", trc_memory}, + {"optlist", trc_optlist}, + {"other", trc_other}, + {"pcos", trc_pcos}, + {"pdi", trc_pdi}, + {"resource", trc_resource}, + {"shadow", trc_shadow}, + {"table", trc_table}, + {"text", trc_text}, + {"textflow", trc_textflow}, + {"user", trc_user}, + {"warning", trc_warning}, + {"wordfinder", trc_wordfinder}, + {"xmp", trc_xmp}, + {"zones", trc_zones}, + {NULL, 0} +}; + +#define PDC_FILENAMELEN 1024 + +static const pdc_defopt pdc_logg_options[] = +{ + {"header", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"enable", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"disable", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"flush", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"remove", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"filename", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_FILENAMELEN, NULL}, + + {"restore", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"save", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"stringformat", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdc_strform_keylist}, + + {"stringlimit", pdc_integerlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"classes", pdc_stringlist, PDC_OPT_EVENNUM |PDC_OPT_SUBOPTLIST, + 1, 2 * PDC_CLASSLIST_SIZE, 1.0, 64, NULL}, + + PDC_OPT_TERMINATE +}; + +static const char *separstr = + "[ --------------------------------------------------------- ]\n"; + +void +pdc_set_logg_options(pdc_core *pdc, const char *optlist) +{ + pdc_loggdef *logg = pdc_get_logg(pdc); + pdc_resopt *resopts = NULL; + char **strlist, *keyword; + char filename[PDC_FILENAMELEN+1]; + pdc_bool sare = pdc_false; + pdc_bool enable = pdc_true; + pdc_bool remfile = pdc_false; + pdc_char level; + int inum, i, pclass = 0, sumlevel = 0; + + filename[0] = 0; + if (optlist && strlen(optlist)) + { + resopts = pdc_parse_optionlist(pdc, optlist, pdc_logg_options, + NULL, pdc_true); + + if (pdc_get_optvalues("save", resopts, &sare, NULL) && sare) + { + i = logg->sri + 1; + if (i >= PDC_CLASSLIST_MAX) + pdc_error(pdc, PDC_E_INT_TOOMUCH_SARE, 0, 0, 0, 0); + memcpy(logg->classlist[i], logg->classlist[logg->sri], + PDC_CLASSLIST_SIZE); + logg->sri = i; + } + + if (pdc_get_optvalues("restore", resopts, &sare, NULL) && sare) + { + i = logg->sri - 1; + if (i < 0) + pdc_error(pdc, PDC_E_INT_TOOMUCH_SARE, 0, 0, 0, 0); + logg->sri = i; + } + + if (pdc_get_optvalues("disable", resopts, &inum, NULL)) + enable = inum ? pdc_false : pdc_true; + + pdc_get_optvalues("header", resopts, &logg->header, NULL); + + pdc_get_optvalues("flush", resopts, &logg->flush, NULL); + + pdc_get_optvalues("remove", resopts, &remfile, NULL); + + if (!logg->fromenviron) + pdc_get_optvalues("filename", resopts, filename, NULL); + + if (pdc_get_optvalues("stringformat", resopts, &inum, NULL)) + logg->strform = (pdc_strform_kind) inum; + + pdc_get_optvalues("stringlimit", resopts, &logg->maxchar, NULL); + + inum = pdc_get_optvalues("classes", resopts, NULL, &strlist); + if (inum) + { + for (i = 0; i < inum; i++, i++) + { + if (!pdc_stricmp(strlist[i], "other")) + { + i++; + if (pdc_str2integer(strlist[i], + PDC_INT_CHAR | PDC_INT_UNSIGNED, + &level)) + { + memset(logg->classlist[logg->sri], (int)level, + PDC_CLASSLIST_SIZE); + } + break; + } + } + for (i = 0; i < inum; i++) + { + keyword = strlist[i]; + pclass = pdc_get_keycode_ci(keyword, pdf_protoclass_keylist); + if (pclass == PDC_KEY_NOTFOUND) + pdc_error(pdc, PDC_E_OPT_ILLKEYWORD, + "classes", keyword, 0, 0); + i++; + if (!pdc_str2integer(strlist[i], + PDC_INT_CHAR | PDC_INT_UNSIGNED, + &level)) + pdc_error(pdc, PDC_E_OPT_ILLINTEGER, + keyword, strlist[i], 0, 0); + + logg->classlist[logg->sri][pclass] = level; + } + + for (i = 0; i < PDC_CLASSLIST_SIZE; i++) + sumlevel += (int) logg->classlist[logg->sri][i]; + logg->classapi = + (sumlevel == 2 && + logg->classlist[logg->sri][trc_api] && + logg->classlist[logg->sri][trc_warning]) ? + pdc_true : pdc_false; + } + + pdc_cleanup_optionlist(pdc, resopts); + } + + /* disable */ + if (logg->enabled && logg->header && !enable) + { + pdc_logg(pdc, "\n"); + pdc_logg(pdc, separstr); + } + + /* no new logging file name specified */ + if (!strlen(filename)) + { + if (logg->filename == NULL) + { + char tmpname[PDC_FILENAMELEN]; + + sprintf(tmpname, DEFAULTLOGFILE, pdc->prodname); + pdc_strtolower(tmpname); + strcpy(filename, tmpname); + } + else + { + strcpy(filename, logg->filename); + } + } + + /* new logging file */ + if (logg->filename == NULL || strcmp(logg->filename, filename)) + { + pdc_time ltime; + + /* close file */ + if (logg->fp != stdout && logg->fp != stderr && logg->filename) + { + pdc_localtime(<ime); + pdc_logg(pdc, "[%04d-%02d-%02d %02d:%02d:%02d]\n", + ltime.year + 1900, ltime.month + 1, ltime.mday, + ltime.hour, ltime.minute, ltime.second); + if (logg->fp != NULL) + fclose(logg->fp); + } + logg->enabled = pdc_false; + + /* remove file */ + if (remfile && strcmp(filename, "stdout") && strcmp(filename, "stderr")) + remove(filename); + + /* file name */ + if (logg->filename != NULL) + pdc_free(pdc, logg->filename); + logg->filename = pdc_strdup(pdc, filename); + + /* open file */ + if (!logg->flush) + { + if (!strcmp(logg->filename, "stdout")) + logg->fp = stdout; + else if (!strcmp(logg->filename, "stderr")) + logg->fp = stderr; + else + logg->fp = fopen(logg->filename, APPENDMODE); + if (logg->fp == NULL) + { + pdc_error(pdc, PDC_E_IO_WROPEN, "log ", logg->filename, + 0, 0); + } + } + else + { + logg->fp = NULL; + } + + + /* header line */ + logg->enabled = enable; + if (logg->enabled && logg->header && pdc->prodname != NULL) + { + char binding[64]; + + pdc_localtime(<ime); + binding[0] = 0; + if (pdc->binding) + { + strcat(binding, pdc->binding); + strcat(binding, " binding "); + } + pdc_logg(pdc, separstr); + pdc_logg(pdc, "[ %s %s %son %s (%s) ", + pdc->prodname, pdc->version, binding, + PDF_PLATFORM, PDC_ISBIGENDIAN ? "be" : "le"); + pdc_logg(pdc, "%04d-%02d-%02d %02d:%02d:%02d ]\n", + ltime.year + 1900, ltime.month + 1, ltime.mday, + ltime.hour, ltime.minute, ltime.second); + + if (logg->classapi) + pdc_logg(pdc, "[ Use %%s/\\[[^]]*\\]//g and %%s/)$/);" + "/ in vi to compile it ]\n"); + pdc_logg(pdc, separstr); + } + } + else + { + logg->enabled = enable; + } +} + +const char * +pdc_print_loggstring(pdc_core *pdc, const char *str, int len) +{ + if (pdc->logg != NULL && pdc->logg->enabled) + { + + str = pdc_strprint(pdc, str, len, pdc->logg->maxchar, + pdc->logg->strform); + + + return str; + } + else + return ""; +} + +/* logging function without any class level check and decorations + */ +static void +pdc_logg_output(pdc_core *pdc, const char *fmt, va_list ap) +{ + pdc_loggdef *logg = pdc->logg; + + if (logg->flush) + { + FILE *fp = NULL; + + if (!strcmp(logg->filename, "stdout")) + fp = stdout; + else if (!strcmp(logg->filename, "stderr")) + fp = stderr; + else + fp = fopen(logg->filename, APPENDMODE); + + if (fp == NULL) + { + logg->enabled = pdc_false; + pdc_error(pdc, PDC_E_IO_WROPEN, "log ", logg->filename, + 0, 0); + } + + pdc_vfprintf(pdc, pdc_false, fp, fmt, ap); + + if (fp != stdout && fp != stderr) + fclose(fp); + } + else + { + pdc_vfprintf(pdc, pdc_false, logg->fp, fmt, ap); + fflush(logg->fp); + } +} + + +/* standard logging protocol functions for api function calls + */ +pdc_bool +pdc_enter_api_logg(pdc_core *pdc, const char *funame, pdc_bool enter_api, + const char *fmt, va_list args) +{ + pdc_bool retval = pdc_true; + + if (enter_api) + retval = pdc_enter_api(pdc, funame); + + if (retval) + { + /* logging option list defined by environment variable */ + if (pdc->loggenv == pdc_false) + { + char envname[32]; + const char *envval = NULL; + + pdc->loggenv = pdc_true; + sprintf(envname, LOGGINGENVNAME, pdc->prodname); + pdc_strtoupper(envname); + envval = pdc_getenv(envname); + if (envval != NULL) + { + pdc_set_logg_options(pdc, envval); + } +#if defined(WIN32) + else + { + char buffer[BUFSIZE]; + char regkey[128]; + HKEY hKey = NULL; + DWORD size, lType; + + sprintf(regkey, REGISTRYKEY, pdc->prodname, pdc->version); + + /* process registry entries */ + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0L, + (REGSAM) KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + size = BUFSIZE - 2; + pdc_strtolower(envname); + if (RegQueryValueExA(hKey, envname, (LPDWORD) NULL, + &lType, (LPBYTE) buffer, &size) + == ERROR_SUCCESS && *buffer) + { + pdc_set_logg_options(pdc, buffer); + } + + RegCloseKey(hKey); + } + } + #endif + } + + if (pdc->logg != NULL && + pdc->logg->enabled && + pdc->logg->classlist[pdc->logg->sri][trc_api]) + { + /* time stamp */ + if (pdc->logg->classlist[pdc->logg->sri][trc_api] > 1) + { + pdc_time ltime; + + if (funame[0] == '\n') + { + pdc_logg(pdc, "\n"); + funame++; + } + + pdc_localtime(<ime); + pdc_logg(pdc, "[%02d:%02d:%02d] ", + ltime.hour, ltime.minute, ltime.second); + } + + /* function name */ + pdc_logg(pdc, "%s", funame); + + /* function arg list */ + pdc_logg_output(pdc, fmt, args); + } + } + + return retval; +} + +void +pdc_logg_exit_api(pdc_core *pdc, pdc_bool cleanup, const char *fmt, ...) +{ + if (fmt != NULL && pdc != NULL && + pdc->logg != NULL && + pdc->logg->enabled && + pdc->logg->classlist[pdc->logg->sri][trc_api]) + { + va_list ap; + + va_start(ap, fmt); + pdc_logg_output(pdc, fmt, ap); + va_end(ap); + } + + if (cleanup) + pdc_tmlist_cleanup(pdc); +} + +/* + * General logging functions + */ + +/* + * pdc_logg_enable() enables/disables logging + */ +void +pdc_logg_enable(pdc_core *pdc, pdc_bool enable) +{ + if (pdc != NULL && pdc->logg != NULL) + pdc->logg->enabled = enable; +} + +/* + * pdc_logg_is_enabled() returns pdc_true + * if logging is enabled for logging class 'pclass' and level 'level'. + * Otherwise pdc_false will be returned. + */ +pdc_bool +pdc_logg_is_enabled(pdc_core *pdc, int level, int pclass) +{ + return pdc->logg != NULL && + pdc->logg->enabled && + level <= pdc->logg->classlist[pdc->logg->sri][pclass]; +} + + +/* + * pdc_logg() writes formatted text in the current logging file + * without checking whether logging is enabled. + * This function should only be used in connection with + * pdc_logg_is_enabled(): + */ +void +pdc_logg(pdc_core *pdc, const char *fmt, ...) +{ + if (pdc != NULL && pdc->logg != NULL && pdc->logg->enabled) + { + va_list ap; + + va_start(ap, fmt); + pdc_logg_output(pdc, fmt, ap); + va_end(ap); + } +} + +/* + * pdc_logg_cond() writes formatted text in the current logging file + * if logging is enabled for logging class 'pclass' and level 'level'. + */ +void +pdc_logg_cond(pdc_core *pdc, int level, int pclass, const char *fmt, ...) +{ + if (pdc != NULL && pdc->logg != NULL && + pdc->logg->enabled && + level <= pdc->logg->classlist[pdc->logg->sri][pclass]) + { + va_list ap; + + va_start(ap, fmt); + pdc_logg_output(pdc, fmt, ap); + va_end(ap); + } +} + + +/* + * pdc_logg_getlevel() returns the current level for a logging class + */ +int +pdc_logg_getlevel(pdc_core *pdc, int pclass) +{ + if (pdc->logg != NULL && pdc->logg->enabled) + return (int) pdc->logg->classlist[pdc->logg->sri][pclass]; + else + return 0; +} + +/* + * pdc_logg_bitarr() writes the literal representation of a bit array + (including a descriptive message) in 1 line in the current logging file. + variable nbit must be <=32. + */ +void +pdc_logg_bitarr(pdc_core *pdc, const char *msg, const char *bitarr, int nbit) +{ + int i; + + pdc_logg(pdc,"%s = ", msg); + + nbit = MIN(nbit, 32); + for (i = 0; i <= nbit; i++) + { + if (!(i%8)) + { + pdc_logg(pdc, "|"); + } + if (i == nbit) + { + if (nbit == 8) + pdc_logg(pdc, " (%02X)", bitarr[0]); + else if (nbit == 16) + pdc_logg(pdc, " (%04X)", *((pdc_uint16 *) &bitarr[0])); + else if (nbit == 32) + pdc_logg(pdc, " (%08X)", *((pdc_uint32 *) &bitarr[0])); + pdc_logg(pdc, "\n"); + } + else + { + pdc_logg(pdc, "%s", pdc_getbit(bitarr, i) ? "1" : "0"); + } + } +} + + +/* + * pdc_logg_hexdump() writes the hexadecimal output of the specified buffer + (including a descriptive message) in the current logging file. + */ +void +pdc_logg_hexdump(pdc_core *pdc, const char *msg, const char *prefix, + const char *text, int tlen) +{ + int i, k; + pdc_byte ct; + + if (tlen == 1) + { + ct = (pdc_byte) text[0]; + pdc_logg(pdc, "%s%s: %02X '%c'\n", prefix, msg, ct, + pdc_logg_isprint((int) ct) ? ct : '.'); + } + else + { + pdc_logg(pdc,"%s%s:\n", prefix, msg); + + for (i = 0; i < tlen; i += 16) + { + pdc_logg(pdc,"%s", prefix); + for (k = 0; k < 16; ++k) + { + if (i + k < tlen) + { + ct = (pdc_byte) text[i + k]; + pdc_logg(pdc,"%02X ", ct); + } + else + pdc_logg(pdc," "); + } + + pdc_logg(pdc," "); + for (k = 0; k < 16; ++k) + { + if (i + k < tlen) + { + ct = (pdc_byte) text[i + k]; + pdc_logg(pdc,"%c", pdc_logg_isprint((int)ct) ? ct : '.'); + } + else + pdc_logg(pdc," "); + } + + pdc_logg(pdc,"\n"); + } + } +} + +/* + * pdc_warning() is the former function of PDFlib exception handling. + * Now, pdc_warning() calls the function pdc_set_warnmsg(), which writes + * only a warning message generated from a xx_generr.h file into the logfile, + * if warning = 1. + */ +void +pdc_warning(pdc_core *pdc, int errnum, const char *parm1, const char *parm2, + const char *parm3, const char *parm4) +{ + if (!pdc->smokerun) + pdc_set_warnmsg(pdc, errnum, parm1, parm2, parm3, parm4); +} + +/* + * utility function for logging a Unicode character + * + */ +void +pdc_logg_unichar(pdc_core *pdc, int unichar, pdc_bool kfill, pdc_bool newline) +{ + if (unichar > 0xFFFF) + { + pdc_logg(pdc, "U+%05X", unichar); + } + else + { + pdc_logg(pdc, "U+%04X", unichar); + + if ((unichar >= PDC_UNICODE_SPACE && unichar <= PDC_UNICODE_DELETE) || + (unichar >= PDC_UNICODE_NBSP && unichar <= PDC_UNICODE_MAXLATIN1)) + { + char c = (char) unichar; + + + pdc_logg(pdc, " [%c]", c); + } + else if (kfill) + { + pdc_logg(pdc, " "); + } + } + + if (newline) + pdc_logg(pdc, "\n"); +} + +/* + * utility function for logging a Unicode string + * + */ +static const pdc_keyconn pdc_ascii_escape_keylist[] = +{ + {"a", 0x07}, + {"b", 0x08}, + {"e", 0x1B}, + {"f", 0x0C}, + {"n", 0x0A}, + {"r", 0x0D}, + {"t", 0x09}, + {"v", 0x0B}, + {NULL, 0} +}; + +void +pdc_logg_unitext(pdc_core *pdc, pdc_ushort *ustext, int len, pdc_bool newline) +{ + int i; + pdc_ushort usv; + const char *s; + char c; + + pdc_logg(pdc, "\""); + for (i = 0; i < len; i++) + { + usv = ustext[i]; + if (usv > PDC_UNICODE_MAXLATIN1) + { + pdc_logg(pdc, "\\u%04X", usv); + } + else + { + if (usv < PDC_UNICODE_SPACE) + { + s = pdc_get_keyword((int) usv, pdc_ascii_escape_keylist); + if (s != NULL) + { + pdc_logg(pdc, "\\%s", s); + continue; + } + } + + if ((usv >= PDC_UNICODE_SPACE && usv <= PDC_UNICODE_DELETE) || + (usv >= PDC_UNICODE_NBSP && usv <= PDC_UNICODE_MAXLATIN1)) + { + c = (char) usv; + + + pdc_logg(pdc, "%c", c); + } + else + { + pdc_logg(pdc, "\\x%02X", usv); + } + } + } + + pdc_logg(pdc, "\""); + if (newline) + pdc_logg(pdc, "\n"); +} + + diff --git a/src/pdflib/pdcore/pc_resource.h b/src/pdflib/pdcore/pc_resource.h new file mode 100644 index 0000000..f83498c --- /dev/null +++ b/src/pdflib/pdcore/pc_resource.h @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_resource.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Resource routines + * + */ + +#ifndef PC_RESOURCE_H +#define PC_RESOURCE_H + +/* pdcore logg classes (maximal PDC_CLASSLIST_SIZE) */ +typedef enum +{ + trc_other = 0, /* other classes */ + trc_api, /* API function call logging */ + trc_encoding, /* encoding, cmap end textformat logging */ + trc_digsig, /* digital signatures */ + trc_filesearch, /* file search logging */ + trc_font, /* font logging */ + trc_image, /* image and template logging */ + trc_memory, /* memory logging */ + trc_optlist, /* optlist logging */ + trc_pcos, /* pcos logging */ + trc_pdi, /* pdi logging */ + trc_resource, /* resource logging */ + trc_shadow, /* shadow logging */ + trc_text, /* text logging */ + trc_textflow, /* textflow logging */ + trc_table, /* table logging */ + trc_user, /* user logging */ + trc_warning, /* logging of disabled warnings */ + trc_wordfinder, /* word finder logging */ + trc_xmp, /* xmp logging */ + trc_zones /* zones logging */ +} +pdc_logg_class; + +/* string code kinds */ +typedef enum +{ + strform_readable, + strform_readable0, + strform_octal, + strform_hexa, + strform_java +} +pdc_strform_kind; + + +typedef struct pdc_res_s pdc_res; +typedef struct pdc_category_s pdc_category; +typedef struct pdc_reslist_s pdc_reslist; +typedef struct pdc_virtfile_s pdc_virtfile; +typedef struct pdc_loggdef_s pdc_loggdef; + + +/* -------------------------- resource handling ----------------------------- */ + +pdc_reslist *pdc_new_reslist(pdc_core *pdc); +void pdc_delete_reslist(pdc_core *pdc); +void pdc_set_resourcefile(pdc_core *pdc, const char *filename); +void pdc_add_resource_ext(pdc_core *pdc, const char *category, + const char *resname, const char *resvalue, pdc_encoding enc, + int codepage); +void pdc_add_resource(pdc_core *pdc, const char *category, + const char *resname, const char *resvalue); +const char *pdc_find_resource(pdc_core *pdc, const char *category, + const char *name); +const char *pdc_find_resource_nr(pdc_core *pdc, const char *category, int nr); +const char *pdc_get_resourcefile(pdc_core *pdc); + + + +/* ----------------------- virtual file handling ---------------------------- */ + +void pdc__create_pvf(pdc_core *pdc, const char *filename, + const void *data, size_t size, const char *optlist); +int pdc__delete_pvf(pdc_core *pdc, const char *filename); +void pdc_lock_pvf(pdc_core *pdc, const char *filename); +void pdc_unlock_pvf(pdc_core *pdc, const char *filename); +void pdc_delete_filesystem(pdc_core *pdc); + + +/* ----------------------- logging file handling ---------------------------- */ + +void pdc_delete_logg(pdc_core *pdc); +void pdc_set_logg_options(pdc_core *pdc, const char *optlist); +const char *pdc_print_loggstring(pdc_core *pdc, const char *str, int len); +pdc_bool pdc_enter_api_logg(pdc_core *pdc, const char *funame, + pdc_bool enter_api, const char *fmt, va_list args); +void pdc_logg_exit_api(pdc_core *pdc, pdc_bool cleanup, + const char *fmt, ...); +void pdc_logg_enable(pdc_core *pdc, pdc_bool enable); +pdc_bool pdc_logg_is_enabled(pdc_core *pdc, int level, int pclass); +void pdc_logg(pdc_core *pdc, const char *fmt, ...); +void pdc_logg_cond(pdc_core *pdc, int level, int pclass, + const char *fmt, ...); +void pdc_logg_bitarr(pdc_core *pdc, const char *msg, const char *bitarr, + int nbit); +void pdc_logg_hexdump(pdc_core *pdc, const char *msg, const char *prefix, + const char *text, int tlen); +void pdc_warning(pdc_core *pdc, int errnum, const char *parm1, + const char *parm2, const char *parm3, const char *parm4); + +void pdc_logg_unichar(pdc_core *pdc, int unichar, pdc_bool kfill, + pdc_bool newline); +void pdc_logg_unitext(pdc_core *pdc, pdc_ushort *ustext, int len, + pdc_bool newline); + +int pdc_logg_getlevel(pdc_core *pdc, int pclass); + +#endif /* PC_RESOURCE_H */ + diff --git a/src/pdflib/pdcore/pc_scan.c b/src/pdflib/pdcore/pc_scan.c new file mode 100644 index 0000000..94e713a --- /dev/null +++ b/src/pdflib/pdcore/pc_scan.c @@ -0,0 +1,19 @@ +/*---------------------------------------------------------------------------* + | PDC -- PDF content stream parser | + +---------------------------------------------------------------------------+ + | Copyright (c) 2002 PDFlib GmbH. All rights reserved. | + *---------------------------------------------------------------------------* + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_scan.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ */ + + +#include "pc_util.h" +#include "pc_strconst.h" +#include "pc_ctype.h" +#include "pc_scan.h" + +#include "pc_string.h" + + diff --git a/src/pdflib/pdcore/pc_scan.h b/src/pdflib/pdcore/pc_scan.h new file mode 100644 index 0000000..1b31e54 --- /dev/null +++ b/src/pdflib/pdcore/pc_scan.h @@ -0,0 +1,15 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_scan.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ */ + +#ifndef PC_SCAN_H_INCLUDED +#define PC_SCAN_H_INCLUDED + + +#endif /* PC_SCAN_H_INCLUDED */ diff --git a/src/pdflib/pdcore/pc_scantok.h b/src/pdflib/pdcore/pc_scantok.h new file mode 100644 index 0000000..84420c9 --- /dev/null +++ b/src/pdflib/pdcore/pc_scantok.h @@ -0,0 +1,14 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | Proprietary source code -- do not redistribute! | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_scantok.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDCORE generic token scanner standard tokens. + * + */ + diff --git a/src/pdflib/pdcore/pc_scope.c b/src/pdflib/pdcore/pc_scope.c new file mode 100644 index 0000000..73daac2 --- /dev/null +++ b/src/pdflib/pdcore/pc_scope.c @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_scope.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Scoping routines and macros + * + */ + +#include "pc_util.h" +#include "pc_scope.h" +#include "pc_file.h" +#include "pc_ctype.h" + + +static void pdc_check_scope_core(void) {} + diff --git a/src/pdflib/pdcore/pc_scope.h b/src/pdflib/pdcore/pc_scope.h new file mode 100644 index 0000000..8c8a8f6 --- /dev/null +++ b/src/pdflib/pdcore/pc_scope.h @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_scope.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Scoping routines and macros + * + */ + +#ifndef PC_SCOPE_H +#define PC_SCOPE_H + + +#endif /* PC_SCOPE_H */ diff --git a/src/pdflib/pdcore/pc_strconst.h b/src/pdflib/pdcore/pc_strconst.h new file mode 100644 index 0000000..2e96842 --- /dev/null +++ b/src/pdflib/pdcore/pc_strconst.h @@ -0,0 +1,5 @@ +#ifndef PC_STRCONST_H_INCLUDED +#define PC_STRCONST_H_INCLUDED + +#endif /* PC_STRCONST_H_INCLUDED */ + diff --git a/src/pdflib/pdcore/pc_string.c b/src/pdflib/pdcore/pc_string.c new file mode 100644 index 0000000..f792ac1 --- /dev/null +++ b/src/pdflib/pdcore/pc_string.c @@ -0,0 +1,514 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_string.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * The core string classes. + * + */ + +#include + +#include "pc_util.h" +#include "pc_string.h" +#include "pc_ctype.h" + +#undef SBUF_RESERVE +#define SBUF_RESERVE PDC_STR_INLINE_CAP + + +/* TODO: + + - think over the pdcore temporary memory model. + + - s->buf should be reference-counted (delayed copy). +*/ + +void pdc_init_strings(pdc_core *pdc) +{ + pdc->bstr_pool = pdc_mp_new(pdc, sizeof (pdc_bstr)); + pdc->ustr_pool = pdc_mp_new(pdc, sizeof (pdc_ustr)); +} /* pdc_init_strings */ + +void pdc_cleanup_strings(pdc_core *pdc) +{ + pdc_mp_delete(pdc->bstr_pool); + pdc_mp_delete(pdc->ustr_pool); +} /* pdc_init_strings */ + + +/************************************************************************/ +/* */ +/* string object construction and deletion. */ +/* */ +/************************************************************************/ + +void +pdc_bs_boot(pdc_core *pdc, pdc_bstr *s) +{ + s->pdc = pdc; + s->buf = (pdc_byte *) 0; + s->len = 0; + s->cap = PDC_STR_INLINE_CAP; +} /* pdc_bs_boot */ + +void +pdc_us_boot(pdc_core *pdc, pdc_ustr *s) +{ + s->pdc = pdc; + s->buf = (pdc_ucval *) 0; + s->len = 0; + s->cap = PDC_STR_INLINE_CAP; +} /* pdc_us_boot */ + + +void +pdc_bs_shutdown(pdc_bstr *s) +{ + if (s->buf != (pdc_byte *) 0) + pdc_free(s->pdc, s->buf); + + pdc_bs_boot(s->pdc, s); +} /* pdc_bs_shutdown */ + +void +pdc_us_shutdown(pdc_ustr *s) +{ + if (s->buf != (pdc_ucval *) 0) + pdc_free(s->pdc, s->buf); + + pdc_us_boot(s->pdc, s); +} /* pdc_us_shutdown */ + + +#undef USE_POOL +#define USE_POOL + +pdc_bstr * +pdc_bs_new(pdc_core *pdc) +{ +#ifndef USE_POOL + static const char fn[] = "pdc_bs_new"; + + pdc_bstr *result = (pdc_bstr *) pdc_malloc(pdc, sizeof (pdc_bstr), fn); +#else + pdc_bstr *result = (pdc_bstr *) pdc_mp_alloc(pdc->bstr_pool); +#endif + + pdc_bs_boot(pdc, result); + return result; +} /* pdc_bs_new */ + +pdc_ustr * +pdc_us_new(pdc_core *pdc, const pdc_ucval *src, size_t len) +{ +#ifndef USE_POOL + static const char fn[] = "pdc_us_new"; + + pdc_ustr *result = (pdc_ustr *) pdc_malloc(pdc, sizeof (pdc_ustr), fn); +#else + pdc_ustr *result = (pdc_ustr *) pdc_mp_alloc(pdc->ustr_pool); +#endif + + pdc_us_boot(pdc, result); + pdc_us_write(result, src, len); + return result; +} /* pdc_us_new */ + + +pdc_bstr * +pdc_bs_dup(const pdc_bstr *src) +{ + const pdc_byte * buf = src->buf ? src->buf : src->buf0; + pdc_bstr * result = pdc_bs_new(src->pdc); + + pdc_bs_write(result, buf, src->len); + return result; +} /* pdc_bs_dup */ + +pdc_ustr * +pdc_us_dup(const pdc_ustr *src) +{ + const pdc_ucval *buf = src->buf ? src->buf : src->buf0; + + return pdc_us_new(src->pdc, buf, src->len); +} /* pdc_us_dup */ + + +void +pdc_bs_delete(pdc_bstr *s) +{ + pdc_bs_shutdown(s); +#ifndef USE_POOL + pdc_free(s->pdc, s); +#else + pdc_mp_free(s->pdc->bstr_pool, s); +#endif +} /* pdc_bs_delete */ + +void +pdc_us_delete(pdc_ustr *s) +{ + pdc_us_shutdown(s); +#ifndef USE_POOL + pdc_free(s->pdc, s); +#else + pdc_mp_free(s->pdc->ustr_pool, s); +#endif +} /* pdc_bs_delete */ + + +/************************************************************************/ +/* */ +/* "getters". */ +/* */ +/************************************************************************/ + +size_t +pdc_bs_length(const pdc_bstr *s) +{ + return s->len; +} /* pdc_bs_length */ + +size_t +pdc_us_length(const pdc_ustr *s) +{ + return s->len; +} /* pdc_us_length */ + + +pdc_byte +pdc_bs_get(const pdc_bstr *s, int idx) +{ + static const char fn[] = "pdc_bs_get"; + + const pdc_byte *buf = s->buf ? s->buf : s->buf0; + + if (idx < 0 || s->len <= (size_t) idx) + pdc_error(s->pdc, PDC_E_INT_ARRIDX, + pdc_errprintf(s->pdc, "%d", idx), fn, 0, 0); + + return buf[idx]; +} /* pdc_bs_get */ + +pdc_ucval +pdc_us_get(const pdc_ustr *s, int idx) +{ + static const char fn[] = "pdc_us_get"; + + const pdc_ucval *buf = s->buf ? s->buf : s->buf0; + + if (idx < 0 || s->len <= (size_t) idx) + pdc_error(s->pdc, PDC_E_INT_ARRIDX, + pdc_errprintf(s->pdc, "%d", idx), fn, 0, 0); + + return buf[idx]; +} /* pdc_us_get */ + + +const pdc_byte * +pdc_bs_get_cptr(const pdc_bstr *s) +{ + static const pdc_byte empty = 0; + + /* TODO: avoid the ugly "un-const" cast. */ + pdc_byte *buf = (pdc_byte *) (s->buf ? s->buf : s->buf0); + + if (!s->len) + return ∅ + + buf[s->len] = 0; + return buf; +} + +const pdc_byte * +pdc_us_get_cptr(const pdc_ustr *s) +{ + static const pdc_byte empty = 0; + + const pdc_ucval *buf = s->buf ? s->buf : s->buf0; + + if (!s->len) + return ∅ + + return (const pdc_byte *) buf; +} + + +/************************************************************************/ +/* */ +/* "modifiers". */ +/* */ +/************************************************************************/ + +void +pdc_bs_copy(pdc_bstr *dst, const pdc_bstr *src) +{ + const pdc_byte *buf = src->buf ? src->buf : src->buf0; + + dst->len = 0; + + if (src->len) + pdc_bs_write(dst, buf, src->len); +} /* pdc_bs_copy */ + +void +pdc_us_copy(pdc_ustr *dst, const pdc_ustr *src) +{ + const pdc_ucval *buf = src->buf ? src->buf : src->buf0; + + dst->len = 0; + + if (src->len) + pdc_us_write(dst, buf, src->len); +} /* pdc_us_copy */ + + +void +pdc_bs_substr(pdc_bstr *dst, const pdc_bstr *src, size_t pos, size_t len) +{ + static const char fn[] = "pdc_bs_substr"; + + const pdc_byte *buf = src->buf ? src->buf : src->buf0; + + if ((pos < 0) || (len < 0) || (pos > src->len) || ((pos + len) > src->len)) + pdc_error(src->pdc, PDC_E_INT_ILLARG, fn, 0, 0, 0); + + dst->len = 0; + pdc_bs_write(dst, buf + pos, len); +} /* pdc_bs_substr */ + +void +pdc_us_substr(pdc_ustr *dst, const pdc_ustr *src, size_t pos, size_t len) +{ + static const char fn[] = "pdc_us_substr"; + + const pdc_ucval *buf = src->buf ? src->buf : src->buf0; + + if ((pos < 0) || (len < 0) || (pos > src->len) || ((pos + len) > src->len)) + pdc_error(src->pdc, PDC_E_INT_ILLARG, fn, 0, 0, 0); + + dst->len = 0; + pdc_us_write(dst, buf + pos, len); +} /* pdc_us_substr */ + + +void +pdc_bs_concat(pdc_bstr *dst, const pdc_bstr *src) +{ + const pdc_byte *buf = src->buf ? src->buf : src->buf0; + + if (src->len) + pdc_bs_write(dst, buf, src->len); +} /* pdc_bs_concat */ + +void +pdc_us_concat(pdc_ustr *dst, const pdc_ustr *src) +{ + const pdc_ucval *buf = src->buf ? src->buf : src->buf0; + + if (src->len) + pdc_us_write(dst, buf, src->len); +} /* pdc_us_concat */ + + +void +pdc_bs_set(pdc_bstr *s, int idx, pdc_byte val) +{ + static const char fn[] = "pdc_bs_set"; + + pdc_byte *buf = s->buf ? s->buf : s->buf0; + + if (idx < 0 || s->len <= (size_t) idx) + pdc_error(s->pdc, PDC_E_INT_ARRIDX, + pdc_errprintf(s->pdc, "%d", idx), fn, 0, 0); + + buf[idx] = val; +} /* pdc_bs_set */ + +void +pdc_us_set(pdc_ustr *s, int idx, pdc_ucval val) +{ + static const char fn[] = "pdc_us_set"; + + pdc_ucval *buf = s->buf ? s->buf : s->buf0; + + if (idx < 0 || s->len <= (size_t) idx) + pdc_error(s->pdc, PDC_E_INT_ARRIDX, + pdc_errprintf(s->pdc, "%d", idx), fn, 0, 0); + + buf[idx] = val; +} /* pdc_us_set */ + + +void +pdc_bs_tolower(pdc_bstr *s) +{ + pdc_byte * buf = s->buf ? s->buf : s->buf0; + int i; + + for (i = 0; i < (int) s->len; ++i) + buf[i] = pdc_tolower(buf[i]); +} /* pdc_bs_tolower */ + +void +pdc_bs_toupper(pdc_bstr *s) +{ + pdc_byte * buf = s->buf ? s->buf : s->buf0; + int i; + + for (i = 0; i < (int) s->len; ++i) + buf[i] = pdc_toupper(buf[i]); +} /* pdc_bs_toupper */ + + +/************************************************************************/ +/* */ +/* stream-like functions. */ +/* */ +/************************************************************************/ + +void +pdc_bs_write(pdc_bstr *dst, const pdc_byte *src, size_t len) +{ + static const char fn[] = "pdc_bs_write"; + + pdc_byte *buf = dst->buf ? dst->buf : dst->buf0; + + if (!src || !len) + return; + + if (dst->cap < dst->len + len + 1) + { + dst->cap = dst->len + len + 1 + SBUF_RESERVE; + + if (!dst->buf) + { + dst->buf = (pdc_byte *) pdc_malloc(dst->pdc, dst->cap, fn); + memcpy(dst->buf, dst->buf0, dst->len); + } + else + { + dst->buf = (pdc_byte *) pdc_realloc(dst->pdc, + dst->buf, dst->cap, fn); + } + + buf = dst->buf; + } + + memcpy(buf + dst->len, src, len); + dst->len += len; +} /* pdc_bs_write */ + + +void +pdc_bs_puts(pdc_bstr *dst, const pdc_byte *src) +{ + if (!src) + return; + + pdc_bs_write(dst, src, strlen(src)); +} /* pdc_bs_puts */ + + +void +pdc_us_write(pdc_ustr *dst, const pdc_ucval *src, size_t len) +{ + static const char fn[] = "pdc_us_write"; + + pdc_ucval *buf = dst->buf ? dst->buf : dst->buf0; + + if (!src || len == 0) + return; + + if (dst->cap < dst->len + len) + { + dst->cap = dst->len + len + SBUF_RESERVE; + + if (!dst->buf) + { + dst->buf = (pdc_ucval *) + pdc_malloc(dst->pdc, dst->cap * sizeof (pdc_ucval), fn); + + memcpy(dst->buf, dst->buf0, dst->len * sizeof (pdc_ucval)); + } + else + { + dst->buf = (pdc_ucval *) pdc_realloc(dst->pdc, + dst->buf, dst->cap * sizeof (pdc_ucval), fn); + } + + buf = dst->buf; + } + + memcpy(buf + dst->len, src, len * sizeof (pdc_ucval)); + dst->len += len; +} /* pdc_us_write */ + + +void +pdc_bs_rewrite(pdc_bstr *s) +{ + s->len = 0; +} /* pdc_bs_rewrite */ + +void +pdc_us_rewrite(pdc_ustr *s) +{ + s->len = 0; +} /* pdc_us_rewrite */ + + +void +pdc_bs_putc(pdc_bstr *s, pdc_byte val) +{ + pdc_bs_write(s, &val, 1); +} /* pdc_bs_putc */ + +void +pdc_us_putc(pdc_ustr *s, pdc_ucval val) +{ + pdc_us_write(s, &val, 1); +} /* pdc_us_putc */ + + +/************************************************************************/ +/* */ +/* other utilities. */ +/* */ +/************************************************************************/ + +int +pdc_bs_compare(const pdc_bstr *s1, const pdc_bstr *s2) +{ + const char *buf1 = (const char *) (s1->buf ? s1->buf : s1->buf0); + const char *buf2 = (const char *) (s2->buf ? s2->buf : s2->buf0); + int result; + + if (s1->len < s2->len) + { + if ((result = strncmp(buf1, buf2, s1->len)) != 0) + return result; + + return -1; + } + + if (s2->len < s1->len) + { + if ((result = strncmp(buf1, buf2, s2->len)) != 0) + return result; + + return +1; + } + + return strncmp(buf1, buf2, s1->len); +} /* pdc_bs_compare */ diff --git a/src/pdflib/pdcore/pc_string.h b/src/pdflib/pdcore/pc_string.h new file mode 100644 index 0000000..631635f --- /dev/null +++ b/src/pdflib/pdcore/pc_string.h @@ -0,0 +1,267 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_string.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * The core string classes. + * + */ + +#ifndef PC_STRING_H +#define PC_STRING_H + +#include "pc_core.h" + +/* there are two pdcore string classes. the structures "behind" +** these classes are opaque. conceptually, pdc_bstr objects are +** sequences of 'pdc_byte' (unsigned 8-bit entities), whereas +** pdc_ustr objects are sequences of 'pdc_ucval' ("unicode value"; +** unsigned 32-bit entities). +*/ +#ifndef PDC_STRINGS_DEFINED +#define PDC_STRINGS_DEFINED +typedef struct pdc_bstr_s pdc_bstr; /* byte strings */ +typedef struct pdc_ustr_s pdc_ustr; /* unicode strings */ +#endif + + +/* TODO: naming conventions for "per module" init/cleanup */ +void pdc_init_strings(pdc_core *pdc); +void pdc_cleanup_strings(pdc_core *pdc); + + +/************************************************************************/ +/* */ +/* string object construction and deletion. */ +/* */ +/************************************************************************/ + +/* convert raw memory into an (empty) string object. +*/ +void pdc_bs_boot(pdc_core *pdc, pdc_bstr *s); +void pdc_us_boot(pdc_core *pdc, pdc_ustr *s); + +/* release all resources allocated by a string object (if any). +*/ +void pdc_bs_shutdown(pdc_bstr *s); +void pdc_us_shutdown(pdc_ustr *s); + +/* allocate a new (empty) pdc_bstr object. +*/ +pdc_bstr *pdc_bs_new(pdc_core *pdc); + +/* allocate a new pdc_ustr object and initialize its contents with the +** 'n' values from 'src'. if 'src' is null or 'n' is zero, +** an empty string object is constructed. +*/ +pdc_ustr *pdc_us_new(pdc_core *pdc, const pdc_ucval *src, size_t n); + +/* TODO: more constructors for various "source" types, eg. +** +pdc_ustr *pdc_us_new_utf16(pdc_core *pdc, const pdc_ushort *src, size_t n); +pdc_ustr *pdc_us_new_utf8(pdc_core *pdc, const pdc_byte *src, size_t n); +*/ + +/* return a copy of string 'src' ("copy constructor"). +*/ +pdc_bstr *pdc_bs_dup(const pdc_bstr *src); +pdc_ustr *pdc_us_dup(const pdc_ustr *src); + +/* delete a string object explicitly ("destructor"). +*/ +void pdc_bs_delete(pdc_bstr *s); +void pdc_us_delete(pdc_ustr *s); + +/************************************************************************/ +/* */ +/* "getters". */ +/* */ +/************************************************************************/ + +/* get the length of a string object in bytes or unicode values, resp. +*/ +size_t pdc_bs_length(const pdc_bstr *s); +size_t pdc_us_length(const pdc_ustr *s); + +/* string component access (range checked). +*/ +pdc_byte pdc_bs_get(const pdc_bstr *s, int idx); +pdc_ucval pdc_us_get(const pdc_ustr *s, int idx); + +/* TODO: try to get rid of that. */ +const pdc_byte *pdc_bs_get_cptr(const pdc_bstr *s); +const pdc_byte *pdc_us_get_cptr(const pdc_ustr *s); + +/************************************************************************/ +/* */ +/* "modifiers". */ +/* */ +/************************************************************************/ + +/* copy 'src' to 'dst' ("assignment operator"). +*/ +void pdc_bs_copy(pdc_bstr *dst, const pdc_bstr *src); +void pdc_us_copy(pdc_ustr *dst, const pdc_ustr *src); + +/* copy part of 'src' to 'dst'. +*/ +void pdc_bs_substr(pdc_bstr *dst, const pdc_bstr *src, + size_t pos, size_t len); +void pdc_us_substr(pdc_ustr *dst, const pdc_ustr *src, + size_t pos, size_t len); + +/* insert 'src' into 'dst' at 'pos'. +*/ +void pdc_bs_insert(pdc_bstr *dst, const pdc_bstr *src, size_t pos); +void pdc_us_insert(pdc_ustr *dst, const pdc_ustr *src, size_t pos); + +/* append 'src' to 'dst'. +*/ +void pdc_bs_concat(pdc_bstr *dst, const pdc_bstr *src); +void pdc_us_concat(pdc_ustr *dst, const pdc_ustr *src); + +/* string component access (range checked). +*/ +void pdc_bs_set(pdc_bstr *s, int idx, pdc_byte val); +void pdc_us_set(pdc_ustr *s, int idx, pdc_ucval val); + +/* case conversion. +*/ +void pdc_bs_tolower(pdc_bstr *s); +void pdc_bs_toupper(pdc_bstr *s); + +/************************************************************************/ +/* */ +/* stream-like functions. */ +/* */ +/************************************************************************/ + +/* append 'n' values from 'src' to 'dst'. if 'n' is zero, +** or 'src' is null, 'dst' remains unchanged. +*/ +void pdc_bs_write(pdc_bstr *dst, const pdc_byte *src, size_t n); + +/* append the null terminated string 'src' to 'dst'. +*/ +void pdc_bs_puts(pdc_bstr *dst, const pdc_byte *src); + +/* append 'n' values from 'src' to 'dst'. if 'src' is null or 'n' +** is zero, 'dst' remains unchanged. +*/ +void pdc_us_write(pdc_ustr *dst, const pdc_ucval *src, size_t n); + +void pdc_us_write_utf16(pdc_ustr *dst, const pdc_ushort *src, size_t n); + +/* TODO: more writer functions for various "source" types, eg. +** +void pdc_us_write_utf8(pdc_ustr *dst, const pdc_byte *src, size_t n); +*/ + +/* reset 's' to an empty stream object. +*/ +void pdc_bs_rewrite(pdc_bstr *s); +void pdc_us_rewrite(pdc_ustr *s); + +/* append a single byte (or unicode value, resp.) to a string object. +*/ +void pdc_bs_putc(pdc_bstr *s, pdc_byte val); +void pdc_us_putc(pdc_ustr *s, pdc_ucval val); + +/* TODO: stream-like read access. again, the read functions for pdc_ustr +** objects will be available in several flavors in order to support +** conversion to various "external" formats. +** +void pdc_bs_reset(pdc_bstr *s); +void pdc_us_reset(pdc_ustr *s); +void pdc_bs_seek(pdc_bstr *s, size_t pos); +void pdc_us_seek(pdc_ustr *s, size_t pos); +size_t pdc_bs_tell(const pdc_bstr *s); +size_t pdc_us_tell(const pdc_ustr *s); +size_t pdc_bs_read(pdc_bstr *src, pdc_byte *dst, size_t n); +size_t pdc_us_read(pdc_ustr *src, pdc_ucval *dst, size_t n); +size_t pdc_us_read_utf16(pdc_ustr *src, pdc_ushort *dst, size_t n); +size_t pdc_us_read_utf8(pdc_ustr *src, pdc_byte *dst, size_t n); +*/ + +/************************************************************************/ +/* */ +/* other utilities. */ +/* */ +/************************************************************************/ + +int pdc_bs_compare(const pdc_bstr *s1, const pdc_bstr *s2); + +/************************************************************************/ +/* */ +/* PRIVATE SECTION */ +/* */ +/* the declarations below are strictly private to the implementation */ +/* module, and must not be used by any client modules! */ +/* */ +/************************************************************************/ + +#define PDC_STR_INLINE_CAP 16 + +struct pdc_bstr_s +{ + pdc_core * pdc; + + pdc_byte buf0[PDC_STR_INLINE_CAP]; + pdc_byte * buf; + size_t len; + size_t cap; +}; + +struct pdc_ustr_s +{ + pdc_core * pdc; + + pdc_ucval buf0[PDC_STR_INLINE_CAP]; + pdc_ucval * buf; + size_t len; + size_t cap; +}; + +#if 0 +/* string representation. +*/ +typedef struct +{ + pdc_byte * buf; /* contents */ + size_t cap; /* capacity (unit: pdc_byte) */ + size_t len; /* length (unit: pdc_byte) */ + int ref; /* reference count */ +} pdc_bs_rep; + +typedef struct +{ + pdc_ucval * buf; /* contents */ + size_t cap; /* capacity (unit: pdc_ucval) */ + size_t len; /* length (unit: pdc_ucval) */ + int ref; /* reference count */ +} pdc_us_rep; + + +struct pdc_bstr_s +{ + pdc_core * pdc; + pdc_bs_rep *rep; +}; + +struct pdc_ustr_s +{ + pdc_core * pdc; + pdc_us_rep *rep; +}; +#endif + +#endif /* PC_STRING_H */ diff --git a/src/pdflib/pdcore/pc_unicode.c b/src/pdflib/pdcore/pc_unicode.c new file mode 100644 index 0000000..7b32022 --- /dev/null +++ b/src/pdflib/pdcore/pc_unicode.c @@ -0,0 +1,1886 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_unicode.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib Unicode converting routines + * + */ + +#define PC_UNICODE_C + +#include "pc_util.h" + +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#endif /* WIN32 */ + +/* + * The following source is based on Unicode's original source + * code ConvertUTF.c. It has been adapted to PDFlib programming + * conventions. + * + * The original file had the following notice: + * + * Copyright 2001 Unicode, Inc. + * + * Limitations on Rights to Redistribute This Code + * + * Author: Mark E. Davis, 1994. + * Rev History: Rick McGowan, fixes & updates May 2001. + * + * + * Functions for conversions between UTF32, UTF-16, and UTF-8. + * These funtions forming a complete set of conversions between + * the three formats. UTF-7 is not included here. + * + * Each of these routines takes pointers to input buffers and output + * buffers. The input buffers are const. + * + * Each routine converts the text between *sourceStart and sourceEnd, + * putting the result into the buffer between *targetStart and + * targetEnd. Note: the end pointers are *after* the last item: e.g. + * *(sourceEnd - 1) is the last item. + * + * The return result indicates whether the conversion was successful, + * and if not, whether the problem was in the source or target buffers. + * (Only the first encountered problem is indicated.) + * + * After the conversion, *sourceStart and *targetStart are both + * updated to point to the end of last text successfully converted in + * the respective buffers. + * + * Input parameters: + * sourceStart - pointer to a pointer to the source buffer. + * The contents of this are modified on return so that + * it points at the next thing to be converted. + * targetStart - similarly, pointer to pointer to the target buffer. + * sourceEnd, targetEnd - respectively pointers to the ends of the + * two buffers, for overflow checking only. + * + * These conversion functions take a pdc_convers_flags argument. When this + * flag is set to strict, both irregular sequences and isolated surrogates + * will cause an error. When the flag is set to lenient, both irregular + * sequences and isolated surrogates are converted. + * + * Whether the flag is strict or lenient, all illegal sequences will cause + * an error return. This includes sequences such as: , , + * or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code + * must check for illegal sequences. + * + * When the flag is set to lenient, characters over 0x10FFFF are converted + * to the replacement character; otherwise (when the flag is set to strict) + * they constitute an error. + * + * Output parameters: + * The value "sourceIllegal" is returned from some routines if the input + * sequence is malformed. When "sourceIllegal" is returned, the source + * value will point to the illegal value that caused the problem. E.g., + * in UTF-8 when a sequence is malformed, it points to the start of the + * malformed sequence. + * + * Author: Mark E. Davis, 1994. + * Rev History: Rick McGowan, fixes & updates May 2001. + * + */ + +/* + * The following 4 definitions are compiler-specific. + * The C standard does not guarantee that wchar_t has at least + * 16 bits, so wchar_t is no less portable than unsigned short! + * All should be unsigned values to avoid sign extension during + * bit mask & shift operations. + */ + +/* Unicode original: +typedef unsigned long UTF32; at least 32 bits +typedef unsigned short UTF16; at least 16 bits +*/ + +typedef unsigned int UTF32; /* 32 bits */ +typedef unsigned short UTF16; /* 16 bits */ +typedef unsigned char UTF8; /* typically 8 bits */ + +/* Some fundamental constants */ +#define UNI_SUR_HIGH_START (UTF32)0xD800 +#define UNI_SUR_HIGH_END (UTF32)0xDBFF +#define UNI_SUR_LOW_START (UTF32)0xDC00 +#define UNI_SUR_LOW_END (UTF32)0xDFFF +#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD +#define UNI_MAX_BMP (UTF32)0x0000FFFF +#define UNI_MAX_UTF16 (UTF32)0x0010FFFF +#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF + +static const int halfShift = 10; /* used for shifting by 10 bits */ + +static const UTF32 halfBase = 0x0010000UL; +static const UTF32 halfMask = 0x3FFUL; + + +/* --------------------------------------------------------------------- */ + +static pdc_convers_result +pdc_convertUTF32toUTF16 ( + UTF32** sourceStart, const UTF32* sourceEnd, + UTF16** targetStart, const UTF16* targetEnd, + const pdc_convers_flags flags) { + pdc_convers_result result = conversionOK; + UTF32* source = *sourceStart; + UTF16* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + if (target >= targetEnd) { + result = targetExhausted; break; + } + ch = *source++; + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + if ((flags == strictConversion) && + (ch >= UNI_SUR_HIGH_START && + ch <= UNI_SUR_LOW_END)) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = (UTF16) ch; /* normal case */ + } + } else if (ch > UNI_MAX_UTF16) { + if (flags == strictConversion) { + result = sourceIllegal; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + if (target + 1 >= targetEnd) { + result = targetExhausted; + break; + } + ch -= halfBase; + *target++ = (UTF16) ((ch >> halfShift) + UNI_SUR_HIGH_START); + *target++ = (UTF16) ((ch & halfMask) + UNI_SUR_LOW_START); + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +static pdc_convers_result +pdc_convertUTF16toUTF32 ( + UTF16** sourceStart, UTF16* sourceEnd, + UTF32** targetStart, const UTF32* targetEnd, + const pdc_convers_flags flags) { + pdc_convers_result result = conversionOK; + UTF16* source = *sourceStart; + UTF32* target = *targetStart; + UTF32 ch, ch2; + while (source < sourceEnd) { + ch = *source++; + if (ch >= UNI_SUR_HIGH_START && + ch <= UNI_SUR_HIGH_END && + source < sourceEnd) { + ch2 = *source; + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + + (ch2 - UNI_SUR_LOW_START) + halfBase; + ++source; + } else if (flags == strictConversion) { + /* it's an unpaired high surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } else if ((flags == strictConversion) && + (ch >= UNI_SUR_LOW_START && + ch <= UNI_SUR_LOW_END)) { + /* an unpaired low surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + if (target >= targetEnd) { + result = targetExhausted; + break; + } + *target++ = ch; + } + *sourceStart = source; + *targetStart = target; +#ifdef CVTUTF_DEBUG +if (result == sourceIllegal) { + fprintf(stderr, "pdc_convertUTF16toUTF32 illegal seq 0x%04x,%04x\n", + ch, ch2); + fflush(stderr); +} +#endif + return result; +} + +/* --------------------------------------------------------------------- */ + +/* + * Index into the table below with the first byte of a UTF-8 sequence to + * get the number of trailing bytes that are supposed to follow it. + */ +static const char trailingBytesForUTF8[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 +}; + +#if 0 +static const char +pdc_get_trailingBytesForUTF8(int i) { + return (trailingBytesForUTF8[i]); +} +#endif + +/* + * Magic values subtracted from a buffer value during UTF8 conversion. + * This table contains as many values as there might be trailing bytes + * in a UTF-8 sequence. + */ +static const UTF32 offsetsFromUTF8[6] = { + 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL +}; + +/* + * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed + * into the first byte, depending on how many bytes follow. There are + * as many entries in this table as there are UTF-8 sequence types. + * (I.e., one byte sequence, two byte... six byte sequence.) + */ +static const UTF8 firstByteMark[7] = { + 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC +}; + +/* --------------------------------------------------------------------- */ + +/* The interface converts a whole buffer to avoid function-call overhead. + * Constants have been gathered. Loops & conditionals have been removed as + * much as possible for efficiency, in favor of drop-through switches. + * (See "Note A" at the bottom of the file for equivalent code.) + * If your compiler supports it, the "pdc_islegalUTF8" call can be turned + * into an inline function. + */ + +/* --------------------------------------------------------------------- */ + +static pdc_convers_result +pdc_convertUTF16toUTF8 ( + UTF16** sourceStart, const UTF16* sourceEnd, + UTF8** targetStart, const UTF8* targetEnd, + const pdc_convers_flags flags) { + pdc_convers_result result = conversionOK; + UTF16* source = *sourceStart; + UTF8* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0xBF; + const UTF32 byteMark = 0x80; + ch = *source++; + /* If we have a surrogate pair, convert to UTF32 first. */ + if (ch >= UNI_SUR_HIGH_START && + ch <= UNI_SUR_HIGH_END && + source < sourceEnd) { + UTF32 ch2 = *source; + if (ch2 >= UNI_SUR_LOW_START && + ch2 <= UNI_SUR_LOW_END) { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + + (ch2 - UNI_SUR_LOW_START) + halfBase; + ++source; + } else if (flags == strictConversion) { + /* it's an unpaired high surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } else if ((flags == strictConversion) && + (ch >= UNI_SUR_LOW_START && + ch <= UNI_SUR_LOW_END)) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + /* Figure out how many bytes the result will require */ + if (ch < (UTF32)0x80) { bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; + } else if (ch < (UTF32)0x200000) { bytesToWrite = 4; + } else { bytesToWrite = 2; + ch = UNI_REPLACEMENT_CHAR; + } + + target += bytesToWrite; + if (target > targetEnd) { + target -= bytesToWrite; result = targetExhausted; break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: *--target = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6; + case 3: *--target = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6; + case 2: *--target = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6; + case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +/* + * Utility routine to tell whether a sequence of bytes is legal UTF-8. + * This must be called with the length pre-determined by the first byte. + * If not calling this from pdc_convertUTF8to*, then the length can be set by: + * length = trailingBytesForUTF8[*source]+1; + * and the sequence is illegal right away if there aren't that many bytes + * available. + * If presented with a length > 4, this returns pdc_false. The Unicode + * definition of UTF-8 goes up to 4-byte sequences. + */ + +static pdc_bool +pdc_islegalUTF8(UTF8 *source, int length) { + UTF8 a; + UTF8 *srcptr = source+length; + switch (length) { + default: return pdc_false; + /* Everything else falls through when "pdc_true"... */ + case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return pdc_false; + case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return pdc_false; + case 2: if ((a = (*--srcptr)) > 0xBF) return pdc_false; + switch (*source) { + /* no fall-through in this inner switch */ + case 0xE0: if (a < 0xA0) return pdc_false; break; + case 0xF0: if (a < 0x90) return pdc_false; break; + case 0xF4: if (a > 0x8F) return pdc_false; break; + default: if (a < 0x80) return pdc_false; + } + case 1: if (*source >= 0x80 && *source < 0xC2) return pdc_false; + if (*source > 0xF4) return pdc_false; + } + return pdc_true; +} + +/* --------------------------------------------------------------------- */ + +/* + * Exported function to return whether a UTF-8 sequence is legal or not. + * This is not used here; it's just exported. + */ +#if 0 +static pdc_bool pdc_islegalUTF8sequence(UTF8 *source, UTF8 *sourceEnd) { + int length = trailingBytesForUTF8[*source]+1; + if (source+length > sourceEnd) { + return pdc_false; + } + return pdc_islegalUTF8(source, length); +} +#endif + +/* --------------------------------------------------------------------- */ + +static pdc_convers_result +pdc_convertUTF8toUTF16 ( + UTF8** sourceStart, UTF8* sourceEnd, + UTF16** targetStart, const UTF16* targetEnd, + const pdc_convers_flags flags) { + pdc_convers_result result = conversionOK; + UTF8* source = *sourceStart; + UTF16* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0L; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; + break; + } + /* Do this check whether lenient or strict */ + if (! pdc_islegalUTF8(source, extraBytesToRead+1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + result = targetExhausted; + break; + } + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + if ((flags == strictConversion) && + (ch >= UNI_SUR_HIGH_START && + ch <= UNI_SUR_LOW_END)) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = (UTF16) ch; /* normal case */ + } + } else if (ch > UNI_MAX_UTF16) { + if (flags == strictConversion) { + result = sourceIllegal; + source -= extraBytesToRead; /* return to the start */ + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + if (target + 1 >= targetEnd) { + result = targetExhausted; + break; + } + ch -= halfBase; + *target++ = (UTF16) ((ch >> halfShift) + UNI_SUR_HIGH_START); + *target++ = (UTF16) ((ch & halfMask) + UNI_SUR_LOW_START); + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +static pdc_convers_result +pdc_convertUTF32toUTF8 ( + UTF32** sourceStart, const UTF32* sourceEnd, + UTF8** targetStart, const UTF8* targetEnd, + const pdc_convers_flags flags) { + pdc_convers_result result = conversionOK; + UTF32* source = *sourceStart; + UTF8* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0x000000BF; + const UTF32 byteMark = 0x00000080; + ch = *source++; + /* surrogates of any stripe are not legal UTF32 characters */ + if (flags == strictConversion ) { + if ((ch >= UNI_SUR_HIGH_START) && (ch <= UNI_SUR_LOW_END)) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + /* Figure out how many bytes the result will require */ + if (ch < (UTF32)0x80) { bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; + } else if (ch < (UTF32)0x200000) { bytesToWrite = 4; + } else { bytesToWrite = 2; + ch = UNI_REPLACEMENT_CHAR; + } + + target += bytesToWrite; + if (target > targetEnd) { + target -= bytesToWrite; result = targetExhausted; break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: *--target = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6; + case 3: *--target = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6; + case 2: *--target = (UTF8) ((ch | byteMark) & byteMask); ch >>= 6; + case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +static pdc_convers_result +pdc_convertUTF8toUTF32 ( + UTF8** sourceStart, UTF8* sourceEnd, + UTF32** targetStart, const UTF32* targetEnd, + const pdc_convers_flags flags) { + pdc_convers_result result = conversionOK; + UTF8* source = *sourceStart; + UTF32* target = *targetStart; + + (void) flags; + + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; break; + } + /* Do this check whether lenient or strict */ + if (! pdc_islegalUTF8(source, extraBytesToRead+1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + result = targetExhausted; + break; + } + if (ch <= UNI_MAX_UTF32) { + *target++ = ch; + } else if (ch > UNI_MAX_UTF32) { + *target++ = UNI_REPLACEMENT_CHAR; + } else { + if (target + 1 >= targetEnd) { + result = targetExhausted; + break; + } + ch -= halfBase; + *target++ = (ch >> halfShift) + UNI_SUR_HIGH_START; + *target++ = (ch & halfMask) + UNI_SUR_LOW_START; + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- + + Note A. + The fall-through switches in UTF-8 reading code save a + temp variable, some decrements & conditionals. The switches + are equivalent to the following loop: + { + int tmpBytesToRead = extraBytesToRead+1; + do { + ch += *source++; + --tmpBytesToRead; + if (tmpBytesToRead) ch <<= 6; + } while (tmpBytesToRead > 0); + } + In UTF-8 writing code, the switches on "bytesToWrite" are + similarly unrolled loops. + + --------------------------------------------------------------------- */ + +static const pdc_keyconn pdc_utfformat_keylist[] = +{ + {"8", pdc_utf8}, + {"16", pdc_utf16}, + {"32", pdc_utf32}, + {NULL, 0} +}; + + +/* + * pdc_convert_string converts a arbitrary encoded string (maybe UTF) to + * another encoded string. + * + * The new converted string is allocated and terminated by the required + * number of zeros. + * + * The caller is responsible for freeing the resulting string buffer. + * + * + * LBP: low byte picking + * + * Input-Parameter: + * + * inutf: input string format (see pc_unicode.h): + * + * pdc_auto: If codepage != 0: + * see above. + * Otherwise: + * If a BOM is recognized: + * pdc_utf8 or pdc_utf16xx resp. + * Otherwise if input encoding is specified + * and flag PDC_CONV_FORCEUTF16 not set: + * pdc_bytes + * Otherwise: + * pdc_utf16 + * + * pdc_auto2: If input encoding is not specified: + * pdc_utf16 + * Otherwise after successfull LBP: + * pdc_auto + * Otherwise: + * pdc_utf16 + * + * pdc_bytes: 8-bit string. Encoding is if specified. + * + * pdc_bytes2: After successfull LBP: + * pdc_bytes + * Otherwise: + * pdc_utf16 + * + * pdc_utf8: UTF-8 formatted string. + * + * pdc_ebcdicutf8: EBCDIC-UTF-8 formatted string. + * + * pdc_utf16: If a UTF16 BOM is recognized: + * pdc_utf16be or pdc_utf16le + * Otherwise UTF-16 machine byte ordered string. + * + * pdc_utf16be UTF-16 big endian formatted string. + * + * pdc_utf16le UTF-16 little endian formatted string. + * + * codepage: OEM multi byte code-page number. If > 0 and + * = pdc_auto, text will be converted to UTF-16. + * + * inev: Encoding vector for input pdc_bytes string. + * + * glyphtab: Mapping table for character reference names + * + * tabsize: Size of mapping table + * + * replchar: Treatment of non resolvable character references: + * >= 0: replacement character + * == text_error: error message + * == text_nocheck: will be ignored + * (see also pdc_charref2unicodelist()) + * + * instring: Input string. + * + * inlen: Length of input string in byte. + * + * oututf: Target format for output string. + * pdc_auto, pdc_auto2 and pdc_bytes2 are not supported. + * + * outev: Encoding vector for output pdc_bytes string. + * + * flags: PDC_CONV_FORCEUTF16: + * In the case of = pdc_auto[2] and != NULL + * = pdc_utf16 will be forced. + * + * PDC_CONV_TRY7BYTES: + * UTF-8 output strings will have no BOM if each byte + * is smaller than x80. + * *oututf: pdc_byte. + * + * PDC_CONV_TRYBYTES: + * UTF-UTF-16xx output strings will be converted by LBP + * if each character is smaller than x0100. + * *oututf: pdc_byte. + * + * PDC_CONV_WITHBOM: + * UTF-8 or UTF-UTF-16xx output strings will be armed + * with an appropriate BOM. + * + * PDC_CONV_NOBOM: + * In UTF-8 or UTF-UTF-16xx output strings any BOM sequence + * will be removed. PDC_CONV_WITHBOM is dominant. + * + * PDC_CONV_AUTOBOM: + * BOM sequence will be set automatically if input string + * has a BOM. + * + * PDC_CONV_ANALYZE: + * Only analyzing BOMs of input string and dissolving auto + * textformats. + * + * PDC_CONV_TMPALLOC + * Temporary memory functions (pdc_malloc_tmp) are used + * rather than pdc_malloc etc. + * + * PDC_CONV_HTMLCHAR + * If input encoding vector is specified HTML character + * entities will be substituted. + * + * PDC_CONV_NEWALLOC + * Input string must be allocated at first to guarantee + * pointer alignment. + * + * PDC_CONV_INFLATE + * Invalid UTF-8 to UTF-16xx conversion will not cause + * an exception but rather an inflated byte string will + * be output. + * + * PDC_CONV_ESCSEQU + * Unicode sequences framed by escape character U+001B + * (found in PDF text strings) will be skipped. + * + * PDC_CONV_BSSEQU + * Code sequences beginning with backslash '\' + * will be substituted. + * + * PDC_CONV_ENCERROR + * If an 8-bit code cannot be converted to Unicode by + * or a Unicode cannot be converted to an 8-bit code by + * an error message will be created. + * + * PDC_CONV_KEEPLBCHAR + * In the case of PDC_CONV_ENCERROR relevant characters for + * line breaking do not lead to an error message. + * + * PDC_CONV_LOGGING + * Enables logging. + * + * verbose: Error messages are put out. Otherwise they are saved only. + * + * Output-Parameter: + * + * oututf: Reached format for output string. + * + * outstring: Pointer of allocated output string + * + * outlen: Length of output string. + * + */ + +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma unmanaged +#endif +int +pdc_convert_string(pdc_core *pdc, + pdc_text_format inutf, int codepage, + pdc_encodingvector *inev, + pdc_byte *instring, int inlen, + pdc_text_format *oututf_p, pdc_encodingvector *outev, + pdc_byte **outstring, int *outlen, int flags, + pdc_bool verbose) +{ + return pdc_convert_textstring(pdc, inutf, codepage, inev, + NULL, 0, -1, instring, inlen, oututf_p, outev, + outstring, outlen, flags, verbose); +} + +int +pdc_convert_textstring(pdc_core *pdc, + pdc_text_format inutf, int codepage, + pdc_encodingvector *inev, + const pdc_glyph_tab *glyphtab, int tabsize, int replchar, + pdc_byte *instring, int inlen, + pdc_text_format *oututf_p, pdc_encodingvector *outev, + pdc_byte **outstring, int *outlen, int flags, + pdc_bool verbose) +{ + static const char *fn = "pdc_convert_textstring"; + pdc_bool logg = flags & PDC_CONV_LOGGING; + const char *stemp1 = NULL, *stemp2 = NULL; + pdc_text_format oututf = *oututf_p; + pdc_text_format oututf_s; + pdc_ushort *usinstr = (pdc_ushort *) instring; + pdc_ushort uv = 0; + pdc_byte *instr = NULL; + pdc_bool inalloc = pdc_false; + pdc_bool hasbom = pdc_false; + pdc_bool toswap = pdc_false; + int errcode = 0; + int i, j, n, len = 0; + + (void) glyphtab; + (void) tabsize; + (void) replchar; + + if (logg) + pdc_logg(pdc, "\t\tinput textformat for string conversion: %s\n", + pdc_get_keyword(inutf, pdc_textformat_keylist)); + + /* prophylactic */ + if (!inlen) + { + instring = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, 4, fn, NULL, NULL) : + pdc_calloc(pdc, 4, fn)); + + inalloc = pdc_true; + } + else if ((flags & PDC_CONV_NEWALLOC) || + (flags & PDC_CONV_TMPALLOC) || + (flags & PDC_CONV_BSSEQU)) + { + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (inlen + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (inlen + 2), fn)); + memcpy(instr, instring, (size_t) inlen); + + inalloc = pdc_true; + instring = instr; + instr = NULL; + usinstr = (pdc_ushort *) instring; + } + + switch(inutf) + { + /* analyzing 2 byte textformat */ + case pdc_auto2: + case pdc_bytes2: + if ((inutf == pdc_auto2 && + (inev == NULL || (flags & PDC_CONV_FORCEUTF16))) || + (flags & PDC_CONV_ANALYZE)) + { + inutf = pdc_utf16; + } + else + { + if (logg) + pdc_logg(pdc, "\t\ttry to pick low bytes\n"); + + len = inlen / 2; + if (2 * len != inlen) + { + errcode = PDC_E_CONV_ILLUTF16; + goto PDC_CONV_ERROR; + } + for (i = 0; i < len; i++) + if (usinstr[i] > PDC_UNICODE_MAXLATIN1) + break; + + /* low byte picking */ + if (i == len) + { + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (len + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (len + 2), fn)); + for (i = 0; i < len; i++) + instr[i] = (pdc_byte) usinstr[i]; + + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + inalloc = pdc_true; + instring = instr; + instr = NULL; + inlen = len; + + if (inutf == pdc_bytes2) + inutf = pdc_bytes; + else + inutf = pdc_auto; + } + else + { + inutf = pdc_utf16; + } + } + break; + + /* OEM multi byte text strings */ + case pdc_auto: + case pdc_bytes: + if (codepage > 0) + { +#if defined(WIN32) + if (!(flags & PDC_CONV_ANALYZE)) + { + if (logg) + pdc_logg(pdc, + "\t\tconverting according Windows codepage %d\n", + codepage); + + len = MultiByteToWideChar((UINT) codepage, (DWORD) 0, + (LPCSTR) instring, inlen, NULL, 0); + if (len == 0) + { + DWORD lasterror = GetLastError(); + + stemp1 = pdc_errprintf(pdc, "cp%d", codepage); + if (lasterror == ERROR_INVALID_PARAMETER) + { + errcode = PDC_E_CONV_UNSUPP_MBTEXTFORM; + } + else + { + errcode = PDC_E_CONV_ILL_MBTEXTSTRING; + } + goto PDC_CONV_ERROR; + } + + len *= 2; + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (len + 2), fn, + NULL, NULL) : + pdc_calloc(pdc, (size_t) (len + 2), fn)); + MultiByteToWideChar((UINT) codepage, (DWORD) 0, (LPCSTR) + instring, inlen, + (LPWSTR) instr, len); + + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + inalloc = pdc_true; + instring = instr; + instr = NULL; + inlen = len; + + inutf = pdc_utf16; + } + else + { + inutf = pdc_bytes; + } +#else /* WIN32 */ + errcode = PDC_E_CONV_UNSUPP_MBTEXTFORM; + goto PDC_CONV_ERROR; +#endif /* !WIN32 */ + } + break; + + default: + break; + } + + /* analyzing UTF-16 textformat */ + if (inutf == pdc_utf16) + { + if (pdc_is_utf16be_unicode(instring)) + inutf = pdc_utf16be; + else if (pdc_is_utf16le_unicode(instring)) + inutf = pdc_utf16le; + } + + /* analyzing auto textformat */ + else if (inutf == pdc_auto) + { + if (pdc_is_utf8_bytecode(instring)) + inutf = PDC_UTF8; + else if (pdc_is_utf16be_unicode(instring)) + inutf = pdc_utf16be; + else if (pdc_is_utf16le_unicode(instring)) + inutf = pdc_utf16le; + else if (inev && !(flags & PDC_CONV_FORCEUTF16)) + inutf = pdc_bytes; + else + inutf = pdc_utf16; + } + + if (logg) + pdc_logg(pdc, "\t\tdetermined textformat: %s\n", + pdc_get_keyword(inutf, pdc_textformat_keylist)); + + /* only analyzing */ + if (flags & PDC_CONV_ANALYZE) + goto PDC_CONV_EXIT; + + /* conversion to UTF-16 by swapping */ + if ((inutf == pdc_utf16be || inutf == pdc_utf16le) && + (inutf != oututf || flags & PDC_CONV_TRYBYTES || + flags & PDC_CONV_HTMLCHAR)) + { + if (inlen && + ((inutf == pdc_utf16be && !PDC_ISBIGENDIAN) || + (inutf == pdc_utf16le && PDC_ISBIGENDIAN))) + { + if (inalloc) + pdc_swap_bytes((char *) instring, inlen, NULL); + else + { + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (inlen + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (inlen + 2), fn)); + pdc_swap_bytes((char *) instring, inlen, (char *) instr); + + inalloc = pdc_true; + instring = instr; + instr = NULL; + } + } + inutf = pdc_utf16; + } + + /* illegal UTF-16 */ + if (inutf >= pdc_utf16 && inlen % 2) + { + errcode = PDC_E_CONV_ILLUTF16; + goto PDC_CONV_ERROR; + } + + + /* conversion to UTF-16 by inflation or encoding vector */ + if (inutf == pdc_bytes && + (oututf != pdc_bytes || flags & PDC_CONV_HTMLCHAR || inev != outev)) + { + if (logg) + { + if (flags & PDC_CONV_HTMLCHAR) + pdc_logg(pdc, "\t\tbyte character entity substitution\n"); + } + + len = 2 * inlen; + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (len + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (len + 2), fn)); + usinstr = (pdc_ushort *) instr; + + j = 0; + for (i = 0; i < inlen; i++) + { + uv = (pdc_ushort) instring[i]; + if (inev) + { + uv = inev->codes[uv]; + if (!uv && (flags & PDC_CONV_ENCERROR) && + (!(flags & PDC_CONV_KEEPLBCHAR) || + !pdc_is_linebreaking_relchar(uv))) + { + errcode = PDC_E_ENC_NOTDEF_CODE; + stemp1 = pdc_errprintf(pdc, "x%02X", instring[i]); + stemp2 = inev->apiname; + goto PDC_CONV_ERROR; + } + } + + + usinstr[j] = uv; + j++; + } + + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + inalloc = pdc_true; + instring = instr; + instr = NULL; + inlen = 2 * j; + inutf = pdc_utf16; + } + + + + /* UTF conversion */ + oututf_s = oututf; + if ((oututf_s == pdc_bytes && inutf == pdc_utf8) || + oututf_s == pdc_utf16be || oututf_s == pdc_utf16le) + oututf_s = pdc_utf16; + if (inutf != oututf_s && oututf_s != pdc_bytes) + { + len = 4 * (inlen + 1); + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) len, fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) len, fn)); + + if (inlen) + { + pdc_convers_result result = conversionOK; + pdc_byte *instringa, *instra, *instringe, *instre; + UTF8 *isa8, *ise8; + UTF16 *isa16, *ise16; + UTF32 *isa32, *ise32; + + if (logg) + pdc_logg(pdc, "\t\tUTF conversion\n"); + + instringa = instring; + instringe = instring + inlen; + instra = instr; + instre = instr + len; + + if (inutf == pdc_utf8) + { + isa8 = (UTF8 *) instringa; + ise8 = (UTF8 *) instringe; + if (oututf_s == pdc_utf16) + { + isa16 = (UTF16 *) instra; + ise16 = (UTF16 *) instre; + result = pdc_convertUTF8toUTF16(&isa8, ise8, + &isa16, ise16, + strictConversion); + instra = (pdc_byte *) isa16; + instre = (pdc_byte *) ise16; + } + else + { + isa32 = (UTF32 *) instra; + ise32 = (UTF32 *) instre; + result = pdc_convertUTF8toUTF32(&isa8, ise8, + &isa32, ise32, + strictConversion); + instra = (pdc_byte *) isa32; + instre = (pdc_byte *) ise32; + } + } + else if (inutf == pdc_utf16) + { + isa16 = (UTF16 *) instringa; + ise16 = (UTF16 *) instringe; + if (oututf_s == pdc_utf8) + { + isa8 = (UTF8 *) instra; + ise8 = (UTF8 *) instre; + result = pdc_convertUTF16toUTF8(&isa16, ise16, &isa8, ise8, + strictConversion); + instra = (pdc_byte *) isa8; + instre = (pdc_byte *) ise8; + } + else + { + isa32 = (UTF32 *) instra; + ise32 = (UTF32 *) instre; + result = pdc_convertUTF16toUTF32(&isa16, ise16, + &isa32, ise32, + strictConversion); + instra = (pdc_byte *) isa32; + instre = (pdc_byte *) ise32; + } + } + else if (inutf == pdc_utf32) + { + isa32 = (UTF32 *) instringa; + ise32 = (UTF32 *) instringe; + if (oututf_s == pdc_utf8) + { + isa8 = (UTF8 *) instra; + ise8 = (UTF8 *) instre; + result = pdc_convertUTF32toUTF8(&isa32, ise32, + &isa8, ise8, + strictConversion); + instra = (pdc_byte *) isa8; + instre = (pdc_byte *) ise8; + } + else + { + isa16 = (UTF16 *) instra; + ise16 = (UTF16 *) instre; + result = pdc_convertUTF32toUTF16(&isa32, ise32, + &isa16, ise16, + strictConversion); + instra = (pdc_byte *) isa16; + instre = (pdc_byte *) ise16; + } + } + + switch (result) + { + case targetExhausted: + errcode = PDC_E_CONV_MEMOVERFLOW; + break; + + case sourceExhausted: + case sourceIllegal: + if (inutf == pdc_utf8 && (flags & PDC_CONV_INFLATE)) + { + pdc_inflate_ascii((char *) instring, inlen, (char *) instr, + pdc_utf16); + instra = instr + 2 * inlen; + } + else + { + errcode = PDC_E_CONV_ILLUTF; + stemp1 = pdc_get_keyword((int)inutf, pdc_utfformat_keylist); + } + break; + + default: + break; + } + + if (errcode) + { + if (logg) + pdc_logg(pdc, "\t\tUTF conversion error %d\n", result); + + goto PDC_CONV_ERROR; + } + + inlen = instra - instr; + } + + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + len = (oututf == pdc_utf32) ? inlen + 4 : inlen + 2; + if (inlen + 4 != len) + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_realloc_tmp(pdc, instr, (size_t) len, fn) : + pdc_realloc(pdc, instr, (size_t) len, fn)); + instr[inlen] = 0; + instr[inlen + 1] = 0; + if (oututf == pdc_utf32) + { + instr[inlen + 2] = 0; + instr[inlen + 3] = 0; + } + + inalloc = pdc_true; + instring = instr; + instr = NULL; + inutf = oututf_s; + } + + if (inutf == pdc_bytes) + { + if (!inalloc) + { + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (inlen + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (inlen + 2), fn)); + memcpy(instr, instring, (size_t) inlen); + + inalloc = pdc_true; + instring = instr; + instr = NULL; + } + } + + /* trying to reduce UTF-16 string to bytes string */ + if (inutf == pdc_utf16 && + (oututf == pdc_bytes || flags & PDC_CONV_TRYBYTES)) + { + if (logg) + pdc_logg(pdc, "\t\ttry to reduce UTF-16 to bytes\n"); + + if (pdc_is_utf16be_unicode(instring) || + pdc_is_utf16le_unicode(instring)) + n = 1; + else + n = 0; + + len = (inlen - n) / 2; + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (len + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (len + 2), fn)); + usinstr = (pdc_ushort *) instring; + + for (i = 0; i < len; i++) + { + uv = usinstr[i + n]; + if (outev && uv) + { + j = pdc_get_encoding_bytecode(pdc, outev, uv); + if (j < 0 && (flags & PDC_CONV_ENCERROR) && oututf == pdc_bytes) + { + errcode = PDC_E_ENC_NOTDEF_UNICODE; + stemp1 = pdc_errprintf(pdc, "%04X", uv); + stemp2 = outev->apiname; + goto PDC_CONV_ERROR; + } + uv = (pdc_ushort) j; + } + if (uv > PDC_UNICODE_MAXLATIN1) + break; + + instr[i] = (pdc_byte) uv; + } + + if (i == len) + { + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + inalloc = pdc_true; + instring = instr; + instr = NULL; + inlen = len; + inutf = pdc_bytes; + } + else + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instr); + else + pdc_free(pdc, instr); + instr = NULL; + } + } + + /* UTF-8 format */ + if (inutf == pdc_utf8) + { + hasbom = pdc_is_utf8_unicode(instring); + + if (flags & PDC_CONV_TRY7BYTES) + { + if (logg) + pdc_logg(pdc, "\t\ttry to reduce UTF-8 to 7-bit\n"); + + for (i = hasbom ? 3 : 0; i < inlen; i++) + if (instring[i] > PDC_UNICODE_MAXASCII) + break; + if (i == inlen) + { + flags &= ~PDC_CONV_WITHBOM; + flags |= PDC_CONV_NOBOM; + inutf = pdc_bytes; + } + } + else if (hasbom && (flags & PDC_CONV_AUTOBOM)) + { + flags &= ~PDC_CONV_NOBOM; + flags |= PDC_CONV_WITHBOM; + } + else if ((flags & PDC_CONV_WITHBOM) && (flags & PDC_CONV_NOBOM)) + { + flags &= ~PDC_CONV_NOBOM; + } + + if (!inalloc || flags & PDC_CONV_WITHBOM || flags & PDC_CONV_NOBOM) + { + i = (flags & PDC_CONV_WITHBOM && !hasbom) ? 3 : 0; + j = (flags & PDC_CONV_NOBOM && hasbom) ? 3 : 0; + + len = inlen + i - j; + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (len + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (len + 2), fn)); + memcpy(&instr[i], &instring[j], (size_t) (inlen - j)); + instr[len] = 0; + + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + instring = instr; + instr = NULL; + inlen = len; + + hasbom = (flags & PDC_CONV_WITHBOM); + } + + if (hasbom) + { + instring[0] = PDF_BOM2; + instring[1] = PDF_BOM3; + instring[2] = PDF_BOM4; + } + + } + + /* UTF-16 formats */ + if (inutf == pdc_utf16 || inutf == pdc_utf16be || inutf == pdc_utf16le) + { + hasbom = pdc_is_utf16be_unicode(instring) || + pdc_is_utf16le_unicode(instring); + + if (hasbom && (flags & PDC_CONV_AUTOBOM)) + { + flags &= ~PDC_CONV_NOBOM; + flags |= PDC_CONV_WITHBOM; + } + else if ((flags & PDC_CONV_WITHBOM) && (flags & PDC_CONV_NOBOM)) + { + flags &= ~PDC_CONV_NOBOM; + } + + if (!inalloc || oututf == pdc_utf16be || oututf == pdc_utf16le || + flags & PDC_CONV_WITHBOM || flags & PDC_CONV_NOBOM) + { + i = (flags & PDC_CONV_WITHBOM && !hasbom) ? 2 : 0; + j = (flags & PDC_CONV_NOBOM && hasbom) ? 2 : 0; + + len = inlen + i - j; + instr = (pdc_byte *) ((flags & PDC_CONV_TMPALLOC) ? + pdc_calloc_tmp(pdc, (size_t) (len + 2), fn, NULL, NULL) : + pdc_calloc(pdc, (size_t) (len + 2), fn)); + memcpy(&instr[i], &instring[j], (size_t) (inlen - j)); + + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + instring = instr; + instr = NULL; + inlen = len; + + hasbom = (flags & PDC_CONV_WITHBOM); + } + + i = hasbom ? 2 : 0; + if (inutf == pdc_utf16) + { + if (oututf == pdc_utf16be) + { + inutf = pdc_utf16be; + toswap = !PDC_ISBIGENDIAN; + } + if (oututf == pdc_utf16le) + { + inutf = pdc_utf16le; + toswap = PDC_ISBIGENDIAN; + } + if (toswap) + pdc_swap_bytes((char *) &instring[i], inlen - i, NULL); + } + + if (hasbom) + { + if (inutf == pdc_utf16be || + (inutf == pdc_utf16 && PDC_ISBIGENDIAN)) + { + instring[0] = PDF_BOM0; + instring[1] = PDF_BOM1; + } + if (inutf == pdc_utf16le || + (inutf == pdc_utf16 && !PDC_ISBIGENDIAN)) + { + instring[0] = PDF_BOM1; + instring[1] = PDF_BOM0; + } + } + } + + if (logg) + pdc_logg(pdc, "\t\ttextformat of converted string: %s\n", + pdc_get_keyword(inutf, pdc_textformat_keylist)); + + PDC_CONV_EXIT: + *oututf_p = inutf; + if (outlen) + *outlen = inlen; + *outstring = instring; + return 0; + + PDC_CONV_ERROR: + if (outlen) + *outlen = 0; + *outstring = NULL; + + if (errcode > 0) + pdc_set_errmsg(pdc, errcode, stemp1, stemp2, 0, 0); + + if (instr != NULL) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instr); + else + pdc_free(pdc, instr); + } + + if (inalloc) + { + if (flags & PDC_CONV_TMPALLOC) + pdc_free_tmp(pdc, instring); + else + pdc_free(pdc, instring); + } + + if (verbose) + PDC_RETHROW(pdc); + + return errcode; +} +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma managed +#endif + + +/* + * pdc_convert_name_ext converts a string of name data type to UTF-8 + * + * flags & PDC_CONV_EBCDIC: converts to EBCDIC-UTF-8 + * + * len == 0: If the string has a [EBCDIC-]UTF-8 BOM or + * flags & PDC_CONV_ISUTF8 is set the string will be duplicated. + * Otherwise the string has encoding enc and codepage + * codepage. + * If enc < pdc_winansi the string is "host" encoded. + * + * len > 0: The string is a UTF-16 string of len bytes. + * + */ +char * +pdc_convert_name_ext(pdc_core *pdc, const char *name, int len, + pdc_encoding enc, int codepage, int flags) +{ + pdc_encodingvector *ev = NULL; + pdc_text_format nameformat = pdc_utf16; + pdc_text_format outnameformat = pdc_utf8; + pdc_byte *convname; + char *outname = NULL; + int outlen; + + if (name == NULL) + return NULL; + + if (len == 0) + { + pdc_bool hasbom = pdc_is_utf8_bytecode(name); + pdc_bool withbom = (flags & PDC_CONV_WITHBOM) ? pdc_true : pdc_false; + + /* already [EBCDIC-]UTF-8 encoded */ + if ((flags & PDC_CONV_ISUTF8) || hasbom) + { + if ((hasbom && withbom) || (!hasbom && !withbom)) + outname = pdc_strdup(pdc, name); + else if (hasbom && !withbom) + outname = pdc_strdup(pdc, &name[3]); + else if (!hasbom && withbom) + outname = pdc_strdup_withbom(pdc, name); + if (outname != NULL) + { + return outname; + } + } + + /* 8-bit encoded string */ + nameformat = pdc_bytes; + if (enc < pdc_winansi) + ev = pdc_get_encoding_vector(pdc, pdc_find_encoding(pdc, "host")); + else + ev = pdc_get_encoding_vector(pdc, enc); + + len = (int) strlen(name); + } + + if (flags & PDC_CONV_EBCDIC) + outnameformat = PDC_UTF8; + + flags |= PDC_CONV_TRY7BYTES; + if (pdc->charref) + flags |= PDC_CONV_HTMLCHAR; + if (pdc->escapesequ) + flags |= PDC_CONV_BSSEQU; + + /* convert to UTF-8 */ + pdc_convert_string(pdc, nameformat, codepage, ev, (pdc_byte *) name, len, + &outnameformat, NULL, &convname, &outlen, flags, + pdc_true); + + return (char *) convname; +} + +char * +pdc_convert_name(pdc_core *pdc, const char *name, int len, int flags) +{ + return pdc_convert_name_ext(pdc, name, len, pdc_invalidenc, 0, flags); +} + +char * +pdc_utf8_to_hostbytes(pdc_core *pdc, pdc_bool honorlang, char *name) +{ + static const char fn[] = "pdc_utf8_to_hostbytes"; + pdc_encoding outenc = pdc_invalidenc; + pdc_encodingvector *outev = NULL; + pdc_text_format informat = PDC_UTF8; + pdc_text_format outformat = pdc_utf16; + pdc_byte *outname = NULL; + int len = (int) strlen(name); + + { + (void) fn; + (void) honorlang; + outenc = pdc_find_encoding(pdc, "host"); + } + + outev = pdc_get_encoding_vector(pdc, outenc); + + pdc_convert_string(pdc, informat, 0, NULL, (pdc_byte *) name, len, + &outformat, outev, &outname, &len, + PDC_CONV_TRYBYTES | PDC_CONV_NOBOM, pdc_true); + if (outformat == pdc_utf16) + { + pdc_free(pdc, outname); + outname = NULL; + } + + return (char *) outname; +} + +char * +pdc_hostbytes_to_utf8(pdc_core *pdc, pdc_bool honorlang, char *name) +{ + static const char fn[] = "pdc_hostbytes_to_utf8"; + pdc_encoding inenc = pdc_invalidenc; + pdc_encodingvector *inev = NULL; + pdc_text_format informat = pdc_bytes; + pdc_text_format outformat = PDC_UTF8; + pdc_byte *outname = NULL; + int len = (int) strlen(name); + + { + (void) fn; + (void) honorlang; + inenc = pdc_find_encoding(pdc, "host"); + } + + inev = pdc_get_encoding_vector(pdc, inenc); + + pdc_convert_string(pdc, informat, 0, inev, (pdc_byte *) name, len, + &outformat, NULL, &outname, &len, + PDC_CONV_NOBOM, pdc_true); + + return (char *) outname; +} + +/* --------------------- basic UTF conversion functions --------------------- */ + +char * +pdc_utf16_to_utf8(pdc_core *pdc, const char *utf16string, int len, int flags, + int *size) +{ + pdc_text_format outtextformat = pdc_utf8; + pdc_byte *utf8string = NULL; + int outlen; + + if (!utf16string) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, "utf16string", 0, 0, 0); + + if (flags & PDC_CONV_EBCDIC) + outtextformat = PDC_UTF8; + + flags |= PDC_CONV_AUTOBOM; + pdc_convert_string(pdc, pdc_utf16, 0, NULL, + (pdc_byte *) utf16string, len, + &outtextformat, NULL, &utf8string, &outlen, + flags, pdc_true); + + if (size) *size = outlen; + + return (char *) utf8string; +} + +char * +pdc_utf8_to_utf16(pdc_core *pdc, const char *utf8string, const char *format, + int flags, int *size) +{ + pdc_text_format textformat = pdc_utf8; + pdc_text_format outtextformat = pdc_utf16; + pdc_byte *utf16string = NULL; + int len; + + if (!utf8string) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, "utf8string", 0, 0, 0); + len = (int) strlen(utf8string); + + if (format && *format) + { + int k = pdc_get_keycode_ci(format, pdc_textformat_keylist); + if (k == PDC_KEY_NOTFOUND || + ((pdc_text_format) k != pdc_utf16 && + (pdc_text_format) k != pdc_utf16be && + (pdc_text_format) k != pdc_utf16le)) + pdc_error(pdc, PDC_E_ILLARG_STRING, "format", format, 0, 0); + outtextformat = (pdc_text_format) k; + } + + if (flags & PDC_CONV_EBCDIC) + textformat = PDC_UTF8; + + if (outtextformat == pdc_utf16) + flags |= PDC_CONV_AUTOBOM; + else + flags |= PDC_CONV_WITHBOM; + pdc_convert_string(pdc, textformat, 0, NULL, + (pdc_byte *) utf8string, len, + &outtextformat, NULL, &utf16string, size, + flags, pdc_true); + + return (char *) utf16string; +} + +char * +pdc_utf16_to_utf32(pdc_core *pdc, const char *utf16string, int len, int *size) +{ + pdc_text_format outtextformat = pdc_utf32; + pdc_byte *utf32string = NULL; + + if (!utf16string) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, "utf16string", 0, 0, 0); + + pdc_convert_string(pdc, pdc_utf16, 0, NULL, + (pdc_byte *) utf16string, len, + &outtextformat, NULL, &utf32string, size, + 0, pdc_true); + + return (char *) utf32string; +} + +char * +pdc_utf32_to_utf8(pdc_core *pdc, const char *utf32string, int len, int flags, + int *size) +{ + pdc_text_format outtextformat = pdc_utf8; + pdc_byte *utf8string = NULL; + int outlen; + + if (!utf32string) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, "utf32string", 0, 0, 0); + + if (flags & PDC_CONV_EBCDIC) + outtextformat = PDC_UTF8; + + flags |= PDC_CONV_AUTOBOM; + pdc_convert_string(pdc, pdc_utf32, 0, NULL, + (pdc_byte *) utf32string, len, + &outtextformat, NULL, &utf8string, &outlen, + flags, pdc_true); + + if (size) *size = outlen; + + return (char *) utf8string; +} + +char * +pdc_utf32_to_utf16(pdc_core *pdc, const char *utf32string, int len, + const char *format, int flags, int *size) +{ + pdc_text_format textformat = pdc_utf32; + pdc_text_format outtextformat = pdc_utf16; + pdc_byte *utf16string = NULL; + + if (!utf32string) + pdc_error(pdc, PDC_E_ILLARG_EMPTY, "utf32string", 0, 0, 0); + + if (format && *format) + { + int k = pdc_get_keycode_ci(format, pdc_textformat_keylist); + if (k == PDC_KEY_NOTFOUND || + ((pdc_text_format) k != pdc_utf16 && + (pdc_text_format) k != pdc_utf16be && + (pdc_text_format) k != pdc_utf16le)) + pdc_error(pdc, PDC_E_ILLARG_STRING, "format", format, 0, 0); + outtextformat = (pdc_text_format) k; + } + + if (outtextformat == pdc_utf16) + flags |= PDC_CONV_AUTOBOM; + else + flags |= PDC_CONV_WITHBOM; + pdc_convert_string(pdc, textformat, 0, NULL, + (pdc_byte *) utf32string, len, + &outtextformat, NULL, &utf16string, size, + flags, pdc_true); + + return (char *) utf16string; +} + +int +pdc_char16_to_char32(pdc_core *pdc, const pdc_ushort *ustext, int *ic, int len, + pdc_bool verbose) +{ + pdc_ushort uvh = ustext[*ic]; + + if (uvh < PDC_UNICODE_MINHIGHSUR || uvh > PDC_UNICODE_MAXLOWSUR) + { + return (int) uvh; + } + else + { + UTF16 *isa16 = (UTF16 *) &ustext[*ic]; + pdc_ushort uvl = 0; + int icn = *ic + 1; + + if (icn < len) + { + uvl = ustext[icn]; + if (uvh <= PDC_UNICODE_MAXHIGHSUR) + { + if (uvl >= PDC_UNICODE_MINLOWSUR && + uvl <= PDC_UNICODE_MAXLOWSUR) + { + int usv; + UTF16 *ise16 = isa16 + 2; + UTF32 *isa32 = (UTF32 *) &usv; + UTF32 *ise32 = isa32 + 1; + + pdc_convers_result result = pdc_convertUTF16toUTF32( + &isa16, ise16, &isa32, ise32, strictConversion); + if (result == conversionOK) + { + *ic = icn; + return usv; + } + } + } + } + + pdc_set_errmsg(pdc, PDC_E_CONV_ILLUTF16SUR, + pdc_errprintf(pdc, "%04X", uvh), + pdc_errprintf(pdc, "%04X", uvl), 0, 0); + + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + } + + return -1; +} + +int +pdc_char32_to_char16(pdc_core *pdc, int usv, pdc_ushort *uvlist, + pdc_bool verbose) +{ + if (usv < PDC_NUM_BMPVAL) + { + uvlist[0] = (pdc_ushort) usv; + return 1; + } + else + { + UTF32 *isa32 = (UTF32 *) &usv; + UTF32 *ise32 = isa32 + 1; + UTF16 *isa16 = (UTF16 *) uvlist; + UTF16 *ise16 = isa16 + 2; + + pdc_convers_result result = pdc_convertUTF32toUTF16( + &isa32, ise32, &isa16, ise16, strictConversion); + if (result == conversionOK) + { + return 2; + } + + pdc_set_errmsg(pdc, PDC_E_CONV_ILLUTF32, + pdc_errprintf(pdc, "%05X", usv), 0, 0, 0); + + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + } + + return 0; +} diff --git a/src/pdflib/pdcore/pc_unicode.h b/src/pdflib/pdcore/pc_unicode.h new file mode 100644 index 0000000..c5c1354 --- /dev/null +++ b/src/pdflib/pdcore/pc_unicode.h @@ -0,0 +1,283 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_unicode.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Unicode glyph name conversion routines + * + */ + +#ifndef PC_UNICODE_H +#define PC_UNICODE_H + +#define PDC_NUM_BMPVAL 0x10000 +#define PDC_NUM_UNIVAL 0x110000 +#define PDC_MAX_UNIVAL 0x10FFFF + +#define PDC_UNICODE_HT 0x0009 +#define PDC_UNICODE_LF 0x000A +#define PDC_UNICODE_VT 0x000B +#define PDC_UNICODE_FF 0x000C +#define PDC_UNICODE_CR 0x000D +#define PDC_UNICODE_ETB 0x0017 +#define PDC_UNICODE_ESC 0x001B +#define PDC_UNICODE_SPACE 0x0020 +#define PDC_UNICODE_QUOTMARK 0x0022 +#define PDC_UNICODE_AMPERSAND 0x0026 +#define PDC_UNICODE_APOSTROPHE 0x0027 +#define PDC_UNICODE_HYPHEN 0x002D +#define PDC_UNICODE_PERIOD 0x002E +#define PDC_UNICODE_SEMICOLON 0x003B +#define PDC_UNICODE_LESS_THAN 0x003C +#define PDC_UNICODE_GREATER_THAN 0x003E +#define PDC_UNICODE_BACKSLASH 0x005C +#define PDC_UNICODE_LEFT_CURLY 0x007B +#define PDC_UNICODE_RIGHT_CURLY 0x007D +#define PDC_UNICODE_DELETE 0x007F +#define PDC_UNICODE_NEL 0x0085 +#define PDC_UNICODE_NBSP 0x00A0 +#define PDC_UNICODE_SHY 0x00AD +#define PDC_UNICODE_MACRON 0x00AF +#define PDC_UNICODE_MICRO 0x00B5 +#define PDC_UNICODE_MIDDLEDOT 0x00B7 +#define PDC_UNICODE_MODMACRON 0x02C9 +#define PDC_UNICODE_CAPDELTA 0x0394 +#define PDC_UNICODE_CAPOMEGA 0x03A9 +#define PDC_UNICODE_SMALLMU 0x03BC +#define PDC_UNICODE_LS 0x2028 +#define PDC_UNICODE_PS 0x2029 +#define PDC_UNICODE_NNBSP 0x202F +#define PDC_UNICODE_FRACSLASH 0x2044 +#define PDC_UNICODE_MMSPACE 0x205F +#define PDC_UNICODE_EURO 0x20AC +#define PDC_UNICODE_OHMSIGN 0x2126 +#define PDC_UNICODE_INCREMENT 0x2206 +#define PDC_UNICODE_DIVSLASH 0x2215 +#define PDC_UNICODE_BULLETOP 0x2219 +#define PDC_UNICODE_IDEOSPACE 0x3000 + +/* maximal value of Latin-1 characters */ +#define PDC_UNICODE_MAXASCII 0x007F +#define PDC_UNICODE_MAXLATIN1 0x00FF + +/* maximal resp. single value of Japanese HW characters */ +#define PDC_UNICODE_MAXHW 0x007E +#define PDC_UNICODE_SINGHW 0x00A5 + +/* Unicode borders of fullwidth forms of ASCII characters */ +#define PDC_UNICODE_MINFWASCII 0xFF00 +#define PDC_UNICODE_MAXFWASCII 0xFF5E +#define PDC_UNICODE_DIFFWASCII 0xFEE0 + /* PDC_UNICODE_MINFASCII - PDC_UNICODE_SPACE */ + +/* Unicode borders of fullwidth forms of Symbol characters */ +#define PDC_UNICODE_MINFWSYMBOL 0xFFE0 +#define PDC_UNICODE_MAXFWSYMBOL 0xFFE6 + +/* Unicode borders of Private Use Area (PUA) */ +#define PDC_UNICODE_MINPUA 0xE000 +#define PDC_UNICODE_MAXPUA 0xF8FF + +/* Begin of PDFlib PUA */ +#define PDC_UNICODE_PDFPUA 0xF200 + +/* Unicode borders of Unicode Corporate Use Subarea as used by Adobe Systems */ +#define PDC_UNICODE_MINCUS 0xF600 +#define PDC_UNICODE_MAXCUS 0xF8FF + +/* Unicode Surrogate ranges */ +#define PDC_UNICODE_MINHIGHSUR 0xD800 +#define PDC_UNICODE_MAXHIGHSUR 0xDBFF +#define PDC_UNICODE_MINLOWSUR 0xDC00 +#define PDC_UNICODE_MAXLOWSUR 0xDFFF + +/* Unicode borders of higher Unicode spaces */ +#define PDC_UNICODE_MINSPACE 0x2000 +#define PDC_UNICODE_MAXSPACE 0x200B + +/* Unicode borders of CJK compatibility forms and small form variants */ +#define PDC_UNICODE_MINCJKFORMS 0xFE30 +#define PDC_UNICODE_MIDCJKFORMS 0xFE48 +#define PDC_UNICODE_MAXCJKFORMS 0xFE6F + +/* replacement character */ +#define PDC_UNICODE_REPLCHAR 0xFFFD + +/* special character for CRLF */ +#define PDF_UNICODE_CRLF 0xFDD0 + +/* not a character */ +#define PDC_UNICODE_NOTCHAR 0xFFFF + +/* Latin and Armenian ligatures */ +#define PDC_UNICODE_CAPLIGATIJ 0x0132 +#define PDC_UNICODE_SMALLLIGATIJ 0x0133 +#define PDC_UNICODE_MINLIGAT 0xFB00 +#define PDC_UNICODE_MAXLIGAT 0xFB17 + + +/* The Unicode byte order mark (BOM) byte parts */ +#define PDC_UNICODE_BOM 0xFEFF +#define PDF_BOM0 0xFE +#define PDF_BOM1 0xFF +#define PDF_BOM2 0xEF +#define PDF_BOM3 0xBB +#define PDF_BOM4 0xBF + +/* + * check whether the string is plain C or UTF16 unicode + * by looking for the BOM in big-endian or little-endian format resp. + * s must not be NULL. + */ +#define pdc_is_utf16be_unicode(s) \ + (((pdc_byte *)(s))[0] == PDF_BOM0 && \ + ((pdc_byte *)(s))[1] == PDF_BOM1) + +#define pdc_is_utf16le_unicode(s) \ + (((pdc_byte *)(s))[0] == PDF_BOM1 && \ + ((pdc_byte *)(s))[1] == PDF_BOM0) + +/* + * check whether the string is plain C or UTF8 unicode + * by looking for the BOM + * s must not be NULL. + */ +#define pdc_is_utf8_unicode(s) \ + (((pdc_byte *)(s))[0] == PDF_BOM2 && \ + ((pdc_byte *)(s))[1] == PDF_BOM3 && \ + ((pdc_byte *)(s))[2] == PDF_BOM4) + + +#define PDC_UTF8_STRING "\xEF\xBB\xBF" +#define pdc_is_utf8_bytecode(s) \ + (((pdc_byte *)(s))[0] == PDF_BOM2 && \ + ((pdc_byte *)(s))[1] == PDF_BOM3 && \ + ((pdc_byte *)(s))[2] == PDF_BOM4) +#define pdc_copy_utf8_bom(s) \ + ((pdc_byte *)(s))[0] = PDF_BOM2, \ + ((pdc_byte *)(s))[1] = PDF_BOM3, \ + ((pdc_byte *)(s))[2] = PDF_BOM4; +#define PDC_UTF8 pdc_utf8 +#define PDC_UTF8_STRG "utf8" +#define PDC_UTF8_FLAG pdc_false + + +#define PDC_HTML_CTRLCHAR '&' +#define PDC_HTML_DELIMITCHAR ';' + +typedef enum +{ + conversionOK, /* conversion successful */ + sourceExhausted, /* partial character in source, but hit end */ + targetExhausted, /* insuff. room in target for conversion */ + sourceIllegal /* source sequence is illegal/malformed */ +} +pdc_convers_result; + +typedef enum +{ + strictConversion = 0, + lenientConversion +} +pdc_convers_flags; + +/* flags for pdc_convert_string(), pdc_strdup_ext(), + * pdc_utfxx6_to_utfxx(), pdc_convert_name_ext() + */ +#define PDC_CONV_FORCEUTF16 (1<<0) +#define PDC_CONV_TRY7BYTES (1<<1) +#define PDC_CONV_TRYBYTES (1<<2) +#define PDC_CONV_WITHBOM (1<<3) +#define PDC_CONV_NOBOM (1<<4) +#define PDC_CONV_AUTOBOM (1<<5) +#define PDC_CONV_ANALYZE (1<<6) +#define PDC_CONV_TMPALLOC (1<<7) +#define PDC_CONV_HTMLCHAR (1<<8) +#define PDC_CONV_NEWALLOC (1<<9) +#define PDC_CONV_INFLATE (1<<10) +#define PDC_CONV_ESCSEQU (1<<11) +#define PDC_CONV_BSSEQU (1<<12) +#define PDC_CONV_EBCDIC (1<<13) +#define PDC_CONV_ENCERROR (1<<14) +#define PDC_CONV_KEEPLBCHAR (1<<15) +#define PDC_CONV_LOGGING (1<<16) +#define PDC_CONV_ISUTF8 (1<<17) + +/* DON'T change the order */ +typedef enum +{ + pdc_auto = 1, + pdc_auto2 = 2, + pdc_bytes = 3, + pdc_bytes2 = 4, + pdc_utf8 = 5, /* UTF-8 */ + + pdc_utf16 = 7, /* UTF-16 */ + pdc_utf16be = 8, /* UTF-16 big endian */ + pdc_utf16le = 9, /* UTF-16 little endian */ + pdc_utf32 = 10 /* UTF-32 */ +} +pdc_text_format; + +/* copy for pdflib in p_keyconn.h */ +#if defined(PC_UNICODE_C) +static const pdc_keyconn pdc_textformat_keylist[] = +{ + {"auto", pdc_auto}, + {"auto2", pdc_auto2}, + {"bytes", pdc_bytes}, + {"bytes2", pdc_bytes2}, + {"utf8", pdc_utf8}, + {"utf16", pdc_utf16}, + {"utf16be", pdc_utf16be}, + {"utf16le", pdc_utf16le}, + {NULL, 0} +}; +#endif /* PC_UNICODE_C */ + +int pdc_convert_string(pdc_core *pdc, + pdc_text_format inutf, int codepage, pdc_encodingvector *inev, + pdc_byte *instring, int inlen, pdc_text_format *oututf_p, + pdc_encodingvector *outev, pdc_byte **outstring, int *outlen, int flags, + pdc_bool verbose); + +int pdc_convert_textstring(pdc_core *pdc, + pdc_text_format inutf, int codepage, pdc_encodingvector *inev, + const pdc_glyph_tab *glyphtab, int tabsize, int replchar, + pdc_byte *instring, int inlen, + pdc_text_format *oututf_p, pdc_encodingvector *outev, + pdc_byte **outstring, int *outlen, int flags, + pdc_bool verbose); + +char *pdc_convert_name(pdc_core *pdc, const char *name, int len, int flags); +char *pdc_convert_name_ext(pdc_core *pdc, const char *name, int len, + pdc_encoding enc, int codepage, int flags); + +char *pdc_utf8_to_hostbytes(pdc_core *pdc, pdc_bool honorlang, char *name); +char *pdc_hostbytes_to_utf8(pdc_core *pdc, pdc_bool honorlang, char *name); + +char *pdc_utf16_to_utf8(pdc_core *pdc, const char *utf16string, int len, + int flags, int *size); +char *pdc_utf8_to_utf16(pdc_core *pdc, const char *utf8string, + const char *format, int flags, int *size); +char *pdc_utf16_to_utf32(pdc_core *pdc, const char *utf16string, int len, + int *size); +char *pdc_utf32_to_utf8(pdc_core *pdc, const char *utf32string, int len, + int flags, int *size); +char *pdc_utf32_to_utf16(pdc_core *pdc, const char *utf32string, int len, + const char *format, int flags, int *size); +int pdc_char16_to_char32(pdc_core *pdc, const pdc_ushort *ustext, int *ic, + int len, pdc_bool verbose); +int pdc_char32_to_char16(pdc_core *pdc, int usv, pdc_ushort *uvlist, + pdc_bool verbose); + +#endif /* PC_UNICODE_H */ diff --git a/src/pdflib/pdcore/pc_util.c b/src/pdflib/pdcore/pc_util.c new file mode 100644 index 0000000..320ee52 --- /dev/null +++ b/src/pdflib/pdcore/pc_util.c @@ -0,0 +1,2726 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_util.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * PDFlib various utility routines + * + */ + +#include + +#include "pc_util.h" +#include "pc_file.h" +#include "pc_ctype.h" + +#ifdef AS400 +#include /* for getenv() emulation */ +#endif + +#ifdef __sun +#include /* for finite */ +#endif + +#if defined (isfinite) +#define PDC_ISFINITE isfinite +#else /* isfinite */ + +#ifdef _WIN32 +#include +#include +#define PDC_ISFINITE _finite +#else /* _WIN32 */ + +#ifdef OS_ZOS_SASC +#define PDC_ISFINITE isfinite +#else /* OS_ZOS_SASC */ + +#define PDC_ISFINITE finite +#endif +#endif +#endif + + +/* ------------------- Floating-point number check ----------------------- */ + + + +/* + * pdc_check_number checks whether a floating-point number + * is valid and within the specified range. If not, an exception + * will be thrown. + */ +void +pdc_check_number_limits(pdc_core *pdc, const char *paramname, double dz, + double dmin, double dmax) +{ + if (!PDC_ISFINITE(dz)) + { + pdc_error(pdc, PDC_E_ILLARG_FLOAT_NAN, paramname, 0, 0, 0); + } + else if (dz < dmin) + { + pdc_error(pdc, PDC_E_ILLARG_FLOAT_TOOSMALL, paramname, + pdc_errprintf(pdc, "%f", dz), + pdc_errprintf(pdc, "%f", dmin), 0); + } + else if (dz > dmax) + { + pdc_error(pdc, PDC_E_ILLARG_FLOAT_TOOLARGE, paramname, + pdc_errprintf(pdc, "%f", dz), + pdc_errprintf(pdc, "%f", dmax), 0); + } +} + +void +pdc_check_number(pdc_core *pdc, const char *paramname, double dz) +{ + pdc_check_number_limits(pdc, paramname, dz, PDC_FLOAT_MIN, PDC_FLOAT_MAX); +} + +void +pdc_check_number_zero(pdc_core *pdc, const char *paramname, double dz) +{ + pdc_check_number_limits(pdc, paramname, dz, PDC_FLOAT_MIN, PDC_FLOAT_MAX); + + if (PDC_FLOAT_ISNULL(dz)) + { + pdc_error(pdc, PDC_E_ILLARG_FLOAT_ZERO, paramname, + pdc_errprintf(pdc, "%f", dz), 0, 0); + } +} + + +/* ---------------- "unsupported feature" error message ------------------ */ + +void +pdc_set_unsupp_error(pdc_core *pdc, int err_config, int err_lite, + pdc_bool warning) +{ + (void) err_config; + (void) err_lite; + +/* this feature is sufficient for non public version */ + if (warning) + pdc_warning(pdc, err_lite, 0, 0, 0, 0); + else + pdc_error(pdc, err_lite, 0, 0, 0, 0); +} + + +/* -------------------------- Time functions ------------------------------ */ + +#ifndef WINCE +#ifndef __USE_POSIX +#define __USE_POSIX +#endif +#include +#else +#include +#endif + +/* our private localtime() function. this one circumvents platform +** quirks we found on WINCE and Solaris, and perhaps some more in +** the future. +*/ +void +pdc_localtime(pdc_time *t) +{ +#ifdef WINCE + + SYSTEMTIME st; + + GetLocalTime (&st); + + t->second = st.wSecond; + t->minute = st.wMinute; + t->hour = st.wHour; + t->mday = st.wDay; + t->wday = st.wDayOfWeek; + t->month = st.wMonth; + t->year = st.wYear; + +#else + + time_t timer; + struct tm ltime; + + time(&timer); + +#if defined(PDC_NEEDS_R_FUNCTIONS) + + /* the localtime() function isn't thread safe on this platform. + ** a thread safe variant must be used instead. + */ + (void) localtime_r(&timer, <ime); + +#else + + ltime = *localtime(&timer); + +#endif /* !PDC_NEEDS_R_FUNCTIONS */ + + t->second = ltime.tm_sec; + t->minute = ltime.tm_min; + t->hour = ltime.tm_hour; + t->mday = ltime.tm_mday; + t->wday = ltime.tm_wday; + t->month = ltime.tm_mon; + t->year = ltime.tm_year; + +#endif /* !WINCE */ +} + +static void +pdc_localtime_r(const time_t *timer, struct tm *res) +{ +#if defined(PDC_NEEDS_R_FUNCTIONS) + (void) localtime_r(timer, res); +#else + *res = *localtime(timer); +#endif +} + +static void +pdc_gmtime_r(const time_t *timer, struct tm *res) +{ +#if defined(PDC_NEEDS_R_FUNCTIONS) + (void) gmtime_r(timer, res); +#else + *res = *gmtime(timer); +#endif +} + +void +pdc_get_timestr(char *str, pdc_bool ktoascii) +{ +#ifndef WINCE + time_t timer, gtimer; + struct tm ltime; + double diffminutes; + int utcoffset; +#else + SYSTEMTIME st; +#endif + + (void) ktoascii; + +#ifndef WINCE + time(&timer); + +#if !defined(I370) + pdc_gmtime_r(&timer, <ime); + gtimer = mktime(<ime); + pdc_localtime_r(&timer, <ime); + ltime.tm_isdst = 0; + diffminutes = difftime(mktime(<ime), gtimer) / 60; + if (diffminutes >= 0) + utcoffset = (int)(diffminutes + 0.5); + else + utcoffset = (int)(diffminutes - 0.5); +#else + utcoffset = 0; +#endif + + /* Get local time again, previous data is damaged by mktime(). */ + pdc_localtime_r(&timer, <ime); + + if (utcoffset > 0) + sprintf(str, "D:%04d%02d%02d%02d%02d%02d+%02d'%02d'", + ltime.tm_year + 1900, ltime.tm_mon + 1, ltime.tm_mday, + ltime.tm_hour, ltime.tm_min, ltime.tm_sec, + utcoffset / 60, utcoffset % 60); + else if (utcoffset < 0) + sprintf(str, "D:%04d%02d%02d%02d%02d%02d-%02d'%02d'", + ltime.tm_year + 1900, ltime.tm_mon + 1, ltime.tm_mday, + ltime.tm_hour, ltime.tm_min, ltime.tm_sec, + abs(utcoffset) / 60, abs(utcoffset) % 60); + else + sprintf(str, "D:%04d%02d%02d%02d%02d%02dZ", + ltime.tm_year + 1900, ltime.tm_mon + 1, ltime.tm_mday, + ltime.tm_hour, ltime.tm_min, ltime.tm_sec); + +#else + GetLocalTime (&st); + sprintf(str, "D:%04d%02d%02d%02d%02d%02d", + st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); +#endif /* !WINCE */ + + +} + + +/* -------------------------- Environment ------------------------------ */ + +char * +pdc_getenv(const char *name) +{ +#ifdef HAVE_ENVVARS + return getenv(name); +#else + (void) name; + + return (char *) 0; +#endif +} + + +/* ------------------------ Language Code ------------------------------ */ + +/* ISO 639 Windows and Mac Language codes */ +static const char lang_codes_ISO639[] = + "ab aa af sq am ar hy as ay az ba eu bn dz bh bi br bg my be km ca zh co" + "hr cs da nl en eo et fo fa fj fi fr fy gl gd gv ka de el kl gn gu ha he" + "hi hu is id ia ie iu ik ga it ja jv kn ks kk rw ky rn ko ku lo la lv li" + "ln lt mk mg ms ml mt mi mr mo mn na ne no oc or om ps pl pt pa qu rm ro" + "ru sm sg sa sr sh st tn sn sd si ss sk sl so es su sw sv tl tg ta tt te" + "th bo ti to ts tr tk tw ug uk ur uz vi vo cy wo xh yi yo zu" + "pt-br en-gb en-us de-de de-ch"; + +pdc_bool +pdc_check_lang_code(pdc_core *pdc, const char* lang_code) +{ + pdc_bool valid = pdc_false; + int i; + char* country_code; + char* language; + + if ((lang_code != NULL) && *lang_code) + { + /* do not check for IANA or private languages */ + if (!(valid = ((lang_code[0] == 'i') || (lang_code[0] == 'x')))) + { + language = pdc_strdup(pdc, lang_code); + for (i = 0; i < (int)strlen(language); i++) + { + if (pdc_isupper(language[i])) + { + language[i] = (char) pdc_tolower((int)language[i]); + } + } + + + country_code = (char *)strstr(lang_codes_ISO639, language); + valid = (country_code != NULL); + + if (!valid && (strlen(language) > 2)) + { + country_code = strchr(language, '-'); + if (country_code != NULL) + { + country_code[0] = '\0'; + + country_code = (char *)strstr(lang_codes_ISO639, language); + valid = (country_code != NULL); + + if (!valid) + { + pdc_warning(pdc, PDC_E_ILLARG_LANG_CODE, + lang_code, 0, 0, 0); + } + } + } + + pdc_free(pdc, language); + } + } + + return valid; +} + + +/* -------------------------- Bit arryas ------------------------------ */ + +void +pdc_setbit(char *bitarr, int bit) +{ + bitarr[bit/8] |= (char) (1<<(bit%8)); +} + +pdc_bool +pdc_getbit(const char *bitarr, int bit) +{ + return (pdc_bool) (bitarr[bit/8] & (1<<(bit%8))); +} + +void +pdc_setbit_text(char *bitarr, const pdc_byte *text, int len, + int nbits, int size) +{ + int i, bit; + pdc_ushort *ustext = (pdc_ushort *) text; + + for (i = 0; i < len; i += size) + { + if (size == sizeof(pdc_byte)) + bit = (int) text[i]; + else + bit = ustext[i/size]; + if (bit < nbits) pdc_setbit(bitarr, bit); + } +} + + +/* ---------- Get functions of integer binary data types --------------- */ + +pdc_short +pdc_get_le_short(const pdc_byte *data) +{ + return (pdc_short) ((pdc_short) (data[1] << 8) | data[0]); +} + +pdc_ushort +pdc_get_le_ushort(const pdc_byte *data) +{ + return (pdc_ushort) ((data[1] << 8) | data[0]); +} + +pdc_uint32 +pdc_get_le_ulong3(const pdc_byte *data) +{ + return (pdc_uint32) (((((data[2]) << 8) | data[1]) << 8) | data[0]); +} + +pdc_sint32 +pdc_get_le_long(const pdc_byte *data) +{ + return ((pdc_sint32) + (((((data[3] << 8) | data[2]) << 8) | data[1]) << 8) | data[0]); +} + +pdc_uint32 +pdc_get_le_ulong(const pdc_byte *data) +{ + return (pdc_uint32) + ((((((data[3] << 8) | data[2]) << 8) | data[1]) << 8) | data[0]); +} + +pdc_short +pdc_get_be_short(const pdc_byte *data) +{ + return (pdc_short) ((pdc_short) (data[0] << 8) | data[1]); +} + +pdc_ushort +pdc_get_be_ushort(const pdc_byte *data) +{ + return (pdc_ushort) ((data[0] << 8) | data[1]); +} + +pdc_uint32 +pdc_get_be_ulong3(const pdc_byte *data) +{ + return (pdc_uint32) (((((data[0]) << 8) | data[1]) << 8) | data[2]); +} + +pdc_sint32 +pdc_get_be_long(const pdc_byte *data) +{ + return ((pdc_sint32) + (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]); +} + +pdc_uint32 +pdc_get_be_ulong(const pdc_byte *data) +{ + return (pdc_uint32) + ((((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]); +} + + +/* ----------------- String handling for Unicode too ------------------- */ + +/* strlen() for unicode strings, which are terminated by two zero bytes. + * wstrlen() returns the number of bytes in the Unicode string, + * not including the two terminating null bytes. + */ +static size_t +wstrlen(const char *s) +{ + size_t len = 0; + + while(s[len] != 0 || s[len+1] != 0) + { + len += 2; + } + + return len; +} + +/* + * This function returns the length in bytes for C and Unicode strings. + * Note that unlike strlen() it returns the length _including_ the + * terminator, which may be one or two null bytes. + */ +size_t +pdc_strlen(const char *text) +{ + if (pdc_is_utf16be_unicode(text) || pdc_is_utf16le_unicode(text)) + return wstrlen(text); + else + return strlen(text); +} + + +/* Allocate a local buffer and copy the string including + * the terminating sentinel. If the string starts with the Unicode BOM + * it is considered a Unicode string, and must be terminated by + * two null bytes. Otherwise it is considered a plain C string and + * must be terminated by a single null byte. + * The caller is responsible for freeing the buffer. + * + * The special functions pdc_strdup and pdc_strdup_tmp + * should be replaced by the more sophisticated function pdc_strdup_ext. + * There: flags (see pc_unicode.h): + * + * PDC_CONV_TMPALLOC, PDC_CONV_EBCDIC + * + */ +char * +pdc_strdup_ext(pdc_core *pdc, const char *text, int flags, const char *fn) +{ + char *buf = NULL; + + if (text != NULL) + { + size_t len = pdc_strlen(text) + 1; + + if (flags & PDC_CONV_TMPALLOC) + buf = (char *) pdc_malloc_tmp(pdc, len + 1, fn, NULL, NULL); + else + buf = (char *) pdc_malloc(pdc, len + 1, fn); + memcpy(buf, text, len); + buf[len] = 0; + + } + + return buf; +} + +char * +pdc_strdup(pdc_core *pdc, const char *text) +{ + char *buf = NULL; + static const char fn[] = "pdc_strdup"; + + if (text != NULL) + { + size_t len = pdc_strlen(text) + 1; + + buf = (char *) pdc_malloc(pdc, len + 1, fn); + memcpy(buf, text, len); + buf[len] = 0; + } + + return buf; +} + +char * +pdc_strdup2(pdc_core *pdc, const char *text, size_t len) +{ + char *buf = NULL; + static const char fn[] = "pdc_strdup2"; + + if (text != NULL) + { + buf = (char *) pdc_malloc(pdc, len + 1, fn); + memcpy(buf, text, len); + buf[len] = 0; + } + + return buf; +} + +char * +pdc_strdup_tmp(pdc_core *pdc, const char *text) +{ + char *buf = NULL; + static const char fn[] = "pdc_strdup_tmp"; + + if (text != NULL) + { + size_t len = pdc_strlen(text) + 1; + + buf = (char *) pdc_malloc_tmp(pdc, len + 1, fn, NULL, NULL); + memcpy(buf, text, len); + buf[len] = 0; + } + + return buf; +} + +/* Allocate a local buffer and copy a locale UTF-8 string + * provided with an UTF-8 BOM. + * The caller is responsible for freeing the buffer. + */ +char * +pdc_strdup_withbom(pdc_core *pdc, const char *text) +{ + char *buf = NULL; + static const char fn[] = "pdc_strdup_withbom"; + + if (text != NULL) + { + size_t len; + + if (pdc_is_utf8_bytecode(text)) + { + buf = pdc_strdup(pdc, text); + } + else + { + len = strlen(text); + buf = (char *) pdc_malloc(pdc, len + 4, fn); + + pdc_copy_utf8_bom(buf); + strcpy(&buf[3], text); + } + } + + return buf; +} + +char * +pdc_strdup_convert(pdc_core *pdc, pdc_encoding encto, pdc_encoding encfrom, + const char *text, int flags, const char *fn) +{ + pdc_encodingvector *evfrom, *evto; + char *buf; + size_t len; + int i; + + evto = pdc_get_encoding_vector(pdc, encto); + evfrom = pdc_get_encoding_vector(pdc, encfrom); + buf = pdc_strdup_ext(pdc, text, flags, fn); + len = strlen(buf); + + for (i = 0; i < (int) len; i++) + buf[i] = (char) pdc_transform_bytecode(pdc, evto, evfrom, + (pdc_byte) text[i]); + + return buf; +} + +pdc_bool +pdc_logg_isprint(int c) +{ + if (c < 0x20 || (c >= 0x7F && c < 0xA0)) + return pdc_false; + return pdc_true; +} + + +/* + * Put out an arbitrary string. + * + * strform = readable: Direct byte output with replacing not + * printable bytes by their octal codes. + * = readable0: Like readable, but byte 0 will be displayed as space. + * = octal: All bytes will be put out as octal. + * = hexa: All bytes will be put out as hexadecimal value. + * = java: Like readable, but Unicode strings and not printable + * bytes will be put out in Java notation \uxxxx, + * + * Output string is temporarily allocated. + * + */ +char * +pdc_strprint(pdc_core *pdc, const char *str, int leni, int maxchar, + pdc_strform_kind strform) +{ + static const char fn[] = "pdc_strprint"; + + if (str != NULL) + { + pdc_bool isunicode = pdc_false; + int len = leni; + + if (!leni) + len = (int) strlen(str); + + if (len) + { + pdc_strform_kind sf; + char *ts, *tmpstr; + pdc_byte c = ' ', cp = '.'; + pdc_ushort *ush = (pdc_ushort *) str; + int i, im; + + tmpstr = (char *) pdc_calloc_tmp(pdc, (size_t) (4 * (len + 4)), fn, + NULL, NULL); + ts = tmpstr; + + if (strform == strform_java) + { + if (leni && !(leni % 2)) + isunicode = pdc_true; + else + strform = strform_readable; + } + + if (maxchar <= 0) + maxchar = len; + im = (maxchar < len) ? maxchar : len; + if (isunicode) + im = im/2; + for (i = 0; i < im; i++) + { + if (isunicode) + { + if (ush[i] > PDC_UNICODE_MAXLATIN1) + { + sf = strform_java; + } + else + { + c = (pdc_byte) ush[i]; + sf = strform_readable; + } + } + else + { + c = (pdc_byte) str[i]; + sf = strform; + } + + switch (sf) + { + case strform_hexa: + ts += sprintf(ts, "\\x%02X", c); + break; + + case strform_octal: + ts += sprintf(ts, "\\%03o", c); + break; + + case strform_java: + ts += sprintf(ts, "\\u%04X", ush[i]); + break; + + default: + if (c == 0x0 && sf == strform_readable0) + c = 0x20; + + if (!pdc_logg_isprint((int) c)) + { + if (isunicode) + ts += sprintf(ts, "\\u%04X", c); + else + ts += sprintf(ts, "\\%03o", c); + } + else + { + if (c == '"') + { + *ts = '\\'; + ts++; + } + *ts = (char) c; + ts++; + } + } + } + + if (maxchar < len) + { + switch (strform) + { + case strform_hexa: + ts += sprintf(ts, "\\x%02X\\x%02X\\x%02X", cp, cp, cp); + break; + + case strform_octal: + ts += sprintf(ts, "\\%03o\\%03o\\%03o", cp, cp, cp); + break; + + case strform_java: + ts += sprintf(ts, "\\u%04X\\u%04X\\u%04X", cp, cp, cp); + break; + + default: + ts += sprintf(ts, "%c%c%c", cp, cp, cp); + break; + } + } + + return tmpstr; + } + } + + return (char *) pdc_calloc_tmp(pdc, 1, fn, NULL, NULL); +} + +const char * +pdc_utf8strprint(pdc_core *pdc, const char *str) +{ + int i = pdc_is_utf8_bytecode(str) ? 3 : 0; + return pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, &str[i]); +} + +/* + * Split a given text string into single strings which are separated by + * arbitrary characters. This characters must be specified in a string. + * If this string is NULL, " \f\n\r\t\v" (standard white spaces) is assumed. + * + * There is the convention that text inside braces {} will be taken verbatim. + * Inside brace expressions braces must exist only in pairs. Braces are + * masked by backslash. + * + * The caller is responsible for freeing the resultated string list + * by calling the function pdc_cleanup_stringlist. + * + * Not for unicode strings. + * + * Return value: Number of strings. + * If braces aren't balanced the number is negative. + * + */ +int +pdc_split_stringlist(pdc_core *pdc, const char *text, const char *i_separstr, + int flags, char ***stringlist) +{ + static const char fn[] = "pdc_split_stringlist"; + const char *separstr = " \f\n\r\t\v"; + const char *oldtext; + char **strlist = NULL, *newtext; + pdc_bool isoptlist = (flags & PDC_SPLIT_ISOPTLIST); + int it, len, jt = 0, jtb = 0, maxk = 0, count = 0, inside = 0; + int ns, nbs = 0, nbss; + + if (stringlist) + *stringlist = NULL; + if (i_separstr) + separstr = i_separstr; + + if (text == NULL) + return 0; + + /* check for empty string */ + ns = (int) strspn(text, separstr); + oldtext = &text[ns]; + len = (int) strlen(oldtext); + if (!len) return 0; + + /* check for UTF-8-BOM */ + if (pdc_is_utf8_bytecode(oldtext)) + { + oldtext = &text[ns + 3]; + len -= 3; + ns = (int) strspn(oldtext, separstr); + oldtext = &oldtext[ns]; + len -= ns; + if (!len) return 0; + } + + /* new string */ + newtext = (char *) pdc_malloc(pdc, (size_t) (len + 1), fn); + for (it = 0; it <= len; it++) + { + /* check for separators */ + if (it == len) + ns = 1; + else if (inside <= 0) + ns = (int) strspn(&oldtext[it], separstr); + else + ns = 0; + + /* close text part */ + if (ns) + { + newtext[jt] = 0; + if (count == maxk) + { + maxk += 16; + strlist = (strlist == NULL) ? + (char **) pdc_malloc(pdc, maxk * sizeof(char *), fn): + (char **) pdc_realloc(pdc, strlist, maxk * + sizeof(char *), fn); + } + strlist[count] = &newtext[jtb]; + count++; + + /* Exit */ + it += ns; + if (it >= len ) break; + + /* new text part */ + jt++; + jtb = jt; + } + + /* option list */ + if (isoptlist) + { + /* save backslash counter */ + nbss = nbs; + + /* backslash */ + if (oldtext[it] == '\\') + { + nbs++; + if (!(nbs % 2) && inside <= 1) + continue; + } + else + { + nbs = 0; + } + + /* open and close brace */ + if (oldtext[it] == '{') + { + if (!(nbss % 2)) + { + inside++; + if (inside == 1) + continue; + } + else if (inside <= 1) + { + jt--; + } + } + else if (oldtext[it] == '}') + { + if (!(nbss % 2)) + { + inside--; + if (inside == 0) + continue; + } + else if (inside <= 1) + { + jt--; + } + } + } + + /* save character */ + newtext[jt] = oldtext[it]; + jt++; + } + + if (stringlist) + *stringlist = strlist; + + return inside ? -count : count; +} + +void +pdc_cleanup_stringlist(pdc_core *pdc, char **stringlist) +{ + if(stringlist != NULL) + { + if(stringlist[0] != NULL) + pdc_free(pdc, stringlist[0]); + + pdc_free(pdc, stringlist); + } +} + + +/* + * Substitute a list of variables in a string by its values recursively. + * A variable begins with the character 'vchar' and ends at a character + * in 'delimiters' or at the end of string resp.. + * + * The character 'vchar' must be masked by 'vchar'. + * + * If at least one of a variable was substituted, a new allocated null + * terminated string is returned. Otherwise the original pointer. + * + * The caller is responsible for freeing the new string. + * + * string null terminated string with variables + * vchar begin character for a variable + * delimiters string with characters delimiting a variable name + * varslist list of variable names + * valslist list of variable values + * nvars number of variables + * errind[2] contains index and length of an unkown variable in string + * + */ + +static char * +substitute_variables(pdc_core *pdc, char *string, int ibeg, int *level, + const char **varslist, const char **valslist, int nvars, char vchar, + const char *separstr, int *errind) +{ + static const char fn[] = "substitue_variables"; + int i, j, l; + + j = ibeg; + for (i = ibeg; string[i] != 0; i++) + { + if (string[i] == vchar) + { + if (string[i + 1] == vchar) + i++; + else + break; + } + + string[j] = string[i]; + j++; + } + + if (string[i] != 0) + { + char *s = &string[i + 1]; + size_t n = strcspn(s, separstr); + + for (l = 0; l < nvars; l++) + { + if (n == strlen(varslist[l]) && !strncmp(s, varslist[l], n)) + { + char *newstring; + int k = (int) (i + n + 1); + size_t nv = strlen(valslist[l]); + size_t nr = strlen(&string[k]); + size_t nb = (size_t) j + nv + nr + 1; + + newstring = (char *) pdc_malloc(pdc, nb, fn); + strncpy(newstring, string, (size_t) j); + strncpy(&newstring[j], valslist[l], nv); + strcpy(&newstring[j + nv], &string[k]); + + pdc_free(pdc, string); + (*level)++; + + string = substitute_variables(pdc, newstring, j, level, + varslist, valslist, nvars, vchar, separstr, + errind); + break; + } + } + if (l == nvars) + { + errind[0] = i; + errind[1] = (int) (n + 1); + } + } + else + { + string[j] = 0; + } + return string; +} + +char * +pdc_substitute_variables(pdc_core *pdc, const char *string, char vchar, + const char *delimiters, const char **varslist, + const char **valslist, int nvars, int *errind) +{ + static const char fn[] = "pdc_substitue_variables"; + char *subststr, *newstring, separstr[64]; + int level = 0; + + newstring = pdc_strdup_ext(pdc, string, 0, fn); + + separstr[0] = vchar; + separstr[1] = 0; + strcat(separstr, delimiters); + + errind[0] = -1; + errind[1] = 0; + subststr = substitute_variables(pdc, newstring, 0, &level, + varslist, valslist, nvars, vchar, separstr, errind); + + return subststr; +} + +/* + * Compares its arguments and returns an integer less than, + * equal to, or greater than zero, depending on whether s1 + * is lexicographically less than, equal to, or greater than s2. + * Null pointer values for s1 and s2 are treated the same as pointers + * to empty strings. + * + * Presupposition: basic character set + * + * Return value: < 0 s1 < s2; + * = 0 s1 == s2; + * > 0 s1 > s2; + * + */ +int +pdc_strcmp(const char *s1, const char *s2) +{ + if (s1 == s2) return (0); + if (s1 == NULL) return (-1); + if (s2 == NULL) return (1); + + return strcmp(s1, s2); +} + +int +pdc_stricmp(const char *s1, const char *s2) +{ + if (s1 == s2) return (0); + if (s1 == NULL) return (-1); + if (s2 == NULL) return (1); + + for (; *s1; ++s1, ++s2) + { + if (pdc_tolower(*s1) != pdc_tolower(*s2)) + break; + } + + return (pdc_tolower(*s1) - pdc_tolower(*s2)); +} + + +/* + * Compares its arguments and returns an integer less than, + * equal to, or greater than zero, depending on whether s1 + * is lexicographically less than, equal to, or greater than s2. + * But only up to n characters compared (n less than or equal + * to zero yields equality).Null pointer values for s1 and s2 + * are treated the same as pointers to empty strings. + * + * Presupposition: basic character set + * + * Return value: < 0 s1 < s2; + * = 0 s1 == s2; + * > 0 s1 > s2; + * + */ +int +pdc_strincmp(const char *s1, const char *s2, int n) +{ + int i; + + if (s1 == s2) return (0); + if (s1 == NULL) return (-1); + if (s2 == NULL) return (1); + + for (i = 0; i < n && *s1 && *s2; ++i, ++s1, ++s2) + { + if (pdc_tolower(*s1) != pdc_tolower(*s2)) + break; + } + + return (i == n) ? 0 : (pdc_tolower(*s1) - pdc_tolower(*s2)); +} + +/* + * pdc_strtrim removes trailing white space characters from an input string. + * pdc_str2trim removes leading and trailing white space characters from an + * input string.. + */ +char * +pdc_strtrim(char *str) +{ + int i, n; + + n = (int) strlen(str); + for (i = n - 1; i >= 0; i--) + if (!pdc_isspace(str[i])) break; + str[i + 1] = '\0'; + + return str; +} + +char * +pdc_str2trim(char *str) +{ + int i, n; + + n = (int) strlen(str); + for (i = n - 1; i >= 0; i--) + if (!pdc_isspace(str[i])) break; + str[i + 1] = '\0'; + + for (i = 0; ; i++) + if (!pdc_isspace(str[i])) break; + if (i > 0) + memmove(str, &str[i], strlen(&str[i]) + 1); + + return str; +} + +char * +pdc_strtoupper(char *str) +{ + int i, n; + + n = (int) strlen(str); + for (i = 0; i < n; i++) + str[i] = (char) pdc_toupper(str[i]); + + return str; +} + +char * +pdc_strtolower(char *str) +{ + int i, n; + + n = (int) strlen(str); + for (i = 0; i < n; i++) + str[i] = (char) pdc_tolower(str[i]); + + return str; +} + +int +pdc_tolower_ascii(int c) +{ + c = (int) pdc_tolower(c); + + return c; +} + +int +pdc_toupper_ascii(int c) +{ + c = (int) pdc_toupper((int) c); + + return c; +} + +void +pdc_swap_bytes(char *instring, int inlen, char *outstring) +{ + char c; + int i,j; + + if (instring == NULL) + return; + + if (outstring == NULL) + outstring = instring; + + inlen = 2 * inlen / 2; + for (i = 0; i < inlen; i++) + { + j = i; + i++; + c = instring[j]; + outstring[j] = instring[i]; + outstring[i] = c; + } +} + +void +pdc_swap_unicodes(char *instring) +{ + if (instring && + ((pdc_is_utf16be_unicode(instring) && !PDC_ISBIGENDIAN) || + (pdc_is_utf16le_unicode(instring) && PDC_ISBIGENDIAN))) + pdc_swap_bytes(&instring[2], (int) (wstrlen(instring) - 2), NULL); +} + +void +pdc_inflate_ascii(const char *instring, int inlen, char *outstring, + pdc_text_format textformat) +{ + int i, j; + pdc_bool is_bigendian = (textformat == pdc_utf16be) || + (textformat == pdc_utf16 && PDC_ISBIGENDIAN); + + j = 0; + for (i = 0; i < inlen; i++) + { + if (is_bigendian) + { + outstring[j] = 0; + j++; + outstring[j] = instring[i]; + } + else + { + outstring[j] = instring[i]; + j++; + outstring[j] = 0; + } + j++; + } +} + +/* + * pdc_stresc -- + * Remove from a string containing escaped non-printable cha- + * racters. The string must follows the C-standard escape + * mechanism: an escaped character is preceeded by an escape + * character which is a backslash '\' character and followed + * by one or more characters to define the non-printable + * character to be inserted here. The supported escapes are + * + * \a bell (ASCII/EBCDIC-BEL) + * \b backspace (ASCII/EBCDIC-BS) + * \e escape charater (ASCII/EBCDIC-ESC) + * \f formfeed (ASCII/EBCDIC-FF) + * \n linefeed (ASCII/EBCDIC-LF) + * \r return (ASCII/EBCDIC-CR) + * \t tab character (ASCII/EBCDIC-TAB) + * \v vertical tab (ASCII/EBCDIC-VT) + * \\ the slash itself + * \xnn two hex digits n to define a + * character numerically as ASCII/EBCDIC value. + * \nnn three octal digits n to define a + * character numerically as ASCII/EBCDIC value. + * + * For example: \x0A, \x0a or \012 has the same effect in ASCII + * as \n (i.e linefeed). + * Note, if the last character in a string is the backslash + * then the backslash is illegal. + * The special characters a,b,e,f, and so on are recognized in + * lower case only. + * + * textformat: + * pdc_bytes: Latin1 or EBCDIC bytes on EBCDIC platforms + * pdc_utf8: Latin1 + * pdc_ebcdicutf8: EBCDIC - only on EBCDIC platforms + * pdc_utf16: 2 bytes Latin1 + * + * If a illegal escaped sequence was detected an exception will + * be thrown (verbose == pdc_true) or the sequence will be taken + * as it (verbose == pdc_false). + * +*/ + +static const pdc_keyconn pdc_ascii_escape_keylist[] = +{ + {"\\", 0x5C}, + {"a", 0x07}, + {"b", 0x08}, + {"e", 0x1B}, + {"f", 0x0C}, + {"n", 0x0A}, + {"r", 0x0D}, + {"t", 0x09}, + {"v", 0x0B}, + {"x", 0x78}, + {NULL, 0} +}; + +pdc_ushort +pdc_get_string_value(pdc_byte *str, int i, int charlen) +{ + pdc_ushort retval = 0; + + if (charlen == 1) + { + retval = (pdc_ushort) str[i]; + } + else + { + pdc_ushort *ustr = (pdc_ushort *) str; + + retval = ustr[i]; + } + + return retval; +} + +int +pdc_subst_backslash(pdc_core *pdc, pdc_byte *str, int len, + pdc_encodingvector *ev, pdc_text_format textformat, + pdc_bool verbose) +{ + pdc_ushort *ustr = (pdc_ushort *) str; + int charlen = (textformat == pdc_utf16) ? 2 : 1; + pdc_byte bschar = '\\'; + pdc_ushort uv; + int i, j, k, code; + + if (ev != NULL) + { + code = pdc_get_encoding_bytecode(pdc, ev, PDC_UNICODE_BACKSLASH); + if (code != -1) + bschar = (pdc_byte) code; + } + + + j = 0; + len /= charlen; + for (i = 0; i < len; i++) + { + uv = pdc_get_string_value(str, i, charlen); + if (uv > PDC_UNICODE_MAXLATIN1) + { + ustr[j] = uv; + j++; + continue; + } + + /* backslash found */ + if (uv == bschar) + { + pdc_byte escseq[4], stemp[6]; + pdc_bool kerror = pdc_false; + + i++; + if (i < len) + { + uv = pdc_get_string_value(str, i, charlen); + if (uv > PDC_UNICODE_MAXLATIN1) + goto PDC_OVERFLOW_EXIT; + + escseq[0] = (pdc_byte) uv; + escseq[1] = 0; + + code = pdc_get_keycode((char *) escseq, + pdc_ascii_escape_keylist); + if (code != PDC_KEY_NOTFOUND) + { + /* hex number */ + if (code == 0x78) + { + for (k = 0; k < 2; k++) + { + i++; + if (i < len) + { + uv = pdc_get_string_value(str, i, charlen); + if (uv > PDC_UNICODE_MAXLATIN1) + goto PDC_OVERFLOW_EXIT; + } + else + { + uv = 0; + } + escseq[k] = (pdc_byte) uv; + } + escseq[k] = 0; + if (i >= len || + !pdc_str2integer((char *) escseq, PDC_INT_UNICODE, + &uv)) + { + strcpy((char *) stemp, "\\x"); + strcat((char *) stemp, (char *) escseq); + kerror = pdc_true; + } + } + else + { + pdc_char c = (pdc_char) code; + uv = (pdc_ushort) (pdc_byte) c; + } + } + else + { + /* octal number */ + for (k = 0; k < 3; k++) + { + if (k) i++; + if (i < len) + { + uv = pdc_get_string_value(str, i, charlen); + if (uv > PDC_UNICODE_MAXLATIN1) + goto PDC_OVERFLOW_EXIT; + } + else + { + uv = 0; + } + escseq[k] = (pdc_byte) uv; + } + escseq[k] = 0; + if (i >= len || + !pdc_str2integer((char *) escseq, + PDC_INT_SHORT | + PDC_INT_UNSIGNED | + PDC_INT_OCTAL, + &uv) || + (charlen == 1 && uv > 0xFF)) + { + strcpy((char *) stemp, "\\"); + strcat((char *) stemp, (char *) escseq); + kerror = pdc_true; + } + } + } + else + { + strcpy((char *) stemp, "\\"); + kerror = pdc_true; + } + + /* error message */ + if (kerror) + { + pdc_set_errmsg(pdc, PDC_E_STR_ILL_ESCSEQ, (char *) stemp, + 0, 0, 0); + + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + + return 0; + } + } + + if (charlen == 1) + str[j] = (pdc_byte) uv; + else + ustr[j] = uv; + + j++; + } + + if (charlen == 1) + str[j] = 0; + else + ustr[j] = 0; + + return charlen * j; + + PDC_OVERFLOW_EXIT: + + pdc_set_errmsg(pdc, PDC_E_STR_ILL_UNIESCSEQ, + pdc_errprintf(pdc, "%04X", uv), 0, 0, 0); + + if (verbose) + pdc_error(pdc, -1, 0, 0, 0, 0); + + return 0; +} + + +/* ----------------------- number converting ----------------------- */ + +/* + * pdc_str2double converts a null terminated and trimmed string + * to a double precision number + */ +pdc_bool +pdc_str2double(const char *string, double *o_dz) +{ + const char *s = string; + double dz = 0; + int is = 1, isd = 0; + + *o_dz = 0; + + /* sign */ + if (*s == '-') + { + is = -1; + s++; + } + else if (*s == '+') + s++; + + if (!*s) + return pdc_false; + + /* places before decimal point */ + isd = pdc_isdigit(*s); + if (isd) + { + do + { + dz = 10 * dz + *s - '0'; + s++; + } + while (pdc_isdigit(*s)); + } + + /* decimal point */ + if (*s == '.' || *s == ',') + { + const char *sa; + double adz = 0; + + s++; + isd = pdc_isdigit(*s); + if (!isd) + return pdc_false; + + /* places after decimal point */ + sa = s; + do + { + adz = 10 * adz + *s - '0'; + s++; + } + while (pdc_isdigit(*s)); + dz += adz / pow(10.0, (double)(s - sa)); + } + + /* power sign */ + if (*s == 'e' || *s == 'E') + { + s++; + if (!isd) + return pdc_false; + + /* sign */ + if (!*s) + { + dz *= 10; + } + else + { + int isp = 1; + double pdz = 0, pdl = log10(dz); + + if (*s == '-') + { + isp = -1; + s++; + } + else if (*s == '+') + s++; + + if (!pdc_isdigit(*s)) + return pdc_false; + do + { + pdz = 10 * pdz + *s - '0'; + s++; + } + while (pdc_isdigit(*s)); + + + if (*s || fabs(pdl + pdz) > 300.0) + return pdc_false; + + dz *= pow(10.0, isp * pdz); + } + } + else if(*s) + { + return pdc_false; + } + + *o_dz = is * dz; + return pdc_true; +} + +/* + * pdc_str2integer converts a null terminated and trimmed string + * to an hexadecimal or decimal integer number of arbitrary size + */ +pdc_bool +pdc_str2integer(const char *string, int flags, void *o_iz) +{ + const char *s = string; + double dz = 0; + pdc_char cz = 0; + pdc_short sz = 0; + pdc_sint32 lz = 0; + pdc_byte ucz = 0; + pdc_ushort usz = 0; + pdc_uint32 ulz = 0; + int is = 1, lzd; + + if (flags & PDC_INT_CHAR) + memcpy(o_iz, &cz, sizeof(pdc_char)); + else if (flags & PDC_INT_SHORT) + memcpy(o_iz, &sz, sizeof(pdc_short)); + else + memcpy(o_iz, &lz, sizeof(pdc_sint32)); + + /* sign */ + if (*s == '-') + { + if (flags & PDC_INT_UNSIGNED) + return pdc_false; + is = -1; + s++; + } + else if (*s == '+') + s++; + + if (!*s) + return pdc_false; + + /* hexadecimal test */ + if (!(flags & PDC_INT_DEC)) + { + const char *ss = s; + + if (*s == '<') + s += 1; + else if (*s == 'x' || *s == 'X') + s += 1; + else if (!strncmp(s, "0x", 2) || !strncmp(s, "0X", 2)) + s += 2; + if (s > ss) + { + if (!*s) + return pdc_false; + flags |= PDC_INT_HEXADEC; + } + } + + /* hexadecimal */ + if (flags & PDC_INT_HEXADEC) + { + while (pdc_isxdigit(*s)) + { + if (pdc_isalpha(*s)) + lzd = (pdc_isupper(*s) ? 'A' : 'a') - 10; + else + lzd = '0'; + dz = 16 * dz + *s - lzd; + s++; + } + if (*string == '<') + { + if (*s == '>') + s += 1; + else + return pdc_false; + } + } + + /* octal */ + if (flags & PDC_INT_OCTAL) + { + while (pdc_isdigit(*s) && *s < '8') + { + dz = 8 * dz + *s - '0'; + s++; + } + } + + /* decimal */ + else + { + while (pdc_isdigit(*s)) + { + dz = 10 * dz + *s - '0'; + s++; + } + } + if (*s) + return pdc_false; + + dz *= is; + if (flags & PDC_INT_CHAR) + { + if (flags & PDC_INT_UNSIGNED) + { + if (dz > PDC_UCHAR_MAX) + return pdc_false; + ucz = (pdc_byte) dz; + memcpy(o_iz, &ucz, sizeof(pdc_byte)); + } + else + { + if (dz < PDC_SCHAR_MIN || dz > PDC_SCHAR_MAX) + return pdc_false; + cz = (pdc_char) dz; + memcpy(o_iz, &cz, sizeof(pdc_char)); + } + } + else if (flags & PDC_INT_SHORT) + { + if (flags & PDC_INT_UNSIGNED) + { + if (dz > PDC_USHRT_MAX) + return pdc_false; + usz = (pdc_ushort) dz; + memcpy(o_iz, &usz, sizeof(pdc_ushort)); + } + else + { + if (dz < PDC_SHRT_MIN || dz > PDC_SHRT_MAX) + return pdc_false; + sz = (pdc_short) dz; + memcpy(o_iz, &sz, sizeof(pdc_short)); + } + } + else + { + if (flags & PDC_INT_UNSIGNED) + { + if (dz > PDC_UINT_MAX) + return pdc_false; + ulz = (pdc_uint32) dz; + memcpy(o_iz, &ulz, sizeof(pdc_uint32)); + } + else + { + if (dz < PDC_INT_MIN || dz > PDC_INT_MAX) + return pdc_false; + lz = (pdc_sint32) dz; + memcpy(o_iz, &lz, sizeof(pdc_sint32)); + } + } + + return pdc_true; +} + +static const char digits[] = "0123456789ABCDEF"; + +static char * +pdc_ltoa(char *buf, long n, int width, char pad, int base) +{ + char aux[100]; + int k, i = sizeof aux; + char * dest = buf; + pdc_bool sign; + + if (n == 0) + { + if (width == 0) + width = 1; + + for (k = 0; k < width; ++k) + *(dest++) = '0'; + + return dest; + } + + if (n < 0 && base == 10) + { + --width; + sign = pdc_true; + aux[--i] = digits[- (n % base)]; + n = n / -base; + } + else + { + sign = pdc_false; + aux[--i] = digits[n % base]; + n = n / base; + } + + while (0 < n) + { + aux[--i] = digits[n % base]; + n = n / base; + } + + width -= (int) (sizeof aux) - i; + for (k = 0; k < width; ++k) + *(dest++) = pad; + + if (sign) + *(dest++) = '-'; + + memcpy(dest, &aux[i], sizeof aux - i); + return dest + sizeof aux - i; +} /* pdc_ltoa */ + + +static char * +pdc_off_t2a(char *buf, pdc_off_t n, int width, char pad, int base) +{ + char aux[100]; + int k, i = sizeof aux; + char * dest = buf; + pdc_bool sign; + + if (n < 0 && base == 10) + { + --width; + sign = pdc_true; + aux[--i] = digits[- (n % base)]; + n = n / -base; + } + else + { + sign = pdc_false; + aux[--i] = digits[n % base]; + n = n / base; + } + + while (0 < n) + { + aux[--i] = digits[n % base]; + n = n / base; + } + + width -= (int) (sizeof aux) - i; + for (k = 0; k < width; ++k) + *(dest++) = pad; + + if (sign) + *(dest++) = '-'; + + memcpy(dest, &aux[i], sizeof aux - i); + return dest + sizeof aux - i; +} /* pdc_off_t2a */ + + +/* + * pdc_ftoa converts a floating point number to string + * + * Because of historical reason "%f" = "%.12g". + * + * The function calls sprintf() and replaces + * decimal comma by decimal point. + * + * If the number is infinite or not a number + * "nan" will be set. + * + */ + +static char * +pdc_ftoa(pdc_core *pdc, const char *format, char *buf, double x) +{ + char *dest = buf; + char *cd; + int n; + + (void) pdc; + + /* check whether the number is valid */ + if (!PDC_ISFINITE(x)) + { + strcpy(dest, "nan"); + return dest + 3; + } + + /* standard C convert */ + if (!strcmp(format, "%f")) + n = sprintf(dest, "%.12g", x); + else + n = sprintf(dest, format, x); + + /* normalized to decimal point */ + cd = strchr(dest, ','); + if (cd != NULL) + *cd = '.'; + + return dest + n; +} /* pdc_ftoa */ + +/* + * pdc_ftoa_pdfconf converts a floating point number to string + * PDF conforming + * + */ + +static char * +pdc_ftoa_pdfconf(pdc_core *pdc, char *buf, double x) +{ + static const long pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000 }; + char * dest = buf; + double integ, fract, powd; + int ifd; + long f; + + /* check whether the number is valid */ + if (!PDC_ISFINITE(x)) + pdc_error(pdc, PDC_E_INT_ILLFLOAT, 0, 0, 0, 0); + + /* small number will be mapped to 0 */ + if (x < PDF_SMALLREAL && x > -PDF_SMALLREAL) + { + *dest = '0'; + return dest + 1; + } + + /* negative number */ + if (x < 0) + { + x = -x; + *(dest++) = '-'; + } + + /* large number is invalid or will be mapped to integer */ + if (x >= PDF_BIGREAL) + { + if (x > PDF_BIGINT) + pdc_error(pdc, PDC_E_INT_FLOATTOOLARGE, + pdc_errprintf(pdc, "%f", x), 0, 0, 0); + + return pdc_ltoa(dest, (long) (x + 0.5), 0, ' ', 10); + } + + ifd = pdc->floatdigits; + powd = pow10[ifd]; + + fract = modf(x, &integ); + f = (long) (fract * powd + 0.5); + + if (f == powd) + { + integ += 1.0; + f = 0; + } + + if (integ == 0 && f == 0) /* avoid "-0" */ + dest = buf; + + dest = pdc_ltoa(dest, (long) integ, 0, ' ', 10); + + if (f != 0) + { + char * aux; + long rem; + + *(dest++) = '.'; + + do /* avoid trailing zeros */ + { + rem = f % 10; + f = f / 10; + --ifd; + } while (rem == 0); + + aux = dest + ifd + 1; + dest[ifd--] = digits[rem]; + + for (; 0 <= ifd; --ifd) + { + dest[ifd] = digits[f % 10]; + f = f / 10; + } + + return aux; + } + + return dest; +} /* pdc_ftoa_pdfconf */ + +static int +pdc_vxprintf( + pdc_core *pdc, + pdc_bool pdfconf, + char *cp, + FILE *fp, + const char *format, + va_list args) +{ + static const char fn[] = "pdc_vxprintf"; + const char *format_p; + char aux[1024]; + char *buf = cp ? cp : aux; + char *dest = buf; + + for (/* */ ; /* */ ; /* */) + { + int width = 0; + int prec = 0; + char pad = ' '; + pdc_bool left_justify = pdc_false; + + /* as long as there is no '%', just print. + */ + while (*format != 0 && *format != '%') + *(dest++) = *(format++); + + if (*format == 0) + { + if (fp != (FILE *) 0) + { + if (dest > buf) + pdc_fwrite_ascii(pdc, buf, (size_t) (dest - buf), fp); + } + else + *dest = 0; + + return (int) (dest - buf); + } + format_p = format; + + /* get the "flags", if any. + */ + if (*(++format) == '-') + { + left_justify = pdc_true; + ++format; + } + + if (*format == '0') + { + if (!left_justify) + pad = '0'; + + ++format; + } + + /* get the "width", if present. + */ + if (*format == '*') + { + width = va_arg(args, int); /* TODO: sign? */ + ++format; + } + else + { + while (pdc_isdigit(*format)) + width = 10 * width + *(format++) - '0'; + } + + /* get the "precision", if present. + */ + if (*format == '.') + { + ++format; + + if (*format == '*') + { + prec = va_arg(args, int); /* TODO: sign? */ + ++format; + } + else + { + while (pdc_isdigit(*format)) + prec = 10 * prec + *(format++) - '0'; + } + } + + switch (*format) + { + case 'x': + case 'X': + dest = pdc_off_t2a( + dest, (pdc_off_t) va_arg(args, unsigned int), + width, pad, 16); + break; + + case 'c': + *(dest++) = (char) va_arg(args, int); + break; + + case 'd': + dest = pdc_off_t2a(dest, (pdc_off_t) va_arg(args, int), + width, pad, 10); + break; + + case 'g': + case 'f': + if (pdfconf) + { + dest = pdc_ftoa_pdfconf(pdc, dest, va_arg(args, double)); + } + else + { + char ff[32]; + size_t n = (size_t) (format - format_p + 1); + + strncpy(ff, format_p, n); + ff[n] = 0; + dest = pdc_ftoa(pdc, ff, dest, va_arg(args, double)); + } + break; + + case 'l': + { + pdc_off_t n; + + if (format[1] == 'l') + { + n = va_arg(args, pdc_off_t); + ++format; + } + else + { + n = va_arg(args, long); + } + + switch (*(++format)) + { + case 'x': + case 'X': + dest = pdc_off_t2a(dest, n, width, pad, 16); + break; + + case 'd': + dest = pdc_off_t2a(dest, n, width, pad, 10); + break; + + default: + pdc_error(pdc, PDC_E_INT_BADFORMAT, + pdc_errprintf(pdc, "l%c", + pdc_isprint((int) *format) ? *format : '?'), + pdc_errprintf(pdc, "0x%02X", *format), + 0, 0); + } + + break; + } + + case 'p': + { + void *ptr = va_arg(args, void *); + dest += sprintf(dest, "%p", ptr); + break; + } + + case 'a': + case 's': + case 'T': + { + char *str = va_arg(args, char *); + const char *cstr = str; + pdc_bool tobefree = pdc_false; + size_t len; + + if (str == 0) + cstr = "(NULL)"; + len = strlen(cstr); + + if (*format == 'T') + { + int l = va_arg(args, int); + + if (str != 0) + { + cstr = pdc_print_loggstring(pdc, str, l); + len = strlen(cstr); + } + } + + if (*format == 'a' && str != 0) + { + cstr = pdc_strdup_ext(pdc, str, PDC_CONV_EBCDIC, fn); + tobefree = pdc_true; + } + + if (!left_justify && len < (size_t) width) + { + memset(dest, pad, width - len); + dest += width - len; + } + + if (len != 0) + { + if (fp != (FILE *) 0) + { + if (dest > buf) + { + pdc_fwrite_ascii(pdc, buf, + (size_t) (dest - buf), fp); + dest = buf; + } + + pdc_fwrite_ascii(pdc, cstr, len, fp); + } + else + { + memcpy(dest, cstr, len); + dest += len; + } + + if (tobefree) + pdc_free(pdc, (char *) cstr); + } + + if (left_justify && len < (size_t) width) + { + memset(dest, pad, width - len); + dest += width - len; + } + + break; + } + + case '%': + *(dest++) = '%'; + break; + + default: + pdc_error(pdc, PDC_E_INT_BADFORMAT, + pdc_errprintf(pdc, "%c", pdc_isprint((int) *format) ? + *format : '?'), + pdc_errprintf(pdc, "0x%02X", *format), + 0, 0); + } /* switch */ + + ++format; + } /* loop */ +} /* pdc_vxprintf */ + + +/* ----------------------- formatted output ----------------------- */ + +/* + * formatted output to file + */ +int +pdc_vfprintf(pdc_core *pdc, pdc_bool pdfconf, FILE *fp, + const char *format, va_list args) +{ + return pdc_vxprintf(pdc, pdfconf, NULL, fp, format, args); +} /* pdc_vfprintf */ + +int +pdc_fprintf(pdc_core *pdc, pdc_bool pdfconf, FILE *fp, + const char *format, ...) +{ + int result; + va_list ap; + + va_start(ap, format); + result = pdc_vxprintf(pdc, pdfconf, NULL, fp, format, ap); + va_end(ap); + + return result; +} /* pdc_fprintf */ + + +/* + * formatted output to character string + */ +int +pdc_vsprintf(pdc_core *pdc, pdc_bool pdfconf, char *buf, + const char *format, va_list args) +{ + return pdc_vxprintf(pdc, pdfconf, buf, NULL, format, args); +} /* pdc_vsprintf */ + +int +pdc_sprintf(pdc_core *pdc, pdc_bool pdfconf, char *buf, + const char *format, ...) +{ + int result; + va_list ap; + + va_start(ap, format); + result = pdc_vxprintf(pdc, pdfconf, buf, NULL, format, ap); + va_end(ap); + + return result; +} /* pdc_sprintf */ + +/* + * we cannot use own converter because of missing format + * specifications like %lu + */ +int +pdc_vsnprintf(char *buf, size_t size, const char *format, va_list args) +{ + int result; + +#if defined (PDC_NO_VSNPRINTF) + (void) size; + result = vsprintf(buf, format, args); +#else +#if defined(WIN32) + result = _vsnprintf(buf, size, format, args); +#else + result = vsnprintf(buf, size, format, args); +#endif +#endif + + return result; +} /* pdc_vsnprintf */ + + +/* --------------------- name tree handling ----------------------- */ + +struct pdc_branch_s +{ + char *name; /* name - must be allocated pointer */ + void *data; /* private data - must be allocated pointer */ + int nalloc; /* number of allocated kid structs */ + int nkids; /* number of kids */ + pdc_branch **kids; /* kids */ + pdc_branch *parent; /* parent branch */ +}; + +pdc_branch * +pdc_init_tree(pdc_core *pdc) +{ + return pdc_create_treebranch(pdc, NULL, "__tree__root__", + NULL, 0, 0, NULL, NULL); +} + +pdc_branch * +pdc_create_treebranch(pdc_core *pdc, pdc_branch *root, const char *pathname, + void *data, int flags, int size, + pdc_branch_error *errcode, const char **name_p) +{ + static const char fn[] = "pdc_create_branch"; + char *name = NULL; + pdc_branch *branch = NULL; + pdc_branch *kid = NULL; + pdc_branch *parent = NULL; + char **namelist; + int i, j, k, nnames, nkids; + + if (errcode) *errcode = tree_ok; + if (name_p) *name_p = ""; + + if (root) + { + /* search for parent branch */ + parent = root; + nnames = pdc_split_stringlist(pdc, pathname, PDC_NAME_SEPARSTRG, 0, + &namelist); + for (i = 0; i < nnames; i++) + { + /* parent branch must not be a leaf branch */ + if (!parent->nalloc) + { + if (errcode) *errcode = tree_isleaf; + pdc_cleanup_stringlist(pdc, namelist); + return NULL; + } + if (i == nnames - 1) + break; + + name = namelist[i]; + if (name_p) + *name_p = pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, name); + + nkids = parent->nkids; + for (j = 0; j < nkids; j++) + { + kid = parent->kids[j]; + k = pdc_is_utf8_bytecode(kid->name) ? 3 : 0; + if (!strcmp(&kid->name[k], name)) + { + parent = kid; + break; + } + } + if (j == nkids) + { + if (errcode) *errcode = tree_notfound; + pdc_cleanup_stringlist(pdc, namelist); + return NULL; + } + } + + if (pdc_is_utf8_bytecode(pathname)) + name = pdc_strdup_withbom(pdc, namelist[nnames - 1]); + else + name = pdc_strdup(pdc, namelist[nnames - 1]); + pdc_cleanup_stringlist(pdc, namelist); + + /* kids must have different names */ + for (j = 0; j < parent->nkids; j++) + { + kid = parent->kids[j]; + if (!strcmp(kid->name, name)) + { + if (errcode) *errcode = tree_nameexists; + if (name_p) *name_p = + pdc_errprintf(pdc, "%.*s", PDC_ERR_MAXSTRLEN, name); + pdc_free(pdc, name); + return NULL; + } + } + } + else + { + parent = NULL; + name = pdc_strdup(pdc, pathname); + } + + branch = (pdc_branch *) pdc_malloc(pdc, sizeof(pdc_branch), fn); + branch->name = name; + branch->data = data; + if (flags & PDC_TREE_ISLEAF) + { + branch->nalloc = 0; + branch->nkids = 0; + branch->kids = NULL; + } + else + { + branch->nalloc = PDC_KIDS_CHUNKSIZE; + branch->nkids = 0; + branch->kids = (pdc_branch **) pdc_malloc(pdc, + branch->nalloc * sizeof(pdc_branch *), fn); + } + branch->parent = parent; + + /* insert kid */ + if (parent) + { + if (parent->nkids == parent->nalloc) + { + parent->nalloc *= 2; + parent->kids = (pdc_branch **) pdc_realloc(pdc, parent->kids, + parent->nalloc * sizeof(pdc_branch *), fn); + } + parent->kids[parent->nkids] = branch; + (parent->nkids)++; + + if ((flags & PDC_TREE_INHERIT) && parent->data) + memcpy(branch->data, parent->data, (size_t) size); + } + + return branch; +} + +void +pdc_deactivate_name_treebranch(pdc_core *pdc, pdc_branch *branch) +{ + static const char fn[] = "pdc_deactivate_name_treebranch"; + size_t len = strlen(branch->name); + + branch->name = (char *) pdc_realloc(pdc, branch->name, len + 2, fn); + branch->name[len] = PDC_NAME_SEPARSIGN; + branch->name[len+1] = 0; +} + +char * +pdc_get_name_treebranch(pdc_branch *branch) +{ + return branch->name; +} + +pdc_branch * +pdc_get_parent_treebranch(pdc_branch *branch) +{ + return branch->parent; +} + +void * +pdc_get_data_treebranch(pdc_branch *branch) +{ + return branch->data; +} + +pdc_branch ** +pdc_get_kids_treebranch(pdc_branch *branch, int *nkids) +{ + *nkids = branch->nkids; + return branch->kids; +} + +void +pdc_cleanup_treebranch(pdc_core *pdc, pdc_branch *branch) +{ + int i; + + if (branch->name) + pdc_free(pdc, branch->name); + + if (branch->data) + pdc_free(pdc, branch->data); + + if (branch->kids) + { + for(i = 0; i < branch->nkids; i++) + pdc_cleanup_treebranch(pdc, branch->kids[i]); + pdc_free(pdc, branch->kids); + } + + pdc_free(pdc, branch); +} + +/***************************** memory pools *****************************/ + +/* the data structures and functions in this section are more than +** confusing. the funny "mp_item" structure below makes them more +** readable, believe it or not. +*/ +typedef struct mp_item_s mp_item; + +struct mp_item_s +{ + mp_item * next; +}; + +struct pdc_mempool_s +{ + pdc_core * pdc; + + char ** pool_tab; + mp_item * free_list; + + size_t pool_incr; /* pool growth chunk size (items) */ + + size_t ptab_cap; /* total # of slots in pool_tab */ + size_t ptab_size; /* used # of slots in pool_tab */ + size_t ptab_incr; /* pool_tab growth chunk size (slots) */ + + size_t item_size; /* size of a single item (bytes) */ +}; + +#undef COMMENT +#ifdef COMMENT + + pool_incr = 5 + ptab_incr = 4 + ptab_cap = 4 (1 * ptab_incr) + + + +------+ + | free | + +------+ +----------------------------------+ + | free | +--> | | | | free | free | + +------+ | +----------------------------------+ + | | ---+ + +------+ +----------------------------------+ + | | ------> | | | | | | + +------+ +----------------------------------+ + + pool_tab + +#endif /* COMMENT */ + + +pdc_mempool * +pdc_mp_new(pdc_core *pdc, size_t item_size) +{ + static const char fn[] = "pdc_mp_new"; + + int m; + pdc_mempool *mp = (pdc_mempool *) + pdc_malloc(pdc, sizeof (pdc_mempool), fn); + + /* round up 'item_size' to a multiple of 'sizeof (mp_item)' + ** to ensure proper alignment. + */ + if ((m = (int) (item_size % sizeof (mp_item))) != 0) + item_size += sizeof (mp_item) - m; + + mp->pdc = pdc; + + mp->pool_tab = (char **) 0; + mp->free_list = (mp_item *) 0; + mp->pool_incr = 1000; + + mp->ptab_cap = 0; + mp->ptab_size = 0; + mp->ptab_incr = 100; + + mp->item_size = item_size; + + return mp; +} /* pdc_mp_new */ + + +void +pdc_mp_delete(pdc_mempool *mp) +{ + /* TODO: exception if there are still alloc'd items in the pool? */ + /* or, the other way round, call destructors? */ + + pdc_core * pdc = mp->pdc; + int i; + + for (i = 0; i < (int) mp->ptab_size; ++i) + pdc_free(pdc, mp->pool_tab[i]); + + if (mp->pool_tab) + pdc_free(pdc, mp->pool_tab); + + pdc_free(pdc, mp); +} /* pdc_mp_delete */ + + +void * +pdc_mp_alloc(pdc_mempool *mp) +{ + static const char fn[] = "pdc_mp_alloc"; + + pdc_core * pdc = mp->pdc; + mp_item * result; + + if (!mp->free_list) + { + char * new_chunk; + int i; + + if (mp->ptab_size == mp->ptab_cap) + { + mp->ptab_cap += mp->ptab_incr; + + mp->pool_tab = (char **) pdc_realloc(pdc, + mp->pool_tab, mp->ptab_cap * sizeof (char **), fn); + } + + new_chunk = mp->pool_tab[mp->ptab_size] = (char *) + pdc_malloc(pdc, mp->pool_incr * mp->item_size, fn); + + ++mp->ptab_size; + mp->free_list = (mp_item *) new_chunk; + mp->free_list->next = (mp_item *) 0; + + for (i = 1; i < (int) mp->pool_incr; ++i) + { + mp_item *scan = (mp_item *) (new_chunk + i * mp->item_size); + + scan->next = mp->free_list; + mp->free_list = scan; + } + } + + result = mp->free_list; + mp->free_list = result->next; + + return (void *) result; +} /* pdc_mp_alloc */ + + +void +pdc_mp_free(pdc_mempool *mp, void *item) +{ + mp_item *mpi = (mp_item *) item; + + mpi->next = mp->free_list; + mp->free_list = mpi; +} /* pdc_mp_free */ + + +/***************************** miscellaneous ****************************/ + +/* search a sorted (strcmp order) array "names" of size "size" +** for string "name". return the index if found, otherwise -1. +*/ +int +pdc_name2idx(const char **names, int size, const char *name) +{ + int lo = 0, hi = size; + + while (lo != hi) + { + int idx = (lo + hi) / 2; + int cmp = strcmp(name, names[idx]); + + if (cmp == 0) + return idx; + + if (cmp < 0) + hi = idx; + else + lo = idx + 1; + } + + return -1; +} /* pdc_name2idx */ + + +/* linear search; see man page LSEARCH(3). +*/ +void * +pdc_lfind( + const void *key, + const void *base, + size_t * nmemb, + size_t size, + int (*compar)(const void *, const void *)) +{ + size_t i; + + for (i = 0; i < *nmemb; ++i) + { + const char *cp = (const char *) base + i * size; + + if (compar(key, (void *) cp) == 0) + return (void *) cp; + } + + return (void *) 0; +} /* pdc_lfind */ + + +/********************* pseudo random numbers *********************/ + +int +pdc_rand(pdc_core *pdc) +{ + pdc->last_rand = pdc->last_rand * 1103515245 + 12345; + + return (pdc_uint)(pdc->last_rand / 65536) % 32768; +} /* pdc_rand */ + +void +pdc_srand(pdc_core *pdc, pdc_uint seed) +{ + pdc->last_rand = seed; +} /* pdc_srand */ diff --git a/src/pdflib/pdcore/pc_util.h b/src/pdflib/pdcore/pc_util.h new file mode 100644 index 0000000..af84606 --- /dev/null +++ b/src/pdflib/pdcore/pc_util.h @@ -0,0 +1,268 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_util.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * Declaration of various utility routines + * + */ + +#ifndef PC_UTIL_H +#define PC_UTIL_H + +#include +#include +#include +#include +#include +#include + +#include "pc_config.h" +#include "pc_core.h" +#include "pc_ebcdic.h" +#include "pc_optparse.h" +#include "pc_encoding.h" +#include "pc_output.h" +#include "pc_unicode.h" +#include "pc_resource.h" + +/* ---------------------------- forward typedefs --------------------------- */ + +#ifndef PDC_STRINGS_DEFINED +#define PDC_STRINGS_DEFINED +typedef struct pdc_bstr_s pdc_bstr; /* byte strings */ +typedef struct pdc_ustr_s pdc_ustr; /* unicode strings */ +#endif + +#ifndef PDC_MEMPOOL_DEFINED +#define PDC_MEMPOOL_DEFINED +typedef struct pdc_mempool_s pdc_mempool; +#endif + +/* ------------------------ the core public structure ---------------------- */ + +struct pdc_core_s +{ + pdc_core_priv *pr; /* pdcore private structure */ + + pdc_reslist *reslist; /* resource list */ + pdc_virtfile *filesystem; /* virtual file system */ + pdc_loggdef *logg; /* logging definition */ + pdc_bool loggenv; /* logging environ. variable checked */ + pdc_encoding_stack *encstack; /* encoding stack */ + pdc_priv_glyphtab *pglyphtab; /* private glyph table */ + pdc_mempool *bstr_pool; /* pdc_bstr pool */ + pdc_mempool *ustr_pool; /* pdc_ustr pool */ + pdc_ulong last_rand; /* for pdc_rand()/pdc_srand() */ + + const char *prodname; /* product name */ + const char *version; /* version string */ + char *binding; /* name of the language binding */ + pdc_bool unicaplang; /* Unicode capable language */ + pdc_bool objorient; /* binding object orientated */ + pdc_bool hastobepos; /* handles have to be positiv */ + pdc_bool ptfrun; /* while PTF is running */ + pdc_bool smokerun; /* while smoketest is running */ + pdc_bool charref; /* HTML character references will + * be resolved */ + pdc_bool escapesequ; /* escape sequences will be resolved */ + pdc_bool honorlang; /* honor LANG codeset for file names */ + int compatibility; /* PDF version number * 10 */ + int floatdigits; /* floating point output precision */ + int uniqueno; /* unique number for numbering */ + +}; + +#define PDC_BOOLSTR(a) (a != 0 ? "true" : "false") + +#define PDC_ABS(x) (((x) < 0) ? -(x) : (x)) + +/* TODO: replace with PDC_MIN, PDC_MAX +*/ +#ifndef MIN +#define MIN(a, b) (((a) < (b) ? (a) : (b))) +#endif +#ifndef MAX +#define MAX(a, b) (((a) > (b) ? (a) : (b))) +#endif + +/* reasonable values for number limits */ +#define PDC_FLOAT_MAX ((double) 1e+18) +#define PDC_FLOAT_MIN ((double) -1e+18) +#define PDC_FLOAT_PREC ((double) 1e-6) + +#define PDC_ROUND(x) (((x) < 0) ? ceil((x) - 0.5) : floor((x) + 0.5)) + +#define PDC_FLOAT_ISNULL(x) \ + (((((x) < 0) ? -1 * (x) : (x)) < PDC_FLOAT_PREC) ? pdc_true : pdc_false) + +/* flags for pdc_split_stringlist */ +#define PDC_SPLIT_ISOPTLIST (1L<<0) + +#define PDC_INT_UNSIGNED (1L<<0) +#define PDC_INT_CHAR (1L<<1) +#define PDC_INT_SHORT (1L<<2) +#define PDC_INT_HEXADEC (1L<<4) +#define PDC_INT_DEC (1L<<5) +#define PDC_INT_OCTAL (1L<<6) +#define PDC_INT_CASESENS (1L<<7) + +#define PDC_INT_CODE (PDC_INT_UNSIGNED | PDC_INT_CHAR | PDC_INT_HEXADEC) +#define PDC_INT_UNICODE (PDC_INT_UNSIGNED | PDC_INT_SHORT | PDC_INT_HEXADEC) + +#define PDC_GET_SHORT pdc_get_le_short +#define PDC_GET_USHORT pdc_get_le_ushort +#define PDC_GET_WORD pdc_get_le_ushort +#define PDC_GET_DWORD pdc_get_le_ulong +#define PDC_GET_DWORD3 pdc_get_le_ulong3 +#define PDC_GET_LONG pdc_get_le_long +#define PDC_GET_ULONG pdc_get_le_ulong + +#define PDC_TREE_INHERIT (1L<<0) +#define PDC_TREE_ISLEAF (1L<<1) + +#define PDC_NAME_SEPARSIGN '.' +#define PDC_NAME_SEPARSTRG "." + +#define PDC_KIDS_CHUNKSIZE 5 + +/* tree error codes */ +typedef enum +{ + tree_ok = 0, + tree_notfound, + tree_nameexists, + tree_isleaf +} +pdc_branch_error; + +typedef struct pdc_branch_s pdc_branch; + +#define PDC_TIME_SBUF_SIZE 50 + +void pdc_set_unsupp_error(pdc_core *pdc, int err_config, int err_lite, + pdc_bool warning); +void pdc_check_number(pdc_core *pdc, const char *paramname, double dz); +void pdc_check_number_limits(pdc_core *pdc, const char *paramname, double dz, + double dmin, double dmax); +void pdc_check_number_zero(pdc_core *pdc, const char *paramname, double dz); + +typedef struct +{ + int second; + int minute; + int hour; + int mday; + int wday; + int month; + int year; +} pdc_time; + +void pdc_localtime(pdc_time *t); +void pdc_get_timestr(char *str, pdc_bool ktoascii); + +pdc_bool pdc_check_lang_code(pdc_core *pdc, const char* lang_code); + +void pdc_setbit(char *bitarr, int bit); +pdc_bool pdc_getbit(const char *bitarr, int bit); +void pdc_setbit_text(char *bitarr, const unsigned char *text, + int len, int nbits, int size); + +pdc_short pdc_get_le_short(const pdc_byte *data); +pdc_ushort pdc_get_le_ushort(const pdc_byte *data); +pdc_sint32 pdc_get_le_long(const pdc_byte *data); +pdc_uint32 pdc_get_le_ulong3(const pdc_byte *data); +pdc_uint32 pdc_get_le_ulong(const pdc_byte *data); +pdc_short pdc_get_be_short(const pdc_byte *data); +pdc_ushort pdc_get_be_ushort(const pdc_byte *data); +pdc_sint32 pdc_get_be_long(const pdc_byte *data); +pdc_uint32 pdc_get_be_ulong3(const pdc_byte *data); +pdc_uint32 pdc_get_be_ulong(const pdc_byte *data); + +size_t pdc_strlen(const char *text); +char *pdc_getenv(const char *name); +char *pdc_strdup_ext(pdc_core *pdc, const char *text, int flags, + const char *fn); +char *pdc_strdup(pdc_core *pdc, const char *text); +char *pdc_strdup2(pdc_core *pdc, const char *text, size_t len); +char *pdc_strdup_tmp(pdc_core *pdc, const char *text); +pdc_bool pdc_logg_isprint(int c); +char *pdc_strprint(pdc_core *pdc, const char *str, int leni, + int maxchar, pdc_strform_kind strform); +char *pdc_strdup_convert(pdc_core *pdc, pdc_encoding encto, + pdc_encoding encfrom, const char *text, int flags, + const char *fn); +const char *pdc_utf8strprint(pdc_core *pdc, const char *str); +int pdc_split_stringlist(pdc_core *pdc, const char *text, + const char *i_separstr, int flags, char ***stringlist); +char * pdc_substitute_variables(pdc_core *pdc, const char *string, char vchar, + const char *delimiters, const char **varslist, + const char **valslist, int nvars, int *errind); +void pdc_cleanup_stringlist(pdc_core *pdc, char **stringlist); +int pdc_strcmp(const char *s1, const char *s2); +int pdc_stricmp(const char *s1, const char *s2); +int pdc_strincmp(const char *s1, const char *s2, int n); +char *pdc_strtrim(char *m_str); +char *pdc_str2trim(char *m_str); +char *pdc_strtoupper(char *str); +char *pdc_strtolower(char *str); +int pdc_tolower_ascii(int c); +int pdc_toupper_ascii(int c); +void pdc_swap_bytes(char *instring, int inlen, char *outstring); +void pdc_swap_unicodes(char *instring); +char *pdc_strdup_withbom(pdc_core *pdc, const char *text); +void pdc_inflate_ascii(const char *instring, int inlen, char *outstring, + pdc_text_format textformat); + +pdc_ushort pdc_get_string_value(pdc_byte *str, int i, int charlen); + +int pdc_subst_backslash(pdc_core *pdc, pdc_byte *str, int len, + pdc_encodingvector *ev, pdc_text_format textformat, pdc_bool verbose); + +pdc_bool pdc_str2double(const char *string, double *o_dz); +pdc_bool pdc_str2integer(const char *string, int flags, void *o_iz); + +int pdc_vfprintf(pdc_core *pdc, pdc_bool pdfconf, FILE *fp, + const char *format, va_list args); +int pdc_fprintf(pdc_core *pdc, pdc_bool pdfconf, FILE *fp, + const char *format, ...); +int pdc_vsprintf(pdc_core *pdc, pdc_bool pdfconf, char *buf, + const char *format, va_list args); +int pdc_sprintf(pdc_core *pdc, pdc_bool pdfconf, char *buf, + const char *format, ...); +int pdc_vsnprintf(char *buf, size_t size, + const char *format, va_list args); + +pdc_branch *pdc_init_tree(pdc_core *pdc); +pdc_branch *pdc_create_treebranch(pdc_core *pdc, pdc_branch *root, + const char *pathname, void *data, int flags, int size, + pdc_branch_error *errcode, const char **name_p); +char *pdc_get_name_treebranch(pdc_branch *branch); +pdc_branch *pdc_get_parent_treebranch(pdc_branch *branch); +pdc_branch **pdc_get_kids_treebranch(pdc_branch *branch, int *nkids); +void *pdc_get_data_treebranch(pdc_branch *branch); +void pdc_cleanup_treebranch(pdc_core *pdc, pdc_branch *branch); +void pdc_deactivate_name_treebranch(pdc_core *pdc, pdc_branch *branch); + +pdc_mempool * pdc_mp_new(pdc_core *pdc, size_t item_size); +void pdc_mp_delete(pdc_mempool *mp); +void * pdc_mp_alloc(pdc_mempool *mp); +void pdc_mp_free(pdc_mempool *mp, void *item); + +int pdc_name2idx(const char **names, int size, const char *name); +void * pdc_lfind(const void *key, const void *base, size_t *nmemb, + size_t size, int (*compar)(const void *, const void *)); + +int pdc_rand(pdc_core *pdc); +void pdc_srand(pdc_core *pdc, pdc_uint seed); + +#endif /* PC_UTIL_H */ diff --git a/src/pdflib/pdcore/pc_xmp.c b/src/pdflib/pdcore/pc_xmp.c new file mode 100644 index 0000000..f939c0b --- /dev/null +++ b/src/pdflib/pdcore/pc_xmp.c @@ -0,0 +1,31 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_xmp.c,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * The core XMP support. + * + */ + +#include "pc_util.h" +#include "pc_strconst.h" +#include "pc_md5.h" + + + + + + + + + + diff --git a/src/pdflib/pdcore/pc_xmp.h b/src/pdflib/pdcore/pc_xmp.h new file mode 100644 index 0000000..4ad0f12 --- /dev/null +++ b/src/pdflib/pdcore/pc_xmp.h @@ -0,0 +1,27 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pc_xmp.h,v 1.1 2008/10/17 06:10:43 scuri Exp $ + * + * The public core XMP support. + * + */ + +#ifndef PC_XMP_H +#define PC_XMP_H + + +#endif /* PC_XMP_H */ + + + + diff --git a/src/pdflib/pdflib/p_3d.c b/src/pdflib/pdflib/p_3d.c new file mode 100644 index 0000000..033c834 --- /dev/null +++ b/src/pdflib/pdflib/p_3d.c @@ -0,0 +1,22 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + *---------------------------------------------------------------------------*/ + +/* $Id: p_3d.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib 3D functions routines + * + */ + +#define P_3D_C + +#include "p_intern.h" +#include "p_color.h" + diff --git a/src/pdflib/pdflib/p_actions.c b/src/pdflib/pdflib/p_actions.c new file mode 100644 index 0000000..f3c42fc --- /dev/null +++ b/src/pdflib/pdflib/p_actions.c @@ -0,0 +1,1155 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_actions.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib actions handling routines + * + */ + +#define P_ACTIONS_C + +#include "p_intern.h" +#include "p_layer.h" + +typedef enum +{ + pdf_allact = -1, + pdf_goto = (1<<0), + pdf_gotor = (1<<1), + pdf_launch = (1<<2), + pdf_uri = (1<<3), + pdf_hide = (1<<4), + pdf_named = (1<<5), + pdf_submitform = (1<<6), + pdf_resetform = (1<<7), + pdf_importdata = (1<<8), + pdf_javascript = (1<<9), + pdf_setocgstate = (1<<10), + pdf_trans = (1<<11), + pdf_goto3dview = (1<<12) +} +pdf_actiontype; + +static const pdc_keyconn pdf_action_pdfkeylist[] = +{ + {"GoTo", pdf_goto}, + {"GoToR", pdf_gotor}, + {"Launch", pdf_launch}, + {"URI", pdf_uri}, + {"Hide", pdf_hide}, + {"Named", pdf_named}, + {"SubmitForm", pdf_submitform}, + {"ResetForm", pdf_resetform}, + {"ImportData", pdf_importdata}, + {"JavaScript", pdf_javascript}, + {"SetOCGState", pdf_setocgstate}, + {"Trans", pdf_trans}, + {"GoTo3DView", pdf_goto3dview}, + {NULL, 0} +}; + + +typedef enum +{ + /* values are identical with PDF values */ + pdf_exp_fdf = (1<<1), + pdf_exp_html = (1<<2), + pdf_exp_getrequest = (1<<3), + pdf_exp_coordinates = (1<<4), + pdf_exp_xfdf = (1<<5), + pdf_exp_updates = (1<<6), + pdf_exp_annotfields = (1<<7), + pdf_exp_pdf = (1<<8), + pdf_exp_onlyuser = (1<<10), + pdf_exp_exclurl = (1<<11) +} +pdf_exportmethod; + +/* allowed combinations of exportmethod keywords */ +static pdf_exportmethod pdf_allfdf = (pdf_exportmethod) + (pdf_exp_fdf | + pdf_exp_updates | + pdf_exp_exclurl | + pdf_exp_annotfields | + pdf_exp_onlyuser); + +static pdf_exportmethod pdf_allhtml = (pdf_exportmethod) + (pdf_exp_html | + pdf_exp_getrequest | + pdf_exp_coordinates); + +static pdf_exportmethod pdf_allxfdf = pdf_exp_xfdf; + +static pdf_exportmethod pdf_allpdf = (pdf_exportmethod) + (pdf_exp_pdf | + pdf_exp_getrequest); + +static const pdc_keyconn pdf_exportmethod_keylist[] = +{ + {"fdf", pdf_exp_fdf}, + {"html", pdf_exp_html}, + {"xfdf", pdf_exp_xfdf}, + {"pdf", pdf_exp_pdf}, + {"getrequest", pdf_exp_getrequest}, + {"coordinates", pdf_exp_coordinates}, + {"updates", pdf_exp_updates}, + {"annotfields", pdf_exp_annotfields}, + {"onlyuser", pdf_exp_onlyuser}, + {"exclurl", pdf_exp_exclurl}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_filename_keylist[] = +{ + {"filename", (pdf_actiontype) (pdf_gotor | pdf_launch | pdf_importdata)}, + {"url", (pdf_actiontype) (pdf_uri | pdf_submitform)}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_operation_pdfkeylist[] = +{ + {"open", 1}, + {"print", 2}, + {NULL, 0} +}; + + +static const pdc_keyconn pdf_3dview_keylist[] = +{ + {NULL, 0} +}; + + + +#define PDF_LAYER_FLAG PDC_OPT_UNSUPP + +#define PDF_JAVASCRIPT_FLAG PDC_OPT_UNSUPP +#define PDF_3DVIEW_FLAG PDC_OPT_UNSUPP + +static const pdc_defopt pdf_create_action_options[] = +{ + /* deprecated */ + {"actionwarning", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"destination", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"destname", pdc_stringlist, PDC_OPT_IGNOREIF1, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"filename", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_FILENAMELEN, NULL}, + + {"url", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"parameters", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"operation", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_operation_pdfkeylist}, + + {"defaultdir", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"menuname", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"script", pdc_stringlist, PDF_JAVASCRIPT_FLAG, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"scriptname", pdc_stringlist, PDF_JAVASCRIPT_FLAG, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"namelist", pdc_stringlist, PDC_OPT_NONE, 1, PDF_MAXARRAYSIZE, + 0.0, PDC_USHRT_MAX, NULL}, + + {"exportmethod", pdc_keywordlist, PDC_OPT_BUILDOR, 1, 10, + 0.0, 0.0, pdf_exportmethod_keylist}, + + {"newwindow", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"ismap", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"hide", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"exclude", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"submitemptyfields", pdc_booleanlist, PDC_OPT_PDC_1_4, 1, 1, + 0.0, 0.0, NULL}, + + {"canonicaldate", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"layerstate", pdc_stringlist, PDF_LAYER_FLAG | PDC_OPT_EVENNUM, 1, 100, + 1.0, 8.0, NULL}, + + {"preserveradio", pdc_booleanlist, PDF_LAYER_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + {"3dview", pdc_3dviewhandle, PDF_3DVIEW_FLAG, 1, 1, + 0.0, 0.0, pdf_3dview_keylist}, + + {"target", pdc_stringlist, PDF_3DVIEW_FLAG, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"transition", pdc_keywordlist, PDC_OPT_PDC_1_5, 1, 1, + 0.0, 0.0, pdf_transition_keylist}, + + {"duration", pdc_scalarlist, PDC_OPT_PDC_1_5, 1, 1, + 0.0, PDC_FLOAT_MAX, NULL}, + + PDF_ERRORPOLICY_OPTION + + PDC_OPT_TERMINATE +}; + +typedef struct pdf_action_s +{ + pdc_id obj_id; + pdf_actiontype atype; + pdf_dest *dest; + pdc_encoding hypertextencoding; + char *filename; + char *parameters; + char *operation; + char *defaultdir; + char *menuname; + char *script; + char *scriptname; + char **namelist; + int nsnames; + pdc_bool newwindow; + pdc_bool ismap; + pdc_bool hide; + pdc_bool exclude; + pdc_bool submitemptyfields; + pdc_bool canonicaldate; + pdf_exportmethod exportmethod; + int transition; + double duration; +} +pdf_action; + +static void +pdf_reclaim_action(void *item) +{ + pdf_action *action = (pdf_action *) item; + + action->obj_id = PDC_BAD_ID; + action->atype = (pdf_actiontype) 0; + action->dest = NULL; + action->hypertextencoding = pdc_invalidenc; + action->filename = NULL; + action->parameters = NULL; + action->operation = NULL; + action->defaultdir = NULL; + action->menuname = NULL; + action->script = NULL; + action->scriptname = NULL; + action->namelist = NULL; + action->nsnames = 0; + action->newwindow = pdc_undef; + action->ismap = pdc_false; + action->hide = pdc_true; + action->exclude = pdc_false; + action->submitemptyfields = pdc_false; + action->canonicaldate = pdc_false; + action->exportmethod = pdf_exp_fdf; + action->transition = (int) trans_replace; + action->duration = 1; +} + +static void +pdf_release_action(void *context, void *item) +{ + PDF *p = (PDF *) context; + pdf_action *action = (pdf_action *) item; + + pdf_cleanup_destination(p, action->dest); + + if (action->filename) + { + pdc_free(p->pdc, action->filename); + action->filename = NULL; + } + + if (action->parameters) + { + pdc_free(p->pdc, action->parameters); + action->parameters = NULL; + } + + if (action->defaultdir) + { + pdc_free(p->pdc, action->defaultdir); + action->defaultdir = NULL; + } + + if (action->menuname) + { + pdc_free(p->pdc, action->menuname); + action->menuname = NULL; + } + + if (action->script) + { + pdc_free(p->pdc, action->script); + action->script = NULL; + } + + if (action->namelist) + { + pdc_cleanup_optstringlist(p->pdc, action->namelist, action->nsnames); + action->namelist = NULL; + } + +} + +static pdc_ced pdf_action_ced = +{ + sizeof(pdf_action), pdf_reclaim_action, pdf_release_action, NULL +}; + +static pdc_vtr_parms pdf_action_parms = +{ + 0, 10, 10 +}; + +static pdf_action * +pdf_new_action(PDF *p) +{ + pdf_action *result; + + if (p->actions == NULL) + p->actions = pdc_vtr_new(p->pdc, &pdf_action_ced, p, &pdf_action_parms); + + result = pdc_vtr_incr(p->actions, pdf_action); + result->hypertextencoding = p->hypertextencoding; + return result; +} + +void +pdf_delete_actions(PDF *p) +{ + if (p->actions != NULL) + { + pdc_vtr_delete(p->actions); + p->actions = NULL; + } +} + +int +pdf_get_max_action(PDF *p) +{ + return (p->actions == NULL) ? -1 : pdc_vtr_size(p->actions) - 1; +} + +static pdc_id pdf_write_action(PDF *p, pdf_action *action, pdc_id next_id); + + +static int +pdf_opt_effectless(PDF *p, const char *keyword, pdf_actiontype curratype, + pdf_actiontype intendatypes) +{ + if ((pdf_actiontype) !(intendatypes & curratype)) + { + const char *type = pdc_get_keyword(curratype, pdf_action_pdfkeylist); + pdc_warning(p->pdc, PDF_E_ACT_OPTIGNORE_FORTYPE, keyword,type, 0, 0); + return 1; + } + return 0; +} + +int +pdf__create_action(PDF *p, const char *type, const char *optlist) +{ + pdc_resopt *resopts = NULL; + pdc_clientdata data; + pdf_action *action; + pdf_actiontype atype; + pdf_dest *dest = NULL; + pdc_bool verbose = pdc_true; + pdc_bool hasdest = pdc_false; + pdc_encoding htenc; + int htcp; + const char *keyword; + char **strlist; + int i, k, ns; + + if (type == NULL || *type == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "type", 0, 0, 0); + + k = pdc_get_keycode_ci(type, pdf_action_pdfkeylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0); + atype = (pdf_actiontype) k; + + + if (atype == pdf_javascript) + pdc_error(p->pdc, PDF_E_UNSUPP_JAVASCRIPT, 0, 0, 0, 0); + + /* compatibility */ + if (p->compatibility < PDC_1_6 && atype == pdf_goto3dview) + { + pdc_error(p->pdc, PDC_E_PAR_VERSION, type, + pdc_get_pdfversion(p->pdc, PDC_1_6), 0, 0); + } + if (p->compatibility < PDC_1_5 && + (atype == pdf_setocgstate || atype == pdf_trans)) + { + pdc_error(p->pdc, PDC_E_PAR_VERSION, type, + pdc_get_pdfversion(p->pdc, PDC_1_5), 0, 0); + } + + /* new action */ + action = pdf_new_action(p); + action->atype = atype; + + /* Parsing option list */ + pdf_set_clientdata(p, &data); + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_create_action_options, + &data, pdc_true); + + keyword = "actionwarning"; + pdc_get_optvalues(keyword, resopts, &verbose, NULL); + verbose = pdf_get_errorpolicy(p, resopts, verbose); + + htenc = pdf_get_hypertextencoding_opt(p, resopts, &htcp, pdc_true); + + keyword = "destination"; + if (pdc_get_optvalues(keyword, resopts, NULL, &strlist)) + { + if (!pdf_opt_effectless(p, keyword, atype, + (pdf_actiontype) (pdf_goto | pdf_gotor))) + { + action->dest = pdf_parse_destination_optlist(p, strlist[0], + (atype == pdf_goto) ? 0 : 1, + (atype == pdf_goto) ? pdf_locallink : pdf_remotelink); + hasdest = pdc_true; + } + } + else + { + keyword = "destname"; + if (atype == pdf_goto || atype == pdf_gotor) + dest = pdf_get_option_destname(p, resopts, htenc, htcp); + else if (pdc_get_optvalues(keyword, resopts, NULL, NULL)) + pdf_opt_effectless(p, keyword, atype, + (pdf_actiontype) (pdf_goto | pdf_gotor)); + if (dest) + { + action->dest = dest; + hasdest = pdc_true; + } + } + + /* filename or url */ + for (i = 0; ; i++) + { + keyword = pdf_filename_keylist[i].word; + if (keyword) + { + if (pdc_get_optvalues(keyword, resopts, NULL, &strlist)) + { + if (!pdf_opt_effectless(p, keyword, atype, + (pdf_actiontype) pdf_filename_keylist[i].code)) + { + action->filename = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + } + } + else + break; + } + + keyword = "parameters"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL) && + !pdf_opt_effectless(p, keyword, atype, pdf_launch)) + action->parameters = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + keyword = "operation"; + if (pdc_get_optvalues(keyword, resopts, &k, NULL) && + !pdf_opt_effectless(p, keyword, atype, pdf_launch)) + action->operation = + (char *) pdc_get_keyword(k, pdf_operation_pdfkeylist); + + keyword = "defaultdir"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL) && + !pdf_opt_effectless(p, keyword, atype, pdf_launch)) + action->defaultdir = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + keyword = "menuname"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL) && + !pdf_opt_effectless(p, keyword, atype, pdf_named)) + { + action->menuname = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + keyword = "namelist"; + ns = pdc_get_optvalues(keyword, resopts, NULL, NULL); + if (ns && !pdf_opt_effectless(p, keyword, atype, + (pdf_actiontype) (pdf_hide | pdf_submitform | pdf_resetform))) + { + action->namelist = (char **) pdc_save_lastopt(resopts, PDC_OPT_SAVEALL); + action->nsnames = ns; + } + + + keyword = "exportmethod"; + if (pdc_get_optvalues(keyword, resopts, &k, NULL)) + { + action->exportmethod = (pdf_exportmethod) k; + if (!pdf_opt_effectless(p, keyword, atype, pdf_submitform)) + { + if ((action->exportmethod & pdf_exp_fdf && + (action->exportmethod | pdf_allfdf) != pdf_allfdf) || + (action->exportmethod & pdf_exp_html && + (action->exportmethod | pdf_allhtml) != pdf_allhtml) || + (action->exportmethod & pdf_exp_xfdf && + (action->exportmethod | pdf_allxfdf) != pdf_allxfdf) || + (action->exportmethod & pdf_exp_pdf && + (action->exportmethod | pdf_allpdf) != pdf_allpdf)) + { + pdc_error(p->pdc, PDC_E_OPT_ILLCOMB, keyword, 0, 0, 0); + } + if (action->exportmethod & pdf_exp_fdf) + action->exportmethod = (pdf_exportmethod) + (action->exportmethod & ~pdf_exp_fdf); + } + } + + keyword = "newwindow"; + if (pdc_get_optvalues(keyword, resopts, &action->newwindow, NULL)) + pdf_opt_effectless(p, keyword, atype, + (pdf_actiontype) (pdf_gotor | pdf_launch)); + + keyword = "ismap"; + if (pdc_get_optvalues(keyword, resopts, &action->ismap, NULL)) + pdf_opt_effectless(p, keyword, atype, pdf_uri); + + keyword = "hide"; + if (pdc_get_optvalues(keyword, resopts, &action->hide, NULL)) + pdf_opt_effectless(p, keyword, atype, pdf_hide); + + keyword = "exclude"; + if (pdc_get_optvalues(keyword, resopts, &action->exclude, NULL)) + pdf_opt_effectless(p, keyword, atype, + (pdf_actiontype) (pdf_submitform | pdf_resetform)); + + keyword = "submitemptyfields"; + if (pdc_get_optvalues(keyword, resopts, &action->submitemptyfields, NULL)) + pdf_opt_effectless(p, keyword, atype, pdf_submitform); + + keyword = "canonicaldate"; + if (pdc_get_optvalues(keyword, resopts, &action->canonicaldate, NULL)) + pdf_opt_effectless(p, keyword, atype, pdf_submitform); + + keyword = "transition"; + if (pdc_get_optvalues(keyword, resopts, &action->transition, NULL)) + pdf_opt_effectless(p, keyword, atype, pdf_trans); + + keyword = "duration"; + if (pdc_get_optvalues(keyword, resopts, &action->duration, NULL)) + pdf_opt_effectless(p, keyword, atype, pdf_trans); + + + + /* required options */ + keyword = NULL; + if (!hasdest && + (atype == pdf_goto || atype == pdf_gotor)) + keyword = "destination"; + if (!action->filename && + (atype == pdf_gotor || atype == pdf_launch || atype == pdf_importdata)) + keyword = "filename"; + if (!action->menuname && atype == pdf_named) + keyword = "menuname"; + if (!action->namelist && atype == pdf_hide) + keyword = "namelist"; + if (!action->filename && + (atype == pdf_uri || atype == pdf_submitform)) + keyword = "url"; + if (keyword) + pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, keyword, 0, 0, 0); + + + return pdf_get_max_action(p); +} + + +static pdc_id +pdf_write_action(PDF *p, pdf_action *action, pdc_id next_id) +{ + pdc_id ret_id = PDC_BAD_ID; + int i, flags = 0; + + + ret_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Action object */ + pdc_begin_dict(p->out); /* Action dict */ + + pdc_puts(p->out, "/Type/Action\n"); + pdc_printf(p->out, "/S/%s\n", + pdc_get_keyword(action->atype, pdf_action_pdfkeylist)); + + /* next action */ + if (next_id != PDC_BAD_ID) + pdc_objref(p->out, "/Next", next_id); + else + action->obj_id = ret_id; + + /* destination */ + switch (action->atype) + { + case pdf_goto: + case pdf_gotor: + + pdc_puts(p->out, "/D"); + pdf_write_destination(p, action->dest); + + default: + break; + } + + /* file specification */ + switch (action->atype) + { + case pdf_gotor: + case pdf_launch: + if (action->newwindow != pdc_undef) + pdc_printf(p->out, "/NewWindow %s\n", + PDC_BOOLSTR(action->newwindow)); + case pdf_importdata: + + if (action->parameters || action->operation || action->defaultdir) + { + /* Windows-specific launch parameters */ + pdc_puts(p->out, "/Win"); + pdc_begin_dict(p->out); /* Win dict */ + pdc_printf(p->out, "/F"); + pdf_put_hypertext(p, action->filename); + pdc_puts(p->out, "\n"); + if (action->parameters) + { + pdc_printf(p->out, "/P"); + pdf_put_hypertext(p, action->parameters); + pdc_puts(p->out, "\n"); + pdc_free(p->pdc, action->parameters); + action->parameters = NULL; + } + if (action->operation) + { + pdc_printf(p->out, "/O"); + pdf_put_hypertext(p, action->operation); + pdc_puts(p->out, "\n"); + action->operation = NULL; + } + if (action->defaultdir) + { + pdc_printf(p->out, "/D"); + pdf_put_hypertext(p, action->defaultdir); + pdc_puts(p->out, "\n"); + pdc_free(p->pdc, action->defaultdir); + action->defaultdir = NULL; + } + pdc_end_dict(p->out); /* Win dict */ + } + else + { + pdc_puts(p->out, "/F"); + pdc_begin_dict(p->out); /* F dict */ + pdc_puts(p->out, "/Type/Filespec\n"); + pdc_printf(p->out, "/F"); + pdf_put_pdffilename(p, action->filename); + pdc_puts(p->out, "\n"); + pdc_end_dict(p->out); /* F dict */ + } + + default: + break; + } + + /* URI */ + switch (action->atype) + { + case pdf_uri: + pdc_puts(p->out, "/URI"); + pdf_put_hypertext(p, action->filename); + pdc_puts(p->out, "\n"); + + /* IsMap */ + if (action->ismap == pdc_true) + pdc_puts(p->out, "/IsMap true\n"); + + default: + break; + } + + /* Named */ + switch (action->atype) + { + case pdf_named: + pdc_printf(p->out, "/N"); + pdf_put_pdfname(p, action->menuname); + pdc_puts(p->out, "\n"); + + default: + break; + } + + /* name list */ + switch (action->atype) + { + case pdf_hide: + if (action->hide == pdc_false) + pdc_puts(p->out, "/H false\n"); + case pdf_submitform: + case pdf_resetform: + + if (action->nsnames) + { + pdc_printf(p->out, "/%s", + (action->atype == pdf_hide) ? "T" : "Fields"); + pdc_begin_array(p->out); + for (i = 0; i < action->nsnames; i++) + { + pdf_put_hypertext(p, action->namelist[i]); + if (i < action->nsnames - 1) + pdc_puts(p->out, "\n"); + else + pdc_end_array(p->out); + } + } + + default: + break; + } + + /* URL */ + switch (action->atype) + { + case pdf_submitform: + pdc_puts(p->out, "/F"); + pdc_begin_dict(p->out); /* F dict */ + pdc_puts(p->out, "/FS/URL\n"); + pdc_printf(p->out, "/F"); + pdf_put_hypertext(p, action->filename); + pdc_puts(p->out, "\n"); + pdc_end_dict(p->out); /* F dict */ + + default: + break; + } + + /* Trans */ + switch (action->atype) + { + case pdf_trans: + pdc_puts(p->out, "/Trans"); + pdc_begin_dict(p->out); /* Trans dict */ + pdc_puts(p->out, "/Type/Trans\n"); + if (action->transition != trans_replace) + pdc_printf(p->out, "/S/%s", + pdc_get_keyword(action->transition, pdf_transition_pdfkeylist)); + if (action->duration > 0) + pdc_printf(p->out, "/D %f\n", action->duration); + pdc_end_dict(p->out); /* Trans dict */ + + default: + break; + } + + /* Flags */ + switch (action->atype) + { + case pdf_submitform: + flags = (int) action->exportmethod; + if (action->submitemptyfields) + flags |= (1<<1); + if (action->canonicaldate) + flags |= (1<<9); + case pdf_resetform: + + if (action->exclude) + flags |= (1<<0); + if (flags) + pdc_printf(p->out, "/Flags %d\n", flags); + + default: + break; + } + + + + pdc_end_dict(p->out); /* Action dict */ + pdc_end_obj(p->out); /* Action object */ + + return ret_id; +} + + + +/* ---- Annotations events ---- */ + +static const pdc_keyconn pdf_annotevent_keylist[] = +{ + {"activate", 0}, + {"enter", 1}, + {"exit", 2}, + {"down", 3}, + {"up", 4}, + {"focus", 5}, + {"blur", 6}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_annotevent_pdfkeylist[] = +{ + {"A", 0}, + {"E", 1}, + {"X", 2}, + {"D", 3}, + {"U", 4}, + {"Fo", 5}, + {"Bl", 6}, + {NULL, 0} +}; + +static int pdf_annotevent_beginjava = 99; + +static const pdc_defopt pdf_annotevent_options[] = +{ + {"activate", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"enter", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"exit", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"down", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"up", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"focus", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"blur", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + PDC_OPT_TERMINATE +}; + + +/* ---- Bookmark events ---- */ + +static const pdc_keyconn pdf_bookmarkevent_keylist[] = +{ + {"activate", 0}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_bookmarkevent_pdfkeylist[] = +{ + {"A", 0}, + {NULL, 0} +}; + +static int pdf_bookmarkevent_beginjava = 99; + +static const pdc_defopt pdf_bookmarkevent_options[] = +{ + {"activate", pdc_actionhandle, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + PDC_OPT_TERMINATE +}; + + +/* ---- Document events ---- */ + +static const pdc_keyconn pdf_documentevent_keylist[] = +{ + {"open", 0}, + {"didprint", 1}, + {"didsave", 2}, + {"willclose", 3}, + {"willprint", 4}, + {"willsave", 5}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_documentevent_pdfkeylist[] = +{ + {"OpenAction", 0}, + {"DP", 1}, + {"DS", 2}, + {"WC", 3}, + {"WP", 4}, + {"WS", 5}, + {NULL, 0} +}; + +static int pdf_documentevent_beginjava = 1; + +static const pdc_defopt pdf_documentevent_options[] = +{ + {"open", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"didprint", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"didsave", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"willclose", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"willprint", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"willsave", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + PDC_OPT_TERMINATE +}; + + +/* ---- Page events ---- */ + +static const pdc_keyconn pdf_pageevent_keylist[] = +{ + {"", 0}, + {"open", 1}, + {"close", 2}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_pageevent_pdfkeylist[] = +{ + {"", 0}, + {"O", 1}, + {"C", 2}, + {NULL, 0} +}; + +static int pdf_pageevent_beginjava = 99; + +static const pdc_defopt pdf_pageevent_options[] = +{ + {"open", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + {"close", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX, + 0.0, 0.0, NULL}, + + PDC_OPT_TERMINATE +}; + + +pdc_bool +pdf_parse_and_write_actionlist(PDF *p, pdf_event_object eventobj, + pdc_id *act_idlist, const char *optlist) +{ + const pdc_defopt *defopttable = NULL; + const pdc_keyconn *keyconntable = NULL; + pdc_resopt *resopts = NULL; + pdc_clientdata data; + pdc_id ret_id = PDC_BAD_ID; + pdf_action *action = NULL; + pdc_bool calcevent = pdc_false; + const char *keyword, *type; + char **strlist; + int *actlist; + int i, code, nsact, beginjava = 0; + + switch(eventobj) + { + + case event_annotation: + defopttable = pdf_annotevent_options; + keyconntable = pdf_annotevent_keylist; + beginjava = pdf_annotevent_beginjava; + break; + + case event_bookmark: + defopttable = pdf_bookmarkevent_options; + keyconntable = pdf_bookmarkevent_keylist; + beginjava = pdf_bookmarkevent_beginjava; + break; + + case event_document: + defopttable = pdf_documentevent_options; + keyconntable = pdf_documentevent_keylist; + beginjava = pdf_documentevent_beginjava; + break; + + case event_page: + defopttable = pdf_pageevent_options; + keyconntable = pdf_pageevent_keylist; + beginjava = pdf_pageevent_beginjava; + break; + + default: + break; + } + + /* parsing option list */ + pdf_set_clientdata(p, &data); + resopts = pdc_parse_optionlist(p->pdc, optlist, defopttable, + &data, pdc_true); + + /* write actions and saving action ids */ + for (code = 0; ; code++) + { + keyword = pdc_get_keyword(code, keyconntable); + if (keyword) + { + nsact = pdc_get_optvalues(keyword, resopts, NULL, &strlist); + actlist = (int *) strlist; + + /* Not activate event */ + if (code && nsact) + { + /* additional action type check */ + for (i = 0; i < nsact; i++) + { + action = (pdf_action *) &pdc_vtr_at(p->actions, actlist[i], + pdf_action); + if (code >= beginjava && action->atype != pdf_javascript) + { + type = pdc_get_keyword(action->atype, + pdf_action_pdfkeylist); + pdc_error(p->pdc, PDF_E_ACT_BADACTTYPE, + type, keyword, 0, 0); + } + } + + /* saving calculation event */ + if (!strcmp(keyword, "calculate")) + calcevent = pdc_true; + } + + /* write action objects */ + if (act_idlist != NULL) + { + if (nsact == 1) + { + action = (pdf_action *) &pdc_vtr_at(p->actions, actlist[0], + pdf_action); + if (action->obj_id == PDC_BAD_ID) + ret_id = pdf_write_action(p, action, PDC_BAD_ID); + else + ret_id = action->obj_id; + } + else if (nsact > 1) + { + for (i = nsact-1; i >= 0; i--) + { + action = (pdf_action *) &pdc_vtr_at(p->actions, + actlist[i], pdf_action); + ret_id = pdf_write_action(p, action, ret_id); + } + } + else + ret_id = PDC_BAD_ID; + act_idlist[code] = ret_id; + } + } + else + break; + } + + return calcevent; +} + +pdc_bool +pdf_write_action_entries(PDF *p, pdf_event_object eventobj, pdc_id *act_idlist) +{ + const pdc_keyconn *keyconntable = NULL; + const char *keyword; + pdc_id act_id = PDC_BAD_ID; + pdc_bool adict = pdc_false; + pdc_bool aadict = pdc_false; + int code; + + + switch(eventobj) + { + + case event_annotation: + keyconntable = pdf_annotevent_pdfkeylist; + break; + + case event_bookmark: + keyconntable = pdf_bookmarkevent_pdfkeylist; + break; + + case event_document: + keyconntable = pdf_documentevent_pdfkeylist; + break; + + case event_page: + keyconntable = pdf_pageevent_pdfkeylist; + break; + + default: + break; + } + + for (code = 0; ; code++) + { + keyword = pdc_get_keyword(code, keyconntable); + if (keyword) + { + act_id = act_idlist[code]; + if (act_id != PDC_BAD_ID) + { + if (code && !aadict) + { + pdc_puts(p->out, "/AA"); + pdc_begin_dict(p->out); /* AA dict */ + aadict = pdc_true; + } + else if (!code) + adict = pdc_true; + pdc_printf(p->out, "/%s", keyword); + pdc_objref_c(p->out, act_id); + } + } + else + break; + } + if (aadict) + pdc_end_dict(p->out); /* AA dict */ + else if (adict) + pdc_puts(p->out, "\n"); + + return adict; +} diff --git a/src/pdflib/pdflib/p_afm.c b/src/pdflib/pdflib/p_afm.c new file mode 100644 index 0000000..8de04a5 --- /dev/null +++ b/src/pdflib/pdflib/p_afm.c @@ -0,0 +1,756 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_afm.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib AFM parsing routines + * + */ + +#include "p_intern.h" +#include "p_font.h" + +#define AFM_GLYPH_SUPPL 3 + +#define AFM_LINEBUF 4096 + +#define AFM_SEPARATORS "\f\n\r\t\v ,:;" + +/* The values of each of these enumerated items correspond to an entry in the + * table of strings defined below. Therefore, if you add a new string as + * new keyword into the keyStrings table, you must also add a corresponding + * pdf_afmkey AND it MUST be in the same position! + * + * IMPORTANT: since the sorting algorithm is a binary search, the strings of + * keywords must be placed in lexicographical order, below. [Therefore, the + * enumerated items are not necessarily in lexicographical order, depending + * on the name chosen. BUT, they must be placed in the same position as the + * corresponding key string.] The NOPE shall remain in the last position, + * since it does not correspond to any key string. + */ + +#ifndef PDFLIB_EBCDIC +typedef enum +{ + ASCENDER, + CHARBBOX, + CODE, + COMPCHAR, + CODEHEX, + CAPHEIGHT, + CHARWIDTH, + CHARACTERSET, + CHARACTERS, + COMMENT, + DESCENDER, + ENCODINGSCHEME, + ENDCHARMETRICS, + ENDCOMPOSITES, + ENDDIRECTION, + ENDFONTMETRICS, + ENDKERNDATA, + ENDKERNPAIRS, + ENDKERNPAIRS0, + ENDKERNPAIRS1, + ENDMASTERFONTMETRICS, + ENDTRACKKERN, + ESCCHAR, + FAMILYNAME, + FONTBBOX, + FONTNAME, + FULLNAME, + ISBASEFONT, + ISCIDFONT, + ISFIXEDPITCH, + ISFIXEDV, + ITALICANGLE, + KERNPAIR, + KERNPAIRHAMT, + KERNPAIRXAMT, + KERNPAIRYAMT, + LIGATURE, + MAPPINGSCHEME, + METRICSSETS, + CHARNAME, + NOTICE, + COMPCHARPIECE, + STARTCHARMETRICS, + STARTCOMPFONTMETRICS, + STARTCOMPOSITES, + STARTDIRECTION, + STARTFONTMETRICS, + STARTKERNDATA, + STARTKERNPAIRS, + STARTKERNPAIRS0, + STARTKERNPAIRS1, + STARTMASTERFONTMETRICS, + STARTTRACKKERN, + STDHW, + STDVW, + TRACKKERN, + UNDERLINEPOSITION, + UNDERLINETHICKNESS, + VVECTOR, + VERSION, + XYWIDTH, + XY0WIDTH, + X0WIDTH, + Y0WIDTH, + XY1WIDTH, + X1WIDTH, + Y1WIDTH, + XWIDTH, + YWIDTH, + WEIGHT, + XHEIGHT, + NOPE +} +pdf_afmkey; + +/* keywords for the system: + * This a table of all of the current strings that are vaild AFM keys. + * Each entry can be referenced by the appropriate pdf_afmkey value (an + * enumerated data type defined above). If you add a new keyword here, + * a corresponding pdf_afmkey MUST be added to the enumerated data type + * defined above, AND it MUST be added in the same position as the + * string is in this table. + * + * IMPORTANT: since the sorting algorithm is a binary search, the keywords + * must be placed in lexicographical order. And, NULL should remain at the + * end. + */ + +static const char *keyStrings[] = +{ + "Ascender", + "B", + "C", + "CC", + "CH", + "CapHeight", + "CharWidth", + "CharacterSet", + "Characters", + "Comment", + "Descender", + "EncodingScheme", + "EndCharMetrics", + "EndComposites", + "EndDirection", + "EndFontMetrics", + "EndKernData", + "EndKernPairs", + "EndKernPairs0", + "EndKernPairs1", + "EndMasterFontMetrics", + "EndTrackKern", + "EscChar", + "FamilyName", + "FontBBox", + "FontName", + "FullName", + "IsBaseFont", + "IsCIDFont", + "IsFixedPitch", + "IsFixedV", + "ItalicAngle", + "KP", + "KPH", + "KPX", + "KPY", + "L", + "MappingScheme", + "MetricsSets", + "N", + "Notice", + "PCC", + "StartCharMetrics", + "StartCompFontMetrics", + "StartComposites", + "StartDirection", + "StartFontMetrics", + "StartKernData", + "StartKernPairs", + "StartKernPairs0", + "StartKernPairs1", + "StartMasterFontMetrics", + "StartTrackKern", + "StdHW", + "StdVW", + "TrackKern", + "UnderlinePosition", + "UnderlineThickness", + "VVector", + "Version", + "W", + "W0", + "W0X", + "W0Y", + "W1", + "W1X", + "W1Y", + "WX", + "WY", + "Weight", + "XHeight" +}; + +#else /* !PDFLIB_EBCDIC */ +#endif /* PDFLIB_EBCDIC */ + +static pdc_bool +pdf_parse_afm( + PDF *p, + pdc_file *fp, + pdf_font *font, + const char *fontname, + const char *filename) +{ + static const char fn[] = "pdf_parse_afm"; + fnt_font_metric *ftm = &font->ft.m; + const char *afmtype = NULL; + char **wordlist, *keyword, *arg1; + char line[AFM_LINEBUF]; + int i, cmp, lo, hi, nwords, nglyphs = 0, nline = 0; + int tablen = ((sizeof keyStrings) / (sizeof (char *))); + pdc_sint32 iz; + double dz; + pdc_scalar charwidth = -1; + pdf_afmkey keynumber; + fnt_glyphwidth *glw; + pdc_bool toskip = pdc_false; + pdc_bool is_zadbfont = !strcmp(fontname, "ZapfDingbats"); + + /* all new glyph names of AGL 2.0 are missing */ + font->missingglyphs = 0xFFFFFFFF; + + /* read loop. because of Mac files we use pdc_fgetline */ + while (pdc_fgetline(line, AFM_LINEBUF, fp) != NULL) + { + /* split line */ + nline++; + nwords = pdc_split_stringlist(p->pdc, line, AFM_SEPARATORS, 0, + &wordlist); + if (!nwords) continue; + keyword = wordlist[0]; + + /* find keynumber */ + lo = 0; + hi = tablen; + keynumber = NOPE; + while (lo < hi) + { + i = (lo + hi) / 2; + cmp = strcmp(keyword, keyStrings[i]); + + if (cmp == 0) + { + keynumber = (pdf_afmkey) i; + break; + } + + if (cmp < 0) + hi = i; + else + lo = i + 1; + } + + /* unkown key */ + if (keynumber == NOPE) + { + pdc_warning(p->pdc, PDF_E_T1_AFMBADKEY, keyword, filename, 0,0); + goto PDF_PARSECONTD; + } + if (keynumber == ENDDIRECTION) + toskip = pdc_false; + + if (nwords == 1 || toskip == pdc_true) + goto PDF_PARSECONTD; + + /* key switch */ + arg1 = wordlist[1]; + switch (keynumber) + { + case STARTDIRECTION: + if (pdc_str2integer(arg1, 0, &iz) != pdc_true) + goto PDF_SYNTAXERROR; + if (iz) + toskip = pdc_true; + break; + + case STARTCOMPFONTMETRICS: + afmtype = "ACFM"; + goto PDF_SYNTAXERROR; + + case STARTMASTERFONTMETRICS: + afmtype = "AMFM"; + goto PDF_SYNTAXERROR; + + case ISCIDFONT: + afmtype = "CID font"; + if (!strcmp(arg1, "true")) + goto PDF_SYNTAXERROR; + break; + + case FONTNAME: + font->ft.name = pdc_strdup(p->pdc, arg1); + ftm->name = pdc_strdup(p->pdc, arg1); + pdc_logg_cond(p->pdc, 1, trc_font, + "\tPostScript font name: \"%s\"\n", ftm->name); + break; + + /* Recognize Multiple Master fonts by last part of name */ + case FAMILYNAME: + if (!strcmp(wordlist[nwords-1], "MM")) + ftm->type = fnt_MMType1; + else + ftm->type = fnt_Type1; + break; + + /* Default: FontSpecific */ + case ENCODINGSCHEME: + if (!pdc_stricmp(arg1, "StandardEncoding") || + !pdc_stricmp(arg1, "AdobeStandardEncoding")) + font->ft.issymbfont = pdc_false; + break; + + case STDHW: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->StdHW = (int) dz; + break; + + case STDVW: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->StdVW = (int) dz; + break; + + case WEIGHT: + font->ft.weight = fnt_check_weight(fnt_weightname2weight(arg1)); + break; + + case ISFIXEDPITCH: + if (!pdc_stricmp(arg1, "false")) + ftm->isFixedPitch = pdc_false; + else + ftm->isFixedPitch = pdc_true; + break; + + /* New AFM 4.1 keyword "CharWidth" implies fixed pitch */ + case CHARWIDTH: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + charwidth = dz; + ftm->isFixedPitch = pdc_true; + break; + + case ITALICANGLE: + { + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->italicAngle = dz; + } + break; + + case UNDERLINEPOSITION: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->underlinePosition = (int) dz; + break; + + case UNDERLINETHICKNESS: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->underlineThickness = (int) dz; + break; + + case FONTBBOX: + { + if (nwords != 5) + goto PDF_SYNTAXERROR; + for (i = 1; i < nwords; i++) + { + if (pdc_str2double(wordlist[i], &dz) != pdc_true) + goto PDF_SYNTAXERROR; + if (i == 1) + ftm->llx = dz; + else if (i == 2) + ftm->lly = dz; + else if (i == 3) + ftm->urx = dz; + else if (i == 4) + ftm->ury = dz; + } + } + break; + + case CAPHEIGHT: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->capHeight = (int) dz; + break; + + case XHEIGHT: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->xHeight = (int) dz; + break; + + case DESCENDER: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->descender = (int) dz; + break; + + case ASCENDER: + if (pdc_str2double(arg1, &dz) != pdc_true) + goto PDF_SYNTAXERROR; + ftm->ascender = (int) dz; + break; + + /* Character widths */ + + case STARTCHARMETRICS: + if (pdc_str2integer(arg1, PDC_INT_UNSIGNED, (pdc_sint32 *) &nglyphs) + != pdc_true || nglyphs <= 0) + goto PDF_SYNTAXERROR; + ftm->glw = (fnt_glyphwidth *) pdc_calloc(p->pdc, + (size_t) nglyphs * sizeof(fnt_glyphwidth), fn); + break; + + /* Character code */ + case CODE: + case CODEHEX: + if (!nglyphs || !ftm->glw) + goto PDF_SYNTAXERROR; + if (font->ft.numglyphs >= nglyphs) + { + nglyphs++; + ftm->glw = (fnt_glyphwidth *) pdc_realloc(p->pdc, ftm->glw, + (size_t) nglyphs * sizeof(fnt_glyphwidth), fn); + } + glw = &ftm->glw[font->ft.numglyphs]; + if (keynumber == CODE) + { + if (pdc_str2integer(arg1, 0, &iz) != pdc_true) + goto PDF_SYNTAXERROR; + } + else + { + if (pdc_str2integer(arg1, PDC_INT_HEXADEC, &iz) != pdc_true) + goto PDF_SYNTAXERROR; + } + glw->code = (pdc_short) iz; + glw->unicode = 0; + glw->width = (pdc_ushort) + (font->opt.monospace ? font->opt.monospace : charwidth); + font->ft.numglyphs++; + + /* Character width and name */ + for (i = 2; i < nwords; i++) + { + if (!strcmp(wordlist[i], "WX") || + !strcmp(wordlist[i], "W0X") || + !strcmp(wordlist[i], "W")) + { + i++; + if (i == nwords) + goto PDF_SYNTAXERROR; + if (pdc_str2double(wordlist[i], &dz) != pdc_true) + goto PDF_SYNTAXERROR; + glw->width = (pdc_ushort) + (font->opt.monospace ? font->opt.monospace : dz); + } + + if (!strcmp(wordlist[i], "N")) + { + i++; + if (i == nwords) + goto PDF_SYNTAXERROR; + + /* Unicode value by means of AGL, + * internal and private table + */ + glw->unicode = is_zadbfont ? + (pdc_ushort) pdc_zadb2unicode(wordlist[i]): + pdc_insert_glyphname(p->pdc, wordlist[i]); + pdc_delete_missingglyph_bit(glw->unicode, + &font->missingglyphs); + + } + } + break; + + + default: + break; + } + + PDF_PARSECONTD: + pdc_cleanup_stringlist(p->pdc, wordlist); + wordlist = NULL; + + if (keynumber == ENDFONTMETRICS) + break; + } + + /* necessary font struct members */ + if (font->ft.name == NULL || ftm->glw == NULL) + goto PDF_SYNTAXERROR; + + pdc_fclose(fp); + + ftm->numglwidths = font->ft.numglyphs; + return pdc_true; + + PDF_SYNTAXERROR: + pdc_fclose(fp); + pdc_cleanup_stringlist(p->pdc, wordlist); + + if (afmtype) + pdc_set_errmsg(p->pdc, PDF_E_T1_UNSUPP_FORMAT, afmtype, 0, 0, 0); + else + pdc_set_errmsg(p->pdc, PDC_E_IO_ILLSYNTAX, "AFM ", filename, + pdc_errprintf(p->pdc, "%d", nline), 0); + return pdc_false; +} + +pdc_bool +pdf_process_metrics_data( + PDF *p, + pdf_font *font, + const char *fontname) +{ + static const char fn[] = "pdf_process_metrics_data"; + fnt_font_metric *ftm = &font->ft.m; + int width = 0; + pdc_ushort uv; + pdc_encoding enc = font->ft.enc; + pdc_encodingvector *ev = NULL; + int nalloc, foundglyphs = 0, i, j = 0, k; + + (void) j; + + /* Unallowed encoding */ + if (enc == pdc_cid || enc < pdc_builtin) + { + + pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC, 0, 0, 0, 0); + + return pdc_false; + } + + /* Determine the default character width (width of space character) */ + if (font->opt.monospace) + { + ftm->defwidth = font->opt.monospace; + } + else + { + width = fnt_get_glyphwidth((int) PDF_DEFAULT_CHAR, &font->ft); + if (width != FNT_MISSING_WIDTH) + ftm->defwidth = width; + else + ftm->defwidth = FNT_DEFAULT_WIDTH; + } + + /* builtin font */ + if (font->ft.issymbfont == pdc_true && enc != pdc_builtin && + !strcmp(font->encapiname, "auto")) + { + enc = pdc_builtin; + font->ft.enc = enc; + } + + /* optimizing PDF output */ + if (enc == pdc_ebcdic || + enc == pdc_ebcdic_37 || + enc == pdc_ebcdic_winansi) + font->towinansi = pdc_winansi; + + /* glyph name list for incore fonts */ + nalloc = font->ft.numglyphs + AFM_GLYPH_SUPPL; + + /* + * Generate character width according to the chosen encoding + */ + + { + font->ft.numcodes = 256; + font->ft.code2gid = (pdc_ushort *) pdc_calloc(p->pdc, + font->ft.numcodes * sizeof (pdc_ushort), fn); + + ftm->numwidths = font->ft.numcodes; + ftm->widths = (int *)pdc_calloc(p->pdc, + font->ft.numcodes * sizeof(int), fn); + + /* Given 8-bit encoding */ + if (enc >= 0) + { + ev = pdc_get_encoding_vector(p->pdc, enc); + for (k = 0; k < font->ft.numcodes; k++) + { + uv = ev->codes[k]; + ftm->widths[k] = ftm->defwidth; + if (uv) + { + uv = pdc_get_alter_glyphname(uv, font->missingglyphs, NULL); + if (uv) + { + for (i = 0; i < ftm->numglwidths; i++) + { + if (ftm->glw[i].unicode == uv) + { + j = i + 1; + ftm->widths[k] = ftm->glw[i].width; + font->ft.code2gid[k] = j; + foundglyphs++; + } + } + } + } + } + + if (ftm->ciw != NULL) + { + pdc_free(p->pdc, ftm->ciw); + ftm->ciw = NULL; + } + + pdc_logg_cond(p->pdc, 2, trc_font, + "\t\t%d glyphs could be mapped to Unicode\n", foundglyphs); + + /* No characters found */ + if (!foundglyphs) + { + if (font->ft.issymbfont == pdc_false) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC, 0, 0, 0, 0); + return pdc_false; + } + else + { + /* We enforce builtin encoding */ + pdc_warning(p->pdc, PDF_E_FONT_FORCEENC, + pdf_get_encoding_name(p, pdc_builtin, font), + 0, 0, 0); + enc = pdc_builtin; + font->ft.enc = enc; + font->towinansi = pdc_invalidenc; + } + } + else if (foundglyphs < PDF_MIN_GLYPHS) + { + pdc_warning(p->pdc, PDF_E_FONT_INAPPROPENC, + pdc_errprintf(p->pdc, "%d", foundglyphs), 0, 0, 0); + } + } + + /* built-in encoding */ + if (enc == pdc_builtin) + { + if (ftm->glw == NULL) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC, 0, 0, 0, 0); + return pdc_false; + } + + /* encoding for builtin */ + ev = pdf_create_font_encoding(p, enc, font, fontname, pdc_true); + font->symenc = font->ft.enc; + + /***************************/ + font->ft.enc = pdc_builtin; + /***************************/ + + for (i = 0; i < font->ft.numcodes; i++) + { + ftm->widths[i] = ftm->defwidth; + } + + for (i = 0; i < font->ft.numglyphs; i++) + { + pdc_short code = ftm->glw[i].code; + + if (code >= 0 && code < font->ft.numcodes) + { + j = i + 1; + ftm->widths[code] = ftm->glw[i].width; + font->ft.code2gid[code] = j; + if (ev != NULL) + { + ev->codes[code] = ftm->glw[i].unicode; + } + } + } + } + } + + + if (ftm->glw != NULL) + { + pdc_free(p->pdc, ftm->glw); + ftm->glw = NULL; + } + + return pdc_true; +} + +pdc_bool +pdf_get_metrics_afm( + PDF *p, + pdf_font *font, + const char *fontname, + pdc_encoding enc, + const char *filename, + pdc_bool requested) +{ + static const char fn[] = "pdf_get_metrics_afm"; + char fullname[PDC_FILENAMELEN]; + pdc_file *afmfile; + + /* open AFM file */ + afmfile = pdc_fsearch_fopen(p->pdc, filename, fullname, "AFM ", + PDC_FILE_TEXT); + if (afmfile == NULL) + return pdc_check_fopen_errmsg(p->pdc, requested); + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tLoading AFM metric fontfile \"%s\":\n", fullname); + + /* parse AFM file */ + if (pdf_parse_afm(p, afmfile, font, fontname, fullname) == pdc_false) + return pdc_false; + + /* members not fount */ + if (font->ft.m.type == fnt_unknownType) + font->ft.m.type = fnt_Type1; + if (font->ft.name == NULL) + { + font->ft.name = pdc_strdup(p->pdc, fontname); + font->ft.m.name = pdc_strdup(p->pdc, fontname); + } + + /* save full filename */ + font->metricfilename = pdc_strdup_ext(p->pdc, fullname, 0, fn); + + /* process metric data */ + font->ft.enc = enc; + if (pdf_process_metrics_data(p, font, fontname) == pdc_false) + return pdc_false; + + if (!pdf_make_fontflag(p, font)) + return pdc_false; + + return pdc_true; +} diff --git a/src/pdflib/pdflib/p_annots.c b/src/pdflib/pdflib/p_annots.c new file mode 100644 index 0000000..b38da91 --- /dev/null +++ b/src/pdflib/pdflib/p_annots.c @@ -0,0 +1,2078 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_annots.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib routines for annnotations + * + */ + +#define P_ANNOTS_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_font.h" +#include "p_image.h" + + + + +/* annotation types */ +typedef enum +{ + ann_text = (1<<0), + ann_link = (1<<1), + ann_freetext = (1<<2), + ann_line = (1<<3), + ann_square = (1<<4), + ann_circle = (1<<5), + ann_highlight = (1<<6), + ann_underline = (1<<7), + ann_squiggly = (1<<8), + ann_strikeout = (1<<9), + ann_stamp = (1<<10), + ann_ink = (1<<11), + ann_polygon = (1<<12), + ann_polyline = (1<<13), + ann_popup = (1<<14), + ann_fileattachment = (1<<15), + ann_3d = (1<<16) +} +pdf_annottype; + +static const pdc_keyconn pdf_annottype_pdfkeylist[] = +{ + {"Text", ann_text}, + {"Link", ann_link}, + {"FreeText", ann_freetext}, + {"Line", ann_line}, + {"Square", ann_square}, + {"Circle", ann_circle}, + {"Highlight", ann_highlight}, + {"Underline", ann_underline}, + {"Squiggly", ann_squiggly}, + {"StrikeOut", ann_strikeout}, + {"Stamp", ann_stamp}, + {"Polygon", ann_polygon}, + {"PolyLine", ann_polyline}, + {"Ink", ann_ink}, + {"Popup", ann_popup}, + {"FileAttachment", ann_fileattachment}, + {"3D", ann_3d}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_polyline_pdfkeylist[] = +{ + {"QuadPoints", ann_link}, + {"QuadPoints", ann_highlight}, + {"QuadPoints", ann_underline}, + {"QuadPoints", ann_squiggly}, + {"QuadPoints", ann_strikeout}, + {"InkList", ann_ink}, + {"Vertices", ann_polygon}, + {"Vertices", ann_polyline}, + {NULL, 0} +}; + +/* flags for annotation dictionary entries */ +typedef enum +{ + anndict_a = (1<<0), + anndict_bs = (1<<1), + anndict_c = (1<<2), + anndict_contents = (1<<3), + anndict_f = (1<<4), + anndict_fs = (1<<5), + anndict_h = (1<<6), + anndict_ic = (1<<7), + anndict_inklist = (1<<8), + anndict_l = (1<<9), + anndict_le = (1<<10), + anndict_name = (1<<11), + anndict_nm = (1<<12), + anndict_open = (1<<13), + anndict_parent = (1<<14), + anndict_popup = (1<<15), + anndict_q = (1<<16), + anndict_quadpoints = (1<<17), + anndict_rect = (1<<18), + anndict_subtype = (1<<19), + anndict_t = (1<<20), + anndict_vertices = (1<<21), + anndict_3dd = (1<<22), + anndict_3da = (1<<23), + anndict_3dv = (1<<24) +} +pdf_anndictentries; + +static const pdc_keyconn pdf_perm_entries_pdfkeylist[] = +{ + {"Contents", anndict_contents}, + {"Name", anndict_name}, + {"NM", anndict_nm}, + {"Open", anndict_open}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_forb_entries_pdfkeylist[] = +{ + {"A", anndict_a}, + {"BS", anndict_bs}, + {"C", anndict_c}, + {"F", anndict_f}, + {"FS", anndict_fs}, + {"H", anndict_h}, + {"IC", anndict_ic}, + {"InkList", anndict_inklist}, + {"L", anndict_l}, + {"LE", anndict_le}, + {"Parent", anndict_parent}, + {"Popup", anndict_popup}, + {"Q", anndict_q}, + {"QuadPoints", anndict_quadpoints}, + {"Rect", anndict_rect}, + {"Subtype", anndict_subtype}, + {"T", anndict_t}, + {"Vertices", anndict_vertices}, + {"3DD", anndict_3dd}, + {"3DV", anndict_3dv}, + {"3DA", anndict_3da}, + {NULL, 0} +}; + +/* line ending styles */ +typedef enum +{ + line_none, + line_square, + line_circle, + line_diamond, + line_openarrow, + line_closedarrow +} +pdf_endingstyles; + +static const pdc_keyconn pdf_endingstyles_pdfkeylist[] = +{ + {"None", line_none}, + {"Square", line_square}, + {"Circle", line_circle}, + {"Diamond", line_diamond}, + {"OpenArrow", line_openarrow}, + {"ClosedArrow", line_closedarrow}, + {NULL, 0} +}; + +/* text icon names */ +typedef enum +{ + icon_text_comment, + icon_text_help, + icon_text_key, + icon_text_insert, + icon_text_newparagraph, + icon_text_note, + icon_text_paragraph +} +pdf_text_iconnames; + +static const pdc_keyconn pdf_text_iconnames_pdfkeylist[] = +{ + {"Comment", icon_text_comment}, + {"Help", icon_text_help}, + {"Key", icon_text_key}, + {"Insert", icon_text_insert}, + {"NewParagraph", icon_text_newparagraph}, + {"Note", icon_text_note}, + {"Paragraph", icon_text_paragraph}, + {NULL, 0} +}; + +/* stamp icon names */ +typedef enum +{ + icon_stamp_approved, + icon_stamp_asls, + icon_stamp_confidential, + icon_stamp_departmental, + icon_stamp_draft, + icon_stamp_experimental, + icon_stamp_expired, + icon_stamp_final, + icon_stamp_forcomment, + icon_stamp_forpublicrelease, + icon_stamp_notapproved, + icon_stamp_notforpublicrelease, + icon_stamp_sold, + icon_stamp_topsecret +} +pdf_stamp_iconnames; + +static const pdc_keyconn pdf_stamp_iconnames_pdfkeylist[] = +{ + {"Approved", icon_stamp_approved}, + {"AsIs", icon_stamp_asls}, + {"Confidential", icon_stamp_confidential}, + {"Departmental", icon_stamp_departmental}, + {"Draft", icon_stamp_draft}, + {"Experimental", icon_stamp_experimental}, + {"Expired", icon_stamp_expired}, + {"Final", icon_stamp_final}, + {"ForComment", icon_stamp_forcomment}, + {"ForPublicRelease", icon_stamp_forpublicrelease}, + {"NotApproved", icon_stamp_notapproved}, + {"NotForPublicRelease", icon_stamp_notforpublicrelease}, + {"Sold", icon_stamp_sold}, + {"TopSecret", icon_stamp_topsecret}, + {NULL, 0} +}; + +/* file attachment icon names */ +typedef enum +{ + icon_attach_graph, + icon_attach_paperclip, + icon_attach_pushpin, + icon_attach_tag +} +pdf_attach_iconnames; + +static const pdc_keyconn pdf_attach_iconnames_pdfkeylist[] = +{ + {"Graph", icon_attach_graph}, + {"Paperclip", icon_attach_paperclip}, + {"PushPin", icon_attach_pushpin}, + {"Tag", icon_attach_tag}, + {NULL, 0} +}; + + +static const pdc_keyconn pdf_3dview_keylist[] = +{ + {NULL, 0} +}; + + + +#define PDF_LAYER_FLAG PDC_OPT_UNSUPP + +#define PDF_3DANNOT_FLAG PDC_OPT_UNSUPP +static const pdc_defopt pdf_create_annot_options[] = +{ + /* deprecated */ + {"annotwarning", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"usercoordinates", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"custom", pdc_stringlist, PDC_OPT_NONE, 1, 64, + 0.0, PDC_INT_MAX, NULL}, + + {"name", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"parentname", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"popup", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"title", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"subject", pdc_stringlist, PDC_OPT_PDC_1_5, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"annotcolor", pdc_stringlist, PDC_OPT_NONE, 1, 5, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"borderstyle", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_borderstyle_keylist}, + + {"dasharray", pdc_scalarlist, PDC_OPT_NONE, 1, 2, + PDC_FLOAT_PREC, PDC_FLOAT_MAX, NULL}, + + {"linewidth", pdc_integerlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"opacity", pdc_scalarlist, PDC_OPT_PDC_1_4 | PDC_OPT_PERCENT, 1, 1, + 0.0, 1.0, NULL}, + + {"highlight", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_highlight_keylist}, + + {"display", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_display_keylist}, + + {"zoom", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"rotate", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"readonly", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"locked", pdc_booleanlist, PDC_OPT_PDC_1_4, 1, 1, + 0.0, 0.0, NULL}, + + {"open", pdc_booleanlist, PDC_OPT_PDC_1_4, 1, 1, + 0.0, 0.0, NULL}, + + {"createdate", pdc_booleanlist, PDC_OPT_PDC_1_5, 1, 1, + 0.0, 0.0, NULL}, + + {"fillcolor", pdc_stringlist, PDC_OPT_NONE, 2, 5, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"alignment", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_quadding_keylist}, + + {"font", pdc_fonthandle, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"fontsize", pdc_scalarlist, PDC_OPT_SUBOPTLIST | PDC_OPT_KEYLIST1, 1, 2, + 0.0, PDC_FLOAT_MAX, pdf_fontsize_keylist}, + + {"orientate", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_orientate_keylist}, + + {"contents", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"destination", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"destname", pdc_stringlist, PDC_OPT_IGNOREIF1, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"filename", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 1.0, PDC_FILENAMELEN, NULL}, + + {"mimetype", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"iconname", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"endingstyles", pdc_keywordlist, PDC_OPT_NONE, 2, 2, + 0.0, 0.0, pdf_endingstyles_pdfkeylist}, + + {"interiorcolor", pdc_stringlist, PDC_OPT_NONE, 1, 5, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"cloudy", pdc_scalarlist, PDC_OPT_PDC_1_5, 1, 1, + 0.0, 2.0, NULL}, + + {"line", pdc_scalarlist, PDC_OPT_NONE, 4, 4, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + {"polylinelist", pdc_polylinelist, PDC_OPT_NONE, 1, PDF_MAXARRAYSIZE, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + {"action", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"usematchbox", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"layer", pdc_layerhandle, PDF_LAYER_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + {"3dactivate", pdc_stringlist, PDF_3DANNOT_FLAG, 1, 1, + 0.0, PDC_USHRT_MAX, NULL}, + + {"3dbox", pdc_scalarlist, PDF_3DANNOT_FLAG, 4, 4, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + {"3ddata", pdc_3ddatahandle, PDF_3DANNOT_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + {"3dinteractive", pdc_booleanlist, PDF_3DANNOT_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + {"3dshared", pdc_booleanlist, PDF_3DANNOT_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + {"3dinitialview", pdc_3dviewhandle, PDF_3DANNOT_FLAG, 1, 1, + 0.0, 0.0, pdf_3dview_keylist}, + + PDC_OPT_TERMINATE +}; + +/* Annotation member */ +typedef struct pdf_annot_s +{ + pdc_bool iscopy; + pdc_id obj_id; + pdf_annottype atype; + int mask; + pdc_rectangle rect; + pdc_bool usercoordinates; + pdc_encoding hypertextencoding; + int hypertextcodepage; + pdf_coloropt annotcolor; + pdf_coloropt interiorcolor; + pdf_coloropt fillcolor; + int linewidth; + pdc_scalar opacity; + pdf_borderstyle borderstyle; + pdc_scalar dasharray[2]; + pdf_highlight highlight; + pdf_display display; + pdc_bool zoom; + pdc_bool rotate; + pdc_bool kreadonly; + pdc_bool locked; + pdc_bool open; + pdc_bool createdate; + int font; + pdc_scalar fontsize; + int orientate; + pdf_quadding alignment; + pdf_endingstyles endingstyles[2]; + pdc_scalar cloudy; + pdf_dest *dest; + char *name; + char *parentname; + char *popup; + char *title; + char *subject; + char *contents; + char *filename; + char *mimetype; + const char *iconname; + pdc_off_t filesize; + pdc_scalar *line; + pdc_polyline *polylinelist; + int nplines; + char **custom; + int ncustoms; + char *action; + + +} +pdf_annot; + +static void +pdf_reclaim_annot(void *item) +{ + pdf_annot *ann = (pdf_annot *) item; + + ann->iscopy = pdc_false; + ann->obj_id = PDC_BAD_ID; + ann->atype = (pdf_annottype)0; + ann->mask = 0; + ann->usercoordinates = pdc_false; + ann->hypertextencoding = pdc_invalidenc; + ann->hypertextcodepage = 0; + ann->annotcolor.type = (int) color_none; + ann->interiorcolor.type = (int) color_none; + ann->fillcolor.type = (int) color_none; + ann->linewidth = 1; + ann->opacity = 1; + ann->borderstyle = border_solid; + ann->dasharray[0] = 3; + ann->dasharray[1] = 3; + ann->highlight = high_invert; + ann->display = disp_visible; + ann->zoom = pdc_true; + ann->rotate = pdc_true; + ann->kreadonly = pdc_false; + ann->locked = pdc_false; + ann->open = pdc_false; + ann->createdate = pdc_false; + ann->font = -1; + ann->fontsize = 0; + ann->orientate = 0; + ann->alignment = quadd_left; + ann->cloudy = -1; + ann->endingstyles[0] = line_none; + ann->endingstyles[1] = line_none; + ann->dest = NULL; + ann->name = NULL; + ann->parentname = NULL; + ann->popup = NULL; + ann->title = NULL; + ann->subject = NULL; + ann->contents = NULL; + ann->filename = NULL; + ann->mimetype = NULL; + ann->iconname = NULL; + ann->filesize = 0; + ann->line = NULL; + ann->polylinelist = NULL; + ann->nplines = 0; + ann->custom = NULL; + ann->ncustoms = 0; + ann->action = NULL; + + + + +} + +static void +pdf_release_annot(void *context, void *item) +{ + PDF *p = (PDF *) context; + pdf_annot *ann = (pdf_annot *) item; + + /* is not a copy */ + if (!ann->iscopy) + { + pdf_cleanup_destination(p, ann->dest); + ann->dest = NULL; + + if (ann->name) + { + pdc_free(p->pdc, ann->name); + ann->name = NULL; + } + if (ann->parentname) + { + pdc_free(p->pdc, ann->parentname); + ann->parentname = NULL; + } + if (ann->popup) + { + pdc_free(p->pdc, ann->popup); + ann->popup = NULL; + } + if (ann->title) + { + pdc_free(p->pdc, ann->title); + ann->title = NULL; + } + if (ann->subject) + { + pdc_free(p->pdc, ann->subject); + ann->subject = NULL; + } + if (ann->contents) + { + pdc_free(p->pdc, ann->contents); + ann->contents = NULL; + } + if (ann->filename) + { + pdc_free(p->pdc, ann->filename); + ann->filename = NULL; + } + if (ann->mimetype) + { + pdc_free(p->pdc, ann->mimetype); + ann->mimetype = NULL; + } + if (ann->line) + { + pdc_free(p->pdc, ann->line); + ann->line = NULL; + } + if (ann->custom) + { + pdc_cleanup_optstringlist(p->pdc, ann->custom, ann->ncustoms); + ann->custom = NULL; + ann->ncustoms = 0; + } + if (ann->action) + { + pdc_free(p->pdc, ann->action); + ann->action = NULL; + } + } + + ann->polylinelist = (pdc_polyline *)pdc_delete_polylinelist( + p->pdc, ann->polylinelist, ann->nplines); +} + +static pdc_ced pdf_annot_ced = +{ + sizeof(pdf_annot), pdf_reclaim_annot, pdf_release_annot, NULL +}; + +static pdc_vtr_parms pdf_annot_parms = +{ + 0, 10, 10 +}; + +static pdf_annot * +pdf_new_annot(PDF *p) +{ + pdc_vtr *annots = pdf_get_annots_list(p); + pdf_annot *result; + + if (annots == NULL) + { + annots = pdc_vtr_new(p->pdc, &pdf_annot_ced, p, &pdf_annot_parms); + pdf_set_annots_list(p, annots); + } + + result = pdc_vtr_incr(annots, pdf_annot); + result->usercoordinates = p->usercoordinates; + result->hypertextencoding = p->hypertextencoding; + result->hypertextcodepage = p->hypertextcodepage; + pdf_init_coloropt(p, &result->fillcolor); + + + return result; +} + +static void +pdf_delete_last_annot(PDF *p) +{ + pdc_vtr *annots = pdf_get_annots_list(p); + + if (annots != NULL) + { + if (pdc_vtr_size(annots) > 1) + { + pdc_vtr_pop(annots); + } + else + { + pdc_vtr_delete(annots); + pdf_set_annots_list(p, NULL); + } + } +} + +static void +pdf_init_rectangle(PDF *p, pdf_annot *ann, + pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury, + pdc_vector *polyline) +{ + static const char fn[] = "pdf_init_rectangle"; + pdc_matrix *ctm = &p->curr_ppt->gstate[p->curr_ppt->sl].ctm; + int i; + + pdc_check_number(p->pdc, "llx", llx); + pdc_check_number(p->pdc, "lly", lly); + pdc_check_number(p->pdc, "urx", urx); + pdc_check_number(p->pdc, "ury", ury); + + pdc_delete_polylinelist(p->pdc, ann->polylinelist, ann->nplines); + ann->nplines = 1; + ann->polylinelist = (pdc_polyline *) pdc_malloc(p->pdc, + ann->nplines * sizeof(pdc_polyline), fn); + ann->polylinelist[0].np = 5; + ann->polylinelist[0].p = (pdc_vector *) pdc_malloc(p->pdc, + ann->polylinelist[0].np * sizeof(pdc_vector), fn); + + if (polyline == NULL) + { + if (!ann->usercoordinates) + ctm = NULL; + pdc_rect_init(&ann->rect, llx, lly, urx, ury); + pdc_rect2polyline(ctm, &ann->rect, ann->polylinelist[0].p); + } + else + { + for (i = 0; i < 5; i++) + pdc_transform_vector(ctm, &polyline[i], + &ann->polylinelist[0].p[i]); + } + + if (ctm != NULL) + pdc_polyline2rect(ann->polylinelist[0].p, 4, &ann->rect); +} + +/* because of Acrobat muddle */ +static void +pdf_permute_coordinates(pdf_annot *ann, pdf_annottype atype) +{ + if (ann->nplines == 1 && + (atype == ann_highlight || + atype == ann_underline || + atype == ann_squiggly || + atype == ann_strikeout)) + { + pdc_vector pl[5]; + int i; + + for (i = 0; i < ann->polylinelist[0].np; i++) + pl[i] = ann->polylinelist[0].p[i]; + + ann->polylinelist[0].p[0] = pl[3]; + ann->polylinelist[0].p[1] = pl[2]; + ann->polylinelist[0].p[2] = pl[0]; + ann->polylinelist[0].p[3] = pl[1]; + ann->polylinelist[0].p[4] = pl[3]; + } +} + +static const pdc_keyconn pdf_keytype_keylist[] = +{ + {"boolean", pdc_booleanlist}, + {"name", pdc_keywordlist}, + {"string", pdc_stringlist}, + {NULL, 0} +}; + +static const pdc_defopt pdf_custom_list_options[] = +{ + {"key", pdc_stringlist, PDC_OPT_REQUIRED, 1, 1, + 1.0, PDF_MAX_NAMESTRING, NULL}, + + {"type", pdc_keywordlist, PDC_OPT_REQUIRED, 1, 1, + 0.0, 0.0, pdf_keytype_keylist}, + + {"value", pdc_stringlist, PDC_OPT_REQUIRED, 1, 1, + 1.0, PDC_USHRT_MAX, NULL}, + + PDC_OPT_TERMINATE +}; + +static void +pdf_parse_and_write_annot_customlist(PDF *p, pdf_annot *ann, pdc_bool output) +{ + int i; + + /* custom entries */ + for (i = 0; i < ann->ncustoms; i++) + { + pdc_resopt *resopts = NULL; + const char *stemp; + const char *keyword; + char **strlist = NULL; + char *string; + int inum; + + resopts = pdc_parse_optionlist(p->pdc, ann->custom[i], + pdf_custom_list_options, NULL, pdc_true); + + keyword = "key"; + pdc_get_optvalues(keyword, resopts, NULL, &strlist); + string = strlist[0]; + + inum = pdc_get_keycode(string, pdf_forb_entries_pdfkeylist); + if (inum != PDC_KEY_NOTFOUND) + { + stemp = pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, string); + pdc_error(p->pdc, PDF_E_ANN_ILLCUSTOMKEY, stemp, 0, 0, 0); + } + inum = pdc_get_keycode(string, pdf_perm_entries_pdfkeylist); + if (inum != PDC_KEY_NOTFOUND) + ann->mask |= inum; + + if (output) + pdc_printf(p->out, "/%s", string); + + keyword = "type"; + pdc_get_optvalues(keyword, resopts, &inum, NULL); + + keyword = "value"; + pdc_get_optvalues(keyword, resopts, NULL, &strlist); + string = strlist[0]; + + switch (inum) + { + case pdc_booleanlist: + if (pdc_stricmp(string, "true") && pdc_stricmp(string, "false")) + { + stemp = + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, string); + + pdc_error(p->pdc, PDC_E_OPT_ILLBOOLEAN, keyword, stemp, 0, 0); + } + if (output) + pdc_printf(p->out, " %s", + PDC_BOOLSTR(pdc_stricmp(string, "false"))); + break; + + case pdc_keywordlist: + if (output) + pdc_printf(p->out, "/%s", string); + break; + + case pdc_stringlist: + pdf_get_opt_textlist(p, keyword, resopts, ann->hypertextencoding, + ann->hypertextcodepage, pdc_true, NULL, &string, NULL); + if (output) + pdf_put_hypertext(p, string); + break; + } + if (output) + pdc_puts(p->out, "\n"); + } +} + + + +static void +pdf_opt_alrdef(PDF *p, const char *keyword, pdf_annot *ann, int flag) +{ + if (ann->mask & flag) + pdc_error(p->pdc, PDF_E_ANN_OPTALRDEF, keyword, 0, 0, 0); +} + +static int +pdf_opt_effectless(PDF *p, const char *keyword, pdf_annottype curratype, + pdf_annottype intendatypes) +{ + if ((pdf_annottype) !(intendatypes & curratype)) + { + const char *type = pdc_get_keyword(curratype, pdf_annottype_pdfkeylist); + pdc_warning(p->pdc, PDF_E_ANN_OPTEFFLESS_FORTYPE, keyword, type, + 0, 0); + return 1; + } + return 0; +} + +void +pdf__create_annotation(PDF *p, + pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury, + const char *type, const char *optlist) +{ + pdc_resopt *resopts = NULL; + pdc_clientdata cdata; + pdf_annottype atype; + pdf_annot *ann; + pdf_dest *dest = NULL; + const char *keyword, *keyword_s = NULL; + char **strlist = NULL; + pdc_scalar *line; + int i, j, k, ns, nss[2]; + pdf_ppt *ppt = p->curr_ppt; + pdc_matrix *ctm = &ppt->gstate[ppt->sl].ctm; + + pdc_check_number(p->pdc, "llx", llx); + pdc_check_number(p->pdc, "lly", lly); + pdc_check_number(p->pdc, "urx", urx); + pdc_check_number(p->pdc, "ury", ury); + + if (type == NULL || *type == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "type", 0, 0, 0); + + k = pdc_get_keycode_ci(type, pdf_annottype_pdfkeylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0); + atype = (pdf_annottype) k; + + + /* compatibility */ + if (p->compatibility < PDC_1_5 && + (atype == ann_polygon || atype == ann_polyline)) + { + pdc_error(p->pdc, PDC_E_PAR_VERSION, type, + pdc_get_pdfversion(p->pdc, PDC_1_5), 0, 0); + } + + /* Parsing option list */ + pdf_set_clientdata(p, &cdata); + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_create_annot_options, + &cdata, pdc_true); + + /* Initializing */ + ann = pdf_new_annot(p); + ann->atype = atype; + + keyword = "usercoordinates"; + pdc_get_optvalues(keyword, resopts, &ann->usercoordinates, NULL); + pdf_init_rectangle(p, ann, llx, lly, urx, ury, NULL); + + ann->hypertextencoding = + pdf_get_hypertextencoding_opt(p, resopts, &ann->hypertextcodepage, + pdc_true); + + keyword = "custom"; + ns = pdf_get_opt_textlist(p, keyword, resopts, ann->hypertextencoding, + ann->hypertextcodepage, pdc_true, NULL, NULL, &ann->custom); + if (ns) + { + pdc_save_lastopt(resopts, PDC_OPT_SAVEALL); + ann->ncustoms = ns; + pdf_parse_and_write_annot_customlist(p, ann, pdc_false); + } + + keyword = "name"; + ns = pdf_get_opt_textlist(p, keyword, resopts, ann->hypertextencoding, + ann->hypertextcodepage, pdc_true, NULL, &ann->name, NULL); + if (ns) + { + pdf_opt_alrdef(p, keyword, ann, anndict_nm); + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + keyword = "parentname"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL)) + ann->parentname = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + keyword = "popup"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL)) + ann->popup = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + keyword = "title"; + if (pdf_get_opt_textlist(p, keyword, resopts, ann->hypertextencoding, + ann->hypertextcodepage, pdc_true, NULL, &ann->title, NULL)) + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + keyword = "subject"; + if (pdf_get_opt_textlist(p, keyword, resopts, ann->hypertextencoding, + ann->hypertextcodepage, pdc_true, NULL, &ann->subject, NULL)) + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + keyword = "annotcolor"; + ns = pdc_get_optvalues(keyword, resopts, NULL, &strlist); + if (ns) + { + pdf_parse_coloropt(p, keyword, strlist, ns, (int) color_rgb, + &ann->annotcolor); + } + + keyword = "borderstyle"; + if (pdc_get_optvalues(keyword, resopts, &ns, NULL)) + ann->borderstyle = (pdf_borderstyle) ns; + + keyword = "dasharray"; + ns = pdc_get_optvalues(keyword, resopts, ann->dasharray, NULL); + if (ns) + { + if (ns == 1) + ann->dasharray[1] = ann->dasharray[0]; + if (ann->borderstyle != border_dashed) + pdc_warning(p->pdc, PDC_E_OPT_IGNORED, keyword, 0, 0, 0); + } + + keyword = "linewidth"; + pdc_get_optvalues(keyword, resopts, &ann->linewidth, NULL); + + keyword = "opacity"; + pdc_get_optvalues(keyword, resopts, &ann->opacity, NULL); + + + keyword = "highlight"; + if (pdc_get_optvalues(keyword, resopts, &ns, NULL)) + { + pdf_opt_effectless(p, keyword, atype, ann_link); + ann->highlight = (pdf_highlight) ns; + } + + keyword = "display"; + if (pdc_get_optvalues(keyword, resopts, &ann->display, NULL)) + ann->display = (pdf_display) ns; + + keyword = "zoom"; + pdc_get_optvalues(keyword, resopts, &ann->zoom, NULL); + + keyword = "rotate"; + pdc_get_optvalues(keyword, resopts, &ann->rotate, NULL); + + keyword = "readonly"; + pdc_get_optvalues(keyword, resopts, &ann->kreadonly, NULL); + + keyword = "locked"; + pdc_get_optvalues(keyword, resopts, &ann->locked, NULL); + + keyword = "open"; + if (pdc_get_optvalues(keyword, resopts, &ann->open, NULL)) + { + pdf_opt_alrdef(p, keyword, ann, anndict_open); + pdf_opt_effectless(p, keyword, atype, + (pdf_annottype) (ann_text | ann_popup)); + } + + keyword = "createdate"; + pdc_get_optvalues(keyword, resopts, &ann->createdate, NULL); + + keyword = "fillcolor"; + ns = pdc_get_optvalues(keyword, resopts, NULL, &strlist); + if (ns && !pdf_opt_effectless(p, keyword, atype, ann_freetext)) + { + pdf_parse_coloropt(p, keyword, strlist, ns, (int) color_cmyk, + &ann->fillcolor); + } + + keyword = "alignment"; + if (pdc_get_optvalues(keyword, resopts, &ns, NULL)) + ann->alignment = (pdf_quadding) ns; + + keyword = "font"; + if (pdc_get_optvalues(keyword, resopts, &ann->font, NULL)) + pdf_opt_effectless(p, keyword, atype, ann_freetext); + + keyword = "fontsize"; + if (pdf_get_fontsize_option(p, ann->font, resopts, &ann->fontsize)) + { + pdf_opt_effectless(p, keyword, atype, ann_freetext); + if (ann->usercoordinates == pdc_true) + ann->fontsize = pdc_transform_scalar(ctm, ann->fontsize); + } + + keyword = "orientate"; + if (pdc_get_optvalues(keyword, resopts, &ann->orientate, NULL)) + pdf_opt_effectless(p, keyword, atype, + (pdf_annottype) (ann_freetext | ann_stamp)); + + keyword = "contents"; + if (atype == ann_freetext) + { + pdc_encoding enc = pdc_invalidenc; + int codepage = 0; + + if (ann->font > -1) + { + enc = p->fonts[ann->font].ft.enc; + codepage = p->fonts[ann->font].codepage; + } + pdf_get_opt_textlist(p, keyword, resopts, enc, codepage, + pdc_false, NULL, &ann->contents, NULL); + } + else + { + pdf_get_opt_textlist(p, keyword, resopts, ann->hypertextencoding, + ann->hypertextcodepage, pdc_true, NULL, &ann->contents, NULL); + } + if (ann->contents) + { + pdf_opt_alrdef(p, keyword, ann, anndict_contents); + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + keyword = "destination"; + if (pdc_get_optvalues(keyword, resopts, NULL, &strlist) && + !pdf_opt_effectless(p, keyword, atype, ann_link)) + { + ann->dest = pdf_parse_destination_optlist(p, strlist[0], 0, + pdf_locallink); + keyword_s = keyword; + } + else + { + keyword = "destname"; + if (atype == ann_link) + dest = pdf_get_option_destname(p, resopts, ann->hypertextencoding, + ann->hypertextcodepage); + else if (pdc_get_optvalues(keyword, resopts, NULL, NULL)) + pdf_opt_effectless(p, keyword, atype, ann_link); + if (dest) + { + ann->dest = dest; + keyword_s = keyword; + } + } + + keyword = "filename"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL) && + !pdf_opt_effectless(p, keyword, atype, ann_fileattachment)) + { + ann->filename = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + ann->filesize = pdf_check_file(p, ann->filename, pdc_true); + } + + keyword = "mimetype"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL) && + !pdf_opt_effectless(p, keyword, atype, ann_fileattachment)) + ann->mimetype = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + keyword = "iconname"; + if (pdc_get_optvalues(keyword, resopts, NULL, &strlist) && + !pdf_opt_effectless(p, keyword, atype, + (pdf_annottype) (ann_text | ann_stamp | ann_fileattachment))) + { + const pdc_keyconn *kc = pdf_text_iconnames_pdfkeylist; + + pdf_opt_alrdef(p, keyword, ann, anndict_name); + + if (atype == ann_stamp) + kc = pdf_stamp_iconnames_pdfkeylist; + else if (atype == ann_fileattachment) + kc = pdf_attach_iconnames_pdfkeylist; + + ann->iconname = pdc_get_int_keyword(strlist[0], kc); + if (ann->iconname == NULL) + pdc_error(p->pdc, PDC_E_OPT_ILLKEYWORD, keyword, strlist[0], + 0, 0); + } + + keyword = "endingstyles"; + if (pdc_get_optvalues(keyword, resopts, nss, NULL)) + { + ann->endingstyles[0] = (pdf_endingstyles) nss[0]; + ann->endingstyles[1] = (pdf_endingstyles) nss[1]; + pdf_opt_effectless(p, keyword, atype, + (pdf_annottype) (ann_line | ann_polyline)); + } + + keyword = "interiorcolor"; + ns = pdc_get_optvalues(keyword, resopts, NULL, &strlist); + if (ns && !pdf_opt_effectless(p, keyword, atype, + (pdf_annottype) (ann_line | ann_polyline | + ann_square | ann_circle))) + { + pdf_parse_coloropt(p, keyword, strlist, ns, (int) color_rgb, + &ann->interiorcolor); + } + + keyword = "cloudy"; + if (pdc_get_optvalues(keyword, resopts, &ann->cloudy, NULL)) + pdf_opt_effectless(p, keyword, atype, ann_polygon); + + keyword = "line"; + ns = pdc_get_optvalues(keyword, resopts, NULL, &strlist); + if (ns && !pdf_opt_effectless(p, keyword, atype, ann_line)) + { + line = (pdc_scalar *) strlist; + if (ann->usercoordinates == pdc_true) + { + pdc_transform_point(ctm, line[0], line[1], &line[0], &line[1]); + pdc_transform_point(ctm, line[2], line[3], &line[2], &line[3]); + } + ann->line = (pdc_scalar *) pdc_save_lastopt(resopts, PDC_OPT_SAVEALL); + } + + keyword = "polylinelist"; + ns = pdc_get_optvalues(keyword, resopts, NULL, &strlist); + if (ns) + { + if (!pdf_opt_effectless(p, keyword, atype, + (pdf_annottype) (ann_ink | ann_polygon | ann_polyline | + ann_highlight | ann_underline | + ann_squiggly | ann_strikeout))) + { + pdc_polyline *pl = (pdc_polyline *) strlist; + + for (j = 0; j < ns; j++) + { + if (pl[j].np < 2 || + (atype != ann_ink && atype != ann_polygon && + atype != ann_polyline && pl[j].np != 4)) + { + pdc_error(p->pdc, PDF_E_ANN_BADNUMCOORD, keyword, 0, 0, 0); + } + for (i = 0; i < pl[j].np; i++) + { + if (ann->usercoordinates == pdc_true) + pdc_transform_vector(ctm, &pl[j].p[i], NULL); + } + } + pdc_delete_polylinelist(p->pdc, ann->polylinelist, ann->nplines); + ann->polylinelist = pl; + ann->nplines = ns; + pdc_save_lastopt(resopts, PDC_OPT_SAVEALL); + } + } + else + pdf_permute_coordinates(ann, atype); + + keyword = "action"; + if (pdc_get_optvalues(keyword, resopts, NULL, &strlist)) + { + if (ann->dest) + { + pdf_cleanup_destination(p, ann->dest); + ann->dest = NULL; + pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword_s, keyword, 0, 0); + } + + /* parsing of action list */ + pdf_parse_and_write_actionlist(p, event_annotation, NULL, + (const char *) strlist[0]); + ann->action = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + + + /* required options */ + keyword = NULL; + if (ann->contents == NULL && atype != ann_link && atype != ann_popup) + keyword = "contents"; + if (ann->fontsize == 0 && atype == ann_freetext) + keyword = "fontsize"; + if (ann->font == -1 && atype == ann_freetext) + keyword = "font"; + if (ann->filename == NULL && atype == ann_fileattachment) + keyword = "filename"; + if (ann->line == NULL && atype == ann_line) + keyword = "line"; + if (ann->polylinelist == NULL && + (atype == ann_ink || atype == ann_polygon || atype == ann_polyline)) + keyword = "polylinelist"; + + if (keyword) + pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, keyword, 0, 0, 0); + + + if (atype == ann_freetext) + { + pdf_font *font_s = &p->fonts[ann->font]; + const char *fontname = + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, font_s->ft.name); + + if (!strcmp(pdf_get_pdf_fontname(font_s), fontname)) + pdc_error(p->pdc, PDF_E_ANN_NOSTDFONT, fontname, 0, 0, 0); + } + + /* + * matchbox available + */ + keyword = "usematchbox"; + if (pdc_get_optvalues(keyword, resopts, NULL, &strlist)) + { + pdf_annot *ann_first = ann; + const char *mboxname; + int ir, nrect, irect; + + mboxname = pdf_get_usematchbox(p, keyword, strlist[0], &irect, &nrect); + if (mboxname != NULL) + { + if (irect > nrect) + { + pdf_delete_last_annot(p); + } + else + { + pdf_mbox *mbox; + pdc_vector pl[5]; + + /* rectangle loop */ + for (ir = irect; ir <= nrect; ir++) + { + if (ir > irect) + { + /* create copy */ + ann = pdf_new_annot(p); + ann->atype = atype; + memcpy(ann, ann_first, sizeof(pdf_annot)); + ann->obj_id = PDC_BAD_ID; + ann->iscopy = pdc_true; + ann->nplines = 0; + ann->polylinelist = NULL; + } + + /* rectangle #ir */ + mbox = pdf_get_mbox(p, NULL, mboxname, ir, NULL); + pdf_get_mbox_rectangle(p, mbox, pl); + pdf_init_rectangle(p, ann, 0, 0, 0, 0, pl); + pdf_permute_coordinates(ann, atype); + ann->usercoordinates = pdc_true; + } + } + } + } + +} + +pdc_id +pdf_write_annots_root(PDF *p, pdc_vtr *annots, pdf_widget *widgetlist) +{ + pdc_id result = PDC_BAD_ID; + + /* Annotations array */ + if (annots != NULL || widgetlist) + { + result = pdc_begin_obj(p->out, PDC_NEW_ID); + pdc_begin_array(p->out); + + if (annots != NULL) + { + pdf_annot *ann; + int i, na = pdc_vtr_size(annots); + + for (i = 0; i < na; i++) + { + ann = (pdf_annot *) &pdc_vtr_at(annots, i, pdf_annot); + if (ann->obj_id == PDC_BAD_ID) + ann->obj_id = pdc_alloc_id(p->out); + pdc_objref_c(p->out, ann->obj_id); + } + } + + (void) widgetlist; + + pdc_end_array(p->out); + pdc_end_obj(p->out); + } + + return result; +} + +#define BUFSIZE 256 + +static void +pdf_write_defappstring(PDF *p, pdf_annot *ann) +{ + char buf[BUFSIZE], *bufc; + pdf_coloropt *fs; + int ct; + + if (ann->font == -1) + return; + + bufc = buf; + + /* font and fontsize */ + bufc += pdc_sprintf(p->pdc, pdc_true, bufc, "/%s %f Tf", + pdf_get_pdf_fontname(&p->fonts[ann->font]), + ann->fontsize); + + /* fill and stroke color */ + fs = &ann->fillcolor; + ct = fs->type; + switch (ct) + { + case color_gray: + bufc += pdc_sprintf(p->pdc, pdc_true, bufc, " %f g", + fs->value[0]); + break; + + case color_rgb: + bufc += pdc_sprintf(p->pdc, pdc_true, bufc, " %f %f %f rg", + fs->value[0], fs->value[1], fs->value[2]); + break; + + case color_cmyk: + bufc += pdc_sprintf(p->pdc, pdc_true, bufc, " %f %f %f %f k", + fs->value[0], fs->value[1], + fs->value[2], fs->value[3]); + break; + } + + pdc_puts(p->out, "/DA"); + pdf_put_hypertext(p, buf); + pdc_puts(p->out, "\n"); +} + +void +pdf_write_page_annots(PDF *p, pdc_vtr *annots) +{ + pdf_annot *ann, *annpar; + pdc_id act_idlist[PDF_MAX_EVENTS]; + int i, j, k, na, flags; + + na = pdc_vtr_size(annots); + + for (k = 0; k < na; k++) + { + ann = (pdf_annot *) &pdc_vtr_at(annots, k, pdf_annot); + + + /* write action objects */ + if (ann->action) + pdf_parse_and_write_actionlist(p, event_annotation, act_idlist, + (const char *) ann->action); + + + pdc_begin_obj(p->out, ann->obj_id); /* Annotation object */ + pdc_begin_dict(p->out); /* Annotation dict */ + + pdc_puts(p->out, "/Type/Annot\n"); + pdc_printf(p->out, "/Subtype/%s\n", + pdc_get_keyword(ann->atype, pdf_annottype_pdfkeylist)); + + + + + /* Contents */ + if (ann->contents) + { + pdc_puts(p->out, "/Contents"); + if (ann->atype == ann_freetext) + pdf_put_fieldtext(p, ann->contents, ann->font); + else + pdf_put_hypertext(p, ann->contents); + pdc_puts(p->out, "\n"); + } + + /* Current Page */ + pdc_objref(p->out, "/P", pdf_get_page_id(p, 0)); + + /* Rectangle */ + pdc_printf(p->out, "/Rect[%f %f %f %f]\n", + ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury); + + /* Name */ + if (ann->name) + { + pdc_puts(p->out, "/NM"); + pdf_put_hypertext(p, ann->name); + pdc_puts(p->out, "\n"); + } + + /* Flags */ + flags = 0; + if (ann->display != disp_noprint) + { + flags = (1<<2); + flags |= ann->display; + } + if (!ann->zoom) + flags |= (1<<3); + if (!ann->rotate) + flags |= (1<<4); + if (ann->kreadonly) + flags |= (1<<6); + if (ann->locked) + flags |= (1<<7); + if (flags) + pdc_printf(p->out, "/F %d\n", flags); + + /* Border style dictionary */ + if (ann->linewidth != 1 || ann->borderstyle != border_solid) + { + pdc_puts(p->out, "/BS"); + pdc_begin_dict(p->out); /* BS dict */ + + pdc_printf(p->out, "/W %d", ann->linewidth); + pdc_printf(p->out, "/S/%s", + pdc_get_keyword(ann->borderstyle, pdf_borderstyle_pdfkeylist)); + if (ann->borderstyle == border_dashed) + pdc_printf(p->out, "/D[%f %f]", + ann->dasharray[0], ann->dasharray[1]); + + pdc_end_dict(p->out); /* BS dict */ + + /* Write the Border key in old-style PDF 1.1 format + * because of a bug in PDF 1.4 and earlier + */ + pdc_printf(p->out, "/Border[0 0 %f", (double) ann->linewidth); + + if (ann->borderstyle == border_dashed) + pdc_printf(p->out, "[%f %f]", + ann->dasharray[0], ann->dasharray[1]); + pdc_puts(p->out, "]\n"); + } + + /* Annotation color */ + if (ann->annotcolor.type != (int) color_none) + { + pdc_printf(p->out, "/C[%f %f %f]\n", ann->annotcolor.value[0], + ann->annotcolor.value[1], ann->annotcolor.value[2]); + } + + /* Title */ + if (ann->title && *ann->title) + { + pdc_puts(p->out, "/T"); + pdf_put_hypertext(p, ann->title); + pdc_puts(p->out, "\n"); + } + + /* Subject */ + if (ann->subject && *ann->subject) + { + pdc_puts(p->out, "/Subj"); + pdf_put_hypertext(p, ann->subject); + pdc_puts(p->out, "\n"); + } + + /* Popup */ + if (ann->popup && *ann->popup) + { + for (i = 0; i < na; i++) + { + annpar = (pdf_annot *) &pdc_vtr_at(annots, i, pdf_annot); + if (annpar->name != NULL && + !strcmp(ann->popup, annpar->name)) + { + pdc_objref(p->out, "/Popup", annpar->obj_id); + break; + } + } + } + + /* Icon Name */ + if (ann->iconname && *ann->iconname) + pdc_printf(p->out, "/Name/%s\n", ann->iconname); + + /* CreationDate */ + if (ann->createdate) + { + char time_str[PDC_TIME_SBUF_SIZE]; + + pdc_get_timestr(time_str, pdc_false); + pdc_puts(p->out, "/CreationDate "); + pdf_put_hypertext(p, time_str); + pdc_puts(p->out, "\n"); + } + + /* Opacity */ + if (ann->opacity != 1) + pdc_printf(p->out, "/CA %f\n", ann->opacity); + + /* write Action entries */ + if (ann->action) + pdf_write_action_entries(p, event_annotation, act_idlist); + + /* custom entries */ + pdf_parse_and_write_annot_customlist(p, ann, pdc_true); + + switch (ann->atype) + { + /* Open */ + case ann_text: + case ann_popup: + if (ann->open) + pdc_puts(p->out, "/Open true\n"); + break; + + /* Alignment, Default appearance string */ + case ann_freetext: + if (ann->alignment != quadd_left) + pdc_printf(p->out, "/Q %d\n", ann->alignment); + pdf_write_defappstring(p, ann); + break; + + /* Line */ + case ann_line: + pdc_printf(p->out, "/L[%f %f %f %f]\n", + ann->line[0], ann->line[1], ann->line[2], ann->line[3]); + break; + + /* InkList, QuadPoints and Vertices */ + case ann_link: + if (!ann->usercoordinates || p->compatibility < PDC_1_6) + break; + case ann_highlight: + case ann_underline: + case ann_squiggly: + case ann_strikeout: + ann->polylinelist[0].np = 4; /* because of Acrobat error */ + case ann_ink: + case ann_polygon: + case ann_polyline: + pdc_printf(p->out, "/%s", + pdc_get_keyword(ann->atype, pdf_polyline_pdfkeylist)); + pdc_begin_array(p->out); + for (i = 0; i < ann->nplines; i++) + { + if (ann->atype == ann_ink) + pdc_begin_array(p->out); + for (j = 0; j < ann->polylinelist[i].np; j++) + pdc_printf(p->out, "%f %f ", ann->polylinelist[i].p[j].x, + ann->polylinelist[i].p[j].y); + if (ann->atype == ann_ink) + pdc_end_array_c(p->out); + } + pdc_end_array(p->out); + break; + + default: + break; + } + + switch (ann->atype) + { + /* Destination, Highlight */ + case ann_link: + if (ann->dest) + { + pdc_puts(p->out, "/Dest"); + pdf_write_destination(p, ann->dest); + } + if (ann->highlight != high_invert) + pdc_printf(p->out, "/H/%s\n", + pdc_get_keyword(ann->highlight, pdf_highlight_pdfkeylist)); + break; + + /* Line ending styles */ + case ann_line: + case ann_polyline: + if (ann->endingstyles[0] != line_none || + ann->endingstyles[1] != line_none) + pdc_printf(p->out, "/LE[/%s /%s]\n", + pdc_get_keyword(ann->endingstyles[0], + pdf_endingstyles_pdfkeylist), + pdc_get_keyword(ann->endingstyles[1], + pdf_endingstyles_pdfkeylist)); + break; + + /* border effect dictionary */ + case ann_polygon: + if (ann->cloudy > -1) + { + pdc_puts(p->out, "/BE"); + pdc_begin_dict(p->out); /* BE dict */ + pdc_puts(p->out, "/S/C"); + if (ann->cloudy > 0) + pdc_printf(p->out, "/I %f", ann->cloudy); + pdc_end_dict(p->out); /* BE dict */ + } + + /* rotate */ + case ann_stamp: + case ann_freetext: + if (ann->orientate) + pdc_printf(p->out, "/Rotate %d", ann->orientate); + break; + + default: + break; + } + + switch (ann->atype) + { + /* Interior color */ + case ann_line: + case ann_polyline: + case ann_square: + case ann_circle: + if (ann->interiorcolor.type != (int) color_none) + { + pdc_printf(p->out, "/IC[%f %f %f]\n", + ann->interiorcolor.value[0], + ann->interiorcolor.value[1], + ann->interiorcolor.value[2]); + } + break; + + /* Parent Annotation */ + case ann_popup: + if (ann->parentname && *ann->parentname) + { + for (i = 0; i < na; i++) + { + annpar = (pdf_annot *) &pdc_vtr_at(annots, i, pdf_annot); + if (annpar->name != NULL && + !strcmp(ann->parentname, annpar->name)) + { + pdc_objref(p->out, "/Parent", annpar->obj_id); + break; + } + } + } + break; + + /* File specification */ + case ann_fileattachment: + { + pdc_puts(p->out, "/FS"); + pdc_begin_dict(p->out); /* FS dict */ + pdc_puts(p->out, "/Type/Filespec\n"); + pdc_puts(p->out, "/F"); + pdf_put_pdffilename(p, ann->filename); + pdc_puts(p->out, "\n"); + + /* alloc id for the actual embedded file stream */ + ann->obj_id = pdc_alloc_id(p->out); + pdc_puts(p->out, "/EF"); + pdc_begin_dict(p->out); + pdc_objref(p->out, "/F", ann->obj_id); + pdc_end_dict(p->out); + pdc_end_dict(p->out); /* FS dict */ + } + break; + + + default: + break; + } + + + pdc_end_dict(p->out); /* Annotation dict */ + pdc_end_obj(p->out); /* Annotation object */ + } + + /* Write the actual embedded files with preallocated ids */ + for (k = 0; k < na; k++) + { + ann = (pdf_annot *) &pdc_vtr_at(annots, k, pdf_annot); + if (ann->atype == ann_fileattachment) + pdf_embed_file(p, ann->obj_id, ann->filename, ann->mimetype, + ann->filesize); + } +} + +/*****************************************************************************/ +/** deprecated historical annotation functions **/ +/*****************************************************************************/ + +void +pdf_create_link( + PDF *p, + const char *type, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury, + const char *annopts, + const char *utext, + int len) +{ + char optlist[2048]; + char *name; + int acthdl; + + if (!pdc_stricmp(type, "URI")) + strcpy(optlist, "url {"); + else if (!pdc_stricmp(type, "GoTo")) + strcpy(optlist, "destname {"); + else if (!pdc_stricmp(type, "GoToR")) + strcpy(optlist, "destination {page 1} filename {"); + + name = pdf_convert_name(p, utext, len, PDC_CONV_WITHBOM); + strcat(optlist, name); + pdc_free(p->pdc, name); + + strcat(optlist, "}"); + + acthdl = pdf__create_action(p, type, optlist); + if (acthdl > -1) + { + if (p->pdc->hastobepos) acthdl++; + pdc_sprintf(p->pdc, pdc_false, optlist, + "action {activate %d} usercoordinates ", acthdl); + strcat(optlist, annopts); + pdf__create_annotation(p, llx, lly, urx, ury, "Link", optlist); + } +} + +void +pdf_init_annot_params(PDF *p) +{ + /* annotation border style defaults */ + p->border_style = border_solid; + p->border_width = 1; + p->border_red = 0; + p->border_green = 0; + p->border_blue = 0; + p->border_dash1 = 3; + p->border_dash2 = 3; + + /* auxiliary function parameters */ + p->launchlink_parameters = NULL; + p->launchlink_operation = NULL; + p->launchlink_defaultdir = NULL; +} + +void +pdf_cleanup_annot_params(PDF *p) +{ + if (p->launchlink_parameters) + { + pdc_free(p->pdc, p->launchlink_parameters); + p->launchlink_parameters = NULL; + } + + if (p->launchlink_operation) + { + pdc_free(p->pdc, p->launchlink_operation); + p->launchlink_operation = NULL; + } + + if (p->launchlink_defaultdir) + { + pdc_free(p->pdc, p->launchlink_defaultdir); + p->launchlink_defaultdir = NULL; + } +} + +static void +pdf_insert_annot_params(PDF *p, pdf_annot *ann) +{ + ann->borderstyle = p->border_style; + ann->linewidth = (int) p->border_width; + ann->annotcolor.type = (int) color_rgb; + ann->annotcolor.value[0] = p->border_red; + ann->annotcolor.value[1] = p->border_green; + ann->annotcolor.value[2] = p->border_blue; + ann->annotcolor.value[3] = 0; + ann->dasharray[0] = p->border_dash1; + ann->dasharray[1] = p->border_dash2; +} + +void +pdf__attach_file( + PDF *p, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury, + const char *filename, + int len_filename, + const char *description, + int len_descr, + const char *author, + int len_auth, + const char *mimetype, + const char *icon) +{ + pdc_file *attfile; + pdf_annot *ann; + pdf_attach_iconnames icontype = icon_attach_pushpin; + + filename = pdf_convert_filename(p, filename, len_filename, "filename", + PDC_CONV_WITHBOM); + + if (icon != NULL && *icon) + { + int k = pdc_get_keycode_ci(icon, pdf_attach_iconnames_pdfkeylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "icon", icon, 0, 0); + icontype = (pdf_attach_iconnames) k; + } + + attfile = pdc_fsearch_fopen(p->pdc, filename, NULL, "attachment ", 0); + if (attfile == NULL) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + + pdc_lock_pvf(p->pdc, filename); + pdc_fclose(attfile); + + /* fill up annotation struct */ + ann = pdf_new_annot(p); + ann->atype = ann_fileattachment; + pdf_init_rectangle(p, ann, llx, lly, urx, ury, NULL); + pdf_insert_annot_params(p, ann); + ann->filename = pdc_strdup(p->pdc, filename); + ann->filesize = pdf_check_file(p, ann->filename, pdc_true); + ann->contents = pdf_convert_hypertext_depr(p, description, len_descr); + ann->title = pdf_convert_hypertext_depr(p, author, len_auth); + if (mimetype != NULL && mimetype) + ann->mimetype = pdc_strdup(p->pdc, mimetype); + if (icontype != icon_attach_pushpin) + ann->iconname = + pdc_get_keyword(icontype, pdf_attach_iconnames_pdfkeylist); + ann->zoom = pdc_false; + ann->rotate = pdc_false; +} + +void +pdf__add_note( + PDF *p, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury, + const char *contents, + int len_cont, + const char *title, + int len_title, + const char *icon, + int kopen) +{ + pdf_annot *ann; + pdf_text_iconnames icontype = icon_text_note; + + if (icon != NULL && *icon) + { + int k = pdc_get_keycode_ci(icon, pdf_text_iconnames_pdfkeylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "icon", icon, 0, 0); + icontype = (pdf_text_iconnames) k; + } + + /* fill up annotation struct */ + ann = pdf_new_annot(p); + ann->atype = ann_text; + pdf_init_rectangle(p, ann, llx, lly, urx, ury, NULL); + pdf_insert_annot_params(p, ann); + ann->contents = pdf_convert_hypertext_depr(p, contents, len_cont); + ann->title = pdf_convert_hypertext_depr(p, title, len_title); + if (icontype != icon_text_note) + ann->iconname = pdc_get_keyword(icontype,pdf_text_iconnames_pdfkeylist); + ann->open = kopen; + ann->display = disp_noprint; +} + +void +pdf__add_pdflink( + PDF *p, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury, + const char *filename, + int page, + const char *optlist) +{ + char actoptlist[2048], *sopt; + pdf_annot *ann; + int acthdl; + + if (filename == NULL || *filename == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "filename", 0, 0, 0); + + /* creating a GoToR action */ + actoptlist[0] = 0; + sopt = actoptlist; + sopt += pdc_sprintf(p->pdc, pdc_false, sopt, "filename {%s} ", filename); + if (optlist == NULL) optlist = ""; + sopt += pdc_sprintf(p->pdc, pdc_false, sopt, "destination {%s page %d} ", + optlist, page); + acthdl = pdf__create_action(p, "GoToR", actoptlist); + + /* fill up annotation struct */ + if (acthdl > -1) + { + ann = pdf_new_annot(p); + ann->atype = ann_link; + pdf_init_rectangle(p, ann, llx, lly, urx, ury, NULL); + pdf_insert_annot_params(p, ann); + if (p->pdc->hastobepos) acthdl++; + pdc_sprintf(p->pdc, pdc_false, actoptlist, "activate %d", acthdl); + ann->action = pdc_strdup(p->pdc, actoptlist); + ann->display = disp_noprint; + } +} + +void +pdf__add_launchlink( + PDF *p, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury, + const char *filename) +{ + char actoptlist[2048], *sopt; + pdf_annot *ann; + int acthdl; + + if (filename == NULL || *filename == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "filename", 0, 0, 0); + + /* creating a Launch action */ + actoptlist[0] = 0; + sopt = actoptlist; + sopt += pdc_sprintf(p->pdc, pdc_false, sopt, "filename {%s} ", filename); + if (p->launchlink_parameters) + { + sopt += pdc_sprintf(p->pdc, pdc_false, sopt, "parameters {%s} ", + p->launchlink_parameters); + pdc_free(p->pdc, p->launchlink_parameters); + p->launchlink_parameters = NULL; + } + if (p->launchlink_operation) + { + sopt += pdc_sprintf(p->pdc, pdc_false, sopt, "operation {%s} ", + p->launchlink_operation); + pdc_free(p->pdc, p->launchlink_operation); + p->launchlink_operation = NULL; + } + if (p->launchlink_defaultdir) + { + sopt += pdc_sprintf(p->pdc, pdc_false, sopt, "defaultdir {%s} ", + p->launchlink_defaultdir); + pdc_free(p->pdc, p->launchlink_defaultdir); + p->launchlink_defaultdir = NULL; + } + acthdl = pdf__create_action(p, "Launch", actoptlist); + + /* fill up annotation struct */ + if (acthdl > -1) + { + ann = pdf_new_annot(p); + ann->atype = ann_link; + pdf_init_rectangle(p, ann, llx, lly, urx, ury, NULL); + pdf_insert_annot_params(p, ann); + if (p->pdc->hastobepos) acthdl++; + pdc_sprintf(p->pdc, pdc_false, actoptlist, "activate %d", acthdl); + ann->action = pdc_strdup(p->pdc, actoptlist); + ann->display = disp_noprint; + } +} + +void +pdf__add_locallink( + PDF *p, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury, + int page, + const char *optlist) +{ + pdf_annot *ann; + + /* fill up annotation struct */ + ann = pdf_new_annot(p); + ann->atype = ann_link; + pdf_init_rectangle(p, ann, llx, lly, urx, ury, NULL); + pdf_insert_annot_params(p, ann); + ann->dest = pdf_parse_destination_optlist(p, optlist, page, pdf_locallink); + ann->display = disp_noprint; +} + +void +pdf__add_weblink( + PDF *p, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury, + const char *url) +{ + char actoptlist[2048]; + pdf_annot *ann; + int acthdl; + + if (url == NULL || *url == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "url", 0, 0, 0); + + /* creating a URI action */ + pdc_sprintf(p->pdc, pdc_false, actoptlist, "url {%s} ", url); + acthdl = pdf__create_action(p, "URI", actoptlist); + + /* fill up annotation struct */ + if (acthdl > -1) + { + ann = pdf_new_annot(p); + ann->atype = ann_link; + pdf_init_rectangle(p, ann, llx, lly, urx, ury, NULL); + pdf_insert_annot_params(p, ann); + if (p->pdc->hastobepos) acthdl++; + pdc_sprintf(p->pdc, pdc_false, actoptlist, "activate %d", acthdl); + ann->action = pdc_strdup(p->pdc, actoptlist); + ann->display = disp_noprint; + } +} + +void +pdf__set_border_style(PDF *p, const char *style, pdc_scalar width) +{ + int k; + + p->border_style = border_solid; + if (style) + { + k = pdc_get_keycode_ci(style, pdf_borderstyle_keylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "style", style, 0, 0); + p->border_style = (pdf_borderstyle) k; + } + + pdc_check_number_limits(p->pdc, "width", width, 0.0, PDC_FLOAT_MAX); + + p->border_width = width; +} + +void +pdf__set_border_color(PDF *p, pdc_scalar red, pdc_scalar green, pdc_scalar blue) +{ + pdc_check_number_limits(p->pdc, "red", red, 0.0, 1.0); + pdc_check_number_limits(p->pdc, "green", green, 0.0, 1.0); + pdc_check_number_limits(p->pdc, "blue", blue, 0.0, 1.0); + + p->border_red = red; + p->border_green = green; + p->border_blue = blue; +} + +void +pdf__set_border_dash(PDF *p, pdc_scalar b, pdc_scalar w) +{ + pdc_check_number_limits(p->pdc, "b", b, 0.0, PDC_FLOAT_MAX); + pdc_check_number_limits(p->pdc, "w", w, 0.0, PDC_FLOAT_MAX); + + p->border_dash1 = b; + p->border_dash2 = w; +} + + + diff --git a/src/pdflib/pdflib/p_block.c b/src/pdflib/pdflib/p_block.c new file mode 100644 index 0000000..24a55a8 --- /dev/null +++ b/src/pdflib/pdflib/p_block.c @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2007 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_block.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Block processing routines (require the PDI library) + * + */ + +#define P_BLOCK_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_font.h" +#include "p_image.h" +#include "p_defopt.h" + diff --git a/src/pdflib/pdflib/p_bmp.c b/src/pdflib/pdflib/p_bmp.c new file mode 100644 index 0000000..ac6a974 --- /dev/null +++ b/src/pdflib/pdflib/p_bmp.c @@ -0,0 +1,795 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_bmp.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * BMP processing for PDFlib + * + */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +#ifndef PDF_BMP_SUPPORTED + +pdc_bool +pdf_is_BMP_file(PDF *p, pdc_file *fp) +{ + (void) p; + (void) fp; + + return pdc_false; +} + +int +pdf_process_BMP_data( + PDF *p, + int imageslot) +{ + pdf_image *image = &p->images[imageslot]; + + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "BMP", 0, 0, 0); + + return -1; +} + +#else /* !PDF_BMP_SUPPORTED */ + +/* for documentation only */ +#if 0 + +/* BMP file header structure */ +typedef struct +{ + pdc_ushort bfType; /* Magic number for file */ + pdc_uint32 bfSize; /* Size of file */ + pdc_ushort bfReserved1; /* Reserved */ + pdc_ushort bfReserved2; /* ... */ + pdc_uint32 bfOffBits; /* Offset to bitmap data */ +} +BITMAPFILEHEADER; + +/* BMP file info structure */ +typedef struct +{ + pdc_uint32 biSize; /* Size of info header */ + pdc_sint32 biWidth; /* Width of image */ + pdc_sint32 biHeight; /* Height of image */ + pdc_ushort biPlanes; /* Number of color planes */ + pdc_ushort biBitCount; /* Number of bits per pixel */ + pdc_uint32 biCompression; /* Type of compression to use */ + pdc_uint32 biSizeImage; /* Size of image data */ + pdc_sint32 biXPelsPerMeter; /* X pixels per meter */ + pdc_sint32 biYPelsPerMeter; /* Y pixels per meter */ + pdc_uint32 biClrUsed; /* Number of colors used */ + pdc_uint32 biClrImportant; /* Number of important colors */ +} +BITMAPINFOHEADER; + +#endif + +#define PDF_GET_BYTE(pos) *pos, pos += sizeof(pdc_byte) +#define PDF_GET_SHORT(pos) pdc_get_le_short(pos), pos += sizeof(pdc_short) +#define PDF_GET_USHORT(pos) pdc_get_le_ushort(pos), pos += sizeof(pdc_ushort) +#define PDF_GET_LONG(pos) pdc_get_le_long(pos), pos += sizeof(pdc_sint32) +#define PDF_GET_ULONG(pos) pdc_get_le_ulong(pos), pos += sizeof(pdc_uint32) + +#define PDF_BMP_STRING "\102\115" /* "BM" */ + +#define PDF_BMP_RGB 0 /* No compression - straight BGR data */ +#define PDF_BMP_RLE8 1 /* 8-bit run-length compression */ +#define PDF_BMP_RLE4 2 /* 4-bit run-length compression */ +#define PDF_BMP_BITFIELDS 3 /* RGB bitmap with RGB masks */ + +#define PDF_BMP_FILE_HEADSIZE 14 /* File header size */ +#define PDF_BMP_INFO_HEAD2SIZE 12 /* Info header size BMP Version 2 */ +#define PDF_BMP_INFO_HEAD3SIZE 40 /* Info header size BMP Version 3 */ +#define PDF_BMP_INFO_HEAD4SIZE 108 /* Info header size BMP Version 4 */ + +static void +pdf_data_source_BMP_init(PDF *p, PDF_data_source *src) +{ + static const char *fn = "pdf_data_source_BMP_init"; + pdf_image *image = (pdf_image *) src->private_data; + + src->buffer_length = image->info.bmp.rowbytes_buf; + src->buffer_start = (pdc_byte *) + pdc_calloc(p->pdc, image->info.bmp.rowbytes_pad, fn); + src->bytes_available = image->info.bmp.rowbytes_pdf; + src->next_byte = src->buffer_start; +} + +static pdc_bool +pdf_data_source_BMP_fill(PDF *p, PDF_data_source *src) +{ + pdf_image *image = (pdf_image *) src->private_data; + int i, j; + + (void) p; + + if (image->info.bmp.bpp == 16) + { + if (image->info.bmp.pos < image->info.bmp.end) + { + pdc_ushort pixel, ppixel; + int ilast = image->info.bmp.rowbytes_buf - 3; + + i = 0; + for (j = 0; j < (int) image->info.bmp.rowbytes; j += 2) + { + pixel = PDF_GET_USHORT(image->info.bmp.pos); + + if (i <= ilast) + { + ppixel = (pixel & image->info.bmp.redmask); + ppixel = (ppixel >> image->info.bmp.redmove); + src->buffer_start[i] = (pdc_byte) ((ppixel * 255) / + image->info.bmp.redmax); + i++; + + ppixel = (pixel & image->info.bmp.greenmask); + ppixel = (ppixel >> image->info.bmp.greenmove); + src->buffer_start[i] = (pdc_byte) ((ppixel * 255) / + image->info.bmp.greenmax); + i++; + + ppixel = (pixel & image->info.bmp.bluemask); + ppixel = (ppixel >> image->info.bmp.bluemove); + src->buffer_start[i] = (pdc_byte) ((ppixel * 255) / + image->info.bmp.bluemax); + i++; + } + } + } + else + { + src->bytes_available = 0; + } + } + + else if (image->info.bmp.bpp == 32 || + image->info.bmp.compression == PDF_BMP_RGB) + { + size_t avail; + + /* Read 1 padded row from file */ + avail = pdc_fread(src->buffer_start, 1, image->info.bmp.rowbytes_pad, + image->fp); + if (avail > 0) + { + /* Fill up remaining bytes */ + if (avail < image->info.bmp.rowbytes_pad) + { + for (i = (int) avail; i < (int) src->buffer_length; i++) + src->buffer_start[i] = 0; + } + + if (image->colorspace == DeviceRGB) + { + /* Swap red and blue */ + if (image->info.bmp.bpp == 32) + { + pdc_uint32 pixel, ppixel; + pdc_byte *pos = src->buffer_start; + + i = 0; + for (j = 0; j < (int) image->info.bmp.rowbytes_buf; j += 4) + { + pixel = PDF_GET_ULONG(pos); + + ppixel = (pixel & image->info.bmp.redmask); + ppixel = (ppixel >> image->info.bmp.redmove); + src->buffer_start[i] = (pdc_byte) ((ppixel * 255) / + image->info.bmp.redmax); + i++; + + ppixel = (pixel & image->info.bmp.greenmask); + ppixel = (ppixel >> image->info.bmp.greenmove); + src->buffer_start[i] = (pdc_byte) ((ppixel * 255) / + image->info.bmp.greenmax); + i++; + + ppixel = (pixel & image->info.bmp.bluemask); + ppixel = (ppixel >> image->info.bmp.bluemove); + src->buffer_start[i] = (pdc_byte) ((ppixel * 255) / + image->info.bmp.bluemax); + i++; + } + } + else + { + for (j = 0; j < (int) image->info.bmp.rowbytes_buf; j += 3) + { + pdc_byte c = src->buffer_start[j]; + src->buffer_start[j] = src->buffer_start[j + 2]; + src->buffer_start[j + 2] = c; + } + } + } + } + else + { + src->bytes_available = 0; + } + } + + /* Compression methods RLE8 and RLE4 */ + else + { + int col = 0; + int fnibble = 1; + pdc_byte c, cc, ccc, cn[2], ccn; + + if (image->info.bmp.pos < image->info.bmp.end) + { + if (image->info.bmp.skiprows) + { + for (; col < (int) image->info.bmp.rowbytes; col++) + src->buffer_start[col] = 0; + image->info.bmp.skiprows--; + } + else + { + while (1) + { + c = *image->info.bmp.pos; + image->info.bmp.pos++; + if (image->info.bmp.pos >= image->info.bmp.end) + goto PDF_BMP_CORRUPT; + cc = *image->info.bmp.pos; + + if (c != 0) + { + /* Repeat c time pixel value */ + if (image->info.bmp.compression == PDF_BMP_RLE8) + { + for (i = 0; i < (int) c; i++) + { + if (col >= (int) image->info.bmp.rowbytes) + goto PDF_BMP_CORRUPT; + src->buffer_start[col] = cc; + col++; + } + } + else + { + cn[0] = (pdc_byte) ((cc & 0xF0) >> 4); + cn[1] = (pdc_byte) (cc & 0x0F); + for (i = 0; i < (int) c; i++) + { + if (col >= (int) image->info.bmp.rowbytes) + goto PDF_BMP_CORRUPT; + ccn = cn[i%2]; + if (fnibble) + { + fnibble = 0; + src->buffer_start[col] = + (pdc_byte) (ccn << 4); + } + else + { + fnibble = 1; + src->buffer_start[col] |= ccn; + col++; + } + } + } + } + else if (cc > 2) + { + /* cc different pixel values */ + if (image->info.bmp.compression == PDF_BMP_RLE8) + { + for (i = 0; i < (int) cc; i++) + { + image->info.bmp.pos++; + if (image->info.bmp.pos >= image->info.bmp.end) + goto PDF_BMP_CORRUPT; + if (col >= (int) image->info.bmp.rowbytes) + goto PDF_BMP_CORRUPT; + src->buffer_start[col] = *image->info.bmp.pos; + col++; + } + } + else + { + for (i = 0; i < (int) cc; i++) + { + if (!(i%2)) + { + image->info.bmp.pos++; + if (image->info.bmp.pos >= + image->info.bmp.end) + goto PDF_BMP_CORRUPT; + ccc = *image->info.bmp.pos; + cn[0] = (pdc_byte) ((ccc & 0xF0) >> 4); + cn[1] = (pdc_byte) (ccc & 0x0F); + } + if (col >= (int) image->info.bmp.rowbytes) + goto PDF_BMP_CORRUPT; + ccn = cn[i%2]; + if (fnibble) + { + fnibble = 0; + src->buffer_start[col] = + (pdc_byte) (ccn << 4); + } + else + { + fnibble = 1; + src->buffer_start[col] |= ccn; + col++; + } + } + if (cc % 2) cc++; + cc /= 2; + } + + /* Odd number of bytes */ + if (cc % 2) + image->info.bmp.pos++; + } + else if (cc < 2) + { + /* End of scan line or end of bitmap data*/ + for (; col < (int) image->info.bmp.rowbytes; col++) + src->buffer_start[col] = 0; + } + else if (cc == 2) + { + int cola; + + /* Run offset marker */ + if (image->info.bmp.pos >= image->info.bmp.end - 1) + goto PDF_BMP_CORRUPT; + image->info.bmp.pos++; + c = *image->info.bmp.pos; + image->info.bmp.pos++; + cc = *image->info.bmp.pos; + + /* Fill current row */ + cola = col; + for (; col < (int) image->info.bmp.rowbytes; col++) + src->buffer_start[col] = 0; + if (col - cola != (int) c) + goto PDF_BMP_CORRUPT; + + /* Number of rows to be skipped */ + image->info.bmp.skiprows = (size_t) cc; + } + + image->info.bmp.pos++; + if (col >= (int) image->info.bmp.rowbytes) + { + /* Skip end of scan line marker */ + if (image->info.bmp.pos < image->info.bmp.end - 1) + { + c = *image->info.bmp.pos; + cc = *(image->info.bmp.pos + 1); + if(cc == 0 && cc <= 1) + image->info.bmp.pos += 2; + } + break; + } + } + } + } + else + { + src->bytes_available = 0; + } + } + + return (src->bytes_available ? pdc_true : pdc_false); + + PDF_BMP_CORRUPT: + + image->corrupt = pdc_true; + src->bytes_available = 0; + return pdc_false; +} + +static void +pdf_data_source_BMP_terminate(PDF *p, PDF_data_source *src) +{ + pdf_image *image = (pdf_image *) src->private_data; + + pdc_free(p->pdc, (void *) src->buffer_start); + if (image->info.bmp.bitmap != NULL) + pdc_free(p->pdc, (void *) image->info.bmp.bitmap); +} + +pdc_bool +pdf_is_BMP_file(PDF *p, pdc_file *fp) +{ + pdc_byte buf[2]; + + pdc_logg_cond(p->pdc, 1, trc_image, "\tChecking image type BMP...\n"); + + if (pdc_fread(buf, 1, 2, fp) < 2 || + strncmp((const char *) buf, PDF_BMP_STRING, 2) != 0) + { + pdc_fseek(fp, 0L, SEEK_SET); + return pdc_false; + } + return pdc_true; +} + +int +pdf_process_BMP_data( + PDF *p, + int imageslot) +{ + static const char *fn = "pdf_process_BMP_data"; + pdc_byte buf[256], *pos, *cmap, bdummy; + pdf_image *image = &p->images[imageslot]; + pdc_file *fp = image->fp; + pdc_uint32 uldummy, infosize = 0, offras = 0, planes = 0, bitmapsize = 0; + pdc_uint32 ncolors = 0, importcolors = 0, compression = PDF_BMP_RGB; + pdc_ushort usdummy, bpp = 0, bpp_pdf = 0; + pdc_sint32 width = 0, height = 0, dpi_x = 0, dpi_y = 0; + pdc_uint32 redmask = 0, greenmask = 0, bluemask = 0, ccmax; + size_t nbytes; + pdf_colorspace cs; + pdf_colormap colormap; + int i, slot, colsize = 0, errcode = 0; + + /* Error reading magic number or not a BMP file */ + if (pdf_is_BMP_file(p, image->fp) == pdc_false) + { + errcode = PDC_E_IO_BADFORMAT; + goto PDF_BMP_ERROR; + } + + /* read file header without FileType field + */ + /* Size field of info header */ + pos = &buf[2]; + nbytes = PDF_BMP_FILE_HEADSIZE - 2 + 4; + if (!PDC_OK_FREAD(fp, pos, nbytes)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_BMP_ERROR; + } + uldummy = PDF_GET_ULONG(pos); + usdummy = PDF_GET_USHORT(pos); + usdummy = PDF_GET_USHORT(pos); + offras = PDF_GET_ULONG(pos); + infosize = PDF_GET_ULONG(pos); + + /* no support of later version than 3 */ + if (infosize != PDF_BMP_INFO_HEAD2SIZE && + infosize != PDF_BMP_INFO_HEAD3SIZE) + { + errcode = PDF_E_BMP_VERSUNSUPP; + goto PDF_BMP_ERROR; + } + + /* info header */ + pos = buf; + nbytes = infosize - 4; + if (!PDC_OK_FREAD(fp, pos, nbytes)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_BMP_ERROR; + } + if (infosize == PDF_BMP_INFO_HEAD2SIZE) + { + width = PDF_GET_SHORT(pos); + height = PDF_GET_SHORT(pos); + planes = PDF_GET_USHORT(pos); + bpp = PDF_GET_USHORT(pos); + colsize = 3; + } + else if (infosize == PDF_BMP_INFO_HEAD3SIZE) + { + width = PDF_GET_LONG(pos); + height = PDF_GET_LONG(pos); + planes = PDF_GET_USHORT(pos); + bpp = PDF_GET_USHORT(pos); + compression = PDF_GET_ULONG(pos); + bitmapsize = PDF_GET_ULONG(pos); + dpi_x = PDF_GET_LONG(pos); + dpi_y = PDF_GET_LONG(pos); + ncolors = PDF_GET_ULONG(pos); + importcolors = PDF_GET_ULONG(pos); + colsize = 4; + } + + /* compressed BMP images by bitfields */ + if (compression == PDF_BMP_BITFIELDS) + { + pos = buf; + nbytes = 3 * sizeof(pdc_uint32); + if (!PDC_OK_FREAD(fp, pos, nbytes)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_BMP_ERROR; + } + else + { + redmask = PDF_GET_ULONG(pos); + greenmask = PDF_GET_ULONG(pos); + bluemask = PDF_GET_ULONG(pos); + } + } + + pdc_logg_cond(p->pdc, 5, trc_image, + "\t\t\tinfosize = %d\n" + "\t\t\twidth = %d\n" + "\t\t\theight = %d\n" + "\t\t\tplanes = %d\n" + "\t\t\tbpp = %d\n" + "\t\t\tcompression = %d\n" + "\t\t\tbitmapsize = %d\n" + "\t\t\tdpi_x = %d\n" + "\t\t\tdpi_y = %d\n" + "\t\t\tncolors = %d\n" + "\t\t\timportcolors = %d\n" + "\t\t\tcolsize = %d\n" + "\t\t\tredmask = 0x%08X\n" + "\t\t\tgreenmask = 0x%08X\n" + "\t\t\tbluemask = 0x%08X\n", + infosize, width, height, planes, bpp, compression, + bitmapsize, dpi_x, dpi_y, ncolors, importcolors, + colsize, redmask, greenmask, bluemask); + + image->bpc = bpp; + image->width = width; + image->height = -height; + image->dpi_x = (pdc_scalar) (PDC_INCH2METER * dpi_x); + image->dpi_y = (pdc_scalar) (PDC_INCH2METER * dpi_y); + image->info.bmp.bpp = bpp; + bpp_pdf = bpp; + + /* color map only for bpp = 1, 4, 8 */ + if (bpp < 16) + { + if (!ncolors) + ncolors = (pdc_uint32) (1 << bpp); + if (ncolors > (offras - PDF_BMP_FILE_HEADSIZE - infosize) / colsize) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_BMP_ERROR; + } + + /* allocate and read color map */ + nbytes = colsize * ncolors; + cmap = (pdc_byte *) pdc_malloc(p->pdc, nbytes, fn); + if (!PDC_OK_FREAD(fp, cmap, nbytes)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_BMP_ERROR; + } + + /* set color map (bgr) */ + pos = cmap; + for (i = 0; i < (int) ncolors; i++) + { + colormap[i][2] = PDF_GET_BYTE(pos); + colormap[i][1] = PDF_GET_BYTE(pos); + colormap[i][0] = PDF_GET_BYTE(pos); + if (infosize == PDF_BMP_INFO_HEAD3SIZE) + { + bdummy = PDF_GET_BYTE(pos); + } + } + pdc_free(p->pdc, cmap); + + pdc_logg_cond(p->pdc, 5, trc_image, + "\t\t\tcolor map with %d colors generated\n", + ncolors); + + image->components = 1; + + cs.type = Indexed; + cs.val.indexed.base = DeviceRGB; + cs.val.indexed.palette_size = (int) ncolors; + cs.val.indexed.colormap = &colormap; + cs.val.indexed.colormap_id = PDC_BAD_ID; + slot = pdf_add_colorspace(p, &cs, pdc_false); + + image->colorspace = slot; + + + } + else + { + image->colorspace = DeviceRGB; + image->components = 3; + image->bpc = 8; + if (bpp == 16) + { + bpp = 24; + bpp_pdf = 24; + if (compression == PDF_BMP_RGB) + { + redmask = 0x00007C00; + greenmask = 0x000003E0; + bluemask = 0x0000001F; + } + } + if (bpp == 32) + { + bpp_pdf = 24; + if (compression == PDF_BMP_RGB) + { + redmask = 0x00FF0000; + greenmask = 0x0000FF00; + bluemask = 0x000000FF; + } + } + + /* maximum and movement */ + if (image->info.bmp.bpp != 24) + { + for (i = 0; i < 32; i++) + { + ccmax = (redmask >> i); + if (ccmax & 0x00000001) + break; + } + image->info.bmp.redmask = redmask; + image->info.bmp.redmax = ccmax; + image->info.bmp.redmove = i; + + + for (i = 0; i < 32; i++) + { + ccmax = (greenmask >> i); + if (ccmax & 0x00000001) + break; + } + image->info.bmp.greenmask = greenmask; + image->info.bmp.greenmax = ccmax; + image->info.bmp.greenmove = i; + + for (i = 0; i < 32; i++) + { + ccmax = (bluemask >> i); + if (ccmax & 0x00000001) + break; + } + image->info.bmp.bluemask = bluemask; + image->info.bmp.bluemax = ccmax; + image->info.bmp.bluemove = i; + } + } + + if (image->imagemask) + { + if (image->components != 1) { + errcode = PDF_E_IMAGE_BADMASK; + goto PDF_BMP_ERROR; + } + + if (p->compatibility <= PDC_1_3) { + if (image->components != 1 || image->bpc != 1) { + errcode = PDF_E_IMAGE_MASK1BIT13; + goto PDF_BMP_ERROR; + } + } else if (image->bpc > 1) { + /* images with more than one bit will be written as /SMask, + * and don't require an /ImageMask entry. + */ + image->imagemask = pdc_false; + } + image->colorspace = DeviceGray; + } + + + + /* we invert this flag later */ + if (image->ignoremask) + image->transparent = pdc_true; + + /* number of bytes per row */ + image->info.bmp.rowbytes_pdf = (size_t) ((bpp_pdf * width + 7) / 8); + image->info.bmp.rowbytes_buf = (size_t) ((bpp * width + 7) / 8); + if (bpp == 4) + image->info.bmp.rowbytes = image->info.bmp.rowbytes_buf; + else if (image->info.bmp.bpp == 16) + image->info.bmp.rowbytes = + (size_t) (4 * ((image->info.bmp.bpp * width + 31) / 32)); + else + image->info.bmp.rowbytes = (size_t) ((bpp * width) / 8); + image->info.bmp.rowbytes_pad = (size_t) (4 * ((bpp * width + 31) / 32)); + image->info.bmp.compression = compression; + image->info.bmp.skiprows = 0; + image->info.bmp.bitmap = NULL; + + pdc_logg_cond(p->pdc, 5, trc_image, + "\t\t\tinternal variables:\n" + "\t\t\t\tbpp_pdf = %d\n" + "\t\t\t\trowbytes = %d\n" + "\t\t\t\trowbytes_buf = %d\n" + "\t\t\t\trowbytes_pdf = %d\n" + "\t\t\t\trowbytes_pad = %d\n", + bpp_pdf, image->info.bmp.rowbytes, image->info.bmp.rowbytes_buf, + image->info.bmp.rowbytes_pdf, image->info.bmp.rowbytes_pad); + + /* read whole bitmap */ + if (image->info.bmp.bpp < 24 && (image->info.bmp.bpp == 16 || + image->info.bmp.compression != PDF_BMP_RGB)) + { + if (!bitmapsize) + { + bitmapsize = (int) (pdc_file_size(fp) - pdc_ftell(fp)); + pdc_logg_cond(p->pdc, 5, trc_image, + "\t\t\tcalculated bitmapsize = %d\n", bitmapsize); + } + + image->info.bmp.bitmap = + (pdc_byte *) pdc_malloc(p->pdc, bitmapsize, fn); + if (!PDC_OK_FREAD(fp, image->info.bmp.bitmap, bitmapsize)) + { + pdc_free(p->pdc, (void *) image->info.bmp.bitmap); + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_BMP_ERROR; + } + image->info.bmp.pos = image->info.bmp.bitmap; + image->info.bmp.end = image->info.bmp.bitmap + bitmapsize; + } + + /* offset bitmap data */ + pdc_fseek(image->fp, (pdc_sint32) offras, SEEK_SET); + + /* put image data */ + image->src.init = pdf_data_source_BMP_init; + image->src.fill = pdf_data_source_BMP_fill; + image->src.terminate = pdf_data_source_BMP_terminate; + image->src.private_data = (void *) image; + + image->use_raw = pdc_false; + image->in_use = pdc_true; + + pdf_put_image(p, imageslot, pdc_true, pdc_true); + + if (image->corrupt) + errcode = PDF_E_IMAGE_CORRUPT; + else + return imageslot; + + PDF_BMP_ERROR: + { + const char *stemp = NULL; + + if (errcode) + stemp = pdf_get_image_filename(p, image); + + switch (errcode) + { + case PDF_E_IMAGE_MASK1BIT13: + case PDF_E_BMP_VERSUNSUPP: + case PDF_E_BMP_COMPUNSUPP: + case PDF_E_IMAGE_BADMASK: + pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0); + break; + + case PDC_E_IO_BADFORMAT: + pdc_set_errmsg(p->pdc, errcode, stemp, "BMP", 0, 0); + break; + + case PDF_E_IMAGE_CORRUPT: + pdc_set_errmsg(p->pdc, errcode, "BMP", stemp, 0, 0); + break; + + case 0: /* error code and message already set */ + break; + } + } + + return -1; +} + +#endif /* PDF_BMP_SUPPORTED */ + diff --git a/src/pdflib/pdflib/p_ccitt.c b/src/pdflib/pdflib/p_ccitt.c new file mode 100644 index 0000000..ce028b7 --- /dev/null +++ b/src/pdflib/pdflib/p_ccitt.c @@ -0,0 +1,186 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_ccitt.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * CCITT (Fax G3 and G4) processing for PDFlib + * + */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +/* + * Do a bit-reversal of all bytes in the buffer. + * This is supported for some clients which provide + * CCITT-compressed data in a byte-reversed format. + */ + +static void +pdf_reverse_bit_order(unsigned char *buffer, size_t size) +{ + size_t i; + + /* table for fast byte reversal */ + static const pdc_byte reverse[256] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff + }; + + if (buffer != NULL) { + for (i = 0; i < size; i++) { + buffer[i] = reverse[buffer[i]]; + } + } +} + +static void +pdf_data_source_ccitt_raw_init(PDF *p, PDF_data_source *src) +{ + (void) p; + + src->bytes_available = 0; +} + +static pdc_bool +pdf_data_source_ccitt_raw_fill(PDF *p, PDF_data_source *src) +{ + pdf_image *image; + pdc_bool ismem; + + (void) p; + + if (src->bytes_available) + return pdc_false; + + image = (pdf_image *) src->private_data; + + src->buffer_start = (pdc_byte *) + pdc_freadall(image->fp, (size_t *) &src->buffer_length, &ismem); + + if (src->buffer_length == 0) + return pdc_false; + + src->bytes_available = src->buffer_length; + src->next_byte = src->buffer_start; + + if (image->info.ccitt.BitReverse) + pdf_reverse_bit_order(src->buffer_start, src->bytes_available); + + if (ismem) + src->buffer_length = 0; + + return pdc_true; +} + +static void +pdf_data_source_ccitt_raw_terminate(PDF *p, PDF_data_source *src) +{ + if (src->buffer_length) + pdc_free(p->pdc, (void *) src->buffer_start); +} + +static int +pdf_process_ccitt_raw_data(PDF *p, int imageslot) +{ + pdf_image *image = &p->images[imageslot]; + + /* check data length for raw uncompressed images */ + if (image->compression == pdf_comp_none && image->fp) + { + pdc_off_t length = pdc_file_size(image->fp); + if (length != (image->height_pixel * + ((image->width_pixel * image->components * image->bpc + 7) / 8))) + { + pdc_set_errmsg(p->pdc, PDF_E_RAW_ILLSIZE, + pdc_errprintf(p->pdc, "%lld", length), + pdf_get_image_filename(p, image), 0, 0); + return -1; + } + } + + + + + if (image->reference == pdf_ref_direct) + { + image->src.init = pdf_data_source_ccitt_raw_init; + image->src.fill = pdf_data_source_ccitt_raw_fill; + image->src.terminate = pdf_data_source_ccitt_raw_terminate; + image->src.private_data = (void *) image; + } + + image->in_use = pdc_true; /* mark slot as used */ + + if (image->doinline) + pdf_put_inline_image(p, imageslot); + else + pdf_put_image(p, imageslot, pdc_true, pdc_true); + + return imageslot; +} + +int +pdf_process_CCITT_data(PDF *p, int imageslot) +{ + pdf_image *image = &p->images[imageslot]; + + /* CCITT specific information */ + image->info.ccitt.BitReverse = image->bitreverse; + image->compression = pdf_comp_ccitt; + image->use_raw = pdc_true; + + return pdf_process_ccitt_raw_data(p, imageslot); +} + +int +pdf_process_RAW_data(PDF *p, int imageslot) +{ + pdf_image *image = &p->images[imageslot]; + + /* RAW specific information */ + image->info.ccitt.BitReverse = 0; + image->compression = pdf_comp_none; + + return pdf_process_ccitt_raw_data(p, imageslot); +} diff --git a/src/pdflib/pdflib/p_cid.c b/src/pdflib/pdflib/p_cid.c new file mode 100644 index 0000000..6d7766c --- /dev/null +++ b/src/pdflib/pdflib/p_cid.c @@ -0,0 +1,198 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_cid.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib CID font handling routines + * + */ + +#include "p_intern.h" +#include "p_font.h" + +#include "ft_cid.h" + + +/* +** Returns CMap slot and for standard CJK fonts: fontandle. +** +** pdc_invalidenc: predefined CMap not found +** pdc_cid or pdc_unicode: predefined CMap found +** +** *o_slot: +** >= 0: standard font found +** < 0: |error code| +*/ +pdc_bool +pdf_handle_cidfont(PDF *p, const char *fontname, const char *encoding, + pdc_encoding enc, pdf_font *font, int *o_slot, + pdc_encoding *newenc) +{ + const char *encapiname = encoding; + fnt_cmap_info cmapinfo; + const fnt_font_metric *fontmetric; + pdc_bool isidentity = pdc_false; + pdc_bool isstdfont = pdc_false; + pdc_bool iscjkcp = pdc_false; + int charcoll, slot; + + (void) enc; + (void) iscjkcp; + (void) encapiname; + + *o_slot = -1; + *newenc = pdc_invalidenc; + + + /* + * Look whether font is already in the cache. + * If font with same name and encoding is found, + * returns its slot number. + */ + + for (slot = 0; slot < p->fonts_number; slot++) + { + if (p->fonts[slot].ft.enc == pdc_cid && + p->fonts[slot].opt.fontstyle == font->opt.fontstyle && + p->fonts[slot].opt.embedding == font->opt.embedding && + !strcmp(p->fonts[slot].apiname, fontname) && + !strcmp(p->fonts[slot].ft.cmapname, encoding)) + { + *o_slot = slot; + *newenc = pdc_cid; + return pdc_true; + } + } + + /* Check the requested CMap */ + charcoll = fnt_get_predefined_cmap_info(encoding, &cmapinfo); + if (charcoll == (int) cc_none) + return pdc_true; + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tPredefined CMap \"%s\" found\n", encoding); + + /* Check whether this CMap is supported in the desired PDF version */ + if (cmapinfo.compatibility > p->compatibility) + { + pdc_set_errmsg(p->pdc, PDF_E_DOC_PDFVERSION, + encoding, pdc_get_pdfversion(p->pdc, p->compatibility), 0, 0); + return pdc_false; + } + + /* For Unicode capable language wrappers only UCS2/UTF16 CMaps allowed */ + if (cmapinfo.codesize == 0 && p->pdc->unicaplang) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_NEEDUCS2, 0, 0, 0, 0); + return pdc_false; + } + + /* Check whether the font name is among the known Acrobat CJK fonts */ + charcoll = fnt_get_preinstalled_cidfont(fontname, &fontmetric); + isidentity = cmapinfo.charcoll == (int) cc_identity; + if (isidentity) + cmapinfo.charcoll = abs(charcoll); + + /* known Acrobat CID font */ + if (charcoll != (int) cc_none) + { + pdc_logg_cond(p->pdc, 1, trc_font, + "\tStandard CJK font \"%s\" found\n", fontname); + + /* Selected CMap and known standard font don't match */ + if ((cmapinfo.charcoll != abs(charcoll) || + (charcoll == (int) cc_japanese && cmapinfo.codesize == -2))) + { + pdc_set_errmsg(p->pdc, PDF_E_CJK_UNSUPP_CHARCOLL, + 0, 0, 0, 0); + return pdc_false; + } + isstdfont = pdc_true; + + + /* Embedding not possible */ + if (font->opt.embedding) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_EMBEDCMAP, 0, 0, 0, 0); + return pdc_false; + } + } +#ifdef WIN32 + else if (iscjkcp && !p->pdc->ptfrun) + { + return pdc_true; + } +#endif + + + /* embedding check */ + if (!pdf_check_font_embedding(p, font, fontname)) + return pdc_false; + + /* supplement number, number of codes = (maximal) number of CIDs */ + font->supplement = fnt_get_supplement(&cmapinfo, p->compatibility); + if (isidentity) + font->supplement = -1; + font->ft.numcodes = fnt_get_maxcid(cmapinfo.charcoll, font->supplement) + 1; + + { + font->passthrough = pdc_true; + font->codesize = 0; + } + + /* CMap and default settings */ + font->ft.vertical = cmapinfo.vertical; + font->ft.cmapname = pdc_strdup(p->pdc, encoding); + if (font->outcmapname == NULL) + font->outcmapname = pdc_strdup(p->pdc, encoding); + font->ft.enc = pdc_cid; + font->iscidfont = pdc_true; + + /* Fill up the font struct */ + fnt_fill_font_metric(p->pdc, &font->ft, pdc_false, fontmetric); + + /* CID widths not available */ + font->widthsmissing = pdc_true; + + pdc_logg_cond(p->pdc, 1, trc_font, + "\n\t%s CJK font: \"%s\"\n\tPredefined CMap: \"%s\"\n" + "\tOrdering: \"%s\"\n\tSupplement: %d\n", + font->ft.isstdfont ? "Adobe Standard" : "Custom", fontname, encoding, + fnt_get_ordering_cid(font->ft.m.charcoll), font->supplement); + + *newenc = pdc_cid; + + return pdc_true; +} + +#ifdef PDF_CJKFONTWIDTHS_SUPPORTED +void +pdf_put_cidglyph_widths(PDF *p, pdf_font *font) +{ + if (font->opt.monospace) + { + if (font->opt.monospace != FNT_DEFAULT_CIDWIDTH) + pdc_printf(p->out, "/DW %d\n", font->opt.monospace); + } + else + { + const char **widths = fnt_get_cid_widths_array(p->pdc, &font->ft); + int i; + + pdc_puts(p->out, "/W"); + pdc_begin_array(p->out); + for (i = 0; i < FNT_CIDMETRIC_INCR - 1; i++) + pdc_puts(p->out, widths[i]); + pdc_end_array(p->out); + } +} +#endif /* PDF_CJKFONTWIDTHS_SUPPORTED */ diff --git a/src/pdflib/pdflib/p_color.c b/src/pdflib/pdflib/p_color.c new file mode 100644 index 0000000..d996d06 --- /dev/null +++ b/src/pdflib/pdflib/p_color.c @@ -0,0 +1,1130 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2007 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_color.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib color routines + * + */ + +#define P_COLOR_C + +#include "p_intern.h" +#include "p_color.h" + + +static const pdc_keyconn pdf_colortype_keylist[] = +{ + {"none", color_none}, + {"gray", color_gray}, + {"rgb", color_rgb}, + {"cmyk", color_cmyk}, + {"spotname", color_spotname}, + {"spot", color_spot}, + {"pattern", color_pattern}, + {"iccbasedgray", color_iccbasedgray}, + {"iccbasedrgb", color_iccbasedrgb}, + {"iccbasedcmyk", color_iccbasedcmyk}, + {"lab", color_lab}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_colorcomp_keylist[] = +{ + {"none", 0}, + {"gray", 1}, + {"rgb", 3}, + {"cmyk", 4}, + {"spotname", 2}, + {"spot", 2}, + {"pattern", 1}, + {"iccbasedgray", 1}, + {"iccbasedrgb", 3}, + {"iccbasedcmyk", 4}, + {"lab", 3}, + {NULL, 0} +}; + +/* ------------------------ color state ----------------------- */ + +struct pdf_cstate_s +{ + pdf_color fill; + pdf_color stroke; +}; + +void +pdf_init_cstate(PDF *p) +{ + static const char fn[] = "pdf_init_cstate"; + pdf_cstate *cstate; + + if (!p->curr_ppt->cstate) + { + p->curr_ppt->cstate = (pdf_cstate *) pdc_malloc(p->pdc, + PDF_MAX_SAVE_LEVEL * sizeof(pdf_cstate), fn); + } + + cstate = &p->curr_ppt->cstate[p->curr_ppt->sl]; + + cstate->fill.cs = DeviceGray; + cstate->fill.val.gray = 0.0; + + cstate->stroke.cs = DeviceGray; + cstate->stroke.val.gray = 0.0; +} + +void +pdf_save_cstate(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + int sl = ppt->sl; + + memcpy(&ppt->cstate[sl + 1], &ppt->cstate[sl], sizeof(pdf_cstate)); +} + +pdf_color * +pdf_get_cstate(PDF *p, pdf_drawmode mode) +{ + if (mode == pdf_fill) + return &p->curr_ppt->cstate[p->curr_ppt->sl].fill; + else + return &p->curr_ppt->cstate[p->curr_ppt->sl].stroke; +} + +void +pdf_cleanup_page_cstate(PDF *p, pdf_ppt *ppt) +{ + if (ppt->cstate != NULL) + pdc_free(p->pdc, ppt->cstate); + + ppt->cstate = NULL; +} + + + +/* Avoid wrong error messages due to rounding artifacts. + * This doesn't do any harm since we truncate to 5 decimal places anyway + * when producing PDF output. + */ +#define EPSILON ((1.0 + PDF_SMALLREAL)) + +static void pdf_check_color_values(PDF *p, pdf_colorspacetype type, + pdc_scalar c1, pdc_scalar c2, pdc_scalar c3, pdc_scalar c4); + +static int +pdf_color_components(PDF *p, int slot) +{ + static const char *fn = "pdf_color_components"; + pdf_colorspace *cs; + int components = 0; + + cs = &p->colorspaces[slot]; + + switch (cs->type) { + case DeviceGray: + case Indexed: + components = 1; + break; + + case DeviceRGB: + components = 3; + break; + + case DeviceCMYK: + components = 4; + break; + + case PatternCS: + if (cs->val.pattern.base == pdc_undef) + components = 0; /* PaintType 1: colored pattern */ + else + components = pdf_color_components(p, cs->val.pattern.base); + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", slot), + pdc_errprintf(p->pdc, "%d", cs->type), 0); + } + + return components; +} /* pdf_color_components */ + +static void +pdf_write_color_values(PDF *p, pdf_color *color, pdf_drawmode drawmode) +{ + static const char *fn = "pdf_write_color_values"; + pdf_colorspace * cs = &p->colorspaces[color->cs]; + int cs_bias = p->curr_ppt->cs_bias; + int pt_bias = p->curr_ppt->pt_bias; + + switch (cs->type) + { + case DeviceGray: + { + pdc_printf(p->out, "%f", color->val.gray); + + if (drawmode == pdf_fill) + pdc_puts(p->out, " g\n"); + else if (drawmode == pdf_stroke) + pdc_puts(p->out, " G\n"); + + break; + } + + case DeviceRGB: + { + pdc_printf(p->out, "%f %f %f", + color->val.rgb.r, color->val.rgb.g, color->val.rgb.b); + + if (drawmode == pdf_fill) + pdc_puts(p->out, " rg\n"); + else if (drawmode == pdf_stroke) + pdc_puts(p->out, " RG\n"); + + break; + } + + case DeviceCMYK: + { + pdc_printf(p->out, "%f %f %f %f", + color->val.cmyk.c, color->val.cmyk.m, + color->val.cmyk.y, color->val.cmyk.k); + + if (drawmode == pdf_fill) + pdc_puts(p->out, " k\n"); + else if (drawmode == pdf_stroke) + pdc_puts(p->out, " K\n"); + + break; + } + + + case PatternCS: + { + if (drawmode == pdf_fill) + { + if (p->pattern[color->val.pattern].painttype == 1) + { + pdc_puts(p->out, "/Pattern cs"); + } + else if (p->pattern[color->val.pattern].painttype == 2) + { + pdc_printf(p->out, "/C%d cs ", cs_bias + color->cs); + pdf_write_color_values(p, + &p->curr_ppt->cstate[p->curr_ppt->sl].fill, pdf_none); + } + + pdc_printf(p->out, "/P%d scn\n", pt_bias + color->val.pattern); + } + else if (drawmode == pdf_stroke) + { + if (p->pattern[color->val.pattern].painttype == 1) + { + pdc_puts(p->out, "/Pattern CS"); + } + else if (p->pattern[color->val.pattern].painttype == 2) + { + pdc_printf(p->out, "/C%d CS ", cs_bias + color->cs); + pdf_write_color_values(p, + &p->curr_ppt->cstate[p->curr_ppt->sl].stroke, pdf_none); + } + + pdc_printf(p->out, "/P%d SCN\n", pt_bias + color->val.pattern); + } + + p->pattern[color->val.pattern].used_on_current_page = pdc_true; + break; + } + + + case Indexed: /* LATER */ + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", color->cs), + pdc_errprintf(p->pdc, "%d", cs->type), 0); + } +} /* pdf_write_color_values */ + +static pdc_bool +pdf_color_equal(PDF *p, pdf_color *c1, pdf_color *c2) +{ + pdf_colorspace *cs1; + + cs1 = &p->colorspaces[c1->cs]; + + if (c1->cs != c2->cs) + return pdc_false; + + switch (cs1->type) { + case DeviceGray: + return (c1->val.gray == c2->val.gray); + break; + + case DeviceRGB: + return (c1->val.rgb.r == c2->val.rgb.r && + c1->val.rgb.g == c2->val.rgb.g && + c1->val.rgb.b == c2->val.rgb.b); + break; + + case DeviceCMYK: + return (c1->val.cmyk.c == c2->val.cmyk.c && + c1->val.cmyk.m == c2->val.cmyk.m && + c1->val.cmyk.y == c2->val.cmyk.y && + c1->val.cmyk.k == c2->val.cmyk.k); + break; + + case Indexed: + return (c1->val.idx == c2->val.idx); + break; + + case PatternCS: + return (c1->val.pattern == c2->val.pattern); + break; + + + default: + break; + } + + return pdc_true; +} /* pdf_color_equal */ + +static pdc_bool +pdf_colorspace_equal(PDF *p, pdf_colorspace *cs1, pdf_colorspace *cs2) +{ + static const char *fn = "pdf_colorspace_equal"; + + if (cs1->type != cs2->type) + return pdc_false; + + switch (cs1->type) { + case DeviceGray: + case DeviceRGB: + case DeviceCMYK: + return pdc_true; + break; + + + case Indexed: + return ((cs1->val.indexed.base == cs2->val.indexed.base) && + (cs1->val.indexed.palette_size==cs2->val.indexed.palette_size)&& + (cs1->val.indexed.colormap_id != PDC_BAD_ID && + cs1->val.indexed.colormap_id == cs2->val.indexed.colormap_id)); + break; + + case PatternCS: + return (cs1->val.pattern.base == cs2->val.pattern.base); + break; + + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, "(unknown)", + pdc_errprintf(p->pdc, "%d", cs1->type), 0); + } + + return pdc_false; +} /* pdf_colorspace_equal */ + +static void +pdf_grow_colorspaces(PDF *p) +{ + int i; + + p->colorspaces = (pdf_colorspace *) pdc_realloc(p->pdc, p->colorspaces, + sizeof(pdf_colorspace) * 2 * p->colorspaces_capacity, + "pdf_grow_colorspaces"); + + for (i = p->colorspaces_capacity; i < 2 * p->colorspaces_capacity; i++) { + p->colorspaces[i].used_on_current_page = pdc_false; + } + + p->colorspaces_capacity *= 2; +} + +int +pdf_add_colorspace(PDF *p, pdf_colorspace *cs, pdc_bool inuse) +{ + pdf_colorspace *cs_new; + static const char fn[] = "pdf_add_colorspace"; + int slot; + + for (slot = 0; slot < p->colorspaces_number; slot++) + { + if (pdf_colorspace_equal(p, &p->colorspaces[slot], cs)) + { + if (inuse) + p->colorspaces[slot].used_on_current_page = pdc_true; + return slot; + } + } + + slot = p->colorspaces_number; + + if (p->colorspaces_number >= p->colorspaces_capacity) + pdf_grow_colorspaces(p); + + cs_new = &p->colorspaces[slot]; + + cs_new->type = cs->type; + + /* don't allocate id for simple color spaces, since we don't write these */ + if (PDF_SIMPLE_COLORSPACE(cs)) { + cs_new->obj_id = PDC_BAD_ID; + cs_new->used_on_current_page = pdc_false; + + } else { + cs_new->obj_id = pdc_alloc_id(p->out); + cs_new->used_on_current_page = inuse; + } + + switch (cs_new->type) { + case DeviceGray: + case DeviceRGB: + case DeviceCMYK: + break; + + + case Indexed: + { + size_t palsize; /* palette size in bytes */ + + palsize = cs->val.indexed.palette_size * + pdf_color_components(p, cs->val.indexed.base); + + cs_new->val.indexed.base = cs->val.indexed.base; + cs_new->val.indexed.palette_size = cs->val.indexed.palette_size; + cs_new->val.indexed.colormap_id = pdc_alloc_id(p->out); + cs_new->val.indexed.colormap = + (pdf_colormap *) pdc_malloc(p->pdc, palsize, fn); + memcpy(cs_new->val.indexed.colormap, cs->val.indexed.colormap, palsize); + cs_new->val.indexed.colormap_done = pdc_false; + break; + + case PatternCS: + cs_new->val.pattern.base = cs->val.pattern.base; + break; + } + + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", slot), + pdc_errprintf(p->pdc, "%d", cs_new->type), 0); + } + + p->colorspaces_number++; + + return slot; +} /* pdf_add_colorspace */ + + +static void +pdf_set_color_values(PDF *p, pdf_color *c, pdf_drawmode drawmode) +{ + pdf_color *current; + pdf_colorspace *cs; + + cs = &p->colorspaces[c->cs]; + + if (drawmode == pdf_stroke || drawmode == pdf_fillstroke) + { + current = &p->curr_ppt->cstate[p->curr_ppt->sl].stroke; + + if (!pdf_color_equal(p, current, c) || PDF_FORCE_OUTPUT()) + { + if (PDF_GET_STATE(p) != pdf_state_document) + pdf_write_color_values(p, c, pdf_stroke); + + *current = *c; + } + } + if (drawmode == pdf_fill || drawmode == pdf_fillstroke) + { + current = &p->curr_ppt->cstate[p->curr_ppt->sl].fill; + + if (!pdf_color_equal(p, current, c) || PDF_FORCE_OUTPUT()) + { + if (PDF_GET_STATE(p) != pdf_state_document) + pdf_write_color_values(p, c, pdf_fill); + + *current = *c; + } + } + + /* simple colorspaces don't get written */ + if (!PDF_SIMPLE_COLORSPACE(cs)) + cs->used_on_current_page = pdc_true; + +} /* pdf_set_color_values */ + +void +pdf_init_colorspaces(PDF *p) +{ + int i, slot; + pdf_colorspace cs; + + + p->colorspaces_number = 0; + p->colorspaces_capacity = COLORSPACES_CHUNKSIZE; + + p->colorspaces = (pdf_colorspace *) + pdc_malloc(p->pdc, sizeof(pdf_colorspace) * p->colorspaces_capacity, + "pdf_init_colorspaces"); + + for (i = 0; i < p->colorspaces_capacity; i++) { + p->colorspaces[i].used_on_current_page = pdc_false; + } + + /* + * Initialize a few slots with simple color spaces for easier use. + * These can be used without further ado: the slot number is identical + * to the enum value due to the ordering below. + */ + + cs.type = DeviceGray; + slot = pdf_add_colorspace(p, &cs, pdc_false); + cs.type = DeviceRGB; + slot = pdf_add_colorspace(p, &cs, pdc_false); + cs.type = DeviceCMYK; + slot = pdf_add_colorspace(p, &cs, pdc_false); + +} /* pdf_init_colorspaces */ + +void +pdf_write_page_colorspaces(PDF *p) +{ + int i, total = 0; + int bias = p->curr_ppt->cs_bias; + + for (i = 0; i < p->colorspaces_number; i++) + if (p->colorspaces[i].used_on_current_page) + total++; + + if (total > 0 || bias + ) + { + pdc_puts(p->out, "/ColorSpace"); + pdc_begin_dict(p->out); + + if (total > 0) + { + for (i = 0; i < p->colorspaces_number; i++) + { + pdf_colorspace *cs = &p->colorspaces[i]; + + if (cs->used_on_current_page) + { + cs->used_on_current_page = pdc_false; /* reset */ + + /* don't write simple color spaces as resource */ + if (!PDF_SIMPLE_COLORSPACE(cs)) + { + pdc_printf(p->out, "/C%d", bias + i); + pdc_objref(p->out, "", cs->obj_id); + } + } + } + } + + + if (!bias) + pdc_end_dict(p->out); /* color space names */ + } +} /* pdf_write_page_colorspaces */ + +void +pdf_get_page_colorspaces(PDF *p, pdf_reslist *rl) +{ + int i; + + for (i = 0; i < p->colorspaces_number; i++) + { + pdf_colorspace *cs = &p->colorspaces[i]; + + if (cs->used_on_current_page) + { + cs->used_on_current_page = pdc_false; + + if (!PDF_SIMPLE_COLORSPACE(cs)) + pdf_add_reslist(p, rl, i); + } + } +} + +void +pdf_mark_page_colorspace(PDF *p, int n) +{ + p->colorspaces[n].used_on_current_page = pdc_true; +} + +void +pdf_write_function_dict(PDF *p, pdf_color *c0, pdf_color *c1, pdc_scalar N) +{ + static const char *fn = "pdf_write_function_dict"; + + pdf_colorspace *cs; + + cs = &p->colorspaces[c1->cs]; + + pdc_begin_dict(p->out); /* function dict */ + + pdc_puts(p->out, "/FunctionType 2\n"); + pdc_puts(p->out, "/Domain[0 1]\n"); + pdc_printf(p->out, "/N %f\n", N); + + switch (cs->type) { + + case DeviceGray: + pdc_puts(p->out, "/Range[0 1]\n"); + if (c0->val.gray != 0) pdc_printf(p->out, "/C0[%f]\n", c0->val.gray); + if (c1->val.gray != 1) pdc_printf(p->out, "/C1[%f]", c1->val.gray); + break; + + case DeviceRGB: + pdc_puts(p->out, "/Range[0 1 0 1 0 1]\n"); + pdc_printf(p->out, "/C0[%f %f %f]\n", + c0->val.rgb.r, c0->val.rgb.g, c0->val.rgb.b); + pdc_printf(p->out, "/C1[%f %f %f]", + c1->val.rgb.r, c1->val.rgb.g, c1->val.rgb.b); + break; + + case DeviceCMYK: + pdc_puts(p->out, "/Range[0 1 0 1 0 1 0 1]\n"); + pdc_printf(p->out, "/C0[%f %f %f %f]\n", + c0->val.cmyk.c, c0->val.cmyk.m, c0->val.cmyk.y, c0->val.cmyk.k); + pdc_printf(p->out, "/C1[%f %f %f %f]", + c1->val.cmyk.c, c1->val.cmyk.m, c1->val.cmyk.y, c1->val.cmyk.k); + break; + + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, "(unknown)", + pdc_errprintf(p->pdc, "%d", cs->type), 0); + } + + pdc_end_dict_c(p->out); /* function dict */ +} /* pdf_write_function_dict */ + +void +pdf_write_colormap(PDF *p, int slot) +{ + PDF_data_source src; + pdf_colorspace *cs, *base; + pdc_id length_id; + + cs = &p->colorspaces[slot]; + + if (cs->type != Indexed || cs->val.indexed.colormap_done == pdc_true) + return; + + base = &p->colorspaces[cs->val.indexed.base]; + + pdc_begin_obj(p->out, cs->val.indexed.colormap_id); /* colormap object */ + pdc_begin_dict(p->out); + + if (pdc_get_compresslevel(p->out)) + pdc_puts(p->out, "/Filter/FlateDecode\n"); + + /* Length of colormap object */ + length_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Length", length_id); + pdc_end_dict(p->out); + + src.init = NULL; + src.fill = pdf_data_source_buf_fill; + src.terminate = NULL; + + src.buffer_start = (unsigned char *) cs->val.indexed.colormap; + + src.buffer_length = (size_t) (cs->val.indexed.palette_size * + pdf_color_components(p, cs->val.indexed.base)); + + src.bytes_available = 0; + src.next_byte = NULL; + + /* Write colormap data */ + pdf_copy_stream(p, &src, pdc_true); /* colormap data */ + + pdc_end_obj(p->out); /* colormap object */ + + pdc_put_pdfstreamlength(p->out, length_id); + + /* free the colormap now that it's written */ + pdc_free(p->pdc, cs->val.indexed.colormap); + cs->val.indexed.colormap = NULL; + cs->val.indexed.colormap_done = pdc_true; +} /* pdf_write_colormap */ + +void +pdf_write_colorspace(PDF *p, int slot, pdc_bool direct) +{ + static const char *fn = "pdf_write_colorspace"; + + pdf_colorspace *cs; + int base; + + if (slot < 0 || slot >= p->colorspaces_number) + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", slot), + "(unknown)", 0); + + cs = &p->colorspaces[slot]; + + /* we always write simple colorspaces directly */ + if (PDF_SIMPLE_COLORSPACE(cs)) + direct = pdc_true; + + if (!direct) { + pdc_objref_c(p->out, cs->obj_id); + return; + } + + switch (cs->type) { + case DeviceGray: + pdc_printf(p->out, "/DeviceGray"); + break; + + case DeviceRGB: + pdc_printf(p->out, "/DeviceRGB"); + break; + + case DeviceCMYK: + pdc_printf(p->out, "/DeviceCMYK"); + break; + + + case Indexed: + base = cs->val.indexed.base; + + pdc_begin_array(p->out); + pdc_puts(p->out, "/Indexed"); + + pdf_write_colorspace(p, base, pdc_false); + + pdc_printf(p->out, " %d", cs->val.indexed.palette_size - 1); + pdc_objref_c(p->out, cs->val.indexed.colormap_id); + pdc_end_array_c(p->out); + break; + + case PatternCS: + pdc_begin_array(p->out); + pdc_printf(p->out, "/Pattern"); + pdf_write_colorspace(p, cs->val.pattern.base, pdc_false); + pdc_end_array(p->out); + break; + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", slot), + pdc_errprintf(p->pdc, "%d", cs->type), 0); + } +} /* pdf_write_colorspace */ + +void +pdf_write_doc_colorspaces(PDF *p) +{ + int i; + + for (i = 0; i < p->colorspaces_number; i++) { + pdf_colorspace *cs = &p->colorspaces[i]; + + /* don't write simple color spaces as resource */ + if (PDF_SIMPLE_COLORSPACE(cs)) + continue; + + pdc_begin_obj(p->out, cs->obj_id); + pdf_write_colorspace(p, i, pdc_true); + pdc_puts(p->out, "\n"); + pdc_end_obj(p->out); /* color space resource */ + + pdf_write_colormap(p, i); /* write pending colormaps */ + } +} + +void +pdf_cleanup_colorspaces(PDF *p) +{ + static const char *fn = "pdf_cleanup_colorspaces"; + + int i; + + if (!p->colorspaces) + return; + + for (i = 0; i < p->colorspaces_number; i++) { + pdf_colorspace *cs = &p->colorspaces[i];; + + switch (cs->type) { + case DeviceGray: + case DeviceRGB: + case DeviceCMYK: + case PatternCS: + break; + + case Indexed: + if (cs->val.indexed.colormap) + pdc_free(p->pdc, cs->val.indexed.colormap); + break; + + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", i), + pdc_errprintf(p->pdc, "%d", cs->type), 0); + } + } + + pdc_free(p->pdc, p->colorspaces); + p->colorspaces = NULL; +} + + + + + +static void +pdf_check_color_values( + PDF *p, + pdf_colorspacetype type, + pdc_scalar c1, pdc_scalar c2, pdc_scalar c3, pdc_scalar c4) +{ + switch (type) { + case DeviceGray: + pdc_check_number_limits(p->pdc, "c1", c1, 0.0, EPSILON); + break; + + case DeviceRGB: + pdc_check_number_limits(p->pdc, "c1", c1, 0.0, EPSILON); + pdc_check_number_limits(p->pdc, "c2", c2, 0.0, EPSILON); + pdc_check_number_limits(p->pdc, "c3", c3, 0.0, EPSILON); + + break; + + case DeviceCMYK: + pdc_check_number_limits(p->pdc, "c1", c1, 0.0, EPSILON); + pdc_check_number_limits(p->pdc, "c2", c2, 0.0, EPSILON); + pdc_check_number_limits(p->pdc, "c3", c3, 0.0, EPSILON); + pdc_check_number_limits(p->pdc, "c4", c4, 0.0, EPSILON); + break; + + + + case PatternCS: + pdf_check_handle(p, (int) c1, pdc_patternhandle); + if (c1 == p->pattern_number - 1 && PDF_GET_STATE(p) & pdf_state_pattern) + { + pdc_error(p->pdc, PDF_E_PATTERN_SELF, 0, 0, 0, 0); + } + break; + + case Separation: + pdf_check_handle(p, (int) c1, pdc_colorhandle); + pdc_check_number_limits(p->pdc, "c2", c2, 0.0, EPSILON); + break; + + case Indexed: + default: + break; + } +} /* pdf_check_color_values */ + +static void +pdf_setcolor_internal(PDF *p, int drawmode, int colortype, + pdc_scalar c1, pdc_scalar c2, pdc_scalar c3, pdc_scalar c4, + pdf_color *fcolor) +{ + pdf_color c; + pdf_colorspace cs; + + /* TODO: synchronize the PDF/X checks below with pdf_check_pdfx_colorspaces + */ + switch (colortype) + { + case color_gray: + cs.type = DeviceGray; + c.cs = cs.type; + c.val.gray = c1; + pdf_check_color_values(p, cs.type, c1, c2, c3, c4); + break; + + case color_rgb: + cs.type = DeviceRGB; + c.cs = cs.type; + c.val.rgb.r = c1; + c.val.rgb.g = c2; + c.val.rgb.b = c3; + pdf_check_color_values(p, cs.type, c1, c2, c3, c4); + break; + + case color_cmyk: + cs.type = DeviceCMYK; + c.cs = cs.type; + c.val.cmyk.c = c1; + c.val.cmyk.m = c2; + c.val.cmyk.y = c3; + c.val.cmyk.k = c4; + pdf_check_color_values(p, cs.type, c1, c2, c3, c4); + break; + + + case color_pattern: + cs.type = PatternCS; + if (p->pdc->hastobepos) c1 -= 1; + c.val.pattern = (int) c1; + pdf_check_color_values(p, cs.type, c1, c2, c3, c4); + + if (p->pattern[c.val.pattern].painttype == 1) + { + cs.val.pattern.base = pdc_undef; + c.cs = pdf_add_colorspace(p, &cs, pdc_false); + } + else + { + cs.val.pattern.base = p->curr_ppt->cstate[p->curr_ppt->sl].fill.cs; + c.cs = pdf_add_colorspace(p, &cs, pdc_true); + } + break; + + } + + + + if (fcolor == NULL) + pdf_set_color_values(p, &c, (pdf_drawmode) drawmode); + else + *fcolor = c; +} + +static const pdc_keyconn pdf_fstype_keylist[] = +{ + {"stroke", pdf_stroke}, + {"fill", pdf_fill}, + {"fillstroke", pdf_stroke | pdf_fill}, + {"both", pdf_stroke | pdf_fill}, + {NULL, 0} +}; + +void +pdf__setcolor( + PDF *p, + const char *fstype, + const char *colorspace, + pdc_scalar c1, pdc_scalar c2, pdc_scalar c3, pdc_scalar c4) +{ + int drawmode = (int) pdf_none; + int colortype; + + if (!fstype || !*fstype) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fstype", 0, 0, 0); + + if (!colorspace || !*colorspace) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "colorspace", 0, 0, 0); + + drawmode = pdc_get_keycode_ci(fstype, pdf_fstype_keylist); + if (drawmode == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "fstype", fstype, 0, 0); + + colortype = pdc_get_keycode_ci(colorspace, pdf_colortype_keylist); + if (colortype == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "colorspace", colorspace, 0, 0); + + pdf_setcolor_internal(p, drawmode, colortype, c1, c2, c3, c4, NULL); +} + +void +pdf_set_default_color(PDF *p, pdc_bool reset) +{ + + + + if (reset) + pdf__setcolor(p, "fillstroke", "gray", 0, 0, 0, 0); +} + + +void +pdf_parse_coloropt(PDF *p, const char *optname, char **optvalue, int ns, + int maxtype, pdf_coloropt *c) +{ + int errcode = 0; + const char *stemp = NULL; + + if (ns) + { + int i, j, n, iz = 0; + double dz; + + c->type = pdc_get_keycode_ci(optvalue[0], pdf_colortype_keylist); + if (c->type == PDC_KEY_NOTFOUND || c->type > maxtype) + { + stemp = pdc_errprintf(p->pdc, + "%.*s", PDC_ERR_MAXSTRLEN, optvalue[0]); + errcode = PDC_E_OPT_ILLKEYWORD; + goto PDF_COLOPT_ERROR; + } + + if (c->type == (int) color_spotname || c->type == (int) color_spot) + { + errcode = PDF_E_UNSUPP_SPOTCOLOR; + goto PDF_COLOPT_ERROR; + } + + n = 1 + pdc_get_keycode_ci(optvalue[0], pdf_colorcomp_keylist); + if (n != ns) + { + if (c->type == (int) color_spotname) + n++; + if (n != ns) + { + stemp = pdc_errprintf(p->pdc, "%d", n); + errcode = n < ns ? PDC_E_OPT_TOOMANYVALUES : + PDC_E_OPT_TOOFEWVALUES; + goto PDF_COLOPT_ERROR; + } + } + + for (i = 0; i < 4; i++) + { + j = i + 1; + if (i >= ns - 1) + { + if (!i || c->type != (int) color_gray) + c->value[i] = 0.0; + else + c->value[i] = c->value[0]; + } + else + { + if (!i && (c->type >= (int) color_spotname && + c->type <= (int) color_pattern)) + { + c->name[0] =0; + if (pdc_str2integer(optvalue[j], 0, (pdc_sint32 *) &iz) == + pdc_false) + { + { + stemp = pdc_errprintf(p->pdc, "%.*s", + PDC_ERR_MAXSTRLEN, optvalue[j]); + errcode = PDC_E_OPT_ILLNUMBER; + goto PDF_COLOPT_ERROR; + } + } + c->value[i] = iz; + } + else + { + if (pdc_str2double(optvalue[j], &dz) == pdc_false) + { + stemp = pdc_errprintf(p->pdc, "%.*s", + PDC_ERR_MAXSTRLEN, optvalue[j]); + errcode = PDC_E_OPT_ILLNUMBER; + goto PDF_COLOPT_ERROR; + } + else + c->value[i] = dz; + } + } + } + + if (c->type <= (int) color_cmyk) + { + for (i = 0; i < ns - 1; i++) + { + if (c->value[i] < 0 || c->value[i] > EPSILON) + { + stemp = pdc_errprintf(p->pdc, "%f", c->value[i]); + errcode = PDC_E_OPT_ILLNUMBER; + goto PDF_COLOPT_ERROR; + } + } + } + } + + PDF_COLOPT_ERROR: + + if (errcode) + pdc_error(p->pdc, errcode, optname, stemp, 0, 0); +} + + +void +pdf_set_coloropt(PDF *p, int drawmode, pdf_coloropt *c) +{ + if (c->type == (int) color_none) + return; + if (c->type == (int) color_spotname) + { + pdc_error(p->pdc, PDF_E_UNSUPP_SPOTCOLOR, 0, 0, 0, 0); + } + + pdf_setcolor_internal(p, drawmode, c->type, + c->value[0], c->value[1], c->value[2], c->value[3], + NULL); +} + +void +pdf_init_coloropt(PDF *p, pdf_coloropt *c) +{ + (void) p; + + { + c->name[0] = 0; + c->type = (int) color_gray; + c->value[0] = 0; + c->value[1] = 0; + c->value[2] = 0; + c->value[3] = 0; + } +} + +void +pdf_logg_coloropt(PDF *p, pdf_coloropt *c, pdc_bool newline) +{ + const char *keyword = + pdc_get_keyword((int) c->type, pdf_colortype_keylist); + + pdc_logg(p->pdc, "{%s ", keyword); + + switch (c->type) + { + case color_gray: + case color_iccbasedgray: + case color_pattern: + case color_spot: + pdc_logg(p->pdc, "%g}", c->value[0]); + break; + + case color_rgb: + case color_iccbasedrgb: + case color_lab: + pdc_logg(p->pdc, "%g %g %g}", c->value[0], c->value[1], c->value[2]); + break; + + case color_cmyk: + case color_iccbasedcmyk: + pdc_logg(p->pdc, "%g %g %g %g}", c->value[0], c->value[1], + c->value[2], c->value[3]); + break; + + case color_spotname: + pdc_logg(p->pdc, "{%s} %g}", c->name, c->value[0]); + break; + + default: + pdc_logg(p->pdc, "}"); + break; + } + + if (newline) + pdc_logg(p->pdc, "\n"); +} diff --git a/src/pdflib/pdflib/p_color.h b/src/pdflib/pdflib/p_color.h new file mode 100644 index 0000000..d8a0fa8 --- /dev/null +++ b/src/pdflib/pdflib/p_color.h @@ -0,0 +1,109 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_color.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib color definitions + * + */ + +#ifndef P_COLOR_H +#define P_COLOR_H + +/* + * These are treated specially in the global colorspace list, and are not + * written as /ColorSpace resource since we always specify them directly. + * Pattern colorspace with base == pdc_undef means PaintType == 1. + */ +#define PDF_SIMPLE_COLORSPACE(cs) \ + ((cs)->type == DeviceGray || \ + (cs)->type == DeviceRGB || \ + (cs)->type == DeviceCMYK || \ + ((cs)->type == PatternCS && cs->val.pattern.base == pdc_undef)) + + +struct pdf_pattern_s { + pdc_id obj_id; /* object id of this pattern */ + int painttype; /* colored (1) or uncolored (2) */ + pdc_bool used_on_current_page; /* this pattern used on current page */ +}; + +typedef pdc_byte pdf_colormap[256][3]; + +typedef struct { + int cs; /* slot of underlying color space */ + + union { + pdc_scalar gray; /* DeviceGray */ + int pattern; /* Pattern */ + int idx; /* Indexed */ + struct { /* DeviceRGB */ + pdc_scalar r; + pdc_scalar g; + pdc_scalar b; + } rgb; + struct { /* DeviceCMYK */ + pdc_scalar c; + pdc_scalar m; + pdc_scalar y; + pdc_scalar k; + } cmyk; + } val; +} pdf_color; + +struct pdf_colorspace_s { + pdf_colorspacetype type; /* color space type */ + + union { + struct { /* Indexed */ + int base; /* base color space */ + pdf_colormap *colormap; /* pointer to colormap */ + pdc_bool colormap_done; /* colormap already written to output */ + int palette_size; /* # of palette entries (not bytes!) */ + pdc_id colormap_id; /* object id of colormap */ + } indexed; + + struct { /* Pattern */ + int base; /* base color space for PaintType 2 */ + } pattern; + + } val; + + pdc_id obj_id; /* object id of this colorspace */ + pdc_bool used_on_current_page; /* this resource used on current page */ +}; + +/* "color" option */ +typedef struct +{ + char name[PDF_MAX_NAMESTRING + 1]; + int type; + pdc_scalar value[4]; +} +pdf_coloropt; + + +pdf_color *pdf_get_cstate(PDF *p, pdf_drawmode mode); +void pdf_get_page_colorspaces(PDF *p, pdf_reslist *rl); +void pdf_write_function_dict(PDF *p, pdf_color *c0, pdf_color *c1, + pdc_scalar N); +int pdf_add_colorspace(PDF *p, pdf_colorspace *cs, pdc_bool inuse); +void pdf_parse_coloropt(PDF *p, const char *optname, char **optvalue, int ns, + int maxtype, pdf_coloropt *c); +void pdf_set_coloropt(PDF *p, int drawmode, pdf_coloropt *c); +void pdf_init_coloropt(PDF *p, pdf_coloropt *c); +void pdf_logg_coloropt(PDF *p, pdf_coloropt *c, pdc_bool newline); + + + +#endif /* P_COLOR_H */ + diff --git a/src/pdflib/pdflib/p_defopt.h b/src/pdflib/pdflib/p_defopt.h new file mode 100644 index 0000000..6c4a862 --- /dev/null +++ b/src/pdflib/pdflib/p_defopt.h @@ -0,0 +1,494 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_defopt.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib shared option definitions and structures + * + */ + +#ifndef P_DEFOPT_H +#define P_DEFOPT_H + +#define PDF_KEEP_TEXTLEN (1L<<0) /* keep text length */ +#define PDF_KEEP_CONTROL (1L<<1) /* keep special control character */ +#define PDF_KEEP_UNICODE (1L<<2) /* keep Unicode text */ +#define PDF_FORCE_NEWALLOC (1L<<3) /* force alloc for new text */ +#define PDF_USE_TMPALLOC (1L<<4) /* use temporary memory */ + +#define PDF_RETURN_BOXEMPTY "_boxempty" +#define PDF_RETURN_BOXFULL "_boxfull" +#define PDF_RETURN_NEXTPAGE "_nextpage" +#define PDF_RETURN_STOP "_stop" + +typedef enum +{ + is_block = (1L<<0), + is_image = (1L<<1), + is_textline = (1L<<2), + is_textflow = (1L<<3), + is_inline = (1L<<4) +} +pdf_elemflags; + +struct pdf_text_options_s +{ + pdc_scalar charspacing; + pdc_scalar charspacing_pc; + pdf_coloropt fillcolor; + int font; + pdc_scalar fontsize; + pdc_scalar fontsize_pc; + int fontsize_st; + pdc_bool glyphwarning; + pdc_scalar horizscaling; + pdc_scalar italicangle; + pdc_bool fakebold; + pdc_bool kerning; + unsigned int mask; + unsigned int pcmask; + unsigned int fontset; + pdc_bool overline; + pdc_bool strikeout; + pdf_coloropt strokecolor; + pdc_scalar strokewidth; + pdc_scalar dasharray[2]; + char *text; + int textlen; + pdc_text_format textformat; + int textrendering; + pdc_scalar textrise; + pdc_scalar textrise_pc; + pdc_scalar leading; + pdc_scalar leading_pc; + pdc_bool underline; + pdc_scalar wordspacing; + pdc_scalar wordspacing_pc; + pdc_scalar underlinewidth; + pdc_scalar underlineposition; + pdc_scalar *xadvancelist; + int nglyphs; + char *link; + char *linktype; + pdc_bool charref; + pdc_bool escapesequence; + pdc_glyphcheck glyphcheck; +}; + +typedef enum +{ + xo_filename, + xo_ignoreorientation, + xo_imagewarning, + xo_dpi, + xo_page, + xo_scale +} +pdf_xobject_optflags; + +typedef struct +{ + pdc_bool adjustpage; + pdc_bool blind; + char *filename; + int flags; + pdc_bool imagewarning; + pdc_bool ignoreorientation; + unsigned int mask; + int im; + int page; + pdc_scalar dpi[2]; + pdc_scalar scale[2]; +} +pdf_xobject_options; + +typedef enum +{ + fit_boxsize, + fit_fitmethod, + fit_margin, + fit_shrinklimit, + fit_position, + fit_orientate, + fit_rotate, + fit_matchbox, + fit_alignchar, + fit_refpoint +} +pdf_fit_optflags; + + +typedef struct +{ + pdc_scalar boxsize[2]; + pdc_fitmethod fitmethod; + int flags; + pdc_scalar margin[2]; + unsigned int mask; + unsigned int pcmask; + pdc_scalar shrinklimit; + pdc_scalar position[2]; + int orientate; + pdc_scalar refpoint[2]; + pdc_scalar rotate; + pdc_bool showborder; + pdf_mbox *matchbox; + pdc_ushort alignchar; +} +pdf_fit_options; + +typedef struct pdf_fittext_s pdf_fittext; + + +/* font option definitions */ + +#define PDF_KERNING_FLAG PDC_OPT_UNSUPP +#define PDF_SUBSETTING_FLAG PDC_OPT_UNSUPP +#define PDF_AUTOCIDFONT_FLAG PDC_OPT_UNSUPP +#define PDF_EMBEDOPENTYPE_FLAG PDC_OPT_UNSUPP +#define PDF_CHARREF_FLAG PDC_OPT_UNSUPP +#define PDF_ESCAPESEQU_FLAG PDC_OPT_UNSUPP +#define PDF_GLYPHCHECK_FLAG PDC_OPT_UNSUPP +#define PDF_VERTICAL_FLAG PDC_OPT_UNSUPP +#define PDF_REPLCHAR_FLAG PDC_OPT_UNSUPP +#define PDF_KEEPNATIVE_FLAG PDC_OPT_UNSUPP +#define PDF_STAMP_FLAG PDC_OPT_UNSUPP +#define PDF_LEADER_FLAG PDC_OPT_UNSUPP + +#define PDF_METADATA_FLAG PDC_OPT_UNSUPP + +#define PDF_CLIPPATH_FLAG PDC_OPT_UNSUPP + +#define PDF_FONT_OPTIONS1 \ +\ + {"encoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"fontname", pdc_stringlist, PDC_OPT_NONE | PDC_OPT_CONVUTF8, 1, 1, \ + 1.0, PDF_MAX_FONTNAME, NULL}, \ + + +#define PDF_FONT_OPTIONS2 \ +\ + {"autocidfont", pdc_booleanlist, PDF_AUTOCIDFONT_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"autosubsetting", pdc_booleanlist, PDF_SUBSETTING_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"embedding", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"fontstyle", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_fontstyle_pdfkeylist}, \ +\ + /* deprecated */ \ + {"fontwarning", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"monospace", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + 1.0, FNT_MAX_METRICS, NULL}, \ +\ + {"ascender", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + -FNT_MAX_METRICS, FNT_MAX_METRICS, NULL}, \ +\ + {"descender", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + -FNT_MAX_METRICS, FNT_MAX_METRICS, NULL}, \ +\ + {"capheight", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + -FNT_MAX_METRICS, FNT_MAX_METRICS, NULL}, \ +\ + {"xheight", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + -FNT_MAX_METRICS, FNT_MAX_METRICS, NULL}, \ +\ + {"linegap", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + -FNT_MAX_METRICS, FNT_MAX_METRICS, NULL}, \ +\ + {"subsetlimit", pdc_doublelist, PDF_SUBSETTING_FLAG|PDC_OPT_PERCENT, 1, 1, \ + 0.0, 100.0, NULL}, \ +\ + {"subsetminsize", pdc_doublelist, PDF_SUBSETTING_FLAG, 1, 1, \ + 0.0, PDC_FLOAT_MAX, NULL}, \ +\ + {"subsetting", pdc_booleanlist, PDF_SUBSETTING_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"unicodemap", pdc_booleanlist, PDF_AUTOCIDFONT_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"embedopentype", pdc_booleanlist, PDF_EMBEDOPENTYPE_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"keepnative", pdc_booleanlist, PDF_KEEPNATIVE_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"vertical", pdc_booleanlist, PDF_VERTICAL_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"replacementchar", pdc_unicharlist, PDF_REPLCHAR_FLAG, 1, 1, \ + 0.0, PDC_MAX_UNIVAL, NULL}, \ +\ + {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ + + +#define PDF_FONT_OPTIONS3 \ +\ + {"kerning", pdc_booleanlist, PDF_KERNING_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ + + +/* text option definitions */ + +#define PDF_TEXT_OPTIONS \ +\ + {"charspacing", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, \ +\ + /* deprecated */ \ + {"glyphwarning", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"fillcolor", pdc_stringlist, PDC_OPT_NONE, 1, 5, \ + 0.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"font", pdc_fonthandle, PDC_OPT_NONE, 1, 1, \ + 0, 0, NULL}, \ +\ + {"fontsize", pdc_scalarlist, \ + PDC_OPT_PERCENT | PDC_OPT_SUBOPTLIST | PDC_OPT_KEYLIST1, 1, 2, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, pdf_fontsize_keylist}, \ +\ + {"horizscaling", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, \ +\ + {"italicangle", pdc_scalarlist, PDC_OPT_NONE, 1, 1, \ + -89.99, 89.99, NULL}, \ +\ + {"fakebold", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"kerning", pdc_booleanlist, PDF_KERNING_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"overline", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"strikeout", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"strokecolor", pdc_stringlist, PDC_OPT_NONE, 1, 5, \ + 0.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"strokewidth", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, \ + 0.0, PDC_FLOAT_MAX, pdf_underlinewidth_keylist}, \ +\ + {"dasharray", pdc_scalarlist, PDC_OPT_NONE, 1, 2, \ + 0.0, PDC_FLOAT_MAX, NULL}, \ +\ + {"textformat", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_textformat_keylist}, \ +\ + {"textrendering", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + 0, PDF_LAST_TRMODE, NULL}, \ +\ + {"textrise", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, \ +\ + {"underline", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"wordspacing", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, \ +\ + {"underlinewidth", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, \ + 0.0, PDC_FLOAT_MAX, pdf_underlinewidth_keylist}, \ +\ + {"underlineposition", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, pdf_underlineposition_keylist}, \ +\ + /* deprecated */ \ + {"weblink", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + /* deprecated */ \ + {"locallink", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + /* deprecated */ \ + {"pdflink", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"charref", pdc_booleanlist, PDF_CHARREF_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"escapesequence", pdc_booleanlist, PDF_ESCAPESEQU_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"glyphcheck", pdc_keywordlist, PDF_GLYPHCHECK_FLAG, 1, 1, \ + 0.0, 0.0, pdf_glyphcheck_keylist}, \ +\ + + +/* xobject option definitions */ + +#define PDF_XOBJECT_OPTIONS1 \ +\ + {"adjustpage", pdc_booleanlist, PDC_OPT_PDC_1_3, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"blind", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ + + +#define PDF_XOBJECT_OPTIONS2 \ +\ + {"ignoreorientation", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"ignoreclippingpath", pdc_booleanlist, PDF_CLIPPATH_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + /* deprecated */ \ + {"imagewarning", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"dpi", pdc_scalarlist, PDC_OPT_NONE, 1, 2, \ + 0.0, PDC_INT_MAX, pdf_dpi_keylist}, \ + + +#define PDF_XOBJECT_OPTIONS3 \ +\ + {"scale", pdc_scalarlist, PDC_OPT_NOZERO, 1, 2, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, \ + + +/* general fit option definitions */ + +#define PDF_FIT_OPTIONS1 \ +\ + {"boxsize", pdc_scalarlist, PDC_OPT_NONE, 2, 2, \ + 0, PDC_FLOAT_MAX, NULL}, \ +\ + {"margin", pdc_scalarlist, PDC_OPT_NONE, 1, 2, \ + 0, PDC_FLOAT_MAX, NULL}, \ +\ + {"shrinklimit", pdc_scalarlist, PDC_OPT_PERCENT | PDC_OPT_PERCRANGE, 1, 1, \ + 0.0, 100.0, NULL}, \ +\ + {"position", pdc_scalarlist, PDC_OPT_NONE, 1, 2, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, pdf_position_keylist}, \ +\ + {"matchbox", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ + + +#define PDF_FIT_OPTIONS2 \ +\ + {"fitmethod", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_fitmethod_keylist}, \ +\ + {"rotate", pdc_scalarlist, PDC_OPT_NONE, 1, 1, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, \ +\ + {"orientate", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_orientate_keylist}, \ +\ + {"showborder", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ + + +#define PDF_FIT_OPTIONS6 \ +\ + {"alignchar", pdc_unicharlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_USHRT_MAX, pdf_charname_keylist}, \ +\ + {"stamp", pdc_keywordlist, PDF_STAMP_FLAG, 1, 1, \ + 0.0, 0.0, pdf_stampdir_keylist}, \ +\ + {"leader", pdc_stringlist, PDF_LEADER_FLAG, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ + + +#define PDF_FIT_OPTIONS3 \ +\ + {"refpoint", pdc_scalarlist, PDC_OPT_NONE, 2, 2, \ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, \ + + + +/* p_font.c */ +void pdf_get_font_options(PDF *p, pdf_font_options *fo, pdc_resopt *resopts); +int pdf_load_font_internal(PDF *p, pdf_font_options *fo); + +/* p_image.c */ +void pdf_init_xobject_options(PDF *p, pdf_xobject_options *xo); +void pdf_get_xobject_options(PDF *p, pdf_xobject_options *xo, + pdc_resopt *resopts); +pdc_resopt *pdf_parse_fitxobject_optlist(PDF *p, int im, + pdf_xobject_options *xo, pdf_fit_options *fit, const char *optlist); +void pdf_fit_xobject_internal(PDF *p, pdf_xobject_options *xo, + pdf_fit_options *fit, pdc_matrix *immatrix); + +/* p_mbox.c */ +void pdf_init_fit_options(PDF *p, pdc_bool fortflow, pdf_fit_options *fit); +void pdf_cleanup_fit_options(PDF *p, pdf_fit_options *fit); +void pdf_get_fit_options(PDF *p, pdc_bool fortflow, pdf_fit_options *fit, + pdc_resopt *resopts); +void pdf_get_mbox_boxheight(PDF *p, pdf_mbox *mbox, + pdc_scalar *boxheight); +pdc_bool pdf_get_mbox_clipping(PDF *p, pdf_mbox *mbox, + pdc_scalar width, pdc_scalar height, pdc_box *clipbox); +double pdf_get_mbox_info(PDF *p, pdf_mbox *mbox, const char *keyword); + +/* p_text.c */ +pdc_bool pdf_calculate_text_options(PDF *p, pdf_text_options *to, + pdc_bool force, pdc_scalar fontscale, pdc_scalar minfontsize, + pdc_scalar fontsizeref); +void pdf_set_text_options(PDF *p, pdf_text_options *to); +void pdf_init_text_options(PDF *p, pdf_text_options *to); +void pdf_get_text_options(PDF *p, pdf_text_options *to, pdc_resopt *resopts); +pdc_resopt *pdf_parse_fittextline_optlist(PDF *p, pdf_text_options *to, + pdf_fit_options *fit, const char *optlist); +int pdf_fit_textline_internal(PDF *p, pdf_fittext *fitres, + pdf_text_options *to, pdf_fit_options *fit, pdc_matrix *matrix); +void pdf_calculate_textline_size(PDF *p, pdf_text_options *to, + pdf_fit_options *fit, pdc_scalar *width, pdc_scalar *height); +pdc_bool pdf_is_horiz_orientated(pdf_fit_options *fit); +int pdf_calculate_leader_pos(PDF *p, pdf_alignment alignment, + pdf_text_options *to, int nchars,pdc_scalar *xstart, pdc_scalar *xstop, + pdc_scalar width, pdc_bool left); +void pdf_draw_leader_text(PDF *p, pdc_scalar xstart, pdc_scalar ybase, + pdc_scalar width, int nchars, pdc_byte *utext, int len, int charlen, + pdf_text_options *to); + +int pdf_get_approximate_uvlist(PDF *p, pdf_font *currfont, + pdc_encodingvector *ev, int usv, pdc_bool replace, pdc_ushort *uvlist, + pdc_ushort *cglist); +void pdf_get_input_textformat(pdf_font *currfont, + pdc_text_format *intextformat, int *convflags); +int pdf_check_textstring(PDF *p, const char *text, int len, int flags, + pdf_text_options *to, pdc_byte **outtext, int *outlen, int *outcharlen, + pdc_bool verbose); +pdc_scalar pdf_calculate_textsize(PDF *p, const pdc_byte *text, int len, + int charlen, pdf_text_options *to, int breakchar, pdc_scalar *height, + pdc_bool verbose); +pdc_scalar pdf_trim_textwidth(pdc_scalar width, pdf_text_options *to); +void pdf_place_text(PDF *p, pdc_byte *text, int len, int charlen, + pdf_text_options *to, pdc_scalar width, pdc_scalar height, + pdc_bool cont); + + + + +#endif /* P_DEFOPT_H */ + diff --git a/src/pdflib/pdflib/p_document.c b/src/pdflib/pdflib/p_document.c new file mode 100644 index 0000000..4c00aa3 --- /dev/null +++ b/src/pdflib/pdflib/p_document.c @@ -0,0 +1,1939 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_document.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib document related routines + * + */ + + +#undef MVS_TEST + +#define P_DOCUMENT_C + +/* For checking the beta expiration date */ +#include + +#include "p_intern.h" +#include "p_image.h" +#include "p_layer.h" +#include "p_page.h" +#include "p_tagged.h" + + + + + +#if (defined(WIN32) || defined(OS2)) && !defined(WINCE) +#include +#include +#endif + + +/* file attachment structure */ +typedef struct +{ + char *filename; + char *name; + char *description; + char *mimetype; + pdc_off_t filesize; +} +pdf_attachments; + +#define PDF_MAX_LANGCODE 8 + +/* Document open modes */ + +typedef enum +{ + open_auto, + open_none, + open_bookmarks, + open_thumbnails, + open_fullscreen, + open_attachments + +} +pdf_openmode; + +static const pdc_keyconn pdf_openmode_keylist[] = +{ + {"none", open_none}, + {"bookmarks", open_bookmarks}, + {"thumbnails", open_thumbnails}, + {"fullscreen", open_fullscreen}, + {"attachments", open_attachments}, + + {NULL, 0} +}; + +static const pdc_keyconn pdf_openmode_pdfkeylist[] = +{ + {"UseNone", open_auto}, + {"UseNone", open_none}, + {"UseOutlines", open_bookmarks}, + {"UseThumbs", open_thumbnails}, + {"FullScreen", open_fullscreen}, + {"UseAttachments", open_attachments}, + + {NULL, 0} +}; + + +/* Document page layout */ + +typedef enum +{ + layout_default, + layout_singlepage, + layout_onecolumn, + layout_twocolumnleft, + layout_twocolumnright, + layout_twopageleft, + layout_twopageright +} +pdf_pagelayout; + +static const pdc_keyconn pdf_pagelayout_pdfkeylist[] = +{ + {"Default", layout_default}, + {"SinglePage", layout_singlepage}, + {"OneColumn", layout_onecolumn}, + {"TwoColumnLeft", layout_twocolumnleft}, + {"TwoColumnRight", layout_twocolumnright}, + {"TwoPageLeft", layout_twopageleft}, + {"TwoPageRight", layout_twopageright}, + {NULL, 0} +}; + + +/* NonFullScreenPageMode */ + +static const pdc_keyconn pdf_nonfullscreen_keylist[] = +{ + {"none", open_none}, + {"bookmarks", open_bookmarks}, + {"thumbnails", open_thumbnails}, + + {NULL, 0} +}; + +typedef enum +{ + doc_none, + doc_l2r, + doc_r2l, + doc_appdefault, + doc_simplex, + doc_duplexflipshortedge, + doc_duplexfliplongedge +} +pdf_viewerprefence; + +/* Direction */ + +static const pdc_keyconn pdf_textdirection_pdfkeylist[] = +{ + {"L2R", doc_l2r}, + {"R2L", doc_r2l}, + {NULL, 0} +}; + +/* PrintScaling */ + +static const pdc_keyconn pdf_printscaling_pdfkeylist[] = +{ + {"None", doc_none}, + {"AppDefault", doc_appdefault}, + {NULL, 0} +}; + +/* Duplex */ + +static const pdc_keyconn pdf_duplex_pdfkeylist[] = +{ + {"None", doc_none}, + {"Simplex", doc_simplex}, + {"DuplexFlipShortEdge", doc_duplexflipshortedge}, + {"DuplexFlipLongEdge", doc_duplexfliplongedge}, + {NULL, 0} +}; + + + +static const pdc_keyconn pdf_pdfa_keylist[] = +{ + {NULL, 0} +}; + + + +static const pdc_keyconn pdf_pdfx_keylist[] = +{ + {NULL, 0} +}; + + +/* configurable flush points */ + +static const pdc_keyconn pdf_flush_keylist[] = +{ + {"none", pdc_flush_none}, + {"page", pdc_flush_page}, + {"content", pdc_flush_content}, + {"heavy", pdc_flush_heavy}, + {NULL, 0} +}; + +static const pdc_keyconn pl_pwencoding_keylist[] = +{ + {"ebcdic", pdc_ebcdic}, + {"ebcdic_37", pdc_ebcdic_37}, + {"ebcdic_winansi", pdc_ebcdic_winansi}, + {"pdfdoc", pdc_pdfdoc}, + {"winansi", pdc_winansi}, + {"macroman", pdc_macroman_apple}, + {NULL, 0} +}; + +#define PDF_MAXPW 0 +static const pdc_keyconn pdc_permissions_keylist[] = +{ + {NULL, 0} +}; + +#define PDF_PDFA_FLAG PDC_OPT_UNSUPP + +#define PDF_SECURITY_FLAG PDC_OPT_UNSUPP + +#define PDF_LINEARIZE_FLAG PDC_OPT_UNSUPP + +#define PDF_ICC_FLAG PDC_OPT_UNSUPP + +#define PDF_TAGGED_FLAG PDC_OPT_UNSUPP + +#define PDF_METADATA_FLAG PDC_OPT_UNSUPP + +#define PDF_UPDATE_FLAG PDC_OPT_UNSUPP + +#define PDF_DOCUMENT_OPTIONS1 \ +\ + {"pdfa", pdc_keywordlist, PDF_PDFA_FLAG, 1, 1, \ + 0.0, 0.0, pdf_pdfa_keylist}, \ +\ + {"pdfx", pdc_keywordlist, PDF_ICC_FLAG, 1, 1, \ + 0.0, 0.0, pdf_pdfx_keylist}, \ +\ + {"compatibility", pdc_keywordlist, PDC_OPT_IGNOREIF1, 1, 1, \ + 0.0, 0.0, pdf_compatibility_keylist}, \ +\ + {"flush", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_flush_keylist}, \ +\ + {"passwordencoding", pdc_keywordlist, PDF_SECURITY_FLAG, 1, 1, \ + 0.0, 0.0, pl_pwencoding_keylist}, \ +\ + {"attachmentpassword", pdc_stringlist, PDF_SECURITY_FLAG, 1, 1, \ + 0.0, PDF_MAXPW, NULL}, \ +\ + {"masterpassword", pdc_stringlist, PDF_SECURITY_FLAG, 1, 1, \ + 0.0, PDF_MAXPW, NULL}, \ +\ + {"userpassword", pdc_stringlist, PDF_SECURITY_FLAG, 1, 1, \ + 0.0, PDF_MAXPW, NULL}, \ +\ + {"permissions", pdc_keywordlist, \ + PDF_SECURITY_FLAG | PDC_OPT_BUILDOR | PDC_OPT_DUPORIGVAL, 1, 9,\ + 0.0, 0.0, pdc_permissions_keylist}, \ +\ + {"update", pdc_booleanlist, PDF_UPDATE_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"tagged", pdc_booleanlist, PDF_TAGGED_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"lang", pdc_stringlist, PDF_TAGGED_FLAG, 1, 1, \ + 0.0, PDF_MAX_LANGCODE, NULL}, \ +\ + {"search", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"groups", pdc_stringlist, PDC_OPT_NONE, 1, PDC_USHRT_MAX, \ + 0.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"optimize", pdc_booleanlist, PDF_LINEARIZE_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"linearize", pdc_booleanlist, PDF_LINEARIZE_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"inmemory", pdc_booleanlist, PDF_LINEARIZE_FLAG, 1, 1,\ + 0.0, 0.0, NULL}, \ +\ + {"tempdirname", pdc_stringlist, PDF_LINEARIZE_FLAG, 1, 1, \ + 4.0, 400.0, NULL}, \ + + +#if defined(MVS) || defined(MVS_TEST) +#define PDF_DOCUMENT_OPTIONS10 \ +\ + {"recordsize", pdc_integerlist, PDF_LINEARIZE_FLAG, 1, 1, \ + 0.0, 32768.0, NULL}, \ +\ + {"tempfilenames", pdc_stringlist, PDF_LINEARIZE_FLAG, 2, 2, \ + 4.0, 400.0, NULL}, \ + +#endif + + +#define PDF_DOCUMENT_OPTIONS2 \ +\ + {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"moddate", pdc_booleanlist, PDC_OPT_NONE, 1, 1,\ + 0.0, 0.0, NULL}, \ +\ + {"destination", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"destname", pdc_stringlist, PDC_OPT_IGNOREIF1, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"action", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"labels", pdc_stringlist, PDC_OPT_NONE, 1, PDC_USHRT_MAX, \ + 0.0, PDC_USHRT_MAX, NULL}, \ +\ + {"openmode", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_openmode_keylist}, \ +\ + {"pagelayout", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_pagelayout_pdfkeylist}, \ +\ + {"uri", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"viewerpreferences", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_USHRT_MAX, NULL}, \ +\ + {"autoxmp", pdc_booleanlist, PDF_METADATA_FLAG, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"attachments", pdc_stringlist, PDC_OPT_NONE, 1, PDC_USHRT_MAX, \ + 0.0, PDC_INT_MAX, NULL}, \ + + +/* document struct */ + +struct pdf_document_s +{ + int compatibility; /* PDF version number * 10 */ + pdc_flush_state flush; /* output flushing points */ + + + + + + + pdc_bool moddate; /* modified date will be created */ + char lang[PDF_MAX_LANGCODE + 1]; /* default natural language */ + char *action; /* document actions */ + pdf_dest *dest; /* destination as open action */ + char *uri; /* document's base url */ + char *viewerpreferences; /* option list with viewer preferences */ + pdc_bool writevpdict; /* viewer preferences dictionary + * must be written */ + pdf_openmode openmode; /* document open mode */ + pdf_pagelayout pagelayout; /* page layout within document */ + + char *searchindexname; /* file name for search index */ + char *searchindextype; /* type for search index */ + + pdf_attachments *attachments; /* temporarily file attachments */ + int nattachs; /* number of file attachments */ + + + char *filename; /* file name of document */ + size_t (*writeproc)(PDF *p, void *data, size_t size); + /* output procedure */ + FILE *fp; /* file id - deprecated */ + int len; /* length of custom */ +}; + +static pdf_document * +pdf_init_get_document(PDF *p) +{ + static const char fn[] = "pdf_init_get_document"; + + if (p->document == NULL) + { + pdf_document *doc = (pdf_document *) + pdc_malloc(p->pdc, sizeof(pdf_document), fn); + + doc->compatibility = PDF_DEF_COMPATIBILITY; + doc->flush = pdc_flush_page; + + + + + + + doc->moddate = pdc_false; + doc->lang[0] = 0; + doc->action = NULL; + doc->dest = NULL; + doc->uri = NULL; + doc->viewerpreferences = NULL; + doc->writevpdict = pdc_false; + doc->openmode = open_auto; + doc->pagelayout = layout_default; + + doc->searchindexname = NULL; + doc->searchindextype = NULL; + + doc->attachments = NULL; + doc->nattachs = 0; + + + doc->fp = NULL; + doc->filename = NULL; + doc->writeproc = NULL; + doc->len = 0; + + p->document = doc; + } + + return p->document; +} + +static void +pdf_cleanup_document_internal(PDF *p) +{ + pdf_document *doc = (pdf_document *) p->document; + + if (doc) + { + pdf_cleanup_destination(p, doc->dest); + doc->dest = NULL; + + if (doc->action) + { + pdc_free(p->pdc, doc->action); + doc->action = NULL; + } + + if (doc->uri) + { + pdc_free(p->pdc, doc->uri); + doc->uri = NULL; + } + + if (doc->viewerpreferences) + { + pdc_free(p->pdc, doc->viewerpreferences); + doc->viewerpreferences = NULL; + } + + + + + if (doc->searchindexname) + { + pdc_free(p->pdc, doc->searchindexname); + doc->searchindexname = NULL; + } + + if (doc->searchindextype) + { + pdc_free(p->pdc, doc->searchindextype); + doc->searchindextype = NULL; + } + + if (doc->filename) + { + pdc_free(p->pdc, doc->filename); + doc->filename = NULL; + } + + pdc_free(p->pdc, doc); + p->document = NULL; + } +} + + +/* ---------------------------- PDFA / PDFX -------------------------- */ + + + +void +pdf_fix_openmode(PDF *p) +{ + pdf_document *doc = pdf_init_get_document(p); + + if (doc->openmode == open_auto) + doc->openmode = open_bookmarks; +} + + + + + +/* ------------------------- viewerpreferences ----------------------- */ + +static const pdc_defopt pdf_viewerpreferences_options[] = +{ + {"centerwindow", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0, NULL}, + + {"direction", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_textdirection_pdfkeylist}, + + {"displaydoctitle", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0, NULL}, + + {"fitwindow", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0, NULL}, + + {"hidemenubar", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0, NULL}, + + {"hidetoolbar", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0, NULL}, + + {"hidewindowui", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0, NULL}, + + {"nonfullscreenpagemode", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_nonfullscreen_keylist}, + + {"viewarea", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_usebox_keylist}, + + {"viewclip", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_usebox_keylist}, + + {"printarea", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_usebox_keylist}, + + {"printclip", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_usebox_keylist}, + + {"printscaling", pdc_keywordlist, PDC_OPT_PDC_1_6, 1, 1, + 0.0, 0.0, pdf_printscaling_pdfkeylist}, + + {"duplex", pdc_keywordlist, PDC_OPT_PDC_1_7, 1, 1, + 0.0, 0.0, pdf_duplex_pdfkeylist}, + + {"picktraybypdfsize", pdc_booleanlist, PDC_OPT_PDC_1_7, 1, 1, + 0.0, 0, NULL}, + + {"printpagerange", pdc_integerlist, PDC_OPT_PDC_1_7 | PDC_OPT_EVENNUM, + 1, PDC_USHRT_MAX, 1.0, PDC_INT_MAX, NULL}, \ + + {"numcopies", pdc_integerlist, PDC_OPT_PDC_1_7, 1, 1, \ + 1.0, 5.0, NULL}, \ + + PDC_OPT_TERMINATE +}; + +static int +pdf_parse_and_write_viewerpreferences(PDF *p, const char *optlist, + pdc_bool output) +{ + pdc_resopt *resopts = NULL; + pdc_clientdata cdata; + char **strlist; + pdc_bool writevpdict = pdc_false; + pdc_bool flag; + int i, nv, inum; + + /* parsing option list */ + pdf_set_clientdata(p, &cdata); + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_viewerpreferences_options, &cdata, pdc_true); + + if (pdc_get_optvalues("hidetoolbar", resopts, &flag, NULL) && flag) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/HideToolbar true\n"); + } + + if (pdc_get_optvalues("hidemenubar", resopts, &flag, NULL) && flag) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/HideMenubar true\n"); + } + + if (pdc_get_optvalues("hidewindowui", resopts, &flag, NULL) && flag) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/HideWindowUI true\n"); + } + + if (pdc_get_optvalues("fitwindow", resopts, &flag, NULL) && flag) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/FitWindow true\n"); + } + + if (pdc_get_optvalues("centerwindow", resopts, &flag, NULL) && flag) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/CenterWindow true\n"); + } + + if (pdc_get_optvalues("displaydoctitle", resopts, &flag, NULL) && flag) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/DisplayDocTitle true\n"); + } + + if (pdc_get_optvalues("nonfullscreenpagemode", resopts, &inum, NULL) && + inum != (int) open_none) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/NonFullScreenPageMode/%s\n", + pdc_get_keyword(inum, pdf_openmode_pdfkeylist)); + } + + + if (pdc_get_optvalues("direction", resopts, &inum, NULL) && + inum != (int) doc_l2r) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/Direction/%s\n", + pdc_get_keyword(inum, pdf_textdirection_pdfkeylist)); + } + + if (pdc_get_optvalues("viewarea", resopts, &inum, NULL) && + inum != (int) pdc_pbox_crop) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/ViewArea%s\n", + pdc_get_keyword(inum, pdf_usebox_pdfkeylist)); + } + + if (pdc_get_optvalues("viewclip", resopts, &inum, NULL) && + inum != (int) pdc_pbox_crop) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/ViewClip%s\n", + pdc_get_keyword(inum, pdf_usebox_pdfkeylist)); + } + + if (pdc_get_optvalues("printarea", resopts, &inum, NULL) && + inum != (int) pdc_pbox_crop) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/PrintArea%s\n", + pdc_get_keyword(inum, pdf_usebox_pdfkeylist)); + } + + if (pdc_get_optvalues("printclip", resopts, &inum, NULL) && + inum != (int) pdc_pbox_crop) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/PrintClip%s\n", + pdc_get_keyword(inum, pdf_usebox_pdfkeylist)); + } + + if (pdc_get_optvalues("printscaling", resopts, &inum, NULL) && + inum != (int) doc_appdefault) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/PrintScaling/%s\n", + pdc_get_keyword(inum, pdf_printscaling_pdfkeylist)); + } + + if (pdc_get_optvalues("duplex", resopts, &inum, NULL) && + inum != (int) doc_none) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/Duplex/%s\n", + pdc_get_keyword(inum, pdf_duplex_pdfkeylist)); + } + + if (pdc_get_optvalues("picktraybypdfsize", resopts, &flag, NULL)) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/PickTrayByPDFSize %s\n", + PDC_BOOLSTR(flag)); + } + + nv = pdc_get_optvalues("printpagerange", resopts, NULL, &strlist); + if (nv) + { + writevpdict = pdc_true; + if (output) + { + int *prs = (int *) strlist; + + pdc_printf(p->out, "/PrintPageRange"); + pdc_begin_array(p->out); + for (i = 0; i < nv; i++) + pdc_printf(p->out, "%d ", prs[i]); + pdc_end_array(p->out); + } + } + + if (pdc_get_optvalues("numcopies", resopts, &inum, NULL)) + { + writevpdict = pdc_true; + if (output) pdc_printf(p->out, "/NumCopies %d\n", inum); + } + + pdc_cleanup_optionlist(p->pdc, resopts); + + return writevpdict; +} + + +/* ------------------------- search ----------------------- */ + +static const pdc_defopt pdf_search_options[] = +{ + {"filename", pdc_stringlist, PDC_OPT_REQUIRED, 1, 1, + 1.0, PDC_FILENAMELEN, NULL}, + + {"indextype", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + PDC_OPT_TERMINATE +}; + +static void +pdf_parse_search_optlist(PDF *p, const char *optlist) +{ + pdf_document *doc = p->document; + pdc_resopt *resopts = NULL; + + /* parsing option list */ + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_search_options, NULL, pdc_true); + + if (pdc_get_optvalues("filename", resopts, NULL, NULL)) + doc->searchindexname = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + if (pdc_get_optvalues("indextype", resopts, NULL, NULL)) + doc->searchindextype = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + else + doc->searchindextype = pdc_strdup(p->pdc, "PDX"); + + pdc_cleanup_optionlist(p->pdc, resopts); +} + +static void +pdf_write_search_indexes(PDF *p) +{ + pdf_document *doc = p->document; + + if (doc->searchindexname != NULL) + { + pdc_puts(p->out, "/Search"); + pdc_begin_dict(p->out); /* Search */ + pdc_puts(p->out, "/Indexes"); + pdc_begin_array(p->out); + pdc_begin_dict(p->out); /* Indexes */ + pdc_puts(p->out, "/Name"); + pdc_printf(p->out, "/%s", doc->searchindextype); + pdc_puts(p->out, "/Index"); + pdc_begin_dict(p->out); /* Index */ + pdc_puts(p->out, "/Type/Filespec"); + pdc_puts(p->out, "/F"); + pdf_put_pdffilename(p, doc->searchindexname); + pdc_end_dict(p->out); /* Index */ + pdc_end_dict(p->out); /* Indexes */ + pdc_end_array(p->out); + pdc_end_dict(p->out); /* Search */ + } +} + + +/* ---------------------- file attachements -------------------- */ + +static void +pdc_cleanup_attachments_tmp(void *opaque, void *mem) +{ + if (mem) + { + PDF *p = (PDF *) opaque; + pdf_document *doc = p->document; + int i; + + if (doc != NULL) + { + for (i = 0; i < doc->nattachs; i++) + { + pdf_attachments *fat = &doc->attachments[i]; + + if (fat->filename != NULL) + pdc_free(p->pdc, fat->filename); + if (fat->name != NULL) + pdc_free(p->pdc, fat->name); + if (fat->description != NULL) + pdc_free(p->pdc, fat->description); + if (fat->mimetype != NULL) + pdc_free(p->pdc, fat->mimetype); + } + + doc->attachments = NULL; + doc->nattachs = 0; + } + } +} + +static const pdc_defopt pdf_attachments_options[] = +{ + {"filename", pdc_stringlist, PDC_OPT_REQUIRED, 1, 1, + 1.0, PDC_FILENAMELEN, NULL}, + + {"description", pdc_stringlist, PDC_OPT_PDC_1_6, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"name", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"mimetype", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + PDC_OPT_TERMINATE +}; + +static void +pdf_parse_attachments_optlist(PDF *p, char **optlists, int ns, + pdc_encoding htenc, int htcp) +{ + static const char fn[] = "pdf_parse_attachments_optlist"; + pdf_document *doc = p->document; + pdc_resopt *resopts = NULL; + pdc_clientdata cdata; + int i; + + doc->attachments = (pdf_attachments *) pdc_malloc_tmp(p->pdc, + ns * sizeof(pdf_attachments), fn, + p, pdc_cleanup_attachments_tmp); + doc->nattachs = ns; + + pdf_set_clientdata(p, &cdata); + + for (i = 0; i < ns; i++) + { + pdf_attachments *fat = &doc->attachments[i]; + + fat->filename = NULL; + fat->name = NULL; + fat->description = NULL; + fat->mimetype = NULL; + fat->filesize = 0; + } + + for (i = 0; i < ns; i++) + { + pdf_attachments *fat = &doc->attachments[i]; + + /* parsing option list */ + resopts = pdc_parse_optionlist(p->pdc, optlists[i], + pdf_attachments_options, &cdata, pdc_true); + + if (pdc_get_optvalues("filename", resopts, NULL, NULL)) + fat->filename = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + if (pdf_get_opt_textlist(p, "description", resopts, htenc, htcp, + pdc_true, NULL, &fat->description, NULL)) + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + if (pdf_get_opt_textlist(p, "name", resopts, htenc, htcp, + pdc_true, NULL, &fat->name, NULL)) + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + if (pdc_get_optvalues("mimetype", resopts, NULL, NULL)) + fat->mimetype = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + pdc_cleanup_optionlist(p->pdc, resopts); + + fat->filesize = pdf_check_file(p, fat->filename, pdc_true); + } +} + +static void +pdf_write_attachments(PDF *p) +{ + static const char fn[] = "pdf_write_attachments"; + pdf_document *doc = p->document; + pdc_id attachment_id, obj_id; + char *name; + int i; + + for (i = 0; i < doc->nattachs; i++) + { + pdf_attachments *fat = &doc->attachments[i]; + + if (fat->filesize > 0) + { + /* create file specification dictionary */ + attachment_id = pdc_begin_obj(p->out, PDC_NEW_ID); + pdc_begin_dict(p->out); /* FS dict */ + + pdc_puts(p->out, "/Type/Filespec\n"); + pdc_printf(p->out, "/F"); + pdf_put_pdffilename(p, fat->filename); + pdc_puts(p->out, "\n"); + + if (fat->description != NULL) + { + pdc_puts(p->out, "/Desc"); + pdf_put_hypertext(p, fat->description); + pdc_puts(p->out, "\n"); + } + + obj_id = pdc_alloc_id(p->out); + pdc_puts(p->out, "/EF"); + pdc_begin_dict(p->out); + pdc_objref(p->out, "/F", obj_id); + pdc_end_dict(p->out); + + pdc_end_dict(p->out); /* FS dict */ + pdc_end_obj(p->out); + + /* embed file */ + pdf_embed_file(p, obj_id, fat->filename, fat->mimetype, + fat->filesize); + + /* insert name in tree */ + if (fat->name == NULL) + name = pdc_strdup_ext(p->pdc, fat->filename, 0, fn); + else + name = pdc_strdup_ext(p->pdc, fat->name, 0, fn); + pdf_insert_name(p, name, names_embeddedfiles, attachment_id); + } + } +} + +pdc_off_t +pdf_check_file(PDF *p, const char *filename, pdc_bool verbose) +{ + pdc_off_t filesize = 0; + const char *qualifier = "attachment "; + pdc_file *fp; + + fp = pdc_fsearch_fopen(p->pdc, filename, NULL, qualifier, + PDC_FILE_BINARY); + if (fp == NULL) + { + if (verbose) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + } + else + { + filesize = pdc_file_size(fp); + pdc_fclose(fp); + + if (filesize == 0) + { + pdc_set_errmsg(p->pdc, PDC_E_IO_FILE_EMPTY, qualifier, filename, + 0, 0); + if (verbose) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + } + } + + return filesize; +} + +void +pdf_embed_file(PDF *p, pdc_id obj_id, const char *filename, + const char *mimetype, pdc_off_t filesize) +{ + pdc_id length_id; + PDF_data_source src; + + pdc_begin_obj(p->out, obj_id); + pdc_begin_dict(p->out); /* F dict */ + + pdc_puts(p->out, "/Type/EmbeddedFile\n"); + + if (mimetype && *mimetype) + { + pdc_puts(p->out, "/Subtype"); + pdf_put_pdfname(p, mimetype); + pdc_puts(p->out, "\n"); + } + + pdc_puts(p->out, "/Params"); + pdc_begin_dict(p->out); /* Params */ + pdc_printf(p->out, "/Size %lld", filesize); + pdc_end_dict(p->out); /* Params */ + + if (pdc_get_compresslevel(p->out)) + { + pdc_puts(p->out, "/Filter/FlateDecode\n"); + } + + length_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Length", length_id); + + pdc_end_dict(p->out); /* F dict */ + + /* write the file in the PDF */ + src.private_data = (void *) filename; + src.init = pdf_data_source_file_init; + src.fill = pdf_data_source_file_fill; + src.terminate = pdf_data_source_file_terminate; + src.length = (long) 0; + src.offset = (long) 0; + + + pdf_copy_stream(p, &src, pdc_true); + + + pdc_end_obj(p->out); + + pdc_put_pdfstreamlength(p->out, length_id); + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); +} + + +/* ---------------------- linearize -------------------- */ + + + +/* ------------------ document options ----------------- */ + +static void +pdf_get_document_common_options(PDF *p, pdc_resopt *resopts, int fcode) +{ + pdf_document *doc = p->document; + pdc_encoding htenc; + int htcp; + char **strlist; + int i, inum, ns; + + + htenc = + pdf_get_hypertextencoding_opt(p, resopts, &htcp, pdc_true); + + if (pdc_get_optvalues("destination", resopts, NULL, &strlist)) + { + if (doc->dest) + pdc_free(p->pdc, doc->dest); + doc->dest = pdf_parse_destination_optlist(p, strlist[0], 1, + pdf_openaction); + } + else + { + pdf_dest *dest = pdf_get_option_destname(p, resopts, htenc, htcp); + if (dest) + { + if (doc->dest) + pdc_free(p->pdc, doc->dest); + doc->dest = dest; + } + } + + if (pdc_get_optvalues("action", resopts, NULL, NULL)) + { + if (doc->action) + pdc_free(p->pdc, doc->action); + doc->action = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + pdf_parse_and_write_actionlist(p, event_document, NULL, doc->action); + } + + inum = pdc_get_optvalues("labels", resopts, NULL, &strlist); + for (i = 0; i < inum; i++) + pdf_set_pagelabel(p, strlist[i], fcode); + + if (pdc_get_optvalues("openmode", resopts, &inum, NULL)) + doc->openmode = (pdf_openmode) inum; + if (doc->openmode == open_attachments && p->compatibility < PDC_1_6) + pdc_error(p->pdc, PDC_E_OPT_VERSION, "openmode=attachments", + pdc_get_pdfversion(p->pdc, p->compatibility), 0, 0); + + if (pdc_get_optvalues("pagelayout", resopts, &inum, NULL)) + doc->pagelayout = (pdf_pagelayout) inum; + if (p->compatibility < PDC_1_5) + { + if (doc->pagelayout == layout_twopageleft) + pdc_error(p->pdc, PDC_E_OPT_VERSION, "pagelayout=TwoPageLeft", + pdc_get_pdfversion(p->pdc, p->compatibility), 0, 0); + if (doc->pagelayout == layout_twopageright) + pdc_error(p->pdc, PDC_E_OPT_VERSION, "pagelayout=TwoPageRight", + pdc_get_pdfversion(p->pdc, p->compatibility), 0, 0); + } + + if (pdc_get_optvalues("uri", resopts, NULL, NULL)) + { + if (doc->uri) + pdc_free(p->pdc, doc->uri); + doc->uri = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + if (pdc_get_optvalues("viewerpreferences", resopts, NULL, NULL)) + { + if (doc->viewerpreferences) + pdc_free(p->pdc, doc->viewerpreferences); + doc->viewerpreferences = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + doc->writevpdict |= + pdf_parse_and_write_viewerpreferences(p, doc->viewerpreferences, + pdc_false); + } + + if (pdc_get_optvalues("search", resopts, NULL, &strlist)) + pdf_parse_search_optlist(p, strlist[0]); + + + pdc_get_optvalues("moddate", resopts, &doc->moddate, NULL); + + + + ns = pdc_get_optvalues("attachments", resopts, NULL, &strlist); + if (ns) + pdf_parse_attachments_optlist(p, strlist, ns, htenc, htcp); +} + +static const pdc_defopt pdf_begin_document_options[] = +{ + PDF_DOCUMENT_OPTIONS1 +#if defined(MVS) || defined(MVS_TEST) + PDF_DOCUMENT_OPTIONS10 +#endif + PDF_DOCUMENT_OPTIONS2 + PDF_ERRORPOLICY_OPTION + PDC_OPT_TERMINATE +}; + + +/* + * The external callback interface requires a PDF* as the first argument, + * while the internal interface uses pdc_output* and doesn't know about PDF*. + * We use a wrapper to bridge the gap, and store the PDF* within the + * pdc_output structure opaquely. + */ + +static size_t +writeproc_wrapper(pdc_output *out, void *data, size_t size) +{ + size_t ret; + + PDF *p = (PDF *) pdc_get_opaque(out); + + ret = (p->writeproc)(p, data, size); + pdc_logg_cond(p->pdc, 1, trc_api, + "/* writeproc(data[%p], %d)[%d] */\n", data, size, ret); + return ret; +} + + + +/* ---------------------------- begin document -------------------------- */ + +static int +pdf_begin_document_internal(PDF *p, const char *optlist, pdc_bool callback) +{ + pdf_document *doc = p->document; + pdc_resopt *resopts = NULL; + char **groups = NULL; + int n_groups = 0; + pdc_bool verbose = p->debug[(int) 'o']; + pdc_outctl oc; + + (void) callback; + + verbose = pdf_get_errorpolicy(p, NULL, verbose); + + /* parsing option list */ + if (optlist && *optlist) + { + int inum; + + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_begin_document_options, NULL, pdc_true); + + verbose = pdf_get_errorpolicy(p, resopts, verbose); + + pdc_get_optvalues("compatibility", resopts, &doc->compatibility, NULL); + + if (pdc_get_optvalues("flush", resopts, &inum, NULL)) + doc->flush = (pdc_flush_state) inum; + + pdc_get_optvalues("lang", resopts, doc->lang, NULL); + + + + + + + + + n_groups = pdc_get_optvalues("groups", resopts, NULL, &groups); + } + + /* copy for easy access */ + p->compatibility = doc->compatibility; + p->pdc->compatibility = doc->compatibility; + p->flush = doc->flush; + + + + + + /* + * None of these functions must call pdc_alloc_id() or generate + * any output since the output machinery is not yet initialized! + */ + + pdf_init_pages(p, (const char **) groups, n_groups); + + /* common options */ + pdf_get_document_common_options(p, resopts, PDF_FC_BEGIN_DOCUMENT); + + + /* deprecated */ + p->bookmark_dest = pdf_init_destination(p); + + pdf_init_images(p); + pdf_init_xobjects(p); + pdf_init_fonts(p); + pdf_init_outlines(p); + pdf_init_annot_params(p); + pdf_init_colorspaces(p); + pdf_init_pattern(p); + pdf_init_shadings(p); + pdf_init_extgstates(p); + + + + + + /* create document digest */ + pdc_init_digest(p->out); + + if (!p->pdc->ptfrun) + { + if (doc->fp) + pdc_update_digest(p->out, (pdc_byte *) doc->fp, doc->len); + else if (doc->writeproc) + pdc_update_digest(p->out, (pdc_byte *) &doc->writeproc, doc->len); + else if (doc->filename) + pdc_update_digest(p->out, (pdc_byte *) doc->filename, doc->len); + } + + pdf_feed_digest_info(p); + + if (!p->pdc->ptfrun) + { + pdc_update_digest(p->out, (pdc_byte *) &p, sizeof(PDF*)); + pdc_update_digest(p->out, (pdc_byte *) p, sizeof(PDF)); + } + + + pdc_finish_digest(p->out, !p->pdc->ptfrun); + + /* preparing output struct */ + pdc_init_outctl(&oc); + oc.flush = doc->flush; + + if (doc->fp) + oc.fp = doc->fp; + else if (doc->writeproc) + { + oc.writeproc = writeproc_wrapper; + p->writeproc = doc->writeproc; + } + else if (doc->filename) + oc.filename = doc->filename; + else + oc.filename = ""; + + + + if (!pdc_init_output((void *) p, p->out, doc->compatibility, &oc)) + { + if (oc.filename && *oc.filename) + { + pdc_set_fopen_errmsg(p->pdc, + pdc_get_fopen_errnum(p->pdc, PDC_E_IO_WROPEN), "PDF ", + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, oc.filename)); + + if (verbose) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + } + + pdf_cleanup_document_internal(p); + return -1; + } + + /* Write the constant /ProcSet array once at the beginning */ + p->procset_id = pdc_begin_obj(p->out, PDC_NEW_ID); + pdc_puts(p->out, "[/PDF/ImageB/ImageC/ImageI/Text]\n"); + pdc_end_obj(p->out); + + pdf_init_pages2(p); + + pdf_write_attachments(p); + + return 1; +} + +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma unmanaged +#endif +int +pdf__begin_document(PDF *p, const char *filename, int len, const char *optlist) +{ + pdf_document *doc; + pdc_bool verbose = p->debug[(int) 'o']; + int retval; + + verbose = pdf_get_errorpolicy(p, NULL, verbose); + + + doc = pdf_init_get_document(p); + + /* file ID or filename */ + if (len == -1) + { + FILE *fp = (FILE *) filename; + + /* + * It is the callers responsibility to open the file in binary mode, + * but it doesn't hurt to make sure it really is. + * The Intel version of the Metrowerks compiler doesn't have setmode(). + */ +#if !defined(__MWERKS__) && (defined(WIN32) || defined(OS2)) +#if defined WINCE + _setmode(fileno(fp), _O_BINARY); +#else + setmode(fileno(fp), O_BINARY); +#endif +#endif + + doc->fp = fp; + doc->len = sizeof(FILE); + } + else if (filename && (*filename || len > 0)) + { + filename = pdf_convert_filename(p, filename, len, "filename", + PDC_CONV_WITHBOM); + doc->filename = pdc_strdup(p->pdc, filename); + doc->len = (int) strlen(doc->filename); + } + + retval = pdf_begin_document_internal(p, optlist, pdc_false); + + if (retval > -1) + PDF_SET_STATE(p, pdf_state_document); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Begin document]\n"); + + return retval; +} +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma managed +#endif + +void +pdf__begin_document_callback(PDF *p, + size_t (*i_writeproc)(PDF *p, void *data, size_t size), const char *optlist) +{ + size_t (*writeproc)(PDF *, void *, size_t) = i_writeproc; + pdf_document *doc; + + if (writeproc == NULL) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "writeproc", 0, 0, 0); + + doc = pdf_init_get_document(p); + + /* initializing and opening the document */ + doc->writeproc = writeproc; + doc->len = sizeof(writeproc); + + (void) pdf_begin_document_internal(p, optlist, pdc_true); + + PDF_SET_STATE(p, pdf_state_document); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Begin document]\n"); +} + +/* ----------------------------- name tree ----------------------------- */ + +struct pdf_name_s +{ + pdc_id obj_id; /* id of this name object */ + char * name; /* name string */ + pdf_nametree_type type; /* name tree type */ +}; + +static void +pdf_cleanup_names(PDF *p) +{ + int i; + + if (p->names == NULL) + return; + + for (i = 0; i < p->names_number; i++) + { + pdc_free(p->pdc, p->names[i].name); + } + + pdc_free(p->pdc, p->names); + p->names_number = 0; + p->names = NULL; +} + +void +pdf_insert_name(PDF *p, const char *name, pdf_nametree_type type, pdc_id obj_id) +{ + static const char fn[] = "pdf_insert_name"; + int i; + + if (p->names == NULL || p->names_number == p->names_capacity) + { + if (p->names == NULL) + { + p->names_number = 0; + p->names_capacity = NAMES_CHUNKSIZE; + p->names = (pdf_name *) pdc_malloc(p->pdc, + sizeof(pdf_name) * p->names_capacity, fn); + } + else + { + p->names_capacity *= 2; + p->names = (pdf_name *) pdc_realloc(p->pdc, p->names, + sizeof(pdf_name) * p->names_capacity, fn); + } + for (i = p->names_number; i < p->names_capacity; i++) + { + p->names[i].obj_id = PDC_BAD_ID; + p->names[i].name = NULL; + p->names[i].type = names_undef; + } + } + + /* check identity */ + for (i = 0; i < p->names_number; i++) + { + if (p->names[i].type == type && !strcmp(p->names[i].name, name)) + { + pdc_free(p->pdc, p->names[i].name); + p->names[i].name = (char *) name; + return; + } + } + + p->names[i].obj_id = obj_id; + p->names[i].name = (char *) name; + p->names[i].type = type; + p->names_number++; +} + +pdc_id +pdf_get_id_from_nametree(PDF *p, pdf_nametree_type type, const char *name) +{ + int i; + + for (i = 0; i < p->names_number; i++) + { + if (p->names[i].type == type && !strcmp(name, p->names[i].name)) + return p->names[i].obj_id; + } + + return PDC_BAD_ID; +} + +static pdc_id +pdf_write_names(PDF *p, pdf_nametree_type type) +{ + pdc_id ret = PDC_BAD_ID; + int i, ibeg = -1, iend = 0; + + for (i = 0; i < p->names_number; i++) + { + if (p->names[i].type == type) + { + if (ibeg == -1) + ibeg = i; + iend = i; + } + } + + if (ibeg > -1) + { + ret = pdc_begin_obj(p->out, PDC_NEW_ID); /* Names object */ + + pdc_begin_dict(p->out); /* Node dict */ + + /* + * Because we have only the 1 tree - the root tree + * the /Limits entry is not allowed (see chapter 3.8.5). + * + pdc_puts(p->out, "/Limits"); + pdc_begin_array(p->out); + pdf_put_hypertext(p, p->names[ibeg].name); + pdf_put_hypertext(p, p->names[iend].name); + pdc_end_array(p->out); + */ + + pdc_puts(p->out, "/Names"); + pdc_begin_array(p->out); + + for (i = ibeg; i <= iend; i++) + { + if (p->names[i].type == type) + { + pdf_put_hypertext(p, p->names[i].name); + pdc_objref(p->out, "", p->names[i].obj_id); + } + } + + pdc_end_array(p->out); + + pdc_end_dict(p->out); /* Node dict */ + + pdc_end_obj(p->out); /* Names object */ + + } + return ret; +} + +static int +name_compare( const void* a, const void* b) +{ + pdf_name *p1 = (pdf_name *) a; + pdf_name *p2 = (pdf_name *) b; + + return strcmp(p1->name, p2->name); +} + +/* ---------------------------- write document -------------------------- */ + +static pdc_id +pdf_write_pages_and_catalog(PDF *p, pdc_id orig_root_id) +{ + pdf_document *doc = p->document; + pdc_bool openact = pdc_false; + pdc_bool forpdfa = pdc_false; + pdc_id act_idlist[PDF_MAX_EVENTS]; + pdc_id root_id = PDC_BAD_ID; + pdc_id names_dests_id = PDC_BAD_ID; + pdc_id names_javascript_id = PDC_BAD_ID; + pdc_id names_ap_id = PDC_BAD_ID; + pdc_id names_embeddedfiles_id = PDC_BAD_ID; + pdc_id outintents1_id = PDC_BAD_ID; + pdc_id outintents2_id = PDC_BAD_ID; + + pdc_id pages_id = pdf_write_pages_tree(p); + pdc_id labels_id = pdf_write_pagelabels(p); + + + + (void) orig_root_id; + + /* name tree dictionaries */ + if (p->names_number) + { + + qsort(p->names, (size_t) p->names_number, sizeof(pdf_name), + name_compare); + + + names_dests_id = pdf_write_names(p, names_dests); + names_javascript_id = pdf_write_names(p, names_javascript); + names_ap_id = pdf_write_names(p, names_ap); + names_embeddedfiles_id = pdf_write_names(p, names_embeddedfiles); + } + + + (void) forpdfa; + + + + + /* write action objects */ + if (doc->action) + pdf_parse_and_write_actionlist(p, event_document, act_idlist, + (const char *) doc->action); + + root_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Catalog */ + pdc_begin_dict(p->out); + pdc_puts(p->out, "/Type/Catalog\n"); + + pdc_objref(p->out, "/Pages", pages_id); /* Pages object */ + + + if (labels_id != PDC_BAD_ID) + { + pdc_objref(p->out, "/PageLabels", labels_id); + } + + if (p->names_number) + { + pdc_printf(p->out, "/Names"); + pdc_begin_dict(p->out); /* Names */ + + if (names_dests_id != PDC_BAD_ID) + pdc_objref(p->out, "/Dests", names_dests_id); + if (names_javascript_id != PDC_BAD_ID) + pdc_objref(p->out, "/JavaScript", names_javascript_id); + if (names_ap_id != PDC_BAD_ID) + pdc_objref(p->out, "/AP", names_ap_id); + if (names_embeddedfiles_id != PDC_BAD_ID) + pdc_objref(p->out, "/EmbeddedFiles", names_embeddedfiles_id); + + pdc_end_dict(p->out); /* Names */ + } + + if (doc->writevpdict) + { + pdc_printf(p->out, "/ViewerPreferences\n"); + pdc_begin_dict(p->out); /* ViewerPreferences */ + pdf_parse_and_write_viewerpreferences(p, + doc->viewerpreferences, pdc_true); + pdc_end_dict(p->out); /* ViewerPreferences */ + } + + if (doc->pagelayout != layout_default) + pdc_printf(p->out, "/PageLayout/%s\n", + pdc_get_keyword(doc->pagelayout, pdf_pagelayout_pdfkeylist)); + + if (doc->openmode != open_auto && doc->openmode != open_none) + pdc_printf(p->out, "/PageMode/%s\n", + pdc_get_keyword(doc->openmode, pdf_openmode_pdfkeylist)); + + pdf_write_outline_root(p); /* /Outlines */ + + if (doc->action) /* /AA */ + openact = pdf_write_action_entries(p, event_document, act_idlist); + + if (doc->dest && !openact) + { + pdc_puts(p->out, "/OpenAction"); + pdf_write_destination(p, doc->dest); + } + + if (doc->uri) + { + pdc_puts(p->out, "/URI"); + pdc_begin_dict(p->out); + pdc_printf(p->out, "/Base"); + pdf_put_hypertext(p, doc->uri); + pdc_end_dict(p->out); + } + + + if (doc->lang[0]) + { + pdc_puts(p->out, "/Lang"); + pdf_put_hypertext(p, doc->lang); + pdc_puts(p->out, "\n"); + } + + /* /StructTreeRoot /MarkInfo */ + + /* /OCProperties */ + + if (outintents1_id != PDC_BAD_ID || outintents2_id != PDC_BAD_ID) + { + pdc_puts(p->out, "/OutputIntents"); + pdc_begin_array(p->out); + if (outintents1_id != PDC_BAD_ID) + pdc_objref(p->out, "", outintents1_id); + if (outintents2_id != PDC_BAD_ID) + pdc_objref(p->out, "", outintents2_id); + pdc_end_array(p->out); + } + + /* /Search */ + pdf_write_search_indexes(p); + + /* /Metadata */ + + /* not supported: /Threads /PieceInfo /Perms /Legal */ + + pdc_end_dict(p->out); /* Catalog */ + pdc_end_obj(p->out); + + return root_id; +} + + +static void +pdf_write_document(PDF *p) +{ + if (PDF_GET_STATE(p) != pdf_state_error) + { + pdf_document *doc = p->document; + pdc_id info_id = PDC_BAD_ID; + pdc_id root_id = PDC_BAD_ID; + + if (pdf_last_page(p) == 0) + pdc_error(p->pdc, PDF_E_DOC_EMPTY, 0, 0, 0, 0); + + pdf_write_attachments(p); + + + /* Write all pending document information up to xref table + trailer */ + info_id = pdf_write_info(p, doc->moddate); + + pdf_write_doc_fonts(p); /* font objects */ + pdf_write_doc_colorspaces(p); /* color space resources */ + pdf_write_doc_extgstates(p); /* ExtGState resources */ + root_id = pdf_write_pages_and_catalog(p, root_id); + pdf_write_outlines(p); + pdc_write_xref(p->out); + + pdc_write_trailer(p->out, info_id, root_id, 0, -1, -1, -1); + } + + pdc_close_output(p->out); +} + +/* ------------------------------ end document ---------------------------- */ + +void +pdf_cleanup_document(PDF *p) +{ + if (PDF_GET_STATE(p) != pdf_state_object) + { + /* Don't call pdc_cleanup_output() here because we may still need + * the buffer contents for pdf__get_buffer() after pdf__end_document(). + */ + + pdf_delete_actions(p); + + pdf_cleanup_destination(p, p->bookmark_dest); /* deprecated */ + pdf_cleanup_pages(p); + pdf_cleanup_document_internal(p); + pdf_cleanup_info(p); + pdf_cleanup_fonts(p); + pdf_cleanup_outlines(p); + pdf_cleanup_annot_params(p); + pdf_cleanup_names(p); + pdf_cleanup_colorspaces(p); + pdf_cleanup_pattern(p); + pdf_cleanup_shadings(p); + pdf_cleanup_images(p); + pdf_cleanup_xobjects(p); + pdf_cleanup_extgstates(p); + + + + + + + + + + pdf_cleanup_stringlists(p); + + PDF_SET_STATE(p, pdf_state_object); + } +} + +static const pdc_defopt pdf_end_document_options[] = +{ + PDF_DOCUMENT_OPTIONS2 + PDC_OPT_TERMINATE +}; + +void +pdf__end_document(PDF *p, const char *optlist) +{ + pdf_document *doc; + + /* check if there are any suspended pages left. + */ + pdf_check_suspended_pages(p); + + /* get document pointer */ + doc = pdf_init_get_document(p); + + if (optlist && *optlist) + { + pdc_resopt *resopts = NULL; + pdc_clientdata cdata; + + /* parsing option list */ + pdf_set_clientdata(p, &cdata); + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_end_document_options, &cdata, pdc_true); + + /* get options */ + pdf_get_document_common_options(p, resopts, PDF_FC_END_DOCUMENT); + + } + + pdf_write_document(p); + + + pdf_cleanup_document(p); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[End document]\n\n"); +} + +const char * +pdf__get_buffer(PDF *p, long *size) +{ + const char *ret; + pdc_off_t llsize; + + + ret = pdc_get_stream_contents(p->out, &llsize); + + if (llsize > LONG_MAX) + pdc_error(p->pdc, PDF_E_DOC_GETBUF_2GB, 0, 0, 0, 0); + + *size = (long) llsize; + return ret; +} + + + + +/*****************************************************************************/ +/** deprecated historical document functions **/ +/*****************************************************************************/ + +void +pdf_set_flush(PDF *p, const char *flush) +{ + if (p->pdc->binding != NULL && strcmp(p->pdc->binding, "C++")) + return; + + if (flush != NULL && *flush) + { + int i = pdc_get_keycode_ci(flush, pdf_flush_keylist); + if (i != PDC_KEY_NOTFOUND) + { + pdf_document *doc = pdf_init_get_document(p); + + doc->flush = (pdc_flush_state) i; + p->flush = doc->flush; + return; + } + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, flush, "flush", + 0, 0); + } +} + +void +pdf_set_uri(PDF *p, const char *uri) +{ + pdf_document *doc = pdf_init_get_document(p); + + if (doc->uri) + pdc_free(p->pdc, doc->uri); + doc->uri = pdc_strdup(p->pdc, uri); +} + + +void +pdf_set_compatibility(PDF *p, const char *compatibility) +{ + + if (compatibility != NULL && *compatibility) + { + int i = pdc_get_keycode_ci(compatibility, pdf_compatibility_keylist); + if (i != PDC_KEY_NOTFOUND) + { + pdf_document *doc = pdf_init_get_document(p); + + p->compatibility = i; + doc->compatibility = i; + p->pdc->compatibility = i; + return; + } + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, compatibility, "compatibility", + 0, 0); + } +} + +void +pdf_set_openaction(PDF *p, const char *openaction) +{ + pdf_document *doc = pdf_init_get_document(p); + + if (openaction != NULL && *openaction) + { + pdf_cleanup_destination(p, doc->dest); + doc->dest = pdf_parse_destination_optlist(p, openaction, 1, + pdf_openaction); + } +} + +void +pdf_set_openmode(PDF *p, const char *openmode) +{ + int i; + + if (openmode == NULL || !*openmode) + openmode = "none"; + + i = pdc_get_keycode_ci(openmode, pdf_openmode_keylist); + if (i != PDC_KEY_NOTFOUND) + { + pdf_document *doc = pdf_init_get_document(p); + + doc->openmode = (pdf_openmode) i; + } + else + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, openmode, "openmode", 0, 0); +} + +void +pdf_set_viewerpreference(PDF *p, const char *viewerpreference) +{ + static const char fn[] = "pdf_set_viewerpreference"; + pdf_document *doc = pdf_init_get_document(p); + char *optlist; + size_t nb1 = 0, nb2 = 0; + + if (doc->viewerpreferences) + nb1 = strlen(doc->viewerpreferences) * sizeof(char *); + nb2 = strlen(viewerpreference) * sizeof(char *); + + optlist = (char *) pdc_malloc(p->pdc, nb1 + nb2 + 2, fn); + optlist[0] = 0; + if (doc->viewerpreferences) + { + strcat(optlist, doc->viewerpreferences); + strcat(optlist, " "); + } + strcat(optlist, viewerpreference); + + if (doc->viewerpreferences) + pdc_free(p->pdc, doc->viewerpreferences); + doc->viewerpreferences = optlist; + doc->writevpdict |= + pdf_parse_and_write_viewerpreferences(p, optlist, pdc_false); +} + + + + diff --git a/src/pdflib/pdflib/p_draw.c b/src/pdflib/pdflib/p_draw.c new file mode 100644 index 0000000..dc9271e --- /dev/null +++ b/src/pdflib/pdflib/p_draw.c @@ -0,0 +1,410 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_draw.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib drawing routines + * + */ + +#include "p_intern.h" +#include "p_layer.h" +#include "p_tagged.h" + +/* Path segment operators */ + +static void +pdf_begin_path(PDF *p) +{ + if (PDF_GET_STATE(p) == pdf_state_path) + return; + + + + + pdf_end_text(p); + PDF_PUSH_STATE(p, "pdf_begin_path", pdf_state_path); +} + +static void +pdf_end_path(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + + PDF_POP_STATE(p, "pdf_end_path"); + + ppt->gstate[ppt->sl].x = 0; + ppt->gstate[ppt->sl].y = 0; +} + +/* ----------------- Basic functions for API functions --------------*/ + +void +pdf__moveto(PDF *p, pdc_scalar x, pdc_scalar y) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + + ppt->gstate[ppt->sl].startx = ppt->gstate[ppt->sl].x = x; + ppt->gstate[ppt->sl].starty = ppt->gstate[ppt->sl].y = y; + + pdf_begin_path(p); + pdc_printf(p->out, "%f %f m\n", x, y); +} + +void +pdf__rmoveto(PDF *p, pdc_scalar x, pdc_scalar y) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_scalar x_0 = ppt->gstate[ppt->sl].x; + pdc_scalar y_0 = ppt->gstate[ppt->sl].y; + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + + pdf__moveto(p, x_0 + x, y_0 + y); +} + +void +pdf__lineto(PDF *p, pdc_scalar x, pdc_scalar y) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + + pdc_printf(p->out, "%f %f l\n", x, y); + + ppt->gstate[ppt->sl].x = x; + ppt->gstate[ppt->sl].y = y; +} + +void +pdf__rlineto(PDF *p, pdc_scalar x, pdc_scalar y) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_scalar x_0 = ppt->gstate[ppt->sl].x; + pdc_scalar y_0 = ppt->gstate[ppt->sl].y; + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + + pdf__lineto(p, x_0 + x, y_0 + y); +} + +void +pdf__curveto(PDF *p, + pdc_scalar x_1, pdc_scalar y_1, + pdc_scalar x_2, pdc_scalar y_2, + pdc_scalar x_3, pdc_scalar y_3) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_check_number(p->pdc, "x_1", x_1); + pdc_check_number(p->pdc, "y_1", y_1); + pdc_check_number(p->pdc, "x_2", x_2); + pdc_check_number(p->pdc, "y_2", y_2); + pdc_check_number(p->pdc, "x_3", x_3); + pdc_check_number(p->pdc, "y_3", y_3); + + /* second c.p. coincides with final point */ + if (fabs(x_2 - x_3) < PDC_FLOAT_PREC && + fabs(y_2 - y_3) < PDC_FLOAT_PREC) + pdc_printf(p->out, "%f %f %f %f y\n", x_1, y_1, x_3, y_3); + + /* general case with four distinct points */ + else + pdc_printf(p->out, "%f %f %f %f %f %f c\n", + x_1, y_1, x_2, y_2, x_3, y_3); + + ppt->gstate[ppt->sl].x = x_3; + ppt->gstate[ppt->sl].y = y_3; +} + +void +pdf__rcurveto(PDF *p, + pdc_scalar x_1, pdc_scalar y_1, + pdc_scalar x_2, pdc_scalar y_2, + pdc_scalar x_3, pdc_scalar y_3) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_scalar x_0 = ppt->gstate[ppt->sl].x; + pdc_scalar y_0 = ppt->gstate[ppt->sl].y; + + pdc_check_number(p->pdc, "x_1", x_1); + pdc_check_number(p->pdc, "y_1", y_1); + pdc_check_number(p->pdc, "x_2", x_2); + pdc_check_number(p->pdc, "y_2", y_2); + pdc_check_number(p->pdc, "x_3", x_3); + pdc_check_number(p->pdc, "y_3", y_3); + + pdf__curveto(p, x_0 + x_1, y_0 + y_1, + x_0 + x_2, y_0 + y_2, + x_0 + x_3, y_0 + y_3); +} + +void +pdf_rrcurveto(PDF *p, + pdc_scalar x_1, pdc_scalar y_1, + pdc_scalar x_2, pdc_scalar y_2, + pdc_scalar x_3, pdc_scalar y_3) +{ + pdf__rcurveto(p, x_1, y_1, + x_1 + x_2, y_1 + y_2, + x_1 + x_2 + x_3, y_1 + y_2 + y_3); +} + +void +pdf_hvcurveto(PDF *p, pdc_scalar x_1, pdc_scalar x_2, + pdc_scalar y_2, pdc_scalar y_3) +{ + pdf_rrcurveto(p, x_1, 0, x_2, y_2, 0, y_3); +} + +void +pdf_vhcurveto(PDF *p, pdc_scalar y_1, pdc_scalar x_2, + pdc_scalar y_2, pdc_scalar x_3) +{ + pdf_rrcurveto(p, 0, y_1, x_2, y_2, x_3, 0); +} + +void +pdf__rect(PDF *p, pdc_scalar x, pdc_scalar y, + pdc_scalar width, pdc_scalar height) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + pdc_check_number(p->pdc, "width", width); + pdc_check_number(p->pdc, "height", height); + + ppt->gstate[ppt->sl].startx = ppt->gstate[ppt->sl].x = x; + ppt->gstate[ppt->sl].starty = ppt->gstate[ppt->sl].y = y; + + pdf_begin_path(p); + pdc_printf(p->out, "%f %f %f %f re\n", x, y, width, p->ydirection * height); +} + +/* 4/3 * (1-cos 45°)/sin 45° = 4/3 * sqrt(2) - 1 */ +#define ARC_MAGIC (0.552284749) + +static void +pdf_short_arc(PDF *p, pdc_scalar x, pdc_scalar y, pdc_scalar r, + pdc_scalar alpha, pdc_scalar beta) +{ + pdc_scalar bcp; + pdc_scalar cos_alpha, cos_beta, sin_alpha, sin_beta; + + alpha = alpha * PDC_DEG2RAD; + beta = beta * PDC_DEG2RAD; + + /* This formula yields ARC_MAGIC for alpha == 0, beta == 90 degrees */ + bcp = (4.0/3 * (1 - cos((beta - alpha)/2)) / sin((beta - alpha)/2)); + + sin_alpha = sin(alpha); + sin_beta = sin(beta); + cos_alpha = cos(alpha); + cos_beta = cos(beta); + + pdf__curveto(p, + x + r * (cos_alpha - bcp * sin_alpha), /* p1 */ + y + r * (sin_alpha + bcp * cos_alpha), + x + r * (cos_beta + bcp * sin_beta), /* p2 */ + y + r * (sin_beta - bcp * cos_beta), + x + r * cos_beta, /* p3 */ + y + r * sin_beta); +} + +static void +pdf_orient_arc(PDF *p, pdc_scalar x, pdc_scalar y, pdc_scalar r, + pdc_scalar alpha, pdc_scalar beta, pdc_scalar orient) +{ + pdf_ppt *ppt = p->curr_ppt; + pdc_scalar rad_a = alpha * PDC_DEG2RAD; + pdc_scalar startx = (x + r * cos(rad_a)); + pdc_scalar starty = (y + r * sin(rad_a)); + + if (PDF_GET_STATE(p) != pdf_state_path) + { + pdf__moveto(p, startx, starty); /* this enters pdf_state_path */ + } + else if ((ppt->gstate[ppt->sl].x != startx + || ppt->gstate[ppt->sl].y != starty)) + { + pdf__lineto(p, startx, starty); + } + + if (orient > 0) + { + while (beta < alpha) + beta += 360; + + if (alpha == beta) + return; + + while (beta - alpha > 90) + { + pdf_short_arc(p, x, y, r, alpha, alpha + 90); + alpha += 90; + } + } + else + { + while (alpha < beta) + alpha += 360; + + if (alpha == beta) + return; + + while (alpha - beta > 90) + { + pdf_short_arc(p, x, y, r, alpha, alpha - 90); + alpha -= 90; + } + } + + if (alpha != beta) + pdf_short_arc(p, x, y, r, alpha, beta); +} + +void +pdf__arc(PDF *p, pdc_scalar x, pdc_scalar y, pdc_scalar r, + pdc_scalar alpha, pdc_scalar beta) +{ + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + pdc_check_number_limits(p->pdc, "r", r, PDC_FLOAT_PREC, PDC_FLOAT_MAX); + pdc_check_number(p->pdc, "alpha", alpha); + pdc_check_number(p->pdc, "beta", beta); + + pdf_orient_arc(p, x, y, r, + p->ydirection * alpha, p->ydirection * beta, p->ydirection); +} + +void +pdf__arcn(PDF *p, pdc_scalar x, pdc_scalar y, pdc_scalar r, + pdc_scalar alpha, pdc_scalar beta) +{ + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + pdc_check_number_limits(p->pdc, "r", r, PDC_FLOAT_PREC, PDC_FLOAT_MAX); + pdc_check_number(p->pdc, "alpha", alpha); + pdc_check_number(p->pdc, "beta", beta); + + pdf_orient_arc(p, x, y, r, + p->ydirection * alpha, p->ydirection * beta, -p->ydirection); +} + +void +pdf__circle(PDF *p, pdc_scalar x, pdc_scalar y, pdc_scalar r) +{ + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + pdc_check_number_limits(p->pdc, "r", r, PDC_FLOAT_PREC, PDC_FLOAT_MAX); + + /* + * pdf_begin_path() not required since we descend to other + * path segment functions. + */ + + /* draw four Bezier curves to approximate a circle */ + pdf__moveto(p, x + r, y); + pdf__curveto(p, x + r, y + r*ARC_MAGIC, x + r*ARC_MAGIC, y + r, x, y + r); + pdf__curveto(p, x - r*ARC_MAGIC, y + r, x - r, y + r*ARC_MAGIC, x - r, y); + pdf__curveto(p, x - r, y - r*ARC_MAGIC, x - r*ARC_MAGIC, y - r, x, y - r); + pdf__curveto(p, x + r*ARC_MAGIC, y - r, x + r, y - r*ARC_MAGIC, x + r, y); + + pdf__closepath(p); +} + +void +pdf__closepath(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + + pdc_puts(p->out, "h\n"); + + ppt->gstate[ppt->sl].x = ppt->gstate[ppt->sl].startx; + ppt->gstate[ppt->sl].y = ppt->gstate[ppt->sl].starty; +} + +void +pdf__endpath(PDF *p) +{ + pdc_puts(p->out, "n\n"); + pdf_end_path(p); +} + +void +pdf__stroke(PDF *p) +{ + pdc_puts(p->out, "S\n"); + pdf_end_path(p); +} + +void +pdf__closepath_stroke(PDF *p) +{ + pdc_puts(p->out, "s\n"); + pdf_end_path(p); +} + +void +pdf__fill(PDF *p) +{ + if (p->curr_ppt->fillrule == pdf_fill_winding) + pdc_puts(p->out, "f\n"); + else if (p->curr_ppt->fillrule == pdf_fill_evenodd) + pdc_puts(p->out, "f*\n"); + + pdf_end_path(p); +} + +void +pdf__fill_stroke(PDF *p) +{ + if (p->curr_ppt->fillrule == pdf_fill_winding) + pdc_puts(p->out, "B\n"); + else if (p->curr_ppt->fillrule == pdf_fill_evenodd) + pdc_puts(p->out, "B*\n"); + + pdf_end_path(p); +} + +void +pdf__closepath_fill_stroke(PDF *p) +{ + if (p->curr_ppt->fillrule == pdf_fill_winding) + pdc_puts(p->out, "b\n"); + else if (p->curr_ppt->fillrule == pdf_fill_evenodd) + pdc_puts(p->out, "b*\n"); + + pdf_end_path(p); +} + +void +pdf__clip(PDF *p) +{ + if (p->curr_ppt->fillrule == pdf_fill_winding) + pdc_puts(p->out, "W n\n"); + else if (p->curr_ppt->fillrule == pdf_fill_evenodd) + pdc_puts(p->out, "W* n\n"); + + pdf_end_path(p); +} + diff --git a/src/pdflib/pdflib/p_encoding.c b/src/pdflib/pdflib/p_encoding.c new file mode 100644 index 0000000..af24792 --- /dev/null +++ b/src/pdflib/pdflib/p_encoding.c @@ -0,0 +1,187 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_encoding.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib encoding handling routines + * + */ + +#include "p_intern.h" +#include "p_font.h" + +void +pdf__encoding_set_char(PDF *p, const char *encoding, int slot, + const char *glyphname, int uv) +{ + int enc; + pdc_encodingvector *ev; + char given; + + if (!encoding || !*encoding) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "encoding", 0, 0, 0); + + if (slot < 0 || slot > 255) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "slot", pdc_errprintf(p->pdc, "%d", slot), 0, 0); + + if (uv < 0 || uv >= PDC_NUM_BMPVAL) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "uv", pdc_errprintf(p->pdc, "%d", uv), 0, 0); + + if (!glyphname || !*glyphname) + { + if (uv == 0) + pdc_error(p->pdc, PDF_E_ENC_GLYPHORCODE, 0, 0, 0, 0); + } + + for (enc = (int) pdc_invalidenc + 1; enc < (int) pdc_firstvarenc; enc++) + { + if (!strcmp(encoding, pdc_get_fixed_encoding_name((pdc_encoding) enc))) + pdc_error(p->pdc, PDF_E_ENC_CANTCHANGE, encoding, 0, 0, 0); + } + + if (uv == 0) + { + given = 1; + uv = (int) pdc_insert_glyphname(p->pdc, glyphname); + } + else if (!glyphname || !*glyphname) + { + given = 0; + glyphname = pdc_insert_unicode(p->pdc, (pdc_ushort) uv); + } + else + { + const char *reg_glyphname; + pdc_ushort reg_uv; + int retval; + + given = 1; + reg_glyphname = pdc_unicode2glyphname(p->pdc, (pdc_ushort) uv); + if (reg_glyphname) + { + if (strcmp(reg_glyphname, glyphname) && + p->debug[(int) 'F'] == pdc_true) + { + pdc_warning(p->pdc, PDF_E_ENC_BADGLYPH, + glyphname, + pdc_errprintf(p->pdc, "%04X", uv), + reg_glyphname, 0); + } + + /* We take the registered name */ + } + else + { + retval = pdc_glyphname2unicode(p->pdc, glyphname); + if (retval > -1) + { + reg_uv = (pdc_ushort) retval; + if (reg_uv && reg_uv != (pdc_ushort) uv && + p->debug[(int) 'F'] == pdc_true) + { + pdc_error(p->pdc, PDF_E_ENC_BADUNICODE, + pdc_errprintf(p->pdc, "%04X", uv), glyphname, + pdc_errprintf(p->pdc, "%04X", reg_uv), 0); + } + } + + /* We register the new glyph name and unicode value */ + pdc_register_glyphname(p->pdc, glyphname, (pdc_ushort) uv, + pdc_false); + } + } + + /* search for a registered encoding */ + enc = pdc_find_encoding(p->pdc, encoding); + + /* not found */ + if (enc == pdc_invalidenc) + { + ev = pdc_new_encoding(p->pdc, encoding); + ev->flags |= PDC_ENC_USER; + ev->flags |= PDC_ENC_SETNAMES; + ev->flags |= PDC_ENC_ALLOCCHARS; + + enc = pdc_insert_encoding_vector(p->pdc, ev); + } + + /* encoding vector */ + ev = pdc_get_encoding_vector(p->pdc, (pdc_encoding)enc); + if (!(ev->flags & PDC_ENC_USER)) + { + pdc_error(p->pdc, PDF_E_ENC_CANTCHANGE, encoding, 0, 0, 0); + } + else if (ev->flags & PDC_ENC_USED) + { + pdc_error(p->pdc, PDF_E_ENC_INUSE, encoding, 0, 0, 0); + } + + /* Free character name */ + if (ev->chars[slot] != NULL) + pdc_free(p->pdc, ev->chars[slot]); + + /* Saving */ + ev->codes[slot] = (pdc_ushort) uv; + if (glyphname != NULL) + ev->chars[slot] = pdc_strdup(p->pdc, glyphname); + ev->given[slot] = given; + + pdc_encoding_logg_protocol(p->pdc, ev); +} + +pdc_encoding +pdf_get_hypertextencoding_param(PDF *p, int *codepage) +{ + if (p->hypertextencoding == pdc_invalidenc) + { + p->hypertextencoding = pdf_get_hypertextencoding(p, "auto", + &p->hypertextcodepage, pdc_true); + + if (p->hypertextencoding == pdc_invalidenc) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + } + + if (codepage) + *codepage = p->hypertextcodepage; + + return p->hypertextencoding; +} + +pdc_encoding +pdf_get_hypertextencoding(PDF *p, const char *encoding, int *codepage, + pdc_bool verbose) +{ + pdc_encoding enc = pdc_invalidenc; + + *codepage = 0; + + if (!*encoding) + { + enc = pdc_unicode; + } + else + { + { + enc = pdc_get_encoding(p->pdc, encoding, codepage, verbose); + if (enc < 0 && enc != pdc_invalidenc && enc != pdc_unicode) + { + pdc_set_errmsg(p->pdc, PDF_E_ENC_BADHYPTEXTENC, encoding, + 0, 0, 0); + enc = pdc_invalidenc; + } + } + } + + return enc; +} diff --git a/src/pdflib/pdflib/p_fields.c b/src/pdflib/pdflib/p_fields.c new file mode 100644 index 0000000..4900b3b --- /dev/null +++ b/src/pdflib/pdflib/p_fields.c @@ -0,0 +1,30 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_fields.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib form fields handling routines + * + */ + +#define P_FIELDS_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_font.h" +#include "p_image.h" + + + + + + diff --git a/src/pdflib/pdflib/p_filter.c b/src/pdflib/pdflib/p_filter.c new file mode 100644 index 0000000..d5a11a6 --- /dev/null +++ b/src/pdflib/pdflib/p_filter.c @@ -0,0 +1,120 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_filter.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Compressed and uncompressed stream output + * + */ + +#include "p_intern.h" + +/* methods for constructing a data source from a file */ + +#define FILE_BUFSIZE 1024 + +void +pdf_data_source_file_init(PDF *p, PDF_data_source *src) +{ + pdc_file *fp; + + src->buffer_length = FILE_BUFSIZE; + src->buffer_start = (pdc_byte *) + pdc_malloc(p->pdc, src->buffer_length, "pdf_data_source_file_init"); + + fp = pdc_fsearch_fopen(p->pdc, (const char *) src->private_data, NULL, + "embedded ", PDC_FILE_BINARY); + + if (fp == NULL) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + + if (src->offset) + pdc_fseek(fp, src->offset, SEEK_SET); + + src->private_data = (void *) fp; + src->total = (long) 0; +} + +pdc_bool +pdf_data_source_file_fill(PDF *p, PDF_data_source *src) +{ + size_t bytes_needed; + (void) p; /* avoid compiler warning "unreferenced parameter" */ + + if (src->length != (long) 0 && src->total + FILE_BUFSIZE > src->length) + bytes_needed = (size_t) (src->length - src->total); + else + bytes_needed = FILE_BUFSIZE; + + src->next_byte = src->buffer_start; + src->bytes_available = pdc_fread(src->buffer_start, 1, + bytes_needed, (pdc_file *) (src->private_data)); + + src->total += (long) src->bytes_available; + + if (src->bytes_available == 0) + return pdc_false; + else + return pdc_true; +} + +void +pdf_data_source_file_terminate(PDF *p, PDF_data_source *src) +{ + pdc_free(p->pdc, (void *) src->buffer_start); + pdc_fclose((pdc_file *) src->private_data); + + if (src->length != (long) 0 && src->total != src->length) + pdc_error(p->pdc, PDC_E_IO_READ, "?", 0, 0, 0); +} + +/* methods for constructing a data source from a memory buffer */ + +int +pdf_data_source_buf_fill(PDF *p, PDF_data_source *src) +{ + (void) p; /* avoid compiler warning "unreferenced parameter" */ + + if (src->next_byte == NULL) { + src->next_byte = src->buffer_start; + src->bytes_available = src->buffer_length; + return pdc_true; + } + + return pdc_false; +} + +/* copy the complete contents of src to a stream */ +void +pdf_copy_stream(PDF *p, PDF_data_source *src, pdc_bool compress) +{ + int oldcompresslevel = pdc_get_compresslevel(p->out); + + if (!compress) + pdc_set_compresslevel(p->out, 0); + + if (src->init) + src->init(p, src); + + pdc_begin_pdfstream(p->out); + + while (src->fill(p, src)) + pdc_write(p->out, src->next_byte, src->bytes_available); + + pdc_end_pdfstream(p->out); + + if (src->terminate) + src->terminate(p, src); + + if (!compress) + pdc_set_compresslevel(p->out, oldcompresslevel); +} diff --git a/src/pdflib/pdflib/p_font.c b/src/pdflib/pdflib/p_font.c new file mode 100644 index 0000000..5dfce77 --- /dev/null +++ b/src/pdflib/pdflib/p_font.c @@ -0,0 +1,2513 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_font.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib font handling routines + * + */ + +#define P_FONT_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_defopt.h" +#include "p_font.h" +#include "p_tagged.h" + +#include "ft_truetype.h" + + +#define PDF_TTC_SEPARATOR ':' + +static const pdc_keyconn pdf_fonttype_pdfkeylist[] = +{ + {"Type1", fnt_Type1}, + {"MMType1", fnt_MMType1}, + {"TrueType", fnt_TrueType}, + {"Type0", fnt_CIDFontType2}, + {"Type1", fnt_Type1C}, + {"Type0", fnt_CIDFontType0}, + {"Type3", fnt_Type3}, + {NULL, 0} +}; + +typedef enum +{ + font_afm = 1, + font_pfm = 2, + font_ttot = 3, + font_pfab = 4 +} +pdf_fontfile_type; + +static const pdc_keyconn pdf_extension_names[] = +{ + {".tte", font_ttot}, + {".ttf", font_ttot}, + {".otf", font_ttot}, + {".afm", font_afm}, + {".pfm", font_pfm}, + {".ttc", font_ttot}, + {".TTE", font_ttot}, + {".TTF", font_ttot}, + {".OTF", font_ttot}, + {".AFM", font_afm}, + {".PFM", font_pfm}, + {".TTC", font_ttot}, + {".pfa", font_pfab}, + {".pfb", font_pfab}, + {".PFA", font_pfab}, + {".PFB", font_pfab}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_fontoption_keylist[] = +{ + {"fontname", fo_fontname}, + {"encoding", fo_encoding}, + {"fontstyle", fo_fontstyle}, + {"monospace", fo_monospace}, + {NULL, 0} +}; + + +void +pdf_init_font(PDF *p, pdf_font *font, pdf_font_options *fo) +{ + (void) p; + + /* font metric */ + fnt_init_font(&font->ft); + + /* font options */ + font->opt = *fo; + font->verbose = fo->fontwarning; + + font->apiname = NULL; + font->filename = NULL; + font->metricfilename = NULL; + + font->used_in_formfield = pdc_false; + font->used_in_current_doc = pdc_false; + font->used_on_current_page = pdc_false; + font->obj_id = PDC_BAD_ID; + + font->cff_offset = 0; + font->cff_length = 0; + + font->t3font = NULL; + font->hasoriginal = pdc_false; + + font->encapiname = NULL; + font->outcmapname = NULL; + font->codepage = 0; + font->towinansi = pdc_invalidenc; + font->hasnomac = pdc_false; + font->passthrough = pdc_false; + font->unibyte = pdc_false; + font->asciispace = pdc_false; + font->issemantic = pdc_false; + font->widthsmissing = pdc_false; + font->missingglyphs = 0; + font->metricflags = 0; + font->supplement = 0; + font->symenc = pdc_invalidenc; + font->replacementchar = -1; + font->replacementcode = -1; + + font->codesize = 1; + font->lastcode = -1; + font->gid0code = -1; + font->usedgids = NULL; + font->expectglyphs = pdc_false; + font->iscidfont = pdc_false; + +} + +void +pdf_cleanup_font(PDF *p, pdf_font *font) +{ + if (font->ft.imgname) + pdc_unlock_pvf(p->pdc, font->ft.imgname); + + /* font metric */ + fnt_cleanup_font(p->pdc, &font->ft); + + if (font->apiname != NULL) + { + pdc_free(p->pdc, font->apiname); + font->apiname = NULL; + } + + if (font->metricfilename != NULL) + { + pdc_free(p->pdc, font->metricfilename); + font->metricfilename = NULL; + } + + if (font->encapiname != NULL) + { + pdc_free(p->pdc, font->encapiname); + font->encapiname = NULL; + } + + if (font->outcmapname != NULL) + { + pdc_free(p->pdc, font->outcmapname); + font->outcmapname = NULL; + } + + + if (font->usedgids != NULL) + { + pdc_free(p->pdc, font->usedgids); + font->usedgids = NULL; + } + + /* Type3 font */ + if (font->t3font != NULL && font->hasoriginal) + { + pdf_cleanup_t3font(p, font->t3font); + pdc_free(p->pdc, font->t3font); + font->t3font = NULL; + } + +} + +void +pdf_init_fonts(PDF *p) +{ + p->fonts = NULL; + p->fonts_number = 0; + p->fonts_capacity = 0; + p->t3slot = -1; + + + pdc_init_encoding_info_ids(p->pdc); +} + +void +pdf_cleanup_fonts(PDF *p) +{ + int slot; + + if (p->fonts != NULL) + { + for (slot = 0; slot < p->fonts_number; slot++) + pdf_cleanup_font(p, &p->fonts[slot]); + + pdc_free(p->pdc, p->fonts); + p->fonts = NULL; + } + +} + +int +pdf_insert_font(PDF *p, pdf_font *font) +{ + static const char fn[] = "pdf_insert_font"; + int slot = p->fonts_number; + + /* insert font */ + if (p->fonts_number == p->fonts_capacity) + { + if (p->fonts_capacity == 0) + { + p->fonts_capacity = FONTS_CHUNKSIZE; + p->fonts = (pdf_font *) pdc_calloc(p->pdc, + sizeof(pdf_font) * p->fonts_capacity, fn); + } + else + { + p->fonts_capacity *= 2; + p->fonts = (pdf_font *) pdc_realloc(p->pdc, p->fonts, + sizeof(pdf_font) * p->fonts_capacity, fn); + } + } + p->fonts[slot] = *font; + + p->fonts_number++; + + return slot; +} + + +const char * +pdf_get_pdf_fontname(pdf_font *font) +{ + const char *fontname; + + fontname = fnt_get_abb_std_fontname(font->ft.name); + if (fontname == NULL) + fontname = fnt_get_abb_cjk_fontname(font->ft.name); + if (fontname == NULL) + fontname = font->ft.name; + + return (const char *) fontname; +} + +const char * +pdf_get_encoding_name(PDF *p, pdc_encoding enc, pdf_font *font) +{ + const char *apiname = pdc_get_fixed_encoding_name(enc); + if (!apiname[0] && enc >= 0) + { + pdc_encodingvector *ev = pdc_get_encoding_vector(p->pdc, enc); + apiname = (const char *) ev->apiname; + } + else if (enc == pdc_cid && font != NULL && font->outcmapname != NULL) + apiname = (const char *) font->outcmapname; + return apiname; +} + +char * +pdf_get_encoding_adaptname(PDF *p, pdc_encoding enc, pdf_font *font, + const char *fontname) +{ + static const char *fn = "pdf_get_encoding_adaptname"; + char *encname = (char *) pdf_get_encoding_name(p, enc, font); + char *adaptname = NULL; + size_t len; + + len = strlen(encname) + 1 + strlen(fontname) + 1; + adaptname = (char *) pdc_malloc_tmp(p->pdc, len, fn, 0, 0); + strcpy(adaptname, encname); + strcat(adaptname, PDC_ENC_MODSEPAR); + strcat(adaptname, fontname); + + return adaptname; +} + +pdc_encodingvector * +pdf_create_font_encoding(PDF *p, pdc_encoding enc, pdf_font *font, + const char *fontname, pdc_bool kreg) +{ + pdc_encodingvector *ev = NULL; + char *adaptname = NULL; + + adaptname = pdf_get_encoding_adaptname(p, enc, font, fontname); + + /* search for a registered encoding */ + enc = pdc_find_encoding(p->pdc, adaptname); + if (enc != pdc_invalidenc) + { + font->ft.enc = enc; + } + else + { + /* create a font encoding */ + ev = pdc_new_encoding(p->pdc, adaptname); + ev->flags |= PDC_ENC_FONT; + ev->flags |= PDC_ENC_SETNAMES; + + if (kreg) + { + enc = pdc_insert_encoding_vector(p->pdc, ev); + font->ft.enc = enc; + } + } + + pdc_free_tmp(p->pdc, adaptname); + + return ev; +} + +const char * +pdf_get_font_char_option(PDF *p, pdf_font_optflags fflags) +{ + pdf_text_options *to = p->curr_ppt->currto; + pdf_font *currfont; + + if (p->fonts_number == 0 || to->font == -1) + pdc_error(p->pdc, PDF_E_TEXT_NOFONT_PAR, + pdc_get_keyword(fflags, pdf_fontoption_keylist), 0, 0, 0); + currfont = &p->fonts[to->font]; + + switch (fflags) + { + case fo_fontname: + return (const char *) currfont->ft.name; + + case fo_encoding: + return pdf_get_encoding_name(p, currfont->ft.enc, currfont); + + case fo_fontstyle: + return pdc_get_keyword(currfont->opt.fontstyle, + pdf_fontstyle_pdfkeylist); + + default: + return NULL; + } +} + +double +pdf_get_font_float_option(PDF *p, pdf_font_optflags fflags) +{ + pdf_text_options *to = p->curr_ppt->currto; + pdf_font *currfont; + + if (p->fonts_number == 0 || to->font == -1) + pdc_error(p->pdc, PDF_E_TEXT_NOFONT_PAR, + pdc_get_keyword(fflags, pdf_fontoption_keylist), 0, 0, 0); + currfont = &p->fonts[to->font]; + + switch (fflags) + { + case fo_monospace: + return (double) currfont->opt.monospace; + + default: + return 0; + } +} + +static const pdc_keyconn pdf_courier_keylist[] = +{ + {"Courier", fnt_Normal}, + {"Courier-Bold", fnt_Bold}, + {"Courier-Oblique", fnt_Italic}, + {"Courier-BoldOblique", fnt_BoldItalic}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_helvetica_keylist[] = +{ + {"Helvetica", fnt_Normal}, + {"Helvetica-Bold", fnt_Bold}, + {"Helvetica-Oblique", fnt_Italic}, + {"Helvetica-BoldOblique", fnt_BoldItalic}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_times_keylist[] = +{ + {"Times-Roman", fnt_Normal}, + {"Times-Bold", fnt_Bold}, + {"Times-Italic", fnt_Italic}, + {"Times-BoldItalic", fnt_BoldItalic}, + {NULL, 0} +}; + +static const char * +pdf_get_fontname_core(pdf_font *font, const char *fontname, pdc_bool checktimes) +{ + const char *fname = NULL; + + /* font style for core fonts */ + if (font->opt.fontstyle != fnt_Normal) + { + if (!strcmp(fontname, "Courier")) + fname = pdc_get_keyword(font->opt.fontstyle, pdf_courier_keylist); + else if (!strcmp(fontname, "Helvetica")) + fname = pdc_get_keyword(font->opt.fontstyle, pdf_helvetica_keylist); + else if (!strcmp(fontname, "Times-Roman")) + fname = pdc_get_keyword(font->opt.fontstyle, pdf_times_keylist); + } + + if (checktimes) + { + if (!strcmp(fontname, "Times")) + fname = pdc_get_keyword(font->opt.fontstyle, pdf_times_keylist); + } + + return fname; +} + +static pdc_bool +pdf_get_metrics_core(PDF *p, pdf_font *font, const char *fontname, + pdc_encoding enc, pdc_bool checktimes) +{ + const char *fname = NULL; + const fnt_font_metric *ftm; + + fname = pdf_get_fontname_core(font, fontname, checktimes); + if (fname != NULL) + { + fontname = fname; + font->opt.fontstyle = fnt_Normal; + } + + ftm = fnt_get_core_metric(fontname); + if (ftm != NULL) + { + pdc_logg_cond(p->pdc, 1, trc_font, + "\tLoading metrics data for core font \"%s\":\n", fontname); + + /* Fill up the font struct */ + fnt_fill_font_metric(p->pdc, &font->ft, + pdc_false, + ftm); + font->ft.enc = enc; + + /* all new glyph names of AGL 2.0 are missing */ + font->missingglyphs = 0xFFFFFFFF; + + /* Process metrics data */ + if (pdf_process_metrics_data(p, font, fontname)) + { + if (pdf_make_fontflag(p, font)) + { + if (!font->opt.monospace) + return pdc_true; + else + pdc_set_errmsg(p->pdc, PDC_E_OPT_IGNORED, "monospace", + 0, 0, 0); + } + } + + return pdc_false; + } + + return pdc_undef; +} + +void +pdf_font_set_missvalues(PDF *p, pdf_font *font) +{ + pdf_font_options *fo = &font->opt; + fnt_font_metric *ftm = &font->ft.m; + + (void) p; + + if (ftm->descender > 0) + ftm->descender = -(ftm->descender); + + if (fo->mask & (1L << fo_ascender)) + { + font->metricflags |= font_ascender; + ftm->ascender = fo->ascender; + } + else if (ftm->ascender <= 0) + { + font->metricflags |= font_ascender; + ftm->ascender = 720; + } + + if (fo->mask & (1L << fo_descender)) + { + font->metricflags |= font_descender; + ftm->descender = fo->descender; + } + else if (ftm->descender == FNT_MISSING_FONTVAL) + { + font->metricflags |= font_descender; + ftm->descender = (int) PDC_ROUND(-0.25 * ftm->ascender); + } + + if (fo->mask & (1L << fo_capheight)) + { + font->metricflags |= font_capheight; + ftm->capHeight = fo->capheight; + } + else if (ftm->capHeight <= 0) + { + font->metricflags |= font_capheight; + ftm->capHeight = (int) PDC_ROUND(0.93 * ftm->ascender); + } + + if (fo->mask & (1L << fo_xheight)) + { + font->metricflags |= font_xheight; + ftm->xHeight = fo->xheight; + } + else if (ftm->xHeight <= 0) + { + font->metricflags |= font_xheight; + ftm->xHeight = (int) PDC_ROUND(0.66 * ftm->ascender); + } + + if (fo->mask & (1L << fo_linegap)) + { + font->metricflags |= font_linegap; + font->ft.linegap = fo->linegap; + } + else if (font->ft.linegap == FNT_MISSING_FONTVAL) + { + font->metricflags |= font_linegap; + font->ft.linegap = (int) PDC_ROUND(0.23 * ftm->ascender); + } + + if (ftm->llx == FNT_MISSING_FONTVAL) + ftm->llx = -50; + if (ftm->lly == FNT_MISSING_FONTVAL) + ftm->lly = ftm->descender; + if (ftm->urx == FNT_MISSING_FONTVAL) + ftm->urx = 1000; + if (ftm->ury == FNT_MISSING_FONTVAL) + ftm->ury = ftm->ascender; + + /* try to fix broken entries */ + if (ftm->lly > ftm->ury) + ftm->ury = ftm->lly + ftm->ascender; + if (ftm->llx > ftm->urx) + ftm->urx = ftm->llx + 1000; +} + +pdc_bool +pdf_font_get_is_faked(pdf_font *font, pdf_font_values flag) +{ + return (font->metricflags & flag) ? pdc_true : pdc_false; +} + +double +pdf_font_get_metric_value(int value) +{ + return (double) value / 1000.0; +} + + +/* --------------------------- font processing ---------------------------- */ + +pdc_bool +pdf_make_fontflag(PDF *p, pdf_font *font) +{ + int errcode = 0; + + if (font->ft.m.type != fnt_Type3) + { + if (font->ft.m.isFixedPitch) + font->ft.m.flags |= FNT_FIXEDWIDTH; + + if (font->ft.issymbfont == pdc_false || + font->ft.enc == pdc_winansi || + font->ft.enc == pdc_macroman || + font->ft.enc == pdc_ebcdic || + font->ft.enc == pdc_ebcdic_37 || + font->ft.enc == pdc_ebcdic_winansi) + font->ft.m.flags |= FNT_ADOBESTANDARD; + else + font->ft.m.flags |= FNT_SYMBOL; + + if (font->ft.m.italicAngle < 0 || + font->opt.fontstyle == fnt_Italic || + font->opt.fontstyle == fnt_BoldItalic) + font->ft.m.flags |= FNT_ITALIC; + if (font->ft.m.italicAngle == 0 && + font->ft.m.flags & FNT_ITALIC) + font->ft.m.italicAngle = FNT_DEF_ITALICANGLE; + + /* heuristic to identify (small) caps fonts */ + if (font->ft.name && + (strstr(font->ft.name, "Caps") || + !strcmp(font->ft.name + strlen(font->ft.name) - 2, "SC"))) + font->ft.m.flags |= FNT_SMALLCAPS; + + if (font->opt.fontstyle == fnt_Bold || + font->opt.fontstyle == fnt_BoldItalic) + font->ft.weight = FNT_FW_BOLD; + + if (strstr(font->ft.name, "Bold") || + font->ft.weight >= FNT_FW_BOLD) + font->ft.m.flags |= FNT_FORCEBOLD; + + /* determine values for FontWeight to StemV */ + if (font->ft.m.StdVW == 0) + font->ft.m.StdVW = fnt_weight2stemv(font->ft.weight); + else if (font->ft.weight == 0) + font->ft.weight = fnt_stemv2weight(font->ft.m.StdVW); + } + + fnt_font_logg_protocol(p->pdc, &font->ft); + + switch(font->ft.m.type) + { + case fnt_Type1: + case fnt_MMType1: + case fnt_Type3: + if (font->opt.fontstyle == fnt_Bold || + font->opt.fontstyle == fnt_BoldItalic) + { + font->metricflags |= font_bold; + } + + if (font->opt.fontstyle == fnt_Italic || + font->opt.fontstyle == fnt_BoldItalic) + { + font->metricflags |= font_italic; + } + + break; + + default: + if (font->opt.embedding) + { + if (font->opt.fontstyle == fnt_Bold || + font->opt.fontstyle == fnt_BoldItalic) + { + font->metricflags |= font_bold; + } + + if (font->opt.fontstyle == fnt_Italic || + font->opt.fontstyle == fnt_BoldItalic) + { + font->metricflags |= font_italic; + } + } + break; + } + + + return errcode ? pdc_false : pdc_true; +} + +int +pdf_get_code_or_glyphid(PDF *p, pdf_font *font, pdc_encodingvector *ev, + pdc_ushort uv) +{ + if (ev != NULL) + { + int code = pdc_get_encoding_bytecode(p->pdc, ev, uv); + + if (code >= 0) + { + if (fnt_get_glyphid(code, &font->ft) <= 0) + code = 0; + } + return code; + } + + return fnt_get_glyphid((int) uv, &font->ft); +} + +void +pdf_set_replchar(PDF *p, pdf_font *font) +{ + pdc_encoding enc = font->ft.enc; + + switch (enc) + { + case pdc_glyphid: + case pdc_cid: + return; + + case pdc_builtin: + font->replacementcode = 0; + return; + + case pdc_unicode: + default: + { + pdc_encodingvector *ev = pdc_get_encoding_vector(p->pdc, enc); + pdc_ushort uv = 0; + int cg = 0; + uv = PDC_UNICODE_NBSP; + cg = pdf_get_code_or_glyphid(p, font, ev, uv); + if (cg <= 0) + { + uv = PDC_UNICODE_SPACE; + cg = pdf_get_code_or_glyphid(p, font, ev, uv); + if (cg <= 0) + { + uv = 0; + cg = 0; + } + } + + font->replacementchar = (int) uv; + font->replacementcode = cg; + } + return; + } +} + +void +pdf_font_issemantic(PDF *p, pdf_font *font) +{ + pdc_encoding enc = font->ft.enc; + pdc_ushort spacechar = 0; + + /* Flag: encoding with ASCII space for wordspacing */ + if (enc >= 0) + { + pdc_encodingvector *ev = pdc_get_encoding_vector(p->pdc, enc); + int i; + + ev->flags |= PDC_ENC_USED; + i = pdc_get_encoding_bytecode(p->pdc, ev, PDC_UNICODE_SPACE); + if (i > -1) + { + spacechar = (pdc_ushort) i; + if (spacechar == PDC_UNICODE_SPACE) + font->asciispace = pdc_true; + } + } + + /* Flag: encoding is Unicode interpretable */ + if ((enc >= 0) || + (enc == pdc_cid && font->codesize == 2) || + (enc == pdc_unicode)) + font->issemantic = pdc_true; + + /* determine code of space character */ + switch(enc) + { + case pdc_cid: + if (font->codesize == 2) + font->ft.spacechar = PDC_UNICODE_SPACE; + break; + + case pdc_unicode: + font->ft.spacechar = PDC_UNICODE_SPACE; + break; + + case pdc_glyphid: + font->ft.spacechar = + (pdc_ushort) MAX(fnt_get_glyphid(PDC_UNICODE_SPACE, &font->ft), 0); + break; + + default: + font->ft.spacechar = spacechar; + break; + } +} + +/* definitions of font options */ +static const pdc_defopt pdf_load_font_options[] = +{ + PDF_FONT_OPTIONS2 + PDF_FONT_OPTIONS3 + PDF_ERRORPOLICY_OPTION + PDC_OPT_TERMINATE +}; + +void +pdf_init_font_options(PDF *p, pdf_font_options *fo) +{ + static const char fn[] = "pdf_init_font_options"; + + if (fo == NULL) + { + p->currfo = (pdf_font_options *) pdc_malloc(p->pdc, + sizeof(pdf_font_options), fn); + + + fo = p->currfo; + } + else + { + } + + + fo->embedding = pdc_false; /* default true if CID custom font */ + fo->encoding = NULL; + fo->flags = 0; + fo->fontname = NULL; + fo->fontstyle = fnt_Normal; + fo->fontwarning = p->debug[(int) 'F']; + fo->fontwarning = pdf_get_errorpolicy(p, NULL, fo->fontwarning); + fo->mask = 0; + fo->monospace = 0; + fo->ascender = 0; + fo->descender = 0; + fo->capheight = 0; + fo->xheight = 0; + fo->linegap = 0; + fo->auxiliary = pdc_false; + +} + +void +pdf_cleanup_font_curroptions(PDF *p) +{ + if (p->currfo) + { + pdc_free(p->pdc, p->currfo); + p->currfo = NULL; + } +} + +void +pdf_cleanup_font_options(PDF *p, pdf_font_options *fo) +{ + if (fo->fontname != NULL) + { + pdc_free(p->pdc, fo->fontname); + fo->fontname = NULL; + } + + if (fo->encoding != NULL) + { + pdc_free(p->pdc, fo->encoding); + fo->encoding = NULL; + } +} + +void +pdf_parse_font_options(PDF *p, const char *optlist) +{ + pdc_resopt *resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_load_font_options, NULL, pdc_true); + + pdf_get_font_options(p, p->currfo, resopts); + pdc_cleanup_optionlist(p->pdc, resopts); +} + +void +pdf_get_font_options(PDF *p, pdf_font_options *fo, pdc_resopt *resopts) +{ + int inum; + + (void) p; + + if (fo->flags & is_block || + fo->flags & is_textline || + fo->flags & is_textflow) + { + if (pdc_get_optvalues("fontname", resopts, NULL, NULL)) + { + fo->fontname = (char *)pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + fo->mask |= (1L << fo_fontname); + } + + if (pdc_get_optvalues("encoding", resopts, NULL, NULL)) + { + fo->encoding = (char *)pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + fo->mask |= (1L << fo_encoding); + } + } + + if (pdc_get_optvalues("fontwarning", resopts, &fo->fontwarning, NULL)) + fo->mask |= (1L << fo_fontwarning); + fo->fontwarning = pdf_get_errorpolicy(p, resopts, fo->fontwarning); + + if (pdc_get_optvalues("embedding", resopts, &fo->embedding, NULL)) + fo->mask |= (1L << fo_embedding); + + + if (pdc_get_optvalues("fontstyle", resopts, &inum, NULL)) + { + fo->fontstyle = (fnt_fontstyle) inum; + fo->mask |= (1L << fo_fontstyle); + } + + if (pdc_get_optvalues("monospace", resopts, &fo->monospace, NULL)) + fo->mask |= (1L << fo_monospace); + + if (pdc_get_optvalues("ascender", resopts, &fo->ascender, NULL)) + fo->mask |= (1L << fo_ascender); + + if (pdc_get_optvalues("descender", resopts, &fo->descender, NULL)) + fo->mask |= (1L << fo_descender); + + if (pdc_get_optvalues("capheight", resopts, &fo->capheight, NULL)) + fo->mask |= (1L << fo_capheight); + + if (pdc_get_optvalues("xheight", resopts, &fo->xheight, NULL)) + fo->mask |= (1L << fo_xheight); + + if (pdc_get_optvalues("linegap", resopts, &fo->linegap, NULL)) + fo->mask |= (1L << fo_linegap); + +} + +int +pdf__load_font(PDF *p, const char *fontname, int inlen, + const char *encoding, const char *optlist) +{ + int slot; + pdf_font_options fo; + + if (encoding == NULL || *encoding == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "encoding", 0, 0, 0); + + if (fontname == NULL) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0); + + /* initialize */ + pdf_init_font_options(p, &fo); + + /* Converting fontname */ + fo.fontname = (char *) pdf_convert_name(p, fontname, inlen, + PDC_CONV_WITHBOM); + if (fo.fontname == NULL || *fo.fontname == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0); + + /* encoding */ + fo.encoding = (char *) pdc_strdup(p->pdc, encoding); + + /* parsing option list */ + if (optlist && strlen(optlist)) + { + pdc_resopt *resopts; + pdc_clientdata data; + + pdf_set_clientdata(p, &data); + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_load_font_options, &data, pdc_true); + if (!resopts) + { + pdf_cleanup_font_options(p, &fo); + return -1; + } + + pdf_get_font_options(p, &fo, resopts); + pdc_cleanup_optionlist(p->pdc, resopts); + } + + slot = pdf_load_font_internal(p, &fo); + return slot; +} + +static void +pdf_check_font_identical(PDF *p, pdf_font *font, int *slot) +{ + pdf_font *oldfont = &p->fonts[*slot]; + const char *optname = NULL; + + if (!oldfont->opt.embedding && font->opt.embedding) + { + optname = "embedding"; + if (p->errorpolicy == errpol_legacy) + { + pdc_warning(p->pdc, PDF_E_FONT_NOTFULFILL, optname, optname, + 0, 0); + } + else + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_NOTFULFILL, optname, optname, + 0, 0); + *slot = -1; + } + } + +} + +pdc_bool +pdf_check_font_embedding(PDF *p, pdf_font *font, const char *fontname) +{ + (void) p; + (void) font; + (void) fontname; + + + + return pdc_true; +} + +int +pdf_load_font_internal(PDF *p, pdf_font_options *fo) +{ + pdc_bool logg2 = pdc_logg_is_enabled(p->pdc, 2, trc_font); + const char *fontname; + const char *encoding; + const char *encoding_aux; + pdc_encoding enc = pdc_invalidenc; + pdf_font tmpfont, *font; + const char *filename = NULL; + const char *extension = NULL; + const char *outfilename = NULL; + char *fontname_p = NULL; + char testfilename[PDF_MAX_FONTNAME + 5]; + char *sf, *mmparam, mastername[PDF_MAX_FONTNAME + 1]; + char ittc; + size_t len; + pdc_bool retval = pdc_false; + int slot = -1, i; + + /* host or UTF-8 encoded font name without BOM */ + fontname_p = pdc_utf8_to_hostbytes(p->pdc, pdc_false, fo->fontname); + if (fontname_p == NULL) + { + fontname = pdc_utf8strprint(p->pdc, fo->fontname); + } + else + { + fontname = pdc_utf8strprint(p->pdc, fontname_p); + pdc_free(p->pdc, fontname_p); + } + fontname_p = NULL; + + /* font encoding */ + encoding = fo->encoding; + encoding_aux = encoding; + + /* initialize font struct */ + font = &tmpfont; + pdf_init_font(p, font, fo); + + /* error message prefix */ + pdc_push_errmsg(p->pdc, PDF_E_FONT_PREFIX, fontname, encoding, 0, 0); + + + + + /* API font name */ + font->apiname = pdc_strdup(p->pdc, fontname); + + /* UTF-8 font name with BOM */ + font->ft.utf8name = pdc_strdup(p->pdc, fo->fontname); + + pdc_logg_cond(p->pdc, 1, trc_font, "\tFont UTF-8 name: \"%s\"\n", + font->ft.utf8name); + + /* specified encoding name */ + font->encapiname = pdc_strdup(p->pdc, encoding); + + /* search for a registered encoding */ + enc = pdc_find_encoding(p->pdc, encoding); + if (enc == pdc_invalidenc || enc == pdc_unicode) + { + /* search for a predefined CMap and registered fonts */ + if (!pdf_handle_cidfont(p, fontname, encoding, enc, font, &slot, &enc)) + goto PDF_PREMATURE_EXIT; + + if (enc == pdc_invalidenc) + { + /* search for a new encoding */ + enc = pdc_insert_encoding(p->pdc, encoding, &font->codepage, + font->verbose); + if (enc == pdc_invalidenc) + goto PDF_PREMATURE_EXIT; + } + else if (enc == pdc_cid) + { + if (slot == -1) + goto PDF_NEWFONT_EXIT; + else + goto PDF_PREMATURE_EXIT; + } + else if (enc == pdc_glyphid) + { + encoding_aux = "glyphid"; + } + else if (enc == pdc_unicode) + { + encoding_aux = "unicode"; + } + } + + if (pdc_strcmp(font->encapiname, encoding)) + { + pdc_push_errmsg(p->pdc, PDF_E_FONT_PREFIX2, + fontname, font->encapiname, encoding, 0); + } + encoding = encoding_aux; + + encoding = pdc_get_user_encoding(p->pdc, enc); + pdc_logg_cond(p->pdc, 1, trc_encoding, "\tFont encoding: \"%s\"\n", + encoding); + + if (enc == pdc_unicode || enc == pdc_glyphid) + { + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0); + goto PDF_PREMATURE_EXIT; + } + + /* + * Look whether font is already in the cache. + * Look first for the auxiliary font (obj_id == -1). + * If a font with same encoding and same relevant options is found, + * return its handle. + * If a Type 3 font with the same name but different encoding + * is found, make a copy in a new slot and attach the requested encoding. + */ + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tFont will be searched in the PDFlib font cache\n"); + for (slot = 0; slot < p->fonts_number; slot++) + { + if (p->fonts[slot].obj_id == PDC_BAD_ID && + p->fonts[slot].ft.m.type != fnt_Type3) + { + if (font->opt.auxiliary) + goto PDF_PREMATURE_EXIT; + } + else if (!font->opt.auxiliary && + !pdc_strcmp(p->fonts[slot].apiname, fontname) && + p->fonts[slot].opt.fontstyle == font->opt.fontstyle) + { + if (p->fonts[slot].ft.m.type == fnt_Type3) + { + if (logg2) + pdc_logg(p->pdc, "\t\tType3 font [%d] found\n", slot); + + if (enc < pdc_winansi && enc != pdc_unicode) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC, 0, 0, 0, 0); + + slot = -1; + goto PDF_PREMATURE_EXIT; + } + + if (p->fonts[slot].ft.enc != enc) + { + if (!pdf_handle_t3font(p, fontname, enc, font, &slot)) + { + slot = -1; + goto PDF_PREMATURE_EXIT; + } + if (slot > -1) + font = &p->fonts[slot]; + goto PDF_NEWFONT_EXIT; + } + + goto PDF_PREMATURE_EXIT; + } + else if (p->fonts[slot].opt.monospace == font->opt.monospace + ) + { + if (p->fonts[slot].ft.enc == enc && + p->fonts[slot].codepage == font->codepage) + { + if (logg2) + pdc_logg(p->pdc, + "\t\tfont [%d] with same encoding found\n", + slot); + + pdf_check_font_identical(p, font, &slot); + goto PDF_PREMATURE_EXIT; + } + else + { + char *adaptname; + int kc; + + /* Comparing apiname of encoding */ + if (!pdc_stricmp(font->encapiname, + p->fonts[slot].encapiname) && + !pdc_stricmp(font->ft.cmapname, + p->fonts[slot].ft.cmapname)) + { + if (logg2) + pdc_logg(p->pdc, + "\t\tfont [%d] with same encoding " + "apiname '%s' found\n", slot, encoding); + + pdf_check_font_identical(p, font, &slot); + goto PDF_PREMATURE_EXIT; + } + + /* Name of adapted to font encoding */ + adaptname = + pdf_get_encoding_adaptname(p, enc, font, fontname); + kc = strcmp(adaptname, pdf_get_encoding_name(p, + p->fonts[slot].ft.enc, &p->fonts[slot])); + if (!kc) + { + if (logg2) + pdc_logg(p->pdc, + "\t\tfont [%d] with same internal " + "encoding name '%s' found\n", + slot, adaptname); + pdc_free_tmp(p->pdc, adaptname); + + pdf_check_font_identical(p, font, &slot); + goto PDF_PREMATURE_EXIT; + } + pdc_free_tmp(p->pdc, adaptname); + } + } + } + else if (!font->opt.auxiliary && + p->fonts[slot].ft.m.type == fnt_Type1 && + p->fonts[slot].ft.isstdfont && p->fonts[slot].ft.enc == enc) + { + /* different core font specifications */ + const char *fname = pdf_get_fontname_core(font, fontname, pdc_true); + + if ((fname != NULL && !strcmp(fname, p->fonts[slot].ft.name) && + p->fonts[slot].opt.fontstyle == fnt_Normal) || + (!strcmp(fontname, p->fonts[slot].ft.name) && + p->fonts[slot].opt.fontstyle == font->opt.fontstyle)) + { + if (logg2) + pdc_logg(p->pdc, + "\t\tfont [%d] with same font style '%s' found\n", + slot, pdc_get_keyword(font->opt.fontstyle, + pdf_fontstyle_pdfkeylist)); + + pdf_check_font_identical(p, font, &slot); + goto PDF_PREMATURE_EXIT; + } + } + } + + slot = -1; + pdc_logg_cond(p->pdc, 1, trc_font, + "\tFont not found in the PDFlib font cache\n"); + + /* embedding check */ + if (!pdf_check_font_embedding(p, font, fontname)) + { + goto PDF_PREMATURE_EXIT; + } + + /* Multiple Master handling: + * - strip MM parameters to build the master name + * - the master name is used to find the metrics + * - the instance name (client-supplied font name) is used in all places + * - although the master name is used for finding the metrics, the + * instance name is stored in the font struct. + */ + + len = strlen(fontname); + if (len > PDF_MAX_FONTNAME) + { + pdc_set_errmsg(p->pdc, FNT_E_FONT_NAMETOOLONG, + pdc_errprintf(p->pdc, "%d", PDF_MAX_FONTNAME), 0, 0, 0); + goto PDF_PREMATURE_EXIT; + } + strcpy(mastername, fontname); + + /* A Multiple Master font was requested */ + if ((mmparam = strstr(mastername, "MM_")) != NULL) + { + if (font->opt.embedding) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_EMBEDMM, 0, 0, 0, 0); + goto PDF_PREMATURE_EXIT; + } + mmparam[2] = '\0'; /* strip the parameter from the master name */ + } + + /* Font for vertical writing mode */ + fontname_p = mastername; + if (mastername[0] == '@') + { + font->ft.vertical = pdc_true; + fontname_p = &mastername[1]; + } + + /* protocol */ + pdc_logg_cond(p->pdc, 1, trc_font, + "\tPDFlib font name: \"%s\"\n", fontname_p); + + /* Font file search hierarchy + * - Check "FontOutline" resource entry and check TrueType font + * - Check "FontAFM" resource entry + * - Check "FontPFM" resource entry + * - Check "HostFont" resource entry + * - Check available in-core metrics + * - Check host font + */ + retval = pdc_false; + while (1) + { +#ifdef PDF_TRUETYPE_SUPPORTED + /* Check specified TrueType file */ + filename = pdc_find_resource(p->pdc, "FontOutline", fontname_p); + if (!filename) + { + /* check for TTC font names with index */ + ittc = PDF_TTC_SEPARATOR; + sf = strrchr(fontname_p, ittc); + + if (sf != NULL) + { + *sf = 0; + filename = pdc_find_resource(p->pdc, "FontOutline", fontname_p); + *sf = ittc; + } + } + if (filename) + { + outfilename = filename; + retval = fnt_check_tt_font(p->pdc, filename, fontname_p, &font->ft, + pdc_false); + if (retval == pdc_true) + { + retval = pdf_get_metrics_tt(p, font, fontname_p, enc, filename); + break; + } + else if (retval == pdc_undef && + pdc_get_errnum(p->pdc) == PDC_E_IO_RDOPEN_NF) + { + /* file must be exist */ + retval = pdc_false; + } + if (retval == pdc_false) + break; + } +#endif /* PDF_TRUETYPE_SUPPORTED */ + + /* Check specified AFM file */ + filename = pdc_find_resource(p->pdc, "FontAFM", fontname_p); + if (filename) + { + retval = pdf_get_metrics_afm(p, font, fontname_p, enc, filename, + pdc_true); + break; + } + + /* Check specified PFM file */ + filename = pdc_find_resource(p->pdc, "FontPFM", fontname_p); + if (filename) + { + retval = pdf_get_metrics_pfm(p, font, fontname_p, enc, filename, + pdc_true); + break; + } + + + + /* Check available in-core metrics */ + retval = pdf_get_metrics_core(p, font, fontname_p, enc, pdc_false); + if (retval != pdc_undef) + break; + retval = pdc_false; + + + /* Check available in-core metrics */ + retval = pdf_get_metrics_core(p, font, fontname_p, enc, pdc_true); + if (retval != pdc_undef) + break; + retval = pdc_false; + + /* Searching for a metric file */ + pdc_logg_cond(p->pdc, 1, trc_font, + "\tSearching for font metrics data file:\n"); + + filename = testfilename; + for (i = 0; i < 100; i++) + { + extension = pdf_extension_names[i].word; + if (!extension) + break; + + strcpy(testfilename, fontname_p); + sf = strrchr(testfilename, PDF_TTC_SEPARATOR); + if (sf != NULL) + *sf = 0; + strcat(testfilename, extension); + + switch (pdf_extension_names[i].code) + { +#ifdef PDF_TRUETYPE_SUPPORTED + case font_ttot: + retval = fnt_check_tt_font(p->pdc, filename, fontname_p, + &font->ft, pdc_false); + if (retval == pdc_true) + retval = pdf_get_metrics_tt(p, font, fontname_p, enc, + filename); + break; +#endif /* PDF_TRUETYPE_SUPPORTED */ + + case font_afm: + retval = pdf_get_metrics_afm(p, font, fontname_p, enc, + filename, pdc_false); + break; + + case font_pfm: + retval = pdf_get_metrics_pfm(p, font, fontname_p, enc, + filename, pdc_false); + break; + + default: + break; + } + + /* file found or error */ + if (retval != pdc_undef) + { + if (retval == pdc_true) + if (pdf_extension_names[i].code == font_ttot) + outfilename = filename; + break; + } + } + + if (retval == pdc_undef) + { + retval = pdc_false; + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tMetric data file for font \"%s\" not available\n", + fontname_p); + pdc_set_errmsg(p->pdc, PDF_E_FONT_NOMETRICS, 0, 0, 0, 0); + } + + break; + } + + /* metrics data search finished */ + + if (retval == pdc_false) + { + goto PDF_PREMATURE_EXIT; + } + + /* store instance name instead of master name in the font structure */ + if (mmparam) + { + pdc_free(p->pdc, font->ft.name); + font->ft.name = pdc_strdup(p->pdc, fontname); + pdc_free(p->pdc, font->ft.m.name); + font->ft.m.name = pdc_strdup(p->pdc, fontname); + } + + /* If embedding was requested, check font file (or raise an exception) */ + if (font->opt.embedding) + { + if (font->ft.img == NULL) + { + retval = pdc_undef; + + if (outfilename) + { + /* Font outline file specified */ + if (font->ft.m.type == fnt_Type1 || + font->ft.m.type == fnt_MMType1) + { + retval = pdf_t1open_fontfile(p, font, outfilename, NULL, + pdc_true); + } + else + { + retval = fnt_check_tt_font(p->pdc, outfilename, NULL, + &font->ft, pdc_true); + } + } + else + { + /* Searching font outline file */ + pdc_logg_cond(p->pdc, 1, trc_font, + "\tSearching for font outline data file:\n"); + + outfilename = testfilename; + for (i = 0; i < 100; i++) + { + extension = pdf_extension_names[i].word; + if (!extension) + break; + + strcpy(testfilename, fontname_p); + strcat(testfilename, extension); + + if (font->ft.m.type == fnt_Type1 || + font->ft.m.type == fnt_MMType1) + { + if (pdf_extension_names[i].code == font_pfab) + { + retval = pdf_t1open_fontfile(p, font, outfilename, + NULL, pdc_false); + } + } + else if (pdf_extension_names[i].code == font_ttot) + { + retval = fnt_check_tt_font(p->pdc, outfilename, + NULL, &font->ft, pdc_false); + } + + /* file found or error */ + if (retval != pdc_undef) + break; + } + + if (retval == pdc_undef) + { + retval = pdc_false; + pdc_set_errmsg(p->pdc, PDF_E_FONT_NOOUTLINE, 0, 0, 0, 0); + } + } + + if (retval == pdc_false) + { + pdc_logg_cond(p->pdc, 1, trc_font, + "\tOutline data file for font \"%s\" not found\n", + fontname_p); + } + else + { + if (!font->ft.img) + font->filename = font->ft.filename; + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tFont outline data file \"%s\" available\n", + font->filename ? + font->filename : font->ft.imgname); + } + } + } + else if (font->ft.img) + { + if (!font->ft.imgname) + pdc_free(p->pdc, font->ft.img); + else + { + pdc_unlock_pvf(p->pdc, font->ft.imgname); + pdc_free(p->pdc, font->ft.imgname); + font->ft.imgname = NULL; + } + font->ft.img = NULL; + font->ft.filelen = 0; + } + + if (retval && font->opt.monospace && font->opt.embedding) + { + pdc_set_errmsg(p->pdc, PDC_E_OPT_IGNORED, "monospace", 0, 0, 0); + retval = pdc_false; + } + + if (retval == pdc_false) + { + goto PDF_PREMATURE_EXIT; + } + + PDF_NEWFONT_EXIT: + + pdf_cleanup_font_options(p, fo); + + encoding = pdc_get_user_encoding(p->pdc, font->ft.enc); + if (pdc_strcmp(font->encapiname, encoding)) + pdc_logg_cond(p->pdc, 1, trc_encoding, + "\tDetermined font encoding: \"%s\"\n", encoding); + + /* set missing font metrics values */ + pdf_font_set_missvalues(p, font); + + /* font is semantic (Unicode compatible) */ + pdf_font_issemantic(p, font); + + /* set replacement character and code */ + pdf_set_replchar(p, font); + + /* font object ID */ + if (!font->opt.auxiliary) + font->obj_id = pdc_alloc_id(p->out); + + /* Now everything is fine, insert font */ + if (slot == -1) + slot = pdf_insert_font(p, font); + + + pdc_pop_errmsg(p->pdc); + + return slot; + + + PDF_PREMATURE_EXIT: + + pdf_cleanup_font_options(p, fo); + pdf_cleanup_font(p, font); + + if (slot == -1) + { + if (font->verbose) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + } + + pdc_pop_errmsg(p->pdc); + + return slot; +} + + +/* --------------------------- font writing ---------------------------- */ + +static char * +pdf_code2fontglyphname(pdf_font *font, pdc_encodingvector *ev, int code) +{ + char *glyphname; + + glyphname = ev->chars[code]; + pdc_get_alter_glyphname(ev->codes[code], font->missingglyphs, + &glyphname); + + return glyphname ? glyphname : (char *) pdc_get_notdef_glyphname(); +} + +void +pdf_transform_fontwidths(PDF *p, pdf_font *font, pdc_encodingvector *evto, + pdc_encodingvector *evfrom) +{ + int widths[256]; + pdc_ushort code2gid[256]; + int i, j; + + for (i = 0; i < 256; i++) + { + widths[i] = font->ft.m.defwidth; + code2gid[i] = 0; + } + + for (i = 0; i < 256; i++) + { + j = (int) pdc_transform_bytecode(p->pdc, evto, evfrom, (pdc_byte)i); + widths[j] = font->ft.m.widths[i]; + if (font->ft.code2gid != NULL) + code2gid[j] = font->ft.code2gid[i]; + } + + widths[0] = font->ft.m.defwidth; + memcpy(font->ft.m.widths, widths, 256 * sizeof(int)); + if (font->ft.code2gid != NULL) + memcpy(font->ft.code2gid, code2gid, 256 * sizeof(pdc_ushort)); +} + + + +static void +pdf_write_fontdescriptor( + PDF *p, + pdf_font *font, + int missingwidth, + pdc_id fontdescriptor_id, + pdc_id cidset_id, + pdc_id fontfile_id, + int nusedgids) +{ + (void) cidset_id; + (void) nusedgids; + + /* + * Font descriptor object + */ + pdc_begin_obj(p->out, fontdescriptor_id); /* font descriptor obj */ + pdc_begin_dict(p->out); /* font descriptor dict */ + + pdc_puts(p->out, "/Type/FontDescriptor\n"); + pdc_printf(p->out, "/Flags %ld\n", font->ft.m.flags); + + + pdc_printf(p->out, "/Ascent %d\n", font->ft.m.ascender); + pdc_printf(p->out, "/CapHeight %d\n", font->ft.m.capHeight); + pdc_printf(p->out, "/Descent %d\n", font->ft.m.descender); + pdc_printf(p->out, "/FontBBox[%d %d %d %d]\n", + (int) font->ft.m.llx, (int) font->ft.m.lly, + (int) font->ft.m.urx, (int) font->ft.m.ury); + + pdc_printf(p->out, "/FontName"); + pdf_put_pdfname(p, font->ft.m.name); + pdc_puts(p->out, "\n"); + + pdc_printf(p->out, "/ItalicAngle %d\n", (int) (font->ft.m.italicAngle)); + pdc_printf(p->out, "/StemV %d\n", font->ft.m.StdVW); + + if (font->ft.m.StdHW > 0) + pdc_printf(p->out, "/StemH %d\n", font->ft.m.StdHW); + + if (font->ft.m.xHeight > 0) + pdc_printf(p->out, "/XHeight %d\n", font->ft.m.xHeight); + + if (missingwidth > 0) + pdc_printf(p->out, "/MissingWidth %d\n", missingwidth); + + if (fontfile_id != PDC_BAD_ID) + { + switch(font->ft.m.type) + { + case fnt_Type1: + case fnt_MMType1: + pdc_objref(p->out, "/FontFile", fontfile_id); + break; + +#ifdef PDF_TRUETYPE_SUPPORTED + case fnt_TrueType: + case fnt_CIDFontType2: + pdc_objref(p->out, "/FontFile2", fontfile_id); + break; + + case fnt_Type1C: + case fnt_CIDFontType0: + pdc_objref(p->out, "/FontFile3", fontfile_id); + break; +#endif /* PDF_TRUETYPE_SUPPORTED */ + + default: + break; + } + } + + + pdc_end_dict(p->out); /* font descriptor dict */ + pdc_end_obj(p->out); /* font descriptor obj */ +} + +static void +pdf_put_font(PDF *p, pdf_font *font) +{ + const char *fontname = font->ft.name; + fnt_fonttype fonttype = font->ft.m.type; + pdc_id fontdescriptor_id = PDC_BAD_ID; + pdc_id fontfile_id = PDC_BAD_ID; + pdc_id encoding_id = PDC_BAD_ID; + pdc_id cidset_id = PDC_BAD_ID; + pdc_id length_id = PDC_BAD_ID; + pdc_id descendant_id = PDC_BAD_ID; + pdc_encoding enc = font->ft.enc; + const char *encoding; + pdc_encoding_info *encinfo = NULL; + pdc_bool comp_font = pdc_false; + pdc_bool acro_fontstyle = pdc_false; + pdc_scalar a = 1.0; + PDF_data_source src; + int nusedgids = 0; + + /* save font struct members */ + pdc_encodingvector *ev = NULL; + pdc_encoding font_encoding = font->ft.enc; + int font_numcodes = font->ft.numcodes; + int font_codesize = font->codesize; + + int missingwidth = 0; + int i; + + encoding = pdc_get_user_encoding(p->pdc, enc); + if (!pdc_strcmp(font->encapiname, encoding)) + { + pdc_push_errmsg(p->pdc, PDF_E_FONT_PREFIX, + font->apiname, font->encapiname, 0, 0); + } + else + { + pdc_push_errmsg(p->pdc, PDF_E_FONT_PREFIX2, + font->apiname, font->encapiname, encoding, 0); + } + + + /* ID for embedded font */ + if (font->opt.embedding) + { + switch(fonttype) + { + case fnt_Type1: + case fnt_MMType1: + case fnt_TrueType: + case fnt_CIDFontType2: + case fnt_Type1C: + case fnt_CIDFontType0: + fontfile_id = pdc_alloc_id(p->out); + break; + + default: + break; + } + } + + /* + * Font dictionary + */ + pdc_begin_obj(p->out, font->obj_id); /* font obj */ + pdc_begin_dict(p->out); /* font dict */ + pdc_puts(p->out, "/Type/Font\n"); + + /* /Subtype */ + pdc_printf(p->out, "/Subtype/%s\n", + pdc_get_keyword(fonttype, pdf_fonttype_pdfkeylist)); + comp_font = fonttype == fnt_CIDFontType0 || fonttype == fnt_CIDFontType2; + + /* Acrobat font style */ + acro_fontstyle = font->opt.fontstyle != fnt_Normal && + !(font->metricflags & (font_bold | font_italic)); + + /* /Name */ + if (fonttype == fnt_Type3 || font->used_in_formfield) + { + /* + * The name is optional, but if we include it it will show up + * in Acrobat's font info box. However, if the same font name + * is used with different encodings Acrobat 4 will not be + * able to distinguish both. For this reason we add the + * encoding name to make the font name unique. + */ + + const char *name = fontname; + + if (font->used_in_formfield) + name = pdf_get_pdf_fontname(font); + + pdc_puts(p->out, "/Name"); + pdf_put_pdfname(p, name); + pdc_puts(p->out, "\n"); + } + + /* /BaseFont */ + switch (fonttype) + { + case fnt_Type1: + case fnt_MMType1: + case fnt_TrueType: + case fnt_Type1C: + case fnt_CIDFontType2: + case fnt_CIDFontType0: + { + pdc_puts(p->out, "/BaseFont"); + pdf_put_pdfname(p, fontname); + if (font->outcmapname) + pdc_printf(p->out, "-%s", font->outcmapname); + if (acro_fontstyle && !comp_font) + pdc_printf(p->out, ",%s", pdc_get_keyword(font->opt.fontstyle, + pdf_fontstyle_pdfkeylist)); + pdc_puts(p->out, "\n"); + } + break; + + /* /FontBBox, /FontMatrix, /CharProcs /Resources */ + case fnt_Type3: + if (font->t3font->charprocs_id == PDC_BAD_ID) + pdc_error(p->pdc, PDF_E_T3_OUTLINESMISSING, fontname, 0, 0, 0); + + pdc_printf(p->out, "/FontBBox[%f %f %f %f]\n", + font->ft.bbox.llx, font->ft.bbox.lly, + font->ft.bbox.urx, font->ft.bbox.ury); + + pdc_printf(p->out, "/FontMatrix[%f %f %f %f %f %f]\n", + font->ft.matrix.a, font->ft.matrix.b, + font->ft.matrix.c, font->ft.matrix.d, + font->ft.matrix.e, font->ft.matrix.f); + pdc_objref(p->out, "/CharProcs", font->t3font->charprocs_id); + pdc_objref(p->out, "/Resources", font->t3font->res_id); + + /* We must apply a correctional factor since Type 3 fonts not + * necessarily use 1000 units per em. We apply the correction + * here, and store the 1000-based width values in the font in + * order to speed up PDF_stringwidth(). + */ + a = 1000 * font->ft.matrix.a; + break; + + default: + break; + } + + /* changing 8-bit font encoding to builtin */ + if (enc >= 0 && font->symenc != pdc_invalidenc) + { + ev = NULL; + enc = pdc_builtin; + font->ft.enc = enc; + } + + /* changing 8-bit font encoding to winansi */ + if (font->towinansi != pdc_invalidenc) + { + pdc_encodingvector *evfrom; + + ev = pdc_get_encoding_vector(p->pdc, font->towinansi); + evfrom = pdc_get_encoding_vector(p->pdc, enc); + pdf_transform_fontwidths(p, font, ev, evfrom); + + enc = font->towinansi; + font->ft.enc = enc; + } + + /* /FontDescriptor, /FirstChar, /LastChar, /Widths */ + switch (fonttype) + { + case fnt_Type1: + /* disabled, because of PDF 1.7 reference + if (font->ft.isstdfont == pdc_true) break; + */ + case fnt_MMType1: + case fnt_TrueType: + case fnt_Type1C: + case fnt_Type3: + { + int firstchar = 0; + int lastchar = 255; + int defwidth = 0; + + if (fonttype != fnt_Type3 + ) + { + fontdescriptor_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/FontDescriptor", fontdescriptor_id); + } + + + /* determine missing width. + * Only for embedded fonts because of a bug in Acrobat, + * which arises if the font is not installed at host. + */ + if (font->opt.embedding) + { + if (fonttype != fnt_Type3) + defwidth = font->ft.m.widths[0]; + + { + for (i = 1; i < 255; i++) + { + if (font->ft.m.widths[i] != defwidth) + break; + } + if (i > 1) + firstchar = i; + for (i = 255; i > 0; i--) + { + if (i == firstchar || font->ft.m.widths[i] != defwidth) + break; + } + lastchar = i; + } + + if (firstchar > 0 || lastchar < 255) + missingwidth = (int) (defwidth / a + 0.5); + } + + pdc_printf(p->out, "/FirstChar %d\n", firstchar); + pdc_printf(p->out, "/LastChar %d\n", lastchar); + + pdc_puts(p->out, "/Widths"); + pdc_begin_array(p->out); + for (i = firstchar; i <= lastchar; i++) + { + pdc_printf(p->out, "%d", + (int) (font->ft.m.widths[i] / a + .5)); + if (i < 255) + pdc_printf(p->out, "%s", ((i + 1) % 16) ? " " : "\n"); + } + pdc_end_array(p->out); + } + break; + + default: + break; + } + + /* /Encoding */ + switch (fonttype) + { + case fnt_Type1: + case fnt_MMType1: + case fnt_TrueType: + case fnt_Type1C: + if (!font->used_in_formfield) + { + if (enc == pdc_winansi) + { + pdc_printf(p->out, "/Encoding/WinAnsiEncoding\n"); + break; + } + if (enc == pdc_macroman && font->hasnomac == pdc_false) + { + pdc_printf(p->out, "/Encoding/MacRomanEncoding\n"); + break; + } + } + case fnt_Type3: + if (enc >= 0) + { + encinfo = pdc_get_encoding_info(p->pdc, enc); + if (encinfo->id == PDC_BAD_ID) + encinfo->id = pdc_alloc_id(p->out); + encoding_id = encinfo->id; + } + + if (encoding_id != PDC_BAD_ID) + pdc_objref(p->out, "/Encoding", encoding_id); + + if (encinfo != NULL) + { + if (!encinfo->stored) + encinfo->stored = pdc_true; + else + encoding_id = PDC_BAD_ID; + } + + break; + + case fnt_CIDFontType2: + case fnt_CIDFontType0: + if (font->outcmapname) + { + pdc_printf(p->out, "/Encoding/%s\n", font->outcmapname); + } + break; + + default: + break; + } + + /* /ToUnicode . Only reasonable if nusedgids != 1 + * (== 1: only notdef character in a font subset) + */ + + + /* /DescendantFonts */ + if (comp_font == pdc_true) + { + descendant_id = pdc_alloc_id(p->out); + pdc_puts(p->out, "/DescendantFonts"); + pdc_begin_array(p->out); + pdc_objref(p->out, "", descendant_id); + pdc_end_array(p->out); + } + + pdc_end_dict(p->out); /* font dict */ + pdc_end_obj(p->out); /* font obj */ + + /* + * Encoding dictionary + */ + if (encoding_id != PDC_BAD_ID) + { + char *glyphname; + + pdc_begin_obj(p->out, encoding_id); /* encoding obj */ + pdc_begin_dict(p->out); /* encoding dict */ + + pdc_puts(p->out, "/Type/Encoding\n"); + + { + pdc_encodingvector *evb = NULL; + + pdc_set_encoding_glyphnames(p->pdc, enc); + ev = pdc_get_encoding_vector(p->pdc, enc); + + /* See Implementation Note 46. The restrictions described there + * are also valid for Acrobat versions up to now. + */ + if (fonttype != fnt_Type3 && !font->used_in_formfield) + { + if (!strncmp(ev->apiname, PDC_ENC_MODWINANSI, + strlen(PDC_ENC_MODWINANSI)) || + !strncmp(ev->apiname, PDC_ENC_ISO8859, + strlen(PDC_ENC_ISO8859)) || + !strncmp(ev->apiname, PDC_ENC_CP125, + strlen(PDC_ENC_CP125))) + { + pdc_puts(p->out, "/BaseEncoding/WinAnsiEncoding\n"); + evb = pdc_get_encoding_vector(p->pdc, pdc_winansi); + } + else if (!strncmp(ev->apiname, PDC_ENC_MODMACROMAN, + strlen(PDC_ENC_MODMACROMAN))) + { + pdc_puts(p->out, "/BaseEncoding/MacRomanEncoding\n"); + evb = pdc_get_encoding_vector(p->pdc, pdc_macroman); + } + else + { + /* /BaseEncoding/StandardEncoding */ + evb = pdc_get_encoding_vector(p->pdc, pdc_stdenc); + } + } + + if (evb != NULL) + { + int iv = -1; + for (i = 0; i < font->ft.numcodes; i++) + { + glyphname = pdf_code2fontglyphname(font, ev, i); + + /* enforce first three names because of bug in Acrobat 6 */ + if (i < 3 || + (glyphname && !evb->chars[i]) || + (!glyphname && evb->chars[i]) || + (glyphname && evb->chars[i] && + strcmp(glyphname, evb->chars[i]))) + { + if (iv == -1) + pdc_puts(p->out, "/Differences[0"); + if (i > iv + 1) + pdc_printf(p->out, "%d", i); + pdf_put_pdfname(p, glyphname); + pdc_puts(p->out, "\n"); + iv = i; + } + } + if (iv > -1) + pdc_end_array(p->out); + } + else + { + pdc_puts(p->out, "/Differences[0"); + for (i = 0; i < font->ft.numcodes; i++) + { + glyphname = pdf_code2fontglyphname(font, ev, i); + pdf_put_pdfname(p, glyphname); + pdc_puts(p->out, "\n"); + } + pdc_end_array(p->out); + } + } + + pdc_end_dict(p->out); /* encoding dict */ + pdc_end_obj(p->out); /* encoding obj */ + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); + } + + + /* + * CID fonts dictionary + */ + if (descendant_id != PDC_BAD_ID) + { + pdc_begin_obj(p->out, descendant_id); /* CID font obj */ + pdc_begin_dict(p->out); /* CID font dict */ + pdc_puts(p->out, "/Type/Font\n"); + + /* /Subtype */ + if (fonttype == fnt_CIDFontType0) + pdc_puts(p->out, "/Subtype/CIDFontType0\n"); + if (fonttype == fnt_CIDFontType2) + pdc_puts(p->out, "/Subtype/CIDFontType2\n"); + + /* /BaseFont */ + pdc_puts(p->out, "/BaseFont"); + pdf_put_pdfname(p, fontname); + if (acro_fontstyle) + pdc_printf(p->out, ",%s", + pdc_get_keyword(font->opt.fontstyle, pdf_fontstyle_pdfkeylist)); + pdc_puts(p->out, "\n"); + + /* /CIDSystemInfo */ + pdc_puts(p->out, "/CIDSystemInfo<out, "/Ordering"); + pdf_put_hypertext(p, fnt_get_ordering_cid(font->ft.m.charcoll)); + pdc_printf(p->out, "/Supplement %d>>\n", MAX(font->supplement, 0)); + + /* /FontDescriptor */ + fontdescriptor_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/FontDescriptor", fontdescriptor_id); + + + + /* /DW /W */ +#ifdef PDF_CJKFONTWIDTHS_SUPPORTED + if (font->ft.isstdfont) + pdf_put_cidglyph_widths(p, font); +#endif /* PDF_CJKFONTWIDTHS_SUPPORTED */ + + + pdc_end_dict(p->out); /* CID font dict */ + pdc_end_obj(p->out); /* CID font obj */ + + } + + + /* + * FontDescriptor dictionary + */ + if (fontdescriptor_id != PDC_BAD_ID) + pdf_write_fontdescriptor(p, font, missingwidth, fontdescriptor_id, + cidset_id, fontfile_id, nusedgids); + + + + /* + * Font embedding + */ + if (fontfile_id != PDC_BAD_ID) + { + pdc_id length1_id = PDC_BAD_ID; + pdc_id length2_id = PDC_BAD_ID; + pdc_id length3_id = PDC_BAD_ID; + pdc_bool compress = pdc_false; + + /* Prepare embedding */ + switch(fonttype) + { + case fnt_Type1: + case fnt_MMType1: + { + pdf_make_t1src(p, font, &src); + length1_id = pdc_alloc_id(p->out); + length2_id = pdc_alloc_id(p->out); + length3_id = pdc_alloc_id(p->out); + } + break; + +#ifdef PDF_TRUETYPE_SUPPORTED + case fnt_TrueType: + case fnt_CIDFontType2: + { + length1_id = pdc_alloc_id(p->out); + } + case fnt_Type1C: + case fnt_CIDFontType0: + case fnt_OpenType: + { + src.private_data = (void *) font->filename; + if (font->filename) + { + /* Read the font from file */ + src.init = pdf_data_source_file_init; + src.fill = pdf_data_source_file_fill; + src.terminate = pdf_data_source_file_terminate; + switch(fonttype) + { + case fnt_TrueType: + case fnt_CIDFontType2: + case fnt_OpenType: + src.offset = (long) 0; + src.length = (long) 0; + break; + + case fnt_Type1C: + case fnt_CIDFontType0: + src.offset = font->cff_offset; + src.length = (long) font->cff_length; + break; + + default: + break; + } + } + else + { + /* Read the font from memory */ + src.init = NULL; + src.fill = pdf_data_source_buf_fill; + src.terminate = NULL; + switch(fonttype) + { + case fnt_TrueType: + case fnt_CIDFontType2: + case fnt_OpenType: + src.buffer_start = font->ft.img; + src.buffer_length = font->ft.filelen; + break; + + case fnt_Type1C: + case fnt_CIDFontType0: + src.buffer_start = font->ft.img + font->cff_offset; + src.buffer_length = font->cff_length; + break; + + default: + break; + } + src.bytes_available = 0; + src.next_byte = NULL; + } + } + break; +#endif /* PDF_TRUETYPE_SUPPORTED */ + + default: + break; + } + + /* Embedded font stream dictionary */ + pdc_begin_obj(p->out, fontfile_id); /* Embedded font stream obj */ + pdc_begin_dict(p->out); /* Embedded font stream dict */ + + /* /Length, /Filter */ + length_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Length", length_id); + switch(fonttype) + { + case fnt_Type1: + case fnt_MMType1: + break; + +#ifdef PDF_TRUETYPE_SUPPORTED + case fnt_TrueType: + case fnt_CIDFontType2: + case fnt_Type1C: + case fnt_CIDFontType0: + case fnt_OpenType: + if (font->ft.filelen != 0L) + { + compress = pdc_true; + if (pdc_get_compresslevel(p->out)) + pdc_puts(p->out, "/Filter/FlateDecode\n"); + } + break; +#endif /* PDF_TRUETYPE_SUPPORTED */ + + default: + break; + } + + /* /Length1, /Length2, Length3 */ + if (length1_id != PDC_BAD_ID) + pdc_objref(p->out, "/Length1", length1_id); + if (length2_id != PDC_BAD_ID) + pdc_objref(p->out, "/Length2", length2_id); + if (length3_id != PDC_BAD_ID) + pdc_objref(p->out, "/Length3", length3_id); + +#ifdef PDF_TRUETYPE_SUPPORTED + /* /Subtype */ + if(fonttype == fnt_Type1C) + pdc_puts(p->out, "/Subtype/Type1C\n"); + if (fonttype == fnt_CIDFontType0) + pdc_puts(p->out, "/Subtype/CIDFontType0C\n"); + if (fonttype == fnt_OpenType) + pdc_puts(p->out, "/Subtype/OpenType\n"); +#endif /* PDF_TRUETYPE_SUPPORTED */ + + + pdc_end_dict(p->out); /* Embedded font stream dict */ + + /* Stream */ + pdf_copy_stream(p, &src, compress); + + pdc_end_obj(p->out); /* Embedded font stream obj */ + + pdc_put_pdfstreamlength(p->out, length_id); + + /* Length objects */ + switch(fonttype) + { + case fnt_Type1: + case fnt_MMType1: + pdf_put_length_objs(p, &src, length1_id, length2_id, length3_id); + break; + +#ifdef PDF_TRUETYPE_SUPPORTED + case fnt_TrueType: + case fnt_CIDFontType2: + if (compress) + { + pdc_begin_obj(p->out, length1_id); /* Length1 obj */ + pdc_printf(p->out, "%ld\n", (long) font->ft.filelen); + pdc_end_obj(p->out); /* Length1 obj */ + } + else + { + /* same as /Length */ + pdc_put_pdfstreamlength(p->out, length1_id); + } + break; +#endif /* PDF_TRUETYPE_SUPPORTED */ + + default: + break; + } + } + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); + + /* restore font struct members */ + font->ft.enc = font_encoding; + font->ft.numcodes = font_numcodes; + font->codesize = font_codesize; + + pdc_pop_errmsg(p->pdc); +} + +void +pdf_write_doc_fonts(PDF *p) +{ + int slot; + pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_font); + + /* output pending font objects */ + for (slot = 0; slot < p->fonts_number; slot++) + { + pdf_font *font = &p->fonts[slot]; + + switch(p->fonts[slot].ft.m.type) + { + case fnt_Type1: + case fnt_MMType1: +#ifdef PDF_TRUETYPE_SUPPORTED + case fnt_TrueType: + case fnt_CIDFontType2: + case fnt_Type1C: +#endif /* PDF_TRUETYPE_SUPPORTED */ + case fnt_CIDFontType0: + case fnt_Type3: + if (font->obj_id != PDC_BAD_ID) + { + if (logg1) + { + pdc_logg(p->pdc, + "\tProcessing font %d: \"%s\" " + "with encoding \"%s\" and PDF object id %ld", + slot, font->ft.name, + pdf_get_encoding_name(p, font->ft.enc, font), + font->obj_id); + } + + if (font->ft.enc == pdc_invalidenc || + font->used_in_current_doc == pdc_false) + { + if (logg1) + pdc_logg(p->pdc, " - but not used\n", font->obj_id); + + /* + * This font has been defined, but never used in the + * document. Ignore it. However, the font's object id + * has already been allocated, so we mark the object + * as free in order to avoid a complaint of the object + * machinery. + */ + pdc_mark_free(p->out, font->obj_id); + } + else + { + if (logg1) + pdc_logg(p->pdc, "\n"); + + pdf_put_font(p, font); + } + } + break; + + default: + break; + } + } +} + +void +pdf_write_page_fonts(PDF *p) +{ + int i, total = 0; + int bias = p->curr_ppt->fn_bias; + + /* This doesn't really belong here, but all modules which write + * font resources also need this, so we include it here. + * Note that keeping track of ProcSets is considered obsolete + * starting with PDF 1.4, so we always include the full set which + * is written as a constant object at the beginning of the file. + */ + + pdc_objref(p->out, "/ProcSet", p->procset_id); + + for (i = 0; i < p->fonts_number; i++) + if (p->fonts[i].used_on_current_page == pdc_true) + total++; + + if (total > 0 || bias) + { + pdc_puts(p->out, "/Font"); + pdc_begin_dict(p->out); /* font resource dict */ + } + + if (total > 0) + { + for (i = 0; i < p->fonts_number; i++) + { + if (p->fonts[i].used_on_current_page == pdc_true) { + p->fonts[i].used_on_current_page = pdc_false; /* reset */ + pdc_printf(p->out, "/F%d", bias + i); + pdc_objref(p->out, "", p->fonts[i].obj_id); + } + } + + if (!bias) + pdc_end_dict(p->out); /* font resource dict */ + } +} + +void +pdf_get_page_fonts(PDF *p, pdf_reslist *rl) +{ + int i; + + for (i = 0; i < p->fonts_number; i++) + { + if (p->fonts[i].used_on_current_page) + { + p->fonts[i].used_on_current_page = pdc_false; /* reset */ + pdf_add_reslist(p, rl, i); + } + } +} + +void +pdf_mark_page_font(PDF *p, int ft) +{ + p->fonts[ft].used_on_current_page = pdc_true; +} + + + diff --git a/src/pdflib/pdflib/p_font.h b/src/pdflib/pdflib/p_font.h new file mode 100644 index 0000000..3dc4d91 --- /dev/null +++ b/src/pdflib/pdflib/p_font.h @@ -0,0 +1,225 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_font.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Header file for the PDFlib font subsystem + * + */ + +#ifndef P_FONT_H +#define P_FONT_H + +#define PDF_DEFAULT_CHAR PDC_UNICODE_SPACE + +/* internal maximal length of fontnames */ +#define PDF_MAX_FONTNAME 128 + +/* last text rendering mode number */ +#define PDF_LAST_TRMODE 7 + +/* minimal number of glyphs for appropriate encoding */ +#define PDF_MIN_GLYPHS 5 + +typedef enum +{ + font_ascender = (1<<0), + font_descender = (1<<1), + font_capheight = (1<<2), + font_xheight = (1<<3), + font_linegap = (1<<4), + + font_italic = (1<<8), + font_bold = (1<<9) +} +pdf_font_values; + +typedef struct pdf_t3glyph_s pdf_t3glyph; + +/* font options */ +struct pdf_font_options_s +{ + pdc_bool embedding; + char *encoding; + int flags; + char *fontname; + fnt_fontstyle fontstyle; + pdc_bool fontwarning; + int mask; + int monospace; + int ascender; + int descender; + int capheight; + int xheight; + int linegap; + pdc_bool auxiliary; +}; + +/* Type3 font structures */ +struct pdf_t3glyph_s +{ + char *name; + pdc_id charproc_id; + pdc_scalar wx; + pdc_scalar llx; + pdc_scalar lly; + pdc_scalar urx; + pdc_scalar ury; + pdc_scalar width; + int pass; /* 0, 1, 2 */ +}; + +struct pdf_t3font_s +{ + pdf_t3glyph *glyphs; /* dynamically growing glyph table */ + int capacity; /* current number of slots */ + int next_glyph; /* next available slot */ + int curr_glyph; /* slot of current glyph */ + + pdc_id charprocs_id; /* id of /CharProcs dict */ + pdc_id res_id; /* id of /Resources dict */ + pdc_bool colorized; /* glyphs colorized */ + int pass; /* 0, 1, 2 */ + +}; + +/* pdflib font structure */ +struct pdf_font_s +{ + /* pdcore font structure */ + fnt_font ft; + + /* font options */ + pdf_font_options opt; /* pdflib font options */ + pdc_bool verbose; /* put out warning/error messages */ + + /* special font names */ + char *apiname; /* font name specified in API call */ + const char *filename; /* name of font file, copy of ft.filename */ + char *metricfilename; /* name of metric font file */ + + /* font control */ + pdc_bool used_in_formfield; /* this font is in use in form field */ + pdc_bool used_in_current_doc; /* this font is in use in current doc. */ + pdc_bool used_on_current_page; /* this font is in use on current page */ + pdc_id obj_id; /* object id of this font */ + + /* CFF table */ + long cff_offset; /* start of CFF table in font */ + size_t cff_length; /* length of CFF table in font */ + + /* Type3 font */ + pdf_t3font *t3font; /* Type3 font data */ + pdc_bool hasoriginal; /* has the original Type3 font data */ + + /* pdflib encoding and CMap properties */ + char *encapiname; /* encoding name specified in API call */ + char *outcmapname; /* output CMap namel */ + int codepage; /* OEM multi byte code-page number */ + pdc_encoding towinansi; /* convert to 'towinansi' enc. for output */ + pdc_bool hasnomac; /* TT font has no macroman cmap */ + pdc_bool passthrough; /* text will be passed through as is */ + pdc_bool unibyte; /* take Unicode encoding as byte encoding */ + pdc_bool asciispace; /* encoding has space at x20 */ + pdc_bool issemantic; /* encoding is Unicode interpretable */ + pdc_bool widthsmissing; /* GID widths not available */ + pdc_ulong missingglyphs; /* bit mask for missing new AGL glyphs */ + int metricflags; /* flags for faked font values */ + int supplement; /* supplement number of CMap + * = -1: Identity-H/V */ + pdc_encoding symenc; /* font encoding for symbol fonts */ + int replacementchar; /* replacement character */ + int replacementcode; /* replacement code or glyph id resp. */ + + /* encoding and glyph control */ + int codesize; /* code size */ + /* = 0: unknown, no Unicode CMap */ + /* = 1: 1 byte encoding */ + /* = 2: 2 byte encoding */ + int lastcode; /* AFM: last byte code for generating runtime */ + /* byte encoding. = -1: ignore */ + int gid0code; /* code für gid 0 (because of Type3 fonts) */ + pdc_byte *usedgids; /* used Glyph IDs for font subsetting */ + pdc_bool expectglyphs; /* TT: glyph id text strings are expected */ + pdc_bool iscidfont; /* is CID font */ + +}; + +/* p_truetype.c */ +pdc_bool pdf_get_metrics_tt(PDF *p, pdf_font *font, + const char *fontname, pdc_encoding enc, + const char *filename); +int pdf_check_tt_hostfont(PDF *p, const char *hostname); + +/* p_afm.c */ +pdc_bool pdf_process_metrics_data(PDF *p, pdf_font *font, + const char *fontname); +pdc_bool pdf_get_metrics_afm(PDF *p, pdf_font *font, + const char *fontname, pdc_encoding enc, + const char *filename, pdc_bool requested); + +/* p_pfm.c */ +pdc_bool pdf_check_pfm_encoding(PDF *p, pdf_font *font, + pdc_encoding enc); +pdc_bool pdf_get_metrics_pfm(PDF *p, pdf_font *font, + const char *fontname, pdc_encoding enc, + const char *filename, pdc_bool requested); + +/* p_cid.c */ +pdc_bool pdf_handle_cidfont(PDF *p, const char *fontname, + const char *encoding, pdc_encoding enc, pdf_font *font, int *o_slot, + pdc_encoding *newenc); +void pdf_put_cidglyph_widths(PDF *p, pdf_font *font); + +/* p_font.c */ +void pdf_get_page_fonts(PDF *p, pdf_reslist *rl); +void pdf_parse_font_options(PDF *p, const char *optlist); +double pdf_get_font_float_option(PDF *p, pdf_font_optflags fflags); +pdc_bool pdf_check_font_embedding(PDF *p, pdf_font *font, const char *fontname); +pdc_bool pdf_make_fontflag(PDF *p, pdf_font *font); +int pdf_get_code_or_glyphid(PDF *p, pdf_font *font, pdc_encodingvector *ev, + pdc_ushort uv); +void pdf_set_replchar(PDF *p, pdf_font *font); +void pdf_font_issemantic(PDF *p, pdf_font *font); +void pdf_font_set_missvalues(PDF *p, pdf_font *font); +pdc_bool pdf_font_get_is_faked(pdf_font *font, pdf_font_values flag); +double pdf_font_get_metric_value(int value); +const char *pdf_get_encoding_name(PDF *p, pdc_encoding enc, pdf_font *font); +const char *pdf_get_font_char_option(PDF *p, pdf_font_optflags fflags); +const char *pdf_get_pdf_fontname(pdf_font *font); +char *pdf_get_encoding_adaptname(PDF *p, pdc_encoding enc, pdf_font *font, + const char *fontname); +pdc_encodingvector *pdf_create_font_encoding(PDF *p, pdc_encoding enc, + pdf_font *font, const char *fontname, pdc_bool kreg); +void pdf_transform_fontwidths(PDF *p, pdf_font *font, + pdc_encodingvector *evto, pdc_encodingvector *evfrom); + +/* p_type1.c */ +pdc_bool pdf_t1open_fontfile(PDF *p, pdf_font *font, const char *fontname, + PDF_data_source *t1src, pdc_bool requested); +pdc_bool pdf_make_t1src(PDF *p, pdf_font *font, PDF_data_source *t1src); +void pdf_put_length_objs(PDF *p, PDF_data_source *t1src, + pdc_id length1_id, pdc_id length2_id, pdc_id length3_id); + +/* p_type3.c */ +void pdf_cleanup_t3font(PDF *p, pdf_t3font *t3font); +void pdf_init_type3(PDF *p); +pdc_bool pdf_handle_t3font(PDF *p, const char *fontname, pdc_encoding enc, + pdf_font *font, int *slot); +pdc_bool pdf_isvalid_font(PDF *p, int slot); + +/* p_subsett.c */ +int pdf_prepare_ttfont(PDF *p, pdf_font *font); + + +#endif /* P_FONT_H */ + diff --git a/src/pdflib/pdflib/p_generr.h b/src/pdflib/pdflib/p_generr.h new file mode 100644 index 0000000..166e0f7 --- /dev/null +++ b/src/pdflib/pdflib/p_generr.h @@ -0,0 +1,705 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_generr.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib error messages + * + */ + +#define P_GENERR_H + +#if pdf_genNames +#define gen(n, num, nam, msg) PDF_E_##nam = num, +#elif pdf_genInfo +#define gen(n, num, nam, msg) { n, num, msg, (const char *) 0 }, + +#else +#error invalid inclusion of generator file +#endif + + +/* -------------------------------------------------------------------- */ +/* Configuration (20xx) */ +/* -------------------------------------------------------------------- */ + +gen(0, 2000, UNSUPP_CRYPT, "Encryption not supported in PDFlib Lite") + +gen(0, 2002, UNSUPP_KERNING, "Kerning not supported in PDFlib Lite") + +gen(0, 2003, UNSUPP_FONTINFO, "Font info not supported in PDFlib Lite") + +gen(0, 2004, UNSUPP_SUBSET, "Subsetting not supported in PDFlib Lite") + +gen(0, 2006, UNSUPP_PDFX, "PDF/X not supported in PDFlib Lite") + +gen(1, 2008, UNSUPP_IMAGE, "$1 images not supported in this configuration") + +gen(0, 2010, UNSUPP_ICC, "ICC profiles not supported in PDFlib Lite") + +gen(0, 2012, UNSUPP_UNICODE, + "Unicode and glyph id addressing not supported in PDFlib Lite") + +gen(0, 2014, UNSUPP_SPOTCOLOR, "Spot colors not supported in PDFlib Lite") + +gen(0, 2016, UNSUPP_PDI, "PDF import (PDI) not supported in PDFlib Lite") + +gen(0, 2017, UNSUPP_PDI_CONFIG, + "PDF import (PDI) not supported in this configuration") + +gen(0, 2018, UNSUPP_BLOCK, + "Personalization with blocks not supported in PDFlib Lite") + +gen(0, 2019, UNSUPP_BLOCK_CONFIG, + "Personalization with blocks not supported in this configuration") + +gen(0, 2020, UNSUPP_FORMFIELDS, "Form fields not supported in PDFlib Lite") + +gen(0, 2021, UNSUPP_JAVASCRIPT, "JavaScript not supported in PDFlib Lite") + +gen(0, 2022, UNSUPP_MC, "Marked content not supported in PDFlib Lite") + +gen(0, 2024, UNSUPP_TAGGED, "Tagged PDF not supported in PDFlib Lite") + +gen(0, 2026, UNSUPP_LAYER, + "Optional content (layers) not supported in PDFlib Lite") + +gen(0, 2028, UNSUPP_TEXTFLOWS, "Textflow not supported in PDFlib Lite") + +gen(0, 2029, UNSUPP_GLYPHCHECK, + "Glyph check not supported in PDFlib Lite") + +gen(0, 2030, UNSUPP_CHARREF, + "Character references not supported in PDFlib Lite") + +gen(0, 2031, UNSUPP_ESCAPESEQU, + "Escape sequences not supported in PDFlib Lite") + +gen(0, 2032, UNSUPP_JPEG2000, + "JPEG2000 images not supported in PDFlib Lite") + +gen(0, 2033, UNSUPP_TABLES, "Tables not supported in PDFlib Lite") + +gen(0, 2034, UNSUPP_3DANNOT, "3D annotations not supported in PDFlib Lite") + +gen(0, 2035, UNSUPP_HONORLANG, + "LANG environment variable not supported in PDFlib Lite") + +gen(0, 2098, BETA_EXPIRED, + "PDFlib 6 beta expired -- get latest version at www.pdflib.com") + + +/* -------------------------------------------------------------------- */ +/* Document, page, scoping and resource (21xx) */ +/* -------------------------------------------------------------------- */ + +gen(1, 2100, DOC_SCOPE, "Function must not be called in '$1' scope") + +gen(1, 2102, DOC_FUNCUNSUPP, "Function not supported for '$1'") + +gen(2, 2104, DOC_PDFVERSION, "$1 not supported in PDF $2") + +gen(0, 2106, DOC_EMPTY, "Generated document doesn't contain any pages") + +gen(0, 2110, PAGE_SIZE_ACRO, "Page size incompatible with Acrobat") + +gen(2, 2112, PAGE_BADBOX, "Illegal $1 [$2]") + +gen(0, 2114, PAGE_ILLCHGSIZE, + "Page size cannot be changed in top-down coordinate system") + +gen(2, 2120, RES_BADRES, "Bad resource specification '$1' for category '$2'") + +gen(2, 2122, DOC_SCOPE_GET, "Can't get parameter '$1' in '$2' scope") + +gen(2, 2124, DOC_SCOPE_SET, "Can't set parameter '$1' in '$2' scope") + +gen(1, 2126, PAGE_NOSUSPEND, "Page number $1 has not been suspended") + +gen(2, 2128, PAGE_NOSUSPEND2, + "Page number $1 in group '$2' has not been suspended") + +gen(1, 2130, PAGE_ILLNUMBER, "Illegal page number $1") + +gen(1, 2132, PAGE_NOTEXIST, "Page number $1 does not exist") + +gen(2, 2134, PAGE_NOTEXIST2, "Page number $1 in group '$2' does not exist") + +gen(0, 2136, PAGE_NEEDGROUP, "No page group specified") + +gen(0, 2138, PAGE_NEEDGROUP2, + "No page group specified (use PDF_begin_page_ext)") + +gen(1, 2140, DOC_UNKNOWNGROUP, "Unknown page group '$1'") + +gen(1, 2142, DOC_GROUPMISSING, + "Page group '$1' is missing in list of option 'grouporder'") + +gen(0, 2144, DOC_OPTGROUPORDER, + "Option 'grouporder' is illegal (no page groups are specified)") + +gen(1, 2146, DOC_DUPLGROUP, + "Duplicate definition of group '$1' in option 'grouporder'") + +gen(1, 2148, DOC_ILL_LABELOPT, + "Label option '$1' is illegal for this function") + +gen(1, 2150, DOC_NEED_LABELOPT, + "Option 'labels' requires suboption '$1' if used with this function") + +gen(1, 2152, PAGE_TRANS_COMPAT, + "Page transition '$1' requires PDF version 1.5 or higher") + +gen(1, 2154, PAGE_ILLROTATE, "Option 'rotate' has illegal value $1") + +gen(0, 2156, PAGE_SUSPEND_TAGGED, + "This function must not be used in Tagged PDF mode") + +gen(0, 2158, PAGE_SEP_NOSPOT, + "Option 'separationinfo' requires 'spotname' or 'spotcolor'") + +gen(0, 2160, PAGE_SEP_ILLPAGES, + "Option 'separationinfo' must not use 'pages' if not first page in group") + +gen(0, 2162, PAGE_SEP_NOPAGES, "Option 'separationinfo' requires 'pages'") + +gen(0, 2164, PAGE_SEP_NOINFO, "Option 'separationinfo' missing") + +gen(0, 2166, DOC_SEP_INCOMPLETE, "Incomplete separation group") + +gen(0, 2168, PAGE_TOPDOWN_NODIMS, + "Must specify page dimensions with option 'topdown'") + +gen(0, 2170, PAGE_NODIMS, "No dimensions specified for this page") + +gen(0, 2172, DOC_GETBUF_2GB, + "Can't process buffers larger than 2GB on this platform") + +gen(1, 2174, PAGE_SUSPENDED, "Page number $1 is still suspended") + +gen(0, 2176, DOC_GETBUF_LIN, + "Don't fetch buffer contents before PDF_end_document() when linearizing") + +gen(1, 2178, PAGE_ILLREF, + "A link annotation refers to non-existing page '$1'") + + +/* -------------------------------------------------------------------- */ +/* Graphics and Text (22xx) */ +/* -------------------------------------------------------------------- */ + +gen(0, 2200, GSTATE_UNMATCHEDSAVE, "Unmatched save level") + +gen(0, 2202, GSTATE_RESTORE, "Invalid restore (no matching save level)") + +gen(1, 2204, GSTATE_SAVELEVEL, "Too many save levels (max. $1)") + +gen(0, 2210, PATTERN_SELF, "Can't use a pattern within its own definition") + +gen(0, 2212, SHADING13, "Smooth shadings are not supported in PDF 1.3") + +gen(1, 2220, TEMPLATE_SELF, + "Can't place template handle $1 within its own definition") + +/* UNUSED +gen(1, 2230, TEXT_UNICODENOTSHOW, + "Can't show character with Unicode value U+$1") + +gen(1, 2232, TEXT_GLYPHIDNOTSHOW, "Can't show character with glyph id $1") + +gen(1, 2233, TEXT_BUILTINNOTSHOW, + "Can't show 16-bit character $1 for builtin encoding") +*/ + +gen(1, 2234, TEXT_TOOLONG, "Text too long (max. $1)") + +gen(2, 2235, TEXT_SIZENOMATCH, + "Size ($1) of glyphwidths list doesn't match size ($2 characters) of text") + +gen(0, 2236, TEXT_TOOMANYCODES, "Too many different unicode values (> 256)") + +gen(0, 2237, TEXT_NOFONTSIZESET, "Font size not specified for text") + +gen(0, 2238, TEXT_NOFONT, "No font set for text") + +gen(0, 2239, TEXT_ITALUNSUPP, + "Parameter 'italicangle' not supported for vertical writing mode") + +gen(1, 2240, TEXT_NOFONT_PAR, "No font set for parameter '$1'") + + + + + + +/* -------------------------------------------------------------------- */ +/* Color (23xx) */ +/* -------------------------------------------------------------------- */ + +gen(0, 2300, COLOR_SPOT, +"Spot color can not be based on a Pattern, Indexed, or Separation color space") + +gen(2, 2302, COLOR_BADSPOT, "Color name '$1' not found in $2 table") + +gen(1, 2304, COLOR_SPOTBW, + "Alternate color for custom spot color '$1' is black or white") + +gen(1, 2306, COLOR_UNLIC_SPOTCOLOR, "$1 spot colors not licensed") + +gen(0, 2308, COLOR_UNSUPP_SPOTNAME, "Unicode spot color names not supported") + +gen(2, 2309, COLOR_REDEFINE_SPOTNAME, + "Option '$1': spot color '$2' has already an alternative color") + + + +/* -------------------------------------------------------------------- */ +/* Image (24xx) */ +/* -------------------------------------------------------------------- */ + +gen(2, 2400, IMAGE_CORRUPT, "Corrupt $1 image file '$2'") + +gen(3, 2402, IMAGE_NOPAGE, "Requested page $1 in $2 image '$3' not found") + +gen(2, 2404, IMAGE_BADDEPTH, + "Bad number of bits per pixel ($1) in image file '$2'") + +gen(1, 2406, IMAGE_BADMASK, + "Image '$1' not suitable as mask (more than one color component)") + +gen(2, 2407, IMAGE_NOMATCH, + "Image '$1' not suitable as mask for image '$2' (different orientation)") + +gen(1, 2408, IMAGE_MASK1BIT13, + "Image '$1' with more than 1 bit not supported as mask in PDF 1.3") + +gen(1, 2410, IMAGE_COLORMAP, "Couldn't read colormap in image '$1'") + +gen(2, 2412, IMAGE_BADCOMP, + "Bad number of color components ($1) in image '$2'") + +gen(1, 2414, IMAGE_COLORIZE, + "Can't colorize image '$1' with more than 1 component") + +gen(1, 2416, IMAGE_ICC, "Couldn't handle embedded ICC profile in image '$1'") + +gen(1, 2418, IMAGE_ICC2, + "ICC profile for image file '$1' doesn't match image data") + +gen(0, 2420, IMAGE_THUMB, "More than one thumbnail for this page") + +gen(1, 2422, IMAGE_THUMB_MULTISTRIP, + "Can't use multi-strip image $1 as thumbnail") + +gen(1, 2424, IMAGE_THUMB_CS, + "Unsupported color space in thumbnail image handle $1") + +gen(2, 2426, IMAGE_THUMB_SIZE, "Thumbnail image $1 larger than $2 pixels") + +gen(2, 2428, IMAGE_OPTUNSUPP, + "Option '$1' for image type '$2' not supported") + +gen(2, 2430, IMAGE_OPTUNREAS, + "Option '$1' for image type '$2' doesn't have any effect") + +gen(2, 2432, IMAGE_OPTBADMASK, "Option '$1' has bad image mask $2") + +gen(1, 2434, IMAGE_UNKNOWN, "Unknown image type in file '$1'") + +gen(0, 2436, IMAGE_NOADJUST, + "Option 'adjustpage' must not be used in top-down system") + +gen(1, 2437, IMAGE_OPI_ILLRECT, "Option '$1' has bad rectangle") + +gen(2, 2438, IMAGE_OPI_ILLMAPSIZE, "Option '$1': Number of values must be $2") + +gen(1, 2439, IMAGE_OPI_ILLPARALL, "Option '$1' has bad parallelogram") + +gen(2, 2440, RAW_ILLSIZE, + "Size ($1 bytes) of raw image file '$2' doesn't match specified options") + +gen(2, 2442, IMAGE_TYPUNSUPP, "Image type '$1' is not supported in PDF $2") + +gen(1, 2444, BMP_VERSUNSUPP, + "Version of BMP image file '$1' not supported") + +gen(1, 2446, BMP_COMPUNSUPP, + "Compression in BMP image file '$1' not supported") + +gen(2, 2450, JPEG_COMPRESSION, + "JPEG compression scheme $1 in file '$2' not supported in PDF") + +/* UNUSED +gen(1, 2452, JPEG_MULTISCAN, + "JPEG file '$1' contains multiple scans, which is not supported in PDF") +*/ + +gen(2, 2454, JPEG_TRANSCODE, + "Problems during JPEG transcoding in file '$1' ($2)") + +/* UNUSED +gen(1, 2460, GIF_LZWOVERFLOW, "LZW code size overflow in GIF file '$1'") + +gen(1, 2462, GIF_LZWSIZE, + "Color palette in GIF file '$1' with fewer than 128 colors not supported") + +gen(1, 2464, GIF_INTERLACED, "Interlaced GIF image '$1' not supported") + +gen(2, 2470, TIFF_UNSUPP_CS, + "Couldn't open TIFF image '$1' (unsupported color space; photometric $2)") + +gen(2, 2472, TIFF_UNSUPP_PREDICT, + "Couldn't open TIFF image '$1' (unsupported predictor tag $2)") + +gen(1, 2474, TIFF_UNSUPP_LZW, "Couldn't open LZW-compressed TIFF image '$1')") + +gen(1, 2476, TIFF_UNSUPP_LZW_PLANES, + "Couldn't open TIFF image '$1' (separate planes with LZW compression)") + +gen(1, 2478, TIFF_UNSUPP_LZW_ALPHA, + "Couldn't open TIFF image '$1' (alpha channel with LZW compression)") + +gen(2, 2480, TIFF_UNSUPP_JPEG, + "Couldn't open TIFF image '$1' (JPEG compression scheme $2)") + +gen(1, 2482, TIFF_UNSUPP_JPEG_TILED, + "Couldn't open TIFF image '$1' (tiled image with JPEG compression)") +*/ + +gen(2, 2483, TIFF_UNSUPP_COLORSPACE, + "Color space (photometric) $1 in TIFF image '$2' not supported") + +gen(1, 2484, TIFF_UNSUPP_JPEG_SEPARATE, + "Couldn't open TIFF image '$1' (JPEG with separate image planes)") + +gen(2, 2486, TIFF_UNSUPP_SEP_NONCMYK, + "Couldn't open TIFF image '$1' (unsupported inkset tag $2)") + +gen(1, 2488, TIFF_MASK_MULTISTRIP, "Can't mask multistrip TIFF image '$1'") + +gen(2, 2489, TIFF_CLIPPPATH_NOTFOUND, + "Couldn't find clipping path '$1' in TIFF image '$2'") + +gen(1, 2490, TIFF_16BITCMYK_UNSUPP, + "Compressed 16-bit CMYK TIFF image '$1' not supported") + +gen(1, 2491, TIFF_16BIT_UNSUPP, + "More than 16 bits per component in TIFF image '$1' not supported") + +gen(1, 2492, TIFF_CMYK_MASK, "Couldn't open TIFF image '$1' (CMYK with mask)") + +gen(2, 2493, TIFF_UNSUPP_COMPRESSION, + "Compression scheme $1 in TIFF image '$2' not supported") + +gen(1, 2494, JPX_FORMATUNSUPP, + "JPEG2000 flavor in image file '$1' not supported") + +gen(1, 2496, JPX_RAWDATAUNSUPP, + "Raw JPEG2000 code stream in image file '$1' not supported") + +gen(1, 2498, JPX_COMPOUNDUNSUPP, + "Compound JPEG2000 (JPM) image file '$1' not supported") + + +/* -------------------------------------------------------------------- */ +/* Font (25xx) */ +/* -------------------------------------------------------------------- */ + +gen(2, 2500, FONT_CORRUPT, "Corrupt $1 font file '$2'") + +gen(2, 2501, FONT_PREFIX, "Font '$1' with encoding '$2': ") + +gen(0, 2502, FONT_BADENC, "Font doesn't support encoding") + +gen(3, 2503, FONT_PREFIX2, "Font '$1' with encoding '$2' (changed to '$3'): ") + +gen(1, 2504, FONT_FORCEENC, + "Font doesn't support encoding (encoding '$1' will be used)") + +gen(0, 2505, FONT_NEEDUCS2, + "Encoding not supported (use Unicode-compatible CMap)") + +/* UNUSED +gen(0, 2506, FONT_FORCEEMBED, + "Font will be embedded (encoding requires CID font") +*/ + +gen(1, 2507, FONT_INAPPROPENC, + "Encoding not appropriate for the font (only $1 glyphs found)") + +/* UNUSED +gen(1, 2508, FONT_BADTEXTFORM, + "Current text format not allowed for builtin encoding") +*/ + +gen(0, 2509, FONT_FORCECVTUNI, + "Native text code (keepnative) for this font configuration will be ignored") + +gen(0, 2514, FONT_EMBEDMM, "Multiple Master font cannot be embedded") + +gen(0, 2516, FONT_NOMETRICS, "Metrics data not found") + +gen(0, 2518, FONT_NOOUTLINE, "File with outline data not found") + +/* Unused +gen(0, 2520, FONT_NOGLYPHID, "Font doesn't contain any glyph IDs") +*/ + +gen(0, 2522, FONT_FORCEEMBED2, "Metadata requires embedding") + +gen(0, 2530, CJK_UNSUPP_REGISTRY, + "Font not supported (contains non-Adobe registry in CMap)") + +gen(0, 2531, CJK_UNSUPP_CHARCOLL, + "CJK font doesn't support encoding (use a compatible predefined CMap)") + +gen(0, 2532, FONT_EMBEDCMAP, + "Standard CJK font with predefined CMap cannot be embedded") + +gen(0, 2533, FONT_ONLY_CMAP, + "Font doesn't support encoding (use predefined CMap or 'unicode' encoding)") + +/* Unused +gen(0, 2534, FONT_EMBEDSTYLE, + "Option 'fontstyle' not allowed for embedded fonts") +*/ + +gen(0, 2535, FONT_UNSUPP_CMAP, + "Font doesn't support predefined CMap") + +gen(2, 2536, FONT_UNSUPPOPTION, + "Option '$1' not supported for font type '$2'") + +gen(0, 2538, FONT_IGNOREVERTICAL, + "Option 'vertical' ignored because of predefined CMap or font name resp.") + +gen(1, 2540, T3_BADBBOX, + "Bounding box values must be 0 for colorized font") + +gen(1, 2541, T3_FONT_PREFIX, "Type3 font '$1': ") + +gen(1, 2542, T3_GLYPH, "Glyph '$1' already defined") + +gen(0, 2544, T3_FONTEXISTS, "Already exists") + +gen(0, 2545, T3_FONTSUBSET, "Font with subsetting can only be loaded once") + +gen(1, 2546, T3_GLYPHMISSING, "Outlines of glyph '$1' not defined") + +gen(1, 2547, T3_OUTLINESMISSING, "Outlines of Type3 font '$1' missing") + +gen(1, 2548, T3_UNKOWNGLYPH, "Glyph '$1' unknown") + +gen(1, 2549, T3_MISSNOTDEF, "Glyph for character '.notdef' is missing") + +gen(1, 2550, T1_BADCHARSET, + "PDFlib doesn't support encoding (dfCharSet $1 in PFM file unknown)") + +gen(1, 2551, T1_UNSUPP_FORMAT, "'$1' metrics file type not supported") + +gen(2, 2554, T1_AFMBADKEY, "Unknown key '$1' in AFM file '$2'") + +gen(1, 2558, T1_NOFONT, "'$1' is not a PostScript Type1 font file") + +gen(2, 2560, FONT_CODENOTFOUND1, + "Glyph with character code $1 not found in font '$2'") + +gen(2, 2561, FONT_CODENOTFOUNDREP1, + "Glyph with character code $1 not found in font '$2' (will be replaced)") + +gen(2, 2562, FONT_UNICODENOTFOUND, + "Glyph with Unicode value U+$1 not found in font '$2'") + +gen(2, 2563, FONT_UNICODENOTFOUNDREP, + "Glyph with Unicode value U+$1 not found in font '$2' (will be replaced)") + +gen(2, 2564, FONT_GLYPHIDNOTFOUND, + "Glyph with id $1 not found in font '$2'") + +gen(3, 2566, FONT_CODENOTFOUND2, + "Glyph with code $1 and Unicode value U+$2 not found in font '$3'") + +gen(3, 2567, FONT_CODENOTFOUNDREP2, + "Glyph with code $1 and Unicode value U+$2 not found in font '$3' " + "(will be replaced)") + +gen(2, 2569, FONT_NOTFULFILL, + "Option '$1' cannot be fulfilled (same font already loaded with no$1)") + +/* -------------------------------------------------------------------- */ +/* Encoding (26xx) */ +/* -------------------------------------------------------------------- */ + +/* MOVED to pc_generr.h, #1552 +gen(1, 2600, ENC_NOTFOUND, "Couldn't find encoding '$1'") +*/ + +gen(1, 2602, ENC_UNSUPP, "Code page '$1' not supported") + +gen(1, 2606, ENC_CANTQUERY, "Can't query encoding '$1'") + +gen(1, 2608, ENC_CANTCHANGE, "Can't change encoding '$1'") + +gen(1, 2610, ENC_INUSE, + "Encoding '$1' can't be changed since it has already been used") + +/* MOVED to pc_generr.h, #1550 +gen(2, 2612, ENC_TOOLONG, "Encoding name '$1' too long (max. $2)") + + MOVED to pc_generr.h, #1551 +gen(2, 2614, ENC_BADLINE, "Syntax error in encoding file '$1' (line '$2')") +*/ + +gen(0, 2616, ENC_GLYPHORCODE, "Glyph name or Unicode value required") + +gen(3, 2618, ENC_BADGLYPH, + "Glyph name '$1' for Unicode value U+$2 differs from AGL name '$3'") + +gen(3, 2620, ENC_BADUNICODE, + "Unicode value U+$1 for glyph name '$2' differs from AGL value U+$3") + +gen(2, 2622, ENC_BADFONT, + "Current font $1 wasn't specified with encoding '$2'") + +gen(1, 2640, ENC_BADHYPTEXTENC, "Bad hypertext encoding '$1'") + +gen(1, 2650, ENC_UNSUPPENCFORMAT, + "Parameter or option '$1' not supported in Unicode-capable languages") + +/* Unused +gen(2, 2670, CMAP_ILLCODESEQU, "Illegal code sequence in '$1' for CMap '$2'") +*/ + + + +/* -------------------------------------------------------------------- */ +/* Hypertext, form fields, actions, annotations (28xx) */ +/* -------------------------------------------------------------------- */ + +gen(2, 2802, HYP_OPTIGNORE_FORTYPE, + "Option '$1' for destination type '$2' doesn't have any effect") + +gen(1, 2804, HYP_OPTIGNORE_FORELEM, + "Option '$1' for hypertext function will be ignored") + +gen(2, 2820, FF_OPTEFFLESS_FORTYPE, + "Option '$1' for field type '$2' doesn't have any effect") + +gen(1, 2822, FF_GROUPMISSING, + "Required field group missing for radio button field '$1'") + +gen(1, 2824, FF_FONTMISSING, "Font not specified for field '$1'") + +gen(2, 2826, FF_OPTIONMISSING, + "Option '$1' not specified for field '$2'") + +gen(1, 2828, FF_CIDFONT, + "Specified font '$1' not allowed for fields (encoding not supported)") + +gen(1, 2830, FF_NOEMBEDFONT, + "Specified font '$1' not allowed for fields (must be embedded)") + +gen(1, 2832, FF_SUBSETTFONT, + "Specified font '$1' not allowed for fields (must not be subset)") + +gen(1, 2834, FF_CAPTMISSING, "No caption or icon specified for field '$1'") + +gen(0, 2836, FF_DIFFSTRLISTS, + "Options 'itemnamelist' and 'itemtextlist' contain " + "different numbers of strings") + +gen(2, 2838, FF_INVALINDEX, "Option '$1' has invalid list index '$2'") + +gen(2, 2840, FF_NOTFOUND, + "Illegal field pathname '$1' (name '$2' not found)") + +gen(2, 2842, FF_NAMEEXISTS, + "Illegal field pathname '$1' (name '$2' already exists)") + +gen(2, 2844, FF_NOTGROUP, + "Illegal field pathname '$1' ('$2' is not a field group)") + +gen(3, 2846, FF_TYPENOTMATCH, + "Type '$1' of field '$2' doesn't match type '$3' of group") + +gen(0, 2848, FF_ITEMNAMEORNOT, +"Either all or none of the buttons/checkboxes in a group can have item names") + +gen(2, 2850, FF_OPTEFFONLY, + "Option '$1' for field type '$2' only has an effect for highlight=push") + +gen(2, 2852, FF_ILLUNINAME, + "Illegal field name '$1' (Unicode names are not supported in PDF $2") + +gen(0, 2854, FF_DEMOLIMIT, + "No more than 10 fields can be created with the evaluation version") + +gen(0, 2856, FF_RICHTEXT, + "fontsize 0 not supported for fields with rich text") + +gen(2, 2860, ACT_OPTIGNORE_FORTYPE, + "Option '$1' for action type '$2' doesn't have any effect") + +gen(2, 2862, ACT_BADACTTYPE, "Action type '$1' for event '$2' not allowed") + + +gen(2, 2880, ANN_OPTEFFLESS_FORTYPE, + "Option '$1' for annotation type '$2' doesn't have any effect") + +gen(1, 2882, ANN_NOSTDFONT, + "Font '$1' not allowed for annotations (not a core or standard CJK font)") + +gen(1, 2884, ANN_BADNUMCOORD, "Option '$1' has bad number of coordinates") + +gen(1, 2886, ANN_OPTALRDEF, + "Option '$1' already defined in option 'custom'") + +gen(1, 2888, ANN_ILLCUSTOMKEY, + "Option 'custom' uses illegal key '$1' (already defined in PDF)") + + +/* -------------------------------------------------------------------- */ +/* Internal (29xx) */ +/* -------------------------------------------------------------------- */ + +gen(1, 2900, INT_BADSCOPE, "Bad scope '$1'") + +gen(1, 2902, INT_BADANNOT, "Bad annotation type '$1'") + +gen(3, 2904, INT_BADCS, +"Unknown color space (function $1, index $2, type $3)") + +gen(1, 2906, INT_BADALTERNATE, "Bad alternate color space $1") + +gen(1, 2908, INT_BADPROFILE, "Unknown number of profile components ($1)") + +gen(1, 2910, INT_SSTACK_OVER, "State stack overflow in function '$1'") + +gen(1, 2912, INT_SSTACK_UNDER, "State stack underflow in function '$1'") + +gen(3, 2914, INT_WRAPPER, "Error in PDFlib $1 wrapper function $2 ($3)") + +gen(0, 2990, OT_UNSUPP_SID2CID, + "Accented characters not supported; contact support@pdflib.com") + + + + + + + +#undef gen +#undef pdf_genNames +#undef pdf_genInfo + + + diff --git a/src/pdflib/pdflib/p_gif.c b/src/pdflib/pdflib/p_gif.c new file mode 100644 index 0000000..59d80f5 --- /dev/null +++ b/src/pdflib/pdflib/p_gif.c @@ -0,0 +1,744 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_gif.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * GIF processing for PDFlib + * + */ + +/* + * This module contains modified parts of the giftopnm.c progam in the + * netpbm package. It contained the following copyright notice: + */ + +/* +-------------------------------------------------------------------+ */ +/* | Copyright 1990 - 1994, David Koblas. (koblas@netcom.com) | */ +/* | Permission to use, copy, modify, and distribute this software | */ +/* | and its documentation for any purpose and without fee is hereby | */ +/* | granted, provided that the above copyright notice appear in all | */ +/* | copies and that both that copyright notice and this permission | */ +/* | notice appear in supporting documentation. This software is | */ +/* | provided "as is" without express or implied warranty. | */ +/* +-------------------------------------------------------------------+ */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +#ifndef PDF_GIF_SUPPORTED + +pdc_bool +pdf_is_GIF_file(PDF *p, pdc_file *fp) +{ + (void) p; + (void) fp; + + return pdc_false; +} + +int +pdf_process_GIF_data( + PDF *p, + int imageslot) +{ + pdf_image *image = &p->images[imageslot]; + + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "GIF", 0, 0, 0); + + return -1; +} + +/* CDPDF - added missing function */ +void +pdf_cleanup_gif(PDF *p, pdf_image *image) +{ + (void) p; + (void) image; +} + +#else + +#define LOCALCOLORMAP 0x80 +#define BitSet(byteval, bitval) (((byteval) & (bitval)) == (bitval)) + +static int ReadColorMap(pdc_core *pdc, pdc_file *fp, + int number, pdf_colormap *buffer); +static int DoExtension(PDF *p, pdf_image *image, int label); +static int GetDataBlock(PDF *p, pdf_image *image, unsigned char *buf); +static void ReadImage(PDF *p, pdf_image *image, PDF_data_source *src); + +static void +pdf_data_source_GIF_init(PDF *p, PDF_data_source *src) +{ + pdf_image *image; + + image = (pdf_image *) src->private_data; + + src->buffer_length = (size_t) (image->width * image->height * 1); + src->buffer_start = (pdc_byte *) pdc_malloc(p->pdc, src->buffer_length, + "pdf_data_source_GIF_init"); + src->bytes_available= 0; + src->next_byte = NULL; +} + +static pdc_bool +pdf_data_source_GIF_fill(PDF *p, PDF_data_source *src) +{ + pdf_image *image; + + if (src->next_byte != NULL) /* all finished in one turn */ + return pdc_false; + + image = (pdf_image *) src->private_data; + + src->next_byte = src->buffer_start; + src->bytes_available = src->buffer_length; + + PDC_TRY(p->pdc) + { + ReadImage(p, image, src); + } + PDC_CATCH(p->pdc) + { + image->corrupt = pdc_true; + } + + pdf_cleanup_gif(p, image); + + return !image->corrupt; +} + +static void +pdf_data_source_GIF_terminate(PDF *p, PDF_data_source *src) +{ + pdc_free(p->pdc, (void *) src->buffer_start); +} + +#define PDF_STRING_GIF "\107\111\106" +#define PDF_STRING_87a "\070\067\141" +#define PDF_STRING_89a "\070\071\141" + +pdc_bool +pdf_is_GIF_file(PDF *p, pdc_file *fp) +{ + unsigned char buf[3]; + + pdc_logg_cond(p->pdc, 1, trc_image, "\tChecking image type GIF...\n"); + + if (!PDC_OK_FREAD(fp, buf, 3) || + strncmp((const char *) buf, PDF_STRING_GIF, 3) != 0) + { + pdc_fseek(fp, 0L, SEEK_SET); + return pdc_false; + } + return pdc_true; +} + +int +pdf_process_GIF_data( + PDF *p, + int imageslot) +{ + unsigned char buf[16]; + char c; + int imageCount = 0; + char version[4]; + int errcode = 0; + pdf_image *image; + pdf_colorspace cs; + pdf_colormap colormap; + int slot; + + image = &p->images[imageslot]; + + image->info.gif.stack = NULL; + image->info.gif.table = NULL; + + /* we invert this flag later */ + if (image->ignoremask) + image->transparent = pdc_true; + + if (image->page == pdc_undef) + image->page = 1; + + /* Error reading magic number or not a GIF file */ + if (pdf_is_GIF_file(p, image->fp) == pdc_false) { + errcode = PDC_E_IO_BADFORMAT; + goto PDF_GIF_ERROR; + } + + /* Version number */ + if (! PDC_OK_FREAD(image->fp, buf, 3)) { + errcode = PDC_E_IO_BADFORMAT; + goto PDF_GIF_ERROR; + } + strncpy(version, (const char *) buf, 3); + version[3] = '\0'; + if ((strcmp(version, PDF_STRING_87a) != 0) && + (strcmp(version, PDF_STRING_89a) != 0)) { + errcode = PDC_E_IO_BADFORMAT; + goto PDF_GIF_ERROR; + } + + /* Failed to read screen descriptor */ + if (! PDC_OK_FREAD(image->fp, buf, 7)) { + errcode = PDC_E_IO_BADFORMAT; + goto PDF_GIF_ERROR; + } + + cs.type = Indexed; + /* size of the global color table */ + cs.val.indexed.palette_size = 2 << (buf[4] & 0x07); + cs.val.indexed.base = DeviceRGB; + cs.val.indexed.colormap = &colormap; + cs.val.indexed.colormap_id = PDC_BAD_ID; + + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + if (ReadColorMap(p->pdc, image->fp, + cs.val.indexed.palette_size, &colormap)) { + errcode = PDF_E_IMAGE_COLORMAP; + goto PDF_GIF_ERROR; + } + } + + /* translate the aspect ratio to PDFlib notation */ + if (buf[6] != 0) { + image->dpi_x = (pdc_scalar) (-(buf[6] + 15.0) / 64.0); + image->dpi_y = -1.0; + } + + for (/* */ ; /* */ ; /* */) { + /* EOF / read error in image data */ + if (!PDC_OK_FREAD(image->fp, &c, 1)) { + errcode = PDC_E_IO_READ; + goto PDF_GIF_ERROR; + } + +#define PDF_SEMICOLON ((char) 0x3b) /* ASCII ';' */ + + if (c == PDF_SEMICOLON) { /* GIF terminator */ + /* Not enough images found in file */ + if (imageCount < image->page) { + if (!imageCount) + errcode = PDF_E_IMAGE_CORRUPT; + else + errcode = PDF_E_IMAGE_NOPAGE; + goto PDF_GIF_ERROR; + } + break; + } + +#define PDF_EXCLAM ((char) 0x21) /* ASCII '!' */ + + if (c == PDF_EXCLAM) { /* Extension */ + if (!PDC_OK_FREAD(image->fp, &c, 1)) { + /* EOF / read error on extension function code */ + errcode = PDC_E_IO_READ; + goto PDF_GIF_ERROR; + } + DoExtension(p, image, (int) c); + continue; + } + +#define PDF_COMMA ((char) 0x2c) /* ASCII ',' */ + + if (c != PDF_COMMA) { /* Not a valid start character */ + /* Bogus character, ignoring */ + continue; + } + + ++imageCount; + + if (! PDC_OK_FREAD(image->fp, buf, 9)) { + /* Couldn't read left/top/width/height */ + errcode = PDC_E_IO_READ; + goto PDF_GIF_ERROR; + } + + image->components = 1; + image->bpc = 8; + image->width = (pdc_scalar) pdc_get_le_ushort(&buf[4]); + image->height = (pdc_scalar) pdc_get_le_ushort(&buf[6]); + +#define INTERLACE 0x40 + image->info.gif.interlace= BitSet(buf[8], INTERLACE); + + if (image->imagemask) + { + if (p->compatibility <= PDC_1_3) { + errcode = PDF_E_IMAGE_MASK1BIT13; + goto PDF_GIF_ERROR; + } else { + /* images with more than one bit will be written as /SMask, + * and don't require an /ImageMask entry. + */ + image->imagemask = pdc_false; + } + image->colorspace = DeviceGray; + } + + if (BitSet(buf[8], LOCALCOLORMAP)) { + /* The local color map may have a different size */ + cs.val.indexed.palette_size = 2 << (buf[8] & 0x07); + + if (ReadColorMap(p->pdc, image->fp, + cs.val.indexed.palette_size, &colormap)) + { + errcode = PDF_E_IMAGE_COLORMAP; + goto PDF_GIF_ERROR; + } + } + + if (imageCount == image->page) + break; + } + + image->src.init = pdf_data_source_GIF_init; + image->src.fill = pdf_data_source_GIF_fill; + image->src.terminate = pdf_data_source_GIF_terminate; + image->src.private_data = (void *) image; + + image->compression = pdf_comp_none; + image->use_raw = pdc_false; + + image->in_use = pdc_true; /* mark slot as used */ + + slot = pdf_add_colorspace(p, &cs, pdc_false); + image->colorspace = slot; + + + + + pdf_put_image(p, imageslot, pdc_true, pdc_true); + + if (!image->corrupt) + return imageslot; + + PDF_GIF_ERROR: + { + const char *stemp = NULL; + + if (errcode) + stemp = pdf_get_image_filename(p, image); + + switch (errcode) + { + case PDC_E_IO_READ: + case PDF_E_IMAGE_COLORMAP: + case PDF_E_IMAGE_MASK1BIT13: + pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0); + break; + + case PDC_E_IO_BADFORMAT: + pdc_set_errmsg(p->pdc, errcode, stemp, "GIF", 0, 0); + break; + + case PDF_E_IMAGE_CORRUPT: + pdc_set_errmsg(p->pdc, errcode, "GIF", stemp, 0, 0); + break; + + case PDF_E_IMAGE_NOPAGE: + pdc_set_errmsg(p->pdc, errcode, + pdc_errprintf(p->pdc, "%d", image->page), "GIF", stemp, 0); + break; + + case 0: /* error code and message already set */ + break; + } + } + + return -1; +} /* pdf_open_GIF_data */ + +static int +ReadColorMap(pdc_core *pdc, pdc_file *fp, int number, pdf_colormap *buffer) +{ + int i; + unsigned char rgb[3]; + + (void) pdc; + + for (i = 0; i < number; ++i) { + if (! PDC_OK_FREAD(fp, rgb, sizeof(rgb))) { + return pdc_true; /* yk: true == error */ + } + + (*buffer)[i][0] = rgb[0] ; + (*buffer)[i][1] = rgb[1] ; + (*buffer)[i][2] = rgb[2] ; + } + return pdc_false; /* yk: false == ok. */ +} /* ReadColorMap */ + +static int +DoExtension(PDF *p, pdf_image *image, int label) +{ + pdc_byte buf[256]; + + switch ((unsigned char) label) { + case 0x01: /* Plain Text Extension */ + break; + + case 0xff: /* Application Extension */ + break; + + case 0xfe: /* Comment Extension */ + while (GetDataBlock(p, image, (unsigned char*) buf) != 0) { + /* */ + } + return pdc_false; + + case 0xf9: /* Graphic Control Extension */ + (void) GetDataBlock(p, image, (unsigned char*) buf); + + if ((buf[0] & 0x1) != 0) { + image->transparent = !image->transparent; + image->transval[0] = buf[3]; + } + + while (GetDataBlock(p, image, (unsigned char*) buf) != 0) { + /* */ ; + } + return pdc_false; + + default: + break; + } + + while (GetDataBlock(p, image, (unsigned char*) buf) != 0) { + /* */ ; + } + + return pdc_false; +} /* DoExtension */ + +/* + * A bunch of formely static variables which are now kept in the + * image structure in order to keep the GIF reader thread-safe. + */ + +/* for GetDataBlock() */ +#define ZeroDataBlock (image->info.gif.ZeroDataBlock) + +/* for initLWZ() */ +#define curbit (image->info.gif.curbit) +#define lastbit (image->info.gif.lastbit) +#define get_done (image->info.gif.get_done) +#define last_byte (image->info.gif.last_byte) +#define return_clear (image->info.gif.return_clear) + +#define sp (image->info.gif.sp) +#define code_size (image->info.gif.code_size) +#define set_code_size (image->info.gif.set_code_size) +#define max_code (image->info.gif.max_code) +#define max_code_size (image->info.gif.max_code_size) +#define clear_code (image->info.gif.clear_code) +#define end_code (image->info.gif.end_code) + +/* for nextCode() */ +#define buf (image->info.gif.buf) + +/* for nextLWZ() */ +#define stack (image->info.gif.stack) +#define table (image->info.gif.table) +#define firstcode (image->info.gif.firstcode) +#define oldcode (image->info.gif.oldcode) + +static int +GetDataBlock(PDF *p, pdf_image *image, unsigned char *lbuf) +{ + unsigned char count; + pdc_file *fp = image->fp; + + if (!PDC_OK_FREAD(fp, &count, 1)) + return -1; /* Error in getting DataBlock size */ + + ZeroDataBlock = (count == 0); + + if ((count != (unsigned char) 0) && (!PDC_OK_FREAD(fp, lbuf, count))) + { + /* Error in reading DataBlock */ + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF", + pdf_get_image_filename(p, image), 0, 0); + } + + return count; +} /* GetDataBlock */ + +static void +initLWZ(PDF *p, pdf_image *image, int input_code_size) +{ +#define GIF_TABLE_SIZE (sizeof(int [2][GIF_TABLE_ELEMENTS])) +#define GIF_STACK_SIZE (sizeof(int [GIF_TABLE_ELEMENTS*2])) + + table = (int(*)[GIF_TABLE_ELEMENTS]) + pdc_malloc(p->pdc, GIF_TABLE_SIZE, "initLWZ"); + stack = (int *) pdc_malloc(p->pdc, GIF_STACK_SIZE, "initLWZ"); + + set_code_size = input_code_size; + code_size = set_code_size + 1; + clear_code = 1 << set_code_size ; + end_code = clear_code + 1; + max_code_size = 2 * clear_code; + max_code = clear_code + 2; + + curbit = lastbit = 0; + last_byte = 2; + get_done = pdc_false; + + return_clear = pdc_true; + + sp = stack; +} + +/* + * We clean up after decompressing the image; in rare cases (exception + * caused by damaged compressed data) this may also be called when + * cleaning up the full image struct. + */ +void +pdf_cleanup_gif(PDF *p, pdf_image *image) +{ + if (table) + { + pdc_free(p->pdc, table); + table = NULL; + } + if (stack) + { + pdc_free(p->pdc, stack); + stack = NULL; + } +} + +static int +nextCode(PDF *p, pdf_image *image, int codesize) +{ + static const int maskTbl[16] = { + 0x0000, 0x0001, 0x0003, 0x0007, + 0x000f, 0x001f, 0x003f, 0x007f, + 0x00ff, 0x01ff, 0x03ff, 0x07ff, + 0x0fff, 0x1fff, 0x3fff, 0x7fff, + }; + int i, j, ret, end; + + if (return_clear) { + return_clear = pdc_false; + return clear_code; + } + + end = curbit + codesize; + + if (end >= lastbit) { + int count; + + if (get_done) { + if (curbit >= lastbit) + { + /* + ERROR("ran off the end of my bits" ); + */ + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF", + pdf_get_image_filename(p, image), 0, 0); + } + return -1; + } + + if (last_byte >= 2) + { + buf[0] = buf[last_byte-2]; + buf[1] = buf[last_byte-1]; + } + + if ((count = GetDataBlock(p, image, &buf[2])) == 0) + get_done = pdc_true; + + last_byte = 2 + count; + curbit = (curbit - lastbit) + 16; + lastbit = (2+count)*8 ; + + end = curbit + codesize; + } + + j = end / 8; + i = curbit / 8; + + if (i == j) + ret = buf[i]; + else if (i + 1 == j) + ret = buf[i] | (buf[i+1] << 8); + else + ret = buf[i] | (buf[i+1] << 8) | (buf[i+2] << 16); + + ret = (ret >> (curbit % 8)) & maskTbl[codesize]; + + curbit += codesize; + + return ret; +} + +#define readLWZ(p, image) ((sp > stack) ? *--sp : nextLWZ(p, image)) + +static int +nextLWZ(PDF *p, pdf_image *image) +{ + int code, incode; + int i; + + while ((code = nextCode(p, image, code_size)) >= 0) { + if (code == clear_code) { + for (i = 0; i < clear_code; ++i) { + table[0][i] = 0; + table[1][i] = i; + } + for (; i < (1< 0) + ; + + /* count != 0: INFO_MSG(("missing EOD in data stream")); */ + + return -2; + } + + incode = code; + + if (code >= max_code) { + *sp++ = firstcode; + code = oldcode; + } + + while (code >= clear_code) { + *sp++ = table[1][code]; + if (code == table[0][code]) + { + /* ERROR("circular table entry BIG ERROR"); */ + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF", + pdf_get_image_filename(p, image), 0, 0); + } + code = table[0][code]; + } + + *sp++ = firstcode = table[1][code]; + + if ((code = max_code) <(1<= max_code_size) && + (max_code_size < (1< stack) + return *--sp; + } + return code; +} + +static void +ReadImage(PDF *p, pdf_image *image, PDF_data_source *src) +{ + unsigned char c; + int v; + unsigned int xpos = 0, ypos = 0; + pdc_byte *dp; + unsigned int h = (unsigned int) image->height; + unsigned int w = (unsigned int) image->width; + + /* + * Initialize the Compression routines + */ + ZeroDataBlock = pdc_false; + + if (!PDC_OK_FREAD(image->fp, &c, 1)) + { + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF", + pdf_get_image_filename(p, image), 0, 0); + } + + initLWZ(p, image, c); + + if (image->info.gif.interlace) { + int i; + int pass = 0, step = 8; + + for (i = 0; i < (int) h; i++) { + dp = &src->buffer_start[w * ypos]; + for (xpos = 0; xpos < w; xpos++) { + if ((v = readLWZ(p, image)) < 0) + goto fini; + + *dp++ = v; + } + if ((ypos += step) >= h) { + do { + if (pass++ > 0) + step /= 2; + ypos = step / 2; + } while (ypos > h); + } + } + } else { + dp = src->buffer_start; + for (ypos = 0; ypos < h; ypos++) { + for (xpos = 0; xpos < w; xpos++) { + if ((v = readLWZ(p, image)) < 0) + goto fini; + + *dp++ = v; + } + } + } + +fini: + if (readLWZ(p, image) >= 0) + /* Too much input data in GIF file '%s', ignoring extra. */ + ; +} + +#undef fresh +#undef code_size +#undef set_code_size +#undef max_code +#undef max_code_size +#undef firstcode +#undef oldcode +#undef clear_code +#undef end_code +#undef sp +#undef table +#undef stack + +#endif /* PDF_GIF_SUPPORTED */ diff --git a/src/pdflib/pdflib/p_gstate.c b/src/pdflib/pdflib/p_gstate.c new file mode 100644 index 0000000..2b62542 --- /dev/null +++ b/src/pdflib/pdflib/p_gstate.c @@ -0,0 +1,451 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_gstate.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib routines dealing with the graphics states + * + */ + +#include "p_intern.h" + +/* ---------------------- matrix functions ----------------------------- */ + +void +pdf_concat_raw(PDF *p, pdc_matrix *m) +{ + if (pdc_is_identity_matrix(m)) + return; + + pdf_end_text(p); + + pdc_printf(p->out, "%f %f %f %f %f %f cm\n", + m->a, m->b, m->c, m->d, m->e, m->f); + + pdc_multiply_matrix(m, &p->curr_ppt->gstate[p->curr_ppt->sl].ctm); +} + +void +pdf_set_topdownsystem(PDF *p, pdc_scalar height) +{ + if (p->ydirection < 0) + { + pdc_matrix m, sm; + + pdc_translation_matrix(0, height, &m); + pdc_scale_matrix(1, -1, &sm); + pdc_multiply_matrix(&sm, &m); + pdf_concat_raw(p, &m); + } +} + +/* -------------------- Special graphics state ---------------------------- */ + +void +pdf_init_gstate(PDF *p) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + + pdc_identity_matrix(&gs->ctm); + + gs->x = 0; + gs->y = 0; + + p->curr_ppt->fillrule = pdf_fill_winding; + + gs->lwidth = 1; + gs->lcap = 0; + gs->ljoin = 0; + gs->miter = 10; + gs->flatness = -1; /* -1 means "has not been set" */ + gs->dashed = pdc_false; +} + +void +pdf__save(PDF *p) +{ + pdf_ppt * ppt = p->curr_ppt; + int sl = ppt->sl; + + if (sl == PDF_MAX_SAVE_LEVEL - 1) + pdc_error(p->pdc, PDF_E_GSTATE_SAVELEVEL, + pdc_errprintf(p->pdc, "%d", PDF_MAX_SAVE_LEVEL - 1), 0, 0, 0); + + pdf_end_text(p); + pdc_puts(p->out, "q\n"); + + /* propagate states to next level */ + memcpy(&ppt->gstate[sl + 1], &ppt->gstate[sl], sizeof(pdf_gstate)); + pdf_save_cstate(p); + pdf_save_tstate(p); + ++ppt->sl; +} + +void +pdf__restore(PDF *p) +{ + if (p->curr_ppt->sl == 0) + pdc_error(p->pdc, PDF_E_GSTATE_RESTORE, 0, 0, 0, 0); + + pdf_end_text(p); + + pdc_puts(p->out, "Q\n"); + + p->curr_ppt->sl--; + + pdf_restore_currto(p); +} + +void +pdf__translate(PDF *p, pdc_scalar tx, pdc_scalar ty) +{ + pdc_matrix m; + + pdc_check_number(p->pdc, "tx", tx); + pdc_check_number(p->pdc, "ty", ty); + + if (tx == 0 && ty == 0) + return; + + pdc_translation_matrix(tx, ty, &m); + + pdf_concat_raw(p, &m); +} + +void +pdf__scale(PDF *p, pdc_scalar sx, pdc_scalar sy) +{ + pdc_matrix m; + + pdc_check_number_zero(p->pdc, "sx", sx); + pdc_check_number_zero(p->pdc, "sy", sy); + + if (sx == 1 && sy == 1) + return; + + pdc_scale_matrix(sx, sy, &m); + + pdf_concat_raw(p, &m); +} + +void +pdf__rotate(PDF *p, pdc_scalar phi) +{ + pdc_matrix m; + + pdc_check_number(p->pdc, "phi", phi); + + if (phi == 0) + return; + + pdc_rotation_matrix(p->ydirection * phi, &m); + + pdf_concat_raw(p, &m); +} + +void +pdf__skew(PDF *p, pdc_scalar alpha, pdc_scalar beta) +{ + pdc_matrix m; + + pdc_check_number(p->pdc, "alpha", alpha); + pdc_check_number(p->pdc, "beta", beta); + + if (alpha == 0 && beta == 0) + return; + + if (alpha > 360 || alpha < -360 || + alpha == -90 || alpha == -270 || + alpha == 90 || alpha == 270) + { + pdc_error(p->pdc, PDC_E_ILLARG_FLOAT, + "alpha", pdc_errprintf(p->pdc, "%f", alpha), 0, 0); + } + + if (beta > 360 || beta < -360 || + beta == -90 || beta == -270 || + beta == 90 || beta == 270) + { + pdc_error(p->pdc, PDC_E_ILLARG_FLOAT, + "beta", pdc_errprintf(p->pdc, "%f", beta), 0, 0); + } + + pdc_skew_matrix(p->ydirection * alpha, p->ydirection * beta, &m); + + pdf_concat_raw(p, &m); +} + +void +pdf__concat(PDF *p, pdc_scalar a, pdc_scalar b, pdc_scalar c, pdc_scalar d, + pdc_scalar e, pdc_scalar f) +{ + pdc_matrix m; + pdc_scalar det = a * d - b * c; + + pdc_check_number(p->pdc, "a", a); + pdc_check_number(p->pdc, "b", b); + pdc_check_number(p->pdc, "c", c); + pdc_check_number(p->pdc, "d", d); + pdc_check_number(p->pdc, "e", e); + pdc_check_number(p->pdc, "f", f); + + if (fabs(det) < PDF_SMALLREAL) + pdc_error(p->pdc, PDC_E_ILLARG_MATRIX, + pdc_errprintf(p->pdc, "%f %f %f %f %f %f", a, b, c, d, e, f), + 0, 0, 0); + + m.a = a; + m.b = b; + m.c = c; + m.d = d; + m.e = e; + m.f = f; + + pdf_concat_raw(p, &m); +} + +void +pdf_setmatrix_e(PDF *p, pdc_matrix *n) +{ + pdc_matrix m; + pdc_scalar det = n->a * n->d - n->b * n->c; + + if (fabs(det) < PDF_SMALLREAL) + pdc_error(p->pdc, PDC_E_ILLARG_MATRIX, + pdc_errprintf(p->pdc, "%f %f %f %f %f %f", + n->a, n->b, n->c, n->d, n->e, n->f), + 0, 0, 0); + + pdc_invert_matrix(p->pdc, &m, &p->curr_ppt->gstate[p->curr_ppt->sl].ctm); + pdc_multiply_matrix(n, &m); + pdf_concat_raw(p, &m); +} + + +void +pdf__setmatrix(PDF *p, pdc_scalar a, pdc_scalar b, pdc_scalar c, pdc_scalar d, + pdc_scalar e, pdc_scalar f) +{ + pdc_matrix n; + + pdc_check_number(p->pdc, "a", a); + pdc_check_number(p->pdc, "b", b); + pdc_check_number(p->pdc, "c", c); + pdc_check_number(p->pdc, "d", d); + pdc_check_number(p->pdc, "e", e); + pdc_check_number(p->pdc, "f", f); + + n.a = a; + n.b = b; + n.c = c; + n.d = d; + n.e = e; + n.f = f; + pdf_setmatrix_e(p, &n); +} + +/* -------------------- General graphics state ---------------------------- */ + +/* definitions of dash options */ +static const pdc_defopt pdf_dashoptions[] = +{ + {"dasharray", pdc_scalarlist, PDC_OPT_NONE, 2, PDF_MAX_DASHLENGTH, + PDC_FLOAT_PREC, PDC_FLOAT_MAX, NULL}, + + {"dashphase", pdc_scalarlist, PDC_OPT_NONE, 1, 1, 0.0, PDC_FLOAT_MAX, NULL}, + + PDC_OPT_TERMINATE +}; + +void +pdf_setdashpattern_internal(PDF *p, pdc_scalar *darray, int length, + pdc_scalar phase) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + + /* length == 0 or 1 means solid line */ + if (length < 2) + { + if (gs->dashed || PDF_FORCE_OUTPUT()) + { + pdc_puts(p->out, "[] 0 d\n"); + gs->dashed = pdc_false; + } + } + else + { + int i; + + pdc_begin_array(p->out); + for (i = 0; i < length; i++) + { + pdc_printf(p->out, "%f ", darray[i]); + } + pdc_end_array_c(p->out); + pdc_printf(p->out, "%f d\n", phase); + gs->dashed = pdc_true; + } +} + +void +pdf__setdash(PDF *p, pdc_scalar b, pdc_scalar w) +{ + pdc_scalar darray[2]; + int length = 2; + + pdc_check_number_limits(p->pdc, "b", b, 0.0, PDC_FLOAT_MAX); + pdc_check_number_limits(p->pdc, "w", w, 0.0, PDC_FLOAT_MAX); + + /* both zero means solid line */ + if (b == 0.0 && w == 0.0) + { + length = 0; + } + else + { + darray[0] = b; + darray[1] = w; + } + pdf_setdashpattern_internal(p, darray, length, 0); +} + +void +pdf__setdashpattern(PDF *p, const char *optlist) +{ + pdc_resopt *results; + char **strlist; + pdc_scalar *darray = NULL, phase = 0; + int length; + + /* parsing optlist */ + results = pdc_parse_optionlist(p->pdc, optlist, pdf_dashoptions, NULL, + pdc_true); + + length = pdc_get_optvalues("dasharray", results, NULL, &strlist); + darray = (pdc_scalar *) strlist; + + pdc_get_optvalues("dashphase", results, &phase, NULL); + + pdf_setdashpattern_internal(p, darray, length, phase); + + pdc_cleanup_optionlist(p->pdc, results); +} + +void +pdf__setflat(PDF *p, pdc_scalar flat) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + + pdc_check_number_limits(p->pdc, "flat", flat, 0.0, 100.0); + + if (flat != gs->flatness || PDF_FORCE_OUTPUT()) + { + gs->flatness = flat; + pdc_printf(p->out, "%f i\n", flat); + } +} + +void +pdf__setlinejoin(PDF *p, int join) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + const int LAST_JOIN = 2; + + if (join < 0 || join > LAST_JOIN) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "join", pdc_errprintf(p->pdc, "%d", join), 0, 0); + + if (join != gs->ljoin || PDF_FORCE_OUTPUT()) + { + gs->ljoin = join; + pdc_printf(p->out, "%d j\n", join); + } +} + +void +pdf__setlinecap(PDF *p, int cap) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + const int LAST_CAP = 2; + + if (cap < 0 || cap > LAST_CAP) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "cap", pdc_errprintf(p->pdc, "%d", cap), 0, 0); + + if (cap != gs->lcap || PDF_FORCE_OUTPUT()) + { + gs->lcap = cap; + pdc_printf(p->out, "%d J\n", cap); + } +} + +void +pdf__setmiterlimit(PDF *p, pdc_scalar miter) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + + pdc_check_number_limits(p->pdc, "miter", miter, 1.0, PDC_FLOAT_MAX); + + if (miter != gs->miter || PDF_FORCE_OUTPUT()) + { + gs->miter = miter; + pdc_printf(p->out, "%f M\n", miter); + } +} + +void +pdf__setlinewidth(PDF *p, pdc_scalar width) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + + pdc_check_number_limits(p->pdc, "width", width, + PDC_FLOAT_PREC, PDC_FLOAT_MAX); + + if (width != gs->lwidth || PDF_FORCE_OUTPUT()) + { + gs->lwidth = width; + pdc_printf(p->out, "%f w\n", width); + } +} + +/* reset all gstate parameters except CTM +*/ +void +pdf_reset_gstate(PDF *p) +{ + pdf_gstate *gs = &p->curr_ppt->gstate[p->curr_ppt->sl]; + + pdf_set_default_color(p, pdc_true); + pdf__setlinewidth(p, 1); + pdf__setlinecap(p, 0); + pdf__setlinejoin(p, 0); + pdf__setmiterlimit(p, 10); + pdf__setdash(p, 0, 0); + + if (gs->flatness != -1) + pdf__setflat(p, 1); +} + +void +pdf__initgraphics(PDF *p) +{ + pdc_matrix inv_ctm; + + pdf_reset_gstate(p); + + pdc_invert_matrix(p->pdc, &inv_ctm, + &p->curr_ppt->gstate[p->curr_ppt->sl].ctm); + pdf_concat_raw(p, &inv_ctm); + + /* This also resets the CTM which guards against rounding artifacts. */ + pdf_init_gstate(p); +} diff --git a/src/pdflib/pdflib/p_hkscmyk.h b/src/pdflib/pdflib/p_hkscmyk.h new file mode 100644 index 0000000..924ad64 --- /dev/null +++ b/src/pdflib/pdflib/p_hkscmyk.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_hkscmyk.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib HKS spot CMYK color table + * + * HKS is a registered trademark of + * HKS (Hostmann-Steinberg, K+E, Schmincke)-Warenzeichenverband e.V. + * Germany + * + */ + +#ifndef P_HKSCMYK_H +#define P_HKSCMYK_H + + +#endif /* P_HKSCMYK_H */ + diff --git a/src/pdflib/pdflib/p_hkslab.h b/src/pdflib/pdflib/p_hkslab.h new file mode 100644 index 0000000..68f13bb --- /dev/null +++ b/src/pdflib/pdflib/p_hkslab.h @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_hkslab.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib HKS spot Lab color table + * + * HKS is a registered trademark of + * HKS (Hostmann-Steinberg, K+E, Schmincke)-Warenzeichenverband e.V. Germany + * + */ + +#ifndef P_HKSLAB_H +#define P_HKSLAB_H + + +#endif /* P_HKSTAB_H */ diff --git a/src/pdflib/pdflib/p_hyper.c b/src/pdflib/pdflib/p_hyper.c new file mode 100644 index 0000000..644e311 --- /dev/null +++ b/src/pdflib/pdflib/p_hyper.c @@ -0,0 +1,1449 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_hyper.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib routines for hypertext stuff: + * named destination, bookmarks, document info + * + */ + +#define P_HYPER_C + +#include "p_intern.h" +#include "p_color.h" + + + + +/* -------------------------- named destinations -------------------------- */ + +typedef enum +{ + fixed, + fitwindow, + fitwidth, + fitheight, + fitrect, + fitvisible, + fitvisiblewidth, + fitvisibleheight, + nameddest, + filedest +} +pdf_desttype; + +static const pdc_keyconn pdf_type_keylist[] = +{ + {"fixed", fixed}, + {"fitwindow", fitwindow}, + {"fitwidth", fitwidth}, + {"fitheight", fitheight}, + {"fitrect", fitrect}, + {"fitvisible", fitvisible}, + {"fitvisiblewidth", fitvisiblewidth}, + {"fitvisibleheight",fitvisibleheight}, + {"nameddest", nameddest}, + {"file", filedest}, + {NULL, 0} +}; + +/* Destination structure */ +struct pdf_dest_s +{ + pdf_desttype type; + char *filename; /* name of a file to be launched - deprecated */ + int remote_page; /* remote target page number */ + int pgnum; + pdc_id page; /* local target page object id */ + char *name; /* destination name, only for type=nameddest */ + int len; /* length of the name string */ + pdc_scalar zoom; /* magnification */ + pdc_scalar left; + pdc_scalar right; + pdc_scalar bottom; + pdc_scalar top; + pdc_scalar color[3]; /* rgb color of bookmark text - deprecated */ + fnt_fontstyle fontstyle; /* font style of bookmark text - deprecated */ +}; + +static const pdc_defopt pdf_destination_options[] = +{ + {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"hypertextformat", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_textformat_keylist}, + + {"fitbbox", pdc_booleanlist, PDC_OPT_NONE, + 1, 1, 0.0, 0.0, NULL}, + + {"fitheight", pdc_booleanlist, PDC_OPT_NONE, + 1, 1, 0.0, 0.0, NULL}, + + {"fitpage", pdc_booleanlist, PDC_OPT_NONE, + 1, 1, 0.0, 0.0, NULL}, + + {"fitwidth", pdc_booleanlist, PDC_OPT_NONE, + 1, 1, 0.0, 0.0, NULL}, + + {"retain", pdc_booleanlist, PDC_OPT_NONE, + 1, 1, 0.0, 0.0, NULL}, + + {"type", pdc_keywordlist, PDC_OPT_NONE, + 1, 1, 0.0, 0.0, pdf_type_keylist}, + + {"name", pdc_stringlist, PDC_OPT_NONE, + 1, 1, 1.0, PDC_INT_MAX, NULL}, + + {"page", pdc_integerlist, PDC_OPT_NONE, + 1, 1, 0, PDC_INT_MAX, NULL}, + + {"group", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 1.0, PDF_MAX_NAMESTRING, NULL}, + + /* Acrobat 5 supports a maximum zoom of 1600%, but we allow some more */ + {"zoom", pdc_scalarlist, PDC_OPT_PERCENT, + 1, 1, 0.0, 10000, NULL}, + + {"left", pdc_scalarlist, PDC_OPT_NONE, + 1, 1, 0.0, PDF_ACRO_MAXPAGE, NULL}, + + {"right", pdc_scalarlist, PDC_OPT_NONE, + 1, 1, 0.0, PDF_ACRO_MAXPAGE, NULL}, + + {"bottom", pdc_scalarlist, PDC_OPT_REQUIRIF1, + 1, 1, 0.0, PDF_ACRO_MAXPAGE, NULL}, + + {"top", pdc_scalarlist, PDC_OPT_NONE, + 1, 1, 0.0, PDF_ACRO_MAXPAGE, NULL}, + + {"color", pdc_scalarlist, PDC_OPT_NONE, + 1, 3, 0.0, 1.0, NULL}, + + {"fontstyle", pdc_keywordlist, PDC_OPT_NONE, + 1, 1, 0.0, 0.0, pdf_fontstyle_pdfkeylist}, + + {"filename", pdc_stringlist, PDC_OPT_NONE, + 1, 1, 0.0, PDC_FILENAMELEN, NULL}, + + PDC_OPT_TERMINATE +}; + +pdf_dest * +pdf_init_destination(PDF *p) +{ + static const char fn[] = "pdf_init_destination"; + pdf_dest *dest = (pdf_dest *) pdc_malloc(p->pdc, sizeof(pdf_dest), fn); + + dest->type = fitwindow; + dest->remote_page = 0; + dest->pgnum = 0; + dest->page = PDC_BAD_ID; + dest->left = -1; + dest->right = -1; + dest->bottom = -1; + dest->top = -1; + dest->zoom = -1; + dest->name = NULL; + dest->color[0] = 0.0; + dest->color[1] = 0.0; + dest->color[2] = 0.0; + dest->fontstyle = fnt_Normal; + dest->filename = NULL; + + return dest; +} + +void +pdf_cleanup_destination(PDF *p, pdf_dest *dest) +{ + if (dest) + { + if (dest->name) + { + pdc_free(p->pdc, dest->name); + dest->name = NULL; + } + if (dest->filename) + { + pdc_free(p->pdc, dest->filename); + dest->filename = NULL; + } + + pdc_free(p->pdc, dest); + } +} + +pdf_dest * +pdf_parse_destination_optlist( + PDF *p, + const char *optlist, + int page, + pdf_destuse destuse) +{ + int minpage; + pdc_resopt *resopts; + pdc_encoding hypertextencoding; + int hypertextcodepage; + const char *keyword; + const char *type_name; + char **strlist = NULL; + int inum; + pdc_bool boolval; + + /* Defaults */ + pdf_dest *dest = pdf_init_destination(p); + + /* parse option list */ + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_destination_options, + NULL, pdc_true); + + if (pdc_get_optvalues("fitbbox", resopts, &boolval, NULL) && + boolval == pdc_true) + dest->type = fitvisible; + + if (pdc_get_optvalues("fitheight", resopts, &boolval, NULL) && + boolval == pdc_true) + dest->type = fitheight; + + if (pdc_get_optvalues("fitpage", resopts, &boolval, NULL) && + boolval == pdc_true) + dest->type = fitwindow; + + if (pdc_get_optvalues("fitwidth", resopts, &boolval, NULL) && + boolval == pdc_true) + dest->type = fitwidth; + + if (pdc_get_optvalues("retain", resopts, &boolval, NULL) && + boolval == pdc_true) + dest->type = fixed; + + if (pdc_get_optvalues("type", resopts, &inum, NULL)) + dest->type = (pdf_desttype) inum; + type_name = pdc_get_keyword(dest->type, pdf_type_keylist); + + hypertextencoding = + pdf_get_hypertextencoding_opt(p, resopts, &hypertextcodepage, pdc_true); + + keyword = "name"; + if (pdf_get_opt_textlist(p, keyword, resopts, hypertextencoding, + hypertextcodepage, pdc_true, NULL, &dest->name, NULL)) + { + if (dest->type != nameddest) + { + dest->name = NULL; + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, + type_name, 0, 0); + } + else + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + keyword = "page"; + if (pdc_get_optvalues(keyword, resopts, &page, NULL) && + dest->type == filedest) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, type_name, + 0, 0); + + keyword = "group"; + if (pdc_get_optvalues(keyword, resopts, NULL, &strlist)) + { + page = pdf_xlat_pageno(p, page, strlist[0]); + } + + keyword = "zoom"; + if (pdc_get_optvalues(keyword, resopts, &dest->zoom, NULL) && + dest->type != fixed) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, type_name, + 0, 0); + + keyword = "left"; + if (pdc_get_optvalues(keyword, resopts, &dest->left, NULL) && + (dest->type == fitwindow || dest->type == fitwidth || + dest->type == fitvisible || dest->type == fitvisiblewidth || + dest->type == nameddest || dest->type == filedest)) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, type_name, + 0, 0); + + keyword = "right"; + if (pdc_get_optvalues(keyword, resopts, &dest->right, NULL) && + dest->type != fitrect) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, type_name, + 0, 0); + + keyword = "bottom"; + if (pdc_get_optvalues(keyword, resopts, &dest->bottom, NULL) && + dest->type != fitrect) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, type_name, + 0, 0); + + keyword = "top"; + if (pdc_get_optvalues(keyword, resopts, &dest->top, NULL) && + (dest->type == fitwindow || dest->type == fitheight || + dest->type == fitvisible || dest->type == fitvisibleheight || + dest->type == nameddest || dest->type == filedest)) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, type_name, + 0, 0); + + keyword = "color"; + if (pdc_get_optvalues(keyword, resopts, &dest->color, NULL) && + destuse != pdf_bookmark) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORELEM, keyword, 0, 0, 0); + + keyword = "fontstyle"; + if (pdc_get_optvalues(keyword, resopts, &inum, NULL)) + { + dest->fontstyle = (fnt_fontstyle) inum; + if (destuse != pdf_bookmark) + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORELEM, keyword, 0, 0, 0); + } + + keyword = "filename"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL)) + { + if (dest->type != filedest) + { + pdc_warning(p->pdc, PDF_E_HYP_OPTIGNORE_FORTYPE, keyword, + type_name, 0, 0); + } + else + dest->filename = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + pdc_cleanup_optionlist(p->pdc, resopts); + + switch (dest->type) + { + case fitwidth: + /* Trick: we don't know the height of a future page yet, + * so we use a "large" value for top which will do for + * most pages. If it doesn't work, not much harm is done. + */ + if (dest->top == -1) + dest->top = 10000; + break; + + case fitrect: + case fitheight: + case fitvisiblewidth: + case fitvisibleheight: + if (dest->left == -1) + dest->left = 0; + if (dest->bottom == -1) + dest->bottom = 0; + if (dest->right == -1) + dest->right = 1000; + if (dest->top == -1) + dest->top = 1000; + break; + + case nameddest: + if (destuse == pdf_nameddest) + { + pdf_cleanup_destination(p, dest); + pdc_error(p->pdc, PDC_E_OPT_ILLKEYWORD, "type", type_name, 0, 0); + } + if (dest->name == NULL) + { + pdf_cleanup_destination(p, dest); + pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, "name", 0, 0, 0); + } + break; + + case filedest: + if (destuse != pdf_bookmark) + { + pdf_cleanup_destination(p, dest); + pdc_error(p->pdc, PDC_E_OPT_ILLKEYWORD, "type", type_name, 0, 0); + } + if (dest->filename == NULL) + { + pdf_cleanup_destination(p, dest); + pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, "filename", 0, 0, 0); + } + break; + + default: + break; + } + + /* check for minpage */ + minpage = (destuse == pdf_bookmark) ? 0 : 1; + switch (destuse) + { + case pdf_nameddest: + case pdf_locallink: + if (page == 0) + { + page = pdf_current_page(p); + } + + case pdf_openaction: + case pdf_bookmark: + case pdf_remotelink: + if (page < minpage) + { + const char *stemp = pdc_errprintf(p->pdc, "%d", page); + pdf_cleanup_destination(p, dest); + pdc_error(p->pdc, PDC_E_ILLARG_HANDLE, "page", stemp, 0, 0); + } + break; + } + + dest->pgnum = page; + + if (destuse != pdf_remotelink && destuse != pdf_openaction && page != 0) + { + dest->page = pdf_get_page_id(p, page); + } + + /* remote page number */ + if (destuse == pdf_remotelink) + dest->remote_page = page; + + return dest; +} + +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma unmanaged +#endif +pdf_dest * +pdf_get_option_destname(PDF *p, pdc_resopt *resopts, + pdc_encoding hypertextencoding, + int hypertextcodepage) +{ + pdc_text_format hypertextformat = pdc_bytes; + pdf_dest *dest = NULL; + char **strlist; + int outlen; + + if (pdc_get_optvalues("destname", resopts, NULL, &strlist)) + { + dest = pdf_init_destination(p); + dest->type = nameddest; + + if (pdc_is_lastopt_utf8(resopts)) + hypertextformat = PDC_UTF8; + dest->name = pdf_convert_hypertext(p, strlist[0], 0, hypertextformat, + hypertextencoding, hypertextcodepage, + &outlen, PDC_UTF8_FLAG, pdc_true); + } + return dest; +} +#if defined(_MSC_VER) && defined(_MANAGED) +#pragma managed +#endif + + +void +pdf_write_destination(PDF *p, pdf_dest *dest) +{ + if (dest->type == nameddest) + { + pdf_put_hypertext(p, dest->name); + pdc_puts(p->out, "\n"); + return; + } + + pdc_begin_array(p->out); + + if (dest->remote_page) + { + pdc_printf(p->out, "%d", dest->remote_page - 1); /* zero-based */ + } + else + { + if (dest->page == PDC_BAD_ID) + dest->page = pdf_get_page_id(p, dest->pgnum); + + pdc_objref_c(p->out, dest->page); + } + + switch (dest->type) { + + case fixed: + pdc_puts(p->out, "/XYZ "); + + if (dest->left != -1) + pdc_printf(p->out, "%f ", dest->left); + else + pdc_puts(p->out, "null "); + + if (dest->top != -1) + pdc_printf(p->out, "%f ", dest->top); + else + pdc_puts(p->out, "null "); + + if (dest->zoom != -1) + pdc_printf(p->out, "%f", dest->zoom); + else + pdc_puts(p->out, "null"); + + break; + + case fitwindow: + pdc_puts(p->out, "/Fit"); + break; + + case fitwidth: + pdc_printf(p->out, "/FitH %f", dest->top); + break; + + case fitheight: + pdc_printf(p->out, "/FitV %f", dest->left); + break; + + case fitrect: + pdc_printf(p->out, "/FitR %f %f %f %f", + dest->left, dest->bottom, dest->right, dest->top); + break; + + case fitvisible: + pdc_puts(p->out, "/FitB"); + break; + + case fitvisiblewidth: + pdc_printf(p->out, "/FitBH %f", dest->top); + break; + + case fitvisibleheight: + pdc_printf(p->out, "/FitBV %f", dest->left); + break; + + default: + break; + } + + pdc_end_array(p->out); +} + +void +pdf__add_nameddest( + PDF *p, + const char *name, + int len, + const char *optlist) +{ + pdc_resopt *resopts = NULL; + pdc_text_format hypertextformat = p->hypertextformat; + pdc_encoding hypertextencoding; + int hypertextcodepage; + pdc_id obj_id = PDC_BAD_ID; + char *name2 = NULL; + pdf_dest *dest; + int inum; + + if (!name) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "name", 0, 0, 0); + + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_destination_options, NULL, pdc_true); + + hypertextencoding = + pdf_get_hypertextencoding_opt(p, resopts, &hypertextcodepage, pdc_true); + + if (pdc_get_optvalues("hypertextformat", resopts, &inum, NULL)) + { + hypertextformat = (pdc_text_format) inum; + pdf_check_hypertextformat(p, hypertextformat); + } + + pdc_cleanup_optionlist(p->pdc, resopts); + + /* create hypertext string */ + name2 = pdf_convert_hypertext(p, name, len, hypertextformat, + hypertextencoding, hypertextcodepage, &len, + pdc_true, pdc_true); + if (name2 == NULL || len == 0) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "name", 0, 0, 0); + + /* parsing option list */ + dest = pdf_parse_destination_optlist(p, optlist, 0, pdf_nameddest); + + /* interrupt the content stream if we are on a page */ + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_end_contents_section(p); + + obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Dest object */ + pdc_begin_dict(p->out); /* Destination dict */ + + pdc_puts(p->out, "/D"); + pdf_write_destination(p, dest); + + pdc_end_dict(p->out); /* Destination dict */ + pdc_end_obj(p->out); /* Dest object */ + + /* continue the contents stream */ + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_begin_contents_section(p); + + pdf_cleanup_destination(p, dest); + + /* insert name in tree */ + pdf_insert_name(p, name2, names_dests, obj_id); +} + + +/* -------------------------- bookmarks -------------------------- */ + +static const pdc_defopt pdf_create_bookmark_options[] = +{ + {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"hypertextformat", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_textformat_keylist}, + + {"textcolor", pdc_stringlist, PDC_OPT_NONE, 2, 5, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"fontstyle", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, pdf_fontstyle_pdfkeylist}, + + {"parent", pdc_bookmarkhandle, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"index", pdc_integerlist, PDC_OPT_NONE, 1, 1, + -1, PDC_INT_MAX, NULL}, + + {"open", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"destination", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"destname", pdc_stringlist, PDC_OPT_IGNOREIF1, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"action", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + PDC_OPT_TERMINATE +}; + +struct pdf_outline_s { + pdc_id obj_id; /* id of this outline object */ + char *text; /* bookmark text */ + int count; /* number of open sub-entries */ + pdc_bool open; /* whether or not to display children */ + pdc_scalar textcolor[3]; /* rgb color of bookmark text */ + fnt_fontstyle fontstyle; /* font style of bookmark text */ + char *action; /* action optlist */ + pdf_dest *dest; /* outline destination */ + + /* these members control automatic ordering of bookmarks. + */ + pdc_bool in_order; /* this book mark is "in order" */ + pdc_id page_id; /* id of page where this bookmark */ + /* was defined */ + + /* the members below are indices into the p->outlines[] array. + */ + int prev; /* previous entry at this level */ + int next; /* next entry at this level */ + int parent; /* ancestor's index */ + int first; /* first sub-entry */ + int last; /* last sub-entry */ +}; + +static void +pdf_init_outline(PDF *p, pdf_outline *outline) +{ + (void) p; + + outline->obj_id = PDC_BAD_ID; + outline->text = NULL; + outline->count = 0; + outline->open = pdc_false; + outline->textcolor[0] = 0.0; + outline->textcolor[1] = 0.0; + outline->textcolor[2] = 0.0; + outline->fontstyle = fnt_Normal; + outline->action = NULL; + outline->dest = NULL; + outline->in_order = pdc_false; + outline->page_id = PDC_BAD_ID; + outline->prev = 0; + outline->next = 0; + outline->parent = 0; + outline->first = 0; + outline->last = 0; +} + +/* We can't work with pointers in the outline objects because + * the complete outline block may be reallocated. Therefore we use + * this simple mechanism for achieving indirection. + */ +#define COUNT(jndex) (p->outlines[jndex].count) +#define OPEN(jndex) (p->outlines[jndex].open) +#define IN_ORDER(jndex) (p->outlines[jndex].in_order) +#define PAGE_ID(jndex) (p->outlines[jndex].page_id) +#define LAST(jndex) (p->outlines[jndex].last) +#define PARENT(jndex) (p->outlines[jndex].parent) +#define FIRST(jndex) (p->outlines[jndex].first) +#define OBJ_ID(jndex) (p->outlines[jndex].obj_id) +#define PREV(jndex) (p->outlines[jndex].prev) +#define NEXT(jndex) (p->outlines[jndex].next) + +static int +search_forward(PDF *p, int start_page, int start_index) +{ + int idx; + + for (idx = start_index; idx != 0; idx = NEXT(idx)) + { + if (IN_ORDER(idx)) + return pdf_search_page_fwd(p, start_page, PAGE_ID(idx)); + } + + return PDC_INT_MAX; +} + +static int +search_backward(PDF *p, int start_page, int start_index) +{ + int idx; + + for (idx = start_index; idx != 0; idx = PREV(idx)) + { + if (IN_ORDER(idx)) + { + int pg = pdf_search_page_bwd(p, start_page, PAGE_ID(idx)); + + return (pg == -1) ? PDC_INT_MAX : pg; + } + } + + return -1; +} + +static int +pdf_insert_bookmark( + PDF *p, + const char *hypertext, + pdf_outline *outline, + int jndex) +{ + static const char fn[] = "pdf_insert_bookmark"; + pdf_outline *root, *self; + int parent; + int self_idx; + int pageno = pdf_current_page(p); + + /* allocation */ + if (p->outline_count == 0) + { + p->outline_capacity = OUTLINE_CHUNKSIZE; + p->outlines = (pdf_outline *) pdc_calloc(p->pdc, + sizeof(pdf_outline) * p->outline_capacity, fn); + + /* populate the root outline object */ + root = &p->outlines[0]; + pdf_init_outline(p, root); + root->obj_id = pdc_alloc_id(p->out); + root->open = pdc_true; + + /* set the open mode show bookmarks if we have at least one, + * and the client didn't already set his own open mode. + */ + pdf_fix_openmode(p); + } + else if (p->outline_count + 1 >= p->outline_capacity) + { + p->outline_capacity *= 2; + p->outlines = (pdf_outline *) pdc_realloc(p->pdc, p->outlines, + sizeof(pdf_outline) * p->outline_capacity, fn); + } + + /* copy */ + self_idx = ++p->outline_count; + self = &p->outlines[self_idx]; + memcpy(self, outline, sizeof(pdf_outline)); + + self->obj_id = pdc_alloc_id(p->out); + self->text = (char *) hypertext; + self->page_id = pdf_get_page_id(p, 0); + parent = self->parent; + + /* default destination */ + if (self->action == NULL && self->dest == NULL) + self->dest = pdf_init_destination(p); + + /* no destination */ + if (self->dest != NULL && + self->dest->name != NULL && !strlen(self->dest->name)) + { + pdf_cleanup_destination(p, self->dest); + self->dest = NULL; + } + + /* current page */ + if (self->dest) + { + /* this ugly code is for compatibility with the + ** obsolete "bookmarkdest" parameter. + */ + if (self->dest->pgnum == 0) + self->dest->pgnum = pdf_current_page(p); + + if (self->dest->pgnum == 0) + { + self->dest->pgnum = 1; + } + else if (self->dest->page == PDC_BAD_ID) + { + self->dest->page = pdf_get_page_id(p, self->dest->pgnum); + } + } + + /* special case: empty list. + */ + if (FIRST(parent) == 0) + { + if (jndex > 0) + pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index", + pdc_errprintf(p->pdc, "%d", jndex), 0, 0); + + FIRST(parent) = LAST(parent) = self_idx; + self->in_order = pdc_true; + } + else switch (jndex) + { + case -2: /* insert "in order" */ + { + /* the "natural" case: append to the end if appropriate. + */ + if (pageno >= search_backward(p, -1, LAST(parent))) + { + self->prev = LAST(parent); + NEXT(LAST(parent)) = self_idx; + LAST(parent) = self_idx; + } + else + { + int idx; + int curr_pg = 1; + int next_pg; + + for (idx = FIRST(parent); idx != 0; idx = NEXT(idx)) + { + if (!IN_ORDER(idx)) + continue; + + next_pg = pdf_search_page_fwd(p, curr_pg, PAGE_ID(idx)); + + /* TODO: understand why this can happen. + */ + if (next_pg < 1) + { + idx = 0; + break; + } + + if (next_pg > pageno) + { + self->next = idx; + self->prev = PREV(idx); + PREV(idx) = self_idx; + + if (self->prev == 0) + FIRST(parent) = self_idx; + else + NEXT(self->prev) = self_idx; + + break; + } + + curr_pg = next_pg; + } + + /* if there are no "in order" bookmarks yet, + ** we simply append this one to the end. + */ + if (idx == 0) + { + self->prev = LAST(parent); + NEXT(LAST(parent)) = self_idx; + LAST(parent) = self_idx; + } + } + + self->in_order = pdc_true; + break; + } + + case -1: /* append to the end */ + { + self->prev = LAST(parent); + NEXT(LAST(parent)) = self_idx; + LAST(parent) = self_idx; + + self->in_order = + (pageno >= search_backward(p, pageno, self->prev)); + break; + } + + case 0: /* insert at the beginning */ + { + self->next = FIRST(parent); + PREV(FIRST(parent)) = self_idx; + FIRST(parent) = self_idx; + + self->in_order = + (pageno <= search_forward(p, pageno, self->next)); + break; + } + + default: /* insert before [1..LAST] */ + { + int i; + int target = FIRST(parent); + + for (i = 0; i < jndex; ++i) + { + if (target == LAST(parent)) + pdc_error(p->pdc, PDC_E_OPT_ILLINTEGER, "index", + pdc_errprintf(p->pdc, "%d", jndex), 0, 0); + + target = NEXT(target); + } + + self->next = target; + self->prev = PREV(target); + NEXT(self->prev) = PREV(self->next) = self_idx; + + self->in_order = + ((pageno >= search_backward(p, pageno, self->prev)) && + (pageno <= search_forward(p, pageno, self->next))); + break; + } + } /* else switch */ + + /* increase the number of open sub-entries for all relevant ancestors */ + do { + COUNT(parent)++; + } while (OPEN(parent) && (parent = PARENT(parent)) != 0); + + return (self_idx); /* caller may use this as handle */ +} + +int +pdf__create_bookmark(PDF *p, const char *text, int len, const char *optlist) +{ + pdc_resopt *resopts = NULL; + pdc_clientdata data; + pdf_outline self; + pdf_dest *dest = NULL; + pdc_text_format hypertextformat; + pdc_encoding hypertextencoding; + pdf_coloropt textcolor; + char *hypertext = NULL; + const char *keyword = NULL; + char **strlist = NULL; + int hypertextcodepage; + int ns, inum, outlen, retval = 0; + int jndex = -2; + + /* Initialize */ + pdf_init_outline(p, &self); + hypertextformat = p->hypertextformat; + hypertextencoding = p->hypertextencoding; + hypertextcodepage = p->hypertextcodepage; + + /* Parsing option list */ + if (optlist && strlen(optlist)) + { + pdf_set_clientdata(p, &data); + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_create_bookmark_options, &data, pdc_true); + + hypertextencoding = + pdf_get_hypertextencoding_opt(p, resopts, &hypertextcodepage, + pdc_true); + + if (pdc_get_optvalues("hypertextformat", resopts, &inum, NULL)) + { + hypertextformat = (pdc_text_format) inum; + pdf_check_hypertextformat(p, hypertextformat); + } + + ns = pdc_get_optvalues("textcolor", resopts, NULL, &strlist); + if (ns) + { + pdf_parse_coloropt(p, "textcolor", strlist, ns, (int) color_rgb, + &textcolor); + self.textcolor[0] = textcolor.value[0]; + self.textcolor[1] = textcolor.value[1]; + self.textcolor[2] = textcolor.value[2]; + } + + if (pdc_get_optvalues("fontstyle", resopts, &inum, NULL)) + self.fontstyle = (fnt_fontstyle) inum; + + pdc_get_optvalues("parent", resopts, &self.parent, NULL); + + pdc_get_optvalues("index", resopts, &jndex, NULL); + + pdc_get_optvalues("open", resopts, &self.open, NULL); + + if (pdc_get_optvalues("destination", resopts, NULL, &strlist)) + { + self.dest = pdf_parse_destination_optlist(p, strlist[0], 0, + pdf_bookmark); + keyword = "destination"; + } + else + { + dest = pdf_get_option_destname(p, resopts, hypertextencoding, + hypertextcodepage); + if (dest) + { + self.dest = dest; + keyword = "destname"; + } + } + + if (pdc_get_optvalues("action", resopts, NULL, &strlist)) + { + if (self.dest) + { + pdf_cleanup_destination(p, self.dest); + self.dest = NULL; + pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword, "action", 0, 0); + } + + /* parsing of action list */ + pdf_parse_and_write_actionlist(p, event_bookmark, NULL, + (const char *) strlist[0]); + self.action = + (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + } + + pdc_cleanup_optionlist(p->pdc, resopts); + } + + /* create hypertext string */ + hypertext = pdf_convert_hypertext(p, text, len, hypertextformat, + hypertextencoding, hypertextcodepage, + &outlen, PDC_UTF8_FLAG, pdc_true); + if (hypertext) + retval = pdf_insert_bookmark(p, hypertext, &self, jndex); + + return retval; +} + +static void +pdf_write_outline_dict(PDF *p, int entry) +{ + pdf_outline *outline = &p->outlines[entry]; + pdc_id act_idlist[PDF_MAX_EVENTS]; + + /* write action objects */ + if (outline->action) + pdf_parse_and_write_actionlist(p, event_bookmark, act_idlist, + (const char *) outline->action); + + pdc_begin_obj(p->out, OBJ_ID(entry)); /* outline object */ + pdc_begin_dict(p->out); + + pdc_objref(p->out, "/Parent", OBJ_ID(PARENT(entry))); + + /* outline destination */ + if (outline->dest) + { + pdc_puts(p->out, "/Dest"); + pdf_write_destination(p, outline->dest); + } + + /* write Action entries */ + else if (outline->action) + pdf_write_action_entries(p, event_bookmark, act_idlist); + + pdc_puts(p->out, "/Title"); /* outline text */ + pdf_put_hypertext(p, outline->text); + pdc_puts(p->out, "\n"); + + if (PREV(entry)) + pdc_objref(p->out, "/Prev", OBJ_ID(PREV(entry))); + if (NEXT(entry)) + pdc_objref(p->out, "/Next", OBJ_ID(NEXT(entry))); + + if (FIRST(entry)) { + pdc_objref(p->out, "/First", OBJ_ID(FIRST(entry))); + pdc_objref(p->out, "/Last", OBJ_ID(LAST(entry))); + } + if (COUNT(entry)) { + if (OPEN(entry)) + pdc_printf(p->out, "/Count %d\n", COUNT(entry)); /* open */ + else + pdc_printf(p->out, "/Count %d\n", -COUNT(entry));/* closed */ + } + + /* Color */ + if (outline->textcolor[0] != 0.0 || + outline->textcolor[1] != 0.0 || + outline->textcolor[2] != 0.0) + pdc_printf(p->out, "/C[%f %f %f]\n", outline->textcolor[0], + outline->textcolor[1], + outline->textcolor[2]); + + /* FontStyle */ + if (outline->fontstyle != fnt_Normal) + { + int fontstyle = 0; + if (outline->fontstyle == fnt_Bold) + fontstyle = 2; + if (outline->fontstyle == fnt_Italic) + fontstyle = 1; + if (outline->fontstyle == fnt_BoldItalic) + fontstyle = 3; + pdc_printf(p->out, "/F %d\n", fontstyle); + } + + pdc_end_dict(p->out); + pdc_end_obj(p->out); /* outline object */ +} + +void +pdf_write_outlines(PDF *p) +{ + int i; + + if (p->outline_count == 0) /* no outlines: return */ + return; + + pdc_begin_obj(p->out, p->outlines[0].obj_id); /* root outline object */ + pdc_begin_dict(p->out); + + if (p->outlines[0].count != 0) + pdc_printf(p->out, "/Count %d\n", COUNT(0)); + pdc_objref(p->out, "/First", OBJ_ID(FIRST(0))); + pdc_objref(p->out, "/Last", OBJ_ID(LAST(0))); + + pdc_end_dict(p->out); + pdc_end_obj(p->out); /* root outline object */ + +#define PDF_FLUSH_AFTER_MANY_OUTLINES 1000 /* ca. 50-100 KB */ + for (i = 1; i <= p->outline_count; i++) { + /* reduce memory usage for many outline entries */ + if (i % PDF_FLUSH_AFTER_MANY_OUTLINES == 0) + pdc_flush_stream(p->out); + + pdf_write_outline_dict(p, i); + } +} + +void +pdf_write_outline_root(PDF *p) +{ + if (p->outline_count != 0) + pdc_objref(p->out, "/Outlines", p->outlines[0].obj_id); +} + +void +pdf_init_outlines(PDF *p) +{ + p->outline_count = 0; +} + +/* Free outline entries */ +void +pdf_cleanup_outlines(PDF *p) +{ + int i; + + if (!p->outlines || p->outline_count == 0) + return; + + /* outlines[0] is the outline root object */ + for (i = 0; i <= p->outline_count; i++) + { + if (p->outlines[i].text) + { + pdc_free(p->pdc, p->outlines[i].text); + p->outlines[i].text = NULL; + } + if (p->outlines[i].action) + { + pdc_free(p->pdc, p->outlines[i].action); + p->outlines[i].action = NULL; + } + pdf_cleanup_destination(p, p->outlines[i].dest); + p->outlines[i].dest = NULL; + } + + pdc_free(p->pdc, (void*) p->outlines); + + p->outlines = NULL; +} + + +/*****************************************************************************/ +/** deprecated historical bookmark function **/ +/*****************************************************************************/ + +int +pdf__add_bookmark(PDF *p, const char *text, int len, int parent, int open) +{ + pdf_outline self; + pdf_dest *dest = (pdf_dest *) p->bookmark_dest; + char *hypertext = NULL; + int acthdl; + int retval = 0; + + pdf_init_outline(p, &self); + + if (parent != 0) + pdf_check_handle(p, parent, pdc_bookmarkhandle); + self.parent = parent; + self.open = open; + + /* creating a Launch action - defined via bookmarkdest */ + if (dest->filename) + { + char actoptlist[2048]; + + sprintf(actoptlist, "filename {%s} ", dest->filename); + acthdl = pdf__create_action(p, "Launch", actoptlist); + if (acthdl != -1) + { + if (p->pdc->hastobepos) acthdl++; + sprintf(actoptlist, "activate %d", acthdl); + self.action = pdc_strdup(p->pdc, actoptlist); + } + } + else + { + self.dest = pdf_init_destination(p); + *self.dest = *dest; + if (dest->name) + self.dest->name = pdc_strdup(p->pdc, dest->name); + } + + memcpy(self.textcolor, dest->color, 3 * sizeof(pdc_scalar)); + self.fontstyle = dest->fontstyle; + + hypertext = pdf_convert_hypertext_depr(p, text, len); + if (hypertext) + retval = pdf_insert_bookmark(p, hypertext, &self, -1); + + return retval; +} + +/* -------------------------- document info ------------------------------- */ + +struct pdf_info_s +{ + char *key; /* ASCII string */ + char *value; /* Unicode string */ + pdf_info *next; /* next info entry */ +}; + +void +pdf_cleanup_info(PDF *p) +{ + pdf_info *info, *last; + + if (p->userinfo) + { + for (info = p->userinfo; info != NULL; /* */) + { + last = info; + info = info->next; + + pdc_free(p->pdc, last->key); + pdc_free(p->pdc, last->value); + pdc_free(p->pdc, last); + } + + p->userinfo = NULL; + } +} + +static pdf_info * +pdf_have_infokey(PDF *p, const char *key) +{ + pdf_info *info; + + for (info = p->userinfo; info != NULL; info = info->next) + { + if (strlen(info->key) == strlen(key) && !strcmp(info->key, key)) + return info; + } + + return NULL; +} + +void +pdf_feed_digest_info(PDF *p) +{ + pdf_info *info; + + if (p->userinfo) + { + for (info = p->userinfo; info != NULL; info = info->next) + { + pdc_update_digest(p->out, + (unsigned char *) info->key, strlen(info->key)); + } + } +} + +#define PDF_TRAPPED_TRUE "True" +#define PDF_TRAPPED_FALSE "False" +#define PDF_TRAPPED_UNKNOWN "Unknown" + +/* Set Info dictionary entries */ +void +pdf__set_info(PDF *p, const char *key, const char *value, int len) +{ + static const char fn[] = "pdf__set_info"; + char *key_buf, *val_buf; + pdf_info *oldentry, *newentry; + + if (key == NULL || !*key) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "key", 0, 0, 0); + + if (!strcmp(key, "Producer") || + !strcmp(key, "CreationDate") || + !strcmp(key, "ModDate")) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "key", key, 0, 0); + + /* converting key */ + key_buf = pdf_convert_name(p, key, 0, 0); + + /* convert text string */ + val_buf = pdf_convert_hypertext_depr(p, value, len); + if (!val_buf) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "value", 0, 0, 0); + + /* special handling required for "Trapped" */ + if (!strcmp(key_buf, "Trapped")) + { + if (strcmp(val_buf, PDF_TRAPPED_TRUE) && + strcmp(val_buf, PDF_TRAPPED_FALSE) && + strcmp(val_buf, PDF_TRAPPED_UNKNOWN)) + { + pdc_free(p->pdc, val_buf); + pdc_free(p->pdc, key_buf); + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + } + } + + oldentry = pdf_have_infokey(p, key_buf); + if (oldentry != NULL) + { + pdc_free(p->pdc, key_buf); + pdc_free(p->pdc, oldentry->value); + oldentry->value = val_buf; + } + else + { + newentry = (pdf_info *) + pdc_malloc(p->pdc, sizeof(pdf_info), fn); + newentry->key = key_buf; + newentry->value = val_buf; + newentry->next = p->userinfo; + + /* ordering doesn't matter so we insert at the beginning */ + p->userinfo = newentry; + } +} + + +pdc_id +pdf_write_info(PDF *p, pdc_bool moddate) +{ + char time_str[PDC_TIME_SBUF_SIZE]; + char producer[PDF_MAX_PARAMSTRING]; + pdf_info *info; + pdc_id info_id; + + + + const char *product = "PDFlib Lite"; + + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, + "[Full product name: \"%s\"]\n", product); + + info_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Info object */ + + pdc_begin_dict(p->out); + + /* + * Although it would be syntactically correct, we must not remove + * the space characters after the dictionary keys since this + * would break the PDF properties feature in Windows Explorer. + */ + + if (p->userinfo) + { + for (info = p->userinfo; info != NULL; info = info->next) + { + pdf_put_pdfname(p, info->key); + pdc_puts(p->out, " "); + + if (strcmp(info->key, "Trapped")) + pdf_put_hypertext(p, info->value); + else + pdf_put_pdfname(p, info->value); + + pdc_puts(p->out, "\n"); + } + } + + + pdc_get_timestr(time_str, pdc_false); + + /* creation date and time */ + pdc_puts(p->out, "/CreationDate "); + pdf_put_hypertext(p, time_str); + pdc_puts(p->out, "\n"); + + /* modification date and time */ + if (moddate) + { + pdc_puts(p->out, "/ModDate "); + pdf_put_hypertext(p, time_str); + pdc_puts(p->out, "\n"); + } + + /* + * If you change the /Producer entry your license to use + * PDFlib will be void! + */ + + if (p->pdc->binding) + sprintf(producer, "%s %s (%s/%s)", product, + PDFLIB_VERSIONSTRING, p->pdc->binding, PDF_PLATFORM); + else + sprintf(producer, "%s %s (%s)", product, + PDFLIB_VERSIONSTRING, PDF_PLATFORM); + + pdc_puts(p->out, "/Producer "); + pdf_put_hypertext(p, producer); + pdc_puts(p->out, "\n"); + + pdc_end_dict(p->out); + pdc_end_obj(p->out); /* Info object */ + + + + + return info_id; +} + + diff --git a/src/pdflib/pdflib/p_icc.c b/src/pdflib/pdflib/p_icc.c new file mode 100644 index 0000000..072ea55 --- /dev/null +++ b/src/pdflib/pdflib/p_icc.c @@ -0,0 +1,32 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_icc.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib ICC handling routines + * + * This software is based in part on the work of Graeme W. Gill + * + */ + +#define P_ICC_C + +#include "p_intern.h" +#include "p_color.h" + +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#endif + + + diff --git a/src/pdflib/pdflib/p_icc.h b/src/pdflib/pdflib/p_icc.h new file mode 100644 index 0000000..73fedfa --- /dev/null +++ b/src/pdflib/pdflib/p_icc.h @@ -0,0 +1,24 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_icc.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib ICC typedefs, structures, and enums + * + */ + +#ifndef P_ICC_H +#define P_ICC_H + + +#endif /* P_ICC_H */ + diff --git a/src/pdflib/pdflib/p_icc9809.h b/src/pdflib/pdflib/p_icc9809.h new file mode 100644 index 0000000..3ceb0f7 --- /dev/null +++ b/src/pdflib/pdflib/p_icc9809.h @@ -0,0 +1,38 @@ +/* $Id: p_icc9809.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Header file of ICC (name see note above) for ICClib and PDFlib + * + */ + +/* + * Note: Modified for use by icclib V2.00: + * + * Changed guard bands from ICC_H to ICC9809_H + * + * Replace tag last values 0xFFFFFFFFL with define icMaxTagVal, + * and define this to be -1, for better compiler compatibility. + * + * Add section to use machine specific INR & ORD to define + * the sizes of ic Numbers, if ORD is defined. + * + * Adding colorspaces 'MCH5-8' for Hexachrome and others. (Colorsync ?) + * Added the Positive/Negative and Color/BlackAndWhite Attribute bits + * + * I believe icMeasurementFlare as an enumeration is bogus in + * this file. It is meant to be a u16.16 number. + * + * Add Chromaticity Tag and Type from ICC.1A:1999-04, + * but there is no formal "icc.h" from the ICC that indicates + * what the names should be. + * + * Added Colorsync 2.5 specific VideoCardGamma defines. + * + * Graeme Gill. + */ + +/* Header file guard bands */ +#ifndef P_ICC9809_H +#define P_ICC9809_H + + +#endif /* P_ICC9809_H */ diff --git a/src/pdflib/pdflib/p_icclib.c b/src/pdflib/pdflib/p_icclib.c new file mode 100644 index 0000000..02275da --- /dev/null +++ b/src/pdflib/pdflib/p_icclib.c @@ -0,0 +1,62 @@ +/* $Id: p_icclib.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * ICClib routines for PDFlib, slightly modified from the original ICClib. + * (see below). + * + * $Log: p_icclib.c,v $ + * Revision 1.1 2008/10/17 06:11:49 scuri + * First commit - moving from LuaForge to SourceForge + * + * Revision 1.3 2007/11/06 15:48:55 scuri + * PDF Lite library updated to version "7.0.2". + * + * Revision 1.18.8.3 2007/05/23 21:15:00 york + * fixed #1230: "Performance problems in mulithreaded env with tolower/toupper". + * + * Revision 1.18.8.2 2007/05/23 19:37:21 york + * implemented pdc_isXXX() character classification macros. + * started to replace isXXX() with pdc_isXXX() in all modules. + * + * Revision 1.18.8.1 2007/03/28 12:47:10 kurt + * bug #1180 (Function prefixes missing for zlib assembler and ICC code) fixed + * names of all external functions of ICClib have the prefix "pdf_" now + * + * Revision 1.18 2004/08/05 09:11:27 rjs + * merged 6.0.x to pdflib-x + * + * Revision 1.17.2.1 2004/07/30 16:14:30 kurt + * icc_read: all free statements in the error case removed + * (because of program crash in icc_delete) + * icc_delete: more security checks + * new public function: icc_get_errmsg + * + */ + +/* + * International Color Consortium Format Library (icclib) + * For ICC profile version 3.4 + * + * Author: Graeme W. Gill + * Date: 2002/04/22 + * Version: 2.02 + * + * Copyright 1997 - 2002 Graeme W. Gill + * See Licence.txt file for conditions of use. + */ + +#include +#include +#include +#include +#include +#ifdef __sun +#include +#endif +#if defined(__IBMC__) && defined(_M_IX86) +#include +#endif + +/* PDFlib */ +#include "pc_util.h" +#include "pc_core.h" +#include "pc_ctype.h" diff --git a/src/pdflib/pdflib/p_icclib.h b/src/pdflib/pdflib/p_icclib.h new file mode 100644 index 0000000..b300419 --- /dev/null +++ b/src/pdflib/pdflib/p_icclib.h @@ -0,0 +1,38 @@ +/* $Id: p_icclib.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * ICClib Header file icc.h for PDFlib + * + * $Log: p_icclib.h,v $ + * Revision 1.1 2008/10/17 06:11:49 scuri + * First commit - moving from LuaForge to SourceForge + * + * Revision 1.3 2007/11/06 15:48:55 scuri + * PDF Lite library updated to version "7.0.2". + * + * Revision 1.12.8.1 2007/03/28 12:47:10 kurt + * bug #1180 (Function prefixes missing for zlib assembler and ICC code) fixed + * names of all external functions of ICClib have the prefix "pdf_" now + * + * Revision 1.12 2004/08/05 09:11:27 rjs + * merged 6.0.x to pdflib-x + * + * Revision 1.11.2.1 2004/07/30 16:14:31 kurt + * icc_read: all free statements in the error case removed + * (because of program crash in icc_delete) + * icc_delete: more security checks + * new public function: icc_get_errmsg + * + * Revision 1.11 2004/06/14 10:53:19 kurt + * FEATURE defines reduced and renamed + * + * Revision 1.10 2003/03/03 12:46:43 tm + * Changed the licensing comment. + * + */ + +#ifndef P_ICCLIB_H +#define P_ICCLIB_H + + +#endif /* P_ICCLIB_H */ + diff --git a/src/pdflib/pdflib/p_image.c b/src/pdflib/pdflib/p_image.c new file mode 100644 index 0000000..fe95b1c --- /dev/null +++ b/src/pdflib/pdflib/p_image.c @@ -0,0 +1,2253 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2007 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_image.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib image routines + * + */ + +#define P_IMAGE_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_defopt.h" +#include "p_font.h" +#include "p_image.h" +#include "p_layer.h" +#include "p_tagged.h" + +static void +pdf_init_image_struct(PDF *p, pdf_image *image) +{ + (void) p; + + /********** option variables *************/ + image->verbose = p->debug[(int) 'i']; + image->verbose = pdf_get_errorpolicy(p, NULL, image->verbose); + image->bitreverse = pdc_false; + image->bpc = pdc_undef; + image->components = pdc_undef; + image->height_pixel = pdc_undef; + image->ignoremask = pdc_false; + image->ignoreorient = pdc_false; + image->doinline = pdc_false; + image->interpolate = pdc_false; + image->invert = pdc_false; + image->jpegoptimize = pdc_true; + image->passthrough = pdc_undef; + image->K = 0; + image->imagemask = pdc_false; + image->mask = pdc_undef; + image->ri = AutoIntent; + image->page = 1; + image->reference = pdf_ref_direct; + image->width_pixel = pdc_undef; + image->topdown_save = pdc_false; + image->iconname = (char *) NULL; + /*****************************************/ + + image->orientation = 1; + image->transparent = pdc_false; + image->compression = pdf_comp_none; + image->predictor = pred_default; + image->in_use = pdc_false; + image->corrupt = pdc_false; + image->fp = (pdc_file *) NULL; + image->filename = (char *) NULL; + image->params = (char *) NULL; + image->dpi_x = 0; + image->dpi_y = 0; + image->strips = 1; + image->rowsperstrip = 1; + image->colorspace = pdc_undef; + image->dochandle = pdc_undef; /* this means "not a PDI page" */ + image->use_raw = pdc_false; + image->pixelmode = pdc_undef; + image->type = pdf_img_auto; + image->transval[0] = 0; + image->transval[1] = 0; + image->transval[2] = 0; + image->transval[3] = 0; + + + /********* image-type specific stuff *****/ + /* This is ugly, but we must do it here since both the TIFF and JPEG + * modules are affected. + */ + image->info.jpeg.jpegifoffset = 0L; +} + +void +pdf_init_images(PDF *p) +{ + int im; + + p->images_capacity = IMAGES_CHUNKSIZE; + + p->images = (pdf_image *) + pdc_malloc(p->pdc, + sizeof(pdf_image) * p->images_capacity, "pdf_init_images"); + + for (im = 0; im < p->images_capacity; im++) + pdf_init_image_struct(p, &(p->images[im])); +} + +void +pdf_grow_images(PDF *p) +{ + int im; + + p->images = (pdf_image *) pdc_realloc(p->pdc, p->images, + sizeof(pdf_image) * 2 * p->images_capacity, "pdf_grow_images"); + + for (im = p->images_capacity; im < 2 * p->images_capacity; im++) + pdf_init_image_struct(p, &(p->images[im])); + + p->images_capacity *= 2; +} + +void +pdf_cleanup_image(PDF *p, int im) +{ + pdf_image *image = &p->images[im]; + + /* clean up parameter string if necessary */ + if (image->params) + { + pdc_free(p->pdc, image->params); + image->params = NULL; + } + + if (image->filename) + { + pdc_free(p->pdc, image->filename); + image->filename = NULL; + } + + if (image->fp) + { + pdc_fclose(image->fp); + image->fp = NULL; + } + + if (image->iconname) + { + pdc_free(p->pdc, image->iconname); + image->iconname = NULL; + } + + + + /* type-specific cleanups */ + if (image->type == pdf_img_gif) + pdf_cleanup_gif(p, image); + + if (image->type == pdf_img_jpeg) + pdf_cleanup_jpeg(p, image); + + /* free the image slot and prepare for next use */ + pdf_init_image_struct(p, image); +} + +void +pdf_cleanup_images(PDF *p) +{ + int im; + + if (!p->images) + return; + + /* Free images which the caller left open */ + + /* When we think of inter-document survival of images, + ** we MUST NOT FORGET that the current TIFF algorithm + ** depends on contiguous image slots for the image strips! + */ + for (im = 0; im < p->images_capacity; im++) + { + if (p->images[im].in_use) /* found used slot */ + pdf_cleanup_image(p, im); /* free image descriptor */ + } + + pdc_free(p->pdc, p->images); + p->images = NULL; +} + +void +pdf_init_xobjects(PDF *p) +{ + int idx; + + p->xobjects_number = 0; + + if (p->xobjects == (pdf_xobject *) 0) + { + p->xobjects_capacity = XOBJECTS_CHUNKSIZE; + + p->xobjects = (pdf_xobject *) + pdc_malloc(p->pdc, sizeof(pdf_xobject) * p->xobjects_capacity, + "pdf_init_xobjects"); + } + + for (idx = 0; idx < p->xobjects_capacity; idx++) + p->xobjects[idx].flags = 0; +} + +int +pdf_new_xobject(PDF *p, pdf_xobj_type type, pdc_id obj_id) +{ + static const char fn[] = "pdf_new_xobject"; + int i, slot = p->xobjects_number++; + + if (slot == p->xobjects_capacity) + { + p->xobjects = (pdf_xobject *) pdc_realloc(p->pdc, p->xobjects, + sizeof(pdf_xobject) * 2 * p->xobjects_capacity, fn); + + for (i = p->xobjects_capacity; i < 2 * p->xobjects_capacity; i++) + p->xobjects[i].flags = 0; + + p->xobjects_capacity *= 2; + } + + if (obj_id == PDC_NEW_ID) + obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); + + p->xobjects[slot].obj_id = obj_id; + p->xobjects[slot].type = type; + p->xobjects[slot].flags = xobj_flag_used; + + return slot; +} + +pdc_id +pdf_get_xobject(PDF *p, int im) +{ + if (im >= 0 && im < p->images_capacity) + { + pdf_image *img = &p->images[im]; + + if (img->in_use) + return p->xobjects[img->no].obj_id; + } + return PDC_BAD_ID; +} + +void +pdf_write_xobjects(PDF *p) +{ + if (p->xobjects_number > 0) + { + pdc_bool hit = pdc_false; + int i; + + for (i = 0; i < p->xobjects_number; ++i) + { + if (p->xobjects[i].flags & xobj_flag_write) + { + if (!hit) + { + pdc_puts(p->out, "/XObject"); + pdc_begin_dict(p->out); + hit = pdc_true; + } + + pdc_printf(p->out, "/I%d", i); + pdc_objref(p->out, "", p->xobjects[i].obj_id); + p->xobjects[i].flags &= ~xobj_flag_write; + } + } + + if (hit) + pdc_end_dict(p->out); + } +} + +void +pdf_get_page_xobjects(PDF *p, pdf_reslist *rl) +{ + int i; + + for (i = 0; i < p->xobjects_number; i++) { + if (p->xobjects[i].flags & xobj_flag_write) { + p->xobjects[i].flags &= ~xobj_flag_write; + pdf_add_reslist(p, rl, i); + } + } +} + +void +pdf_mark_page_xobject(PDF *p, int n) +{ + p->xobjects[n].flags |= xobj_flag_write; +} + +void +pdf_cleanup_xobjects(PDF *p) +{ + if (p->xobjects) { + pdc_free(p->pdc, p->xobjects); + p->xobjects = NULL; + } +} + + +/* ---------------------------- put image ----------------------------------- */ + +void +pdf_put_inline_image(PDF *p, int im) +{ + static const char *fn = "pdf_put_inline_image"; + pdf_image *image; + pdc_matrix m; + PDF_data_source *src; + int i; + + image = &p->images[im]; + + /* Image object */ + + image->no = -1; + + pdf__save(p); + + pdc_scale_matrix(image->width, image->height, &m); + + pdf_concat_raw(p, &m); + + pdc_puts(p->out, "BI"); + + pdc_printf(p->out, "/W %d", (int) image->width); + pdc_printf(p->out, "/H %d", (int) image->height); + + /* Acrobat 7 and 8 require /BPC even for image masks */ + pdc_printf(p->out, "/BPC %d", image->bpc); + + if (image->imagemask == pdc_true) { + pdc_puts(p->out, "/IM true"); + + } else if (image->colorspace != pdc_undef) { + + switch (p->colorspaces[image->colorspace].type) { + case DeviceGray: + pdc_printf(p->out, "/CS/G"); + break; + + case DeviceRGB: + pdc_printf(p->out, "/CS/RGB"); + break; + + case DeviceCMYK: + pdc_printf(p->out, "/CS/CMYK"); + break; + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", image->colorspace), + pdc_errprintf(p->pdc, "%d", + (int) p->colorspaces[image->colorspace].type), + 0); + break; + } + } + + if (image->compression != pdf_comp_none) { + pdc_printf(p->out, "/F/%s", + pdc_get_keyword(image->compression, pdf_shortfilter_pdfkeylist)); + } + + /* prepare precompressed (raw) image data */ + if (image->use_raw && + (image->params || + image->predictor != pred_default || + image->compression == pdf_comp_ccitt)) { + + pdc_printf(p->out, "/DP[<<"); + + /* write EarlyChange */ + if (image->params) + pdc_puts(p->out, image->params); + + if (image->compression == pdf_comp_ccitt) { + if (image->K != 0) + pdc_printf(p->out, "/K %d", image->K); + } + + if (image->compression == pdf_comp_flate || + image->compression == pdf_comp_lzw) { + if (image->predictor != pred_default) { + pdc_printf(p->out, "/Predictor %d", (int) image->predictor); + pdc_printf(p->out, "/Columns %d", (int) image->width); + if (image->bpc != 8) + pdc_printf(p->out, "/BitsPerComponent %d", image->bpc); + + if (image->components != 1) /* 1 is default */ + pdc_printf(p->out, "/Colors %d", image->components); + } + } + + if (image->compression == pdf_comp_ccitt) { + if ((int) image->width != 1728) /* CCITT default width */ + pdc_printf(p->out, "/Columns %d", (int) image->width); + + /* /Rows is not required */ + } + pdc_puts(p->out, ">>]"); /* DecodeParms dict and array */ + } + + if (image->ri != AutoIntent) { + pdc_printf(p->out, "/Intent/%s", + pdc_get_keyword(image->ri, pdf_renderingintent_pdfkeylist)); + } + + if (image->interpolate) { + pdc_puts(p->out, "/I true"); + } + + if (image->invert) { + pdc_puts(p->out, "/D[1 0"); + for (i = 1; i < image->components; i++) + pdc_puts(p->out, " 1 0"); + pdc_puts(p->out, "]ID\n"); + + } else { + pdc_puts(p->out, " ID\n"); + } + + /* Write the actual image data to the content stream */ + + src = &image->src; + + /* We can't use pdf_copy_stream() here because it automatically + * generates a stream object, which is not correct for inline + * image data. + */ + if (src->init) + src->init(p, src); + + while (src->fill(p, src)) + pdc_write(p->out, src->next_byte, src->bytes_available); + + if (src->terminate) + src->terminate(p, src); + + /* Acrobat requires whitespace between image data and "EI" */ + pdc_puts(p->out, "\nEI\n"); + + pdf__restore(p); + + /* Do the equivalent of PDF_close_image() since the image handle + * cannot be re-used anyway. + */ + pdf_cleanup_image(p, im); +} + +void +pdf_put_image(PDF *p, int im, pdc_bool firststrip, pdc_bool checkcontentstream) +{ + static const char *fn = "pdf_put_image"; + pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_image); + pdc_id length_id; + pdf_image *image; + int i; + pdf_compression compression; + + image = &p->images[im]; + + if (logg3) + pdc_logg(p->pdc, "\t\t\tput image %d to PDF file ...\n", im); + + /* Images may also be written to the output before the first page */ + if (checkcontentstream && PDF_GET_STATE(p) == pdf_state_page) + pdf_end_contents_section(p); + + + + pdc_logg_cond(p->pdc, 2, trc_image, + "\tpdf_put_image:\n" + "\t\t\tim = %d\n" + "\t\t\timage->colorspace = %d\n", + im, + image->colorspace); + + if (image->colorspace != pdc_undef) + pdc_logg_cond(p->pdc, 2, trc_image, + "\t\t\tcolor space type = %d\n", + (int) p->colorspaces[image->colorspace].type); + + /* Image object */ + + image->no = pdf_new_xobject(p, image_xobject, PDC_NEW_ID); + + pdc_begin_dict(p->out); /* XObject */ + + pdc_puts(p->out, "/Subtype/Image\n"); + + pdc_printf(p->out, "/Width %d\n", (int) image->width); + pdc_printf(p->out, "/Height %d\n", (int) fabs(image->height)); + + /* + * Transparency handling + */ + + /* Masking by color: single transparent color value */ + if (image->transparent && image->colorspace != pdc_undef) { + pdf_colorspace *cs = &p->colorspaces[image->colorspace]; + + switch (cs->type) { + case Indexed: + case DeviceGray: + pdc_printf(p->out,"/Mask[%d %d]\n", + (int) image->transval[0], (int) image->transval[0]); + break; + + + case DeviceRGB: + pdc_printf(p->out,"/Mask[%d %d %d %d %d %d]\n", + (int) image->transval[0], (int) image->transval[0], + (int) image->transval[1], (int) image->transval[1], + (int) image->transval[2], (int) image->transval[2]); + break; + + case DeviceCMYK: + pdc_printf(p->out,"/Mask[%d %d %d %d %d %d %d %d]\n", + (int) image->transval[0], (int) image->transval[0], + (int) image->transval[1], (int) image->transval[1], + (int) image->transval[2], (int) image->transval[2], + (int) image->transval[3], (int) image->transval[3]); + break; + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", image->colorspace), + pdc_errprintf(p->pdc, "%d", + (int) p->colorspaces[image->colorspace].type), + 0); + } + + /* Masking by position: separate bitmap mask */ + } else if (image->mask != pdc_undef && p->images[image->mask].bpc > 1) { + pdc_objref(p->out, "/SMask", + p->xobjects[p->images[image->mask].no].obj_id); + + } else if (image->mask != pdc_undef) { + pdc_objref(p->out, "/Mask", + p->xobjects[p->images[image->mask].no].obj_id); + } + + /* + * /BitsPerComponent is optional for image masks according to the + * PDF reference, but some viewers require it nevertheless. + * We must therefore always write it. + */ + if (image->type != pdf_img_jpeg2000) + pdc_printf(p->out, "/BitsPerComponent %d\n", image->bpc); + + if (image->imagemask) { + pdc_puts(p->out, "/ImageMask true\n"); + if (image->type == pdf_img_jpeg2000) + pdc_puts(p->out, "/SMaskInData 1\n"); + + } else if (image->colorspace != pdc_undef) { + + switch (p->colorspaces[image->colorspace].type) { + case DeviceGray: + break; + + case DeviceRGB: + break; + + case DeviceCMYK: + break; + + case Indexed: + break; + + + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, fn, + pdc_errprintf(p->pdc, "%d", image->colorspace), + pdc_errprintf(p->pdc, "%d", + (int) p->colorspaces[image->colorspace].type), + 0); + } + + pdc_puts(p->out, "/ColorSpace"); + pdf_write_colorspace(p, image->colorspace, pdc_false); + pdc_puts(p->out, "\n"); + } + + if (image->invert) { + pdc_puts(p->out, "/Decode[1 0"); + for (i = 1; i < image->components; i++) + pdc_puts(p->out, " 1 0"); + pdc_end_array(p->out); + } + + if (image->ri != AutoIntent) { + pdc_printf(p->out, "/Intent/%s\n", + pdc_get_keyword(image->ri, pdf_renderingintent_pdfkeylist)); + } + + if (image->interpolate) { + pdc_puts(p->out, "/Interpolate true\n"); + } + + /* special case: referenced image data instead of direct data */ + if (image->reference != pdf_ref_direct) { + + if (image->compression != pdf_comp_none) { + pdc_printf(p->out, "/FFilter[/%s]\n", + pdc_get_keyword(image->compression, pdf_filter_pdfkeylist)); + } + + if (image->compression == pdf_comp_ccitt) { + pdc_puts(p->out, "/FDecodeParms[<<"); + + if ((int) image->width != 1728) /* CCITT default width */ + pdc_printf(p->out, "/Columns %d", (int) image->width); + + /* + pdc_printf(p->out, "/Rows %d", (int) fabs(image->height)); + */ + + if (image->K != 0) + pdc_printf(p->out, "/K %d", image->K); + + pdc_puts(p->out, ">>]\n"); + + } + + if (image->reference == pdf_ref_file) { + + /* LATER: make image file name platform-neutral: + * Change : to / on the Mac + * Change \ to / on Windows + */ + pdc_puts(p->out, "/F"); + pdc_put_pdfstring(p->out, image->filename, 0); + pdc_puts(p->out, "/Length 0"); + + } else if (image->reference == pdf_ref_url) { + + pdc_puts(p->out, "/F<out, image->filename, 0); + pdc_puts(p->out, ">>/Length 0"); + } + + pdc_end_dict(p->out); /* XObject */ + + /* We must avoid pdc_begin/end_pdfstream() here in order to + * generate a really empty stream. + */ + pdc_puts(p->out, "stream\n"); /* dummy image stream */ + pdc_puts(p->out, "endstream\n"); + + pdc_end_obj(p->out); /* XObject */ + + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_begin_contents_section(p); + + return; + } + + compression = image->compression; + + /* + * Now the (more common) handling of actual image + * data to be included in the PDF output. + */ + + /* force compression if not a recognized precompressed image format */ + if ((!image->use_raw || compression == pdf_comp_none) && + pdc_get_compresslevel(p->out)) + compression = pdf_comp_flate; + + if (compression != pdf_comp_none) + pdc_printf(p->out, "/Filter/%s\n", + pdc_get_keyword(compression, pdf_filter_pdfkeylist)); + + /* prepare precompressed (raw) image data; avoid empty DecodeParms */ + if (image->use_raw && + (image->params || + image->predictor != pred_default || + compression == pdf_comp_ccitt)) { + + pdc_printf(p->out, "/DecodeParms<<"); + + /* write EarlyChange */ + if (image->params) + pdc_puts(p->out, image->params); + + if (compression == pdf_comp_ccitt) { + if (image->K != 0) + pdc_printf(p->out, "/K %d", image->K); + } + + if (compression == pdf_comp_flate || compression == pdf_comp_lzw) { + if (image->predictor != pred_default) { + pdc_printf(p->out, "/Predictor %d", (int) image->predictor); + pdc_printf(p->out, "/Columns %d", (int) image->width); + if (image->bpc != 8) + pdc_printf(p->out, "/BitsPerComponent %d", image->bpc); + + if (image->components != 1) /* 1 is default */ + pdc_printf(p->out, "/Colors %d", image->components); + } + } + + if (compression == pdf_comp_ccitt) { + if ((int) image->width != 1728) /* CCITT default width */ + pdc_printf(p->out, "/Columns %d", (int) image->width); + + /* /Rows is not required */ + } + + pdc_puts(p->out, ">>\n"); /* DecodeParms dict */ + } + + + + + /* Write the actual image data */ + length_id = pdc_alloc_id(p->out); + + pdc_objref(p->out, "/Length", length_id); + pdc_end_dict(p->out); /* XObject */ + + /* image data */ + + /* + * We must check "image->compression" here since this describes the + * actual status of the input data, as opposed to "compression" + * which describes the desired status of the output data. + */ + + pdf_copy_stream(p, &image->src, + !image->use_raw || image->compression == pdf_comp_none); + + pdc_end_obj(p->out); /* XObject */ + + pdc_put_pdfstreamlength(p->out, length_id); + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); + + /* + * Write colormap information for indexed color spaces + */ + if (firststrip && image->colorspace != pdc_undef && + p->colorspaces[image->colorspace].type == Indexed) { + pdf_write_colormap(p, image->colorspace); + } + + if (checkcontentstream && PDF_GET_STATE(p) == pdf_state_page) + pdf_begin_contents_section(p); + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); +} + + +/* ---------------------------- fit image ----------------------------------- */ + +void +pdf__fit_image(PDF *p, int im, pdc_scalar x, pdc_scalar y, const char *optlist) +{ + pdf_image *image; + int legal_states; + + pdf_check_handle(p, im, pdc_imagehandle); + + image = &p->images[im]; + + if (PDF_GET_STATE(p) == pdf_state_glyph && !pdf_get_t3colorized(p) && + image->imagemask == pdc_false) + legal_states = pdf_state_page | pdf_state_pattern | pdf_state_template; + else + legal_states = pdf_state_content; + PDF_CHECK_STATE(p, legal_states); + + if (PDF_GET_STATE(p) == pdf_state_template && im == p->templ) + pdc_error(p->pdc, PDF_E_TEMPLATE_SELF, + pdc_errprintf(p->pdc, "%d", im), 0, 0, 0); + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + + pdf_place_xobject(p, im, x, y, optlist); +} + +void +pdf_init_xobject_options(PDF *p, pdf_xobject_options *xo) +{ + xo->adjustpage = pdc_false; + xo->blind = pdc_false; + xo->filename = NULL; + xo->flags = 0; + xo->imagewarning = p->debug[(int) 'i']; + xo->ignoreorientation = pdc_false; + xo->im = -1; + xo->mask = 0; + xo->dpi[0] = 0; + xo->dpi[1] = 0; + xo->page = 1; + xo->scale[0] = 1; + xo->scale[1] = 1; +} + +void +pdf_get_xobject_options(PDF *p, pdf_xobject_options *xo, pdc_resopt *resopts) +{ + int inum; + + (void) p; + + if (!(xo->flags & is_block)) + { + pdc_get_optvalues("adjustpage", resopts, &xo->adjustpage, NULL); + + pdc_get_optvalues("blind", resopts, &xo->blind, NULL); + } + + if (xo->flags & is_image) + { + if (pdc_get_optvalues("ignoreorientation", resopts, + &xo->ignoreorientation, NULL)) + xo->mask |= (1L << xo_ignoreorientation); + + + inum = pdc_get_optvalues("dpi", resopts, xo->dpi, NULL); + if (inum) + { + if (inum == 1) + xo->dpi[1] = xo->dpi[0]; + xo->mask |= (1L << xo_dpi); + } + } + + if (xo->flags & is_block) + { + if (pdc_get_optvalues("imagewarning", resopts, &xo->imagewarning, NULL)) + xo->mask |= (1L << xo_imagewarning); + } + + inum = pdc_get_optvalues("scale", resopts, xo->scale, NULL); + if (inum) + { + if (inum == 1) + xo->scale[1] = xo->scale[0]; + xo->mask |= (1L << xo_scale); + } +} + +/* definitions of fit xobject options */ +static const pdc_defopt pdf_fit_xobject_options[] = +{ + PDF_XOBJECT_OPTIONS1 + PDF_XOBJECT_OPTIONS2 + PDF_XOBJECT_OPTIONS3 + PDF_FIT_OPTIONS1 + PDF_FIT_OPTIONS2 + PDC_OPT_TERMINATE +}; + +pdc_resopt * +pdf_parse_fitxobject_optlist(PDF *p, int im, pdf_xobject_options *xo, + pdf_fit_options *fit, const char *optlist) +{ + pdc_resopt *resopts = NULL; + pdf_image *image = &p->images[im]; + + /* initialize */ + pdf_init_xobject_options(p, xo); + xo->im = im; + if (p->xobjects[image->no].type == image_xobject) + { + xo->flags |= is_image; + xo->dpi[0] = dpi_internal; + xo->dpi[1] = dpi_internal; + xo->ignoreorientation = image->ignoreorient; + } + pdf_init_fit_options(p, pdc_false, fit); + fit->flags |= is_image; + + /* parsing option list */ + if (optlist && strlen(optlist)) + { + pdc_clientdata data; + + pdf_set_clientdata(p, &data); + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_fit_xobject_options, &data, pdc_true); + + pdf_get_xobject_options(p, xo, resopts); + pdf_get_fit_options(p, pdc_false, fit, resopts); + } + + return resopts; +} + +void +pdf_place_xobject(PDF *p, int im, pdc_scalar x, pdc_scalar y, + const char *optlist) +{ + pdf_xobject_options xo; + pdf_fit_options fit; + + /* initialize */ + pdf_parse_fitxobject_optlist(p, im, &xo, &fit, optlist); + fit.refpoint[0] = x; + fit.refpoint[1] = y; + + /* put out xobject */ + if (!xo.blind) + { + pdf_end_text(p); + pdf_begin_contents_section(p); + + + + pdf__save(p); + } + + pdf_fit_xobject_internal(p, &xo, &fit, NULL); + + if (!xo.blind) + pdf__restore(p); +} + +void +pdf_fit_xobject_internal(PDF *p, pdf_xobject_options *xo, pdf_fit_options *fit, + pdc_matrix *immatrix) +{ + pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_image); + pdf_image *image = &p->images[xo->im]; + pdf_xobject_options xo_save; + pdc_rectangle matchrect; + pdf_fit_options fit_save; + pdc_matrix m, mm, sm, ctm_save; + pdc_vector tmpscale, elemscale, fitscale, purescale; + pdc_vector elemsize, mirror, shift, relpos; + pdc_vector polyline[5]; + pdc_box fitbox, clipbox, elembox; + pdc_scalar x, y, ss; + pdc_scalar rowsize = 1, lastratio = 1; + pdc_scalar dpi_x, dpi_y, tx = 0, ty = 0, boxwidth, boxheight; + pdc_bool hasfitbox, kclip = pdc_false, kcliptiff = pdc_false; + int indangle, indmirror; + int is, ip, islast; + int imageno; + + /* initialize */ + tmpscale.x = 1; + tmpscale.y = 1; + if (image->mask != pdc_undef) + { + ctm_save = p->curr_ppt->gstate[p->curr_ppt->sl].ctm; + xo_save = *xo; + fit_save = *fit; + } + else + { + pdc_identity_matrix(&ctm_save); + } + + /* box size */ + boxwidth = fit->boxsize[0]; + boxheight = fit->boxsize[1]; + hasfitbox = boxwidth > PDC_FLOAT_PREC && boxheight > PDC_FLOAT_PREC; + + /* element size */ + elemsize.x = fabs(image->width); + elemsize.y = fabs(image->height); + + if (logg3) + pdc_logg(p->pdc, + "\t\t\tfitbox size: width=%g, height=%g\n" + "\t\t\telement size: width=%g, height=%g\n", + boxwidth, boxheight, elemsize.x, elemsize.y); + + /* clipping */ + if (!kclip) + { + kclip = pdf_get_mbox_clipping(p, fit->matchbox, elemsize.x, elemsize.y, + &clipbox); + } + + if (logg3 && kclip) + pdc_logg(p->pdc, + "\t\t\tclip box: llx=%g, lly=%g, urx=%g, ury=%g\n", + clipbox.ll.x, clipbox.ll.y, clipbox.ur.x, clipbox.ur.y); + + /* TIFF image orientation */ + if (image->orientation != 1 && !xo->ignoreorientation) + { + /* Tag Orientation = 1, 2, 3, 4, 5, 6, 7, 8 */ + const int addangle[8] = {0, 0, 180, 180, 90, 270, 270, 90}; + const int rowmirror[8] = {1, -1, 1, -1, -1, 1, -1, 1}; + + if (logg3) + pdc_logg(p->pdc, "\t\t\torientation tag: %d\n", image->orientation); + + is = image->orientation - 1; + + fit->orientate += addangle[is]; + if (fit->orientate >= 360) + fit->orientate -= 360; + tmpscale.x = rowmirror[is]; + + if (kclip) + { + switch (addangle[is]) + { + default: + elembox = clipbox; + break; + + case 90: + elembox.ll.x = clipbox.ll.y; + elembox.ll.y = elemsize.x - clipbox.ur.x; + elembox.ur.x = clipbox.ur.y; + elembox.ur.y = elemsize.x - clipbox.ll.x; + break; + + case 180: + elembox.ll.x = elemsize.x - clipbox.ur.x; + elembox.ll.y = elemsize.y - clipbox.ur.y; + elembox.ur.x = elemsize.x - clipbox.ll.x; + elembox.ur.y = elemsize.y - clipbox.ll.y; + break; + + case 270: + elembox.ll.x = elemsize.y - clipbox.ur.y; + elembox.ll.y = clipbox.ll.x; + elembox.ur.x = elemsize.y - clipbox.ll.y; + elembox.ur.y = clipbox.ur.x; + break; + } + clipbox = elembox; + + if (tmpscale.x == -1) + { + clipbox.ll.x = elemsize.x - elembox.ur.x; + clipbox.ur.x = elemsize.x - elembox.ll.x; + } + } + } + + /* Compensate inverted direction handling in TIFFReadRGBAImageOriented() */ + if (!image->use_raw && image->pixelmode == pdc_true) + { + tmpscale.y = -1; + elembox = clipbox; + clipbox.ll.y = elemsize.y - elembox.ur.y; + clipbox.ur.y = elemsize.y - elembox.ll.y; + } + + if (logg3 && kclip) + pdc_logg(p->pdc, + "\t\t\tclip box: llx=%g, lly=%g, urx=%g, ury=%g " + "(corrected)\n", + clipbox.ll.x, clipbox.ll.y, clipbox.ur.x, clipbox.ur.y); + + /* image scale */ + elemscale.x = tmpscale.x * xo->scale[0]; + elemscale.y = tmpscale.y * xo->scale[1]; + + if (logg3) + pdc_logg(p->pdc, + "\t\t\telement scaling: sx=%g, sy=%g " + "(user, correction mirroring)\n", + elemscale.x, elemscale.y); + + /* element size */ + elemsize.x = fabs(clipbox.ur.x - clipbox.ll.x); + elemsize.y = fabs(clipbox.ur.y - clipbox.ll.y); + + /* calculation of image scale and size */ + if (xo->flags & is_image) + { + tmpscale.x = 1.0; + tmpscale.y = 1.0; + if (xo->dpi[0] == dpi_internal) + { + dpi_x = image->dpi_x; + dpi_y = image->dpi_y; + if (dpi_x > 0 && dpi_y > 0) + { + tmpscale.x = 72.0 / dpi_x; + tmpscale.y = 72.0 / dpi_y; + } + else if (dpi_x < 0 && dpi_y < 0) + { + tmpscale.y = dpi_y / dpi_x; + } + } + else if (xo->dpi[0] > 0) + { + tmpscale.x = 72.0 / xo->dpi[0]; + tmpscale.y = 72.0 / xo->dpi[1]; + } + + elemscale.x *= tmpscale.x; + elemscale.y *= tmpscale.y; + rowsize = elemscale.y * image->rowsperstrip; + + if (logg3) + pdc_logg(p->pdc, + "\t\t\telement scaling: sx=%g, sy=%g " + "(relating to 72dpi)\n", + tmpscale.x, tmpscale.y); + } + + /* pure scaling without mirroring */ + purescale.x = fabs(elemscale.x); + purescale.y = fabs(elemscale.y); + + /* element size */ + elemsize.x *= purescale.x; + elemsize.y *= purescale.y; + + if (logg3) + pdc_logg(p->pdc, + "\t\t\telement size: width=%g, height=%g (scaled)\n", + elemsize.x, elemsize.y); + + if (xo->flags & is_image) + { + elemscale.x *= image->width; + elemscale.y *= image->height; + lastratio = (elemscale.y / rowsize) - (image->strips - 1); + } + + /* mirroring */ + indmirror = 0; + if (elemscale.x < 0 && elemscale.y < 0) + indmirror = 2; + else if (elemscale.x < 0) + indmirror = 1; + else if (elemscale.y < 0) + indmirror = 3; + + /* orientation */ + indangle = fit->orientate / 90; + if (indangle % 2) + { + ss = elemsize.x; + elemsize.x = elemsize.y; + elemsize.y = ss; + } + + /* box for fitting */ + fitbox.ll.x = 0; + fitbox.ll.y = 0; + fitbox.ur.x = boxwidth; + fitbox.ur.y = boxheight; + + /* relative position */ + relpos.x = fit->position[0] / 100.0; + relpos.y = fit->position[1] / 100.0; + + /* calculate image box */ + if (fit->fitmethod == pdc_tauto) + fit->fitmethod = pdc_meet; + pdc_place_element(fit->fitmethod, 1.0, &fitbox, &relpos, + &elemsize, &relpos, &elembox, &fitscale); + + if (logg3) + pdc_logg(p->pdc, + "\t\t\telement scaling: sx=%g, sy=%g " + "(relating to fitbox)\n", + fitscale.x, fitscale.y); + + /* reference point */ + x = fit->refpoint[0]; + y = fit->refpoint[1]; + + + /* adjust page size */ + if (!xo->blind && xo->adjustpage && PDF_GET_STATE(p) == pdf_state_page) + { + pdc_scalar urx, ury, width, height, theight; + + urx = 2 * x + elembox.ur.x; + ury = 2 * y + elembox.ur.y; + pdc_transform_point(&p->curr_ppt->gstate[p->curr_ppt->sl].ctm, + urx, ury, &width, &theight); + height = (p->ydirection > 0) ? theight + : pdf_get_pageheight(p) - p->ydirection * theight; + + if (height < p->ydirection * theight / 2.0) + pdc_error(p->pdc, PDF_E_IMAGE_NOADJUST, 0, 0, 0, 0); + + width = fabs(width); + height = fabs(height); + + if ((width < PDF_ACRO_MINPAGE || width > PDF_ACRO_MAXPAGE || + height < PDF_ACRO_MINPAGE || height > PDF_ACRO_MAXPAGE)) + pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0); + + pdf_set_pagebox(p, pdf_mediabox, 0, 0, width, height); + pdf_set_pagebox(p, pdf_artbox, 0, 0, 0, 0); + pdf_set_pagebox(p, pdf_bleedbox, 0, 0, 0, 0); + pdf_set_pagebox(p, pdf_cropbox, 0, 0, 0, 0); + pdf_set_pagebox(p, pdf_trimbox, 0, 0, 0, 0); + } + + /* reference point */ + pdc_translation_matrix(x, y, &m); + + /* optional rotation */ + if (fabs(fit->rotate) > PDC_FLOAT_PREC) + { + pdc_rotation_matrix(p->ydirection * fit->rotate, &mm); + pdc_multiply_matrix(&mm, &m); + } + + /* output after translation and rotation */ + if (!xo->blind) + { + /* new CTM */ + if (fit->showborder || + fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice) + { + pdf_concat_raw(p, &m); + pdc_identity_matrix(&m); + } + + /* show border */ + if (fit->showborder) + { + pdf__rect(p, 0, 0, boxwidth, boxheight); + pdf__stroke(p); + } + + /* clipping */ + if (fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice) + { + pdc_scalar cw = boxwidth; + pdc_scalar ch = boxheight; + + if (cw < PDC_FLOAT_PREC) + cw = PDF_ACRO_MAXPAGE; + if (ch < PDC_FLOAT_PREC) + ch = PDF_ACRO_MAXPAGE; + pdf__rect(p, 0, 0, cw, ch); + pdf__clip(p); + } + } + + /* translation of element box */ + elembox.ll.y *= p->ydirection; + elembox.ur.y *= p->ydirection; + pdc_box2polyline(NULL, &elembox, polyline); + ip = indangle + indmirror; + if (ip >= 4) ip -= 4; + tx = polyline[ip].x; + ty = polyline[ip].y; + pdc_translation_matrix(tx, ty, &mm); + pdc_multiply_matrix(&mm, &m); + boxwidth = elembox.ur.x - elembox.ll.x; + boxheight = elembox.ur.y - elembox.ll.y; + + /* orientation of image */ + if (fit->orientate != 0) + { + pdc_rotation_matrix(p->ydirection * fit->orientate, &mm); + pdc_multiply_matrix(&mm, &m); + if (indangle % 2) + { + ss = fitscale.x; + fitscale.x = fitscale.y; + fitscale.y = ss; + + ss = boxwidth; + boxwidth = p->ydirection * boxheight; + boxheight = p->ydirection * ss; + } + } + + /* mirroring of image */ + mirror.x = elemscale.x * fitscale.x; + elemscale.x = fabs(mirror.x); + mirror.x /= elemscale.x; + if (image->strips == 1) + mirror.y = p->ydirection * elemscale.y * fitscale.y; + else + mirror.y = p->ydirection * rowsize * fitscale.y; + elemscale.y = fabs(mirror.y); + mirror.y /= elemscale.y; + pdc_scale_matrix(mirror.x, mirror.y, &mm); + pdc_multiply_matrix(&mm, &m); + + if (logg3) + pdc_logg(p->pdc, + "\t\t\tcumulative mirroring: mx=%g, my=%g\n", + mirror.x, mirror.y); + + /* matchbox or clip path */ + if (!xo->blind && (fit->matchbox || kclip || kcliptiff)) + { + pdf_concat_raw(p, &m); + pdc_identity_matrix(&m); + + if (fit->matchbox) + { + matchrect.llx = 0; + matchrect.lly = 0; + matchrect.urx = boxwidth; + matchrect.ury = p->ydirection * boxheight; + pdf_set_mbox_rectangle(p, fit->matchbox, &matchrect, 0); + pdf_draw_mbox_rectangle(p, fit->matchbox, mbox_area | mbox_border); + + pdf_add_page_mbox(p, fit->matchbox); + } + + /* displacement of image because of clipping */ + shift = clipbox.ll; + purescale.x *= fitscale.x; + purescale.y *= fitscale.y; + if (kclip) + { + shift.x *= -purescale.x; + shift.y *= -purescale.y; + } + + if (kclip) + { + /* user clipping path */ + pdf__rect(p, 0, 0, boxwidth, boxheight); + pdf__clip(p); + } + + if (kclip) + { + pdc_translation_matrix(shift.x, shift.y, &mm); + pdc_multiply_matrix(&mm, &m); + } + } + + /* scaling of image */ + pdc_scale_matrix(elemscale.x, elemscale.y, &mm); + pdc_multiply_matrix(&mm, &m); + + /* ctm */ + if (xo->blind) + { + if (immatrix == NULL) + mm = p->curr_ppt->gstate[p->curr_ppt->sl].ctm; + else + mm = *immatrix; + pdc_multiply_matrix(&m, &mm); + } + else + { + pdf_concat_raw(p, &m); + mm = p->curr_ppt->gstate[p->curr_ppt->sl].ctm; + } + + pdc_logg_cond(p->pdc, 5, trc_image, + "\t\t\tCTM components of image %s\"%s\":\n" + "\t\t\ta = %f\n" + "\t\t\tb = %f\n" + "\t\t\tc = %f\n" + "\t\t\td = %f\n" + "\t\t\te = %f\n" + "\t\t\tf = %f\n", + image->imagemask ? "mask " : "", + image->filename, mm.a, mm.b, mm.c, mm.d, mm.e, mm.f); + + if (!xo->blind) + pdf_cleanup_fit_options(p, fit); + + /* check image orientation */ + if (immatrix != NULL) + { + *immatrix = mm; + return; + } + if (image->mask != pdc_undef) + { + sm = ctm_save; + xo_save.im = image->mask; + xo_save.blind = pdc_true; + pdf_fit_xobject_internal(p, &xo_save, &fit_save, &sm); + + if ((sm.a * mm.a < 0) || (sm.b * mm.b < 0) || + (sm.c * mm.c < 0) || (sm.d * mm.d < 0)) + { + pdc_error(p->pdc, PDF_E_IMAGE_NOMATCH, + p->images[image->mask].filename, image->filename, 0, 0); + } + } + + if (!(xo->flags & is_image) && !xo->blind) + { + pdf_reset_gstate(p); + pdf_reset_tstate(p); + } + + + if (!xo->blind) + { + /* last strip first */ + if (image->strips > 1 && lastratio != 1.0) + { + pdc_scale_matrix(1, lastratio, &m); + pdf_concat_raw(p, &m); + } + + /* put out image strips separately if available */ + islast = image->strips - 1; + imageno = image->no + islast; + for (is = islast; is >= 0; is--) + { + pdc_printf(p->out, "/I%d Do\n", imageno); + p->xobjects[imageno].flags |= xobj_flag_write; + if (image->strips > 1 && is > 0) + { + pdc_translation_matrix(0, 1, &m); + if (is == islast && lastratio != 1.0) + { + pdc_scale_matrix(1, (1.0 / lastratio), &sm); + pdc_multiply_matrix(&sm, &m); + } + pdf_concat_raw(p, &m); + imageno--; + } + } + if (image->mask != pdc_undef) + p->xobjects[p->images[image->mask].no].flags |= xobj_flag_write; + } +} + + +/* ---------------------------- info image --------------------------------- */ + +void +pdf_get_image_size(PDF *p, int im, pdc_scalar *width, pdc_scalar *height) +{ + pdf_image *image; + + pdf_check_handle(p, im, pdc_imagehandle); + image = &p->images[im]; + + if (image->orientation < 5 || image->ignoreorient) + { + if (width) + *width = image->width; + if (height) + *height = fabs(image->height); + } + else + { + if (width) + *width = fabs(image->height); + if (height) + *height = image->width; + } +} + +void +pdf_get_image_resolution(PDF *p, int im, pdc_scalar *dpi_x, pdc_scalar *dpi_y) +{ + pdf_image *image; + + pdf_check_handle(p, im, pdc_imagehandle); + image = &p->images[im]; + + if (image->orientation < 5 || image->ignoreorient) + { + if (dpi_x) + *dpi_x = image->dpi_x; + if (dpi_y) + *dpi_y = image->dpi_y; + } + else + { + if (dpi_x) + *dpi_x = image->dpi_y; + if (dpi_y) + *dpi_y = image->dpi_x; + } +} + + +const char * +pdf_get_image_filename(PDF *p, pdf_image *image) +{ + return pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, image->filename); +} + + +/* ---------------------------- load image --------------------------------- */ + +static const pdc_keyconn pdf_extension_names[] = +{ + {".bmp", pdf_img_bmp}, + {".ccitt", pdf_img_ccitt}, + {".g3", pdf_img_ccitt}, + {".g4", pdf_img_ccitt}, + {".fax", pdf_img_ccitt}, + {".gif", pdf_img_gif}, + {".jpg", pdf_img_jpeg}, + {".jpeg", pdf_img_jpeg}, + {".jpx", pdf_img_jpeg2000}, + {".jp2", pdf_img_jpeg2000}, + {".jpf", pdf_img_jpeg2000}, + {".jpm", pdf_img_jpeg2000}, + {".j2k", pdf_img_jpeg2000}, + {".png", pdf_img_png}, + {".raw", pdf_img_raw}, + {".tif", pdf_img_tiff}, + {".tiff", pdf_img_tiff}, + {NULL, 0} +}; + +/* allowed values for options 'bpc' */ +static const pdc_keyconn pdf_bpcvalues[] = +{ + {"1", 1}, {"2", 2}, {"4", 4}, {"8", 8}, {"16", 16}, {NULL, 0} +}; + +/* allowed values for options 'components' */ +static const pdc_keyconn pdf_compvalues[] = +{ + {"1", 1}, {"3", 3}, {"4", 4}, {NULL, 0} +}; + +#define PDF_OPIOPT_FLAG PDC_OPT_UNSUPP +#define PDF_ICCOPT_FLAG PDC_OPT_UNSUPP +#define PDF_CLIPPATH_FLAG PDC_OPT_UNSUPP + +#define PDF_METADATA_FLAG PDC_OPT_UNSUPP + +#define PDF_LAYER_FLAG PDC_OPT_UNSUPP + +/* definitions of open image options */ +static const pdc_defopt pdf_open_image_options[] = +{ + {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"bitreverse", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"bpc", pdc_integerlist, PDC_OPT_INTLIST, 1, 1, 1.0, 16.0, pdf_bpcvalues}, + + {"components", pdc_integerlist, PDC_OPT_INTLIST, 1, 1, 1.0, 4.0, + pdf_compvalues}, + + {"height", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX, NULL}, + + {"width", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX, NULL}, + + {"honoriccprofile", pdc_booleanlist, PDF_ICCOPT_FLAG, 1, 1, 0.0, 0.0, NULL}, + + /* ordering of the next three options is significant */ + + {"iccprofile", pdc_iccprofilehandle, PDF_ICCOPT_FLAG, 1, 1, 1.0, 0.0, NULL}, + + {"colorize", pdc_colorhandle, PDC_OPT_IGNOREIF1, 1, 1, 0.0, 0.0, NULL}, + + {"mask", pdc_booleanlist, PDC_OPT_IGNOREIF2, 1, 1, 0.0, 0.0, NULL}, + + {"honorclippingpath", pdc_booleanlist, PDF_CLIPPATH_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + {"clippingpathname", pdc_stringlist, PDF_CLIPPATH_FLAG, 1, 1, + 1.0, PDC_INT_MAX, NULL}, + + {"ignoremask", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"ignoreorientation", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + /* deprecated */ + {"imagewarning", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"inline", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"interpolate", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"invert", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"jpegoptimize", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"passthrough", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"K", pdc_integerlist, 0, 1, 1, -1.0, 1.0, NULL}, + + {"masked", pdc_imagehandle, 0, 1, 1, 0.0, 0.0, NULL}, + + {"page", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX, NULL}, + + {"renderingintent", pdc_keywordlist, 0, 1, 1, 0.0, 0.0, + pdf_renderingintent_pdfkeylist}, + + {"reftype", pdc_keywordlist, 0, 1, 1, 0.0, 0.0, pdf_reftype_keys}, + + {"template", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"iconname", pdc_stringlist, 0, 1, 1, + 1.0, PDF_MAX_NAMESTRING, NULL}, + + {"OPI-1.3", pdc_stringlist, PDF_OPIOPT_FLAG, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"OPI-2.0", pdc_stringlist, PDF_OPIOPT_FLAG | PDC_OPT_IGNOREIF1, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"layer", pdc_layerhandle, PDF_LAYER_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + PDF_ERRORPOLICY_OPTION + + PDC_OPT_TERMINATE +}; + +int +pdf__load_image( + PDF *p, + const char *type, + const char *filename, + const char *optlist) +{ + const char *keyword = NULL, *stemp1 = NULL, *stemp2 = NULL, *stemp3 = NULL; + char qualname[32], uptype[16], testfilename[PDC_FILENAMELEN + 1]; + pdc_clientdata data; + pdc_resopt *resopts; + pdc_encoding htenc; + int htcp; + pdf_image_type imgtype; + pdc_file *fp = NULL; + int colorize = pdc_undef; + pdf_image *image; + pdc_bool indjpeg = pdc_false; + pdc_bool templ = pdc_false; + pdc_bool verbose = p->debug[(int) 'i']; + int legal_states = 0; + int i, k, inum, imageslot, retval = -1, errcode = 0; + + if (type == NULL || *type == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "type", 0, 0, 0); + + /* parsing image type */ + k = pdc_get_keycode_ci(type, pdf_image_keylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0); + imgtype = (pdf_image_type) k; + type = pdc_get_keyword(imgtype, pdf_image_keylist); + + verbose = pdf_get_errorpolicy(p, NULL, verbose); + + /* filename must be already converted to UTF-8 */ + pdc_logg_cond(p->pdc, 1, trc_image, "\tImage file: \"%s\"\n", filename); + + /* search for image file */ + fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "image ", PDC_FILE_BINARY); + + /* automatic check */ + if (imgtype == pdf_img_auto) + { + pdf_tiff_info tiff_info; + + /* search for files with other extensions */ + if (fp == NULL) + { + pdc_logg_cond(p->pdc, 1, trc_image, + "\tImage file not found; searching for files " + "with alternative extensions\n"); + + for (i = 0; i < 2; i++) + { + for (k = 0; k < 100; k++) + { + const char *extension = pdf_extension_names[k].word; + if (extension) + { + strcpy(testfilename, filename); + strcpy(uptype, extension); + if (i) + pdc_strtoupper(uptype); + strcat(testfilename, uptype); + + fp = pdc_fsearch_fopen(p->pdc, testfilename, NULL, + "image ", PDC_FILE_BINARY); + if (fp != NULL) + break; + } + else + { + break; + } + } + if (fp != NULL) + break; + } + + if (fp != NULL) + { + filename = (const char *) testfilename; + pdc_logg_cond(p->pdc, 1, trc_image, + "\tImage file \"%s\" found\n", filename); + } + else + { + fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "image ", + PDC_FILE_BINARY); + } + } + + /* automatic type check */ + if (fp != NULL) + { + if (pdf_is_BMP_file(p, fp)) + imgtype = pdf_img_bmp; + else if (pdf_is_GIF_file(p, fp)) + imgtype = pdf_img_gif; + else if (pdf_is_PNG_file(p, fp)) + imgtype = pdf_img_png; + else if (pdf_is_TIFF_file(p, fp, &tiff_info, pdc_true)) + imgtype = pdf_img_tiff; + else if (pdf_is_JPEG_file(p, fp)) + imgtype = pdf_img_jpeg; + else if (pdf_is_JPX_file(p, fp)) + imgtype = pdf_img_jpeg2000; + else + { + pdc_fclose(fp); + + pdc_set_errmsg(p->pdc, PDF_E_IMAGE_UNKNOWN, filename, 0, 0, 0); + + if (verbose) + PDC_RETHROW(p->pdc); + + return -1; + } + type = pdc_get_keyword(imgtype, pdf_image_keylist); + } + } + + if (fp == NULL) + { + if (verbose) + PDC_RETHROW(p->pdc); + + return -1; + } + pdc_fclose(fp); + + strcpy(uptype, type); + pdc_strtoupper(uptype); + pdc_logg_cond(p->pdc, 1, trc_image, + "\tImage type \"%s\" detected\n", uptype); + + if (imgtype == pdf_img_jpeg2000) + { + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_JPEG2000, 0, 0, 0, 0); + + if (verbose) + PDC_RETHROW(p->pdc); + + return -1; + } + + /* find free slot */ + for (imageslot = 0; imageslot < p->images_capacity; imageslot++) + if (!p->images[imageslot].in_use) + break; + + if (imageslot == p->images_capacity) + pdf_grow_images(p); + image = &p->images[imageslot]; + + /* copy filename */ + image->filename = pdc_strdup(p->pdc, filename); + + /* inherit global flags */ + image->verbose = verbose; + image->ri = p->rendintent; + + /* parsing optlist */ + if (optlist && strlen(optlist)) + { + pdf_set_clientdata(p, &data); + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_open_image_options, + &data, pdc_true); + /* save and check options */ + keyword = "imagewarning"; + pdc_get_optvalues(keyword, resopts, &image->verbose, NULL); + image->verbose = pdf_get_errorpolicy(p, resopts, image->verbose); + verbose = image->verbose; + + keyword = "reftype"; + if (pdc_get_optvalues(keyword, resopts, &inum, NULL)) + { + image->reference = (pdf_ref_type) inum; + if (image->reference != pdf_ref_direct && + imgtype != pdf_img_ccitt && + imgtype != pdf_img_jpeg && + imgtype != pdf_img_raw) + { + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype, + 0, 0); + image->reference = pdf_ref_direct; + } + } + indjpeg = (imgtype == pdf_img_jpeg && + image->reference != pdf_ref_direct) ? pdc_true : pdc_false; + + keyword = "bpc"; + if (pdc_get_optvalues(keyword, resopts, &image->bpc, NULL)) + { + if (imgtype != pdf_img_raw && !indjpeg) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + if (image->bpc == 16) + { + if (p->compatibility < PDC_1_5) + { + errcode = PDC_E_OPT_VERSION; + stemp1 = "bpc=16"; + stemp2 = pdc_get_pdfversion(p->pdc, p->compatibility); + goto PDF_IMAGE_ERROR; + } + } + } + + keyword = "components"; + if (pdc_get_optvalues(keyword, resopts, &image->components, NULL)) + { + if (imgtype != pdf_img_raw && !indjpeg) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + } + + keyword = "height"; + if (pdc_get_optvalues(keyword, resopts, &image->height_pixel, NULL)) + { + if (imgtype != pdf_img_ccitt && + imgtype != pdf_img_raw && !indjpeg) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + } + + keyword = "width"; + if (pdc_get_optvalues(keyword, resopts, &image->width_pixel, NULL)) + { + if (imgtype != pdf_img_raw && + imgtype != pdf_img_ccitt && !indjpeg) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + } + + keyword = "bitreverse"; + if (pdc_get_optvalues(keyword, resopts, &image->bitreverse, NULL)) + { + if (image->bitreverse && + (imgtype != pdf_img_ccitt || image->reference != pdf_ref_direct)) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + } + + keyword = "colorize"; + if (pdc_get_optvalues(keyword, resopts, &colorize, NULL)) + { + if (imgtype == pdf_img_jpeg2000) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + } + + + keyword = "ignoremask"; + if (pdc_get_optvalues(keyword, resopts, &image->ignoremask, NULL)) + { + if (imgtype == pdf_img_bmp || + imgtype == pdf_img_ccitt || + imgtype == pdf_img_raw) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype, + 0, 0); + } + + keyword = "ignoreorientation"; + if (pdc_get_optvalues(keyword, resopts, &image->ignoreorient, NULL)) + { + if (imgtype == pdf_img_tiff) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype, + 0, 0); + } + + keyword = "inline"; + if (pdc_get_optvalues(keyword, resopts, + &image->doinline, NULL) && image->doinline) + { + if (imgtype != pdf_img_ccitt && + imgtype != pdf_img_jpeg && + imgtype != pdf_img_raw) + { + pdc_warning(p->pdc, + PDF_E_IMAGE_OPTUNSUPP, keyword, uptype, 0, 0); + image->doinline = pdc_false; + } + else if (image->reference != pdf_ref_direct) + { + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + image->doinline = pdc_false; + } + } + + keyword = "interpolate"; + pdc_get_optvalues(keyword, resopts, &image->interpolate, NULL); + + + keyword = "invert"; + if (pdc_get_optvalues(keyword, resopts, &image->invert, NULL)) + { + if (imgtype == pdf_img_jpeg2000) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + } + + keyword = "jpegoptimize"; + pdc_get_optvalues(keyword, resopts, &image->jpegoptimize, NULL); + + keyword = "passthrough"; + pdc_get_optvalues(keyword, resopts, &image->passthrough, NULL); + + keyword = "K"; + if (pdc_get_optvalues(keyword, resopts, &image->K, NULL)) + { + if (imgtype != pdf_img_ccitt) + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype, + 0, 0); + } + + keyword = "mask"; + pdc_get_optvalues(keyword, resopts, &image->imagemask, NULL); + + + keyword = "masked"; + if (pdc_get_optvalues(keyword, resopts, &image->mask, NULL)) + { + + + if (!p->images[image->mask].in_use || + p->images[image->mask].strips != 1 || + (p->compatibility <= PDC_1_3 && + (p->images[image->mask].imagemask != pdc_true || + p->images[image->mask].bpc != 1))) + { + errcode = PDF_E_IMAGE_OPTBADMASK; + stemp1 = keyword; + stemp2 = pdc_errprintf(p->pdc, "%d", image->mask); + goto PDF_IMAGE_ERROR; + } + + if (p->colorspaces[p->images[image->mask].colorspace].type != + DeviceGray) + { + errcode = PDF_E_IMAGE_BADMASK; + stemp1 = pdc_errprintf(p->pdc, "%s", + p->images[image->mask].filename); + goto PDF_IMAGE_ERROR; + } + } + + keyword = "renderingintent"; + if (pdc_get_optvalues(keyword, resopts, &inum, NULL)) + image->ri = (pdf_renderingintent) inum; + + keyword = "page"; + if (pdc_get_optvalues(keyword, resopts, &image->page, NULL)) + { + if (imgtype != pdf_img_tiff) + { + if (image->page == 1) + { + pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, + uptype, 0, 0); + } + else + { + errcode = PDF_E_IMAGE_NOPAGE; + stemp1 = pdc_errprintf(p->pdc, "%d", image->page); + stemp2 = uptype; + stemp3 = pdc_errprintf(p->pdc, "%s", image->filename); + goto PDF_IMAGE_ERROR; + } + } + } + + keyword = "template"; + if (pdc_get_optvalues(keyword, resopts, &templ, NULL)) + { + if (templ && image->doinline) + { + pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword, "inline", + 0, 0); + templ = pdc_false; + } + } + + htenc = + pdf_get_hypertextencoding_opt(p, resopts, &htcp, pdc_true); + keyword = "iconname"; + if (pdf_get_opt_textlist(p, keyword, resopts, htenc, htcp, pdc_true, + NULL, &image->iconname, NULL)) + { + if (image->doinline) + { + image->iconname = NULL; + pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword, "inline", + 0, 0); + } + else + { + pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + templ = pdc_true; + } + } + + + + } + + /* precise scope diagnosis */ + if (image->doinline) + legal_states = pdf_state_content; + else if (templ) + legal_states = pdf_state_document; + else + legal_states = pdf_state_document | pdf_state_page | pdf_state_font; + PDF_CHECK_STATE(p, legal_states); + + /* required options */ + if (imgtype == pdf_img_raw || imgtype == pdf_img_ccitt || indjpeg) + { + keyword = ""; + if (image->height_pixel == pdc_undef) + keyword = "height"; + else if (image->width_pixel == pdc_undef) + keyword = "width"; + else + { + image->width = image->width_pixel; + image->height = image->height_pixel; + } + + if (imgtype == pdf_img_ccitt) + { + image->components = 1; + image->bpc = 1; + } + if (image->bpc == pdc_undef) + keyword = "bpc"; + else if (image->components == pdc_undef) + keyword = "components"; + + if (*keyword) + { + errcode = PDC_E_OPT_NOTFOUND; + stemp1 = keyword; + goto PDF_IMAGE_ERROR; + } + } + + + + /* set colorspace */ + if (colorize != pdc_undef) + { + image->colorspace = colorize; + } + else if (image->imagemask == pdc_true) + { + image->colorspace = (int) DeviceGray; + } + else + { + switch(image->components) + { + case 1: + image->colorspace = DeviceGray; + break; + + case 3: + image->colorspace = DeviceRGB; + break; + + case 4: + image->colorspace = DeviceCMYK; + break; + + default: + break; + } + } + + /* try to open image file */ + if (image->reference == pdf_ref_direct) + { + strcpy(qualname, uptype); + strcat(qualname, " "); + image->fp = pdc_fsearch_fopen(p->pdc, image->filename, NULL, qualname, + PDC_FILE_BINARY); + if (image->fp == NULL) + goto PDF_IMAGE_ERROR; + } + + + /* set image type */ + image->type = imgtype; + + /* call working function */ + switch (imgtype) + { + case pdf_img_bmp: + retval = pdf_process_BMP_data(p, imageslot); + break; + + case pdf_img_ccitt: + retval = pdf_process_CCITT_data(p, imageslot); + break; + + case pdf_img_gif: + retval = pdf_process_GIF_data(p, imageslot); + break; + + case pdf_img_jpeg: + if (image->passthrough == pdc_undef) + image->passthrough = pdc_false; + retval = pdf_process_JPEG_data(p, imageslot); + break; + + case pdf_img_jpeg2000: + retval = pdf_process_JPX_data(p, imageslot); + break; + + case pdf_img_png: + retval = pdf_process_PNG_data(p, imageslot); + break; + + default: + case pdf_img_raw: + retval = pdf_process_RAW_data(p, imageslot); + break; + + case pdf_img_tiff: + if (image->passthrough == pdc_undef) + image->passthrough = pdc_true; + retval = pdf_process_TIFF_data(p, imageslot); + break; + } + + /* cleanup */ + if (retval == -1) + { + pdf_cleanup_image(p, imageslot); + + if (verbose) + PDC_RETHROW(p->pdc); + } + else + { + if (image->fp) + pdc_fclose(image->fp); + image->fp = NULL; + + /* logging protocol */ + if (pdc_logg_is_enabled(p->pdc, 1, trc_image)) + { + pdc_scalar width, height, dpi_x, dpi_y; + + pdf_get_image_size(p, imageslot, &width, &height); + pdf_get_image_resolution(p, imageslot, &dpi_x, &dpi_y); + + pdc_logg(p->pdc, "\tImage width: %g pixel\n" + "\tImage height: %g pixel\n" + "\tImage x resolution: %g dpi\n" + "\tImage y resolution: %g dpi\n", + width, height, dpi_x, dpi_y); + + if (imgtype == pdf_img_tiff) + pdc_logg(p->pdc, "\tOrientation tag: %d\n", + image->orientation); + + } + + if (templ) + { + retval = pdf_embed_image(p, imageslot); + pdf_cleanup_image(p, imageslot); + } + } + + return retval; + + PDF_IMAGE_ERROR: + + pdf_cleanup_image(p, imageslot); + + if (errcode) + pdc_set_errmsg(p->pdc, errcode, stemp1, stemp2, stemp3, 0); + if (verbose) + PDC_RETHROW(p->pdc); + + return retval; +} + +void +pdf__close_image(PDF *p, int image) +{ + pdf_check_handle(p, image, pdc_imagehandle); + pdf_cleanup_image(p, image); +} + + +#define MAX_THUMBNAIL_SIZE 106 + +void +pdf__add_thumbnail(PDF *p, int im) +{ + pdf_image *image; + + pdf_check_handle(p, im, pdc_imagehandle); + + if (pdf_get_thumb_id(p) != PDC_BAD_ID) + pdc_error(p->pdc, PDF_E_IMAGE_THUMB, 0, 0, 0, 0); + + image = &p->images[im]; + + if (image->strips > 1) + pdc_error(p->pdc, PDF_E_IMAGE_THUMB_MULTISTRIP, + pdc_errprintf(p->pdc, "%d", im), 0, 0, 0); + + if (image->width > MAX_THUMBNAIL_SIZE || image->height > MAX_THUMBNAIL_SIZE) + pdc_error(p->pdc, PDF_E_IMAGE_THUMB_SIZE, + pdc_errprintf(p->pdc, "%d", im), + pdc_errprintf(p->pdc, "%d", MAX_THUMBNAIL_SIZE), 0, 0); + + if (image->colorspace != (int) DeviceGray && + image->colorspace != (int) DeviceRGB && + image->colorspace != (int) Indexed) + pdc_error(p->pdc, PDF_E_IMAGE_THUMB_CS, + pdc_errprintf(p->pdc, "%d", im), 0, 0, 0); + + /* Add the image to the thumbnail key of the current page. */ + pdf_set_thumb_id(p, p->xobjects[image->no].obj_id); +} diff --git a/src/pdflib/pdflib/p_image.h b/src/pdflib/pdflib/p_image.h new file mode 100644 index 0000000..2f67649 --- /dev/null +++ b/src/pdflib/pdflib/p_image.h @@ -0,0 +1,358 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_image.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Header file for the PDFlib image subsystem + * + */ + +#ifndef P_IMAGE_H +#define P_IMAGE_H + +#ifdef HAVE_LIBTIFF +#include "tiffio.h" +#endif + +#ifdef HAVE_LIBPNG +#include "png.h" +#endif + +/* image type */ +typedef enum +{ + pdf_img_auto, + pdf_img_bmp, + pdf_img_ccitt, + pdf_img_gif, + pdf_img_jpeg, + pdf_img_jpeg2000, + pdf_img_png, + pdf_img_raw, + pdf_img_tiff +} +pdf_image_type; + +/* compression type */ +typedef enum +{ + pdf_comp_none, + pdf_comp_lzw, + pdf_comp_runlength, + pdf_comp_ccitt, + pdf_comp_dct, + pdf_comp_flate, + pdf_comp_jbig2, + pdf_comp_jpx +} +pdf_compression; + +/* image reference */ +typedef enum +{ + pdf_ref_direct, + pdf_ref_file, + pdf_ref_url +} +pdf_ref_type; + +typedef enum +{ + pred_default = 1, + pred_tiff = 2, + pred_png = 15 +} +pdf_predictor; + +#ifdef P_IMAGE_C + +const pdc_keyconn pdf_image_keylist[] = +{ + {"auto", pdf_img_auto}, + {"bmp", pdf_img_bmp}, + {"ccitt", pdf_img_ccitt}, + {"gif", pdf_img_gif}, + {"jpeg", pdf_img_jpeg}, + {"jpeg2000", pdf_img_jpeg2000}, + {"png", pdf_img_png}, + {"raw", pdf_img_raw}, + {"tiff", pdf_img_tiff}, + {NULL, 0} +}; + +const pdc_keyconn pdf_filter_pdfkeylist[] = +{ + {"", pdf_comp_none}, + {"LZWDecode", pdf_comp_lzw}, + {"RunLengthDecode", pdf_comp_runlength}, + {"CCITTFaxDecode", pdf_comp_ccitt}, + {"DCTDecode", pdf_comp_dct}, + {"FlateDecode", pdf_comp_flate}, + {"JBIG2Decode", pdf_comp_jbig2}, + {"JPXDecode", pdf_comp_jpx}, + {NULL, 0} +}; + +const pdc_keyconn pdf_shortfilter_pdfkeylist[] = +{ + {"", pdf_comp_none}, + {"LZW", pdf_comp_lzw}, + {"RL", pdf_comp_runlength}, + {"CCF", pdf_comp_ccitt}, + {"DCT", pdf_comp_dct}, + {"Fl", pdf_comp_flate}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_reftype_keys[] = +{ + {"direct", pdf_ref_direct}, + {"fileref", pdf_ref_file}, + {"url", pdf_ref_url}, + {NULL, 0} +}; + +#endif /* P_IMAGE_C */ + +/* BMP specific image information */ +typedef struct pdf_bmp_info_t { + pdc_uint32 compression; /* BMP compression */ + pdc_uint32 redmask; /* red mask */ + pdc_ushort redmax; /* red maximal value */ + pdc_ushort redmove; /* red mask's movement */ + pdc_uint32 greenmask; /* green mask */ + pdc_ushort greenmax; /* green maximal value */ + pdc_ushort greenmove; /* green mask's movement */ + pdc_uint32 bluemask; /* blue mask */ + pdc_ushort bluemax; /* blue maximal value */ + pdc_ushort bluemove; /* blue mask's movement */ + pdc_ushort bpp; /* bits per pixel */ + size_t rowbytes; /* length of row data */ + size_t rowbytes_pad; /* padded length of row data */ + size_t rowbytes_buf; /* buffer for row data */ + size_t rowbytes_pdf; /* length of row data for PDF */ + size_t skiprows; /* number of rows to be skipped */ + pdc_byte *bitmap; /* bitmap buffer */ + pdc_byte *end; /* first byte above bitmap buffer */ + pdc_byte *pos; /* current position in bitmap buffer */ +} pdf_bmp_info; + +typedef struct pdf_jpeg_segment_s pdf_jpeg_segment; + +/* JPEG specific image information */ +#define JPEG_MAX_COMPS 4 /* max number components */ +typedef struct pdf_jpeg_info_t { + const char *virtfile; /* temporary virtual file name */ + pdf_jpeg_segment *seglist; /* list of segments to be copy */ + int capacity; /* currently allocated size */ + int number; /* next available segment number */ + pdc_uint32 jpegifoffset; /* offset to JPEG data for TIFF OJPEG */ /* CDPDF - replaced toff_t by pdc_uint32 */ + pdc_byte id[JPEG_MAX_COMPS]; /* component ids */ + pdc_byte hsamp[JPEG_MAX_COMPS]; /* horizontal sampling factor */ + pdc_byte vsamp[JPEG_MAX_COMPS]; /* vertical sampling factor */ + pdc_byte table[JPEG_MAX_COMPS]; /* quant table */ +} pdf_jpeg_info; + +/* GIF specific image information */ +typedef struct pdf_gif_info_t { + int useGlobalColormap; + int interlace; + + /* LZW decompression state */ + int ZeroDataBlock; + int curbit; + int lastbit; + int get_done; + int last_byte; + int return_clear; + int *sp; + int code_size, set_code_size; + int max_code, max_code_size; + int clear_code, end_code; + pdc_byte buf[280]; + int firstcode; + int oldcode; + + /* These are dynamically malloc'ed to avoid wasting 64KB for each image */ +#define MAX_LWZ_BITS 12 +#define GIF_TABLE_ELEMENTS (1<< MAX_LWZ_BITS) + int (*table)[GIF_TABLE_ELEMENTS]; + int *stack; +} pdf_gif_info; + + +/* PNG specific image information */ +typedef struct pdf_png_info_t { + size_t nbytes; /* number of bytes left */ + /* in current IDAT chunk */ +#ifdef HAVE_LIBPNG + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 rowbytes; + pdc_byte *raster; + int cur_line; +#endif /* HAVE_LIBPNG */ +} pdf_png_info; + + +/* TIFF specific image information */ +typedef struct pdf_tiff_info_t { +#ifdef HAVE_LIBTIFF + TIFF *tif; /* pointer to TIFF data structure */ + uint32 *raster; /* frame buffer */ +#endif /* HAVE_LIBTIFF */ + + int cur_line; /* current image row or strip */ +} pdf_tiff_info; + +/* CCITT specific image information */ +typedef struct pdf_ccitt_info_t { + int BitReverse; /* reverse all bits prior to use */ +} pdf_ccitt_info; + +/* The image descriptor */ +struct pdf_image_s { + pdc_file *fp; /* image file pointer */ + char *filename; /* image file name or url */ + /* width and height in pixels, or in points for PDF pages and templates */ + pdc_scalar width; /* image width */ + pdc_scalar height; /* image height */ + int orientation; /* image orientation according TIFF */ + pdf_compression compression; /* image compression type */ + int colorspace; /* image color space */ + + /*************************** option variables *****************************/ + pdc_bool verbose; /* put out warning/error messages */ + pdc_bool bitreverse; /* bitwise reversal of all bytes */ + int bpc; /* bits per color component */ + int components; /* number of color components */ + int height_pixel; /* image height in pixel */ + int width_pixel; /* image width in pixel */ + pdc_bool ignoremask; /* ignore any transparency information*/ + pdc_bool ignoreorient; /* ignore orientation TIFF tag */ + pdc_bool doinline; /* inline image */ + pdc_bool interpolate; /* interpolate image */ + pdc_bool invert; /* reverse black and white */ + pdc_bool jpegoptimize; /* skip application segments of JPEG */ + pdc_bool passthrough; /* pass through mode for TIFF, JPEG */ + int K; /* encoding type of CCITT */ + pdc_bool imagemask; /* create a mask from a 1-bit image */ + int mask; /* image number of image mask */ + pdf_renderingintent ri; /* rendering intent of image */ + int page; /* page number of TIFF image */ + pdf_ref_type reference; /* kind of image data reference */ + pdc_bool topdown_save; /* saved topdown flag */ + char *iconname; /* icon name for template images */ + /**************************************************************************/ + + pdc_bool transparent; /* image is transparent */ + pdc_byte transval[4]; /* transparent color values */ + pdf_predictor predictor; /* predictor for lzw and flate */ + + pdc_scalar dpi_x; /* horiz. resolution in dots per inch */ + pdc_scalar dpi_y; /* vert. resolution in dots per inch */ + /* dpi is 0 if unknown */ + + pdc_bool in_use; /* image slot currently in use */ + pdc_bool corrupt; /* image is corrupt */ + + char *params; /* for TIFF */ + int strips; /* number of strips in image */ + int rowsperstrip; /* number of rows per strip */ + int pagehandle; /* PDI page handle */ + int dochandle; /* PDI document handle */ + pdc_pagebox usebox; + pdc_bool use_raw; /* use raw (compressed) image data */ + /* Only relevant for use_raw = false */ + pdc_bool pixelmode; /* Use TIFFReadRGBAImageOriented() ? */ + + pdf_image_type type; /* image type, used for cleanup */ + /* image format specific information */ + union { + pdf_bmp_info bmp; + pdf_jpeg_info jpeg; + pdf_gif_info gif; + pdf_png_info png; + pdf_tiff_info tiff; + pdf_ccitt_info ccitt; + } info; + + int no; /* PDF image number */ + PDF_data_source src; +}; + +/* xobject types */ +typedef enum { + image_xobject = 1 << 0, + form_xobject = 1 << 1, + pdi_xobject = 1 << 2 +} pdf_xobj_type; + +typedef enum { + xobj_flag_used = 1 << 0, /* in use */ + xobj_flag_write = 1 << 1 /* write at end of page */ +} pdf_xobj_flags; + +/* A PDF xobject */ +struct pdf_xobject_s { + pdc_id obj_id; /* object id of this xobject */ + int flags; /* bit mask of pdf_xobj_flags */ + pdf_xobj_type type; /* type of this xobject */ +}; + +/* p_bmp.c */ +int pdf_process_BMP_data(PDF *p, int imageslot); +pdc_bool pdf_is_BMP_file(PDF *p, pdc_file *fp); + +/* p_ccitt.c */ +int pdf_process_CCITT_data(PDF *p, int imageslot); +int pdf_process_RAW_data(PDF *p, int imageslot); + +/* p_gif.c */ +int pdf_process_GIF_data(PDF *p, int imageslot); +pdc_bool pdf_is_GIF_file(PDF *p, pdc_file *fp); +void pdf_cleanup_gif(PDF *p, pdf_image *image); + +/* p_jpeg.c */ +int pdf_process_JPEG_data(PDF *p, int imageslot); +pdc_bool pdf_is_JPEG_file(PDF *p, pdc_file *fp); +void pdf_cleanup_jpeg(PDF *p, pdf_image *image); + +/* p_jpx.c */ +int pdf_process_JPX_data(PDF *p, int imageslot); +pdc_bool pdf_is_JPX_file(PDF *p, pdc_file *fp); +void pdf_cleanup_jpx(PDF *p, pdf_image *image); + +/* p_png.c */ +int pdf_process_PNG_data(PDF *p, int imageslot); +pdc_bool pdf_is_PNG_file(PDF *p, pdc_file *fp); + +/* p_tiff.c */ +int pdf_process_TIFF_data(PDF *p, int imageslot); +pdc_bool pdf_is_TIFF_file(PDF *p, pdc_file *fp, pdf_tiff_info *tiff, + pdc_bool check); + +/* p_image.c */ +pdc_id pdf_get_xobject(PDF *p, int im); +void pdf_init_xobjects(PDF *p); +void pdf_write_xobjects(PDF *p); +void pdf_place_xobject(PDF *p, int im, pdc_scalar x, pdc_scalar y, + const char *optlist); +int pdf_new_xobject(PDF *p, pdf_xobj_type type, pdc_id obj_id); +void pdf_get_page_xobjects(PDF *p, pdf_reslist *rl); +void pdf_mark_page_xobject(PDF *p, int n); +void pdf_cleanup_xobjects(PDF *p); +const char *pdf_get_image_filename(PDF *p, pdf_image *image); + + +#endif /* P_IMAGE_H */ + diff --git a/src/pdflib/pdflib/p_intern.h b/src/pdflib/pdflib/p_intern.h new file mode 100644 index 0000000..80f92d9 --- /dev/null +++ b/src/pdflib/pdflib/p_intern.h @@ -0,0 +1,1027 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_intern.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib internal definitions + * + */ + +#ifndef P_INTERN_H +#define P_INTERN_H + +#include "pdflib.h" + +#include "ft_font.h" +#include "pc_file.h" +#include "pc_contain.h" + +#include "p_keyconn.h" + + + + +/* ------------------------ PDFlib feature configuration ------------------- */ + +/* changing the following is not recommended, and not supported */ + +/* BMP image support */ +/* #define PDF_BMP_SUPPORTED CDPDF: leave this to the IM library */ + +/* GIF image support */ +/* #define PDF_GIF_SUPPORTED CDPDF: leave this to the IM library */ + +/* JPEG image support */ +/* #define PDF_JPEG_SUPPORTED CDPDF: leave this to the IM library */ + +/* JPEG2000 image support */ +/* #define PDF_JPX_SUPPORTED CDPDF: leave this to the IM library */ + +/* PNG image support, requires HAVE_LIBZ */ +/* #define HAVE_LIBPNG CDPDF: leave this to the IM library */ + +/* TIFF image support */ +/* #define HAVE_LIBTIFF CDPDF: leave this to the IM library */ + + +/* -------------------------------- macros ------------------------------- */ + +/* + * Allocation chunk sizes. These don't affect the generated documents + * in any way. In order to save initial memory, however, you can lower + * the values. Increasing the values will bring some performance gain + * for large documents, but will waste memory for small ones. + */ +#define PAGES_CHUNKSIZE 512 /* pages */ +#define PNODES_CHUNKSIZE 64 /* page tree nodes */ +#define CONTENTS_CHUNKSIZE 64 /* page content streams */ +#define FONTS_CHUNKSIZE 16 /* document fonts */ +#define XOBJECTS_CHUNKSIZE 128 /* document xobjects */ +#define IMAGES_CHUNKSIZE 128 /* document images */ +#define OUTLINE_CHUNKSIZE 256 /* document outlines */ +#define NAMES_CHUNKSIZE 256 /* names */ +#define PDI_CHUNKSIZE 16 /* PDI instances */ +#define COLORSPACES_CHUNKSIZE 16 /* color spaces */ +#define PATTERN_CHUNKSIZE 4 /* pattern */ +#define SHADINGS_CHUNKSIZE 4 /* shadings */ +#define EXTGSTATE_CHUNKSIZE 4 /* external graphic states */ +#define T3GLYPHS_CHUNKSIZE 256 /* type 3 font glyph table */ +#define ICCPROFILE_CHUNKSIZE 4 /* ICC profiles */ +#define STRINGLISTS_CHUNKSIZE 128 /* document stringlists */ +#define ITEMS_CHUNKSIZE 256 /* PDFlib items */ +#define ITEMS_KIDS_CHUNKSIZE 64 /* PDFlib item's kids */ +#define ITEMS_MC_CHUNKSIZE 16 /* PDFlib item mc sequences */ +#define LAYER_DEP_CHUNKSIZE 16 /* PDFlib layer dependencies */ +#define RESLIST_CHUNKSIZE 16 /* per page resource list */ + +/* Acrobat 4 allows only 12 levels, but Acrobat 5 increases the limit to 28 */ +#define PDF_MAX_SAVE_LEVEL 28 /* max number of save levels */ + +#define PDF_MAX_PARAMSTRING 256 /* image parameter string */ +#define PDF_MAX_NAMESTRING 127 /* maximum name length */ +#define PDF_MAX_EVENTS 16 /* maximum number of events */ +#define PDF_MAX_DASHLENGTH 8 /* maximum number of dashes */ + +/* default PDF compatibility */ +#define PDF_DEF_COMPATIBILITY PDC_1_6 + + +/* ------------------------ typedefs and enums --------------------------- */ + +/* PDFlib error numbers. +*/ +#ifndef P_GENERR_H +enum +{ +#define pdf_genNames 1 +#include "p_generr.h" + + PDF_E_dummy +}; +#endif + +#define pdf_state_content \ + (pdf_state) (pdf_state_page | pdf_state_pattern | \ + pdf_state_template | pdf_state_glyph) + +#define pdf_state_all \ + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page | \ + pdf_state_pattern | pdf_state_template | pdf_state_path | \ + pdf_state_font | pdf_state_glyph) + +#define PDF_STATE_STACK_SIZE 4 + +/* function-like macros. +** must behave well wherever function calls are syntactically legal. +*/ +#define PDF_GET_STATE(p) \ + ((p)->state_stack[(p)->state_sp]) + +#define PDF_SET_STATE(p, s) \ + ((p)->state_stack[(p)->state_sp] = (s)) + +/* statement-like macros. +** must behave well wherever statements are syntactically legal. +*/ +#define PDF_CHECK_STATE(p, s) \ + if ((((p)->state_stack[(p)->state_sp] & (s)) != 0)) { \ + } else pdc_error((p)->pdc, \ + PDF_E_DOC_SCOPE, pdf_current_scope(p), 0, 0, 0) + +#define PDF_PUSH_STATE(p, fn, s) \ + if ((p)->state_sp == PDF_STATE_STACK_SIZE - 1) \ + pdc_error((p)->pdc, PDF_E_INT_SSTACK_OVER, fn, 0, 0, 0); \ + else \ + (p)->state_stack[++(p)->state_sp] = (s) + +#define PDF_POP_STATE(p, fn) \ + if ((p)->state_sp == 0) \ + pdc_error((p)->pdc, PDF_E_INT_SSTACK_UNDER, fn, 0, 0, 0); \ + else \ + --(p)->state_sp + + +/* -------------------------- structs ------------------------------ */ + +#ifndef PDI_DEFINED +#define PDI_DEFINED +typedef struct PDI_s PDI; /* The opaque PDI type */ +typedef struct pdi_pcos_s pdi_pcos; +typedef struct pdi_props_s pdi_props; +#endif + +typedef struct +{ + pdc_bool info_mode; + PDI * pi; + pdc_byte * data; + pdi_pcos * pcc; +} pdf_pdi; + +/* Opaque types which are detailed in the respective modules + in alphabetical order */ +typedef struct pdf_category_s pdf_category; +typedef struct pdf_colorspace_s pdf_colorspace; +typedef struct pdf_cstate_s pdf_cstate; +typedef struct pdf_dest_s pdf_dest; +typedef struct pdf_document_s pdf_document; +typedef struct pdf_extgstateresource_s pdf_extgstateresource; +typedef struct pdf_font_options_s pdf_font_options; +typedef struct pdf_font_s pdf_font; +typedef struct pdf_formfields_s pdf_formfields; +typedef struct pdf_iccprofile_s pdf_iccprofile; +typedef struct pdf_image_s pdf_image; +typedef struct pdf_info_s pdf_info; +typedef struct pdf_layers_s pdf_layers; +typedef struct pdf_linearopts_s pdf_linearopts; +typedef struct pdf_mbox_s pdf_mbox; +typedef struct pdf_name_s pdf_name; +typedef struct pdf_outline_s pdf_outline; +typedef struct pdf_pages_s pdf_pages; +typedef struct pdf_pattern_s pdf_pattern; +typedef struct pdf_reslist_s pdf_reslist; +typedef struct pdf_shading_s pdf_shading; +typedef struct pdf_t3font_s pdf_t3font; +typedef struct pdf_tags_s pdf_tags; +typedef struct pdf_text_options_s pdf_text_options; +typedef struct pdf_tstate_s pdf_tstate; +typedef struct pdf_widget_s pdf_widget; +typedef struct pdf_xobject_s pdf_xobject; + + +/* -------------------- special graphics state -------------------- */ +typedef struct { + pdc_matrix ctm; /* current transformation matrix */ + pdc_scalar x; /* current x coordinate */ + pdc_scalar y; /* current y coordinate */ + + pdc_scalar startx; /* starting x point of the subpath */ + pdc_scalar starty; /* starting y point of the subpath */ + + pdc_scalar lwidth; /* line width */ + int lcap; /* line cap style */ + int ljoin; /* line join style */ + pdc_scalar miter; /* miter limit */ + pdc_scalar flatness; /* path flatness */ + pdc_bool dashed; /* line dashing in effect */ +} pdf_gstate; + +/* ---------------------- page/pattern/template ----------------------- */ +typedef struct +{ + /* graphics, text, and color state. + */ + int sl; /* current save level */ + pdf_gstate gstate[PDF_MAX_SAVE_LEVEL]; /* graphics state */ + pdf_tstate *tstate; /* text state */ + pdf_cstate *cstate; /* color state */ + + pdf_text_options *currto; /* current text options */ + pdf_fillrule fillrule; /* nonzero or evenodd fill rule */ + + pdc_vtr * mboxes; /* matchbox chain */ + + /* in update mode, the resource numbers generally don't start + ** with 0, but with a bias value derived from the original + ** page's resources. + */ + int cs_bias; /* colorspaces */ + int eg_bias; /* extended gstates */ + int fn_bias; /* fonts */ + int pt_bias; /* patterns */ + int sh_bias; /* shadings */ + int xo_bias; /* xobjects */ +} pdf_ppt; + +/* Force graphics or color operator output, avoiding the optimization + * which checks whether the new value might be the same as the old. + * This is especially required for Type 3 glyph descriptions which + * inherit the surrounding page description's gstate parameters, + * and therefore even must write default values. + */ +#define PDF_FORCE_OUTPUT() (PDF_GET_STATE(p) == pdf_state_glyph) + +/* + * ************************************************************************* + * The core PDF context descriptor + * ************************************************************************* + */ + +struct PDF_s { + /* -------------------------- general stuff ------------------------ */ + unsigned long magic; /* poor man's integrity check */ + void (*freeproc)(PDF *p, void *mem); + pdc_core *pdc; /* core context */ + int compatibility; /* PDF version number * 10 */ + pdf_errpol errorpolicy; /* error policy */ + + + + + pdf_state state_stack[PDF_STATE_STACK_SIZE]; + int state_sp; /* state stack pointer */ + + /* ------------------- PDF Catalog dictionary --------------------- */ + pdf_document *document; /* document struct */ + + + /* ------------------- PDF Info dictionary entries ----------------- */ + pdf_info *userinfo; /* list of user-defined entries */ + + /* -------------- I/O, error handling and memory management ------------- */ + size_t (*writeproc)(PDF *p, void *data, size_t size); + void (*errorhandler)(PDF *p, int level, const char* msg); + void *opaque; /* user-specific, opaque data */ + + /* ------------------------- PDF import ---------------------------- */ + pdf_pdi *pdi; /* PDI context array */ + int pdi_capacity; /* currently allocated size */ + pdc_pagebox pdi_usebox; + pdc_bool pdi_strict; /* strict PDF parser mode */ + pdc_bstr * pdi_parmbuf; /* string buffer for pdi parms */ + + /* ------------ stuff for hypertext functions ---------- */ + pdc_encoding hypertextencoding; /* encoding of hypertexts */ + pdc_text_format hypertextformat; /* format of hypertexts */ + int hypertextcodepage; /* OEM multi byte code-page number */ + pdc_bool usercoordinates; /* interprete rectangle coordinates */ + /* of hypertext funcs. in user space */ + pdc_bool usehyptxtenc; /* use hypertextencoding */ + /* for name strings */ + + + /* ------------------- PDF output bookkeeping ------------------- */ + pdc_id procset_id; /* id of constant ProcSet array */ + pdc_output *out; /* output manager */ + pdc_id length_id; /* id of current stream's length*/ + pdc_flush_state flush; /* flush state */ + + /* ------------------- page bookkeeping ------------------- */ + pdf_pages *doc_pages; /* document wide page management */ + + /* ------------------- document resources ------------------- */ + pdf_font *fonts; /* all fonts in document */ + int fonts_capacity; /* currently allocated size */ + int fonts_number; /* next available font number */ + int t3slot; /* slot of temporary type 3 font */ + fnt_cmap_stack *cmst; /* CMap stack handle */ + + + + pdf_xobject *xobjects; /* all xobjects in document */ + int xobjects_capacity; /* currently allocated size */ + int xobjects_number; /* next available xobject slot */ + + pdf_colorspace *colorspaces; /* all color space resources */ + int colorspaces_capacity; /* currently allocated size */ + int colorspaces_number; /* next available color space number */ + + + pdf_pattern *pattern; /* all pattern resources */ + int pattern_capacity; /* currently allocated size */ + int pattern_number; /* next available pattern number */ + + pdf_shading *shadings; /* all shading resources */ + int shadings_capacity; /* currently allocated size */ + int shadings_number; /* next available shading number */ + + pdf_extgstateresource *extgstates; /* all ext. graphic state resources */ + int extgstates_capacity; /* currently allocated size */ + int extgstates_number; /* next available extgstate number */ + + pdf_image *images; /* all images in document */ + int images_capacity; /* currently allocated size */ + + pdc_vtr *actions; /* all actions in document */ + + + /* ------------------ utilities ------------------- */ + char ***stringlists; /* string lists */ + int stringlists_capacity; /* currently allocated size */ + int stringlists_number; /* next available string list number */ + int *stringlistsizes; /* sizes of string lists */ + int utilstrlist_index; /* index of utility string list */ + int utilstring_number; /* next available utility string */ + + /* ------------------- document outline tree ------------------- */ + pdf_outline *outlines; /* dynamic array of outlines */ + int outline_capacity; /* currently allocated size */ + int outline_count; /* total number of outlines */ + + /* ------------------- name tree ------------------- */ + pdf_name *names; /* page ids */ + int names_capacity; + int names_number; /* next available names number */ + + /* -------------- page/pattern/template specific stuff -------------- */ + pdf_ppt * curr_ppt; /* current ppt descriptor */ + pdc_id res_id; /* id of this pattern/templ res dict */ + + pdc_scalar ydirection; /* direction of y axis of default */ + /* system rel. to viewport (1 or -1) */ + + pdf_renderingintent rendintent; /* RenderingIntent */ + + pdc_bool preserveoldpantonenames;/* preserve old PANTONE names */ + pdc_bool spotcolorlookup; /* use internal look-up table for + * color values */ + + /* ------------------------ template stuff ----------------------- */ + int templ; /* current template if in templ. state*/ + + /* --------------- other font and text stuff ---------------- */ + + pdf_font_options *currfo; /* current font settings */ + + pdc_glyphcheck glyphcheck; /* check for unavailable glyphs */ + pdc_text_format textformat; /* text storage format */ + pdc_bool in_text; /* currently in BT/ET section */ + + /* ------------------------ miscellaneous ------------------------ */ + char debug[256]; /* debug flags */ + + + + /* ------- deprecated stuff because of deprecated parameter ---------- */ + pdf_borderstyle border_style; + pdc_scalar border_width; + pdc_scalar border_red; + pdc_scalar border_green; + pdc_scalar border_blue; + pdc_scalar border_dash1; + pdc_scalar border_dash2; + pdf_dest *bookmark_dest; + char *launchlink_parameters; + char *launchlink_operation; + char *launchlink_defaultdir; + +}; + +/* Data source for images, compression, ASCII encoding, fonts, etc. */ +typedef struct PDF_data_source_s PDF_data_source; +struct PDF_data_source_s { + pdc_byte *next_byte; + size_t bytes_available; + void (*init)(PDF *, PDF_data_source *src); + int (*fill)(PDF *, PDF_data_source *src); + void (*terminate)(PDF *, PDF_data_source *src); + + pdc_byte *buffer_start; + size_t buffer_length; + void *private_data; + long offset; /* start of data to read */ + long length; /* length of data to read */ + long total; /* total bytes read so far */ +}; + +/* ------ Private functions for library-internal use only --------- */ + + +/* + (((((OpenVMS porting note))))) + + Symbols are restricted to <= 31 bytes on OpenVMS systems.... + Please truncate new function names to fit this silly restriction! + + (((((OpenVMS porting note))))) +*/ + + + + + +/********************** + * + * p_actions.c + * + **********************/ + +int pdf__create_action(PDF *p, const char *type, const char *optlist); + +void pdf_delete_actions(PDF *p); +int pdf_get_max_action(PDF *p); +pdc_bool pdf_parse_and_write_actionlist(PDF *p, pdf_event_object eventobj, + pdc_id *act_idlist, const char *optlist); +pdc_bool pdf_write_action_entries(PDF *p, pdf_event_object eventobj, + pdc_id *act_idlist); + + +/********************** + * + * p_annots.c + * + **********************/ + +void pdf__add_launchlink(PDF *p, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, const char *filename); +void pdf__add_locallink(PDF *p, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, int page, const char *optlist); +void pdf__add_note(PDF *p, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, const char *contents, int len_cont, + const char *title, int len_title, const char *icon, int kopen); +void pdf__add_pdflink(PDF *p, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, const char *filename, int page, + const char *optlist); +void pdf__add_weblink(PDF *p, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, const char *url); +void pdf__attach_file(PDF *p, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, const char *filename, int len_filename, + const char *description, int len_descr, const char *author, + int len_auth, const char *mimetype, const char *icon); +void pdf__create_annotation(PDF *p, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, const char *type, const char *optlist); +void pdf__set_border_color(PDF *p, pdc_scalar red, pdc_scalar green, + pdc_scalar blue); +void pdf__set_border_dash(PDF *p, pdc_scalar b, pdc_scalar w); +void pdf__set_border_style(PDF *p, const char *style, pdc_scalar width); + +void pdf_init_annot_params(PDF *p); +void pdf_cleanup_annot_params(PDF *p); +pdc_id pdf_write_annots_root(PDF *p, pdc_vtr *annots, pdf_widget *widgetlist); +void pdf_write_page_annots(PDF *p, pdc_vtr *annots); + +void pdf_create_link(PDF *p, const char *type, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury, const char *annopts, + const char *utext, int len); + + + +/********************** + * + * p_color.c + * + **********************/ + + +void pdf__setcolor(PDF *p, const char *fstype, const char *colorspace, + pdc_scalar c1, pdc_scalar c2, pdc_scalar c3, pdc_scalar c4); + +void pdf_init_cstate(PDF *p); +void pdf_save_cstate(PDF *p); +void pdf_cleanup_page_cstate(PDF *p, pdf_ppt *ppt); +void pdf_init_colorspaces(PDF *p); +void pdf_set_default_color(PDF *p, pdc_bool reset); +void pdf_write_page_colorspaces(PDF *p); +void pdf_mark_page_colorspace(PDF *p, int n); +void pdf_write_doc_colorspaces(PDF *p); +void pdf_write_colorspace(PDF *p, int slot, pdc_bool direct); +void pdf_cleanup_colorspaces(PDF *p); +void pdf_write_colormap(PDF *p, int slot); + + +/********************** + * + * p_document.c + * + **********************/ + +int pdf__begin_document(PDF *p, const char *filename, int len, + const char *optlist); + +void pdf__begin_document_callback(PDF *p, writeproc_t writeproc, + const char *optlist); + +void pdf__end_document(PDF *p, const char *optlist); + +void pdf_cleanup_document(PDF *p); +void pdf_fix_openmode(PDF *p); +void pdf_insert_name(PDF *p, const char *name, pdf_nametree_type type, + pdc_id obj_id); +pdc_id pdf_get_id_from_nametree(PDF *p, pdf_nametree_type type, + const char *name); +char *pdf_parse_and_write_metadata(PDF *p, const char *optlist, pdc_bool output, + int *outlen); +pdc_off_t pdf_check_file(PDF *p, const char *filename, pdc_bool verbose); +void pdf_embed_file(PDF *p, pdc_id obj_id, const char *filename, + const char *mimetype, pdc_off_t filesize); + +/* deprecated functions: */ +void pdf_set_flush(PDF *p, const char *flush); +void pdf_set_uri(PDF *p, const char *uri); +void pdf_set_compatibility(PDF *p, const char *compatibility); +void pdf_set_openmode(PDF *p, const char *openmode); +void pdf_set_openaction(PDF *p, const char *openaction); +void pdf_set_viewerpreference(PDF *p, const char *viewerpreference); +const char *pdf__get_buffer(PDF *p, long *size); + + + + +/********************** + * + * p_draw.c + * + **********************/ + + +void pdf__arc(PDF *p, pdc_scalar x, pdc_scalar y, + pdc_scalar r, pdc_scalar alpha, pdc_scalar beta); +void pdf__arcn(PDF *p, pdc_scalar x, pdc_scalar y, + pdc_scalar r, pdc_scalar alpha, pdc_scalar beta); +void pdf__circle(PDF *p, pdc_scalar x, pdc_scalar y, pdc_scalar r); +void pdf__clip(PDF *p); +void pdf__closepath(PDF *p); +void pdf__closepath_fill_stroke(PDF *p); +void pdf__closepath_stroke(PDF *p); +void pdf__curveto(PDF *p, pdc_scalar x_1, pdc_scalar y_1, + pdc_scalar x_2, pdc_scalar y_2, pdc_scalar x_3, pdc_scalar y_3); +void pdf__endpath(PDF *p); +void pdf__fill(PDF *p); +void pdf__fill_stroke(PDF *p); +void pdf__lineto(PDF *p, pdc_scalar x, pdc_scalar y); +void pdf__rlineto(PDF *p, pdc_scalar x, pdc_scalar y); +void pdf__moveto(PDF *p, pdc_scalar x, pdc_scalar y); +void pdf__rcurveto(PDF *p, pdc_scalar x_1, pdc_scalar y_1, + pdc_scalar x_2, pdc_scalar y_2, pdc_scalar x_3, pdc_scalar y_3); +void pdf__rect(PDF *p, pdc_scalar x, pdc_scalar y, + pdc_scalar width, pdc_scalar height); +void pdf__rmoveto(PDF *p, pdc_scalar x, pdc_scalar y); +void pdf__stroke(PDF *p); + +void pdf_rrcurveto(PDF *p, pdc_scalar x_1, pdc_scalar y_1, + pdc_scalar x_2, pdc_scalar y_2, pdc_scalar x_3, pdc_scalar y_3); +void pdf_hvcurveto(PDF *p, pdc_scalar x_1, pdc_scalar x_2, + pdc_scalar y_2, pdc_scalar y_3); +void pdf_vhcurveto(PDF *p, pdc_scalar y_1, pdc_scalar x_2, + pdc_scalar y_2, pdc_scalar x_3); + + +/********************** + * + * p_encoding.c + * + **********************/ + +void pdf__encoding_set_char(PDF *p, const char *encoding, int slot, + const char *glyphname, int uv); + +pdc_encoding pdf_get_hypertextencoding_param(PDF *p, int *codepage); +pdc_encoding pdf_get_hypertextencoding(PDF *p, const char *encoding, + int *codepage, pdc_bool verbose); + + + + +/********************** + * + * p_filter.c + * + **********************/ + +int pdf_data_source_buf_fill(PDF *p, PDF_data_source *src); +void pdf_data_source_file_init(PDF *p, PDF_data_source *src); +int pdf_data_source_file_fill(PDF *p, PDF_data_source *src); +void pdf_data_source_file_terminate(PDF *p, PDF_data_source *src); +void pdf_copy_stream(PDF *p, PDF_data_source *src, pdc_bool compress); + + +/********************** + * + * p_font.c + * + **********************/ + +double pdf__info_font(PDF *p, int ifont, const char *keyword, + const char *optlist); +int pdf__load_font(PDF *p, const char *fontname, int len, + const char *encoding, const char *optlist); + +void pdf_init_font_options(PDF *p, pdf_font_options *fo); +void pdf_cleanup_font_curroptions(PDF *p); +void pdf_cleanup_font_options(PDF *p, pdf_font_options *fo); +void pdf_init_font(PDF *p, pdf_font *font, pdf_font_options *fo); +void pdf_cleanup_font(PDF *p, pdf_font *font); +void pdf_init_fonts(PDF *p); +void pdf_cleanup_fonts(PDF *p); +int pdf_insert_font(PDF *p, pdf_font *font); +void pdf_write_doc_fonts(PDF *p); +void pdf_write_page_fonts(PDF *p); +void pdf_get_page_fonts(PDF *p, pdf_reslist *rl); +void pdf_mark_page_font(PDF *p, int ft); + + +/********************** + * + * p_gstate.c + * + **********************/ + +void pdf__concat(PDF *p, pdc_scalar a, pdc_scalar b, pdc_scalar c, pdc_scalar d, + pdc_scalar e, pdc_scalar f); +void pdf__initgraphics(PDF *p); +void pdf__restore(PDF *p); +void pdf__rotate(PDF *p, pdc_scalar phi); +void pdf__save(PDF *p); +void pdf__scale(PDF *p, pdc_scalar sx, pdc_scalar sy); +void pdf__setdash(PDF *p, pdc_scalar b, pdc_scalar w); +void pdf__setdashpattern(PDF *p, const char *optlist); +void pdf__setflat(PDF *p, pdc_scalar flatness); +void pdf__setlinecap(PDF *p, int linecap); +void pdf__setlinejoin(PDF *p, int linejoin); +void pdf__setlinewidth(PDF *p, pdc_scalar width); +void pdf__setmatrix(PDF *p, pdc_scalar a, pdc_scalar b, pdc_scalar c, + pdc_scalar d, pdc_scalar e, pdc_scalar f); +void pdf__setmiterlimit(PDF *p, pdc_scalar miter); +void pdf__skew(PDF *p, pdc_scalar alpha, pdc_scalar beta); +void pdf__translate(PDF *p, pdc_scalar tx, pdc_scalar ty); + +void pdf_setmatrix_e(PDF *p, pdc_matrix *n); +void pdf_init_gstate(PDF *p); +void pdf_concat_raw(PDF *p, pdc_matrix *m); +void pdf_reset_gstate(PDF *p); +void pdf_set_topdownsystem(PDF *p, pdc_scalar height); +void pdf_setdashpattern_internal(PDF *p, pdc_scalar *darray, int length, + pdc_scalar phase); + + +/********************** + * + * p_hyper.c + * + **********************/ + +int pdf__add_bookmark(PDF *p, const char *text, int len, int parent, int open); +void pdf__add_nameddest(PDF *p, const char *name, int len, const char *optlist); +int pdf__create_bookmark(PDF *p, const char *text, int len, + const char *optlist); +void pdf__set_info(PDF *p, const char *key, const char *value, int len); + +pdf_dest *pdf_init_destination(PDF *p); +pdf_dest *pdf_parse_destination_optlist(PDF *p, const char *optlist, + int page, pdf_destuse destuse); +void pdf_cleanup_destination(PDF *p, pdf_dest *dest); +void pdf_write_destination(PDF *p, pdf_dest *dest); +pdf_dest *pdf_get_option_destname(PDF *p, pdc_resopt *resopts, + pdc_encoding hypertextencoding, int hypertextcodepage); +void pdf_init_outlines(PDF *p); +void pdf_write_outlines(PDF *p); +void pdf_write_outline_root(PDF *p); +void pdf_cleanup_outlines(PDF *p); +void pdf_feed_digest_info(PDF *p); +pdc_id pdf_write_info(PDF *p, pdc_bool moddate); +void pdf_cleanup_info(PDF *p); + + + + +/********************** + * + * p_image.c + * + **********************/ + +void pdf__add_thumbnail(PDF *p, int image); +void pdf__close_image(PDF *p, int image); +void pdf__fit_image(PDF *p, int image, pdc_scalar x, pdc_scalar y, + const char *optlist); +int pdf__load_image(PDF *p, const char *imagetype, const char *filename, + const char *optlist); + +void pdf_grow_images(PDF *p); +void pdf_put_image(PDF *p, int im, pdc_bool firststrip, + pdc_bool checkcontentstream); +void pdf_put_inline_image(PDF *p, int im); +void pdf_init_images(PDF *p); +void pdf_cleanup_images(PDF *p); +void pdf_cleanup_image(PDF *p, int im); +void pdf_get_image_size(PDF *p, int im, pdc_scalar *width, pdc_scalar *height); +void pdf_get_image_resolution(PDF *p, int im, pdc_scalar *dpi_x, + pdc_scalar *dpi_y); + + + + + + +/********************** + * + * p_mbox.c + * + **********************/ + +double pdf__info_matchbox(PDF *p, const char *boxname, int len, int num, + const char *keyword); + +pdc_vtr *pdf_new_mboxes(PDF *p, pdf_mbox *mbox, pdc_vtr *mboxes); +pdf_mbox *pdf_parse_mbox_optlist(PDF *p, const char *optlist); +pdf_mbox *pdf_get_mbox(PDF *p, pdc_vtr *mboxes, const char *name, int number, + int *o_count); +void pdf_delete_mbox(PDF *p, pdf_mbox *mbox); +void pdf_add_page_mbox(PDF *p, pdf_mbox *mbox); + +pdc_bool pdf_get_mbox_drawborder(PDF *p, pdf_mbox *mbox, int keycode); +void pdf_set_mbox_rectangle(PDF *p, pdf_mbox *mbox, pdc_rectangle *rect, + int flags); +void pdf_get_mbox_rectangle(PDF *p, pdf_mbox *mbox, pdc_vector *polyline); +void pdf_draw_mbox_rectangle(PDF *p, pdf_mbox *mbox, pdc_bool saverestore); +const char *pdf_get_usematchbox(PDF *p, const char *option, const char *optval, + int *istart, int *istop); + +void pdf_set_position_values(PDF *p, pdc_scalar *i_position, int nv); + + +/********************** + * + * p_object.c + * + **********************/ + +void pdf__delete(PDF *p); + +PDF *pdf__new(errorproc_t errorhandler, allocproc_t allocproc, + reallocproc_t reallocproc, freeproc_t freeproc, void *opaque); + +const char *pdf_current_scope(PDF *p); + + +/********************** + * + * p_page.c + * + **********************/ + +void pdf__begin_page(PDF *p, pdc_scalar width, pdc_scalar height); +void pdf__begin_page_ext(PDF *p, pdc_scalar width, pdc_scalar height, + const char *optlist); +void pdf__end_page_ext(PDF *p, const char *optlist); +void pdf__resume_page(PDF *p, const char *optlist); +void pdf__suspend_page(PDF *p, const char *optlist); +void pdf_pg_resume(PDF *p, int pageno); +void pdf_pg_suspend(PDF *p); + +void pdf_init_pages(PDF *p, const char **groups, int n_groups); +void pdf_init_pages2(PDF *p); +void pdf_check_suspended_pages(PDF *p); +void pdf_cleanup_pages(PDF *p); +pdc_id pdf_get_page_id(PDF *p, int n); +int pdf_current_page(PDF *p); +int pdf_current_page_id(PDF *p); +int pdf_last_page(PDF *p); +int pdf_search_page_fwd(PDF *p, int start_page, pdc_id id); +int pdf_search_page_bwd(PDF *p, int start_page, pdc_id id); +int pdf_xlat_pageno(PDF *p, int pageno, const char *groupname); + +double pdf_get_pageheight(PDF *p); +const pdc_rectangle *pdf_get_pagebox(PDF *p, pdf_pagebox box); +void pdf_set_pagebox_llx(PDF *p, pdf_pagebox box, pdc_scalar llx); +void pdf_set_pagebox_lly(PDF *p, pdf_pagebox box, pdc_scalar lly); +void pdf_set_pagebox_urx(PDF *p, pdf_pagebox box, pdc_scalar urx); +void pdf_set_pagebox_ury(PDF *p, pdf_pagebox box, pdc_scalar ury); +void pdf_set_pagebox(PDF *p, pdf_pagebox box, pdc_scalar llx, pdc_scalar lly, + pdc_scalar urx, pdc_scalar ury); + +pdc_vtr *pdf_get_annots_list(PDF *p); +void pdf_set_annots_list(PDF *p, pdc_vtr *annots); +pdc_id pdf_get_thumb_id(PDF *p); +void pdf_set_thumb_id(PDF *p, pdc_id id); + +void pdf_begin_contents_section(PDF *p); +void pdf_end_contents_section(PDF *p); +void pdf_add_reslist(PDF *p, pdf_reslist *rl, int num); +pdc_id pdf_write_pagelabels(PDF *p); + + + +/********************** + * + * p_parameter.c + * + **********************/ + +const char *pdf__get_parameter(PDF *p, const char *key, double modifier); +double pdf__get_value(PDF *p, const char *key, double modifier); +void pdf__set_parameter(PDF *p, const char *key, const char *value); +void pdf__set_value(PDF *p, const char *key, double value); + + +/********************** + * + * p_pattern.c + * + **********************/ + +int pdf__begin_pattern(PDF *p, + pdc_scalar width, pdc_scalar height, pdc_scalar xstep, pdc_scalar ystep, + int painttype); + +void pdf__end_pattern(PDF *p); + +void pdf_init_pattern(PDF *p); +void pdf_write_page_pattern(PDF *p); +void pdf_get_page_patterns(PDF *p, pdf_reslist *rl); +void pdf_mark_page_pattern(PDF *p, int n); +void pdf_cleanup_pattern(PDF *p); +void pdf_grow_pattern(PDF *p); + + + + +/********************** + * + * p_shading.c + * + **********************/ + +int pdf__shading(PDF *p, const char *shtype, pdc_scalar x_0, pdc_scalar y_0, + pdc_scalar x_1, pdc_scalar y_1, pdc_scalar c_1, pdc_scalar c_2, + pdc_scalar c_3, pdc_scalar c_4, const char *optlist); +int pdf__shading_pattern(PDF *p, int shading, const char *optlist); +void pdf__shfill(PDF *p, int shading); + +void pdf_init_shadings(PDF *p); +void pdf_write_page_shadings(PDF *p); +void pdf_get_page_shadings(PDF *p, pdf_reslist *rl); +void pdf_mark_page_shading(PDF *p, int n); +void pdf_cleanup_shadings(PDF *p); +int pdf_get_shading_painttype(PDF *p); + + + + + + +/********************** + * + * p_template.c + * + **********************/ + +int pdf__begin_template(PDF *p, pdc_scalar width, pdc_scalar height, + const char *optlist); +void pdf__end_template(PDF *p); +int pdf_embed_image(PDF *p, int im); + + +/********************** + * + * p_text.c + * + **********************/ + +void pdf__fit_textline(PDF *p, const char *text, int len, + pdc_scalar x, pdc_scalar y, const char *optlist); +double pdf__info_textline(PDF *p, const char *text, int len, + const char *keyword, const char *optlist); +void pdf__setfont(PDF *p, int font, pdc_scalar fontsize); +void pdf__set_text_pos(PDF *p, pdc_scalar x, pdc_scalar y); +void pdf__show_text(PDF *p, const char *text, int len, pdc_bool cont); +void pdf__xshow(PDF *p, const char *text, int len, + const pdc_scalar *xadvancelist); +int pdf__show_boxed(PDF *p, const char *text, int len, + pdc_scalar left, pdc_scalar top, pdc_scalar width, pdc_scalar height, + const char *hmode, const char *feature); +pdc_scalar pdf__stringwidth(PDF *p, const char *text, int len, + int font, pdc_scalar size); + +void pdf_init_tstate(PDF *p); +void pdf_cleanup_page_tstate(PDF *p, pdf_ppt *ppt); +void pdf_save_tstate(PDF *p); +void pdf_restore_currto(PDF *p); +void pdf_set_tstate(PDF *p, pdc_scalar value, pdf_text_optflags flag); +double pdf_get_tstate(PDF *p, pdf_text_optflags tflag); +void pdf_end_text(PDF *p); +void pdf_reset_tstate(PDF *p); +int pdf_get_font(PDF *p); +void pdf_put_fieldtext(PDF *p, const char *text, int font); +int pdf_get_fontsize_option(PDF *p, int font, pdc_resopt *resopts, + pdc_scalar *fontsize); + + + + + +/********************** + * + * p_type3.c + * + **********************/ + +void pdf__begin_font(PDF *p, const char *fontname, int len, + pdc_scalar a, pdc_scalar b, pdc_scalar c, pdc_scalar d, + pdc_scalar e, pdc_scalar f, const char *optlist); +void pdf__begin_glyph(PDF *p, const char *glyphname, pdc_scalar wx, + pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury); +void pdf__end_font(PDF *p); +void pdf__end_glyph(PDF *p); + +int pdf_get_t3colorized(PDF *p); + + +/********************** + * + * p_util.c + * + **********************/ + +const char *pdf__utf32_to_utf16(PDF *p, const char *utf32string, int len, + const char *ordering, int *outlen); +const char *pdf__utf16_to_utf8(PDF *p, const char *utf16string, int len, + int *outlen); +const char *pdf__utf8_to_utf16(PDF *p, const char *utf8string, + const char *ordering, int *outlen); + +void pdf_check_textformat(PDF *p, pdc_text_format textformat); +void pdf_check_hypertextformat(PDF *p, pdc_text_format hypertextformat); +void pdf_check_hypertextencoding(PDF *p, pdc_encoding hypertextencoding); +void pdf_put_pdfname(PDF *p, const char *name); +pdc_encoding pdf_get_hypertextencoding_opt(PDF *p, pdc_resopt *resopts, + int *codepage, pdc_bool verbose); +char *pdf_convert_hypertext_depr(PDF *p, const char *text, int len); +char *pdf_convert_hypertext(PDF *p, const char *text, int len, + pdc_text_format hypertextformat, pdc_encoding hypertextencoding, + int codepage, int *outlen, pdc_bool oututf8, pdc_bool verbose); +void pdf_put_hypertext(PDF *p, const char *text); +char *pdf_convert_name(PDF *p, const char *name, int len, int flags); +const char *pdf_convert_filename(PDF *p, const char *filename, int len, + const char *paramname, int flags); +void pdf_add_resource(PDF *p, const char *category, const char *resname); +void pdf_put_pdffilename(PDF *p, const char *text); +void pdf_check_handle(PDF *p, int value, pdc_opttype type); +void pdf_set_clientdata(PDF *p, pdc_clientdata *clientdata); +void pdf_init_stringlists(PDF *p); +int pdf_insert_stringlist(PDF *p, char **stringlist, int ns); +void pdf_cleanup_stringlists(PDF *p); +int pdf_insert_utilstring(PDF *p, const char *utilstring, pdc_bool kdup); +const char *pdf_get_utilstring(PDF *p, int i); +int pdf_get_opt_textlist(PDF *p, const char *keyword, pdc_resopt *resopts, + pdc_encoding enc, int codepage, pdc_bool ishypertext, + const char *fieldname, char **text, char ***textlist); +char *pdf_get_opt_utf8name(PDF *p, const char *keyword, pdc_resopt *resopts); +pdc_bool pdf_get_errorpolicy(PDF *p, pdc_resopt *resopts, pdc_bool verbose); + + +/********************** + * + * p_xgstate.c + * + **********************/ + +int pdf__create_gstate(PDF *p, const char *optlist); +void pdf__set_gstate(PDF *p, int gstate); + +void pdf_init_extgstates(PDF *p); +void pdf_write_page_extgstates(PDF *p); +void pdf_get_page_extgstates(PDF *p, pdf_reslist *rl); +void pdf_mark_page_extgstate(PDF *p, int n); +void pdf_write_doc_extgstates(PDF *p); +void pdf_cleanup_extgstates(PDF *p); +pdc_id pdf_get_gstate_id(PDF *p, int gstate); + + + + +#endif /* P_INTERN_H */ + + + + + diff --git a/src/pdflib/pdflib/p_jpeg.c b/src/pdflib/pdflib/p_jpeg.c new file mode 100644 index 0000000..467f282 --- /dev/null +++ b/src/pdflib/pdflib/p_jpeg.c @@ -0,0 +1,1560 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_jpeg.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * JPEG processing for PDFlib + * + */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +#ifndef PDF_JPEG_SUPPORTED + +pdc_bool +pdf_is_JPEG_file(PDF *p, pdc_file *fp) +{ + (void) p; + (void) fp; + + return pdc_false; +} + +int +pdf_process_JPEG_data( + PDF *p, + int imageslot) +{ + pdf_image *image = &p->images[imageslot]; + + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "JPEG", 0, 0, 0); + + return -1; +} + +/* CDPDF - added missing function */ +void +pdf_cleanup_jpeg(PDF *p, pdf_image *image) +{ + (void) p; + (void) image; +} + +#else + +#include "jinclude.h" +#include "jpeglib.h" + +/* + * The following enum is stolen from the IJG JPEG library + * Comments added by tm. + * This table contains far too many names since PDFlib + * is rather simple-minded about markers. + */ + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, /* baseline DCT */ + M_SOF1 = 0xc1, /* extended sequential DCT */ + M_SOF2 = 0xc2, /* progressive DCT */ + M_SOF3 = 0xc3, /* lossless (sequential) */ + + M_SOF5 = 0xc5, /* differential sequential DCT */ + M_SOF6 = 0xc6, /* differential progressive DCT */ + M_SOF7 = 0xc7, /* differential lossless */ + + M_JPG = 0xc8, /* JPEG extensions */ + M_SOF9 = 0xc9, /* extended sequential DCT */ + M_SOF10 = 0xca, /* progressive DCT */ + M_SOF11 = 0xcb, /* lossless (sequential) */ + + M_SOF13 = 0xcd, /* differential sequential DCT */ + M_SOF14 = 0xce, /* differential progressive DCT */ + M_SOF15 = 0xcf, /* differential lossless */ + + M_DHT = 0xc4, /* define Huffman tables */ + + M_DAC = 0xcc, /* define arithmetic conditioning table */ + + M_RST0 = 0xd0, /* restart */ + M_RST1 = 0xd1, /* restart */ + M_RST2 = 0xd2, /* restart */ + M_RST3 = 0xd3, /* restart */ + M_RST4 = 0xd4, /* restart */ + M_RST5 = 0xd5, /* restart */ + M_RST6 = 0xd6, /* restart */ + M_RST7 = 0xd7, /* restart */ + + M_SOI = 0xd8, /* start of image */ + M_EOI = 0xd9, /* end of image */ + M_SOS = 0xda, /* start of scan */ + M_DQT = 0xdb, /* define quantization tables */ + M_DNL = 0xdc, /* define number of lines */ + M_DRI = 0xdd, /* define restart interval */ + M_DHP = 0xde, /* define hierarchical progression */ + M_EXP = 0xdf, /* expand reference image(s) */ + + M_APP0 = 0xe0, /* application marker, used for JFIF */ + M_APP1 = 0xe1, /* application marker, used for Exif */ + M_APP2 = 0xe2, /* application marker, used for FlashPix* + * and ICC Profiles */ + M_APP3 = 0xe3, /* application marker */ + M_APP4 = 0xe4, /* application marker */ + M_APP5 = 0xe5, /* application marker */ + M_APP6 = 0xe6, /* application marker */ + M_APP7 = 0xe7, /* application marker */ + M_APP8 = 0xe8, /* application marker, used for SPIFF */ + M_APP9 = 0xe9, /* application marker */ + M_APP10 = 0xea, /* application marker */ + M_APP11 = 0xeb, /* application marker */ + M_APP12 = 0xec, /* application marker */ + M_APP13 = 0xed, /* application marker, used by Photoshop*/ + M_APP14 = 0xee, /* application marker, used by Adobe */ + M_APP15 = 0xef, /* application marker */ + + M_JPG0 = 0xf0, /* reserved for JPEG extensions */ + M_JPG13 = 0xfd, /* reserved for JPEG extensions */ + M_COM = 0xfe, /* comment */ + + M_TEM = 0x01 /* temporary use */ + +} JPEG_MARKER; + +#define JPEG_SEGLIST_CHUNKSIZE 64 +#define JPEG_MARKER_LEN 2 +#define JPEG_LENGTH_LEN 2 +#define JPEG_BUFSIZE 0xFFFF + +struct pdf_jpeg_segment_s +{ + long pos; /* position of segment */ + size_t length; /* length of segement in byte */ +}; + +static void +pdf_register_JPEG_segment(PDF *p, pdf_image *image, long pos, size_t length) +{ + static const char fn[] = "pdf_register_JPEG_segment"; + pdf_jpeg_info *jpeg = &image->info.jpeg; + size_t len; + + pdc_logg_cond(p->pdc, 5, trc_image, + "\t\tKeep segment, position = 0x%lX, length = 0x%lX(%ld)\n", + pos, length, length); + + while(length > 0) + { + len = length; + if (len > JPEG_BUFSIZE) + len = JPEG_BUFSIZE; + + if (jpeg->number >= jpeg->capacity) + { + if (jpeg->capacity == 0) + { + jpeg->capacity = JPEG_SEGLIST_CHUNKSIZE; + jpeg->seglist = (pdf_jpeg_segment *) pdc_malloc(p->pdc, + jpeg->capacity * sizeof(pdf_jpeg_segment), fn); + } + else + { + jpeg->capacity += JPEG_SEGLIST_CHUNKSIZE; + jpeg->seglist = (pdf_jpeg_segment *) pdc_realloc(p->pdc, + jpeg->seglist, jpeg->capacity* sizeof(pdf_jpeg_segment), fn); + } + } + jpeg->seglist[jpeg->number].pos = pos; + jpeg->seglist[jpeg->number].length = len; + jpeg->number++; + + length -= len; + pos += len; + } +} + +static void +pdf_data_source_JPEG_init(PDF *p, PDF_data_source *src) +{ + static const char fn[] = "pdf_data_source_JPEG_init"; + pdf_image *image; + pdf_jpeg_info *jpeg; + + image = (pdf_image *) src->private_data; + jpeg = &image->info.jpeg; + + jpeg->capacity = jpeg->number; + jpeg->number = 0; + + src->buffer_start = (pdc_byte *) pdc_malloc(p->pdc, JPEG_BUFSIZE, fn); + src->buffer_length = JPEG_BUFSIZE; +} + +static pdc_bool +pdf_data_source_JPEG_fill(PDF *p, PDF_data_source *src) +{ + pdf_image *image; + pdf_jpeg_info *jpeg; + size_t length; + long pos; + + (void) p; + + image = (pdf_image *) src->private_data; + jpeg = &image->info.jpeg; + + if (jpeg->number < jpeg->capacity) + { + pos = jpeg->seglist[jpeg->number].pos; + length = jpeg->seglist[jpeg->number].length; + jpeg->number++; + + pdc_fseek(image->fp, pos, SEEK_SET); + src->next_byte = src->buffer_start; + src->bytes_available = + pdc_fread(src->buffer_start, 1, length, image->fp); + } + else + { + src->bytes_available = 0; + } + + if (src->bytes_available == 0) + return pdc_false; + else + return pdc_true; +} + +static void +pdf_data_source_JPEG_terminate(PDF *p, PDF_data_source *src) +{ + pdc_free(p->pdc, (void *) src->buffer_start); +} + +/********************************************************************** + * + * Decompression data source routines for the case of + * reading JPEG data from a PDFlib virtual file in + * JPEG library - analogous to ../libs/jpeg/jdatasrc.c + * + **********************************************************************/ + +typedef struct +{ + struct jpeg_source_mgr pub; /* public fields */ + pdc_file *infile; + PDF *p; /* required for logging only */ + pdf_image *image; /* required for access to the filename */ +} +pdf_source_mgr; + +typedef pdf_source_mgr * pdf_src_ptr; + +static void +pdf_init_JPEG_source (j_decompress_ptr cinfo) +{ + (void) cinfo; +} + +static boolean +pdf_fill_JPEG_input_buffer (j_decompress_ptr cinfo) +{ + pdf_src_ptr src = (pdf_src_ptr) cinfo->src; + JOCTET *buffer; + size_t nbytes; + + buffer = (JOCTET *) pdc_freadall(src->infile, &nbytes, NULL); + + src->pub.next_input_byte = buffer; + src->pub.bytes_in_buffer = nbytes; + + return TRUE; +} + +static void +pdf_skip_JPEG_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + pdf_src_ptr src = (pdf_src_ptr) cinfo->src; + + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; +} + +static void +pdf_term_JPEG_source (j_decompress_ptr cinfo) +{ + (void) cinfo; +} + +static void +pdf_jpeg_pdcread_src(j_decompress_ptr cinfo, + PDF *p, pdc_file *infile, pdf_image *image) +{ + pdf_src_ptr src; + + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(pdf_source_mgr)); + + src = (pdf_src_ptr) cinfo->src; + src->pub.init_source = pdf_init_JPEG_source; + src->pub.fill_input_buffer = pdf_fill_JPEG_input_buffer; + src->pub.skip_input_data = pdf_skip_JPEG_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; + src->pub.term_source = pdf_term_JPEG_source; + src->infile = infile; + src->p = p; + src->image = image; + src->pub.bytes_in_buffer = 0; + src->pub.next_input_byte = NULL; +} + +/********************************************************************** + * + * Compression data destination routines for the case of + * emitting JPEG data to a open PDFlib PDF file in + * JPEG library - analogous to ../libs/jpeg/jdatadst.c + * + **********************************************************************/ + +typedef struct +{ + struct jpeg_destination_mgr pub; + PDF *p; + pdf_image *image; /* required for access to the filename */ + JOCTET *buffer; +} +pdf_destination_mgr; + +typedef pdf_destination_mgr * pdf_dest_ptr; + +#define OUTPUT_BUF_SIZE 4096 + +static void +pdf_init_JPEG_destination (j_compress_ptr cinfo) +{ + pdf_dest_ptr dest = (pdf_dest_ptr) cinfo->dest; + + dest->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + +static boolean +pdf_empty_JPEG_output_buffer (j_compress_ptr cinfo) +{ + pdf_dest_ptr dest = (pdf_dest_ptr) cinfo->dest; + + pdc_write(dest->p->out, dest->buffer, OUTPUT_BUF_SIZE); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + +static void +pdf_term_JPEG_destination (j_compress_ptr cinfo) +{ + pdf_dest_ptr dest = (pdf_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + if (datacount) + pdc_write(dest->p->out, dest->buffer, datacount); +} + +static void +pdf_jpeg_pdcwrite_dest(j_compress_ptr cinfo, PDF *p, pdf_image *image) +{ + pdf_dest_ptr dest; + + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(pdf_destination_mgr)); + + dest = (pdf_dest_ptr) cinfo->dest; + dest->pub.init_destination = pdf_init_JPEG_destination; + dest->pub.empty_output_buffer = pdf_empty_JPEG_output_buffer; + dest->pub.term_destination = pdf_term_JPEG_destination; + dest->p = p; + dest->image = image; +} + +/**********************************************************************/ + +#define PDF_JMSG_LENGTH_MAX 200 + +/* + * Private replacements for libjpeg's error message function. + * They serve two purposes: + * - avoid libjpeg writing to stderr + * - write the message to the log file if logging is enabled + * One function is required for each source and destination. + */ + +static void +pdf_output_message_src(j_common_ptr cinfo) +{ + char buffer[PDF_JMSG_LENGTH_MAX]; + + /* we use this method only for decompression objects */ + j_decompress_ptr cinfo2 = (j_decompress_ptr) cinfo; + pdf_source_mgr *src = (pdf_source_mgr *) cinfo2->src; + + if (!pdc_logg_is_enabled(src->p->pdc, 5, trc_image)) + return; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + + pdc_logg(src->p->pdc, "\tlibjpeg src: %s\n", buffer); +} + +static void +pdf_output_message_dst(j_common_ptr cinfo) +{ + char buffer[PDF_JMSG_LENGTH_MAX]; + + /* we use this method only for compression objects */ + j_compress_ptr cinfo2 = (j_compress_ptr) cinfo; + pdf_destination_mgr *dst = (pdf_destination_mgr *) cinfo2->dest; + + if (!pdc_logg_is_enabled(dst->p->pdc, 5, trc_image)) + return; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + + pdc_logg(dst->p->pdc, "\tlibjpeg dst: %s\n", buffer); +} + +/* + * Private replacements for libjpeg's error_exit function. + * They serve three purposes: + * - avoid libjpeg exiting + * - write a message to the log file if logging is enabled + * - return control from libjpeg by raising an exception + * One function is required for each source and destination. + */ + +static void +pdf_error_exit_src(j_common_ptr cinfo) +{ + PDF *p; + pdf_image *image; + char buffer[PDF_JMSG_LENGTH_MAX]; + + /* we use this method only for decompression objects */ + j_decompress_ptr cinfo2 = (j_decompress_ptr) cinfo; + pdf_source_mgr *src = (pdf_source_mgr *) cinfo2->src; + + p = src->p; + image = src->image; + + (*cinfo->err->output_message) (cinfo); + (*cinfo->err->format_message) (cinfo, buffer); + + if (pdc_logg_is_enabled(p->pdc, 5, trc_image)) + pdc_logg(p->pdc, "\tlibjpeg (src) called error_exit routine\n"); + + /* clean up libjpeg */ + jpeg_destroy(cinfo); + + pdc_error(p->pdc, PDF_E_JPEG_TRANSCODE, + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, image->filename), + buffer, 0, 0); +} + +static void +pdf_error_exit_dst(j_common_ptr cinfo) +{ + PDF *p; + pdf_image *image; + char buffer[PDF_JMSG_LENGTH_MAX]; + + /* we use this method only for compression objects */ + j_compress_ptr cinfo2 = (j_compress_ptr) cinfo; + pdf_destination_mgr *dst = (pdf_destination_mgr *) cinfo2->dest; + + p = dst->p; + image = dst->image; + + (*cinfo->err->output_message) (cinfo); + (*cinfo->err->format_message) (cinfo, buffer); + + if (pdc_logg_is_enabled(p->pdc, 5, trc_image)) + pdc_logg(p->pdc, "\tlibjpeg (dst) called error_exit routine\n"); + + /* clean up libjpeg */ + jpeg_destroy(cinfo); + + pdc_error(p->pdc, PDF_E_JPEG_TRANSCODE, + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, image->filename), + buffer, 0, 0); +} + +static pdc_bool +pdf_data_source_JPEG_fill_transcode(PDF *p, PDF_data_source *src) +{ + pdf_image *image = (pdf_image *) src->private_data; + pdc_bool logg5 = pdc_logg_is_enabled(p->pdc, 5, trc_image); + + struct jpeg_decompress_struct srcinfo; + struct jpeg_compress_struct dstinfo; + jvirt_barray_ptr * src_coef_arrays; + struct jpeg_error_mgr jsrcerr, jdsterr; + + /* ---------- Setup for decompression ---------- */ + /* Initialize the JPEG decompression object with default error handling. */ + srcinfo.err = jpeg_std_error(&jsrcerr); + + /* Hook up our own message handler for logging */ + srcinfo.err->output_message = pdf_output_message_src; + + /* Hook up our own fatal error handler */ + srcinfo.err->error_exit = pdf_error_exit_src; + + /* Extended libjpeg tracing if PDFlib logging is enabled */ + if (logg5) + srcinfo.err->trace_level = 5; + + jpeg_create_decompress(&srcinfo); + + /* Specify data source for decompression analogous to jpeg_stdio_src */ + pdf_jpeg_pdcread_src(&srcinfo, p, image->fp, image); + + /* ---------- Setup for compression ---------- */ + /* Initialize the JPEG compression object with default error handling. */ + dstinfo.err = jpeg_std_error(&jdsterr); + + /* Hook up our own message handler for logging */ + dstinfo.err->output_message = pdf_output_message_dst; + + /* Hook up our own fatal error handler */ + dstinfo.err->error_exit = pdf_error_exit_dst; + + /* Extended libjpeg tracing if PDFlib logging is enabled */ + if (logg5) + dstinfo.err->trace_level = 5; + + jpeg_create_compress(&dstinfo); + + PDC_TRY(p->pdc) + { + /* ---------- start transcoding ---------- */ + + /* Read file header */ + if (jpeg_read_header(&srcinfo, TRUE) != JPEG_HEADER_OK) + { + if (logg5) + pdc_logg(p->pdc, "\tlibjpeg couldn't read header\n"); + + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "JPEG", + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, + image->filename), 0, 0); + } + + /* Read source file as DCT coefficients */ + src_coef_arrays = jpeg_read_coefficients(&srcinfo); + if (src_coef_arrays == NULL) + { + if (logg5) + pdc_logg(p->pdc, "\tlibjpeg couldn't read coefficients\n"); + + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "JPEG", + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, + image->filename), 0, 0); + } + + /* Initialize destination compression parameters from source values */ + jpeg_copy_critical_parameters(&srcinfo, &dstinfo); + + /* Specify data destination for compression analogous to + * jpeg_stdio_dest + */ + pdf_jpeg_pdcwrite_dest(&dstinfo, p, image); + + /* Start compressor (note no image data is actually written here) */ + jpeg_write_coefficients(&dstinfo, src_coef_arrays); + + /* Finish compression */ + /* DON'T change the order! */ + jpeg_finish_compress(&dstinfo); + (void) jpeg_finish_decompress(&srcinfo); + } + PDC_CATCH(p->pdc) + { + image->corrupt = pdc_true; + } + + /* Release memory */ + jpeg_destroy_compress(&dstinfo); + jpeg_destroy_decompress(&srcinfo); + + /* All done. Check for errors */ + if (jsrcerr.num_warnings != 0 && logg5) + { + /* + * We don't really care about problems in the input since + * they will be fixed by transcoding. Log them, but don't throw an + * exception. + */ + pdc_logg(p->pdc, + "\tlibjpeg total: %d corrupt data warning(s)\n", + jsrcerr.num_warnings); + } + + if (jdsterr.num_warnings != 0) + { + char buffer[PDF_JMSG_LENGTH_MAX]; + + /* + * Errors in the output are rare, but fatal. Log them, + * and unconditionally throw an exception. + */ + if (logg5) + { + pdc_logg(p->pdc, "\tlibjpeg: %d warning(s) for output\n", + jdsterr.num_warnings); + } + + (dstinfo.err->format_message) ((j_common_ptr) &dstinfo, buffer); + pdc_set_errmsg(p->pdc, PDF_E_JPEG_TRANSCODE, + pdf_get_image_filename(p, image), buffer, 0, 0); + + image->corrupt = pdc_true; + } + + return pdc_false; +} + +static pdc_ushort +get_ushort(pdc_file *fp) +{ + pdc_byte c[2]; + + c[0] = (pdc_byte) pdc_fgetc(fp); + c[1] = (pdc_byte) pdc_fgetc(fp); + + return pdc_get_be_ushort(c); +} + +#define CHECK_LENGTH 1024L + +pdc_bool +pdf_is_JPEG_file(PDF *p, pdc_file *fp) +{ + long pos = 0L; + int c; + long start = (long) pdc_ftell(fp); + long check_length = start + CHECK_LENGTH; + + pdc_logg_cond(p->pdc, 1, trc_image, "\tChecking image type JPEG...\n"); + +#if !defined(MVS) || !defined(I370) + /* Tommy's special trick for Macintosh JPEGs: simply skip some */ + /* hundred bytes at the beginning of the file! */ + do + { + do /* skip if not FF */ + { + c = pdc_fgetc(fp); + pos++; + + } + while (!pdc_feof(fp) && c != 0xFF && pos < check_length); + + if (pdc_feof(fp) || pos >= check_length) + { + pdc_fseek(fp, start, SEEK_SET); + return pdc_false; + } + + do /* skip repeated FFs */ + { + c = pdc_fgetc(fp); + pos++; + } + while (c == 0xFF && pos < check_length); + + /* remember start position */ + pos = (pdc_off_t1) pdc_ftell(fp); + if (pos < 0L || pos >= check_length) + { + pdc_fseek(fp, start, SEEK_SET); + return pdc_false; + } + + pos -= JPEG_MARKER_LEN; /* subtract marker length */ + + if (c == M_SOI) + { + pdc_fseek(fp, pos, SEEK_SET); + break; + } + } + while (!pdc_feof(fp)); +#endif /* !MVS || !I370 */ + +#define BOGUS_LENGTH 768 + /* If we are that far from the start we consider the image as damaged if: + * - OJPEG-TIFF: it does not start at the alleged data offset + * - any other flavor: it has too much garbage at the beginning + */ + if (pdc_feof(fp) || pos > (start ? start : BOGUS_LENGTH)) + { + pdc_fseek(fp, start, SEEK_SET); + return pdc_false; + } + + return pdc_true; +} + +/* This function should be moved to p_color.c once it gets used by other + * image modules as well. + */ + +static void +pdf_log_colorspace(PDF *p, int slot) +{ + pdf_colorspace *cs; + + if (slot < 0 || slot >= p->colorspaces_number) + { + pdc_logg(p->pdc, " Bad color space slot %d", slot); + } + + cs = &p->colorspaces[slot]; + + switch (cs->type) { + case DeviceGray: + pdc_logg(p->pdc, "/DeviceGray"); + break; + + case DeviceRGB: + pdc_logg(p->pdc, "/DeviceRGB"); + break; + + case DeviceCMYK: + pdc_logg(p->pdc, "/DeviceCMYK"); + break; + + + case Indexed: + pdc_logg(p->pdc, "/Indexed"); + break; + + case PatternCS: + pdc_logg(p->pdc, "/Pattern"); + break; + + default: + pdc_logg(p->pdc, "%d (unknown)", cs->type); + } +} + +/* open JPEG image and analyze marker */ +int +pdf_process_JPEG_data( + PDF *p, + int imageslot) +{ + int c, unit; + unsigned long length, len = 0, slen; +#define APP_MAX 255 + pdc_byte appstring[APP_MAX]; + const char *filename = NULL; + pdc_bool ismem = pdc_false; + void *filebase = NULL; + size_t filelen; + pdf_image *image; + int transform = 0; + pdc_bool marker_found = pdc_false; + pdc_bool markers_done = pdc_false; + pdc_bool need_transcode = pdc_false; + pdc_bool logg5 = pdc_logg_is_enabled(p->pdc, 5, trc_image); + long pos = 0, endpos = 0; + long adobe_pos = 0, adobe_len = 0; + int errint = 0; + int errcode = 0; + + image = &p->images[imageslot]; + image->compression = pdf_comp_dct; + image->use_raw = pdc_true; + image->info.jpeg.virtfile = NULL; + image->info.jpeg.seglist = NULL; + image->info.jpeg.capacity = 0; + image->info.jpeg.number = 0; + + need_transcode = !image->passthrough; + + if (logg5) + { + pdc_logg(p->pdc, "\tjpegoptimize = %s\n", + image->jpegoptimize ? "true" : "false"); + if (need_transcode) + pdc_logg(p->pdc, "\ttranscoding...\n"); + else + pdc_logg(p->pdc, "\ttranscoding disabled by passthrough option\n"); + } + + /* jpeg file not available */ + if (image->reference != pdf_ref_direct) + { + + + image->in_use = pdc_true; /* mark slot as used */ + pdf_put_image(p, imageslot, pdc_true, pdc_true); + return imageslot; + } + + if (!pdc_file_isvirtual(image->fp)) + { + /* read whole file */ + filebase = (void *) pdc_freadall(image->fp, &filelen, &ismem); + if (filebase == NULL) + { + errcode = PDC_E_IO_READ; + goto PDF_JPEG_ERROR; + } + pdc_fclose(image->fp); + + /* temporary memory */ + pdc_insert_mem_tmp(p->pdc, filebase, 0, 0); + + /* create virtual image file */ + filename = "__jpeg__image__data__"; + pdc__create_pvf(p->pdc, filename, filebase, filelen, ""); + image->info.jpeg.virtfile = filename; + + if (logg5) + { + pdc_logg(p->pdc, "\tVirtual file created, " + "length = 0x%lX(%ld)\n", filelen, filelen); + } + + /* open virtual file */ + image->fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "", + PDC_FILE_BINARY); + } + + if (image->info.jpeg.jpegifoffset) + { + /* Just to be sure: if we were handed a OJPEG-compressed TIFF with + * an offset we let libjpeg transcode. + */ + need_transcode = pdc_true; + + if (logg5) + { + pdc_logg(p->pdc, + "\ttranscoding because of OJPEG-compressed TIFF\n"); + pdc_logg(p->pdc, + "\tseeking to base offset 0x%lX(%ld) (TIFF with OJPEG)\n", + image->info.jpeg.jpegifoffset, image->info.jpeg.jpegifoffset); + } + pdc_fseek(image->fp, image->info.jpeg.jpegifoffset, SEEK_SET); + } + + if (pdf_is_JPEG_file(p, image->fp) == pdc_false) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_JPEG_ERROR; + } + + /* JPEG marker loop */ + while (1) + { + /* look for next JPEG Marker */ + if (!markers_done) + { + do /* repeat if FF/00 */ + { + do /* skip to FF */ + { + if (pdc_feof(image->fp)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_JPEG_ERROR; + } + c = pdc_fgetc(image->fp); + } + while (c != 0xFF); + + do /* skip repeated FFs */ + { + if (pdc_feof(image->fp)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_JPEG_ERROR; + } + c = pdc_fgetc(image->fp); + } + while (c == 0xFF); + } + while (c == 0); + + /* start of new segment */ + pos = (pdc_off_t1) pdc_ftell(image->fp) - JPEG_MARKER_LEN; + + /* skip garbage at the start of image data */ + if (!marker_found && pos > 0) + { + if (logg5 && pos > (long) image->info.jpeg.jpegifoffset) + { + pdc_logg(p->pdc, "\t0x%lX(%ld) bytes garbage " + "at start of image\n", pos, pos); + } + + /* we must create a new virtual file */ + if (image->info.jpeg.virtfile == 0) + { + /* read whole file */ + filebase = (void *) pdc_freadall(image->fp, + &filelen, &ismem); + if (filebase == NULL) + { + errcode = PDC_E_IO_READ; + goto PDF_JPEG_ERROR; + } + + /* temporary memory */ + pdc_insert_mem_tmp(p->pdc, filebase, 0, 0); + + filename = "__jpeg__image__data__"; + } + else + { + /* delete virtual file */ + pdc__delete_pvf(p->pdc, image->info.jpeg.virtfile); + } + + /* [re]create virtual file */ + filelen -= pos; + memmove(filebase, (char *) filebase + pos, filelen); + pdc__create_pvf(p->pdc, filename, filebase, filelen, ""); + image->info.jpeg.virtfile = filename; + + if (logg5) + { + pdc_logg(p->pdc, "\tVirtual file created, " + "length = 0x%lX(%ld)\n", + filelen, filelen); + } + /* [re]open virtual file */ + pdc_fclose(image->fp); + image->fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "", + PDC_FILE_BINARY); + + /* restart with the cleaned file */ + continue; + } + length = 0; + marker_found = pdc_true; + } + else + { + /* enforcing end of image */ + pos = (pdc_off_t1) pdc_ftell(image->fp); + pdc_fseek(image->fp, 0L, SEEK_END); + endpos = (pdc_off_t1) pdc_ftell(image->fp) - JPEG_MARKER_LEN; + length = endpos - pos; + c = M_EOI; + } + + /* analyzing JPEG Marker */ + switch (c) + { + /* markers which are not supported in PDF 1.3 and above */ + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + case M_SOF9: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + { + if (logg5) + { + pdc_logg(p->pdc, "\tMarker 0x%X(SOF%d) found - " + "not supported\n", c, c - M_SOF0); + } + errint = c; + errcode = PDF_E_JPEG_COMPRESSION; + } + goto PDF_JPEG_ERROR; + + /* markers without any parameters */ + case M_SOI: + case M_TEM: + case M_EOI: + case M_RST0: + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + { + if (logg5) + { + pdc_logg(p->pdc, "\tMarker 0x%X", c); + if (c == M_EOI) + pdc_logg(p->pdc, "(EOI)"); + pdc_logg(p->pdc, " found - no contents\n"); + } + pdf_register_JPEG_segment(p, image, pos, + (size_t) (length + JPEG_MARKER_LEN)); + } + break; + + /* skip segment if jpegoptimize = true, otherwise keep */ + case M_APP0: + case M_APP1: + case M_APP2: + case M_APP3: + case M_APP4: + case M_APP5: + case M_APP6: + case M_APP7: + case M_APP8: + case M_APP9: + case M_APP10: + case M_APP11: + case M_APP12: + case M_APP13: + case M_APP14: + case M_APP15: + case M_COM: + { + if (logg5) + { + pdc_logg(p->pdc, "\tMarker 0x%X", c); + if (c == M_COM) + pdc_logg(p->pdc, "(COM) found\n"); + else + pdc_logg(p->pdc, "(APP%d) found\n", c - M_APP0); + } + + length = get_ushort(image->fp); + if (!image->jpegoptimize) + pdf_register_JPEG_segment(p, image, pos, + (size_t) (length + JPEG_MARKER_LEN)); + else if (logg5) + pdc_logg(p->pdc, "\t\tSkip segment, position=0x%lX, " + "length=0x%lX(%ld)\n", + pos, length, length); + + /* We may have to register the Adobe marker later */ + if (c == M_APP14) + { + adobe_pos = pos; + adobe_len = length; + } + + length -= JPEG_LENGTH_LEN; + } + break; + + /* keep segment unconditionally */ + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF10: + case M_SOS: + default: + { + if (logg5) + { + pdc_logg(p->pdc, "\tMarker 0x%X", c); + if (c == M_SOS) + pdc_logg(p->pdc, "(SOS) found\n"); + else if (c <= M_SOF15) + pdc_logg(p->pdc, "(SOF%d) found\n", c - M_SOF0); + else + pdc_logg(p->pdc, " found\n"); + } + + length = get_ushort(image->fp); + pdf_register_JPEG_segment(p, image, pos, + (size_t) (length + JPEG_MARKER_LEN)); + length -= JPEG_LENGTH_LEN; + } + break; + } + + /* end of image */ + if (c == M_EOI) + { + if (logg5) + { + pdc_logg(p->pdc, "\tEnd of image\n"); + } + break; + } + + /* processing JPEG Marker */ + switch (c) + { + /* check for frame header markers */ + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF10: + { + int comp; + + image->bpc = pdc_fgetc(image->fp); + image->height = (pdc_scalar) get_ushort(image->fp); + image->width = (pdc_scalar) get_ushort(image->fp); + image->components = pdc_fgetc(image->fp); + length -= 6; + + for (comp=0; compcomponents; comp++) + { + pdc_byte b; + + /* We don't support more than 4 components */ + if (comp==JPEG_MAX_COMPS) break; + + image->info.jpeg.id[comp] = pdc_fgetc(image->fp); + b = pdc_fgetc(image->fp); + image->info.jpeg.hsamp[comp] = (b >> 4) & 0x0F; + image->info.jpeg.vsamp[comp] = b & 0x0F; + image->info.jpeg.table[comp] = pdc_fgetc(image->fp); + length -= 3; + } + + /* + * No need to read more markers since multiscan detection + * not required for single-component images. + */ + if (image->components == 1) + markers_done = pdc_true; + + if (logg5) + { + pdc_logg(p->pdc, "\t\tbpc = %d\n", image->bpc); + pdc_logg(p->pdc, "\t\theight = %g\n", image->height); + pdc_logg(p->pdc, "\t\twidth = %g\n", image->width); + pdc_logg(p->pdc, "\t\tcomponents = %d\n", + image->components); + + for (comp=0; compcomponents; comp++) + { + if (comp==JPEG_MAX_COMPS) + { + pdc_logg(p->pdc, "\t\tMore components found\n"); + break; + } + + if (pdc_logg_isprint((int) image->info.jpeg.id[comp])) + { + pdc_logg(p->pdc, + "\t\tcomponent 0x%x (name='%c'): " + "%dhx%dv table=%d\n", + image->info.jpeg.id[comp], + image->info.jpeg.id[comp], + image->info.jpeg.hsamp[comp], + image->info.jpeg.vsamp[comp], + image->info.jpeg.table[comp]); + } + else + { + pdc_logg(p->pdc, + "\t\tcomponent 0x%x: %dhx%dv table=%d\n", + image->info.jpeg.id[comp], + image->info.jpeg.hsamp[comp], + image->info.jpeg.vsamp[comp], + image->info.jpeg.table[comp]); + } + } + } + } + break; + + /* check for JFIF marker with resolution */ + case M_APP0: + { + len = MIN(APP_MAX, length); + if (!PDC_OK_FREAD(image->fp, appstring, len)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_JPEG_ERROR; + } + length -= len; + + /* Check for JFIF application marker and read density values + * per JFIF spec version 1.02. + */ + +#define PDF_STRING_JFIF "\x4A\x46\x49\x46" + + slen = strlen(PDF_STRING_JFIF); + if (len > slen && + !strncmp(PDF_STRING_JFIF, (char *) appstring, slen)) + { + /* resolution unit and resolution */ + unit = appstring[7]; + image->dpi_x = (pdc_scalar) + pdc_get_be_ushort(&appstring[8]); + image->dpi_y = (pdc_scalar) + pdc_get_be_ushort(&appstring[10]); + +#define JFIF_ASPECT_RATIO 0 /* JFIF unit byte: aspect ratio only */ +#define JFIF_DOTS_PER_INCH 1 /* JFIF unit byte: dots per inch */ +#define JFIF_DOTS_PER_CM 2 /* JFIF unit byte: dots per cm */ + + switch (unit) + { + case JFIF_DOTS_PER_INCH: + break; + + case JFIF_DOTS_PER_CM: + image->dpi_x *= 100 * PDC_INCH2METER; + image->dpi_y *= 100 * PDC_INCH2METER; + break; + + case JFIF_ASPECT_RATIO: + image->dpi_x *= -1; + image->dpi_y *= -1; + break; + + /* unknown ==> ignore */ + default: + break; + } + + if (logg5) + { + pdc_logg(p->pdc, "\t\tJFIF marker found\n"); + pdc_logg(p->pdc, "\t\tJFIF density unit: %d", unit); + + switch (unit) + { + case JFIF_DOTS_PER_INCH: + pdc_logg(p->pdc, " (inch)\n"); + break; + + case JFIF_DOTS_PER_CM: + pdc_logg(p->pdc, " (cm)\n"); + break; + + case JFIF_ASPECT_RATIO: + pdc_logg(p->pdc, " (aspect ratio)\n"); + break; + + default: + pdc_logg(p->pdc, " (unknown; ignored)\n"); + break; + } + pdc_logg(p->pdc, "\t\tJFIF x resolution = %g\n", + image->dpi_x); + pdc_logg(p->pdc, "\t\tJFIF y resolution = %g\n", + image->dpi_y); + } + } + } + break; + + + /* check for Adobe marker */ + case M_APP14: + { + len = MIN(APP_MAX, length); + if (!PDC_OK_FREAD(image->fp, appstring, len)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_JPEG_ERROR; + } + length -= len; + + /* + * Check for Adobe application marker. It is known + * (per Adobe's TN5116) + * to contain the string "Adobe" at the start + * of the APP14 marker. + */ + +#define PDF_STRING_Adobe "\x41\x64\x6F\x62\x65" + + slen = strlen(PDF_STRING_Adobe); + if (len > slen && + !strncmp(PDF_STRING_Adobe, (char *) appstring, slen)) + { + if (logg5) + { + pdc_byte *val = appstring+slen; + + pdc_logg(p->pdc, "\t\tAdobe marker found\n"); + + if (len >= 12) + { + pdc_logg(p->pdc, "\t\tversion = 0x%02X 0x%02X\n", + (unsigned char) val[0], (unsigned char) val[1]); + pdc_logg(p->pdc, "\t\tflags0 = 0x%02X 0x%02X\n", + (unsigned char) val[2], (unsigned char) val[3]); + pdc_logg(p->pdc, "\t\tflags1 = 0x%02X 0x%02X\n", + (unsigned char) val[4], (unsigned char) val[5]); + pdc_logg(p->pdc, "\t\tcolor transform = 0x%02X\n", + val[6]); + } + } + if (len >= 12) + transform = appstring[slen+6]; + + /* Keep Adobe marker for transform == 2 (YCCK) */ + if (transform == 2) + { + if (logg5) + pdc_logg(p->pdc, + "\t\tYCCK color space: Keep Adobe marker\n"); + + pdf_register_JPEG_segment(p, image, + adobe_pos, (size_t) (adobe_len + JPEG_MARKER_LEN)); + } + } + } + break; + + /* check for start of scan marker */ + case M_SOS: + { + pdc_byte comps = pdc_fgetc(image->fp); + length -= 1; + + if (logg5) + { + pdc_logg(p->pdc, "\t\tNumber of components in scan = " + "%d\n", comps); + } + + /* + * If the scan doesn't contain all components it must be + * a multiscan image, which doesn't work in Acrobat. + */ + + if (comps < image->components) + { + need_transcode = pdc_true; + if (logg5) + { + pdc_logg(p->pdc, + "\ttranscoding because of multiscan\n"); + } + } + + markers_done = pdc_true; + } + break; + + default: + break; + } + + /* jump to the next marker */ + if (length > 0) + { + if (pdc_fseek(image->fp, (long) length, SEEK_CUR) == -1) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_JPEG_ERROR; + } + } + } + + /* do some sanity checks with the parameters */ + if (image->height <= 0 || image->width <= 0 || image->components <= 0) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_JPEG_ERROR; + } + + if (image->bpc != 8) + { + errint = image->bpc; + errcode = PDF_E_IMAGE_BADDEPTH; + goto PDF_JPEG_ERROR; + } + + { + switch (image->components) { + case 1: + /* spot color may have been applied */ + if (image->colorspace == pdc_undef) + image->colorspace = DeviceGray; + break; + + case 3: + image->colorspace = DeviceRGB; + break; + + case 4: + image->colorspace = DeviceCMYK; + break; + + default: + errint = image->components; + errcode = PDF_E_IMAGE_BADCOMP; + goto PDF_JPEG_ERROR; + } + } + + + + if (image->imagemask) + { + if (image->components != 1) + { + errcode = PDF_E_IMAGE_BADMASK; + goto PDF_JPEG_ERROR; + } + + if (p->compatibility <= PDC_1_3) + { + errcode = PDF_E_IMAGE_MASK1BIT13; + goto PDF_JPEG_ERROR; + } + else + { + /* images with more than one bit will be written as /SMask, + * and don't require an /ImageMask entry. + */ + image->imagemask = pdc_false; + } + } + + if (logg5) + { + pdc_logg(p->pdc, "\tColorspace="); + pdf_log_colorspace(p, image->colorspace); + pdc_logg(p->pdc, "\n"); + } + + /* special handling for CMYK JPEG files */ + if (image->components == 4) + { + /* CMYK JPEGs use inverse polarity */ + image->invert = !image->invert; + if (logg5) + pdc_logg(p->pdc, + "\tinverting image because of 4 components\n"); + + /* Adobe and other CMYK JPEGs always require transcoding */ + need_transcode = pdc_true; + if (logg5) + pdc_logg(p->pdc, + "\ttranscoding image because of 4 components\n"); + + } + + image->in_use = pdc_true; /* mark slot as used */ + + if (need_transcode) + { + if (logg5) + { + pdc_logg(p->pdc, "\tcalling libjpeg for transcoding\n"); + } + image->src.init = NULL; + image->src.fill = pdf_data_source_JPEG_fill_transcode; + image->src.terminate = NULL; + } + else + { + image->src.init = pdf_data_source_JPEG_init; + image->src.fill = pdf_data_source_JPEG_fill; + image->src.terminate = pdf_data_source_JPEG_terminate; + } + + image->src.private_data = (void *) image; + + if (image->doinline) + pdf_put_inline_image(p, imageslot); + else + pdf_put_image(p, imageslot, pdc_true, pdc_true); + + if (!image->corrupt) + { + pdf_cleanup_jpeg(p, image); + + return imageslot; + } + + PDF_JPEG_ERROR: + { + const char *stemp = NULL; + + if (errcode) + stemp = pdf_get_image_filename(p, image); + + + switch (errcode) + { + case PDC_E_IO_READ: + case PDF_E_IMAGE_ICC: + case PDF_E_IMAGE_ICC2: + case PDF_E_IMAGE_COLORIZE: + case PDF_E_IMAGE_BADMASK: + case PDF_E_IMAGE_MASK1BIT13: + pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0); + break; + + case PDC_E_IO_BADFORMAT: + pdc_set_errmsg(p->pdc, errcode, stemp, "JPEG", 0, 0); + break; + + case PDF_E_IMAGE_CORRUPT: + pdc_set_errmsg(p->pdc, errcode, "JPEG", stemp, 0, 0); + break; + + case PDF_E_JPEG_COMPRESSION: + case PDF_E_IMAGE_BADDEPTH: + case PDF_E_IMAGE_BADCOMP: + pdc_set_errmsg(p->pdc, errcode, + pdc_errprintf(p->pdc, "%d", errint), stemp, 0, 0); + break; + + case 0: /* error code and message already set */ + break; + } + } + + pdf_cleanup_jpeg(p, image); + + return -1; +} + +void +pdf_cleanup_jpeg(PDF *p, pdf_image *image) +{ + if (image->info.jpeg.virtfile != NULL) + { + (void) pdc__delete_pvf(p->pdc, image->info.jpeg.virtfile); + image->info.jpeg.virtfile = NULL; + } + + if (image->info.jpeg.seglist != NULL) + { + pdc_free(p->pdc, image->info.jpeg.seglist); + image->info.jpeg.seglist = NULL; + } +} + + +#endif /* PDF_JPEG_SUPPORTED */ diff --git a/src/pdflib/pdflib/p_jpx.c b/src/pdflib/pdflib/p_jpx.c new file mode 100644 index 0000000..73e364c --- /dev/null +++ b/src/pdflib/pdflib/p_jpx.c @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_jpx.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * JPEG2000 processing for PDFlib + * + */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +#ifndef PDF_JPX_SUPPORTED + +pdc_bool +pdf_is_JPX_file(PDF *p, pdc_file *fp) +{ + (void) p; + (void) fp; + + return pdc_false; +} + +int +pdf_process_JPX_data( + PDF *p, + int imageslot) +{ + (void) imageslot; + + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "JPEG2000", 0, 0, 0); + + return -1; +} + +#else + + +pdc_bool +pdf_is_JPX_file(PDF *p, pdc_file *fp) +{ + (void) p; + (void) fp; + + return pdc_false; +} + +int +pdf_process_JPX_data( + PDF *p, + int imageslot) +{ + (void) imageslot; + + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "JPEG2000", 0, 0, 0); + + return -1; +} + + + +#endif /* PDF_JPX_SUPPORTED */ + diff --git a/src/pdflib/pdflib/p_kerning.c b/src/pdflib/pdflib/p_kerning.c new file mode 100644 index 0000000..bc711ba --- /dev/null +++ b/src/pdflib/pdflib/p_kerning.c @@ -0,0 +1,21 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_kerning.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib kerning routines + * + */ + +#include "p_intern.h" +#include "p_font.h" + diff --git a/src/pdflib/pdflib/p_keyconn.h b/src/pdflib/pdflib/p_keyconn.h new file mode 100644 index 0000000..a56d783 --- /dev/null +++ b/src/pdflib/pdflib/p_keyconn.h @@ -0,0 +1,827 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_keyconn.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib shared keys connection lists + * + */ + +#ifndef P_KEYCONN_H +#define P_KEYCONN_H + +/* + * ------------- enumerations for pdc_keyconn tables ------------------ + */ + +typedef enum +{ + pdf_state_object = (1<<0), /* outside any document */ + pdf_state_document = (1<<1), /* document */ + pdf_state_page = (1<<2), /* page description in a document */ + pdf_state_pattern = (1<<3), /* pattern in a document */ + pdf_state_template = (1<<4), /* template in a document */ + pdf_state_path = (1<<5), /* path in a page description */ + pdf_state_font = (1<<6), /* font definition */ + pdf_state_glyph = (1<<7), /* glyph description in a Type3 font */ + pdf_state_glyphmetric = (1<<8), /* glyph metric in a Type3 font */ + pdf_state_glyphignore = (1<<9), /* glyph will be ignored without error */ + pdf_state_error = (1<<10) /* in error cleanup */ +} +pdf_state; + +typedef enum +{ + errpol_legacy = -1, + errpol_return = 0, + errpol_exception = 1 +} +pdf_errpol; + +typedef enum +{ + names_undef = 0, + names_3dannots, /* internal for named 3D annotations */ + names_dests, + names_javascript, + names_ap, + names_embeddedfiles +} +pdf_nametree_type; + +typedef enum +{ + event_formfield, + event_annotation, + event_bookmark, + event_page, + event_document +} +pdf_event_object; + +typedef enum +{ + pdf_openaction, + pdf_bookmark, + pdf_remotelink, + pdf_locallink, + pdf_nameddest +} +pdf_destuse; + +typedef enum +{ + pdf_3dview_first = -1, + pdf_3dview_last = -2, + pdf_3dview_next = -3, + pdf_3dview_previous = -4, + pdf_3dview_default = -5 +} +pdf_3dviewoptions; + +typedef enum +{ + pdf_none = 0, + pdf_fill, + pdf_stroke, + pdf_fillstroke +} +pdf_drawmode; + +typedef enum +{ + pdf_fill_winding, + pdf_fill_evenodd +} +pdf_fillrule; + +typedef enum +{ + NoColor = -1, + DeviceGray = 0, + DeviceRGB, + DeviceCMYK, + CalGray, + CalRGB, + Lab, + ICCBased, + Indexed, + PatternCS, + Separation, + DeviceN +} +pdf_colorspacetype; + +typedef enum +{ + color_undefgray = -1, + color_none = 0, + color_gray, + color_rgb, + color_cmyk, + color_spotname, + color_spot, + color_pattern, + color_iccbasedgray, + color_iccbasedrgb, + color_iccbasedcmyk, + color_lab, + + color_max /* for pdf_parse_coloropt */ +} +pdf_colortype; + +typedef enum +{ + AutoIntent = 0, + AbsoluteColorimetric, + RelativeColorimetric, + Saturation, + Perceptual +} +pdf_renderingintent; + +/* only up to 32 values permitted! */ +typedef enum +{ + fo_autocidfont, + fo_autosubsetting, + fo_embedding, + fo_encoding, + fo_fontname, + fo_fontstyle, + fo_fontwarning, + fo_kerning, + fo_monospace, + fo_subsetlimit, + fo_subsetminsize, + fo_subsetting, + fo_unicodemap, + fo_embedopentype, + fo_vertical, + fo_keepnative, + fo_replacementchar, + fo_ascender, + fo_descender, + fo_capheight, + fo_xheight, + fo_linegap +} +pdf_font_optflags; + +/* only up to 32 values permitted! */ +typedef enum +{ + to_charspacing, + to_fillcolor, + to_font, + to_fontsize, + to_fontsize_st, + to_deffont, + to_glyphwarning, + to_horizscaling, + to_italicangle, + to_fakebold, + to_kerning, + to_overline, + to_strikeout, + to_strokecolor, + to_strokewidth, + to_dasharray, + to_text, + to_textformat, + to_textrendering, + to_textrise, + to_leading, + to_underline, + to_wordspacing, + to_underlinewidth, + to_underlineposition, + to_charref, + to_escapesequence, + to_glyphcheck, + + to_textx, + to_texty +} +pdf_text_optflags; + +typedef enum +{ + border_solid, + border_dashed, + border_beveled, + border_inset, + border_underline +} +pdf_borderstyle; + +typedef enum +{ + label_none, + label_123, + label_IVX, + label_ivx, + label_ABC, + label_abc +} +pdf_labelstyle; + +typedef enum { + BM_None = 0, + BM_Normal = (1<<0), + BM_Multiply = (1<<1), + BM_Screen = (1<<2), + BM_Overlay = (1<<3), + BM_Darken = (1<<4), + BM_Lighten = (1<<5), + BM_ColorDodge = (1<<6), + BM_ColorBurn = (1<<7), + BM_HardLight = (1<<8), + BM_SoftLight = (1<<9), + BM_Difference = (1<<10), + BM_Exclusion = (1<<11), + BM_Hue = (1<<12), + BM_Saturation = (1<<13), + BM_Color = (1<<14), + BM_Luminosity = (1<<15) +} +pdf_blendmode; + +/* these values are used directly as indices into +** a page's boxes[] array. +*/ +typedef enum +{ + pdf_artbox, + pdf_bleedbox, + pdf_cropbox, + pdf_mediabox, + pdf_trimbox +} pdf_pagebox; + +typedef enum +{ + tabs_none, + tabs_fitbox, + tabs_validarea +} +pdf_showtabs; + +typedef enum +{ + text_noalign, + text_left, + text_center, + text_right, + text_justify, + text_lastauto, + text_fulljustify, + text_decimal, + text_top, + text_bottom, + text_grid +} +pdf_alignment; + +typedef enum +{ + text_nofit, + text_clip, + text_shrink, + text_split, + text_spread, + text_auto +} +pdf_adjustmethod; + +typedef enum +{ + text_relative, + text_typewriter, + text_ruler +} +pdf_hortabmethod; + +typedef enum +{ + text_none = -90000, + text_textrise = -70000, + text_xheight = -60000, + text_descender = -50000, + text_capheight = -40000, + text_ascender = -30000, + text_fontsize = -20000, + text_leading = -10000 +} +pdf_charmetric; + +typedef enum +{ + mbox_none = 0, + mbox_openleft = (1<<0), + mbox_openright = (1<<1), + mbox_openbottom = (1<<2), + mbox_opentop = (1<<3), + mbox_border = (1<<4), + mbox_area = (1<<5), + mbox_saverestore = (1<<6), + mbox_statleft = (1<<7), + mbox_statright = (1<<8), + mbox_statbottom = (1<<9), + mbox_stattop = (1<<10) +} +pdf_mbox_flags; + +typedef enum +{ + quadd_left = 0, + quadd_center = 1, + quadd_right = 2 +} +pdf_quadding; + +typedef enum +{ + disp_visible = (1<<2), + disp_hidden = (1<<1), + disp_noview = (1<<5), + disp_noprint = 0 +} +pdf_display; + +typedef enum +{ + high_none, + high_invert, + high_outline, + high_push +} +pdf_highlight; + +typedef enum +{ + pos_left = 1000, + pos_bottom = 2000, + pos_center = 50, + pos_right = 1100, + pos_top = 2100 +} +pdf_position; + +typedef enum +{ + dpi_none = -999999, + dpi_internal = 0 +} +pdf_dpi_states; + +typedef enum +{ + trans_none, + trans_split, + trans_blinds, + trans_box, + trans_wipe, + trans_dissolve, + trans_glitter, + trans_replace, + + TRANS_1_5, + trans_fly = TRANS_1_5, + trans_push, + trans_cover, + trans_uncover, + trans_fade +} +pdf_transition; + + +/* + * -------- pdc_keyconn tables shared by more than one c file ---------- + */ + +#if defined(P_MBOX_C) + +static const pdc_keyconn pdf_mbox_keylist[] = +{ + {"all", -1}, + {NULL, 0} +}; + +#endif /* P_MBOX_C */ + + +#if defined(P_DOCUMENT_C) || defined(P_PARAMS_C) + +static const pdc_keyconn pdf_compatibility_keylist[] = +{ + {"1.3", PDC_1_3}, + {"1.4", PDC_1_4}, + {"1.5", PDC_1_5}, + {"1.6", PDC_1_6}, + {"1.7", PDC_1_7}, + {NULL, 0} +}; + +#endif /* P_DOCUMENT_C || P_PARAMS_C */ + + +#if defined(P_ACTIONS_C) || defined(P_PAGE_C) + +static const pdc_keyconn pdf_transition_keylist[] = +{ + {"none", trans_none}, + {"split", trans_split}, + {"blinds", trans_blinds}, + {"box", trans_box}, + {"wipe", trans_wipe}, + {"dissolve", trans_dissolve}, + {"glitter", trans_glitter}, + {"replace", trans_replace}, + {"fly", trans_fly}, + {"push", trans_push}, + {"cover", trans_cover}, + {"uncover", trans_uncover}, + {"fade", trans_fade}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_transition_pdfkeylist[] = +{ + {"R", trans_none}, + {"Split", trans_split}, + {"Blinds", trans_blinds}, + {"Box", trans_box}, + {"Wipe", trans_wipe}, + {"Dissolve", trans_dissolve}, + {"Glitter", trans_glitter}, + {"R", trans_replace}, + {"Fly", trans_fly}, + {"Push", trans_push}, + {"Cover", trans_cover}, + {"Uncover", trans_uncover}, + {"Fade", trans_fade}, + {NULL, 0} +}; + +#endif /* P_ACTIONS_C || P_PAGE_C */ + + +#if defined(P_IMAGE_C) || defined(P_PARAMS_C) || defined(P_XGSTATE_C) + +static const pdc_keyconn pdf_renderingintent_pdfkeylist[] = +{ + {"Auto", AutoIntent}, + {"AbsoluteColorimetric", AbsoluteColorimetric}, + {"RelativeColorimetric", RelativeColorimetric}, + {"Saturation", Saturation}, + {"Perceptual", Perceptual}, + {NULL, 0} +}; + +#endif /* P_IMAGE_C || P_PARAMS_C || P_XGSTATE_C */ + + +#if defined(P_MBOX_C) || defined(P_XGSTATE_C) + +static const pdc_keyconn pdf_linecap_keylist[] = +{ + {"butt", 0}, + {"round", 1}, + {"projecting", 2}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_linejoin_keylist[] = +{ + {"miter", 0}, + {"round", 1}, + {"bevel", 2}, + {NULL, 0} +}; + +#endif /* P_MBOX_C || P_XGSTATE_C */ + + +#if defined(P_DOCUMENT_C) || defined(P_PARAMS_C) || defined(P_PDI_C) + +static const pdc_keyconn pdf_usebox_keylist[] = +{ + {"art", pdc_pbox_art}, + {"bleed", pdc_pbox_bleed}, + {"crop", pdc_pbox_crop}, + {"media", pdc_pbox_media}, + {"trim", pdc_pbox_trim}, + {NULL, 0} +}; + +#endif /* P_DOCUMENT_C || P_PARAMS_C || P_PDI_C */ + +#if defined(P_DOCUMENT_C) || defined(P_PDI_C) + +static const pdc_keyconn pdf_usebox_pdfkeylist[] = +{ + {"/ArtBox", pdc_pbox_art }, + {"/BleedBox", pdc_pbox_bleed }, + {"/CropBox", pdc_pbox_crop }, + {"/MediaBox", pdc_pbox_media }, + {"/TrimBox", pdc_pbox_trim }, + {NULL, 0} +}; + +#endif /* P_DOCUMENT_C || P_PDI_C */ + + +#if defined(P_BLOCK_C) || defined(P_IMAGE_C) + +static const pdc_keyconn pdf_dpi_keylist[] = +{ + {"none", dpi_none}, + {"internal", dpi_internal}, + {NULL, 0} +}; + +#endif /* P_BLOCK_C || P_IMAGE_C */ + +#if defined(P_BLOCK_C) || defined(P_TEXT_C) + +static const pdc_keyconn pdf_stampdir_keylist[] = +{ + {NULL, 0} +}; + +#endif /* P_BLOCK_C || P_TEXT_C */ + + + + +#if defined(P_MBOX_C) || defined(P_TEXTFLOW_C) +static const pdc_keyconn pdf_boxheight_keylist[] = +{ + {"none", text_none}, + {"baseline", text_none}, + {"textrise", text_textrise}, + {"xheight", text_xheight}, + {"descender", text_descender}, + {"capheight", text_capheight}, + {"ascender", text_ascender}, + {"fontsize", text_fontsize}, + {"leading", text_leading}, + {NULL, 0} +}; + +#endif /* P_MBOX_C || P_TEXTFLOW_C */ + + +#if defined(P_BLOCK_C) || defined(P_TEXT_C) || defined(P_TEXTFLOW_C) + +static const pdc_keyconn pdf_charname_keylist[] = +{ + {"none", 0}, + {NULL, 0} +}; + +#define PDF_UNDERLINEWIDTH_AUTO 0 +static const pdc_keyconn pdf_underlinewidth_keylist[] = +{ + {"auto", PDF_UNDERLINEWIDTH_AUTO}, + {NULL, 0} +}; + +#define PDF_UNDERLINEPOSITION_AUTO 1000000 +static const pdc_keyconn pdf_underlineposition_keylist[] = +{ + {"auto", PDF_UNDERLINEPOSITION_AUTO}, + {NULL, 0} +}; + +#endif /* P_BLOCK_C || P_TEXT_C || P_TEXTFLOW_C */ + + +#if defined(P_BLOCK_C)|| defined(P_PARAMS_C) || \ + defined(P_TEXT_C) || defined(P_TEXTFLOW_C) + +static const pdc_keyconn pdf_glyphcheck_keylist[] = +{ + {"none", text_nocheck}, + {"error", text_error}, + {"replace", text_replace}, + {NULL, 0} +}; + +#endif /* P_BLOCK_C || P_PARAMS_C || P_TEXT_C || P_TEXTFLOW_C */ + + +#if defined(P_BLOCK_C) || defined(P_FIELDS_C) || \ + defined(P_IMAGE_C) || defined(P_TEXT_C) + +static const pdc_keyconn pdf_position_keylist[] = +{ + {"left", pos_left}, + {"bottom", pos_bottom}, + {"center", pos_center}, + {"right", pos_right}, + {"top", pos_top}, + {NULL, 0} +}; + +#endif /* P_BLOCK_C || P_FIELDS_C || P_IMAGE_C || P_TEXT_C */ + + +#if defined(P_BLOCK_C) || defined(P_FIELDS_C) || \ + defined(P_IMAGE_C) || defined(P_TABLE_C) || \ + defined(P_TEXT_C) || defined(P_TEXTFLOW_C) + +static const pdc_keyconn pdf_fitmethod_keylist[] = +{ + {"nofit", pdc_nofit}, + {"clip", pdc_clip}, + {"auto", pdc_tauto}, +#if !defined (P_TEXTFLOW_C) + {"slice", pdc_slice}, + {"meet", pdc_meet}, + {"entire", pdc_entire}, +#endif + {NULL, 0} +}; + +#endif /* P_BLOCK_C || P_FIELDS_C || P_IMAGE_C || P_TABLE_C || + P_TEXT_C || P_TEXTFLOW_C */ + + +#if defined(P_ANNOTS_C) || defined(P_BLOCK_C) || defined(P_FIELDS_C) || \ + defined(P_IMAGE_C) || defined(P_TEXT_C) || defined(P_TEXTFLOW_C) + +static const pdc_keyconn pdf_orientate_keylist[] = +{ + {"north", 0}, + {"west", 90}, + {"south", 180}, + {"east", 270}, + {NULL, 0} +}; + +#endif /* P_ANNOTS_C || P_BLOCK_C || P_FIELDS_C || + P_IMAGE_C || P_TEXT_C || P_TEXTFLOW_C */ + + +#if defined(P_ANNOTS_C) || defined(P_BLOCK_C) || defined(P_FIELDS_C) || \ + defined(P_MBOX_C) || defined(P_TEXT_C) || defined(P_TEXTFLOW_C) + +static const pdc_keyconn pdf_fontsize_keylist[] = +{ + {"auto", 0}, + {"xheight", text_xheight}, + {"capheight", text_capheight}, + {"ascender", text_ascender}, + {"bodyheight", text_fontsize}, + {NULL, 0} +}; + +#endif /* P_ANNOTS_C P_BLOCK_C || P_FIELDS_C || + P_MBOX_C || P_TEXT_C || P_TEXTFLOW_C */ + + +#if defined(P_BLOCK_C) || defined(P_FONT_C) || defined(P_HYPER_C) || \ + defined(P_MBOX_C) || defined(P_TEXT_C) || defined(P_TEXTFLOW_C) + +static const pdc_keyconn pdf_fontstyle_pdfkeylist[] = +{ + {"Normal", fnt_Normal}, + {"Bold", fnt_Bold}, + {"Italic", fnt_Italic}, + {"BoldItalic", fnt_BoldItalic}, + {NULL, 0} +}; + +#endif /* P_BLOCK_C || P_FONT_C || P_HYPER_C || + P_MBOX_C || P_TEXT_C || P_TEXTFLOW_C */ + + +#if defined(P_ANNOTS_C) || defined(P_FIELDS_C) + +static const pdc_keyconn pdf_quadding_keylist[] = +{ + {"left", quadd_left}, + {"center", quadd_center}, + {"right", quadd_right}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_display_keylist[] = +{ + {"visible", disp_visible}, + {"hidden", disp_hidden}, + {"noview", disp_noview}, + {"noprint", disp_noprint}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_highlight_keylist[] = +{ + {"none", high_none}, + {"invert", high_invert}, + {"outline", high_outline}, + {"push", high_push}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_highlight_pdfkeylist[] = +{ + {"N", high_none}, + {"I", high_invert}, + {"O", high_outline}, + {"P", high_push}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_borderstyle_keylist[] = +{ + {"solid", border_solid}, + {"dashed", border_dashed}, + {"beveled", border_beveled}, + {"inset", border_inset}, + {"underline", border_underline}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_borderstyle_pdfkeylist[] = +{ + {"S", border_solid}, + {"D", border_dashed}, + {"B", border_beveled}, + {"I", border_inset}, + {"U", border_underline}, + {NULL, 0} +}; + +#endif /* P_ANNOTS_C || P_FIELDS_C */ + + +#if defined(P_3D_C) || defined(P_BLOCK_C) || defined(P_FIELDS_C) || \ + defined(P_HYPER_C) || defined(P_LAYER_C) || defined(P_PARAMS_C) || \ + defined(P_TEXT_C) || defined(P_TEXTFLOW_C) || defined(P_UTIL_C) || \ + defined(P_XMP_C) + +/* original in pc_unicode.h */ +static const pdc_keyconn pdf_textformat_keylist[] = +{ + {"auto", pdc_auto}, + {"auto2", pdc_auto2}, + {"bytes", pdc_bytes}, + {"bytes2", pdc_bytes2}, + {"utf8", pdc_utf8}, + {"utf16", pdc_utf16}, + {"utf16be", pdc_utf16be}, + {"utf16le", pdc_utf16le}, + {NULL, 0} +}; + +#endif /* P_3D_C || P_BLOCK_C || P_FIELDS_C || P_HYPER_C || + P_LAYER_C || P_PARAMS_C || P_TEXT_C || P_TEXTFLOW_C || + P_UTIL_C || P_XMP_C */ + + +#if defined(P_DOCUMENT_C) || \ + defined(P_3D_C) || \ + defined(P_ACTIONS_C) || \ + defined(P_BLOCK_C) || \ + defined(P_FIELDS_C) || \ + defined(P_FONT_C) || \ + defined(P_ICC_C) || \ + defined(P_IMAGE_C) || \ + defined(P_PARAMS_C) || \ + defined(P_PDI_C) || \ + defined(P_TABLE_C) || \ + defined(P_TEMPLATE_C) || \ + defined(P_TEXT_C) || \ + defined(P_TEXTFLOW_C) + +static const pdc_keyconn pdf_errpol_keylist[] = +{ + {"legacy", errpol_legacy}, + {"return", errpol_return}, + {"exception", errpol_exception}, + {NULL, 0} +}; + +#define PDF_ERRORPOLICY_OPTION \ +\ + {"errorpolicy", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0, 0, pdf_errpol_keylist}, \ + +#endif + + +#endif /* P_KEYCONN_H */ + diff --git a/src/pdflib/pdflib/p_layer.c b/src/pdflib/pdflib/p_layer.c new file mode 100644 index 0000000..1600a5b --- /dev/null +++ b/src/pdflib/pdflib/p_layer.c @@ -0,0 +1,36 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + *---------------------------------------------------------------------------*/ + +/* $Id: p_layer.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib optional content routines + * + */ + +#define P_LAYER_C + +#include "p_intern.h" +#include "p_layer.h" +#include "p_tagged.h" + + + + + + + + + + + + + + diff --git a/src/pdflib/pdflib/p_layer.h b/src/pdflib/pdflib/p_layer.h new file mode 100644 index 0000000..74d51eb --- /dev/null +++ b/src/pdflib/pdflib/p_layer.h @@ -0,0 +1,24 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_layer.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib marked content header + * + */ + +#ifndef P_LAYER_H +#define P_LAYER_H + + +#endif /* P_LAYER_H */ + diff --git a/src/pdflib/pdflib/p_mbox.c b/src/pdflib/pdflib/p_mbox.c new file mode 100644 index 0000000..db6ffff --- /dev/null +++ b/src/pdflib/pdflib/p_mbox.c @@ -0,0 +1,943 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_mbox.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib matchbox related routines + * + */ + +#define P_MBOX_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_font.h" +#include "p_defopt.h" + +static const pdc_defopt pdf_create_mbox_options[] = +{ + {"name", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"boxheight", pdc_scalarlist, PDC_OPT_NONE, 2, 2, + 0.0, PDC_FLOAT_MAX, pdf_boxheight_keylist}, + + {"clipping", pdc_scalarlist, PDC_OPT_PERCENT, 4, 4, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + + {"innerbox", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"openrect", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"fillcolor", pdc_stringlist, PDC_OPT_NONE, 1, 5, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"strokecolor", pdc_stringlist, PDC_OPT_NONE, 1, 5, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"borderwidth", pdc_scalarlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_FLOAT_MAX, NULL}, + + {"dasharray", pdc_scalarlist, PDC_OPT_NONE, 0, PDF_MAX_DASHLENGTH, + PDC_FLOAT_PREC, PDC_FLOAT_MAX, NULL}, + + {"dashphase", pdc_scalarlist, PDC_OPT_NONE, 1, 1, + 0.0, PDC_FLOAT_MAX, NULL}, + + {"linecap", pdc_integerlist, PDC_OPT_NONE, 1, 1, + 0.0, 2.0, pdf_linecap_keylist}, + + {"linejoin", pdc_integerlist, PDC_OPT_NONE, 1, 1, + 0.0, 2.0, pdf_linejoin_keylist}, + + {"drawleft", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"drawbottom", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"drawright", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"drawtop", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"margin", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + {"offsetleft", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + {"offsetbottom", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + {"offsetright", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + {"offsettop", pdc_scalarlist, PDC_OPT_PERCENT, 1, 1, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + PDC_OPT_TERMINATE +}; + +struct pdf_mbox_s +{ + char *name; + pdc_rectangle rect; + pdc_matrix ctm; + pdc_scalar boxheight[2]; + pdc_scalar clipping[4]; + pdc_bool percentclipping[4]; + pdc_bool innerbox; + pdc_bool openrect; + pdf_coloropt fillcolor; + pdf_coloropt strokecolor; + pdc_scalar borderwidth; + int linecap; + int linejoin; + pdc_scalar dasharray[PDF_MAX_DASHLENGTH]; + int dashlength; + pdc_scalar dashphase; + pdc_bool drawleft; + pdc_bool drawbottom; + pdc_bool drawright; + pdc_bool drawtop; + pdc_scalar offsetleft; + pdc_bool percentleft; + pdc_scalar offsetbottom; + pdc_bool percentbottom; + pdc_scalar offsetright; + pdc_bool percentright; + pdc_scalar offsettop; + pdc_bool percenttop; +}; + +static void +pdf_reclaim_mbox(void *item) +{ + pdf_mbox *mbox = (pdf_mbox *) item; + + mbox->name = NULL; + pdc_rect_init(&mbox->rect, 0, 0, 0, 0); + pdc_identity_matrix(&mbox->ctm); + mbox->boxheight[0] = (pdc_scalar) text_capheight; + mbox->boxheight[1] = (pdc_scalar) text_none; + mbox->clipping[0] = 0; + mbox->clipping[1] = 0; + mbox->clipping[2] = 1; + mbox->clipping[3] = 1; + mbox->percentclipping[0] = pdc_true; + mbox->percentclipping[1] = pdc_true; + mbox->percentclipping[2] = pdc_true; + mbox->percentclipping[3] = pdc_true; + mbox->innerbox = pdc_false; + mbox->openrect = pdc_false; + mbox->fillcolor.type = (int) color_none; + mbox->strokecolor.type = (int) color_none; + mbox->borderwidth = 0.0; + mbox->linecap = 0; + mbox->linejoin = 0; + mbox->dasharray[0] = 0.0; + mbox->dasharray[1] = 0.0; + mbox->dashlength = 0; + mbox->dashphase = 0; + mbox->drawleft = pdc_true; + mbox->drawbottom = pdc_true; + mbox->drawright = pdc_true; + mbox->drawtop = pdc_true; + mbox->offsetleft = 0.0; + mbox->percentleft = pdc_false; + mbox->offsetbottom = 0.0; + mbox->percentbottom = pdc_false; + mbox->offsetright = 0.0; + mbox->percentright = pdc_false; + mbox->offsettop = 0.0; + mbox->percenttop = pdc_false; +} + +static void +pdf_release_mbox(void *context, void *item) +{ + PDF *p = (PDF *) context; + pdf_mbox *mbox = (pdf_mbox *) item; + + if (mbox->name != NULL) + { + pdc_free(p->pdc, mbox->name); + mbox->name = NULL; + } +} + +static pdc_ced pdf_mbox_ced = +{ + sizeof(pdf_mbox), pdf_reclaim_mbox, pdf_release_mbox, NULL +}; + +static pdc_vtr_parms pdf_mbox_parms = +{ + 0, 10, 10 +}; + +pdc_vtr * +pdf_new_mboxes(PDF *p, pdf_mbox *mbox, pdc_vtr *mboxes) +{ + static const char fn[] = "pdf_new_mboxes"; + char *name = mbox->name; + + if (mboxes == NULL) + mboxes = pdc_vtr_new(p->pdc, &pdf_mbox_ced, p, &pdf_mbox_parms); + + if (mbox->name != NULL) + mbox->name = pdc_strdup_ext(p->pdc, mbox->name, 0, fn); + pdc_vtr_push(mboxes, *mbox, pdf_mbox); + + mbox->name = name; + + return mboxes; +} + +void +pdf_add_page_mbox(PDF *p, pdf_mbox *mbox) +{ + /* save current trafo matrix */ + mbox->ctm = p->curr_ppt->gstate[p->curr_ppt->sl].ctm; + + if (mbox->name && strlen(mbox->name)) + { + pdc_vtr *mboxes_new; + pdc_vtr *mboxes = p->curr_ppt->mboxes; + + mboxes_new = pdf_new_mboxes(p, mbox, mboxes); + if (mboxes_new != mboxes) + p->curr_ppt->mboxes = mboxes_new; + + } +} + +void +pdf_delete_mbox(PDF *p, pdf_mbox *mbox) +{ + if (mbox != NULL) + { + pdf_release_mbox(p, mbox); + pdc_free(p->pdc, mbox); + } +} + +pdf_mbox * +pdf_get_mbox(PDF *p, pdc_vtr *mboxes, const char *name, int number, + int *o_count) +{ + pdf_mbox *o_mbox = NULL; + int count = 0; + + if (mboxes == NULL) + mboxes = p->curr_ppt->mboxes; + + if (mboxes != NULL) + { + if (name == NULL && number <= 0) + { + count = pdc_vtr_size(mboxes); + } + else + { + int i, n = pdc_vtr_size(mboxes); + + for (i = 0; i < n; i++) + { + pdf_mbox *mbox = (pdf_mbox *) &pdc_vtr_at(mboxes, i, pdf_mbox); + + if (name == NULL || !pdc_strcmp(name, mbox->name)) + { + count++; + if (o_count == NULL && count == number) + { + o_mbox = mbox; + break; + } + } + } + } + } + + if (o_count != NULL) + *o_count = count; + + return o_mbox; +} + +pdf_mbox * +pdf_parse_mbox_optlist(PDF *p, const char *optlist) +{ + static const char fn[] = "pdf_parse_mbox_optlist"; + pdc_resopt *resopts = NULL; + pdf_mbox *mbox; + char **strlist = NULL; + pdc_scalar margin; + int i, ns; + + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_create_mbox_options, + NULL, pdc_true); + + mbox = (pdf_mbox *) pdc_malloc(p->pdc, sizeof(pdf_mbox), fn); + pdf_reclaim_mbox(mbox); + + if (pdc_get_optvalues("name", resopts, NULL, NULL)) + mbox->name = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + pdc_get_optvalues("boxheight", resopts, mbox->boxheight, NULL); + if (pdc_get_optvalues("clipping", resopts, mbox->clipping, NULL)) + { + for (i = 0; i < 4; i++) + mbox->percentclipping[i] = pdc_is_lastopt_percent(resopts, i) ? + pdc_true : pdc_false; + } + + + pdc_get_optvalues("innerbox", resopts, &mbox->innerbox, NULL); + pdc_get_optvalues("openrect", resopts, &mbox->openrect, NULL); + + ns = pdc_get_optvalues("fillcolor", resopts, NULL, &strlist); + if (ns) + pdf_parse_coloropt(p, "fillcolor", strlist, ns, (int) color_max, + &mbox->fillcolor); + + pdf_init_coloropt(p, &mbox->strokecolor); + ns = pdc_get_optvalues("strokecolor", resopts, NULL, &strlist); + if (ns) + pdf_parse_coloropt(p, "strokecolor", strlist, ns, (int) color_max, + &mbox->strokecolor); + + pdc_get_optvalues("borderwidth", resopts, &mbox->borderwidth, NULL); + mbox->dashlength = + pdc_get_optvalues("dasharray", resopts, mbox->dasharray, NULL); + pdc_get_optvalues("dashphase", resopts, &mbox->dashphase, NULL); + pdc_get_optvalues("linecap", resopts, &mbox->linecap, NULL); + pdc_get_optvalues("linejoin", resopts, &mbox->linejoin, NULL); + + pdc_get_optvalues("drawleft", resopts, &mbox->drawleft, NULL); + pdc_get_optvalues("drawbottom", resopts, &mbox->drawbottom, NULL); + pdc_get_optvalues("drawright", resopts, &mbox->drawright, NULL); + pdc_get_optvalues("drawtop", resopts, &mbox->drawtop, NULL); + + if (pdc_get_optvalues("margin", resopts, &margin, NULL)) + { + mbox->offsetleft = margin; + mbox->percentleft = pdc_is_lastopt_percent(resopts, 0); + + mbox->offsetbottom = margin; + mbox->percentbottom = pdc_is_lastopt_percent(resopts, 0); + + mbox->offsetright = -margin; + mbox->percentright = pdc_is_lastopt_percent(resopts, 0); + + mbox->offsettop = -margin; + mbox->percenttop = pdc_is_lastopt_percent(resopts, 0); + } + + if (pdc_get_optvalues("offsetleft", resopts, &mbox->offsetleft, NULL)) + { + mbox->percentleft = pdc_is_lastopt_percent(resopts, 0); + } + if (pdc_get_optvalues("offsetbottom", resopts, &mbox->offsetbottom, NULL)) + { + mbox->percentbottom = pdc_is_lastopt_percent(resopts, 0); + } + if (pdc_get_optvalues("offsetright", resopts, &mbox->offsetright, NULL)) + { + mbox->percentright = pdc_is_lastopt_percent(resopts, 0); + } + if (pdc_get_optvalues("offsettop", resopts, &mbox->offsettop, NULL)) + { + mbox->percenttop = pdc_is_lastopt_percent(resopts, 0); + } + + pdc_cleanup_optionlist(p->pdc, resopts); + + return mbox; +} + +void +pdf_get_mbox_boxheight(PDF *p, pdf_mbox *mbox, pdc_scalar *boxheight) +{ + (void) p; + + if (mbox == NULL) + { + boxheight[0] = (pdc_scalar) text_capheight; + boxheight[1] = (pdc_scalar) text_none; + } + else + { + boxheight[0] = mbox->boxheight[0]; + boxheight[1] = mbox->boxheight[1]; + } +} + +pdc_bool +pdf_get_mbox_clipping(PDF *p, pdf_mbox *mbox, + pdc_scalar width, pdc_scalar height, + pdc_box *clipbox) +{ + (void) p; + + if (mbox == NULL) + { + clipbox->ll.x = 0; + clipbox->ll.y = 0; + clipbox->ur.x = width; + clipbox->ur.y = height; + } + else + { + if (mbox->percentclipping[0]) + clipbox->ll.x = mbox->clipping[0] * width; + else + clipbox->ll.x = mbox->clipping[0]; + + if (mbox->percentclipping[1]) + clipbox->ll.y = mbox->clipping[1] * height; + else + clipbox->ll.y = mbox->clipping[1]; + + if (mbox->percentclipping[2]) + clipbox->ur.x = mbox->clipping[2] * width; + else + clipbox->ur.x = mbox->clipping[2]; + + if (mbox->percentclipping[3]) + clipbox->ur.y = mbox->clipping[3] * height; + else + clipbox->ur.y = mbox->clipping[3]; + } + + return (clipbox->ll.x != 0 || clipbox->ll.y != 0 || + clipbox->ur.x != width || clipbox->ur.y != height) ? + pdc_true : pdc_false; +} + +void +pdf_set_mbox_rectangle(PDF *p, pdf_mbox *mbox, pdc_rectangle *rect, int flags) +{ + pdc_scalar width, height; + + (void) p; + + mbox->rect = *rect; + + width = mbox->rect.urx - mbox->rect.llx; + height = mbox->rect.ury - mbox->rect.lly; + + if (!(flags & mbox_statleft)) + { + if (mbox->percentleft) + mbox->rect.llx += mbox->offsetleft * width; + else + mbox->rect.llx += mbox->offsetleft; + } + + if (!(flags & mbox_statbottom)) + { + if (mbox->percentbottom) + mbox->rect.lly += mbox->offsetbottom * height; + else + mbox->rect.lly += mbox->offsetbottom; + } + + if (!(flags & mbox_statright)) + { + if (mbox->percentright) + mbox->rect.urx += mbox->offsetright * width; + else + mbox->rect.urx += mbox->offsetright; + } + + if (!(flags & mbox_stattop)) + { + if (mbox->percenttop) + mbox->rect.ury += mbox->offsettop * height; + else + mbox->rect.ury += mbox->offsettop; + } +} + +double +pdf_get_mbox_info(PDF *p, pdf_mbox *mbox, const char *keyword) +{ + (void) p; + + + if (!strcmp(keyword, "openrect")) + return (double) mbox->openrect; + + if (!strcmp(keyword, "innerbox")) + return (double) mbox->innerbox; + + return 0; +} + +pdc_bool +pdf_get_mbox_drawborder(PDF *p, pdf_mbox *mbox, int keycode) +{ + pdc_bool drawborder = mbox->borderwidth > 0 && + mbox->strokecolor.type != (int) color_none; + + (void) p; + + switch (keycode) + { + case mbox_openleft: + return drawborder && mbox->drawleft; + + case mbox_openright: + return drawborder && mbox->drawright; + + case mbox_openbottom: + return drawborder && mbox->drawbottom; + + case mbox_opentop: + return drawborder && mbox->drawtop; + } + + return pdc_false; +} + +void +pdf_get_mbox_rectangle(PDF *p, pdf_mbox *mbox, pdc_vector *polyline) +{ + pdc_matrix ctminv; + + pdc_invert_matrix(p->pdc, &ctminv, + &p->curr_ppt->gstate[p->curr_ppt->sl].ctm); + pdc_multiply_matrix(&mbox->ctm, &ctminv); + pdc_rect2polyline(&ctminv, &mbox->rect, polyline); +} + +void +pdf_draw_mbox_rectangle(PDF *p, pdf_mbox *mbox, int flags) +{ + pdc_bool drawleft, drawright, drawbottom, drawtop; + pdc_bool saverestore = (flags & mbox_saverestore) && + ((flags & mbox_area && + mbox->fillcolor.type != (int) color_none) || + (flags & mbox_border && + mbox->strokecolor.type != (int) color_none && mbox->borderwidth > 0)); + + if (saverestore) + pdf__save(p); + + if (flags & mbox_area && mbox->fillcolor.type != (int) color_none && + mbox->rect.llx != mbox->rect.urx && + mbox->rect.lly != mbox->rect.ury) + { + pdf_set_coloropt(p, pdf_fill, &mbox->fillcolor); + pdf__moveto(p, mbox->rect.llx, mbox->rect.lly); + pdf__lineto(p, mbox->rect.urx, mbox->rect.lly); + pdf__lineto(p, mbox->rect.urx, mbox->rect.ury); + pdf__lineto(p, mbox->rect.llx, mbox->rect.ury); + pdf__lineto(p, mbox->rect.llx, mbox->rect.lly); + pdf__fill(p); + } + + if (flags & mbox_border && + mbox->strokecolor.type != (int) color_none && mbox->borderwidth > 0) + { + pdf_set_coloropt(p, pdf_stroke, &mbox->strokecolor); + pdf__setlinewidth(p, mbox->borderwidth); + pdf_setdashpattern_internal(p, mbox->dasharray, mbox->dashlength, + mbox->dashphase); + pdf__setlinecap(p, mbox->linecap); + pdf__setlinejoin(p, mbox->linejoin); + + drawbottom = mbox->drawbottom && + (!(flags & mbox_openbottom) || !mbox->openrect); + if (drawbottom) + { + pdf__moveto(p, mbox->rect.llx, mbox->rect.lly); + pdf__lineto(p, mbox->rect.urx, mbox->rect.lly); + } + + drawright = mbox->drawright && + (!(flags & mbox_openright) || !mbox->openrect); + if (drawright) + { + if (!drawbottom) + pdf__moveto(p, mbox->rect.urx, mbox->rect.lly); + pdf__lineto(p, mbox->rect.urx, mbox->rect.ury); + } + + drawtop = mbox->drawtop && + (!(flags & mbox_opentop) || !mbox->openrect); + if (drawtop) + { + if (!drawright) + pdf__moveto(p, mbox->rect.urx, mbox->rect.ury); + pdf__lineto(p, mbox->rect.llx, mbox->rect.ury); + } + + drawleft = mbox->drawleft && + (!(flags & mbox_openleft) || !mbox->openrect); + if (drawleft) + { + if (!drawtop) + pdf__moveto(p, mbox->rect.llx, mbox->rect.ury); + if (drawbottom && drawright && drawtop) + pdf__closepath(p); + else + pdf__lineto(p, mbox->rect.llx, mbox->rect.lly); + } + + pdf__stroke(p); + } + + if (saverestore) + pdf__restore(p); +} + +const char * +pdf_get_usematchbox(PDF *p, const char *option, const char *optval, + int *istart, int *istop) +{ + const char *boxname = NULL, *stemp = NULL; + char **strlist = NULL; + int errcode = 0; + int k, ir, ns, irect = 1, nrect = 0; + + ns = pdc_split_stringlist(p->pdc, optval, NULL, PDC_SPLIT_ISOPTLIST, + &strlist); + if (ns) + { + boxname = pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, strlist[0]); + + /* number of rectangles */ + pdf_get_mbox(p, NULL, boxname, 0, &nrect); + + if (ns == 2) + { + stemp = pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, + strlist[1]); + + /* rectangle number or all rectangles */ + if (!pdc_str2integer(stemp, 0, &ir)) + { + k = pdc_get_keycode_ci(stemp, pdf_mbox_keylist); + if (k == PDC_KEY_NOTFOUND) + { + errcode = PDC_E_OPT_ILLKEYWORD; + goto PDF_USEMATCHBOX_ERROR; + } + } + else if (ir <= 0) + { + errcode = PDC_E_OPT_ILLINTEGER; + goto PDF_USEMATCHBOX_ERROR; + } + else + { + irect = ir; + nrect = MIN(irect, nrect); + } + } + else + { + irect = 1; + } + } + + PDF_USEMATCHBOX_ERROR: + + pdc_cleanup_stringlist(p->pdc, strlist); + + if (errcode) + pdc_error(p->pdc, errcode, option, stemp, 0, 0); + + *istart = irect; + *istop = nrect; + + return boxname; +} + +static const pdc_keyconn pdf_info_keylist[] = +{ + {"count", 0}, + {"exists", 1}, + {"width", 2}, + {"height", 3}, + {"x1", 4}, + {"y1", 5}, + {"x2", 6}, + {"y2", 7}, + {"x3", 8}, + {"y3", 9}, + {"x4", 10}, + {"y4", 11}, + {NULL, 0} +}; + +double +pdf__info_matchbox(PDF *p, const char *boxname, int len, int num, + const char *keyword) +{ + pdf_mbox *mbox; + char *cname; + double mbinfo = 0; + int infokey, count; + + if (boxname == NULL) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "boxname", 0, 0, 0); + + if (keyword == NULL || *keyword == '0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "keyword", 0, 0, 0); + + /* Converting boxname */ + cname = pdf_convert_name(p, boxname, len, 0); + if (cname == NULL || *cname == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "boxname", 0, 0, 0); + boxname = pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, cname); + pdc_free(p->pdc, cname); + + infokey = pdc_get_keycode_ci(keyword, pdf_info_keylist); + if (infokey == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "keyword", keyword, 0, 0); + + /* count */ + if (!infokey) + { + pdf_get_mbox(p, NULL, boxname, num, &count); + mbinfo = (double) count; + } + else + { + if (num < 1) + pdc_error(p->pdc, PDC_E_ILLARG_INT, "num", + pdc_errprintf(p->pdc, "%d", num), 0, 0); + + mbox = pdf_get_mbox(p, NULL, boxname, num, NULL); + if (mbox != NULL) + { + pdc_vector polyline[5]; + + if (infokey > 1) + pdf_get_mbox_rectangle(p, mbox, polyline); + + switch (infokey) + { + case 1: + mbinfo = 1; + break; + + case 2: + mbinfo = pdc_get_vector_length(&polyline[0], &polyline[1]); + break; + + case 3: + mbinfo = pdc_get_vector_length(&polyline[0], &polyline[3]); + break; + + case 4: + mbinfo = polyline[0].x; + break; + + case 5: + mbinfo = polyline[0].y; + break; + + case 6: + mbinfo = polyline[1].x; + break; + + case 7: + mbinfo = polyline[1].y; + break; + + case 8: + mbinfo = polyline[2].x; + break; + + case 9: + mbinfo = polyline[2].y; + break; + + case 10: + mbinfo = polyline[3].x; + break; + + case 11: + mbinfo = polyline[3].y; + break; + } + } + } + + return mbinfo; +} + + +/* -------------------------- fit functions --------------------------- */ + +void +pdf_init_fit_options(PDF *p, pdc_bool fortflow, pdf_fit_options *fit) +{ + (void) p; + (void) fortflow; + + fit->boxsize[0] = 0; + fit->boxsize[1] = 0; + fit->flags = 0; + fit->fitmethod = pdc_nofit; + fit->margin[0] = 0; + fit->margin[1] = 0; + fit->mask = 0; + fit->pcmask = 0; + fit->shrinklimit = 0.75; + fit->position[0] = 0; + fit->position[1] = 0; + fit->orientate = 0; + fit->rotate = 0; + fit->refpoint[0] = 0; + fit->refpoint[1] = 0; + fit->showborder = pdc_false; + fit->matchbox = NULL; + fit->alignchar = 0; +} + +void +pdf_cleanup_fit_options(PDF *p, pdf_fit_options *fit) +{ + pdf_delete_mbox(p, fit->matchbox); + fit->matchbox = NULL; + + +} + +void +pdf_set_position_values(PDF *p, pdc_scalar *i_position, int nv) +{ + pdc_scalar position[2]; + int i, ipos; + + (void) p; + + position[0] = 0; + position[1] = 0; + + for (i = 0; i < nv; i++) + { + ipos = (int) i_position[i]; + switch(ipos) + { + case pos_left: + case pos_right: + position[0] = i_position[i] - pos_left; + break; + + case pos_bottom: + case pos_top: + position[1] = i_position[i] - pos_bottom; + break; + + default: + position[i] = i_position[i]; + break; + } + } + + if (nv == 1) + position[1] = position[0]; + + i_position[0] = position[0]; + i_position[1] = position[1]; +} + + +void +pdf_get_fit_options(PDF *p, pdc_bool fortflow, pdf_fit_options *fit, + pdc_resopt *resopts) +{ + char **strlist = NULL; + int inum; + + (void) fortflow; + + if (pdc_get_optvalues("fitmethod", resopts, &inum, NULL)) + { + fit->fitmethod = (pdc_fitmethod) inum; + fit->mask |= (1L << fit_fitmethod); + } + + if (pdc_get_optvalues("rotate", resopts, &fit->rotate, NULL)) + fit->mask |= (1L << fit_rotate); + + if (pdc_get_optvalues("orientate", resopts, &fit->orientate, NULL)) + fit->mask |= (1L << fit_orientate); + + pdc_get_optvalues("showborder", resopts, &fit->showborder, NULL); + + if (fit->flags & is_textline) + { + inum = pdc_get_optvalues("margin", resopts, fit->margin, NULL); + if (inum) + { + if (inum == 1) + fit->margin[1] = fit->margin[0]; + fit->mask |= (1L << fit_margin); + } + + if (pdc_get_optvalues("alignchar", resopts, &inum, NULL)) + { + fit->alignchar = (pdc_ushort) inum; + fit->mask |= (1L << fit_alignchar); + } + + } + + if (fit->flags & is_block) + { + if (pdc_get_optvalues("refpoint", resopts, fit->refpoint, NULL)) + fit->mask |= (1L << fit_refpoint); + } + + + if (fit->flags & is_block || !(fit->flags & is_textflow)) + { + if (pdc_get_optvalues("boxsize", resopts, fit->boxsize, NULL)) + fit->mask |= (1L << fit_boxsize); + + if (pdc_get_optvalues("shrinklimit", resopts, &fit->shrinklimit, NULL)) + fit->mask |= (1L << fit_shrinklimit); + + inum = pdc_get_optvalues("position", resopts, fit->position, NULL); + if (inum) + { + pdf_set_position_values(p, fit->position, inum); + fit->mask |= (1L << fit_position); + } + + if (pdc_get_optvalues("matchbox", resopts, NULL, &strlist)) + { + fit->matchbox = pdf_parse_mbox_optlist(p, strlist[0]); + fit->mask |= (1L << fit_matchbox); + } + } +} + +pdc_bool +pdf_is_horiz_orientated(pdf_fit_options *fit) +{ + return (fit->orientate == 0 || fit->orientate == 180) ? + pdc_true : pdc_false; +} + diff --git a/src/pdflib/pdflib/p_object.c b/src/pdflib/pdflib/p_object.c new file mode 100644 index 0000000..8ff285c --- /dev/null +++ b/src/pdflib/pdflib/p_object.c @@ -0,0 +1,257 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_object.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib PDF object functions + * + */ + +#define P_OBJECT_C + +#include "p_intern.h" +#include "p_image.h" + + + +static const pdc_keyconn pdf_scope_keylist[] = +{ + {"object", pdf_state_object}, + {"document", pdf_state_document}, + {"page", pdf_state_page}, + {"pattern", pdf_state_pattern}, + {"template", pdf_state_template}, + {"path", pdf_state_path}, + {"font", pdf_state_font}, + {"glyph", pdf_state_glyph}, + {"glyphmetric", pdf_state_glyphmetric}, + {"glyphignore", pdf_state_glyphignore}, + {"error", pdf_state_error}, + {NULL, 0} +}; + +static pdc_error_info pdf_errors[] = +{ +#define pdf_genInfo 1 +#include "p_generr.h" +}; + +#define N_PDF_ERRORS (sizeof pdf_errors / sizeof (pdc_error_info)) + +const char * +pdf_current_scope(PDF *p) +{ + const char *scopename = + pdc_get_keyword(PDF_GET_STATE(p), pdf_scope_keylist); + + if (!scopename) + pdc_error(p->pdc, PDF_E_INT_BADSCOPE, + pdc_errprintf(p->pdc, " (0x%08X)", PDF_GET_STATE(p)), 0, 0, 0); + + return (char *) scopename; /* be happy, compiler! */ +} + +/* p may be NULL on the first call - we don't use it anyway */ +static void * +default_malloc(PDF *p, size_t size, const char *caller) +{ + void *ret = malloc(size); + + (void) p; + (void) caller; + + return ret; +} + +static void * +default_realloc(PDF *p, void *mem, size_t size, const char *caller) +{ + void *ret = realloc(mem, size); + + (void) p; + (void) caller; + + return ret; +} + +static void +default_free(PDF *p, void *mem) +{ + (void) p; + + free(mem); +} + +PDF * +pdf__new( + void (*errorhandler)(PDF *p, int type, const char *msg), + void* (*allocproc)(PDF *p, size_t size, const char *caller), + void* (*reallocproc)(PDF *p, void *mem, size_t size, const char *caller), + void (*freeproc)(PDF *p, void *mem), + void *opaque) +{ + PDF * p; + pdc_core * pdc; + + /* If allocproc is NULL, all entries are supplied internally by PDFlib */ + if (allocproc == NULL) { + allocproc = default_malloc; + reallocproc = default_realloc; + freeproc = default_free; + } + + p = (PDF *) (*allocproc) (NULL, sizeof(PDF), "PDF_new"); + + if (p == NULL) + return NULL; + + /* + * Guard against crashes when PDF_delete is called without any + * PDF_open_*() in between. + */ + memset((void *)p, 0, (size_t) sizeof(PDF)); + + /* these two are required by PDF_get_opaque() */ + p->magic = PDC_MAGIC; + p->opaque = opaque; + + pdc = pdc_new_core( + (pdc_error_fp) errorhandler, + (pdc_alloc_fp) allocproc, + (pdc_realloc_fp) reallocproc, + (pdc_free_fp) freeproc, p, + PDFLIB_PRODUCTNAME, + PDFLIB_VERSIONSTRING); + + if (pdc == NULL) + { + (*freeproc)(p, p); + return NULL; + } + + pdc_register_errtab(pdc, PDC_ET_PDFLIB, pdf_errors, N_PDF_ERRORS); + fnt_register_errtab(pdc); + + PDC_TRY(pdc) + { + p->freeproc = freeproc; + p->pdc = pdc; + p->compatibility = PDF_DEF_COMPATIBILITY; + p->errorpolicy = errpol_legacy; + + p->userinfo = NULL; + p->document = NULL; + + p->errorhandler = errorhandler; + + p->flush = pdc_flush_page; + + p->hypertextencoding= pdc_invalidenc; + p->hypertextformat = pdc_auto; + p->hypertextcodepage= 0; + p->usercoordinates = pdc_false; + p->usehyptxtenc = pdc_false; + + p->currfo = NULL; + p->curr_ppt = NULL; + + p->glyphcheck = text_nocheck; + p->textformat = pdc_auto; + p->in_text = pdc_false; + + + p->rendintent = AutoIntent; + p->preserveoldpantonenames = pdc_false; + p->spotcolorlookup = pdc_true; + p->ydirection = 1; + p->names = NULL; + p->names_capacity = 0; + p->xobjects = NULL; + p->state_sp = 0; + p->doc_pages = NULL; + + p->actions = NULL; + + + + + + PDF_SET_STATE(p, pdf_state_object); + + /* all debug flags are cleared by default + * because of the above memset... */ + + /* ...but warning messages for non-fatal errors should be set, + * as well as font warnings -- the client must explicitly disable these. + */ + p->debug[(int) 'e'] = pdc_true; + p->debug[(int) 'F'] = pdc_true; + p->debug[(int) 'I'] = pdc_true; + + pdf_init_stringlists(p); + pdf_init_font_options(p, NULL); + + p->out = pdc_boot_output(p->pdc); + + + } + PDC_CATCH(pdc) + { + pdc_delete_core(pdc); + return (PDF *) 0; + } + return p; +} /* pdf__new */ + + +/* + * PDF_delete must be called for cleanup in case of error, + * or when the client is done producing PDF. + * It should never be called more than once for a given PDF, although + * we try to guard against duplicated calls. + * + * Note: all pdf_cleanup_*() functions may safely be called multiple times. + */ + +void +pdf__delete(PDF *p) +{ + /* + * Close the output stream, because it could be open + */ + pdc_close_output(p->out); + + /* + * Clean up page-related stuff if necessary. Do not raise + * an error here since we may be called from the error handler. + */ + pdf_cleanup_document(p); + pdf_cleanup_stringlists(p); + pdf_cleanup_font_curroptions(p); + pdc_cleanup_output(p->out, pdc_false); + + + + + if (p->out) + pdc_free(p->pdc, p->out); + + /* we never reach this point if (p->pdc == NULL). + */ + pdc_delete_core(p->pdc); + + /* free the PDF structure and try to protect against duplicated calls */ + + p->magic = 0L; /* we don't reach this with the wrong magic */ + (*p->freeproc)(p, (void *) p); +} + diff --git a/src/pdflib/pdflib/p_opi.c b/src/pdflib/pdflib/p_opi.c new file mode 100644 index 0000000..94cb435 --- /dev/null +++ b/src/pdflib/pdflib/p_opi.c @@ -0,0 +1,21 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_opi.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib OPI routines + * + */ + +#include "p_intern.h" +#include "p_image.h" + diff --git a/src/pdflib/pdflib/p_page.c b/src/pdflib/pdflib/p_page.c new file mode 100644 index 0000000..c03aaf3 --- /dev/null +++ b/src/pdflib/pdflib/p_page.c @@ -0,0 +1,2261 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_page.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib page related routines + * + */ + +#define P_PAGE_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_font.h" +#include "p_image.h" +#include "p_layer.h" +#include "p_page.h" +#include "p_tagged.h" + + + +#define PDF_N_PAGE_BOXES 5 + +static const pdc_keyconn pdf_labelstyle_pdfkeylist[] = +{ + {"none", label_none}, + {"D", label_123}, + {"R", label_IVX}, + {"r", label_ivx}, + {"A", label_ABC}, + {"a", label_abc}, + {NULL, 0} +}; + +typedef enum +{ + tabo_none, + tabo_row, + tabo_column, + tabo_structure +} +pdf_taborder; + +static const pdc_keyconn pdf_taborder_keylist[] = +{ + {"none", tabo_none}, + {"row", tabo_row}, + {"column", tabo_column}, + {"structure", tabo_structure}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_taborder_pdfkeylist[] = +{ + {"R", tabo_row}, + {"C", tabo_column}, + {"S", tabo_structure}, + {NULL, 0} +}; + +static const pdc_keyconn pdf_colorspace_pdfkeylist[] = +{ + {"DeviceGray", color_gray}, + {"DeviceRGB", color_rgb}, + {"DeviceCMYK", color_cmyk}, + {NULL, 0} +}; + +typedef struct +{ + pdf_colortype colorspace; /* color space */ + pdc_bool isolated; /* isolated flag I */ + pdc_bool knockout; /* knockout flag K */ +} pg_transgroup; + +typedef struct +{ + pdf_labelstyle style; /* page label style */ + char * prefix; /* page label prefix */ + int start; /* page label numbering start */ + /* 0 means "no label" */ +} pg_label; + +typedef struct +{ + char * name; /* group name */ + int n_pages; /* # of pages in this group */ + int capacity; /* # of pages reserved */ + int start; /* 1-based physical page number */ + pg_label label; +} pg_group; + +/* per page resource list +*/ +struct pdf_reslist_s +{ + int * list; /* resource numbers */ + int capacity; + int length; +}; + +/* current, or suspended page. +*/ +typedef struct +{ + pdf_ppt ppt; + + /* list of content stream IDs. + */ + pdc_id * contents_ids; + int contents_ids_capacity; + int next_content; + + pdc_vtr * annots; /* annotation chain */ + + /* local values of global parameters. + */ + pdc_scalar ydir; /* p->ydirection */ + + /* resource lists. + */ + pdf_reslist rl_colorspaces; + pdf_reslist rl_extgstates; + pdf_reslist rl_fonts; + pdf_reslist rl_layers; + pdf_reslist rl_patterns; + pdf_reslist rl_shadings; + pdf_reslist rl_xobjects; +} pdf_page; + + +/* PDF page object. +*/ +typedef struct +{ + pg_label label; + pdc_id id; /* object id for this page */ + pdf_page * pg; /* NULL if this page is not suspended */ + + /* object ids (PDC_BAD_ID if not present). + */ + pdc_id annots_id; /* id of page's /Annots entry */ + pdc_id contents_id; /* id of page's /Contents entry */ + pdc_id res_id; /* id of page's /Resources entry */ + pdc_id thumb_id; /* id of page's /Thumb entry */ + + int rotate; /* page's /Rotate entry */ + int transition; /* page transition type, or -1 */ + int taborder; /* page taborder type */ + double duration; /* page display duration, or -1 */ + pdc_scalar userunit; /* page user unit */ + char * action; /* "action" option string */ + + pg_transgroup tgroup; /* transparency group definition */ + + + pdc_id * act_idlist; /* action object ids */ + pdc_rectangle * boxes[PDF_N_PAGE_BOXES]; /* MediaBox etc. */ +} page_obj; + + +struct pdf_pages_s +{ + pdf_page *curr_pg; + pdc_bool have_labels; + pdc_bool have_groups; + pdc_bool in_csect; /* currently in contents section */ + int last_suspended; /* 1-based page number or -1 */ + pdf_ppt default_ppt; /* pseudo-ppt (for document scope) */ + + /* as long as we support the old global parameters in addition to + ** the new options, we have to save their values on entry to + ** begin/resume_page(), and restore them during end/suspend_page(). + */ + pdc_scalar old_ydir; /* p->ydirection */ + + /* deprecated parameters. + */ + int transition; /* page transition type */ + double duration; /* page display duration */ + + /* page descriptors in physical page order. + */ + page_obj * pages; /* page ids and suspended page descr */ + int pages_capacity; + int current_page; /* current page number (1-based) */ + int last_page; /* last page number allocated yet */ + int max_page; /* highest page number pre-allocated yet */ + + /* page groups. + */ + pg_group * groups; + int groups_capacity; + int n_groups; + + pdc_id *pnodes; /* page tree node ids */ + int pnodes_capacity; /* current # of entries in pnodes */ + int current_pnode; /* current node number (0-based) */ + int current_pnode_kids; /* current # of kids in current node */ +}; + + +static const pdc_rectangle pdf_null_rect = +{ + 0, 0, 0, 0 +}; + + +/*********************** initialization & cleanup ***********************/ + +static void +pdf_init_ppt(PDF *p, pdc_bool new_ppt) +{ + pdf_ppt *ppt = p->curr_ppt; + + if (new_ppt) + { + ppt->cstate = 0; + ppt->tstate = 0; + + ppt->mboxes = (pdc_vtr *) 0; + + ppt->cs_bias = 0; + ppt->eg_bias = 0; + ppt->fn_bias = 0; + ppt->pt_bias = 0; + ppt->sh_bias = 0; + ppt->xo_bias = 0; + } + + ppt->sl = 0; + + pdf_init_tstate(p); + pdf_init_gstate(p); + pdf_init_cstate(p); +} /* pdf_init_ppt */ + +static void +pdf_reset_ppt(pdf_ppt *ppt) +{ + if (ppt->mboxes) + { + pdc_vtr_delete(ppt->mboxes); + ppt->mboxes = (pdc_vtr *) 0; + } +} + +static void +pdf_delete_page(PDF *p, pdf_page *pg) +{ + if (pg != 0) + { + pdf_cleanup_page_cstate(p, &pg->ppt); + pdf_cleanup_page_tstate(p, &pg->ppt); + pdf_reset_ppt(&pg->ppt); + + if (pg->contents_ids) + pdc_free(p->pdc, pg->contents_ids); + + if (pg->annots) + { + pdc_vtr_delete(pg->annots); + pg->annots = (pdc_vtr *) 0; + } + + if (pg->rl_colorspaces.list) + pdc_free(p->pdc, pg->rl_colorspaces.list); + if (pg->rl_extgstates.list) + pdc_free(p->pdc, pg->rl_extgstates.list); + if (pg->rl_fonts.list) + pdc_free(p->pdc, pg->rl_fonts.list); + if (pg->rl_layers.list) + pdc_free(p->pdc, pg->rl_layers.list); + if (pg->rl_patterns.list) + pdc_free(p->pdc, pg->rl_patterns.list); + if (pg->rl_shadings.list) + pdc_free(p->pdc, pg->rl_shadings.list); + if (pg->rl_xobjects.list) + pdc_free(p->pdc, pg->rl_xobjects.list); + + pdc_free(p->pdc, pg); + } +} /* pdf_delete_page */ + + +static void +pdf_init_page_obj(page_obj *po) +{ + int i; + + po->id = PDC_BAD_ID; + po->pg = (pdf_page *) 0; + po->label.start = 0; + po->label.prefix = (char *) 0; + + po->tgroup.colorspace = color_none; + po->tgroup.isolated = pdc_false; + po->tgroup.knockout = pdc_false; + + po->annots_id = PDC_BAD_ID; + po->contents_id = PDC_BAD_ID; + po->res_id = PDC_BAD_ID; + po->thumb_id = PDC_BAD_ID; + po->transition = -1; + po->duration = -1; + po->taborder = (int) tabo_none; + po->userunit = 1.0; + po->action = (char *) 0; + + po->rotate = 0; + + po->act_idlist = (pdc_id *) 0; + for (i = 0; i < PDF_N_PAGE_BOXES; ++i) + po->boxes[i] = (pdc_rectangle *) 0; +} /* pdf_init_page_obj */ + + +static void +pdf_grow_pages(PDF *p) +{ + static const char fn[] = "pdf_grow_pages"; + + pdf_pages *dp = p->doc_pages; + int i; + + dp->pages = (page_obj *) pdc_realloc(p->pdc, dp->pages, + 2 * sizeof (page_obj) * dp->pages_capacity, fn); + + for (i = dp->pages_capacity; i < dp->pages_capacity * 2; i++) + pdf_init_page_obj(&dp->pages[i]); + + dp->pages_capacity *= 2; +} /* pdf_grow_pages */ + + +void +pdf_init_pages(PDF *p, const char **groups, int n_groups) +{ + static const char fn[] = "pdf_init_pages"; + + int i, k; + pdf_pages * dp = (pdf_pages *) pdc_malloc(p->pdc, sizeof (pdf_pages), fn); + + p->doc_pages = dp; + + dp->have_labels = pdc_false; + dp->have_groups = (n_groups != 0); + dp->n_groups = 0; + dp->last_suspended = 0; + dp->in_csect = pdc_false; + dp->transition = (int) trans_none; + dp->duration = 0; + + dp->pages = (page_obj *) 0; + dp->pnodes = (pdc_id *) 0; + + dp->pages_capacity = PAGES_CHUNKSIZE; + dp->pages = (page_obj *) + pdc_malloc(p->pdc, sizeof (page_obj) * dp->pages_capacity, fn); + + /* mark ids to allow for pre-allocation of page ids */ + for (i = 0; i < dp->pages_capacity; i++) + pdf_init_page_obj(&dp->pages[i]); + + dp->current_page = 0; + dp->last_page = 0; + dp->max_page = 0; + dp->curr_pg = (pdf_page *) 0; + + dp->pnodes_capacity = PNODES_CHUNKSIZE; + dp->pnodes = (pdc_id *) + pdc_malloc(p->pdc, sizeof (pdc_id) * dp->pnodes_capacity, fn); + + dp->current_pnode = 0; + dp->current_pnode_kids = 0; + + /* clients may set char/word spacing and horizontal scaling outside pages + ** for PDF_stringwidth() calculations, and they may set a color for use + ** in PDF_makespotcolor(). that's what default_ppt is good for. + */ + p->curr_ppt = &dp->default_ppt; + pdf_init_ppt(p, pdc_true); + + for (i = 0; i < n_groups - 1; ++i) + for (k = i + 1; k < n_groups; ++k) + if (strcmp(groups[i], groups[k]) == 0) + { + pdc_error(p->pdc, PDF_E_DOC_DUPLGROUP, groups[i], 0, 0, 0); + } + + dp->n_groups = n_groups; + dp->groups = (pg_group *) (n_groups ? + pdc_malloc(p->pdc, sizeof (pg_group) * n_groups, fn) : 0); + + for (i = 0; i < n_groups; ++i) + { + dp->groups[i].name = pdc_strdup(p->pdc, groups[i]); + dp->groups[i].n_pages = 0; + dp->groups[i].capacity = 0; + dp->groups[i].start = 1; + dp->groups[i].label.prefix = (char *) 0; + dp->groups[i].label.start = 0; + } +} /* pdf_init_pages */ + + +void pdf_check_suspended_pages(PDF *p) +{ + int i; + pdf_pages * dp = p->doc_pages; + + for (i = 0; i <= dp->last_page; ++i) + { + if (dp->pages[i].pg != (pdf_page *) 0) + { + pdc_error(p->pdc, PDF_E_PAGE_SUSPENDED, + pdc_errprintf(p->pdc, "%d", i), 0, 0, 0); + } + } +} /* pdf_check_suspended_pages */ + + +void +pdf_cleanup_pages(PDF *p) +{ + if (p->doc_pages != (pdf_pages *) 0) + { + int i; + pdf_pages * dp = p->doc_pages; + + if (dp->groups) + { + for (i = 0; i < dp->n_groups; ++i) + { + if (dp->groups[i].name) + pdc_free(p->pdc, dp->groups[i].name); + + if (dp->groups[i].label.prefix) + pdc_free(p->pdc, dp->groups[i].label.prefix); + } + + pdc_free(p->pdc, dp->groups); + } + + if (dp->curr_pg) + pdf_delete_page(p, dp->curr_pg); + + if (dp->pages) + { + for (i = 0; i <= dp->last_page; ++i) + { + int k; + page_obj *po = &dp->pages[i]; + + if (po->label.prefix) + pdc_free(p->pdc, po->label.prefix); + + if (po->action) + pdc_free(p->pdc, po->action); + + + if (po->pg != (pdf_page *) 0) + pdf_delete_page(p, po->pg); + + if (po->act_idlist != (pdc_id *) 0) + pdc_free(p->pdc, po->act_idlist); + + for (k = 0; k < PDF_N_PAGE_BOXES; ++k) + { + if (po->boxes[k] != (pdc_rectangle *) 0) + pdc_free(p->pdc, po->boxes[k]); + } + } + + pdc_free(p->pdc, dp->pages); + } + + if (dp->pnodes) + { + pdc_free(p->pdc, dp->pnodes); + } + + if (p->curr_ppt != 0) + { + pdf_cleanup_page_cstate(p, &dp->default_ppt); + pdf_cleanup_page_tstate(p, &dp->default_ppt); + } + + pdc_free(p->pdc, p->doc_pages); + p->doc_pages = (pdf_pages *) 0; + } +} /* pdf_cleanup_pages */ + + +/******************** page group & labels management ********************/ + +static pg_group * +find_group(pdf_pages *dp, const char *name) +{ + int i; + + for (i = 0; i < dp->n_groups; ++i) + if (strcmp(dp->groups[i].name, name) == 0) + return &dp->groups[i]; + + return (pg_group *) 0; +} /* find_group */ + + +static void +grow_group(PDF *p, pg_group *group, int pageno, int n) +{ + pdf_pages * dp = p->doc_pages; + int i; + + while (dp->max_page + n >= dp->pages_capacity) + pdf_grow_pages(p); + + if (dp->max_page >= pageno) + { + memmove(&dp->pages[pageno + n], &dp->pages[pageno], + (dp->max_page - pageno + 1) * sizeof (page_obj)); + + for (i = pageno; i < pageno + n; ++i) + pdf_init_page_obj(&dp->pages[i]); + } + + dp->max_page += n; + + if (dp->last_page >= pageno) + dp->last_page += n; + + if (dp->current_page >= pageno) + dp->current_page += n; + + group->capacity += n; + + for (i = group - dp->groups + 1; i < dp->n_groups; ++i) + dp->groups[i].start += n; +} + + +/* translate the group-relative pageno to an absolute page number. +** as a side effect, the group gets enlarged as needed if pageno +** exceeds the current number of pages in the group. +*/ +int +pdf_xlat_pageno(PDF *p, int pageno, const char *groupname) +{ + pdf_pages * dp = p->doc_pages; + pg_group * group = (pg_group *) 0; + + if (groupname && *groupname) + { + if ((group = find_group(dp, groupname)) == (pg_group *) 0) + pdc_error(p->pdc, PDF_E_DOC_UNKNOWNGROUP, groupname, 0, 0, 0); + } + + if (group) + { + if (pageno < 1) + pdc_error(p->pdc, PDF_E_PAGE_NOTEXIST2, + pdc_errprintf(p->pdc, "%d", pageno), group->name, 0, 0); + + if (pageno > group->capacity) + grow_group(p, group, group->start + group->capacity, + pageno - group->capacity); + + pageno = group->start + pageno - 1; + } + else + { + if (dp->have_groups && pageno != 0) + pdc_error(p->pdc, PDF_E_PAGE_NEEDGROUP, 0, 0, 0, 0); + } + + return pageno; +} + + +/* TODO (york): get rid of this function. +*/ +void +pdf_init_pages2(PDF *p) +{ + pdf_pages * dp = p->doc_pages; + + dp->pnodes[0] = pdc_alloc_id(p->out); +} /* pdf_init_pages2 */ + + +static const pdc_defopt pdf_pagelabel_options[] = +{ + {"pagenumber", pdc_integerlist, PDC_OPT_NONE, 1, 1, + 1.0, PDC_INT_MAX, NULL}, + + {"group", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 1.0, PDF_MAX_NAMESTRING, NULL}, + + {"style", pdc_keywordlist, PDC_OPT_CASESENS, 1, 1, + 0.0, 0.0, pdf_labelstyle_pdfkeylist}, + + {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"prefix", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 0.0, PDF_MAX_NAMESTRING, NULL}, + + {"start", pdc_integerlist, PDC_OPT_NONE, 1, 1, + 1.0, PDC_INT_MAX, NULL}, + + PDC_OPT_TERMINATE +}; + +void +pdf_set_pagelabel(PDF *p, const char *optlist, int pageno) +{ + pdf_pages * dp = p->doc_pages; + pg_label * lp; + pdc_resopt *resopts = NULL; + char ** strlist; + int inum; + + int page = 0; + char * groupname = NULL; + pdf_labelstyle style = label_none; + pdc_encoding htenc; + int htcp; + char * prefix = NULL; + int start = 1; + + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_pagelabel_options, + NULL, pdc_true); + + switch (pageno) + { + case PDF_FC_BEGIN_DOCUMENT: + if (pdc_get_optvalues("group", resopts, NULL, &strlist)) + groupname = strlist[0]; + else + pdc_error(p->pdc, PDF_E_DOC_NEED_LABELOPT, "group", 0, 0, 0); + + if (pdc_get_optvalues("pagenumber", resopts, &page, NULL)) + pdc_error(p->pdc, PDF_E_DOC_ILL_LABELOPT, + "pagenumber", 0, 0, 0); + break; + + case PDF_FC_END_DOCUMENT: + if (pdc_get_optvalues("group", resopts, NULL, &strlist)) + pdc_error(p->pdc, PDF_E_DOC_ILL_LABELOPT, "group", 0, 0, 0); + + if (!pdc_get_optvalues("pagenumber", resopts, &page, NULL)) + pdc_error(p->pdc, PDF_E_DOC_NEED_LABELOPT, + "pagenumber", 0, 0, 0); + + break; + + default: + if (pdc_get_optvalues("group", resopts, NULL, &strlist)) + pdc_error(p->pdc, PDF_E_DOC_ILL_LABELOPT, "group", 0, 0, 0); + + if (pdc_get_optvalues("pagenumber", resopts, &page, NULL)) + pdc_error(p->pdc, PDF_E_DOC_ILL_LABELOPT, + "pagenumber", 0, 0, 0); + + page = pageno; + break; + } + + if (pdc_get_optvalues("style", resopts, &inum, NULL)) + style = (pdf_labelstyle) inum; + + htenc = pdf_get_hypertextencoding_opt(p, resopts, &htcp, pdc_true); + + pdf_get_opt_textlist(p, "prefix", resopts, htenc, htcp, + pdc_true, NULL, &prefix, NULL); + pdc_get_optvalues("start", resopts, &start, NULL); + + dp->have_labels = pdc_true; + + if (groupname) + { + pg_group *group; + + if ((group = find_group(dp, groupname)) == (pg_group *) 0) + pdc_error(p->pdc, PDF_E_DOC_UNKNOWNGROUP, groupname, 0, 0, 0); + + lp = &group->label; + } + else + { + if (dp->last_page < page) + pdc_error(p->pdc, PDF_E_PAGE_NOTEXIST, + pdc_errprintf(p->pdc, "%d", page), 0, 0, 0); + + lp = &dp->pages[page].label; + } + + lp->style = style; + lp->start = start; + + if (prefix) + { + if (lp->prefix) + pdc_free(p->pdc, lp->prefix); + + lp->prefix = pdc_strdup(p->pdc, prefix); + } +} /* pdf_set_pagelabel */ + + +static void +write_label(PDF *p, pg_label *label, int pageno) +{ + pdc_printf(p->out, "%d", pageno); + pdc_begin_dict(p->out); + + if (label->style != label_none) + { + pdc_printf(p->out, "/S/%s", + pdc_get_keyword(label->style, pdf_labelstyle_pdfkeylist)); + } + + if (label->prefix) + { + pdc_printf(p->out, "/P"); + pdf_put_hypertext(p, label->prefix); + } + + if (label->start != 1) + pdc_printf(p->out, "/St %d", label->start); + + pdc_end_dict(p->out); +} /* write_label */ + + +pdc_id +pdf_write_pagelabels(PDF *p) +{ + pdf_pages * dp = p->doc_pages; + pdc_id result; + int i, k; + + if (!dp->have_labels || dp->last_page == 0) + return PDC_BAD_ID; + + result = pdc_begin_obj(p->out, PDC_NEW_ID); + pdc_begin_dict(p->out); + + pdc_printf(p->out, "/Nums"); + pdc_begin_array(p->out); + + /* generate default label if page 1 doesn't have one: + */ + if (dp->pages[1].label.start == 0 && + (dp->n_groups == 0 || dp->groups[0].label.start == 0)) + { + pdc_puts(p->out, "0"); + pdc_begin_dict(p->out); + pdc_puts(p->out, "/S/D"); /* 1-based decimal w/o prefix */ + pdc_end_dict(p->out); + } + + if (dp->n_groups == 0) + { + for (i = 1; i <= dp->last_page; ++i) + if (dp->pages[i].label.start != 0) + write_label(p, &dp->pages[i].label, i - 1); + } + else + { + for (i = 0; i < dp->n_groups; ++i) + { + pg_group *gp = &dp->groups[i]; + + if (gp->label.start != 0 && gp->n_pages != 0) + { + /* if present, the page label beats the group label. + */ + if (dp->pages[gp->start].label.start == 0) + write_label(p, &gp->label, gp->start - 1); + } + + for (k = gp->start; k < gp->start + gp->n_pages; ++k) + if (dp->pages[k].label.start != 0) + write_label(p, &dp->pages[k].label, k - 1); + } + } + + pdc_end_array_c(p->out); + pdc_end_dict(p->out); + pdc_end_obj(p->out); + + return result; +} /* pdf_write_pagelabels */ + +static const pdc_defopt pdf_transgroup_options[] = +{ + {"CS", pdc_keywordlist, PDC_OPT_NONE, 1, 1, + 1.0, PDC_INT_MAX, pdf_colorspace_pdfkeylist}, + + {"I", pdc_booleanlist, PDC_OPT_NONE, 1, 1, + 0.0, 0.0, NULL}, + + {"K", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ + + PDC_OPT_TERMINATE +}; + +static void +pdf_set_transgroup(PDF *p, const char *optlist, int pageno) +{ + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[pageno]; + pdc_resopt *resopts = NULL; + int inum; + + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_transgroup_options, + NULL, pdc_true); + + if (pdc_get_optvalues("CS", resopts, &inum, NULL)) + po->tgroup.colorspace = (pdf_colortype) inum; + + pdc_get_optvalues("I", resopts, &po->tgroup.isolated, NULL); + pdc_get_optvalues("K", resopts, &po->tgroup.knockout, NULL); +} + +static void +write_transgroup(PDF *p, int pageno) +{ + pdf_pages * dp = p->doc_pages; + page_obj *po = &dp->pages[pageno]; + + pdc_puts(p->out, "/Group"); + pdc_begin_dict(p->out); + pdc_printf(p->out, "/S/Transparency/CS/%s", + pdc_get_keyword(po->tgroup.colorspace, + pdf_colorspace_pdfkeylist)); + + if (po->tgroup.isolated) + pdc_printf(p->out, "/I true"); + + if (po->tgroup.knockout) + pdc_printf(p->out, "/K true"); + + pdc_end_dict(p->out); +} + + +/************************** utility functions ***************************/ + +/* get the id of an existing or future page. +** pageno == 0 means current page. note that pdf_get_page_id(0) returns +** PDC_BAD_ID if no page has been opened yet, whereas pdf_current_page_id() +** returns a pre-allocated id for page 1 in this case. +*/ +pdc_id +pdf_get_page_id(PDF *p, int pageno) +{ + pdf_pages *dp = p->doc_pages; + + if (pageno == 0) + { + return dp->pages[dp->current_page].id; + } + else + { + while (pageno >= dp->pages_capacity) + pdf_grow_pages(p); + + /* preallocate page object id for a later page + */ + if (dp->pages[pageno].id == PDC_BAD_ID) + dp->pages[pageno].id = pdc_alloc_id(p->out); + + return dp->pages[pageno].id; + } +} /* pdf_get_page_id */ + +int +pdf_current_page(PDF *p) +{ + pdf_pages *dp = p->doc_pages; + + return dp ? dp->current_page : 0; +} /* pdf_current_page */ + +/* get the id of the current page. if there are no pages in the +** document yet, an id will be pre-allocated for page 1. +*/ +int +pdf_current_page_id(PDF *p) +{ + pdf_pages *dp = p->doc_pages; + + if (dp->current_page != 0) + return dp->pages[dp->current_page].id; + else + return pdf_get_page_id(p, 1); +} /* pdf_current_page_id */ + +int +pdf_last_page(PDF *p) +{ + return p->doc_pages->last_page; +} /* pdf_last_page */ + +int +pdf_search_page_fwd(PDF *p, int start_page, pdc_id id) +{ + pdf_pages * dp = p->doc_pages; + int i; + + for (i = start_page; i <= dp->last_page; ++i) + { + if (dp->pages[i].id == id) + return i; + } + + return -1; +} /* pdf_search_page_fwd */ + +int +pdf_search_page_bwd(PDF *p, int start_page, pdc_id id) +{ + pdf_pages * dp = p->doc_pages; + int i; + + if (start_page == -1) + start_page = dp->last_page; + + for (i = start_page; i > 0; --i) + { + if (dp->pages[i].id == id) + return i; + } + + return -1; +} /* pdf_search_page_bwd */ + + +double +pdf_get_pageheight(PDF *p) +{ + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + return po->boxes[pdf_mediabox]->ury - po->boxes[pdf_mediabox]->lly; +} /* pdf_get_pageheight */ + +void +pdf_set_pagebox( + PDF * p, + pdf_pagebox box, + pdc_scalar llx, + pdc_scalar lly, + pdc_scalar urx, + pdc_scalar ury) +{ + static const char fn[] = "pdf_set_pagebox"; + + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + if (po->boxes[box] == (pdc_rectangle *) 0) + { + po->boxes[box] = (pdc_rectangle *) + pdc_malloc(p->pdc, sizeof (pdc_rectangle), fn); + } + + pdc_rect_init(po->boxes[box], llx, lly, urx, ury); +} /* pdf_set_pagebox */ + +void +pdf_set_pagebox_llx(PDF *p, pdf_pagebox box, pdc_scalar llx) +{ + static const char fn[] = "pdf_set_pagebox_llx"; + + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + if (po->boxes[box] == (pdc_rectangle *) 0) + { + po->boxes[box] = (pdc_rectangle *) + pdc_malloc(p->pdc, sizeof (pdc_rectangle), fn); + + pdc_rect_init(po->boxes[box], 0, 0, 0, 0); + } + + po->boxes[box]->llx = llx; +} /* pdf_set_pagebox_llx */ + +void +pdf_set_pagebox_lly(PDF *p, pdf_pagebox box, pdc_scalar lly) +{ + static const char fn[] = "pdf_set_pagebox_lly"; + + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + if (po->boxes[box] == (pdc_rectangle *) 0) + { + po->boxes[box] = (pdc_rectangle *) + pdc_malloc(p->pdc, sizeof (pdc_rectangle), fn); + + pdc_rect_init(po->boxes[box], 0, 0, 0, 0); + } + + po->boxes[box]->lly = lly; +} /* pdf_set_pagebox_lly */ + +void +pdf_set_pagebox_urx(PDF *p, pdf_pagebox box, pdc_scalar urx) +{ + static const char fn[] = "pdf_set_pagebox_urx"; + + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + if (po->boxes[box] == (pdc_rectangle *) 0) + { + po->boxes[box] = (pdc_rectangle *) + pdc_malloc(p->pdc, sizeof (pdc_rectangle), fn); + + pdc_rect_init(po->boxes[box], 0, 0, 0, 0); + } + + po->boxes[box]->urx = urx; +} /* pdf_set_pagebox_urx */ + +void +pdf_set_pagebox_ury(PDF *p, pdf_pagebox box, pdc_scalar ury) +{ + static const char fn[] = "pdf_set_pagebox_ury"; + + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + if (po->boxes[box] == (pdc_rectangle *) 0) + { + po->boxes[box] = (pdc_rectangle *) + pdc_malloc(p->pdc, sizeof (pdc_rectangle), fn); + + pdc_rect_init(po->boxes[box], 0, 0, 0, 0); + } + + po->boxes[box]->ury = ury; +} /* pdf_set_pagebox_ury */ + +const pdc_rectangle * +pdf_get_pagebox(PDF *p, pdf_pagebox box) +{ + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + if (po->boxes[box]) + return po->boxes[box]; + else + return &pdf_null_rect; +} /* pdf_get_pagebox */ + +pdc_vtr * +pdf_get_annots_list(PDF *p) +{ + pdf_pages * dp = p->doc_pages; + + return dp->curr_pg->annots; +} /* pdf_get_annots_list */ + +void +pdf_set_annots_list(PDF *p, pdc_vtr *annots) +{ + pdf_pages * dp = p->doc_pages; + + if (dp->curr_pg) + dp->curr_pg->annots = annots; +} /* pdf_set_annots_list */ + + +pdc_id +pdf_get_thumb_id(PDF *p) +{ + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + return po->thumb_id; +} /* pdf_get_thumb_id */ + +void +pdf_set_thumb_id(PDF *p, pdc_id id) +{ + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + po->thumb_id = id; +} /* pdf_set_thumb_id */ + + +/************************* contents sections ***************************/ + +void +pdf_begin_contents_section(PDF *p) +{ + pdf_page *pg = p->doc_pages->curr_pg; + + if (PDF_GET_STATE(p) != pdf_state_page || p->doc_pages->in_csect) + return; + + p->doc_pages->in_csect = pdc_true; + + if (pg->next_content >= pg->contents_ids_capacity) { + pg->contents_ids_capacity *= 2; + pg->contents_ids = (pdc_id *) pdc_realloc(p->pdc, pg->contents_ids, + sizeof(pdc_id) * pg->contents_ids_capacity, + "pdf_begin_contents_section"); + } + + pg->contents_ids[pg->next_content] = pdc_begin_obj(p->out, PDC_NEW_ID); + pdc_begin_dict(p->out); + p->length_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Length", p->length_id); + + if (pdc_get_compresslevel(p->out)) + pdc_puts(p->out, "/Filter/FlateDecode\n"); + + pdc_end_dict(p->out); + + pdc_begin_pdfstream(p->out); + + pg->next_content++; +} /* pdf_begin_contents_section */ + + +void +pdf_end_contents_section(PDF *p) +{ + if (!p->doc_pages->in_csect) + return; + + p->doc_pages->in_csect = pdc_false; + + pdf_end_text(p); + pdc_end_pdfstream(p->out); + pdc_end_obj(p->out); + + pdc_put_pdfstreamlength(p->out, p->length_id); +} /* pdf_end_contents_section */ + + +/************************* page tree generation *************************/ + +static void +pdf_write_pnode(PDF *p, + pdc_id node_id, + pdc_id parent_id, + page_obj *kids, + int n_kids, + int n_pages) +{ + pdc_begin_obj(p->out, node_id); + pdc_begin_dict(p->out); + pdc_puts(p->out, "/Type/Pages\n"); + pdc_printf(p->out, "/Count %d\n", n_pages); + + if (parent_id != PDC_BAD_ID) + pdc_objref(p->out, "/Parent", parent_id); + + pdc_puts(p->out, "/Kids"); + pdc_begin_array(p->out); + + do + { + pdc_objref_c(p->out, kids->id); + ++kids; + } while (--n_kids > 0); + + pdc_end_array_c(p->out); + pdc_end_dict(p->out); + pdc_end_obj(p->out); +} /* pdf_write_pnode */ + +#define N_KIDS 10 + +static pdc_id +pdf_get_pnode_id(PDF *p) +{ + static const char fn[] = "pdf_get_pnode_id"; + + pdf_pages *dp = p->doc_pages; + + if (dp->current_pnode_kids == N_KIDS) + { + if (++dp->current_pnode == dp->pnodes_capacity) + { + dp->pnodes_capacity *= 2; + dp->pnodes = (pdc_id *) pdc_realloc(p->pdc, dp->pnodes, + sizeof (pdc_id) * dp->pnodes_capacity, fn); + } + + dp->pnodes[dp->current_pnode] = pdc_alloc_id(p->out); + dp->current_pnode_kids = 1; + } + else + ++dp->current_pnode_kids; + + return dp->pnodes[dp->current_pnode]; +} /* pdf_get_pnode_id */ + +static pdc_id +write_pages_tree(PDF *p, + pdc_id parent_id, + pdc_id *pnodes, + page_obj *pages, + int n_pages) +{ + if (n_pages <= N_KIDS) + { + /* this is a near-to-leaf node. use the pre-allocated id + ** from dp->pnodes. + */ + pdf_write_pnode(p, *pnodes, parent_id, pages, n_pages, n_pages); + return *pnodes; + } + else + { + pdc_id node_id = pdc_alloc_id(p->out); + page_obj kids[N_KIDS]; + int n_kids, rest; + int tpow = N_KIDS; + int i; + + /* tpow < n_pages <= tpow*N_KIDS + */ + while (tpow * N_KIDS < n_pages) + tpow *= N_KIDS; + + n_kids = n_pages / tpow; + rest = n_pages % tpow; + + for (i = 0; i < n_kids; ++i, pnodes += tpow / N_KIDS, pages += tpow) + { + kids[i].id = write_pages_tree(p, node_id, pnodes, pages, tpow); + } + + if (rest) + { + kids[i].id = write_pages_tree(p, node_id, pnodes, pages, rest); + ++n_kids; + } + + pdf_write_pnode(p, node_id, parent_id, kids, n_kids, n_pages); + return node_id; + } +} /* write_pages_tree */ + +static void +pdf_write_box(PDF *p, pdc_rectangle *box, const char *name) +{ + if (!box || pdc_rect_isnull(box)) + return; + + if (box->urx <= box->llx || box->ury <= box->lly) + { + pdc_error(p->pdc, PDF_E_PAGE_BADBOX, name, + pdc_errprintf(p->pdc, "%f %f %f %f", + box->llx, box->lly, box->urx, box->ury), 0, 0); + } + + pdc_printf(p->out, "/%s[%f %f %f %f]\n", + name, box->llx, box->lly, box->urx, box->ury); +} /* pdf_write_box */ + +pdc_id +pdf_write_pages_tree(PDF *p) +{ + int i; + pdf_pages * dp = p->doc_pages; + + for (i = dp->last_page + 1; i < dp->pages_capacity; ++i) + { + if (dp->pages[i].id != PDC_BAD_ID) + { + pdc_error(p->pdc, PDF_E_PAGE_ILLREF, + pdc_errprintf(p->pdc, "%d", i), 0, 0, 0); + } + } + + for (i = 1; i <= dp->last_page; ++i) + { + page_obj *po = &dp->pages[i]; + + pdc_begin_obj(p->out, po->id); + pdc_begin_dict(p->out); + pdc_puts(p->out, "/Type/Page\n"); + pdc_objref(p->out, "/Parent", pdf_get_pnode_id(p)); + + if (po->annots_id != PDC_BAD_ID) + pdc_objref(p->out, "/Annots", po->annots_id); + + if (po->contents_id != PDC_BAD_ID) + pdc_objref(p->out, "/Contents", po->contents_id); + + if (po->res_id != PDC_BAD_ID) + pdc_objref(p->out, "/Resources", po->res_id); + + if (po->thumb_id != PDC_BAD_ID) + pdc_objref(p->out, "/Thumb", po->thumb_id); + + if (po->duration > 0) + pdc_printf(p->out, "/Dur %f\n", po->duration); + + if (po->taborder != (int) tabo_none) + pdc_printf(p->out, "/Tabs/%s\n", + pdc_get_keyword(po->taborder, pdf_taborder_pdfkeylist)); + + if (po->userunit > 1.0) + pdc_printf(p->out, "/UserUnit %f\n", po->userunit); + + if (po->rotate > 0) + pdc_printf(p->out, "/Rotate %d\n", po->rotate); + + if (po->action) + pdf_write_action_entries(p, event_page, po->act_idlist); + + + + + if (po->transition != trans_none) + { + pdc_puts(p->out, "/Trans"); + pdc_begin_dict(p->out); + pdc_printf(p->out, "/S/%s", + pdc_get_keyword(po->transition, pdf_transition_pdfkeylist)); + + pdc_end_dict(p->out); + } + + if (po->tgroup.colorspace != color_none) + write_transgroup(p, i); + + pdf_write_box(p, po->boxes[pdf_artbox], "ArtBox"); + pdf_write_box(p, po->boxes[pdf_bleedbox], "BleedBox"); + pdf_write_box(p, po->boxes[pdf_cropbox], "CropBox"); + pdf_write_box(p, po->boxes[pdf_mediabox], "MediaBox"); + pdf_write_box(p, po->boxes[pdf_trimbox], "TrimBox"); + + pdc_end_dict(p->out); + pdc_end_obj(p->out); + } + + return write_pages_tree(p, PDC_BAD_ID, dp->pnodes, dp->pages + 1, + dp->last_page); +} /* pdf_write_pages_tree */ + + +/**************************** resource lists ****************************/ + +static void +pdf_init_reslist(pdf_reslist *rl) +{ + rl->length = 0; + rl->capacity = 0; + rl->list = (int *) 0; +} /* pdf_init_reslist */ + +void +pdf_add_reslist(PDF *p, pdf_reslist *rl, int num) +{ + static const char fn[] = "pdf_add_reslist"; + + if (rl->length == rl->capacity) + { + if (rl->capacity == 0) + { + rl->capacity = RESLIST_CHUNKSIZE; + rl->list = (int *) + pdc_malloc(p->pdc, rl->capacity * sizeof (pdf_reslist), fn); + } + else + { + rl->capacity *= 2; + rl->list = (int *) pdc_realloc(p->pdc, + rl->list, rl->capacity * sizeof (pdf_reslist), fn); + } + } + + rl->list[rl->length++] = num; +} /* pdf_add_reslist */ + + +/****************************** begin_page ******************************/ + +/* begin_page_ext() only: +*/ +#define PDF_ICC_FLAG PDC_OPT_UNSUPP +#define PDF_SPOT_FLAG PDC_OPT_UNSUPP + +#define PDF_METADATA_FLAG PDC_OPT_UNSUPP + +static const pdc_defopt pdf_sepinfo_options[] = +{ + {"pages", pdc_integerlist, PDC_OPT_NONE, 1, 1, + 1.0, PDC_INT_MAX, NULL}, + + {"spotname", pdc_stringlist, PDC_OPT_NONE, 1, 1, + 1.0, PDF_MAX_NAMESTRING, NULL}, + + {"spotcolor", pdc_colorhandle, PDC_OPT_NONE, 1, 1, + 1.0, PDC_INT_MAX, NULL}, + + PDC_OPT_TERMINATE +}; + +#define PDF_PAGE_OPTIONS1 \ +\ + {"topdown", pdc_booleanlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, NULL}, \ +\ + {"defaultgray", pdc_iccprofilehandle, PDF_ICC_FLAG, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"defaultrgb", pdc_iccprofilehandle, PDF_ICC_FLAG, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"defaultcmyk", pdc_iccprofilehandle, PDF_ICC_FLAG, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"separationinfo", pdc_stringlist, PDF_SPOT_FLAG, 1, 1, \ + 0.0, PDC_USHRT_MAX, NULL}, \ + +/* begin_page_ext() and resume_page(): +*/ +#define PDF_PAGE_OPTIONS2 \ +\ + {"group", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 1.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"pagenumber", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + 1.0, PDC_INT_MAX, NULL}, \ + +/* begin_page_ext() and end_page_ext(): +*/ +static const pdc_keyconn pdf_pagedim_keylist[] = +{ + { "a0.width", (int) a0_width }, + { "a0.height", (int) a0_height }, + { "a1.width", (int) a1_width }, + { "a1.height", (int) a1_height }, + { "a2.width", (int) a2_width }, + { "a2.height", (int) a2_height }, + { "a3.width", (int) a3_width }, + { "a3.height", (int) a3_height }, + { "a4.width", (int) a4_width }, + { "a4.height", (int) a4_height }, + { "a5.width", (int) a5_width }, + { "a5.height", (int) a5_height }, + { "a6.width", (int) a6_width }, + { "a6.height", (int) a6_height }, + { "b5.width", (int) b5_width }, + { "b5.height", (int) b5_height }, + { "letter.width", (int) letter_width }, + { "letter.height", (int) letter_height }, + { "legal.width", (int) legal_width }, + { "legal.height", (int) legal_height }, + { "ledger.width", (int) ledger_width }, + { "ledger.height", (int) ledger_height }, + { "11x17.width", (int) p11x17_width }, + { "11x17.height", (int) p11x17_height }, + { NULL, 0 } +}; + +typedef enum +{ + pdf_unit_mm = -1000, + pdf_unit_cm = -100, + pdf_unit_m = -1 +} +pdf_page_unit; + +static const pdc_keyconn pdf_userunit_keylist[] = +{ + { "mm", pdf_unit_mm }, + { "cm", pdf_unit_cm }, + { "m", pdf_unit_m }, + + { NULL, 0 } +}; + + +#define PDF_PAGE_OPTIONS3 \ +\ + {"action", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 1.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"artbox", pdc_scalarlist, PDC_OPT_NONE, 4, 4,\ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL},\ +\ + {"bleedbox", pdc_scalarlist, PDC_OPT_NONE, 4, 4,\ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL},\ +\ + {"cropbox", pdc_scalarlist, PDC_OPT_NONE, 4, 4,\ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL},\ +\ + {"duration", pdc_scalarlist, PDC_OPT_NONE, 1, 1,\ + 0.0, PDC_FLOAT_MAX, NULL},\ +\ + {"height", pdc_scalarlist, PDC_OPT_NONE, 1, 1,\ + 0.0, PDC_FLOAT_MAX, pdf_pagedim_keylist},\ +\ + {"label", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 0.0, PDC_USHRT_MAX, NULL}, \ +\ + {"mediabox", pdc_scalarlist, PDC_OPT_NONE, 4, 4,\ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL},\ +\ + {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1, \ + 0.0, PDC_INT_MAX, NULL}, \ +\ + {"rotate", pdc_integerlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 270, NULL}, \ +\ + {"transition", pdc_keywordlist, PDC_OPT_NONE, 1, 1, \ + 0.0, 0.0, pdf_transition_keylist}, \ +\ + {"transparencygroup", pdc_stringlist, PDC_OPT_NONE, 1, 1, \ + 1.0, PDF_MAX_NAMESTRING, NULL}, \ +\ + {"taborder", pdc_keywordlist, PDC_OPT_PDC_1_5, 1, 1, \ + 0.0, 0.0, pdf_taborder_keylist}, \ +\ + {"trimbox", pdc_scalarlist, PDC_OPT_NONE, 4, 4,\ + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL},\ +\ + {"userunit", pdc_scalarlist, PDC_OPT_PDC_1_6, 1, 1,\ + 1.0, 75000, pdf_userunit_keylist},\ +\ + {"width", pdc_scalarlist, PDC_OPT_NONE, 1, 1,\ + 0.0, PDC_FLOAT_MAX, pdf_pagedim_keylist},\ + +/* common helper function for pdf__begin_page_ext() and pdf__resume_page(). +** returns the target group (if any) and the target page number. the +** page number is relative to the group (if available). page number -1 +** means "no page number". +*/ +static pg_group * +get_page_options2(PDF *p, pdc_resopt *resopts, int *pageno) +{ + pdf_pages * dp = p->doc_pages; + pg_group * group = (pg_group *) 0; + char ** strlist; + + *pageno = -1; + + if (pdc_get_optvalues("pagenumber", resopts, pageno, NULL)) + { + if (*pageno <= 0) + pdc_error(p->pdc, PDF_E_PAGE_ILLNUMBER, + pdc_errprintf(p->pdc, "%d", *pageno), 0, 0, 0); + } + + if (pdc_get_optvalues("group", resopts, NULL, &strlist)) + { + if ((group = find_group(dp, strlist[0])) == (pg_group *) 0) + pdc_error(p->pdc, PDF_E_DOC_UNKNOWNGROUP, strlist[0], 0, 0, 0); + } + + if (group) + { + if (*pageno > group->n_pages) + pdc_error(p->pdc, PDF_E_PAGE_NOTEXIST2, + pdc_errprintf(p->pdc, "%d", *pageno), group->name, 0, 0); + } + else + { + if (dp->have_groups) + pdc_error(p->pdc, PDF_E_PAGE_NEEDGROUP, 0, 0, 0, 0); + + if (*pageno > dp->last_page) + pdc_error(p->pdc, PDF_E_PAGE_NOTEXIST, + pdc_errprintf(p->pdc, "%d", *pageno), 0, 0, 0); + } + + return group; +} /* get_page_options2 */ + +static pdc_rectangle * +pdf_new_box(PDF *p, const pdc_rectangle *box) +{ + static const char fn[] = "pdf_new_box"; + + pdc_rectangle *result = (pdc_rectangle *) + pdc_malloc(p->pdc, sizeof (pdc_rectangle), fn); + + if (box) + *result = *box; + else + pdc_rect_init(result, 0, 0, 0, 0); + return result; +} /* pdf_new_box */ + +/* common helper function for pdf__begin_page_ext() and pdf__end_page_ext(). +*/ +static void +get_page_options3(PDF *p, pdc_resopt *resopts, pdc_bool end_page) +{ + pdf_pages * dp = p->doc_pages; + int pageno = dp->current_page; + page_obj * po = &dp->pages[pageno]; + pdc_scalar width; + pdc_scalar height; + pdc_bool has_width; + pdc_bool has_height; + pdc_bool has_mediabox; + pdc_rectangle box; + char **slist; + + if (pdc_get_optvalues("action", resopts, NULL, NULL)) + { + po->action = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + pdf_parse_and_write_actionlist(p, event_page, NULL, + (char *) po->action); + } + + if (pdc_get_optvalues("artbox", resopts, &box, NULL)) + po->boxes[pdf_artbox] = pdf_new_box(p, &box); + if (pdc_get_optvalues("bleedbox", resopts, &box, NULL)) + po->boxes[pdf_bleedbox] = pdf_new_box(p, &box); + if (pdc_get_optvalues("cropbox", resopts, &box, NULL)) + po->boxes[pdf_cropbox] = pdf_new_box(p, &box); + if (pdc_get_optvalues("trimbox", resopts, &box, NULL)) + po->boxes[pdf_trimbox] = pdf_new_box(p, &box); + + pdc_get_optvalues("taborder", resopts, &po->taborder, NULL); + pdc_get_optvalues("duration", resopts, &po->duration, NULL); + pdc_get_optvalues("userunit", resopts, &po->userunit, NULL); + if (po->userunit < 1.0) + po->userunit = 72.0 / (PDC_INCH2METER * fabs(po->userunit)); + + if (pdc_get_optvalues("label", resopts, NULL, NULL)) + { + char *pagelabel = pdf_get_opt_utf8name(p, "label", resopts); + pdf_set_pagelabel(p, pagelabel, pageno); + pdc_free(p->pdc, pagelabel); + } + + if (pdc_get_optvalues("transparencygroup", resopts, NULL, &slist)) + pdf_set_transgroup(p, slist[0], pageno); + + /* the "width" and "height" options must be processed BEFORE the + ** "mediabox" option, since the latter dominates over the formers. + */ + has_width = pdc_get_optvalues("width", resopts, &width, NULL); + has_height = pdc_get_optvalues("height", resopts, &height, NULL); + + if (has_width) + po->boxes[pdf_mediabox]->urx = po->boxes[pdf_mediabox]->llx + width; + + if (has_height) + po->boxes[pdf_mediabox]->ury = po->boxes[pdf_mediabox]->lly + height; + + has_mediabox = + pdc_get_optvalues("mediabox", resopts, po->boxes[pdf_mediabox], NULL); + + width = po->boxes[pdf_mediabox]->urx - po->boxes[pdf_mediabox]->llx; + height = po->boxes[pdf_mediabox]->ury - po->boxes[pdf_mediabox]->lly; + + if (p->ydirection == -1) + { + if (end_page) + { + if (has_mediabox || has_width || has_height) + pdc_error(p->pdc, PDF_E_PAGE_ILLCHGSIZE, 0, 0, 0, 0); + } + else + { + if (width == 0 || height == 0) + pdc_error(p->pdc, PDF_E_PAGE_TOPDOWN_NODIMS, 0, 0, 0, 0); + + if ((height < PDF_ACRO_MINPAGE || width < PDF_ACRO_MINPAGE || + height > PDF_ACRO_MAXPAGE || width > PDF_ACRO_MAXPAGE)) + pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0); + } + } + + + pdc_get_optvalues("rotate", resopts, &po->rotate, NULL); + switch (po->rotate) + { + case 0: case 90: case 180: case 270: + break; + + default: + pdc_error(p->pdc, PDF_E_PAGE_ILLROTATE, + pdc_errprintf(p->pdc, "%d", po->rotate), 0, 0, 0); + } + + pdc_get_optvalues("transition", resopts, &po->transition, NULL); + if (po->transition >= (int) TRANS_1_5 && p->compatibility < PDC_1_5) + pdc_error(p->pdc, PDF_E_PAGE_TRANS_COMPAT, + pdc_get_keyword(po->transition, pdf_transition_keylist), 0, 0, 0); +} /* get_page_options3 */ + + + +static const pdc_defopt pdf_begin_page_ext_options[] = +{ + PDF_PAGE_OPTIONS1 + PDF_PAGE_OPTIONS2 + PDF_PAGE_OPTIONS3 + + PDC_OPT_TERMINATE +}; + + +void +pdf__begin_page_ext( + PDF * p, + pdc_scalar width, + pdc_scalar height, + const char *optlist) +{ + static const char fn[] = "pdf__begin_page_ext"; + + pdf_pages * dp = p->doc_pages; + pdf_page * pg; + page_obj * po; + + + pdc_resopt *resopts = NULL; + pg_group * group = (pg_group *) 0; + int pageno = -1; + + pdc_check_number_limits(p->pdc, "width", width, 0.0, PDC_FLOAT_MAX); + pdc_check_number_limits(p->pdc, "height", height, 0.0, PDC_FLOAT_MAX); + + if (optlist && *optlist) + { + pdc_clientdata cdata; + + pdf_set_clientdata(p, &cdata); + resopts = pdc_parse_optionlist(p->pdc, + optlist, pdf_begin_page_ext_options, &cdata, pdc_true); + + group = get_page_options2(p, resopts, &pageno); + } + + if (group) + { + if (pageno == -1) + pageno = group->start + group->n_pages; + else + pageno = group->start + pageno - 1; + + if (++group->n_pages > group->capacity) + { + grow_group(p, group, pageno, 1); + } + else if (pageno < group->start + group->n_pages - 1) + { + memmove(&dp->pages[pageno + 1], &dp->pages[pageno], + (group->start + group->n_pages - pageno) * sizeof (page_obj)); + + pdf_init_page_obj(&dp->pages[pageno]); + } + + if (dp->last_page < group->start + group->n_pages - 1) + dp->last_page = group->start + group->n_pages - 1; + } + else + { + if (dp->last_page + 1 >= dp->pages_capacity) + pdf_grow_pages(p); + + ++dp->last_page; + + if (dp->last_page > dp->max_page) + ++dp->max_page; + + if (pageno == -1) + pageno = dp->last_page; + + if (pageno != dp->last_page) + { + memmove(&dp->pages[pageno + 1], &dp->pages[pageno], + (dp->max_page - pageno) * sizeof (page_obj)); + + pdf_init_page_obj(&dp->pages[pageno]); + } + } + + po = &dp->pages[pageno]; + dp->current_page = pageno; + + /* no id has been preallocated */ + if (po->id == PDC_BAD_ID) + po->id = pdc_alloc_id(p->out); + + pg = dp->curr_pg = (pdf_page *) pdc_malloc(p->pdc, sizeof (pdf_page), fn); + p->curr_ppt = &pg->ppt; + + pg->contents_ids = (pdc_id *) 0; + pg->annots = (pdc_vtr *) 0; + + /* save and take over global parameters. + */ + pg->ydir = dp->old_ydir = p->ydirection; + + pg->rl_colorspaces.list = (int *) 0; + pg->rl_extgstates.list = (int *) 0; + pg->rl_fonts.list = (int *) 0; + pg->rl_layers.list = (int *) 0; + pg->rl_patterns.list = (int *) 0; + pg->rl_shadings.list = (int *) 0; + pg->rl_xobjects.list = (int *) 0; + + pg->contents_ids_capacity = CONTENTS_CHUNKSIZE; + pg->contents_ids = (pdc_id *) pdc_malloc(p->pdc, + sizeof(pdc_id) * pg->contents_ids_capacity, fn); + + /* might be overwritten by options */ + po->boxes[pdf_mediabox] = pdf_new_box(p, 0); + pdc_rect_init(po->boxes[pdf_mediabox], 0, 0, width, height); + + if (resopts) + { + pdc_bool topdown = pdc_false; + + if (pdc_get_optvalues("topdown", resopts, &topdown, NULL)) + p->ydirection = pg->ydir = topdown ? -1 : 1; + + + get_page_options3(p, resopts, pdc_false); + } + + /* initialize the current ppt descriptor. p->ydirection + ** must be set before pdf_init_ppt()! + */ + pdf_init_ppt(p, pdc_true); + + pg->next_content = 0; + + pdf_init_reslist(&pg->rl_colorspaces); + pdf_init_reslist(&pg->rl_extgstates); + pdf_init_reslist(&pg->rl_fonts); + pdf_init_reslist(&pg->rl_layers); + pdf_init_reslist(&pg->rl_patterns); + pdf_init_reslist(&pg->rl_shadings); + pdf_init_reslist(&pg->rl_xobjects); + + PDF_SET_STATE(p, pdf_state_page); + + pdf_begin_contents_section(p); + + /* top-down y coordinates */ + pdf_set_topdownsystem(p, pdf_get_pageheight(p)); + + /* set color differing from PDF default */ + pdf_set_default_color(p, pdc_false); + + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Begin page #%d]\n", + dp->current_page); + +} /* pdf__begin_page_ext */ + + +void +pdf__begin_page( + PDF * p, + pdc_scalar width, + pdc_scalar height) +{ + if (p->doc_pages->have_groups) + pdc_error(p->pdc, PDF_E_PAGE_NEEDGROUP2, 0, 0, 0, 0); + + pdf__begin_page_ext(p, width, height, 0); +} /* pdf__begin_page */ + + +/*************************** suspend & resume ***************************/ + +void +pdf_pg_suspend(PDF *p) +{ + pdf_pages *dp = p->doc_pages; + + if (PDF_GET_STATE(p) != pdf_state_page) + { + dp->last_suspended = -1; + } + else + { + pdf_page *pg = dp->curr_pg; + + pdf_end_contents_section(p); + + /* restore global parms. + */ + p->ydirection = dp->old_ydir; + + pdf_get_page_colorspaces(p, &pg->rl_colorspaces); + pdf_get_page_extgstates(p, &pg->rl_extgstates); + pdf_get_page_fonts(p, &pg->rl_fonts); + pdf_get_page_patterns(p, &pg->rl_patterns); + pdf_get_page_shadings(p, &pg->rl_shadings); + pdf_get_page_xobjects(p, &pg->rl_xobjects); + + dp->pages[dp->current_page].pg = pg; + dp->curr_pg = (pdf_page *) 0; + dp->last_suspended = dp->current_page; + + /* restore the default ppt for out-of-page usage. + */ + p->curr_ppt = &dp->default_ppt; + } + + pdf_init_ppt(p, pdc_false); +} /* pdf_pg_suspend */ + + +static const pdc_defopt pdf_suspend_page_options[] = +{ + PDC_OPT_TERMINATE +}; + +void +pdf__suspend_page(PDF *p, const char *optlist) +{ + if (optlist && *optlist) + { + pdc_resopt *resopts = pdc_parse_optionlist(p->pdc, + optlist, pdf_suspend_page_options, NULL, pdc_true); + + (void) resopts; + } + + pdf_pg_suspend(p); + PDF_SET_STATE(p, pdf_state_document); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Suspend page #%d]\n", + p->doc_pages->current_page); +} /* pdf__suspend_page */ + + +void +pdf_pg_resume(PDF *p, int pageno) +{ + pdf_pages *dp = p->doc_pages; + + pdf_reset_ppt(p->curr_ppt); + + if (pageno == -1) + { + pageno = dp->last_suspended; + dp->last_suspended = -1; + } + + if (pageno == -1) + { + PDF_SET_STATE(p, pdf_state_document); + } + else + { + pdf_page *pg; + int i; + + /* prevent error cleanup from killing the same page twice. + */ + pg = dp->curr_pg = dp->pages[pageno].pg; + dp->pages[pageno].pg = (pdf_page *) 0; + + dp->current_page = pageno; + p->curr_ppt = &pg->ppt; + + PDF_SET_STATE(p, pdf_state_page); + + /* save global parameters and replace them + ** with the page specific ones. + */ + dp->old_ydir = p->ydirection; + + p->ydirection = pg->ydir; + + pdf_begin_contents_section(p); + + /* mark global resources as "used on current page". + */ + for (i = 0; i < pg->rl_colorspaces.length; ++i) + pdf_mark_page_colorspace(p, pg->rl_colorspaces.list[i]); + + for (i = 0; i < pg->rl_extgstates.length; ++i) + pdf_mark_page_extgstate(p, pg->rl_extgstates.list[i]); + + for (i = 0; i < pg->rl_fonts.length; ++i) + pdf_mark_page_font(p, pg->rl_fonts.list[i]); + + + for (i = 0; i < pg->rl_patterns.length; ++i) + pdf_mark_page_pattern(p, pg->rl_patterns.list[i]); + + for (i = 0; i < pg->rl_shadings.length; ++i) + pdf_mark_page_shading(p, pg->rl_shadings.list[i]); + + for (i = 0; i < pg->rl_xobjects.length; ++i) + pdf_mark_page_xobject(p, pg->rl_xobjects.list[i]); + } +} /* pdf_pg_resume */ + + +static const pdc_defopt pdf_resume_page_options[] = +{ + PDF_PAGE_OPTIONS2 + + PDC_OPT_TERMINATE +}; + +void +pdf__resume_page(PDF *p, const char *optlist) +{ + pdf_pages * dp = p->doc_pages; + pg_group * group = (pg_group *) 0; + int pageno = -1; /* logical page number */ + int physno; /* physical page number */ + + if (optlist && *optlist) + { + pdc_resopt *resopts = pdc_parse_optionlist(p->pdc, + optlist, pdf_resume_page_options, NULL, pdc_true); + + group = get_page_options2(p, resopts, &pageno); + } + + if (group) + { + if (pageno == -1) + pageno = group->n_pages; + + physno = group->start + pageno - 1; + } + else + { + if (pageno == -1) + pageno = dp->last_page; + + physno = pageno; + } + + if (dp->pages[physno].pg == (pdf_page *) 0) + { + if (group) + { + pdc_error(p->pdc, PDF_E_PAGE_NOSUSPEND2, + pdc_errprintf(p->pdc, "%d", pageno), group->name, 0, 0); + } + else + { + pdc_error(p->pdc, PDF_E_PAGE_NOSUSPEND, + pdc_errprintf(p->pdc, "%d", pageno), 0, 0, 0); + } + } + + pdf_pg_resume(p, physno); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Resume page #%d]\n", physno); + +} /* pdf__resume_page */ + + +/******************************* end_page *******************************/ + + +static const pdc_defopt pdf_end_page_ext_options[] = +{ + PDF_PAGE_OPTIONS3 + + PDC_OPT_TERMINATE +}; + +void +pdf__end_page_ext(PDF *p, const char *optlist) +{ + static const char fn[] = "pdf__end_page_ext"; + + pdf_pages * dp = p->doc_pages; + page_obj * po = &dp->pages[dp->current_page]; + + pdc_scalar width; + pdc_scalar height; + pdf_page * pg; + pdf_ppt * ppt = p->curr_ppt; + int i; + + + if (optlist && *optlist) + { + pdc_resopt *resopts = pdc_parse_optionlist(p->pdc, + optlist, pdf_end_page_ext_options, NULL, pdc_true); + + get_page_options3(p, resopts, pdc_true); + } + + width = po->boxes[pdf_mediabox]->urx - po->boxes[pdf_mediabox]->llx; + height = po->boxes[pdf_mediabox]->ury - po->boxes[pdf_mediabox]->lly; + + if (width == 0 || height == 0) + pdc_error(p->pdc, PDF_E_PAGE_NODIMS, 0, 0, 0, 0); + + if ((height < PDF_ACRO_MINPAGE || width < PDF_ACRO_MINPAGE || + height > PDF_ACRO_MAXPAGE || width > PDF_ACRO_MAXPAGE)) + pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0); + + + + + /* check whether PDF_save() and PDF_restore() calls are balanced */ + if (ppt->sl > 0) + pdc_error(p->pdc, PDF_E_GSTATE_UNMATCHEDSAVE, 0, 0, 0, 0); + + /* TODO (york): avoid memory leak in error case. */ + pg = dp->curr_pg; + + + pdf_end_contents_section(p); + + + /* if no "duration" or "transition" options have been specified + ** for this page, fall back on the (deprecated) global parameters. + */ + if (po->duration == -1) + po->duration = dp->duration; + + if (po->transition == -1) + po->transition = dp->transition; + + if (pg->next_content > 0) + { + if (pg->next_content == 1) + { + po->contents_id = pg->contents_ids[0]; + } + else + { + po->contents_id = pdc_begin_obj(p->out, PDC_NEW_ID); + pdc_begin_array(p->out); + + for (i = 0; i < pg->next_content; ++i) + { + pdc_objref_c(p->out, pg->contents_ids[i]); + } + + pdc_end_array(p->out); + pdc_end_obj(p->out); + } + } + + if (po->action) + { + po->act_idlist = (pdc_id *) + pdc_malloc(p->pdc, PDF_MAX_EVENTS * sizeof (pdc_id), fn); + + pdf_parse_and_write_actionlist(p, event_page, po->act_idlist, + po->action); + } + + po->annots_id = pdf_write_annots_root(p, pg->annots, NULL); + + /* resources dictionary + */ + po->res_id = pdc_begin_obj(p->out, PDC_NEW_ID); + + pdc_begin_dict(p->out); + + pdf_write_page_fonts(p); /* Font resources */ + + pdf_write_page_colorspaces(p); /* ColorSpace resources */ + + pdf_write_page_pattern(p); /* Pattern resources */ + + pdf_write_page_shadings(p); /* Shading resources */ + + pdf_write_xobjects(p); /* XObject resources */ + + pdf_write_page_extgstates(p); /* ExtGState resources */ + + + pdc_end_dict(p->out); + pdc_end_obj(p->out); + + if (pg->annots != (pdc_vtr *) 0) + pdf_write_page_annots(p, pg->annots); /* Annotation dicts */ + + + /* restore global parms. + */ + p->ydirection = dp->old_ydir; + + /* restore the default ppt for out-of-page usage. + */ + p->curr_ppt = &dp->default_ppt; + pdf_init_ppt(p, pdc_false); + PDF_SET_STATE(p, pdf_state_document); + pdf_delete_page(p, pg); + dp->curr_pg = (pdf_page *) 0; + + if (p->flush & (pdc_flush_page | pdc_flush_content)) + pdc_flush_stream(p->out); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[End page #%d]\n", + dp->current_page); + +} /* pdf__end_page_ext */ + + +/*****************************************************************************/ +/** deprecated historical page functions **/ +/*****************************************************************************/ + +/* set page display duration for current and future pages */ + +void +pdf_set_duration(PDF *p, double t) +{ + p->doc_pages->duration = t; +} + +/* set transition mode for current and future pages */ + +void +pdf_set_transition(PDF *p, const char *transition) +{ + int i; + + if (transition == NULL || !*transition) + transition = "none"; + + i = pdc_get_keycode_ci(transition, pdf_transition_keylist); + + if (i == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, transition, "transition", 0, 0); + + if (i >= (int) TRANS_1_5 && p->compatibility < PDC_1_5) + pdc_error(p->pdc, PDF_E_PAGE_TRANS_COMPAT, + pdc_get_keyword(i, pdf_transition_keylist), 0, 0, 0); + + p->doc_pages->transition = i; +} + diff --git a/src/pdflib/pdflib/p_page.h b/src/pdflib/pdflib/p_page.h new file mode 100644 index 0000000..3f496e4 --- /dev/null +++ b/src/pdflib/pdflib/p_page.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_page.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Header file for the PDFlib page system + * + */ + +#ifndef P_PAGE_H +#define P_PAGE_H + +/* the "pageno" parameter for function pdf_set_pagelabel() can take +** negative values, indicating the calling function. +*/ +#define PDF_FC_BEGIN_DOCUMENT -1 +#define PDF_FC_END_DOCUMENT -2 +void pdf_set_pagelabel(PDF *p, const char *optlist, int pageno); + +pdc_id pdf_write_pages_tree(PDF *p); + +void pdf_set_transition(PDF *p, const char *type); +void pdf_set_duration(PDF *p, double t); + +#endif /* P_PAGE_H */ diff --git a/src/pdflib/pdflib/p_pantlab.h b/src/pdflib/pdflib/p_pantlab.h new file mode 100644 index 0000000..79c35cc --- /dev/null +++ b/src/pdflib/pdflib/p_pantlab.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_pantlab.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib PANTONE spot LAB color table derived from + * PANTONE MATCHING SYSTEM + * + * PANTONE and PANTONE MATCHING SYSTEM is a registered trademark of + * Pantone,Inc. + * + */ + +#ifndef P_PANTLAB_H +#define P_PANTLAB_H + + +#endif /* P_PANTAB_H */ + diff --git a/src/pdflib/pdflib/p_params.c b/src/pdflib/pdflib/p_params.c new file mode 100644 index 0000000..e55a8b1 --- /dev/null +++ b/src/pdflib/pdflib/p_params.c @@ -0,0 +1,1306 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_params.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib parameter handling + * + */ + +#define P_PARAMS_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_font.h" +#include "p_image.h" +#include "p_page.h" +#include "p_tagged.h" + +static const pdc_keyconn pdf_fillrule_keylist[] = +{ + {"winding", pdf_fill_winding }, + {"evenodd", pdf_fill_evenodd }, + {NULL, 0} +}; + +/* + * PDF_get_parameter() and PDF_set_parameter() deal with strings, + * PDF_get_value() and PDF_set_value() deal with numerical values. + */ + +typedef struct +{ + char * name; /* parameter name */ + pdc_bool mod_zero; /* PDF_get_() modifier argument must be 0 */ + pdc_bool check_scope; /* check following scope for PDF_get_...() */ + int scope; /* bit mask of legal states */ + +} +pdf_parm_descr; + +static pdf_parm_descr parms[] = +{ +#define pdf_gen_parm_descr 1 +#include "p_params.h" +#undef pdf_gen_parm_descr + + { "", 0, 0, 0 } +}; + +enum +{ +#define pdf_gen_parm_enum 1 +#include "p_params.h" +#undef pdf_gen_parm_enum + + PDF_PARAMETER_LIMIT +}; + +static int +pdf_get_index(PDF *p, const char *key, pdc_bool setpar) +{ + int i; + + if (key == NULL || !*key) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "key", 0, 0, 0); + + for (i = 0; i < PDF_PARAMETER_LIMIT; ++i) + { + if (pdc_stricmp(key, parms[i].name) == 0) + { + if ((setpar || parms[i].check_scope) && + (p->state_stack[p->state_sp] & parms[i].scope) == 0) + pdc_error(p->pdc, PDF_E_DOC_SCOPE_SET, key, + pdf_current_scope(p), 0, 0); + return i; + } + } + + if (i == PDF_PARAMETER_LIMIT) + pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0); + + return -1; +} + +static pdc_bool +pdf_bool_value(PDF *p, const char *key, const char *value) +{ + if (!pdc_stricmp(value, "true")) + return pdc_true; + + if (!pdc_stricmp(value, "false")) + return pdc_false; + + pdc_error(p->pdc, PDC_E_ILLARG_BOOL, key, value, 0, 0); + + return pdc_false; /* compilers love it */ +} + +void +pdf__set_parameter(PDF *p, const char *key, const char *value) +{ + pdc_pagebox usebox = pdc_pbox_none; + pdc_text_format textformat = pdc_auto; + char optlist[512]; + pdf_ppt *ppt; + int i, k; + + i = pdf_get_index(p, key, pdc_true); + + if (value == NULL) value = ""; + + ppt = p->curr_ppt; + + switch (i) + { + case PDF_PARAMETER_PDIUSEBOX: + case PDF_PARAMETER_VIEWAREA: + case PDF_PARAMETER_VIEWCLIP: + case PDF_PARAMETER_PRINTAREA: + case PDF_PARAMETER_PRINTCLIP: + k = pdc_get_keycode_ci(value, pdf_usebox_keylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + usebox = (pdc_pagebox) k; + strcpy(optlist, key); + strcat(optlist, " "); + strcat(optlist, value); + break; + + case PDF_PARAMETER_TEXTFORMAT: + case PDF_PARAMETER_HYPERTEXTFORMAT: + k = pdc_get_keycode_ci(value, pdf_textformat_keylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + textformat = (pdc_text_format) k; + break; + } + + switch (i) + { + case PDF_PARAMETER_SEARCHPATH: + case PDF_PARAMETER_FONTAFM: + case PDF_PARAMETER_FONTPFM: + case PDF_PARAMETER_FONTOUTLINE: + case PDF_PARAMETER_HOSTFONT: + case PDF_PARAMETER_ENCODING: + case PDF_PARAMETER_ICCPROFILE: + case PDF_PARAMETER_STANDARDOUTPUTINTENT: + { + pdf_add_resource(p, key, value); + break; + } + + case PDF_PARAMETER_DEBUG: + { + const unsigned char *c; + + for (c = (const unsigned char *) value; *c; c++) + p->debug[(int) *c] = 1; + break; + } + + case PDF_PARAMETER_NODEBUG: + { + const unsigned char *c; + + for (c = (const unsigned char *) value; *c; c++) + p->debug[(int) *c] = 0; + break; + } + + case PDF_PARAMETER_BINDING: + if (!p->pdc->binding) + p->pdc->binding = pdc_strdup(p->pdc, value); + break; + + case PDF_PARAMETER_OBJORIENT: + p->pdc->objorient = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_HASTOBEPOS: + p->pdc->hastobepos = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_PTFRUN: + p->pdc->ptfrun = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_SMOKERUN: + p->pdc->smokerun = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_UNICAPLANG: + p->pdc->unicaplang = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_ERRORPOLICY: + k = pdc_get_keycode_ci(value, pdf_errpol_keylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + p->errorpolicy = (pdf_errpol) k; + break; + + case PDF_PARAMETER_UNDERLINE: + pdf_set_tstate(p, (double) pdf_bool_value(p, key, value), + to_underline); + break; + + case PDF_PARAMETER_OVERLINE: + pdf_set_tstate(p, (double) pdf_bool_value(p, key, value), + to_overline); + break; + + case PDF_PARAMETER_STRIKEOUT: + pdf_set_tstate(p, (double) pdf_bool_value(p, key, value), + to_strikeout); + break; + + case PDF_PARAMETER_KERNING: + pdc_warning(p->pdc, PDF_E_UNSUPP_KERNING, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_FAKEBOLD: + pdf_set_tstate(p, (double) pdf_bool_value(p, key, value), + to_fakebold); + break; + + + case PDF_PARAMETER_RESOURCEFILE: + pdc_set_resourcefile(p->pdc, value); + break; + + case PDF_PARAMETER_RENDERINGINTENT: + k = pdc_get_keycode_ci(value, pdf_renderingintent_pdfkeylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + p->rendintent = (pdf_renderingintent) k; + break; + + case PDF_PARAMETER_PRESERVEOLDPANTONENAMES: + p->preserveoldpantonenames = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_SPOTCOLORLOOKUP: + p->spotcolorlookup = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_PDISTRICT: + p->pdi_strict = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_TOPDOWN: + if (pdf_bool_value(p, key, value)) + p->ydirection = -1.0; + else + p->ydirection = 1.0; + break; + + case PDF_PARAMETER_USERCOORDINATES: + p->usercoordinates = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_USEHYPERTEXTENCODING: + p->usehyptxtenc = pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_TEXTFORMAT: + pdf_check_textformat(p, textformat); + p->textformat = textformat; + if (p->curr_ppt) + pdf_set_tstate(p, (double) textformat, to_textformat); + break; + + case PDF_PARAMETER_HYPERTEXTFORMAT: + pdf_check_hypertextformat(p, textformat); + p->hypertextformat = textformat; + break; + + case PDF_PARAMETER_HYPERTEXTENCODING: + { + p->hypertextencoding = + pdf_get_hypertextencoding(p, value, &p->hypertextcodepage, + pdc_true); + pdf_check_hypertextencoding(p, p->hypertextencoding); + break; + } + + case PDF_PARAMETER_CHARREF: + pdc_warning(p->pdc, PDF_E_UNSUPP_CHARREF, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_ESCAPESEQUENCE: + pdc_warning(p->pdc, PDF_E_UNSUPP_ESCAPESEQU, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_HONORLANG: + pdc_warning(p->pdc, PDF_E_UNSUPP_HONORLANG, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_GLYPHCHECK: + pdc_warning(p->pdc, PDF_E_UNSUPP_GLYPHCHECK, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_FILLRULE: + k = pdc_get_keycode_ci(value, pdf_fillrule_keylist); + if (k == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + ppt->fillrule = (pdf_fillrule) k; + break; + + case PDF_PARAMETER_LOGGING: + pdc_set_logg_options(p->pdc, value); + break; + + case PDF_PARAMETER_LOGMSG: + pdc_logg_cond(p->pdc, 1, trc_user, value); + break; + + case PDF_PARAMETER_TRACEMSG: + /* do nothing -- client-supplied string will show up + * in the log file + */ + break; + + case PDF_PARAMETER_NODEMOSTAMP: + break; + + case PDF_PARAMETER_SERIAL: + case PDF_PARAMETER_LICENCE: + case PDF_PARAMETER_LICENSE: + break; + + case PDF_PARAMETER_LICENCEFILE: + case PDF_PARAMETER_LICENSEFILE: + break; + + case PDF_PARAMETER_AUTOSPACE: + pdc_warning(p->pdc, PDF_E_UNSUPP_TAGGED, 0, 0, 0, 0); + break; + +/*****************************************************************************/ +/** deprecated historical parameters **/ +/*****************************************************************************/ + + case PDF_PARAMETER_OPENWARNING: + p->debug[(int) 'o'] = (char) pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_FONTWARNING: + p->debug[(int) 'F'] = (char) pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_ICCWARNING: + p->debug[(int) 'I'] = (char) pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_IMAGEWARNING: + p->debug[(int) 'i'] = (char) pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_PDIWARNING: + p->debug[(int) 'p'] = (char) pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_HONORICCPROFILE: + p->debug[(int) 'e'] = (char) pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_GLYPHWARNING: + p->debug[(int) 'g'] = (char) pdf_bool_value(p, key, value); + if (p->curr_ppt) + pdf_set_tstate(p, (double) pdf_bool_value(p, key, value), + to_glyphwarning); + break; + + case PDF_PARAMETER_TRACE: + { + pdc_bool bv = pdf_bool_value(p, key, value); + if (bv) + pdc_set_logg_options(p->pdc, ""); + else + pdc_set_logg_options(p->pdc, "disable"); + break; + } + + case PDF_PARAMETER_TRACEFILE: + strcpy(optlist, "filename "); + strcat(optlist, value); + pdc_set_logg_options(p->pdc, optlist); + break; + + case PDF_PARAMETER_WARNING: + break; + + case PDF_PARAMETER_MASTERPASSWORD: + pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_USERPASSWORD: + pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_PERMISSIONS: + pdc_warning(p->pdc, PDF_E_UNSUPP_CRYPT, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_COMPATIBILITY: + pdf_set_compatibility(p, value); + break; + + case PDF_PARAMETER_FLUSH: + pdf_set_flush(p, value); + break; + + case PDF_PARAMETER_PDFX: + pdc_warning(p->pdc, PDF_E_UNSUPP_PDFX, 0, 0, 0, 0); + break; + + case PDF_PARAMETER_HIDETOOLBAR: + case PDF_PARAMETER_HIDEMENUBAR: + case PDF_PARAMETER_HIDEWINDOWUI: + case PDF_PARAMETER_FITWINDOW: + case PDF_PARAMETER_CENTERWINDOW: + case PDF_PARAMETER_DISPLAYDOCTITLE: + if (pdf_bool_value(p, key, value)) + pdf_set_viewerpreference(p, key); + break; + + case PDF_PARAMETER_NONFULLSCREENPAGEMODE: + if (!pdc_stricmp(value, "useoutlines")) + pdf_set_viewerpreference(p, "nonfullscreenpagemode bookmarks"); + else if (!pdc_stricmp(value, "usethumbs")) + pdf_set_viewerpreference(p, "nonfullscreenpagemode thumbnails"); + else if (!pdc_stricmp(value, "usenone")) + pdf_set_viewerpreference(p, "nonfullscreenpagemode none"); + else + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + break; + + case PDF_PARAMETER_DIRECTION: + if (!pdc_stricmp(value, "r2l")) + pdf_set_viewerpreference(p, "direction r2l"); + else if (!pdc_stricmp(value, "l2r")) + pdf_set_viewerpreference(p, "direction l2r"); + else + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, value, key, 0, 0); + break; + + case PDF_PARAMETER_VIEWAREA: + case PDF_PARAMETER_VIEWCLIP: + case PDF_PARAMETER_PRINTAREA: + case PDF_PARAMETER_PRINTCLIP: + pdf_set_viewerpreference(p, optlist); + break; + + case PDF_PARAMETER_OPENACTION: + pdf_set_openaction(p, value); + break; + + case PDF_PARAMETER_OPENMODE: + pdf_set_openmode(p, value); + break; + + case PDF_PARAMETER_BOOKMARKDEST: + pdf_cleanup_destination(p, p->bookmark_dest); + p->bookmark_dest = + pdf_parse_destination_optlist(p, value, 0, pdf_bookmark); + break; + + case PDF_PARAMETER_INHERITGSTATE: + (void) pdf_bool_value(p, key, value); + break; + + case PDF_PARAMETER_TRANSITION: + pdf_set_transition(p, value); + break; + + case PDF_PARAMETER_BASE: + pdf_set_uri(p, value); + break; + + case PDF_PARAMETER_LAUNCHLINK_PARAMETERS: + if (p->launchlink_parameters) { + pdc_free(p->pdc, p->launchlink_parameters); + p->launchlink_parameters = NULL; + } + p->launchlink_parameters = pdc_strdup(p->pdc, value); + break; + + case PDF_PARAMETER_LAUNCHLINK_OPERATION: + if (p->launchlink_operation) { + pdc_free(p->pdc, p->launchlink_operation); + p->launchlink_operation = NULL; + } + p->launchlink_operation = pdc_strdup(p->pdc, value); + break; + + case PDF_PARAMETER_LAUNCHLINK_DEFAULTDIR: + if (p->launchlink_defaultdir) { + pdc_free(p->pdc, p->launchlink_defaultdir); + p->launchlink_defaultdir = NULL; + } + p->launchlink_defaultdir = pdc_strdup(p->pdc, value); + break; + + case PDF_PARAMETER_PDIUSEBOX: + p->pdi_usebox = usebox; + break; + + case PDF_PARAMETER_AUTOSUBSETTING: + case PDF_PARAMETER_AUTOCIDFONT: + case PDF_PARAMETER_UNICODEMAP: + pdc_warning(p->pdc, PDF_E_UNSUPP_UNICODE, 0, 0, 0, 0); + break; + + default: + pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0); + break; + } /* switch */ +} /* pdf__set_parameter */ + +static double +pdf_value(PDF *p, const char *key, double value, int minver) +{ + if (p->compatibility < minver) + pdc_error(p->pdc, PDC_E_PAR_VERSION, + key, pdc_get_pdfversion(p->pdc, minver), 0, 0); + + return value; +} + +static double +pdf_pos_value(PDF *p, const char *key, double value, int minver) +{ + if (p->compatibility < minver) + pdc_error(p->pdc, PDC_E_PAR_VERSION, + key, pdc_get_pdfversion(p->pdc, minver), 0, 0); + + if (value <= 0) + pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, + pdc_errprintf(p->pdc, "%f", value), key, 0, 0); + + return value; +} + +void +pdf__set_value(PDF *p, const char *key, double value) +{ + int i; + int ivalue = (int) value; + pdf_ppt *ppt; + + i = pdf_get_index(p, key, pdc_true); + + ppt = p->curr_ppt; + + pdc_check_number(p->pdc, "value", value); + + switch (i) + { + case PDF_PARAMETER_COMPRESS: + if (ivalue < 0 || ivalue > 9) + pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, + pdc_errprintf(p->pdc, "%f", value), key, 0, 0); + + if (pdc_get_compresslevel(p->out) != ivalue) + { + /* + * We must restart the compression engine and start a new + * contents section if we're in the middle of a page. + */ + if (PDF_GET_STATE(p) == pdf_state_page) { + pdf_end_contents_section(p); + pdc_set_compresslevel(p->out, ivalue); + pdf_begin_contents_section(p); + } else + pdc_set_compresslevel(p->out, ivalue); + } + + break; + + case PDF_PARAMETER_FLOATDIGITS: + if (3 <= ivalue && ivalue <= 6) + { + p->pdc->floatdigits = ivalue; + } + else + pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, + pdc_errprintf(p->pdc, "%d", ivalue), key, 0, 0); + break; + + /* TODO (york): take /CropBox into account? + */ + case PDF_PARAMETER_PAGEWIDTH: + { + const pdc_rectangle *box = pdf_get_pagebox(p, pdf_mediabox); + + if (p->ydirection == -1) + pdc_error(p->pdc, PDF_E_PAGE_ILLCHGSIZE, 0, 0, 0, 0); + + if (value < PDF_ACRO_MINPAGE || value > PDF_ACRO_MAXPAGE) + pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0); + + pdf_set_pagebox_urx(p, pdf_mediabox, + box->llx + pdf_pos_value(p, key, value, PDC_1_3)); + break; + } + + /* TODO (york): take /CropBox into account? + */ + case PDF_PARAMETER_PAGEHEIGHT: + { + const pdc_rectangle *box = pdf_get_pagebox(p, pdf_mediabox); + + if (p->ydirection == -1) + pdc_error(p->pdc, PDF_E_PAGE_ILLCHGSIZE, 0, 0, 0, 0); + + if (value < PDF_ACRO_MINPAGE || value > PDF_ACRO_MAXPAGE) + pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0); + + pdf_set_pagebox_ury(p, pdf_mediabox, + box->lly + pdf_pos_value(p, key, value, PDC_1_3)); + break; + } + + case PDF_PARAMETER_CROPBOX_LLX: + pdf_set_pagebox_llx(p, pdf_cropbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_CROPBOX_LLY: + pdf_set_pagebox_lly(p, pdf_cropbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_CROPBOX_URX: + pdf_set_pagebox_urx(p, pdf_cropbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_CROPBOX_URY: + pdf_set_pagebox_ury(p, pdf_cropbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_BLEEDBOX_LLX: + pdf_set_pagebox_llx(p, pdf_bleedbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_BLEEDBOX_LLY: + pdf_set_pagebox_lly(p, pdf_bleedbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_BLEEDBOX_URX: + pdf_set_pagebox_urx(p, pdf_bleedbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_BLEEDBOX_URY: + pdf_set_pagebox_ury(p, pdf_bleedbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_TRIMBOX_LLX: + pdf_set_pagebox_llx(p, pdf_trimbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_TRIMBOX_LLY: + pdf_set_pagebox_lly(p, pdf_trimbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_TRIMBOX_URX: + pdf_set_pagebox_urx(p, pdf_trimbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_TRIMBOX_URY: + pdf_set_pagebox_ury(p, pdf_trimbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_ARTBOX_LLX: + pdf_set_pagebox_llx(p, pdf_artbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_ARTBOX_LLY: + pdf_set_pagebox_lly(p, pdf_artbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_ARTBOX_URX: + pdf_set_pagebox_urx(p, pdf_artbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_ARTBOX_URY: + pdf_set_pagebox_ury(p, pdf_artbox, + pdf_value(p, key, value, PDC_1_3)); + break; + + case PDF_PARAMETER_LEADING: + pdf_set_tstate(p, value, to_leading); + break; + + case PDF_PARAMETER_TEXTRISE: + pdf_set_tstate(p, value, to_textrise); + break; + + case PDF_PARAMETER_HORIZSCALING: + pdf_set_tstate(p, value /100, to_horizscaling); + break; + + case PDF_PARAMETER_ITALICANGLE: + pdf_set_tstate(p, value, to_italicangle); + break; + + case PDF_PARAMETER_TEXTRENDERING: + pdf_set_tstate(p, value, to_textrendering); + break; + + case PDF_PARAMETER_CHARSPACING: + pdf_set_tstate(p, value, to_charspacing); + break; + + case PDF_PARAMETER_WORDSPACING: + pdf_set_tstate(p, value, to_wordspacing); + break; + + case PDF_PARAMETER_UNDERLINEWIDTH: + pdf_set_tstate(p, value, to_underlinewidth); + break; + + case PDF_PARAMETER_UNDERLINEPOSITION: + pdf_set_tstate(p, value, to_underlineposition); + break; + + case PDF_PARAMETER_DEFAULTGRAY: + break; + + case PDF_PARAMETER_DEFAULTRGB: + break; + + case PDF_PARAMETER_DEFAULTCMYK: + break; + + case PDF_PARAMETER_SETCOLOR_ICCPROFILEGRAY: + break; + + case PDF_PARAMETER_SETCOLOR_ICCPROFILERGB: + break; + + case PDF_PARAMETER_SETCOLOR_ICCPROFILECMYK: + break; + +/*****************************************************************************/ +/** deprecated historical parameters **/ +/*****************************************************************************/ + + case PDF_PARAMETER_SUBSETLIMIT: + case PDF_PARAMETER_SUBSETMINSIZE: + { + pdc_warning(p->pdc, PDF_E_UNSUPP_SUBSET, 0, 0, 0, 0); + break; + } + + case PDF_PARAMETER_DURATION: + pdf_set_duration(p, value); + break; + + default: + pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0); + break; + } /* switch */ +} /* pdf__set_value */ + +double +pdf__get_value(PDF *p, const char *key, double mod) +{ + int i = -1; + int imod = (int) mod; + double result = 0; + const pdc_rectangle *box = NULL; + pdf_ppt *ppt; + + i = pdf_get_index(p, key, pdc_false); + + if (parms[i].mod_zero && mod != 0) + pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, + pdc_errprintf(p->pdc, "%f", mod), key, 0, 0); + + ppt = p->curr_ppt; + + switch (i) + { + case PDF_PARAMETER_IMAGEWIDTH: + case PDF_PARAMETER_IMAGEHEIGHT: + case PDF_PARAMETER_RESX: + case PDF_PARAMETER_RESY: + case PDF_PARAMETER_ORIENTATION: + if (p->pdc->hastobepos) imod -= 1; + pdf_check_handle(p, imod, pdc_imagehandle); + break; + + case PDF_PARAMETER_FONTMAXCODE: + case PDF_PARAMETER_CAPHEIGHT: + case PDF_PARAMETER_ASCENDER: + case PDF_PARAMETER_DESCENDER: + case PDF_PARAMETER_XHEIGHT: + if (p->pdc->hastobepos) imod -= 1; + pdf_check_handle(p, imod, pdc_fonthandle); + break; + } + + switch (i) + { + case PDF_PARAMETER_COMPRESS: + result = (double) pdc_get_compresslevel(p->out); + break; + + case PDF_PARAMETER_FLOATDIGITS: + result = (double) p->pdc->floatdigits; + break; + + /* TODO (york): take /CropBox into account? + */ + case PDF_PARAMETER_PAGEWIDTH: + box = pdf_get_pagebox(p, pdf_mediabox); + result = box->urx - box->llx; + break; + + /* TODO (york): take /CropBox into account? + */ + case PDF_PARAMETER_PAGEHEIGHT: + box = pdf_get_pagebox(p, pdf_mediabox); + result = box->ury - box->lly; + break; + + case PDF_PARAMETER_CROPBOX_LLX: + box = pdf_get_pagebox(p, pdf_cropbox); + result = box->llx; + break; + + case PDF_PARAMETER_CROPBOX_LLY: + box = pdf_get_pagebox(p, pdf_cropbox); + result = box->lly; + break; + + case PDF_PARAMETER_CROPBOX_URX: + box = pdf_get_pagebox(p, pdf_cropbox); + result = box->urx; + break; + + case PDF_PARAMETER_CROPBOX_URY: + box = pdf_get_pagebox(p, pdf_cropbox); + result = box->ury; + break; + + case PDF_PARAMETER_BLEEDBOX_LLX: + box = pdf_get_pagebox(p, pdf_bleedbox); + result = box->llx; + break; + + case PDF_PARAMETER_BLEEDBOX_LLY: + box = pdf_get_pagebox(p, pdf_bleedbox); + result = box->lly; + break; + + case PDF_PARAMETER_BLEEDBOX_URX: + box = pdf_get_pagebox(p, pdf_bleedbox); + result = box->urx; + break; + + case PDF_PARAMETER_BLEEDBOX_URY: + box = pdf_get_pagebox(p, pdf_bleedbox); + result = box->ury; + break; + + case PDF_PARAMETER_TRIMBOX_LLX: + box = pdf_get_pagebox(p, pdf_trimbox); + result = box->llx; + break; + + case PDF_PARAMETER_TRIMBOX_LLY: + box = pdf_get_pagebox(p, pdf_trimbox); + result = box->lly; + break; + + case PDF_PARAMETER_TRIMBOX_URX: + box = pdf_get_pagebox(p, pdf_trimbox); + result = box->urx; + break; + + case PDF_PARAMETER_TRIMBOX_URY: + box = pdf_get_pagebox(p, pdf_trimbox); + result = box->ury; + break; + + case PDF_PARAMETER_ARTBOX_LLX: + box = pdf_get_pagebox(p, pdf_artbox); + result = box->llx; + break; + + case PDF_PARAMETER_ARTBOX_LLY: + box = pdf_get_pagebox(p, pdf_artbox); + result = box->lly; + break; + + case PDF_PARAMETER_ARTBOX_URX: + box = pdf_get_pagebox(p, pdf_artbox); + result = box->urx; + break; + + case PDF_PARAMETER_ARTBOX_URY: + box = pdf_get_pagebox(p, pdf_artbox); + result = box->ury; + break; + + case PDF_PARAMETER_IMAGEWIDTH: + pdf_get_image_size(p, imod, (double *) &result, NULL); + break; + + case PDF_PARAMETER_IMAGEHEIGHT: + pdf_get_image_size(p, imod, NULL, (double *) &result); + break; + + case PDF_PARAMETER_RESX: + pdf_get_image_resolution(p, imod, (double *) &result, NULL); + break; + + case PDF_PARAMETER_RESY: + pdf_get_image_resolution(p, imod, NULL, (double *) &result); + break; + + case PDF_PARAMETER_ORIENTATION: + result = (double) (p->images[imod].orientation); + break; + + + case PDF_PARAMETER_CURRENTX: + result = (double) (ppt->gstate[ppt->sl].x); + break; + + case PDF_PARAMETER_CURRENTY: + result = (double) (ppt->gstate[ppt->sl].y); + break; + + case PDF_PARAMETER_CTM_A: + result = (double) (ppt->gstate[ppt->sl].ctm.a); + break; + + case PDF_PARAMETER_CTM_B: + result = (double) (ppt->gstate[ppt->sl].ctm.b); + break; + + case PDF_PARAMETER_CTM_C: + result = (double) (ppt->gstate[ppt->sl].ctm.c); + break; + + case PDF_PARAMETER_CTM_D: + result = (double) (ppt->gstate[ppt->sl].ctm.d); + break; + + case PDF_PARAMETER_CTM_E: + result = (double) (ppt->gstate[ppt->sl].ctm.e); + break; + + case PDF_PARAMETER_CTM_F: + result = (double) (ppt->gstate[ppt->sl].ctm.f); + break; + + case PDF_PARAMETER_TEXTX: + result = pdf_get_tstate(p, to_textx); + break; + + case PDF_PARAMETER_TEXTY: + result = pdf_get_tstate(p, to_texty); + break; + + case PDF_PARAMETER_UNDERLINEWIDTH: + result = pdf_get_tstate(p, to_underlinewidth); + break; + + case PDF_PARAMETER_UNDERLINEPOSITION: + result = pdf_get_tstate(p, to_underlineposition); + break; + + case PDF_PARAMETER_WORDSPACING: + result = pdf_get_tstate(p, to_wordspacing); + break; + + case PDF_PARAMETER_CHARSPACING: + result = pdf_get_tstate(p, to_charspacing); + break; + + case PDF_PARAMETER_HORIZSCALING: + result = 100 * pdf_get_tstate(p, to_horizscaling); + break; + + case PDF_PARAMETER_ITALICANGLE: + result = pdf_get_tstate(p, to_italicangle); + break; + + case PDF_PARAMETER_TEXTRISE: + result = pdf_get_tstate(p, to_textrise); + break; + + case PDF_PARAMETER_LEADING: + result = pdf_get_tstate(p, to_leading); + break; + + case PDF_PARAMETER_TEXTRENDERING: + result = pdf_get_tstate(p, to_textrendering); + break; + + case PDF_PARAMETER_FONTSIZE: + result = pdf_get_tstate(p, to_fontsize); + break; + + case PDF_PARAMETER_FONT: + result = pdf_get_tstate(p, to_font); + if (p->pdc->hastobepos) result += 1; + break; + + case PDF_PARAMETER_MONOSPACE: + result = pdf_get_font_float_option(p, fo_monospace); + break; + + case PDF_PARAMETER_FONTMAXCODE: + result = (double) (p->fonts[imod].ft.numcodes - 1); + break; + + case PDF_PARAMETER_ASCENDER: + result = pdf_font_get_metric_value(p->fonts[imod].ft.m.ascender); + break; + + case PDF_PARAMETER_DESCENDER: + result = pdf_font_get_metric_value(p->fonts[imod].ft.m.descender); + break; + + case PDF_PARAMETER_CAPHEIGHT: + result = pdf_font_get_metric_value(p->fonts[imod].ft.m.capHeight); + break; + + case PDF_PARAMETER_XHEIGHT: + result = pdf_font_get_metric_value(p->fonts[imod].ft.m.xHeight); + break; + + + default: + pdc_error(p->pdc, PDC_E_PAR_UNSUPPKEY, key, 0, 0, 0); + break; + } /* switch */ + + return result; +} /* pdf__get_value */ + +const char * +pdf__get_parameter(PDF *p, const char *key, double mod) +{ + int i = -1; + int imod = (int) mod; + const char *result = ""; + pdf_ppt *ppt; + + i = pdf_get_index(p, key, pdc_false); + + if (parms[i].mod_zero && mod != 0) + pdc_error(p->pdc, PDC_E_PAR_ILLPARAM, + pdc_errprintf(p->pdc, "%f", mod), key, 0, 0); + + ppt = p->curr_ppt; + + switch (i) + { + case PDF_PARAMETER_CAPHEIGHTFAKED: + case PDF_PARAMETER_ASCENDERFAKED: + case PDF_PARAMETER_DESCENDERFAKED: + case PDF_PARAMETER_XHEIGHTFAKED: + if (p->pdc->hastobepos) imod -= 1; + pdf_check_handle(p, imod, pdc_fonthandle); + break; + } + + switch (i) + { + case PDF_PARAMETER_BINDING: + result = p->pdc->binding; + break; + + case PDF_PARAMETER_OBJORIENT: + result = PDC_BOOLSTR(p->pdc->objorient); + break; + + case PDF_PARAMETER_HASTOBEPOS: + result = PDC_BOOLSTR(p->pdc->hastobepos); + break; + + case PDF_PARAMETER_PTFRUN: + result = PDC_BOOLSTR(p->pdc->ptfrun); + break; + + case PDF_PARAMETER_SMOKERUN: + result = PDC_BOOLSTR(p->pdc->smokerun); + break; + + case PDF_PARAMETER_UNICAPLANG: + result = PDC_BOOLSTR(p->pdc->unicaplang); + break; + + + case PDF_PARAMETER_CONFIGURATION: + result = "lite"; + break; + + case PDF_PARAMETER_ERRORPOLICY: + result = pdc_get_keyword(p->errorpolicy, pdf_errpol_keylist); + break; + + case PDF_PARAMETER_PDIUSEBOX: + result = pdc_get_keyword(p->pdi_usebox, pdf_usebox_keylist); + break; + + case PDF_PARAMETER_SEARCHPATH: + case PDF_PARAMETER_FONTAFM: + case PDF_PARAMETER_FONTPFM: + case PDF_PARAMETER_FONTOUTLINE: + case PDF_PARAMETER_HOSTFONT: + case PDF_PARAMETER_ENCODING: + case PDF_PARAMETER_ICCPROFILE: + case PDF_PARAMETER_STANDARDOUTPUTINTENT: + result = pdc_find_resource_nr(p->pdc, key, imod); + break; + + case PDF_PARAMETER_FONTNAME: + result = pdf_get_font_char_option(p, fo_fontname); + break; + + case PDF_PARAMETER_FONTENCODING: + result = pdf_get_font_char_option(p, fo_encoding); + break; + + case PDF_PARAMETER_FONTSTYLE: + result = pdf_get_font_char_option(p, fo_fontstyle); + break; + + case PDF_PARAMETER_ASCENDERFAKED: + result = PDC_BOOLSTR(pdf_font_get_is_faked(&p->fonts[imod], + font_ascender)); + break; + + case PDF_PARAMETER_DESCENDERFAKED: + result = PDC_BOOLSTR(pdf_font_get_is_faked(&p->fonts[imod], + font_descender)); + break; + + case PDF_PARAMETER_CAPHEIGHTFAKED: + result = PDC_BOOLSTR(pdf_font_get_is_faked(&p->fonts[imod], + font_capheight)); + break; + + case PDF_PARAMETER_XHEIGHTFAKED: + result = PDC_BOOLSTR(pdf_font_get_is_faked(&p->fonts[imod], + font_xheight)); + break; + + + case PDF_PARAMETER_UNDERLINE: + result = PDC_BOOLSTR((int) pdf_get_tstate(p, to_underline)); + break; + + case PDF_PARAMETER_OVERLINE: + result = PDC_BOOLSTR((int) pdf_get_tstate(p, to_overline)); + break; + + case PDF_PARAMETER_STRIKEOUT: + result = PDC_BOOLSTR((int) pdf_get_tstate(p, to_strikeout)); + break; + + /* deprecated */ + case PDF_PARAMETER_INHERITGSTATE: + result = PDC_BOOLSTR(pdc_false); + break; + + case PDF_PARAMETER_SCOPE: + result = pdf_current_scope(p); + break; + + case PDF_PARAMETER_TEXTFORMAT: + result = pdc_get_keyword(p->textformat, pdf_textformat_keylist); + break; + + case PDF_PARAMETER_HYPERTEXTFORMAT: + result = pdc_get_keyword(p->hypertextformat,pdf_textformat_keylist); + break; + + case PDF_PARAMETER_HYPERTEXTENCODING: + result = pdf_get_encoding_name(p, p->hypertextencoding, NULL); + break; + + case PDF_PARAMETER_RESOURCEFILE: + result = pdc_get_resourcefile(p->pdc); + break; + + /* deprecated */ + case PDF_PARAMETER_WARNING: + result = PDC_BOOLSTR(0); + break; + + case PDF_PARAMETER_OPENWARNING: + result = PDC_BOOLSTR((int) p->debug[(int) 'o']); + break; + + case PDF_PARAMETER_FONTWARNING: + result = PDC_BOOLSTR((int) p->debug[(int) 'F']); + break; + + case PDF_PARAMETER_ICCWARNING: + result = PDC_BOOLSTR((int) p->debug[(int) 'I']); + break; + + case PDF_PARAMETER_IMAGEWARNING: + result = PDC_BOOLSTR((int) p->debug[(int) 'i']); + break; + + case PDF_PARAMETER_PDIWARNING: + result = PDC_BOOLSTR((int) p->debug[(int) 'p']); + break; + + case PDF_PARAMETER_HONORICCPROFILE: + result = PDC_BOOLSTR((int) p->debug[(int) 'e']); + break; + + case PDF_PARAMETER_GLYPHWARNING: + result = PDC_BOOLSTR((int) p->debug[(int) 'g']); + break; + + case PDF_PARAMETER_RENDERINGINTENT: + result = pdc_get_keyword(p->rendintent, + pdf_renderingintent_pdfkeylist); + break; + + case PDF_PARAMETER_PRESERVEOLDPANTONENAMES: + result = PDC_BOOLSTR(p->preserveoldpantonenames); + break; + + case PDF_PARAMETER_SPOTCOLORLOOKUP: + result = PDC_BOOLSTR(p->spotcolorlookup); + break; + + case PDF_PARAMETER_PDISTRICT: + result = PDC_BOOLSTR(p->pdi_strict); + break; + + case PDF_PARAMETER_TOPDOWN: + result = PDC_BOOLSTR((p->ydirection == -1.0)); + break; + + case PDF_PARAMETER_USERCOORDINATES: + result = PDC_BOOLSTR(p->usercoordinates); + break; + + case PDF_PARAMETER_USEHYPERTEXTENCODING: + result = PDC_BOOLSTR(p->usehyptxtenc); + break; + + + + case PDF_PARAMETER_FILLRULE: + result = pdc_get_keyword(ppt->fillrule, pdf_fillrule_keylist); + break; + + + + case PDF_PARAMETER_COMPATIBILITY: + result = pdc_get_keyword(p->compatibility, + pdf_compatibility_keylist); + break; + + case PDF_PARAMETER_STRING: + pdf_check_handle(p, imod, pdc_stringhandle); + result = pdf_get_utilstring(p, imod); + break; + + default: + pdc_error(p->pdc, PDC_E_PAR_UNSUPPKEY, key, 0, 0, 0); + break; + } /* switch */ + + return result ? result : ""; +} /* pdf__get_parameter */ + + diff --git a/src/pdflib/pdflib/p_params.h b/src/pdflib/pdflib/p_params.h new file mode 100644 index 0000000..12bbf6d --- /dev/null +++ b/src/pdflib/pdflib/p_params.h @@ -0,0 +1,373 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_params.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib parameter table + * + */ + +#if pdf_gen_parm_enum +#define pdf_gen1(code, name, zero, check, scope) PDF_PARAMETER_##code, +#elif pdf_gen_parm_descr +#define pdf_gen1(code, name, zero, check, scope) \ + { name, zero, check, scope }, +#else +#error invalid inclusion of generator file +#endif + +/* + * Deprecated and unsupported parameters: + * dep7 Deprecated since PDFlib 7 + * dep6 Deprecated since PDFlib 6 + * dep5 Deprecated since PDFlib 5 + * unsupp Unsupported (internal use, dysfunctional, or other) + */ + +/* + List of unsupported control characters for the "debug" parameter: + 2 disable the search for the Windows color directory via mscms.dll + e extract embedded ICC profiles from image files + F throw an exception in PDF_load_font (dep7); + g throw an exception in PDF_fit_textline and PDF_show (dep7) + h disable host font processing + i throw an exception in PDF_load_image (dep7) + I throw an exception in PDF_load_iccprofile (dep7); + o throw an exception in PDF_begin_document (dep7) + p throw an exception in PDF_open_pdi (dep7) + + On by default: e F I +*/ + + +/* + * ---------------------------------------------------------------------- + * Setup + * ---------------------------------------------------------------------- + */ + +pdf_gen1(OPENWARNING, "openwarning", 1, 1, pdf_state_all) /* dep6 */ +pdf_gen1(COMPRESS, "compress", 1, 1, + pdf_state_page | pdf_state_document) +pdf_gen1(FLUSH, "flush", 1, 1, pdf_state_all) /* dep6 */ +pdf_gen1(RESOURCEFILE, "resourcefile", 1, 1, pdf_state_all) +pdf_gen1(COMPATIBILITY, "compatibility",1, 0, pdf_state_object) /* dep6 */ +pdf_gen1(PDFX, "pdfx", 1, 0, pdf_state_object) /* dep6 */ +pdf_gen1(SEARCHPATH, "SearchPath", 0, 1, pdf_state_all) +pdf_gen1(ASCIIFILE, "asciifile", 1, 1, pdf_state_all) +pdf_gen1(WARNING, "warning", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(ERRORPOLICY, "errorpolicy", 1, 1, pdf_state_all) +pdf_gen1(NODEMOSTAMP, "nodemostamp", 1, 0, pdf_state_object) +pdf_gen1(LICENSE, "license", 1, 0, pdf_state_object) +pdf_gen1(LICENCE, "licence", 1, 0, pdf_state_object) /* unsupp */ +pdf_gen1(LICENSEFILE, "licensefile", 1, 0, pdf_state_object) +pdf_gen1(LICENCEFILE, "licencefile", 1, 0, pdf_state_object) /* unsupp */ +pdf_gen1(TRACE, "trace", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(TRACEFILE, "tracefile", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(TRACEMSG, "tracemsg", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(LOGGING, "logging", 1, 1, pdf_state_all) +pdf_gen1(LOGMSG, "logmsg", 1, 1, pdf_state_all) +pdf_gen1(CHARREF, "charref", 1, 1, pdf_state_all) +pdf_gen1(ESCAPESEQUENCE,"escapesequence",1,1, pdf_state_all) +pdf_gen1(HONORLANG, "honorlang", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(STRING, "string", 0, 1, pdf_state_all) +pdf_gen1(SCOPE, "scope", 1, 1, pdf_state_all) + +pdf_gen1(SERIAL, "serial", 1, 0, pdf_state_object) /* unsupp */ +pdf_gen1(FLOATDIGITS, "floatdigits", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(BINDING, "binding", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(OBJORIENT, "objorient", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(HASTOBEPOS, "hastobepos", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(UNICAPLANG, "unicaplang", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(DEBUG, "debug", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(NODEBUG, "nodebug", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(PTFRUN, "ptfrun", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(SMOKERUN, "smokerun", 1, 1, pdf_state_all) /* unsupp */ +pdf_gen1(CONFIGURATION, "configuration",1, 1, pdf_state_all) /* unsupp */ + + +/* + * ---------------------------------------------------------------------- + * Versioning (cf. pdflib.c) + * ---------------------------------------------------------------------- + */ + +pdf_gen1(MAJOR, "major", 1, 1, pdf_state_all) +pdf_gen1(MINOR, "minor", 1, 1, pdf_state_all) +pdf_gen1(REVISION, "revision", 1, 1, pdf_state_all) +pdf_gen1(VERSION, "version", 1, 1, pdf_state_all) + + +/* + * ---------------------------------------------------------------------- + * Page + * ---------------------------------------------------------------------- + */ + +/* all of the following group are dep6 */ + +pdf_gen1(PAGEWIDTH, "pagewidth", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(PAGEHEIGHT, "pageheight", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(CROPBOX_LLX, "CropBox/llx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(CROPBOX_LLY, "CropBox/lly", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(CROPBOX_URX, "CropBox/urx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(CROPBOX_URY, "CropBox/ury", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(BLEEDBOX_LLX, "BleedBox/llx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(BLEEDBOX_LLY, "BleedBox/lly", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(BLEEDBOX_URX, "BleedBox/urx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(BLEEDBOX_URY, "BleedBox/ury", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(TRIMBOX_LLX, "TrimBox/llx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(TRIMBOX_LLY, "TrimBox/lly", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(TRIMBOX_URX, "TrimBox/urx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(TRIMBOX_URY, "TrimBox/ury", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(ARTBOX_LLX, "ArtBox/llx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(ARTBOX_LLY, "ArtBox/lly", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(ARTBOX_URX, "ArtBox/urx", 1, 1, pdf_state_page | pdf_state_path) +pdf_gen1(ARTBOX_URY, "ArtBox/ury", 1, 1, pdf_state_page | pdf_state_path) + + +/* + * ---------------------------------------------------------------------- + * Font + * ---------------------------------------------------------------------- + */ + +pdf_gen1(FONTAFM, "FontAFM", 0, 1, pdf_state_all) +pdf_gen1(FONTPFM, "FontPFM", 0, 1, pdf_state_all) +pdf_gen1(FONTOUTLINE, "FontOutline", 0, 1, pdf_state_all) +pdf_gen1(HOSTFONT, "HostFont", 0, 1, pdf_state_all) +pdf_gen1(ENCODING, "Encoding", 0, 1, pdf_state_all) +pdf_gen1(FONTWARNING, "fontwarning", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(FONT, "font", 1, 1, pdf_state_content) +pdf_gen1(FONTSIZE, "fontsize", 1, 1, pdf_state_content) + +pdf_gen1(SUBSETLIMIT, "subsetlimit", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(SUBSETMINSIZE, "subsetminsize",1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(AUTOSUBSETTING,"autosubsetting",1,1, pdf_state_all) /* dep7 */ +pdf_gen1(AUTOCIDFONT, "autocidfont", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(UNICODEMAP, "unicodemap", 1, 1, pdf_state_all) /* dep7 */ + +pdf_gen1(FONTNAME, "fontname", 1, 1, pdf_state_content) /* dep7 */ +pdf_gen1(FONTSTYLE, "fontstyle", 1, 1, pdf_state_content) /* dep7 */ +pdf_gen1(FONTENCODING, "fontencoding", 1, 1, pdf_state_content) /* dep7 */ +pdf_gen1(MONOSPACE, "monospace", 1, 1, pdf_state_content) /* dep7 */ +pdf_gen1(FONTMAXCODE, "fontmaxcode", 0, 1, pdf_state_all) /* dep7 */ +pdf_gen1(ASCENDER, "ascender", 0, 1, pdf_state_all) /* dep7 */ +pdf_gen1(DESCENDER, "descender", 0, 1, pdf_state_all) /* dep7 */ +pdf_gen1(CAPHEIGHT, "capheight", 0, 1, pdf_state_all) /* dep7 */ +pdf_gen1(XHEIGHT, "xheight", 0, 1, pdf_state_all) /* dep7 */ +pdf_gen1(ASCENDERFAKED, "ascenderfaked",0, 1, pdf_state_all) /* dep7 */ +pdf_gen1(DESCENDERFAKED,"descenderfaked",0,1, pdf_state_all) /* dep7 */ +pdf_gen1(CAPHEIGHTFAKED,"capheightfaked",0,1, pdf_state_all) /* dep7 */ +pdf_gen1(XHEIGHTFAKED, "xheightfaked", 0,1, pdf_state_all) /* dep7 */ + + +/* + * ---------------------------------------------------------------------- + * Text + * ---------------------------------------------------------------------- + */ + +pdf_gen1(TEXTX, "textx", 1, 1, pdf_state_content) +pdf_gen1(TEXTY, "texty", 1, 1, pdf_state_content) +pdf_gen1(LEADING, "leading", 1, 1, pdf_state_content) +pdf_gen1(TEXTRISE, "textrise", 1, 1, pdf_state_content) +pdf_gen1(HORIZSCALING, "horizscaling", 1, 1, + pdf_state_content | pdf_state_document) +pdf_gen1(TEXTRENDERING, "textrendering",1, 1, pdf_state_content) +pdf_gen1(CHARSPACING, "charspacing", 1, 1, + pdf_state_content | pdf_state_document) +pdf_gen1(WORDSPACING, "wordspacing", 1, 1, + pdf_state_content | pdf_state_document) +pdf_gen1(ITALICANGLE, "italicangle", 1, 1, + pdf_state_content | pdf_state_document) +pdf_gen1(FAKEBOLD, "fakebold", 1, 1, + pdf_state_content | pdf_state_document) +pdf_gen1(UNDERLINEWIDTH,"underlinewidth", 1, 1, + pdf_state_content | pdf_state_document) +pdf_gen1(UNDERLINEPOSITION,"underlineposition", 1, 1, + pdf_state_content | pdf_state_document) +pdf_gen1(UNDERLINE, "underline", 1, 1, pdf_state_content) +pdf_gen1(OVERLINE, "overline", 1, 1, pdf_state_content) +pdf_gen1(STRIKEOUT, "strikeout", 1, 1, pdf_state_content) +pdf_gen1(KERNING, "kerning", 1, 1, pdf_state_all) +pdf_gen1(TEXTFORMAT, "textformat", 1, 1, pdf_state_all) +pdf_gen1(GLYPHWARNING, "glyphwarning", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(GLYPHCHECK, "glyphcheck", 1, 1, pdf_state_all) + + +/* + * ---------------------------------------------------------------------- + * Graphics + * ---------------------------------------------------------------------- + */ + +pdf_gen1(CURRENTX, "currentx", 1, 1, + pdf_state_content | pdf_state_path) +pdf_gen1(CURRENTY, "currenty", 1, 1, + pdf_state_content | pdf_state_path) +pdf_gen1(FILLRULE, "fillrule", 1, 1, pdf_state_content) +pdf_gen1(TOPDOWN, "topdown", 1, 0, pdf_state_document) +pdf_gen1(CTM_A, "ctm_a", 1, 1, pdf_state_content) +pdf_gen1(CTM_B, "ctm_b", 1, 1, pdf_state_content) +pdf_gen1(CTM_C, "ctm_c", 1, 1, pdf_state_content) +pdf_gen1(CTM_D, "ctm_d", 1, 1, pdf_state_content) +pdf_gen1(CTM_E, "ctm_e", 1, 1, pdf_state_content) +pdf_gen1(CTM_F, "ctm_f", 1, 1, pdf_state_content) + + +/* + * ---------------------------------------------------------------------- + * Color + * ---------------------------------------------------------------------- + */ + +pdf_gen1(SETCOLOR_ICCPROFILEGRAY, "setcolor:iccprofilegray", 1, 1, + pdf_state_document | pdf_state_content) +pdf_gen1(SETCOLOR_ICCPROFILERGB, "setcolor:iccprofilergb", 1, 1, + pdf_state_document | pdf_state_content) +pdf_gen1(SETCOLOR_ICCPROFILECMYK, "setcolor:iccprofilecmyk", 1, 1, + pdf_state_document | pdf_state_content) +pdf_gen1(IMAGE_ICCPROFILE,"image:iccprofile", 0, 1, + pdf_state_path | pdf_state_content | pdf_state_document) +pdf_gen1(ICCWARNING, "iccwarning", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(HONORICCPROFILE, "honoriccprofile", 1, 1, pdf_state_all) +pdf_gen1(ICCCOMPONENTS, "icccomponents", 0, 1, pdf_state_all) +pdf_gen1(ICCPROFILE, "ICCProfile", 0, 1, pdf_state_all) +pdf_gen1(STANDARDOUTPUTINTENT, "StandardOutputIntent", 0, 1, pdf_state_all) +pdf_gen1(RENDERINGINTENT, "renderingintent", 1, 1, pdf_state_all) + +/* 3 x dep6 */ +pdf_gen1(DEFAULTRGB, "defaultrgb", 1, 1, + pdf_state_content | pdf_state_path) +pdf_gen1(DEFAULTGRAY, "defaultgray", 1, 1, + pdf_state_content | pdf_state_path) +pdf_gen1(DEFAULTCMYK, "defaultcmyk", 1, 1, + pdf_state_content | pdf_state_path) + +pdf_gen1(PRESERVEOLDPANTONENAMES, "preserveoldpantonenames", 1, 1, + pdf_state_all) +pdf_gen1(SPOTCOLORLOOKUP, "spotcolorlookup", 1, 1, + pdf_state_all) + +/* + * ---------------------------------------------------------------------- + * Image + * ---------------------------------------------------------------------- + */ + +pdf_gen1(IMAGEWARNING, "imagewarning", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(IMAGEWIDTH, "imagewidth", 0, 1, + pdf_state_path | pdf_state_content | pdf_state_document) +pdf_gen1(IMAGEHEIGHT, "imageheight", 0, 1, + pdf_state_path | pdf_state_content | pdf_state_document) +pdf_gen1(RESX, "resx", 0, 1, + pdf_state_path | pdf_state_content | pdf_state_document) +pdf_gen1(RESY, "resy", 0, 1, + pdf_state_path | pdf_state_content | pdf_state_document) +pdf_gen1(ORIENTATION, "orientation", 0, 1, + pdf_state_path | pdf_state_content | pdf_state_document) + +pdf_gen1(INHERITGSTATE, "inheritgstate",1, 1, pdf_state_all) /* dep6 */ + + +/* + * ---------------------------------------------------------------------- + * PDI + * ---------------------------------------------------------------------- + */ + +pdf_gen1(PDI, "pdi", 1, 1, pdf_state_all) +pdf_gen1(PDIWARNING, "pdiwarning", 1, 1, pdf_state_all) /* dep7 */ +pdf_gen1(PDIUSEBOX, "pdiusebox", 1, 1, pdf_state_all) /* dep6 */ +pdf_gen1(PDISTRICT, "pdistrict", 1, 1, pdf_state_all) /* unsupp */ + + +/* + * ---------------------------------------------------------------------- + * Hypertext + * ---------------------------------------------------------------------- + */ + +pdf_gen1(HYPERTEXTFORMAT, "hypertextformat", 1, 1, pdf_state_all) +pdf_gen1(HYPERTEXTENCODING, "hypertextencoding", 1, 1, pdf_state_all) +pdf_gen1(USERCOORDINATES, "usercoordinates", 1, 1, pdf_state_all) +pdf_gen1(USEHYPERTEXTENCODING, "usehypertextencoding", 1, 1, pdf_state_all) + /* unsupp */ + +pdf_gen1(HIDETOOLBAR, "hidetoolbar", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(HIDEMENUBAR, "hidemenubar", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(HIDEWINDOWUI, "hidewindowui", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(FITWINDOW, "fitwindow", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(CENTERWINDOW, "centerwindow", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(DISPLAYDOCTITLE, "displaydoctitle", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(NONFULLSCREENPAGEMODE, "nonfullscreenpagemode", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(DIRECTION, "direction", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ + +pdf_gen1(VIEWAREA, "viewarea", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(VIEWCLIP, "viewclip", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(PRINTAREA, "printarea", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(PRINTCLIP, "printclip", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ + +pdf_gen1(OPENACTION, "openaction", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(OPENMODE, "openmode", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(BOOKMARKDEST, "bookmarkdest", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ +pdf_gen1(TRANSITION, "transition", 1, 1, pdf_state_all) /* dep6 */ +pdf_gen1(DURATION, "duration", 1, 1, pdf_state_all) /* dep6 */ +pdf_gen1(BASE, "base", 1, 1, + pdf_state_content | pdf_state_document) /* dep6 */ + +pdf_gen1(LAUNCHLINK_PARAMETERS, "launchlink:parameters", 1, 1, + pdf_state_all) /* dep6 */ +pdf_gen1(LAUNCHLINK_OPERATION, "launchlink:operation", 1, 1, + pdf_state_all) /* dep6 */ +pdf_gen1(LAUNCHLINK_DEFAULTDIR, "launchlink:defaultdir", 1, 1, + pdf_state_all) /* dep6 */ + + +/* + * ---------------------------------------------------------------------- + * Security (all dep6) + * ---------------------------------------------------------------------- + */ + +pdf_gen1(USERPASSWORD, "userpassword", 1, 1, pdf_state_object) /* dep6 */ +pdf_gen1(MASTERPASSWORD,"masterpassword",1,1, pdf_state_object) /* dep6 */ +pdf_gen1(PERMISSIONS, "permissions", 1, 1, pdf_state_object) /* dep6 */ + + +/* + * ---------------------------------------------------------------------- + * Tagged PDF + * ---------------------------------------------------------------------- + */ + +pdf_gen1(AUTOSPACE, "autospace", 1, 1, pdf_state_all) + + +#undef pdf_gen1 +#undef pdf_gen2 diff --git a/src/pdflib/pdflib/p_pattern.c b/src/pdflib/pdflib/p_pattern.c new file mode 100644 index 0000000..73306f7 --- /dev/null +++ b/src/pdflib/pdflib/p_pattern.c @@ -0,0 +1,231 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_pattern.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib pattern routines + * + */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +void +pdf_init_pattern(PDF *p) +{ + static const char fn[] = "pdf_init_pattern"; + int i; + + p->pattern_number = 0; + p->pattern_capacity = PATTERN_CHUNKSIZE; + + p->pattern = (pdf_pattern *) pdc_malloc(p->pdc, + sizeof(pdf_pattern) * p->pattern_capacity, fn); + + for (i = 0; i < p->pattern_capacity; i++) { + p->pattern[i].used_on_current_page = pdc_false; + p->pattern[i].obj_id = PDC_BAD_ID; + } +} + +void +pdf_grow_pattern(PDF *p) +{ + static const char fn[] = "pdf_grow_pattern"; + int i; + + p->pattern = (pdf_pattern *) pdc_realloc(p->pdc, p->pattern, + sizeof(pdf_pattern) * 2 * p->pattern_capacity, fn); + + for (i = p->pattern_capacity; i < 2 * p->pattern_capacity; i++) { + p->pattern[i].used_on_current_page = pdc_false; + p->pattern[i].obj_id = PDC_BAD_ID; + } + + p->pattern_capacity *= 2; +} + +void +pdf_write_page_pattern(PDF *p) +{ + int i, total = 0; + int bias = p->curr_ppt->pt_bias; + + for (i = 0; i < p->pattern_number; i++) + if (p->pattern[i].used_on_current_page) + total++; + + if (total > 0 || bias) + { + pdc_puts(p->out, "/Pattern"); + pdc_begin_dict(p->out); + } + + if (total > 0) + { + for (i = 0; i < p->pattern_number; i++) + { + if (p->pattern[i].used_on_current_page) + { + p->pattern[i].used_on_current_page = pdc_false; /* reset */ + pdc_printf(p->out, "/P%d", bias + i); + pdc_objref(p->out, "", p->pattern[i].obj_id); + } + } + + if (!bias) + pdc_end_dict(p->out); + } +} + +void +pdf_get_page_patterns(PDF *p, pdf_reslist *rl) +{ + int i; + + for (i = 0; i < p->pattern_number; i++) { + if (p->pattern[i].used_on_current_page) { + p->pattern[i].used_on_current_page = pdc_false; /* reset */ + pdf_add_reslist(p, rl, i); + } + } +} + +void +pdf_mark_page_pattern(PDF *p, int n) +{ + p->pattern[n].used_on_current_page = pdc_true; +} + +void +pdf_cleanup_pattern(PDF *p) +{ + if (p->pattern) { + pdc_free(p->pdc, p->pattern); + p->pattern = NULL; + } +} + +/* Start a new pattern definition. */ +int +pdf__begin_pattern( + PDF *p, + pdc_scalar width, + pdc_scalar height, + pdc_scalar xstep, + pdc_scalar ystep, + int painttype) +{ + int slot = -1; + + pdc_check_number_limits(p->pdc, "width", width, + PDC_FLOAT_PREC, PDC_FLOAT_MAX); + pdc_check_number_limits(p->pdc, "height", height, + PDC_FLOAT_PREC, PDC_FLOAT_MAX); + + pdc_check_number_zero(p->pdc, "xstep", xstep); + pdc_check_number_zero(p->pdc, "ystep", ystep); + + if (painttype != 1 && painttype != 2) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "painttype", pdc_errprintf(p->pdc, "%d", painttype), 0, 0); + + if (p->pattern_number == p->pattern_capacity) + pdf_grow_pattern(p); + + pdf_pg_suspend(p); + PDF_SET_STATE(p, pdf_state_pattern); + + p->pattern[p->pattern_number].obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); + p->pattern[p->pattern_number].painttype = painttype; + + pdc_begin_dict(p->out); /* pattern dict*/ + + p->res_id = pdc_alloc_id(p->out); + + pdc_puts(p->out, "/PatternType 1\n"); /* tiling pattern */ + + /* colored or uncolored pattern */ + pdc_printf(p->out, "/PaintType %d\n", painttype); + pdc_puts(p->out, "/TilingType 1\n"); /* constant spacing */ + + pdc_printf(p->out, "/BBox[0 0 %f %f]\n", width, height); + + pdc_printf(p->out, "/XStep %f\n", xstep); + pdc_printf(p->out, "/YStep %f\n", ystep); + + pdc_objref(p->out, "/Resources", p->res_id); + + p->length_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Length", p->length_id); + + if (pdc_get_compresslevel(p->out)) + pdc_puts(p->out, "/Filter/FlateDecode\n"); + + pdc_end_dict(p->out); /* pattern dict*/ + pdc_begin_pdfstream(p->out); + + slot = p->pattern_number; + p->pattern_number++; + + /* top-down y-coordinates */ + pdf_set_topdownsystem(p, height); + + /* set color differing from PDF default */ + pdf_set_default_color(p, pdc_false); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Begin pattern %d]\n", slot); + + return slot; +} + +/* Finish the pattern definition. */ +void +pdf__end_pattern(PDF *p) +{ + /* check whether pdf__save() and pdf__restore() calls are balanced */ + if (p->curr_ppt->sl > 0) + pdc_error(p->pdc, PDF_E_GSTATE_UNMATCHEDSAVE, 0, 0, 0, 0); + + pdf_end_text(p); + pdc_end_pdfstream(p->out); + pdc_end_obj(p->out); /* pattern */ + + pdc_put_pdfstreamlength(p->out, p->length_id); + + pdc_begin_obj(p->out, p->res_id); /* Resource object */ + pdc_begin_dict(p->out); /* Resource dict */ + + pdf_write_page_fonts(p); /* Font resources */ + + pdf_write_page_colorspaces(p); /* Color space resources */ + + pdf_write_page_pattern(p); /* Pattern resources */ + + pdf_write_xobjects(p); /* XObject resources */ + + pdf_write_page_extgstates(p); /* ExtGState resources */ + + pdc_end_dict(p->out); /* resource dict */ + pdc_end_obj(p->out); /* resource object */ + + pdf_pg_resume(p, -1); + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[End pattern %d]\n", + p->pattern_number -1); +} diff --git a/src/pdflib/pdflib/p_pdi.c b/src/pdflib/pdflib/p_pdi.c new file mode 100644 index 0000000..a138987 --- /dev/null +++ b/src/pdflib/pdflib/p_pdi.c @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_pdi.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDF import routines (require the PDI library) + * + */ + +#define P_PDI_C + +#include "p_intern.h" + + + + + + + diff --git a/src/pdflib/pdflib/p_pfm.c b/src/pdflib/pdflib/p_pfm.c new file mode 100644 index 0000000..cab291b --- /dev/null +++ b/src/pdflib/pdflib/p_pfm.c @@ -0,0 +1,406 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_pfm.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib routines for fast reading of PFM font metrics files + * + */ + +#include "p_intern.h" +#include "p_font.h" + +/* read data types from the PFM */ +#define PFM_BYTE(offset) pfm[offset] +#define PFM_WORD(offset) PDC_GET_WORD(&pfm[offset]) +#define PFM_SHORT(offset) PDC_GET_SHORT(&pfm[offset]) +#define PFM_DWORD(offset) PDC_GET_DWORD3(&pfm[offset]) + +/* Offsets in the buffer containing the various PFM structures */ +#define header_base 0 +#define header_dfVersion (PFM_WORD(header_base + 0)) +#define header_dfSize (PFM_DWORD(header_base + 2)) +#define header_dfAscent (PFM_WORD(header_base + 74)) +#define header_dfItalic (PFM_BYTE(header_base + 80)) +#define header_dfWeight (PFM_WORD(header_base + 83)) +#define header_dfCharSet (PFM_BYTE(header_base + 85)) +#define header_dfPitchAndFamily (PFM_BYTE(header_base + 90)) +#define header_dfMaxWidth (PFM_WORD(header_base + 93)) +#define header_dfFirstChar (PFM_BYTE(header_base + 95)) +#define header_dfLastChar (PFM_BYTE(header_base + 96)) +#define header_dfDefaultChar (PFM_BYTE(header_base + 97)) + +#define ext_base 117 +#define ext_dfExtentTable (PFM_DWORD(ext_base + 6)) +#define ext_dfKernPairs (PFM_DWORD(ext_base + 14)) +#define ext_dfKernTrack (PFM_DWORD(ext_base + 18)) +#define ext_dfDriverInfo (PFM_DWORD(ext_base + 22)) + +#define etm_base 147 +#define etmCapHeight (PFM_SHORT(etm_base + 14)) +#define etmXHeight (PFM_SHORT(etm_base + 16)) +#define etmLowerCaseAscent (PFM_SHORT(etm_base + 18)) +#define etmLowerCaseDescent (PFM_SHORT(etm_base + 20)) +#define etmSlant (PFM_SHORT(etm_base + 22)) +#define etmUnderlineOffset (PFM_SHORT(etm_base + 32)) +#define etmUnderlineWidth (PFM_SHORT(etm_base + 34)) + +#define dfDevice 199 + +/* Windows font descriptor flags */ +#define PDF_FIXED_PITCH 0x01 /* Fixed width font; rarely used flag */ + +#define PDF_DONTCARE 0x00 /* Don't care or don't know. */ +#define PDF_ROMAN 0x10 /* Variable stroke width, serifed */ +#define PDF_SWISS 0x20 /* Variable stroke width, sans-serifed */ +#define PDF_MODERN 0x30 /* fixed pitch */ +#define PDF_SCRIPT 0x40 /* Cursive, etc. */ +#define PDF_DECORATIVE 0x50 /* Old English, etc. */ + +/* Windows character set flags */ +#define PFM_ANSI_CHARSET 0 +#define PFM_SYMBOL_CHARSET 2 +#define PFM_GREEK_CHARSET 161 +#define PFM_TURKISH_CHARSET 162 +#define PFM_VIETNAMESE_CHARSET 163 +#define PFM_HEBREW_CHARSET 177 +#define PFM_ARABIC_CHARSET 178 +#define PFM_BALTIC_CHARSET 186 +#define PFM_RUSSIAN_CHARSET 204 +#define PFM_THAI_CHARSET 222 +#define PFM_EASTEUROPE_CHARSET 238 + +static const pdc_keyconn pdf_charset_keylist[] = +{ + {"winansi", PFM_ANSI_CHARSET }, + {"", PFM_SYMBOL_CHARSET }, + {"cp1253", PFM_GREEK_CHARSET }, + {"cp1254", PFM_TURKISH_CHARSET }, + {"cp1258", PFM_VIETNAMESE_CHARSET}, + {"cp1255", PFM_HEBREW_CHARSET }, + {"cp1256", PFM_ARABIC_CHARSET }, + {"cp1257", PFM_BALTIC_CHARSET }, + {"cp1251", PFM_RUSSIAN_CHARSET }, + {"cp874", PFM_THAI_CHARSET }, + {"cp1250", PFM_EASTEUROPE_CHARSET}, + {NULL, 0}, +}; + +#define PDF_STRING_PostScript \ + ((const char*) "\120\157\163\164\123\143\162\151\160\164") + +/* + * Kerning pairs + */ +typedef struct kern_ +{ + pdc_byte first; /* First character */ + pdc_byte second; /* Second character */ + pdc_byte kern[2]; /* Kern distance */ +} +KERN; + +pdc_bool +pdf_check_pfm_encoding(PDF *p, pdf_font *font, pdc_encoding enc) +{ + const char *encname = + pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, + pdf_get_encoding_name(p, enc, font)); + const char *newencname = NULL; + pdc_encoding newenc = pdc_invalidenc; + pdc_bool issymbfont = pdc_undef; + + pdc_logg_cond(p->pdc, 2, trc_font, + "\tFont internal charset (dfCharSet): %d\n", font->ft.enc); + + /* Font encoding */ + newencname = pdc_get_keyword(font->ft.enc, pdf_charset_keylist); + if (newencname == NULL) + { + pdc_set_errmsg(p->pdc, PDF_E_T1_BADCHARSET, + pdc_errprintf(p->pdc, "%d", font->ft.enc), 0, 0, 0); + return pdc_false; + } + + if (strlen(newencname)) + { + int codepage = 0; + + pdc_logg_cond(p->pdc, 2, trc_font, + "\tFont internal encoding \"%s\" found\n", newencname); + + newenc = pdc_find_encoding(p->pdc, newencname); + if (newenc == pdc_invalidenc) + newenc = pdc_insert_encoding(p->pdc, newencname, &codepage, + pdc_true); + + font->ft.issymbfont = pdc_false; + } + else + { + pdc_logg_cond(p->pdc, 2, trc_font, "\tSymbol font\n"); + + font->ft.issymbfont = pdc_true; + newenc = pdc_builtin; + + /* auto */ + if (!strcmp(font->encapiname, "auto")) + { + issymbfont = pdc_true; + enc = pdc_builtin; + } + } + + /* builtin */ + if (enc == pdc_builtin) + issymbfont = pdc_true; + + /* unicode */ + if (enc == pdc_unicode) + { + font->unibyte = pdc_true; + issymbfont = pdc_false; + enc = newenc; + } + + /* encoding is subset of 8-bit encoding */ + if (enc >= pdc_winansi && newenc >= pdc_winansi) + { + if (pdc_is_encoding_subset(p->pdc, pdc_get_encoding_vector(p->pdc, enc), + pdc_get_encoding_vector(p->pdc, newenc))) + { + if (enc != pdc_winansi && newenc == pdc_winansi && + strcmp(encname, "iso8859-1")) + font->towinansi = pdc_invalidenc; + + issymbfont = pdc_false; + enc = newenc; + } + } + + /* illegal encoding */ + if (issymbfont == pdc_undef || font->ft.issymbfont == pdc_undef) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC, 0, 0, 0, 0); + return pdc_false; + } + + font->ft.enc = enc; + if (issymbfont && !font->ft.issymbfont) + { + pdc_warning(p->pdc, PDF_E_FONT_FORCEENC, + pdf_get_encoding_name(p, newenc, NULL), + 0, 0, 0); + font->ft.enc = newenc; + } + if (!issymbfont && font->ft.issymbfont) + { + pdc_warning(p->pdc, PDF_E_FONT_FORCEENC, + pdf_get_encoding_name(p, pdc_builtin, NULL), + 0, 0, 0); + font->ft.enc = pdc_builtin; + font->towinansi = pdc_invalidenc; + } + + if (font->towinansi != pdc_invalidenc) + pdf_transform_fontwidths(p, font, + pdc_get_encoding_vector(p->pdc, font->ft.enc), + pdc_get_encoding_vector(p->pdc, font->towinansi)); + + return pdc_true; +} + + +/* + * Currently we do not populate the following fields correctly: + * - serif flag + */ + +static pdc_bool +pdf_parse_pfm(PDF *p, pdc_file *fp, pdf_font *font) +{ + static const char fn[] = "pdf_parse_pfm"; + fnt_font_metric *ftm = &font->ft.m; + size_t length; + pdc_byte *pfm; + pdc_bool ismem; + int i, dfFirstChar, dfLastChar, default_width; + unsigned long dfExtentTable; + + /* read whole file and close it */ + pfm = (pdc_byte *) pdc_freadall(fp, &length, &ismem); + pdc_fclose(fp); + + /* check whether this is really a valid PostScript PFM file */ + if (pfm == NULL || + (header_dfVersion != 0x100 && header_dfVersion != 0x200) || + dfDevice > length || + strncmp((const char *) pfm + dfDevice, PDF_STRING_PostScript, 10) || + ext_dfDriverInfo > length) + { + if (!ismem) + pdc_free(p->pdc, pfm); + return pdc_false; + } + + /* fetch relevant data from the PFM */ + ftm->type = fnt_Type1; + + font->ft.name = pdc_strdup(p->pdc, (const char *)pfm + ext_dfDriverInfo); + ftm->name = pdc_strdup(p->pdc, font->ft.name); + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tPostScript font name: \"%s\"\n", ftm->name); + + switch (header_dfPitchAndFamily & 0xF0) + { + case PDF_ROMAN: + ftm->flags |= FNT_SERIF; + break; + case PDF_MODERN: + /* Has to be ignored, contrary to MS's specs */ + break; + case PDF_SCRIPT: + ftm->flags |= FNT_SCRIPT; + break; + case PDF_DECORATIVE: + /* the dfCharSet flag lies in this case... */ + header_dfCharSet = PFM_SYMBOL_CHARSET; + break; + case PDF_SWISS: + case PDF_DONTCARE: + default: + break; + } + + /* temporarily */ + font->ft.enc = (pdc_encoding) header_dfCharSet; + + dfFirstChar = header_dfFirstChar; + dfLastChar = header_dfLastChar; + dfExtentTable = ext_dfExtentTable; + + /* + * Some rare PFMs do not contain any ExtentTable if the fixed pitch flag + * is set. Use the dfMaxWidth entry for all glyphs in this case. + * If the user forced the font to be monospaced we use this value instead. + */ + if ((!(header_dfPitchAndFamily & PDF_FIXED_PITCH) && dfExtentTable == 0) || + font->opt.monospace) + { + ftm->isFixedPitch = pdc_true; + default_width = font->opt.monospace ? font->opt.monospace : + (int) header_dfMaxWidth; + } + else + { + /* default values -- don't take the width of the default character */ + default_width = FNT_DEFAULT_WIDTH; + } + + font->ft.numcodes = 256; + ftm->numwidths = font->ft.numcodes; + ftm->widths = (int *) pdc_calloc(p->pdc, ftm->numwidths * sizeof(int), fn); + for (i = 0; i < font->ft.numcodes; i++) + ftm->widths[i] = default_width; + + if (!ftm->isFixedPitch) + { + if (ext_dfExtentTable == 0 || + ext_dfExtentTable + 2 * (header_dfLastChar-header_dfFirstChar) + 1 > + length) + { + if (!ismem) + pdc_free(p->pdc, pfm); + return pdc_false; + } + + for (i = dfFirstChar; i <= dfLastChar; i++) + ftm->widths[i] = + (int) PFM_WORD(dfExtentTable + 2 * (i - dfFirstChar)); + /* + * Check whether the font is actually opt.monospaced + * (the fixed pitch flag is not necessarily set) + */ + default_width = ftm->widths[dfFirstChar]; + + for (i = dfFirstChar+1; i <= dfLastChar; i++) + if (default_width != ftm->widths[i]) + break; + + if (i == dfLastChar + 1) + ftm->isFixedPitch = pdc_true; + } + + font->ft.weight = fnt_check_weight(header_dfWeight); + ftm->defwidth = default_width; + ftm->italicAngle = (header_dfItalic ? etmSlant/(10.0) : 0.0); + ftm->capHeight = etmCapHeight; + ftm->xHeight = etmXHeight; + ftm->descender = -etmLowerCaseDescent; + ftm->ascender = (int) header_dfAscent; + + ftm->underlinePosition = -etmUnderlineOffset; + ftm->underlineThickness = etmUnderlineWidth; + + ftm->urx = header_dfMaxWidth; + + + if (!ismem) + pdc_free(p->pdc, pfm); + + return pdc_true; +} + +pdc_bool +pdf_get_metrics_pfm( + PDF *p, + pdf_font *font, + const char *fontname, + pdc_encoding enc, + const char *filename, + pdc_bool requested) +{ + static const char fn[] = "pdf_get_metrics_pfm"; + char fullname[PDC_FILENAMELEN]; + pdc_file *pfmfile; + + (void) fontname; + + /* open PFM file */ + pfmfile = pdc_fsearch_fopen(p->pdc, filename, fullname, "PFM ", + PDC_FILE_BINARY); + if (pfmfile == NULL) + return pdc_check_fopen_errmsg(p->pdc, requested); + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tLoading PFM metric fontfile \"%s\":\n", fullname); + + /* Read PFM metrics */ + if (!pdf_parse_pfm(p, pfmfile, font)) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_CORRUPT, "PFM", fullname, 0, 0); + return pdc_false; + } + + /* save full filename */ + font->metricfilename = pdc_strdup_ext(p->pdc, fullname, 0, fn); + + /* Check encoding */ + if (!pdf_check_pfm_encoding(p, font, enc)) + return pdc_false; + + if (!pdf_make_fontflag(p, font)) + return pdc_false; + + return pdc_true; +} diff --git a/src/pdflib/pdflib/p_photoshp.c b/src/pdflib/pdflib/p_photoshp.c new file mode 100644 index 0000000..354f547 --- /dev/null +++ b/src/pdflib/pdflib/p_photoshp.c @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_photoshp.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib Photoshop image resource data routines + * + */ + +#define P_PHOTOSHP_C + +#include "p_intern.h" +#include "p_image.h" + diff --git a/src/pdflib/pdflib/p_png.c b/src/pdflib/pdflib/p_png.c new file mode 100644 index 0000000..42359a3 --- /dev/null +++ b/src/pdflib/pdflib/p_png.c @@ -0,0 +1,855 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_png.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PNG processing for PDFlib + * + */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +#if defined(__ia64__) && defined (__linux__) +#define PDF_ALIGN16 +#endif + +/* SPNG - Simple PNG +** +** The items below, prefixed with spng_, or SPNG_, establish a replacement +** for LIBPNG that works very fast, but processes simple PNG images only: +** - bit_depth <= 8 (no 16-bit) +** - interlace_type 0 (no interlacing) +** - color_type 0, 2, or 3 (no alpha-channel); color type 3 requires +** libpng for palette processing +*/ +#define SPNG_SIGNATURE "\211\120\116\107\015\012\032\012" + +#define SPNG_CHUNK_IHDR 0x49484452 +#define SPNG_CHUNK_PLTE 0x504C5445 +#define SPNG_CHUNK_tRNS 0x74524E53 +#define SPNG_CHUNK_IDAT 0x49444154 +#define SPNG_CHUNK_IEND 0x49454E44 + +/* spng_init() return codes +*/ +#define SPNG_ERR_OK 0 /* no error */ +#define SPNG_ERR_NOPNG 1 /* bad PNG signature */ +#define SPNG_ERR_FMT 2 /* bad PNG file format */ + +typedef struct +{ + /* from IHDR: + */ + int width; + int height; + pdc_byte bit_depth; + pdc_byte color_type; + pdc_byte compr_type; + pdc_byte filter_type; + pdc_byte interlace_type; +} spng_info; + +static int +spng_getint(pdc_file *fp) +{ + unsigned char buf[4]; + + if (!PDC_OK_FREAD(fp, buf, 4)) + return -1; + + return (int) pdc_get_be_long(buf); +} /* spng_getint */ + +static int +spng_init(PDF *p, pdf_image *image, spng_info *spi) +{ + pdc_file *fp = image->fp; + char buf[8]; + + (void) p; + + /* check signature + */ + if (!PDC_OK_FREAD(fp, buf, 8) || + strncmp(buf, SPNG_SIGNATURE, 8) != 0) + return SPNG_ERR_NOPNG; + + /* read IHDR + */ + if (spng_getint(fp) != 13 || + spng_getint(fp) != SPNG_CHUNK_IHDR) + return SPNG_ERR_FMT; + + spi->width = spng_getint(fp); + spi->height = spng_getint(fp); + + if (!PDC_OK_FREAD(fp, buf, 5)) + return SPNG_ERR_FMT; + + spi->bit_depth = (pdc_byte) buf[0]; + spi->color_type = (pdc_byte) buf[1]; + spi->compr_type = (pdc_byte) buf[2]; + spi->filter_type = (pdc_byte) buf[3]; + spi->interlace_type = (pdc_byte) buf[4]; + + (void) spng_getint(fp); /* CRC */ + + /* decide whether this image is "simple". + */ +#ifdef HAVE_LIBPNG + if (spi->bit_depth > 8 || spi->color_type > 3 || spi->interlace_type != 0) +#else + if (spi->bit_depth > 8 || spi->color_type > 2 || spi->interlace_type != 0) +#endif /* !HAVE_LIBPNG */ + { + image->use_raw = pdc_false; + return SPNG_ERR_OK; + } + else + image->use_raw = pdc_true; + + /* read (or skip) all chunks up to the first IDAT. + */ + for (/* */ ; /* */ ; /* */) + { + int len = spng_getint(fp); + int type = spng_getint(fp); + + switch (type) + { + case SPNG_CHUNK_IDAT: /* prepare data xfer */ + image->info.png.nbytes = (size_t) len; + return SPNG_ERR_OK; + + case -1: + return SPNG_ERR_FMT; + + /* if we decide to live without LIBPNG, + ** we should handle these cases, too. + */ + case SPNG_CHUNK_tRNS: /* transparency chunk */ + case SPNG_CHUNK_PLTE: /* read in palette */ + + default: + pdc_fseek(fp, len + 4, SEEK_CUR); + /* skip data & CRC */ + break; + } /* switch */ + } + + return SPNG_ERR_OK; +} /* spng_init */ + +#define PDF_PNG_BUFFERSIZE 8192 + +static void +pdf_data_source_PNG_init(PDF *p, PDF_data_source *src) +{ + static const char fn[] = "pdf_data_source_PNG_init"; + pdf_image *image = (pdf_image *) src->private_data; + +#ifdef HAVE_LIBPNG + if (image->use_raw) + { +#endif + src->buffer_length = PDF_PNG_BUFFERSIZE; + src->buffer_start = (pdc_byte *) + pdc_malloc(p->pdc, src->buffer_length, fn); + src->bytes_available = 0; + src->next_byte = src->buffer_start; + +#ifdef HAVE_LIBPNG + } + else + { + image->info.png.cur_line = 0; + src->buffer_length = image->info.png.rowbytes; + } +#endif +} + +#undef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +static void +spng_error(PDF *p, PDF_data_source *src) +{ + pdf_image *image = (pdf_image *) src->private_data; + + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "PNG", + pdf_get_image_filename(p, image), 0, 0); +} /* spng_error */ + +static pdc_bool +pdf_data_source_PNG_fill(PDF *p, PDF_data_source *src) +{ + pdf_image *image = (pdf_image *) src->private_data; + + PDC_TRY(p->pdc) + { +#ifdef HAVE_LIBPNG + if (image->use_raw) + { +#endif + pdc_file * fp = image->fp; + size_t buf_avail = src->buffer_length; + pdc_byte *scan = src->buffer_start; + + src->bytes_available = 0; + + if (image->info.png.nbytes == 0) + { + PDC_EXIT_TRY(p->pdc); + return pdc_false; + } + + do + { + size_t nbytes = min(image->info.png.nbytes, buf_avail); + + if (!PDC_OK_FREAD(fp, scan, nbytes)) + spng_error(p, src); + + src->bytes_available += nbytes; + scan += nbytes; + buf_avail -= nbytes; + + if ((image->info.png.nbytes -= nbytes) == 0) + { + /* proceed to next IDAT chunk + */ + (void) spng_getint(fp); /* CRC */ + image->info.png.nbytes = + (size_t) spng_getint(fp); /* length */ + + if (spng_getint(fp) != SPNG_CHUNK_IDAT) + { + image->info.png.nbytes = 0; + PDC_EXIT_TRY(p->pdc); + return pdc_true; + } + } + } + while (buf_avail); + +#ifdef HAVE_LIBPNG + } + else + { + if (image->info.png.cur_line == image->height) + { + PDC_EXIT_TRY(p->pdc); + return pdc_false; + } + + src->next_byte = image->info.png.raster + + image->info.png.cur_line * image->info.png.rowbytes; + + src->bytes_available = src->buffer_length; + + image->info.png.cur_line++; + } +#endif /* HAVE_LIBPNG */ + } + PDC_CATCH(p->pdc) + { + image->corrupt = pdc_true; + } + + return !image->corrupt; +} + +static void +pdf_data_source_PNG_terminate(PDF *p, PDF_data_source *src) +{ + pdf_image *image = (pdf_image *) src->private_data; + +#ifdef HAVE_LIBPNG + if (image->use_raw) + { +#endif + pdc_free(p->pdc, (void *) src->buffer_start); + +#ifdef HAVE_LIBPNG + } +#endif +} + +#ifdef HAVE_LIBPNG +/* + * We suppress libpng's warning message by supplying + * our own error and warning handlers +*/ +static void +pdf_libpng_warning_handler(png_structp png_ptr, png_const_charp message) +{ + (void) png_ptr; /* avoid compiler warning "unreferenced parameter" */ + (void) message; /* avoid compiler warning "unreferenced parameter" */ + + /* do nothing */ + return; +} + +/* + * use the libpng portability aid in an attempt to overcome version differences + */ +#ifndef png_jmpbuf +#define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#endif + +static void +pdf_libpng_error_handler(png_structp png_ptr, png_const_charp message) +{ +#ifdef PDF_ALIGN16 + jmp_buf jbuf; +#endif + + (void) message; /* avoid compiler warning "unreferenced parameter" */ + +#ifdef PDF_ALIGN16 + memcpy(jbuf, png_jmpbuf(png_ptr), sizeof (jmp_buf)); + longjmp(jbuf, 1); +#else + longjmp(png_jmpbuf(png_ptr), 1); +#endif +} + +static void * +pdf_libpng_malloc(png_structp png_ptr, size_t size) +{ + PDF *p = (PDF *)png_ptr->mem_ptr; + + return pdc_malloc(p->pdc, size, "libpng"); +} + +static void +pdf_libpng_free(png_structp png_ptr, void *mem) +{ + PDF *p = (PDF *)png_ptr->mem_ptr; + + pdc_free(p->pdc, mem); +} + +pdc_bool +pdf_is_PNG_file(PDF *p, pdc_file *fp) +{ + pdc_byte sig[8]; + + pdc_logg_cond(p->pdc, 1, trc_image, "\tChecking image type PNG...\n"); + + if (!PDC_OK_FREAD(fp, sig, 8) || !png_check_sig(sig, 8)) { + pdc_fseek(fp, 0L, SEEK_SET); + return pdc_false; + } + return pdc_true; +} + +static void /* CDPDF - moved to inside the HAVE_LIBPNG definition */ +pdf_png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + pdc_file *fp = (pdc_file *) png_ptr->io_ptr; + char *filename = (char *) pdc_file_name(fp); + + if (!PDC_OK_FREAD(fp, data, length)) + { + pdc_core *pdc = pdc_file_getpdc(fp); + + pdc_error(pdc, PDF_E_IMAGE_CORRUPT, "PNG", filename, 0, 0); + } +} + +int +pdf_process_PNG_data( + PDF *p, + int imageslot) +{ + static const char *fn = "pdf_process_PNG_data"; + pdc_file *save_fp; + spng_info s_info; +#ifdef PDF_ALIGN16 + jmp_buf jbuf; +#endif + + png_uint_32 width, height, ui; + png_bytep *row_pointers = NULL, trans; + png_color_8p sig_bit; + png_color_16p trans_values; + int bit_depth, color_type, i, num_trans; + pdc_scalar dpi_x, dpi_y; + pdf_image *image; + volatile int errcode = 0; + pdf_colorspace cs; + pdf_colormap * volatile colormap = NULL; + volatile int slot; + + image = &p->images[imageslot]; + + /* + * We can install our own memory handlers in libpng since + * our PNG library is specially extended to support this. + * A custom version of libpng without support for + * png_create_read_struct_2() is no longer supported. + */ + + image->info.png.png_ptr = + png_create_read_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, + (png_error_ptr)pdf_libpng_error_handler, (png_error_ptr)pdf_libpng_warning_handler, /* CDPDF - added type cast */ + p, (png_malloc_ptr) pdf_libpng_malloc, + (png_free_ptr) pdf_libpng_free); + + if (!image->info.png.png_ptr) + { + pdc_error(p->pdc, PDC_E_MEM_OUT, fn, 0, 0, 0); + } + + image->info.png.info_ptr = png_create_info_struct(image->info.png.png_ptr); + + if (image->info.png.info_ptr == NULL) + { + png_destroy_read_struct(&image->info.png.png_ptr, + (png_infopp) NULL, (png_infopp) NULL); + pdc_error(p->pdc, PDC_E_MEM_OUT, fn, 0, 0, 0); + } + + /* due to alignment bug on itanium machines: + ** use well aligned local jbuf instead of sometimes + ** bad aligned (allocated) jmp_buf. + */ +#ifdef PDF_ALIGN16 + if (setjmp(jbuf)) +#else + if (setjmp(png_jmpbuf(image->info.png.png_ptr))) +#endif + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_PNG_ERROR; + } +#ifdef PDF_ALIGN16 + memcpy(png_jmpbuf(image->info.png.png_ptr), jbuf, sizeof (jmp_buf)); +#endif + + if (pdf_is_PNG_file(p, image->fp) == pdc_false) + { + errcode = PDC_E_IO_BADFORMAT; + goto PDF_PNG_ERROR; + } + + /* from file or from memory */ + png_set_read_fn(image->info.png.png_ptr, image->fp, (png_rw_ptr)pdf_png_read_data); /* CDPDF - added type cast */ + + png_set_sig_bytes(image->info.png.png_ptr, 8); + png_read_info(image->info.png.png_ptr, image->info.png.info_ptr); + png_get_IHDR(image->info.png.png_ptr, image->info.png.info_ptr, + &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); + + image->width = (pdc_scalar) width; + image->height = (pdc_scalar) height; + + /* reduce 16-bit images to 8 bit since PDF < 1.5 stops at 8 bit */ + if (p->compatibility < PDC_1_5 && bit_depth == 16) + { + png_set_strip_16(image->info.png.png_ptr); + bit_depth = 8; + } + + image->bpc = bit_depth; + + /* + * We currently don't support a real alpha channel but only binary + * tranparency ("poor man's alpha"). For palette images we do our best and + * treat alpha values of up to 50% as transparent, and values above 50% + * as opaque. Gray and RGB images with an associated alpha channel will + * be pre-multiplied by libpng (against white background). + */ +#define ALPHA_THRESHOLD 128 + + switch (color_type) + { + case PNG_COLOR_TYPE_GRAY_ALPHA: + /* LATER: construct mask from alpha channel */ + /* + png_set_IHDR(image->info.png.png_ptr, image->info.png.info_ptr, + width, height, bit_depth, PNG_COLOR_MASK_ALPHA, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + */ + /* + * We strip the alpha channel, and let libpng pre-multiply + * the opacity values to the image data. + */ + png_set_strip_alpha(image->info.png.png_ptr); + /* fall through */ + + case PNG_COLOR_TYPE_GRAY: + if (png_get_sBIT(image->info.png.png_ptr, + image->info.png.info_ptr, &sig_bit)) + { + png_set_shift(image->info.png.png_ptr, sig_bit); + } + + image->colorspace = DeviceGray; + + image->components = 1; + break; + + case PNG_COLOR_TYPE_RGB_ALPHA: + /* LATER: construct mask from alpha channel */ + /* + * We strip the alpha channel, and let libpng pre-multiply + * the opacity values to the image data. + */ + png_set_strip_alpha(image->info.png.png_ptr); + /* fall through */ + + case PNG_COLOR_TYPE_RGB: + if (image->colorspace == pdc_undef) + image->colorspace = DeviceRGB; + image->components = 3; + + break; + + case PNG_COLOR_TYPE_PALETTE: + { + png_colorp pcm; + + png_get_PLTE(image->info.png.png_ptr, image->info.png.info_ptr, + &pcm, &cs.val.indexed.palette_size); + + colormap = + (pdf_colormap *) pdc_malloc(p->pdc, sizeof(pdf_colormap), fn); + + /* This seems redundant, but the png_colorp structure may not + * be packed on some platforms. + */ + for (i = 0; i < cs.val.indexed.palette_size; i++) + { + (*colormap)[i][0] = (pdc_byte) pcm[i].red; + (*colormap)[i][1] = (pdc_byte) pcm[i].green; + (*colormap)[i][2] = (pdc_byte) pcm[i].blue; + } + + image->components = 1; + + /* This case should arguably be prohibited. However, we allow + * it and take the palette indices 0 and 1 as the mask, + * disregarding any color values in the palette. + */ + if (image->imagemask) { + image->colorspace = DeviceGray; + break; + } + + cs.type = Indexed; + cs.val.indexed.base = DeviceRGB; + cs.val.indexed.colormap = colormap; + cs.val.indexed.colormap_id = PDC_BAD_ID; + slot = pdf_add_colorspace(p, &cs, pdc_false); + + image->colorspace = slot; + + } + break; + } + if (colormap) + pdc_free(p->pdc, colormap); + + if (image->imagemask) + { + if (image->components != 1) + { + errcode = PDF_E_IMAGE_BADMASK; + goto PDF_PNG_ERROR; + } + + if (p->compatibility <= PDC_1_3) { + if (image->components != 1 || image->bpc != 1) + { + errcode = PDF_E_IMAGE_MASK1BIT13; + goto PDF_PNG_ERROR; + } + } + else if (image->bpc > 1) + { + /* images with more than one bit will be written as /SMask, + * and don't require an /ImageMask entry. + */ + image->imagemask = pdc_false; + } + image->colorspace = DeviceGray; + } + + /* we invert this flag later */ + if (image->ignoremask) + image->transparent = pdc_true; + + /* let libpng expand interlaced images */ + (void) png_set_interlace_handling(image->info.png.png_ptr); + + /* read the physical dimensions chunk to find the resolution values */ + dpi_x = (pdc_scalar) png_get_x_pixels_per_meter(image->info.png.png_ptr, + image->info.png.info_ptr); + dpi_y = (pdc_scalar) png_get_y_pixels_per_meter(image->info.png.png_ptr, + image->info.png.info_ptr); + + if (dpi_x != 0 && dpi_y != 0) + { /* absolute values */ + image->dpi_x = dpi_x * PDC_INCH2METER; + image->dpi_y = dpi_y * PDC_INCH2METER; + + } + else + { /* aspect ratio */ + image->dpi_y = -png_get_pixel_aspect_ratio(image->info.png.png_ptr, + image->info.png.info_ptr); + + if (image->dpi_y == 0) /* unknown */ + image->dpi_x = 0; + else + image->dpi_x = -1.0; + } + + /* read the transparency chunk */ + if (png_get_valid(image->info.png.png_ptr, image->info.png.info_ptr, + PNG_INFO_tRNS)) + { + png_get_tRNS(image->info.png.png_ptr, image->info.png.info_ptr, + &trans, &num_trans, &trans_values); + if (num_trans > 0) + { + if (color_type == PNG_COLOR_TYPE_GRAY) + { + image->transparent = !image->transparent; + /* LATER: scale down 16-bit transparency values ? */ + image->transval[0] = (pdc_byte) trans_values[0].gray; + + } + else if (color_type == PNG_COLOR_TYPE_RGB) + { + image->transparent = !image->transparent; + /* LATER: scale down 16-bit transparency values ? */ + image->transval[0] = (pdc_byte) trans_values[0].red; + image->transval[1] = (pdc_byte) trans_values[0].green; + image->transval[2] = (pdc_byte) trans_values[0].blue; + + } + else if (color_type == PNG_COLOR_TYPE_PALETTE) + { + /* we use the first transparent entry in the tRNS palette */ + for (i = 0; i < num_trans; i++) + { + if ((pdc_byte) trans[i] < ALPHA_THRESHOLD) + { + image->transparent = !image->transparent; + image->transval[0] = (pdc_byte) i; + break; + } + } + } + } + } + + + + + png_read_update_info(image->info.png.png_ptr, image->info.png.info_ptr); + + image->info.png.rowbytes = + png_get_rowbytes(image->info.png.png_ptr, image->info.png.info_ptr); + + image->info.png.raster = (pdc_byte *) + pdc_calloc(p->pdc,image->info.png.rowbytes * height, fn); + + row_pointers = (png_bytep *) + pdc_malloc(p->pdc, height * sizeof(png_bytep), fn); + + for (ui = 0; ui < height; ui++) + { + row_pointers[ui] = + image->info.png.raster + ui * image->info.png.rowbytes; + } + + /* try the simple way: + */ + save_fp = image->fp; + + image->src.init = pdf_data_source_PNG_init; + image->src.fill = pdf_data_source_PNG_fill; + image->src.terminate = pdf_data_source_PNG_terminate; + image->src.private_data = (void *) image; + + + image->fp = pdc_fsearch_fopen(p->pdc, image->filename, NULL, NULL, + PDC_FILE_BINARY); + if (image->fp != NULL && + spng_init(p, image, &s_info) == SPNG_ERR_OK && image->use_raw) + { + pdc_fclose(save_fp); + image->predictor = pred_png; + image->compression = pdf_comp_flate; + } + else + { + if (image->fp != (pdc_file *) 0) + pdc_fclose(image->fp); + + image->fp = save_fp; + + /* Provide a suitable background for images with alpha channel */ + if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_color_16p image_background; + + if (png_get_bKGD(image->info.png.png_ptr, image->info.png.info_ptr, + &image_background)) + { + png_set_background(image->info.png.png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + } + else + { + png_color_16 my_white; + + if (bit_depth == 8) + { + my_white.red = 0xFF; + my_white.green = 0xFF; + my_white.blue = 0xFF; + my_white.gray = 0xFF; + } + else + { + my_white.red = 0xFFFF; + my_white.green = 0xFFFF; + my_white.blue = 0xFFFF; + my_white.gray = 0xFFFF; + } + + png_set_background(image->info.png.png_ptr, &my_white, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + } + } + + /* fetch the actual image data */ + png_read_image(image->info.png.png_ptr, row_pointers); + } + + image->in_use = pdc_true; /* mark slot as used */ + + pdf_put_image(p, imageslot, pdc_true, pdc_true); + + pdc_free(p->pdc, image->info.png.raster); + if (row_pointers != NULL) + pdc_free(p->pdc, row_pointers); + + png_destroy_read_struct(&image->info.png.png_ptr, + &image->info.png.info_ptr, NULL); + + if (!image->corrupt) + return imageslot; + + PDF_PNG_ERROR: + { + const char *stemp = NULL; + + if (errcode) + { + png_destroy_read_struct(&image->info.png.png_ptr, + &image->info.png.info_ptr, NULL); + stemp = pdf_get_image_filename(p, image); + } + + switch (errcode) + { + case PDF_E_IMAGE_ICC: + case PDF_E_IMAGE_ICC2: + case PDF_E_IMAGE_MASK1BIT13: + case PDF_E_IMAGE_BADMASK: + pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0); + break; + + case PDC_E_IO_BADFORMAT: + pdc_set_errmsg(p->pdc, errcode, stemp, "PNG", 0, 0); + break; + + case PDF_E_IMAGE_CORRUPT: + pdc_set_errmsg(p->pdc, errcode, "PNG", stemp, 0, 0); + break; + + case 0: /* error code and message already set */ + break; + } + } + + return -1; +} + +#else /* !HAVE_LIBPNG */ + +pdc_bool +pdf_is_PNG_file(PDF *p, pdc_file *fp) +{ + return pdc_false; +} + +/* simple built-in PNG reader without libpng */ + +int +pdf_process_PNG_data( + PDF *p, + int imageslot) +{ + static const char fn[] = "pdf_process_PNG_data"; + spng_info s_info; + pdf_image *image; + + image = &p->images[imageslot]; + + image->src.init = pdf_data_source_PNG_init; + image->src.fill = pdf_data_source_PNG_fill; + image->src.terminate = pdf_data_source_PNG_terminate; + image->src.private_data = (void *) image; + + if (spng_init(p, image, &s_info) == SPNG_ERR_OK && image->use_raw) + { + image->predictor = pred_png; + image->compression = pdf_comp_flate; /* CDPDF - fixed function name */ + + image->width = (pdc_scalar) s_info.width; + image->height = (pdc_scalar) s_info.height; + image->bpc = s_info.bit_depth; + + image->components = 3; + + /* other types are rejected in spng_init() */ + image->colorspace = + (s_info.color_type == 0 ? DeviceGray : DeviceRGB); + + + + } + else + { + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "PNG", 0, 0, 0); + return -1; + } + + image->in_use = pdc_true; /* mark slot as used */ + + pdf_put_image(p, imageslot, pdc_true, pdc_true); + + return image->corrupt ? -1 : imageslot; +} + +#endif /* !HAVE_LIBPNG */ diff --git a/src/pdflib/pdflib/p_shading.c b/src/pdflib/pdflib/p_shading.c new file mode 100644 index 0000000..e027ce6 --- /dev/null +++ b/src/pdflib/pdflib/p_shading.c @@ -0,0 +1,381 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_shading.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib routines for smooth shading + * + */ + +#include "p_intern.h" +#include "p_color.h" + +typedef enum +{ + shnone = 0, + axial = 2, + radial = 3 +} pdf_shadingtype_e; + +struct pdf_shading_s { + pdc_id obj_id; /* object id of this shading */ + pdc_bool used_on_current_page; /* this shading used on current page */ +}; + +void +pdf_init_shadings(PDF *p) +{ + int i; + + p->shadings_number = 0; + p->shadings_capacity = SHADINGS_CHUNKSIZE; + + p->shadings = (pdf_shading *) pdc_malloc(p->pdc, + sizeof(pdf_shading) * p->shadings_capacity, "pdf_init_shadings"); + + for (i = 0; i < p->shadings_capacity; i++) { + p->shadings[i].used_on_current_page = pdc_false; + p->shadings[i].obj_id = PDC_BAD_ID; + } +} + +static void +pdf_grow_shadings(PDF *p) +{ + int i; + + p->shadings = (pdf_shading *) pdc_realloc(p->pdc, p->shadings, + sizeof(pdf_shading) * 2 * p->shadings_capacity, "pdf_grow_shadings"); + + for (i = p->shadings_capacity; i < 2 * p->shadings_capacity; i++) { + p->shadings[i].used_on_current_page = pdc_false; + p->shadings[i].obj_id = PDC_BAD_ID; + } + + p->shadings_capacity *= 2; +} + +void +pdf_write_page_shadings(PDF *p) +{ + int i, total = 0; + int bias = p->curr_ppt->sh_bias; + + for (i = 0; i < p->shadings_number; i++) + if (p->shadings[i].used_on_current_page) + total++; + + if (total > 0 || bias) + { + pdc_puts(p->out, "/Shading"); + pdc_begin_dict(p->out); + } + + if (total > 0) + { + for (i = 0; i < p->shadings_number; i++) + { + if (p->shadings[i].used_on_current_page) + { + p->shadings[i].used_on_current_page = pdc_false; /* reset */ + pdc_printf(p->out, "/Sh%d", bias + i); + pdc_objref(p->out, "", p->shadings[i].obj_id); + } + } + + if (!bias) + pdc_end_dict(p->out); + } +} + +void +pdf_get_page_shadings(PDF *p, pdf_reslist *rl) +{ + int i; + + for (i = 0; i < p->shadings_number; i++) { + if (p->shadings[i].used_on_current_page) { + p->shadings[i].used_on_current_page = pdc_false; /* reset */ + pdf_add_reslist(p, rl, i); + } + } +} + +void +pdf_mark_page_shading(PDF *p, int n) +{ + p->shadings[n].used_on_current_page = pdc_true; +} + +void +pdf_cleanup_shadings(PDF *p) +{ + if (p->shadings) { + pdc_free(p->pdc, p->shadings); + p->shadings = NULL; + } +} + +int +pdf_get_shading_painttype(PDF *p) +{ + return p->pattern[p->pattern_number - 1].painttype; +} + + +static const pdc_defopt pdf_shading_pattern_options[] = +{ + {"gstate", pdc_gstatehandle, 0, 1, 1, 0, 0, NULL}, + PDC_OPT_TERMINATE +}; + +int +pdf__shading_pattern(PDF *p, int shading, const char *optlist) +{ + pdc_resopt *results; + pdc_clientdata data; + int gstate = -1; + int retval = -1; + + if (p->compatibility == PDC_1_3) + pdc_error(p->pdc, PDF_E_SHADING13, 0, 0, 0, 0); + + pdf_check_handle(p, shading, pdc_shadinghandle); + + if (optlist && strlen(optlist)) { + pdf_set_clientdata(p, &data); + results = pdc_parse_optionlist(p->pdc, + optlist, pdf_shading_pattern_options, &data, pdc_true); + + (void) pdc_get_optvalues("gstate", results, &gstate, NULL); + + pdc_cleanup_optionlist(p->pdc, results); + } + + if (p->pattern_number == p->pattern_capacity) + pdf_grow_pattern(p); + + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_end_contents_section(p); + + /* Pattern object */ + p->pattern[p->pattern_number].obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); + + /* Shadings don't have a painttype, but this signals to the + * code which writes the pattern usage that no color values + * will be required when setting the pattern color space. + */ + p->pattern[p->pattern_number].painttype = 1; + + pdc_begin_dict(p->out); /* Pattern dict*/ + + pdc_puts(p->out, "/PatternType 2\n"); /* shading pattern */ + + pdc_objref(p->out, "/Shading", p->shadings[shading].obj_id); + + p->shadings[shading].used_on_current_page = pdc_true; + + if (gstate != -1) + pdc_objref(p->out, "/ExtGState", pdf_get_gstate_id(p, gstate)); + + pdc_end_dict(p->out); /* Pattern dict*/ + pdc_end_obj(p->out); /* Pattern object */ + + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_begin_contents_section(p); + + retval = p->pattern_number; + p->pattern_number++; + return retval; +} + +void +pdf__shfill(PDF *p, int shading) +{ + int bias = p->curr_ppt->sh_bias; + + if (p->compatibility == PDC_1_3) + pdc_error(p->pdc, PDF_E_SHADING13, 0, 0, 0, 0); + + pdf_check_handle(p, shading, pdc_shadinghandle); + + pdf_end_text(p); + pdc_printf(p->out, "/Sh%d sh\n", bias + shading); + + p->shadings[shading].used_on_current_page = pdc_true; +} + +static const pdc_defopt pdf_shading_options[] = +{ + {"N", pdc_scalarlist, PDC_OPT_NOZERO, 1, 1, 0, PDC_FLOAT_MAX, NULL}, + {"r0", pdc_scalarlist, PDC_OPT_NONE, 1, 1, 0, PDC_FLOAT_MAX, NULL}, + {"r1", pdc_scalarlist, PDC_OPT_NONE, 1, 1, 0, PDC_FLOAT_MAX, NULL}, + {"extend0", pdc_booleanlist, PDC_OPT_NONE, 0, 1, 0, 1, NULL}, + {"extend1", pdc_booleanlist, PDC_OPT_NONE, 0, 1, 0, 0, NULL}, + {"antialias", pdc_booleanlist, PDC_OPT_NONE, 0, 1, 0, 0, NULL}, + PDC_OPT_TERMINATE +}; + +int +pdf__shading( + PDF *p, + const char *type, + pdc_scalar x_0, pdc_scalar y_0, + pdc_scalar x_1, pdc_scalar y_1, + pdc_scalar c_1, pdc_scalar c_2, pdc_scalar c_3, pdc_scalar c_4, + const char *optlist) +{ + pdf_shadingtype_e shtype = shnone; + pdf_color *color0, color1; + pdf_colorspace *cs; + pdc_resopt *results; + pdc_scalar N = 1.0; + pdc_scalar r_0, r_1; + pdc_bool extend0 = pdc_false, extend1 = pdc_false, antialias = pdc_false; + int retval = -1; + + if (p->compatibility == PDC_1_3) + pdc_error(p->pdc, PDF_E_SHADING13, 0, 0, 0, 0); + + if (!pdc_stricmp(type, "axial")) { + shtype = axial; + + } else if (!pdc_stricmp(type, "radial")) { + shtype = radial; + + } else + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0); + + pdc_check_number(p->pdc, "x_0", x_0); + pdc_check_number(p->pdc, "y_0", y_0); + pdc_check_number(p->pdc, "x_1", x_1); + pdc_check_number(p->pdc, "y_1", y_1); + pdc_check_number(p->pdc, "c_1", c_1); + pdc_check_number(p->pdc, "c_2", c_2); + pdc_check_number(p->pdc, "c_3", c_3); + pdc_check_number(p->pdc, "c_4", c_4); + + color0 = pdf_get_cstate(p, pdf_fill); + + color1.cs = color0->cs; + + cs = &p->colorspaces[color0->cs]; + + switch (cs->type) { + case DeviceGray: + color1.val.gray = c_1; + break; + + case DeviceRGB: + color1.val.rgb.r = c_1; + color1.val.rgb.g = c_2; + color1.val.rgb.b = c_3; + break; + + case DeviceCMYK: + color1.val.cmyk.c = c_1; + color1.val.cmyk.m = c_2; + color1.val.cmyk.y = c_3; + color1.val.cmyk.k = c_4; + break; + + + + default: + pdc_error(p->pdc, PDF_E_INT_BADCS, + pdc_errprintf(p->pdc, "%d", color0->cs), 0, 0, 0); + } + + results = pdc_parse_optionlist(p->pdc, + optlist, pdf_shading_options, NULL, pdc_true); + + (void) pdc_get_optvalues("N", results, &N, NULL); + + (void) pdc_get_optvalues("antialias", results, &antialias,NULL); + + if (shtype == radial) { + if (pdc_get_optvalues("r0", results, &r_0, NULL) != 1) + pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, "r0", 0, 0, 0); + + if (pdc_get_optvalues("r1", results, &r_1, NULL) != 1) + pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, "r1", 0, 0, 0); + } + + if (shtype == axial) { + if (pdc_get_optvalues("r0", results, &r_0, NULL) == 1) + pdc_warning(p->pdc, PDC_E_OPT_IGNORED, "r0", 0, 0, 0); + + if (pdc_get_optvalues("r1", results, &r_1, NULL) == 1) + pdc_warning(p->pdc, PDC_E_OPT_IGNORED, "r1", 0, 0, 0); + } + + if (shtype == radial || shtype == axial) { + pdc_get_optvalues("extend0", results, &extend0, NULL); + pdc_get_optvalues("extend1", results, &extend1, NULL); + } + + pdc_cleanup_optionlist(p->pdc, results); + + if (p->shadings_number == p->shadings_capacity) + pdf_grow_shadings(p); + + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_end_contents_section(p); + + /* Shading object */ + p->shadings[p->shadings_number].obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); + + pdc_begin_dict(p->out); /* Shading dict*/ + + pdc_printf(p->out, "/ShadingType %d\n", (int) shtype); + + pdc_printf(p->out, "/ColorSpace"); + pdf_write_colorspace(p, color1.cs, pdc_false); + pdc_puts(p->out, "\n"); + + if (antialias) + pdc_printf(p->out, "/AntiAlias true\n"); + + switch (shtype) { + case axial: /* Type 2 */ + pdc_printf(p->out, "/Coords[%f %f %f %f]\n", x_0, y_0, x_1, y_1); + if (extend0 || extend1) + pdc_printf(p->out, "/Extend[%s %s]\n", + extend0 ? "true" : "false", extend1 ? "true" : "false"); + pdc_puts(p->out, "/Function"); + pdf_write_function_dict(p, color0, &color1, N); + break; + + case radial: /* Type 3 */ + pdc_printf(p->out, "/Coords[%f %f %f %f %f %f]\n", + x_0, y_0, r_0, x_1, y_1, r_1); + if (extend0 || extend1) + pdc_printf(p->out, "/Extend[%s %s]\n", + extend0 ? "true" : "false", extend1 ? "true" : "false"); + pdc_puts(p->out, "/Function"); + pdf_write_function_dict(p, color0, &color1, N); + break; + + default: + break; + } + + pdc_end_dict(p->out); /* Shading dict */ + pdc_end_obj(p->out); /* Shading object */ + + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_begin_contents_section(p); + + retval = p->shadings_number; + p->shadings_number++; + return retval; +} diff --git a/src/pdflib/pdflib/p_subsett.c b/src/pdflib/pdflib/p_subsett.c new file mode 100644 index 0000000..47eece6 --- /dev/null +++ b/src/pdflib/pdflib/p_subsett.c @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_subsett.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib subsetting routines + * + */ + +#include + +#include "p_intern.h" +#include "p_font.h" + +#include "ft_truetype.h" +#include "pc_md5.h" + diff --git a/src/pdflib/pdflib/p_table.c b/src/pdflib/pdflib/p_table.c new file mode 100644 index 0000000..dc45525 --- /dev/null +++ b/src/pdflib/pdflib/p_table.c @@ -0,0 +1,26 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_table.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib table function + * + */ + +#define P_TABLE_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_defopt.h" +#include "p_font.h" +#include "p_tagged.h" + diff --git a/src/pdflib/pdflib/p_tagged.c b/src/pdflib/pdflib/p_tagged.c new file mode 100644 index 0000000..339b848 --- /dev/null +++ b/src/pdflib/pdflib/p_tagged.c @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_tagged.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib marked content routines + * + */ + +#define P_TAGGED_C + +#include "p_intern.h" +#include "p_layer.h" +#include "p_tagged.h" + + + + +#undef PDF_FEATURE_TAGGED + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/pdflib/pdflib/p_tagged.h b/src/pdflib/pdflib/p_tagged.h new file mode 100644 index 0000000..8dab696 --- /dev/null +++ b/src/pdflib/pdflib/p_tagged.h @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_tagged.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib marked content header + * + */ + +#ifndef P_TAGGED_H +#define P_TAGGED_H + + + +#endif /* P_TAGGED_H */ + diff --git a/src/pdflib/pdflib/p_template.c b/src/pdflib/pdflib/p_template.c new file mode 100644 index 0000000..b6a4f6d --- /dev/null +++ b/src/pdflib/pdflib/p_template.c @@ -0,0 +1,246 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_template.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib template routines + * + */ + +#define P_TEMPLATE_C + +#include "p_intern.h" +#include "p_image.h" + + +int +pdf_embed_image(PDF *p, int im) +{ + pdf_image *image = &p->images[im]; + char optlist[2048], *ol; + pdc_scalar width, height; + int templ; + + width = image->width; + height = fabs(image->height); + + /* create option list */ + optlist[0] = 0; + ol = optlist; + + + if (image->iconname) + sprintf(ol, "iconname {%s}", image->iconname); + + /* create template */ + templ = pdf__begin_template(p, width, height, optlist); + + /* fit image */ + sprintf(optlist, "boxsize {%g %g} fitmethod meet", width, height); + pdf__fit_image(p, im, 0, 0, optlist); + + /* end template */ + pdf__end_template(p); + + return templ; +} + +#define PDF_OPIOPT_FLAG PDC_OPT_UNSUPP + +#define PDF_METADATA_FLAG PDC_OPT_UNSUPP + +#define PDF_LAYER_FLAG PDC_OPT_UNSUPP + +/* definitions of begin template options */ +static const pdc_defopt pdf_begin_template_options[] = +{ + {"topdown", pdc_booleanlist, PDC_OPT_NONE, 1, 1, 0.0, 0.0, NULL}, + + {"OPI-1.3", pdc_stringlist, PDF_OPIOPT_FLAG, 1, 1, 0.0, 32000.0, NULL}, + + {"OPI-2.0", pdc_stringlist, PDF_OPIOPT_FLAG | PDC_OPT_IGNOREIF1, + 1, 1, 0.0, 32000.0, NULL}, + + {"iconname", pdc_stringlist, 0, 1, 1, 1.0, PDF_MAX_NAMESTRING, NULL}, + + {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1, + 0.0, PDC_INT_MAX, NULL}, + + {"layer", pdc_layerhandle, PDF_LAYER_FLAG, 1, 1, + 0.0, 0.0, NULL}, + + PDF_ERRORPOLICY_OPTION + + PDC_OPT_TERMINATE +}; + +/* Start a new template definition. */ +int +pdf__begin_template(PDF *p, pdc_scalar width, pdc_scalar height, + const char *optlist) +{ + pdf_image *image; + pdc_resopt *resopts; + const char *keyword; + pdc_clientdata cdata; + pdc_bool topdown; + char *iconname = NULL; + pdc_bool verbose = pdc_true; + int im = -1; + + pdc_check_number_limits(p->pdc, "width", width, + PDC_FLOAT_PREC, PDC_FLOAT_MAX); + pdc_check_number_limits(p->pdc, "height", height, + PDC_FLOAT_PREC, PDC_FLOAT_MAX); + + for (im = 0; im < p->images_capacity; im++) + if (!p->images[im].in_use) /* found free slot */ + break; + + if (im == p->images_capacity) + pdf_grow_images(p); + + image = &p->images[im]; + image->verbose = pdf_get_errorpolicy(p, NULL, image->verbose); + image->topdown_save = (p->ydirection == -1) ? pdc_true : pdc_false; + topdown = image->topdown_save; + image->in_use = pdc_true; /* mark slot as used */ + + /* parsing optlist */ + pdf_set_clientdata(p, &cdata); + resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_begin_template_options, + &cdata, pdc_true); + + /* save and check options */ + if (optlist && *optlist) + { + image->verbose = pdf_get_errorpolicy(p, resopts, image->verbose); + + keyword = "topdown"; + pdc_get_optvalues(keyword, resopts, &topdown, NULL); + + keyword = "iconname"; + if (pdc_get_optvalues(keyword, resopts, NULL, NULL)) + iconname = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM); + + + + + pdc_cleanup_optionlist(p->pdc, resopts); + } + + verbose = image->verbose; + + + + + + p->ydirection = topdown ? -1 : 1; + pdf_pg_suspend(p); + PDF_SET_STATE(p, pdf_state_template); + + /* form xobject */ + image->no = pdf_new_xobject(p, form_xobject, PDC_NEW_ID); + image->width = width; + image->height = height; + + p->templ = im; /* remember the current template id */ + + pdc_begin_dict(p->out); /* form xobject dict*/ + pdc_puts(p->out, "/Type/XObject\n"); + pdc_puts(p->out, "/Subtype/Form\n"); + + /* contrary to the PDF reference /FormType and /Matrix are required! */ + pdc_printf(p->out, "/FormType 1\n"); + pdc_printf(p->out, "/Matrix[1 0 0 1 0 0]\n"); + + p->res_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Resources", p->res_id); + + pdc_printf(p->out, "/BBox[0 0 %f %f]\n", width, height); + + + + + p->length_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Length", p->length_id); + + if (pdc_get_compresslevel(p->out)) + pdc_puts(p->out, "/Filter/FlateDecode\n"); + + pdc_end_dict(p->out); /* form xobject dict*/ + + pdc_begin_pdfstream(p->out); + + /* top-down y-coordinates */ + pdf_set_topdownsystem(p, height); + + /* set color differing from PDF default */ + pdf_set_default_color(p, pdc_false); + + /* insert icon name */ + if (iconname) + { + pdc_id obj_id = pdf_get_xobject(p, im); + pdf_insert_name(p, iconname, names_ap, obj_id); + } + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Begin template %d]\n", p->templ); + + return im; +} + +/* Finish the template definition. */ +void +pdf__end_template(PDF *p) +{ + pdf_image *image = &p->images[p->templ]; + + /* check whether pdf__save() and pdf__restore() calls are balanced */ + if (p->curr_ppt->sl > 0) + pdc_error(p->pdc, PDF_E_GSTATE_UNMATCHEDSAVE, 0, 0, 0, 0); + + pdf_end_text(p); + pdc_end_pdfstream(p->out); + pdc_end_obj(p->out); /* form xobject */ + + pdc_put_pdfstreamlength(p->out, p->length_id); + + pdc_begin_obj(p->out, p->res_id); /* Resource object */ + pdc_begin_dict(p->out); /* Resource dict */ + + pdf_write_page_fonts(p); /* Font resources */ + + pdf_write_page_colorspaces(p); /* Color space resources */ + + pdf_write_page_pattern(p); /* Pattern resources */ + + pdf_write_xobjects(p); /* XObject resources */ + + pdf_write_page_extgstates(p); /* ExtGState resources */ + + pdc_end_dict(p->out); /* resource dict */ + pdc_end_obj(p->out); /* resource object */ + + pdf_pg_resume(p, -1); + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); + + p->ydirection = image->topdown_save ? -1 : 1; + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[End template %d]\n", p->templ); +} + + diff --git a/src/pdflib/pdflib/p_text.c b/src/pdflib/pdflib/p_text.c new file mode 100644 index 0000000..105df11 --- /dev/null +++ b/src/pdflib/pdflib/p_text.c @@ -0,0 +1,3715 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_text.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib text routines + * + */ + +#define P_TEXT_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_defopt.h" +#include "p_font.h" +#include "p_layer.h" +#include "p_tagged.h" + + +/* --------------------- Text state and options functions ------------------- */ + +struct pdf_tstate_s +{ + pdc_bool glyphinit; /* glyph description initialized */ + pdc_bool hsinit; /* horizontal scaling initialized */ + int mask; /* bit mask for text options */ + int font; /* slot number of the current font */ + int trm; /* text rendering mode */ + pdc_scalar fs; /* font size */ + pdc_scalar ld; /* leading */ + pdc_scalar cs; /* character spacing */ + pdc_scalar ws; /* word spacing */ + pdc_scalar hs; /* horizontal scaling */ + pdc_scalar ia; /* italic angle */ + pdc_bool fb; /* fake bold */ + pdc_scalar rise; /* text rise */ + pdc_scalar ulw; /* underline width */ + pdc_scalar ulp; /* underline position */ + + pdc_bool newpos; /* new text position */ + pdc_scalar currtx; /* x coordinate of current text position */ + pdc_scalar currty; /* y coordinate of current text position */ + pdc_scalar prevtx; /* x coordinate of previous text position */ + pdc_scalar prevty; /* y coordinate of previous text position */ + pdc_scalar linetx; /* x coordinate of text line start position */ + pdc_scalar refptx; /* x and y coordinate of reference position */ + pdc_scalar refpty; /* for moving to next text line start position*/ +}; + +/* Initialize the text state at the beginning of each page */ +void +pdf_init_tstate(PDF *p) +{ + static const char fn[] = "pdf_init_tstate"; + + /* text state */ + pdf_ppt *ppt = p->curr_ppt; + pdf_tstate *ts; + + if (!p->curr_ppt->tstate) + { + p->curr_ppt->tstate = (pdf_tstate *) pdc_malloc(p->pdc, + PDF_MAX_SAVE_LEVEL * sizeof(pdf_tstate), fn); + ppt->currto = (pdf_text_options *) pdc_malloc(p->pdc, + sizeof(pdf_text_options), fn); + } + + ts = &ppt->tstate[ppt->sl]; + + ts->glyphinit = pdc_undef; + ts->hsinit = (p->ydirection == -1) ? pdc_false : pdc_true; + + ts->mask = 0; + ts->font = -1; + ts->trm = 0; + ts->fs = PDC_FLOAT_MIN; + ts->ld = 0; + ts->cs = 0; + ts->ws = 0; + ts->hs = 1; + ts->ia = 0; + ts->fb = pdc_false; + ts->rise = 0; + ts->ulw = PDF_UNDERLINEWIDTH_AUTO; + ts->ulp = PDF_UNDERLINEPOSITION_AUTO; + + ts->newpos = pdc_false; + ts->currtx = 0; + ts->currty = 0; + ts->prevtx = 0; + ts->prevty = 0; + ts->linetx = 0; + ts->refptx = 0; + ts->refpty = 0; + + /* current text options */ + pdf_init_text_options(p, ppt->currto); +} + +void +pdf_cleanup_page_tstate(PDF *p, pdf_ppt *ppt) +{ + if (ppt->tstate != NULL) + { + pdc_free(p->pdc, ppt->tstate); + pdc_free(p->pdc, ppt->currto); + ppt->tstate = NULL; + ppt->currto = NULL; + } +} + +void +pdf_save_tstate(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + int sl = ppt->sl; + + memcpy(&ppt->tstate[sl + 1], &ppt->tstate[sl], sizeof(pdf_tstate)); +} + +void +pdf_restore_currto(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_text_options *currto = ppt->currto; + pdf_tstate *ts = &ppt->tstate[ppt->sl]; + + currto->mask = ts->mask; + currto->font = ts->font; + currto->textrendering = ts->trm; + currto->fontsize = ts->fs; + currto->leading = ts->ld; + currto->charspacing = ts->cs; + currto->wordspacing = ts->ws; + currto->horizscaling = ts->hs; + currto->italicangle = ts->ia; + currto->fakebold = ts->fb; + currto->textrise = ts->rise; + currto->underlinewidth = ts->ulw; + currto->underlineposition = ts->ulp; +} + +void +pdf_set_tstate(PDF *p, pdc_scalar value, pdf_text_optflags tflag) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_tstate *ts = &ppt->tstate[ppt->sl]; + pdf_text_options *currto = ppt->currto; + int ivalue = (int) value; + pdc_scalar prevvalue; + + /* text state parameter values can never be percentages */ + + switch (tflag) + { + case to_font: + pdf_check_handle(p, ivalue, pdc_fonthandle); + prevvalue = ts->font; + ts->font = currto->font = ivalue; + if (prevvalue != -1 && + (p->fonts[(int) prevvalue].metricflags & font_italic) != + (p->fonts[currto->font].metricflags & font_italic)) + currto->mask |= (1 << to_italicangle); + break; + + case to_textrendering: + if (ivalue < 0 || ivalue > PDF_LAST_TRMODE) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "textrendering", pdc_errprintf(p->pdc, "%d", ivalue), + 0, 0); + prevvalue = ts->trm; + ts->trm = currto->textrendering = ivalue; + break; + + case to_fontsize: + pdc_check_number_zero(p->pdc, "fontsize", value); + prevvalue = ts->ld; + ts->ld = currto->leading = value; + if (!PDC_FLOAT_ISNULL(value - prevvalue)) + currto->mask |= (1 << to_leading); + prevvalue = ts->fs; + ts->fs = currto->fontsize = value; + break; + + case to_leading: + prevvalue = ts->ld; + ts->ld = currto->leading = value; + break; + + case to_charspacing: + prevvalue = ts->cs; + ts->cs = currto->charspacing = value; + break; + + case to_wordspacing: + prevvalue = ts->ws; + ts->ws = currto->wordspacing = value; + break; + + case to_underlinewidth: + prevvalue = ts->ulw; + ts->ulw = currto->underlinewidth = value; + break; + + case to_underlineposition: + prevvalue = ts->ulp; + ts->ulp = currto->underlineposition = value; + break; + + case to_horizscaling: + pdc_check_number_zero(p->pdc, "horizscaling", value); + prevvalue = ts->hs; + ts->hs = currto->horizscaling = value; + break; + + case to_italicangle: + pdc_check_number_limits(p->pdc, "italicangle", value, + -90 + PDC_FLOAT_PREC, 90 + PDC_FLOAT_MAX); + prevvalue = ts->ia; + ts->ia = currto->italicangle = value; + break; + + case to_fakebold: + prevvalue = ts->fb; + ts->fb = currto->fakebold = (pdc_bool) ivalue; + return; + + case to_textrise: + prevvalue = ts->rise; + ts->rise = currto->textrise = value; + break; + + + case to_overline: + currto->overline = (pdc_bool) ivalue; + return; + + case to_strikeout: + currto->strikeout = (pdc_bool) ivalue; + return; + + case to_underline: + currto->underline = (pdc_bool) ivalue; + return; + + case to_textformat: + currto->textformat = (pdc_text_format) ivalue; + return; + + case to_charref: + currto->charref = (pdc_bool) ivalue; + return; + + case to_escapesequence: + currto->escapesequence = (pdc_bool) ivalue; + return; + + case to_glyphcheck: + currto->glyphcheck = (pdc_glyphcheck) ivalue; + return; + + case to_glyphwarning: + currto->glyphwarning = (pdc_bool) ivalue; + return; + + default: + return; + } + + if (!PDC_FLOAT_ISNULL(value - prevvalue)) + currto->mask |= (1 << tflag); + ts->mask = currto->mask; +} + +void +pdf__setfont(PDF *p, int font, pdc_scalar fontsize) +{ + pdf_set_tstate(p, (pdc_scalar) font, to_font); + pdf_set_tstate(p, fontsize, to_fontsize); +} + +void +pdf__set_text_pos(PDF *p, pdc_scalar x, pdc_scalar y) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_tstate *ts = &ppt->tstate[ppt->sl]; + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + + ts->newpos = pdc_true; + ts->currtx = x; + ts->currty = y; + ts->prevtx = ts->refptx; + ts->prevty = ts->refpty; + ts->linetx = x; +} + +double +pdf_get_tstate(PDF *p, pdf_text_optflags tflag) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_text_options *currto = ppt->currto; + + switch (tflag) + { + case to_font: + return (double) currto->font; + + case to_textrendering: + return (double) currto->textrendering; + + case to_fontsize: + return (double) currto->fontsize; + + case to_leading: + return (double) currto->leading; + + case to_charspacing: + return (double) currto->charspacing; + + case to_wordspacing: + return (double) currto->wordspacing; + + case to_horizscaling: + return (double) currto->horizscaling; + + case to_italicangle: + return (double) currto->italicangle; + + case to_fakebold: + return (double) currto->fakebold; + + case to_textrise: + return (double) currto->textrise; + + case to_underlinewidth: + return (double) currto->underlinewidth; + + case to_underlineposition: + return (double) currto->underlineposition; + + + case to_overline: + return (double) currto->overline; + + case to_strikeout: + return (double) currto->strikeout; + + case to_underline: + return (double) currto->underline; + + case to_textx: + return (double) ppt->tstate[ppt->sl].currtx; + + case to_texty: + return (double) ppt->tstate[ppt->sl].currty; + + default: + break; + } + + return 0; +} + +int +pdf_get_font(PDF *p) +{ + if (p->curr_ppt) + return (int) pdf_get_tstate(p, to_font); + return -1; +} + +void +pdf_init_text_options(PDF *p, pdf_text_options *to) +{ + to->mask = 0; + to->pcmask = 0; + to->font = -1; + to->fontsize = PDC_FLOAT_MIN; + to->fontsize_pc = 0; + to->fontsize_st = (int) text_fontsize; + to->fontset = 0; + to->leading = 0; + to->leading_pc = 0; + to->textrendering = 0; + to->charspacing = 0; + to->charspacing_pc = 0; + to->horizscaling = 1; + to->italicangle = 0; + to->fakebold = pdc_false; + to->textrise = 0; + to->textrise_pc = 0; + to->wordspacing = 0; + to->wordspacing_pc = 0; + to->underlinewidth = PDF_UNDERLINEWIDTH_AUTO; + to->underlineposition = PDF_UNDERLINEPOSITION_AUTO; + to->overline = pdc_false; + to->strikeout = pdc_false; + to->underline = pdc_false; + to->text = NULL; + to->textlen = 0; + to->textformat = p->textformat; + to->charref = p->pdc->charref; + to->escapesequence = p->pdc->escapesequ; + to->glyphcheck = p->glyphcheck; + to->glyphwarning = p->debug[(int) 'g']; + to->glyphwarning = pdf_get_errorpolicy(p, NULL, to->glyphwarning); + pdf_init_coloropt(p, &to->fillcolor); + pdf_init_coloropt(p, &to->strokecolor); + to->strokewidth = PDF_UNDERLINEWIDTH_AUTO; + to->dasharray[0] = 0; + to->dasharray[1] = 0; + to->xadvancelist = NULL; + to->nglyphs = 0; + to->link = NULL; +} + +static pdf_text_optflags pdf_toptflags[] = +{ + to_font, to_fontsize, to_textrendering, to_charspacing, + to_horizscaling, to_italicangle, to_wordspacing, to_textrise +}; + +void +pdf_set_text_options(PDF *p, pdf_text_options *to) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_text_options *currto = p->curr_ppt->currto; + pdf_tstate *ts = &ppt->tstate[ppt->sl]; + pdf_text_optflags tflag; + int i, n; + + /* we synchronize both text state and text options */ + + n = sizeof(pdf_toptflags) / sizeof(pdf_text_optflags); + for (i = 0; i < n; i++) + { + tflag = pdf_toptflags[i]; + if (to->mask & (1 << tflag)) + { + switch (tflag) + { + case to_font: + if (!(currto->mask & (1 << tflag)) && + to->font == currto->font) + break; + ts->font = currto->font = to->font; + continue; + + case to_fontsize: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->fontsize - currto->fontsize)) + break; + ts->fs = currto->fontsize = to->fontsize; + continue; + + case to_textrendering: + if (!(currto->mask & (1 << tflag)) && + to->textrendering == currto->textrendering) + break; + ts->trm = currto->textrendering = to->textrendering; + continue; + + /* to->leading is never used */ + + case to_charspacing: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->charspacing - currto->charspacing)) + break; + ts->cs = currto->charspacing = to->charspacing; + continue; + + case to_horizscaling: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->horizscaling - currto->horizscaling)) + break; + ts->hs = currto->horizscaling = to->horizscaling; + continue; + + case to_italicangle: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->italicangle - currto->italicangle)) + break; + ts->ia = currto->italicangle = to->italicangle; + continue; + + case to_fakebold: + ts->fb = currto->fakebold = to->fakebold; + continue; + + case to_wordspacing: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->wordspacing - currto->wordspacing)) + break; + ts->ws = currto->wordspacing = to->wordspacing; + continue; + + case to_textrise: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->textrise - currto->textrise)) + break; + ts->rise = currto->textrise = to->textrise; + continue; + + case to_underlinewidth: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->underlinewidth - + currto->underlinewidth)) + break; + ts->ulw = currto->underlinewidth = to->underlinewidth; + continue; + + case to_underlineposition: + if (!(currto->mask & (1 << tflag)) && + PDC_FLOAT_ISNULL(to->underlineposition - + currto->underlineposition)) + break; + ts->ulp = currto->underlineposition = to->underlineposition; + continue; + + default: + continue; + } + + to->mask &= ~(1 << tflag); + } + } + + ts->mask = currto->mask = to->mask; +} + +int +pdf_get_fontsize_option(PDF *p, int font, pdc_resopt *resopts, + pdc_scalar *fontsize) +{ + pdc_scalar fs[2], fm ; + int ns; + + /* *fontsize is initialized from outside */ + + fs[0] = 0; /* see "auto" */ + fs[1] = 0; + ns = pdc_get_optvalues("fontsize", resopts, (pdc_scalar *) fs, NULL); + if (ns == 1) + { + *fontsize = fs[0]; + } + else if (ns == 2) + { + int kind = (int) fs[0]; + + pdf_check_handle(p, font, pdc_fonthandle); + + switch(kind) + { + case text_xheight: + fm = (pdc_scalar) p->fonts[font].ft.m.xHeight; + break; + + case text_capheight: + fm = (pdc_scalar) p->fonts[font].ft.m.capHeight; + break; + + case text_ascender: + fm = (pdc_scalar) p->fonts[font].ft.m.ascender; + break; + + default: + fm = 1000.0; + break; + } + + *fontsize = fs[1] * 1000.0 / fm; + } + + return ns; +} + +pdc_bool +pdf_calculate_text_options(PDF *p, pdf_text_options *to, pdc_bool force, + pdc_scalar fontscale, pdc_scalar minfontsize, + pdc_scalar fontsizeref) +{ + pdc_bool kminfs = pdc_false; + + if (to->mask & (1 << to_fontsize) || force) + { + pdc_scalar fontsize; + + if (fontsizeref == 0) + fontsizeref = to->fontsize; + + if (to->pcmask & (1 << to_fontsize)) + fontsize = to->fontsize_pc * fontsizeref; + else + fontsize = fontscale * to->fontsize; + + if (to->fontsize_st != (int) text_fontsize) + { + pdf_font *currfont = &p->fonts[to->font]; + pdc_scalar fm; + + switch(to->fontsize_st) + { + case text_xheight: + fm = (pdc_scalar) currfont->ft.m.xHeight; + break; + + case text_capheight: + fm = (pdc_scalar) currfont->ft.m.capHeight; + break; + + case text_ascender: + fm = (pdc_scalar) currfont->ft.m.ascender; + break; + + default: + fm = 1000.0; + break; + } + + fontsize *= 1000.0 / fm; + } + + if (fontscale < 1.0 && fabs(fontsize) < minfontsize) + { + if (fontsize > 0) + fontsize = minfontsize; + else + fontsize = -minfontsize; + kminfs = pdc_true; + } + to->fontsize = fontsize; + + /* we reset relative fontsize specifications */ + if (to->mask & (1L << to_fontsize)) + { + to->pcmask &= ~(1 << to_fontsize); + to->fontsize_st = (int) text_fontsize; + } + } + + if ((to->mask & (1 << to_charspacing) || force) && + (to->pcmask & (1 << to_charspacing))) + { + to->charspacing = to->charspacing_pc * to->fontsize; + } + + if ((to->mask & (1 << to_wordspacing) || force) && + (to->pcmask & (1 << to_wordspacing))) + { + to->wordspacing = to->wordspacing_pc * to->fontsize; + } + + if ((to->mask & (1 << to_textrise) || force) && + (to->pcmask & (1 << to_textrise))) + { + to->textrise = to->textrise_pc * to->fontsize; + } + + /* maybe used in a future version */ + if ((to->mask & (1 << to_leading) || force) && + (to->pcmask & (1 << to_leading))) + { + to->leading = to->leading_pc * to->fontsize; + } + + return kminfs; +} + +void +pdf_get_text_options(PDF *p, pdf_text_options *to, pdc_resopt *resopts) +{ + char **strlist; + int i, inum; + pdc_scalar fs[2]; + + if (pdc_get_optvalues("glyphwarning", resopts, &to->glyphwarning, NULL)) + to->mask |= (1L << to_glyphwarning); + to->glyphwarning = pdf_get_errorpolicy(p, resopts, to->glyphwarning); + + if (pdc_get_optvalues("font", resopts, &to->font, NULL)) + { + pdf_check_handle(p, to->font, pdc_fonthandle); + to->mask |= (1L << to_font); + to->fontset |= (1L << to_font); + } + + fs[0] = 0; /* see "auto" */ + fs[1] = 0; + inum = pdc_get_optvalues("fontsize", resopts, (pdc_scalar *) fs, NULL); + if (inum) + { + i = inum - 1; + to->fontsize = fs[i]; + if (inum == 2) + to->fontsize_st = (int) fs[0]; + else + to->fontsize_st = (int) text_fontsize; + to->mask |= (1L << to_fontsize); + to->mask |= (1L << to_fontsize_st); + + if (pdc_is_lastopt_percent(resopts, i)) + { + to->pcmask |= (1 << to_fontsize); + to->fontsize_pc = to->fontsize; + } + else + to->pcmask &= ~(1 << to_fontsize); + + to->fontset |= (1L << to_fontsize); + } + + if (pdc_get_optvalues("charref", resopts, &to->charref, NULL)) + to->mask |= (1L << to_charref); + + if (pdc_get_optvalues("escapesequence", resopts, &to->escapesequence, NULL)) + to->mask |= (1L << to_escapesequence); + + if (pdc_get_optvalues("glyphcheck", resopts, &inum, NULL)) + { + to->glyphcheck = (pdc_glyphcheck) inum; + to->mask |= (1L << to_glyphcheck); + } + + if (pdc_get_optvalues("charspacing", resopts, &to->charspacing, NULL)) + { + if (pdc_is_lastopt_percent(resopts, 0)) + { + to->pcmask |= (1 << to_charspacing); + to->charspacing_pc = to->charspacing; + } + else + to->pcmask &= ~(1 << to_charspacing); + to->mask |= (1L << to_charspacing); + } + + if (pdc_get_optvalues("horizscaling", resopts, &to->horizscaling, NULL)) + { + if (!pdc_is_lastopt_percent(resopts, 0)) + to->horizscaling /= 100.0; + to->mask |= (1L << to_horizscaling); + } + + if (pdc_get_optvalues("italicangle", resopts, &to->italicangle, NULL)) + to->mask |= (1L << to_italicangle); + + if (pdc_get_optvalues("fakebold", resopts, &to->fakebold, NULL)) + to->mask |= (1L << to_fakebold); + + + if (pdc_get_optvalues("overline", resopts, &to->overline, NULL)) + to->mask |= (1L << to_overline); + + if (pdc_get_optvalues("strikeout", resopts, &to->strikeout, NULL)) + to->mask |= (1L << to_strikeout); + + if (pdc_get_optvalues("textformat", resopts, &inum, NULL)) + { + to->textformat = (pdc_text_format) inum; + to->mask |= (1L << to_textformat); + pdf_check_textformat(p, to->textformat); + } + + if (pdc_get_optvalues("textrendering", resopts, &to->textrendering, NULL)) + to->mask |= (1L << to_textrendering); + + if (pdc_get_optvalues("textrise", resopts, &to->textrise, NULL)) + { + if (pdc_is_lastopt_percent(resopts, 0)) + { + to->pcmask |= (1 << to_textrise); + to->textrise_pc = to->textrise; + } + else + to->pcmask &= ~(1 << to_textrise); + to->mask |= (1L << to_textrise); + } + + if (pdc_get_optvalues("underline", resopts, &to->underline, NULL)) + to->mask |= (1L << to_underline); + + if (pdc_get_optvalues("wordspacing", resopts, &to->wordspacing, NULL)) + { + if (pdc_is_lastopt_percent(resopts, 0)) + { + to->pcmask |= (1 << to_wordspacing); + to->wordspacing_pc = to->wordspacing; + } + else + to->pcmask &= ~(1 << to_wordspacing); + to->mask |= (1L << to_wordspacing); + } + + if (pdc_get_optvalues("underlinewidth", resopts, &to->underlinewidth, NULL)) + { + if (pdc_is_lastopt_percent(resopts, 0)) + { + to->pcmask |= (1 << to_underlinewidth); + } + else + to->pcmask &= ~(1 << to_underlinewidth); + to->mask |= (1L << to_underlinewidth); + } + + if (pdc_get_optvalues("underlineposition", resopts, + &to->underlineposition, NULL)) + { + if (pdc_is_lastopt_percent(resopts, 0)) + { + to->pcmask |= (1 << to_underlineposition); + } + else + to->pcmask &= ~(1 << to_underlineposition); + to->mask |= (1L << to_underlineposition); + } + + inum = pdc_get_optvalues("fillcolor", resopts, NULL, &strlist); + if (inum) + { + pdf_parse_coloropt(p, "fillcolor", strlist, inum, (int) color_max, + &to->fillcolor); + to->mask |= (1L << to_fillcolor); + } + + inum = pdc_get_optvalues("strokecolor", resopts, NULL, &strlist); + if (inum) + { + pdf_parse_coloropt(p, "strokecolor", strlist, inum, (int) color_max, + &to->strokecolor); + to->mask |= (1L << to_strokecolor); + } + + if (pdc_get_optvalues("strokewidth", resopts, &to->strokewidth, NULL)) + { + if (pdc_is_lastopt_percent(resopts, 0)) + { + to->pcmask |= (1 << to_strokewidth); + } + else + to->pcmask &= ~(1 << to_strokewidth); + to->mask |= (1L << to_strokewidth); + } + + inum = pdc_get_optvalues("dasharray", resopts, to->dasharray, NULL); + if (inum) + { + if (inum == 1) + to->dasharray[1] = to->dasharray[0]; + to->mask |= (1L << to_dasharray); + } + + inum = pdc_get_optvalues("xadvancelist", resopts, NULL, &strlist); + if (inum) + { + to->xadvancelist = (pdc_scalar *) strlist; + to->nglyphs = inum; + } + + /* + * deprecated + */ + if (pdc_get_optvalues("weblink", resopts, NULL, &strlist)) + { + to->link = strlist[0]; + to->linktype = "URI"; + } + else if (pdc_get_optvalues("locallink", resopts, NULL, &strlist)) + { + to->link = strlist[0]; + to->linktype = "GoTo"; + } + else if (pdc_get_optvalues("pdflink", resopts, NULL, &strlist)) + { + to->link = strlist[0]; + to->linktype = "GoToR"; + } +} + +/* ------------------------ Text object functions -------------------------- */ + +static void +pdf_begin_text(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_tstate *ts = &ppt->tstate[ppt->sl]; + pdf_text_options *currto = ppt->currto; + pdf_font *currfont = NULL; + + if (currto->font > -1) + currfont = &p->fonts[currto->font]; + + /* end text object if italicangle changed */ + if (currto->mask & (1L << to_italicangle)) + pdf_end_text(p); + + /* begin text object */ + if (!p->in_text) + { + p->in_text = pdc_true; + pdc_puts(p->out, "BT\n"); + } + + if (PDF_FORCE_OUTPUT() && ts->glyphinit == pdc_undef) + ts->glyphinit = pdc_false; + + if (currfont && + ((currto->mask & (1L << to_font)) || + (currto->mask & (1L << to_fontsize)) || !ts->glyphinit)) + { + pdc_printf(p->out, "/F%d %f Tf\n", + ppt->fn_bias + currto->font, p->ydirection * currto->fontsize); + + currfont->used_in_current_doc = pdc_true; + currfont->used_on_current_page = pdc_true; + } + + if (currto->mask & (1L << to_textrendering) || !ts->glyphinit) + pdc_printf(p->out, "%d Tr\n", currto->textrendering); + + if (currto->mask & (1L << to_leading) || !ts->glyphinit) + pdc_printf(p->out, "%f TL\n", p->ydirection * currto->leading); + + if (currto->mask & (1L << to_charspacing) || !ts->glyphinit) + pdc_printf(p->out, "%f Tc\n", p->ydirection * currto->charspacing); + + if (!ts->hsinit || currto->mask & (1L << to_horizscaling) || !ts->glyphinit) + pdc_printf(p->out, "%f Tz\n", + 100 * p->ydirection * currto->horizscaling); + + if (currto->mask & (1L << to_textrise) || !ts->glyphinit) + pdc_printf(p->out, "%f Ts\n", p->ydirection * currto->textrise); + + /* initialize */ + if (!ts->glyphinit) + ts->glyphinit = pdc_true; + ts->hsinit = pdc_true; + ts->mask = currto->mask = 0; +} + +void +pdf_end_text(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_tstate *ts = &ppt->tstate[ppt->sl]; + + if (p->in_text) + { + p->in_text = pdc_false; + pdc_puts(p->out, "ET\n"); + + ts->newpos = pdc_false; + ts->prevtx = 0; + ts->prevty = 0; + ts->refptx = 0; + ts->refpty = 0; + } +} + +void +pdf_reset_tstate(PDF *p) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_tstate *ts = &ppt->tstate[ppt->sl]; + + pdf_set_tstate(p, 0, to_textrendering); + pdf_set_tstate(p, 0, to_leading); + pdf_set_tstate(p, 0, to_charspacing); + pdf_set_tstate(p, 0, to_wordspacing); + pdf_set_tstate(p, 1, to_horizscaling); + pdf_set_tstate(p, 0, to_italicangle); + pdf_set_tstate(p, 0, to_fakebold); + pdf_set_tstate(p, 0, to_textrise); + pdf_set_tstate(p, PDF_UNDERLINEWIDTH_AUTO, to_underlinewidth); + pdf_set_tstate(p, PDF_UNDERLINEPOSITION_AUTO, to_underlineposition); + + ts->hsinit = (p->ydirection == -1) ? pdc_false : pdc_true; + if (ts->mask || !ts->hsinit) + { + pdc_scalar ydirection = p->ydirection; + p->ydirection = 1; + pdf_begin_text(p); + pdf_end_text(p); + p->ydirection = ydirection; + } +} + + +/* ------------------- Text string checking function ---------------------- */ + +typedef struct pdf_ligat_s pdf_ligat; + +struct pdf_ligat_s +{ + pdf_ligat *next; + int icp; /* text position */ + int nb; /* number of parts */ + pdc_byte culist[2 * PDC_MAX_UVLIST]; + /* ligature parts */ +}; + +static pdf_ligat * +pdf_register_ligat(PDF *p, pdf_ligat *ligatlist, int icp, int nv, + pdc_ushort *culist, int charlen) +{ + static const char fn[] = "pdf_hook_ligat"; + int i; + + pdf_ligat *ligat = + (pdf_ligat *) pdc_malloc_tmp(p->pdc, sizeof(pdf_ligat), fn, NULL, NULL); + + if (ligatlist == NULL) + { + ligatlist = ligat; + } + else + { + pdf_ligat *next = ligatlist; + + while (next->next != NULL) + next = next->next; + next->next = ligat; + } + + ligat->next = NULL; + ligat->icp = charlen * icp; + nv--; + ligat->nb = charlen * nv; + + if (charlen == 1) + { + for (i = 0; i < nv; i++) + ligat->culist[i] = (pdc_byte) culist[i+1]; + } + else + { + memcpy(ligat->culist, &culist[1], (size_t) ligat->nb); + } + return ligatlist; +} + +static void +pdf_cleanup_ligat(PDF *p, pdf_ligat *list) +{ + pdf_ligat *next; + + while (list != NULL) + { + next = list->next; + pdc_free_tmp(p->pdc, list); + list = next; + } +} + + +#define PDF_MAX_GLYPHCHECKS 8 + +int +pdf_get_approximate_uvlist(PDF *p, pdf_font *currfont, pdc_encodingvector *ev, + int usv, pdc_bool replace, + pdc_ushort *uvlist, pdc_ushort *cglist) +{ + int cg = 0, nv = 1; + + (void) p; + (void) ev; + (void) usv; + + + if (cg <= 0) + { + if (replace) + { + cglist[0] = (pdc_ushort) currfont->replacementcode; + uvlist[0] = (pdc_ushort) currfont->replacementchar; + } + else + { + cglist[0] = 0; + uvlist[0] = 0; + } + nv = 1; + } + + return nv; +} + +static void +pdf_logg_glyph_replacement(PDF *p, int ic, int code, + pdc_encoding enc, int charlen, + pdc_ushort *uvlist, pdc_ushort *cglist, int nv) +{ + const char *glyphname; + int i; + + pdc_logg(p->pdc, "\t\tat text position %d: ", ic); + + if (charlen == 1) + pdc_logg(p->pdc, "code x%02X ", code); + else + pdc_logg(p->pdc, "U+%04X ", code); + + pdc_logg(p->pdc, "was replaced by: "); + if (nv > 1) + pdc_logg(p->pdc, "\n"); + + for (i = 0; i < nv; i++) + { + if (nv > 1) + pdc_logg(p->pdc, "\t\t\t"); + + if (charlen == 1) + pdc_logg(p->pdc, "code x%02X ", cglist[i]); + else + pdc_logg(p->pdc, "U+%04X ", uvlist[i]); + + if (enc >= 0) + { + if (charlen == 1) + pdc_logg(p->pdc, "U+%04X ", uvlist[i]); + else + pdc_logg(p->pdc, "code x%02X ", cglist[i]); + } + + glyphname = pdc_unicode2glyphname(p->pdc, uvlist[i]); + if (glyphname && strlen(glyphname)) + pdc_logg(p->pdc, "\"%s\"", glyphname); + + pdc_logg(p->pdc, "\n"); + } +} + +void +pdf_get_input_textformat(pdf_font *currfont, + pdc_text_format *intextformat, int *convflags) +{ + /* input text format */ + if (currfont->unibyte) + { + /* encoding=unicode, but 8-bit encoding ev is available */ + *convflags |= PDC_CONV_FORCEUTF16; + } + else if (currfont->codesize <= 1) + { + /* we must force bytes[2] source input format + * for 8-bit encodings because of "pass through mode". + */ + if (*intextformat == pdc_auto) + *intextformat = pdc_bytes; + else if (*intextformat == pdc_auto2) + *intextformat = pdc_bytes2; + } +} + +/* Converts and checks input text string. + * + * The function returns a pointer to an allocated temporary memory + * (pdc_malloc_tmp, pdc_free_tmp) containing the converted string + * if flag PDF_USE_TMPALLOC is set. + * + * If return value is -1 an error was occurred, otherwise >= 0. + * glyphcheck = none: the number of unmapped glyphs will be returned. + * + */ + +int +pdf_check_textstring(PDF *p, const char *text, int len, int flags, + pdf_text_options *to, pdc_byte **outtext_p, int *outlen, + int *outcharlen, pdc_bool verbose) +{ + static const char fn[] = "pdf_check_textstring"; + + pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_text); + pdc_bool logg2 = pdc_false; + pdf_font *currfont = &p->fonts[to->font]; + pdc_encoding enc = currfont->ft.enc; + pdc_encodingvector *ev = pdc_get_encoding_vector(p->pdc, enc); + pdc_encodingvector *inev = NULL; + pdc_encodingvector *outev = NULL; + + pdc_text_format intextformat = to->textformat; + pdc_text_format outtextformat = pdc_utf16; + + int charlen = 1, newcharlen = 1; + int convflags = PDC_CONV_NOBOM; + int unmapgids = 0; + + pdf_ligat *ligat, *ligatlist = NULL; + pdc_byte *intext = (pdc_byte *) text, *outtext = NULL; + int newlen = -1, maxlen, replchar; + + if (logg1) + { + logg2 = pdc_logg_is_enabled(p->pdc, 2, trc_text); + + if (logg2) + pdc_logg_hexdump(p->pdc, "input text", "\t\t", (char *) text, len); + else + pdc_logg(p->pdc, + "\tText will be checked and converted: \"%T\"\n", text, len); + + if (logg2) + { + pdc_logg(p->pdc, + "\t\tfont: \"%s\"\n" + "\t\tencoding: \"%s\"\n" + "\t\ttextformat: %s\n" + "\t\tcharref: %s\n" + "\t\tescapesequence: %s\n" + "\t\tglyphwarning: %s\n" + "\t\tglyphcheck: %s\n", + currfont->ft.name, + pdf_get_encoding_name(p, enc, currfont), + pdc_get_keyword(intextformat, pdf_textformat_keylist), + PDC_BOOLSTR(to->charref), + PDC_BOOLSTR(to->escapesequence), + PDC_BOOLSTR(to->glyphwarning), + pdc_get_keyword(to->glyphcheck, pdf_glyphcheck_keylist)); + + convflags |= PDC_CONV_LOGGING; + } + } + + /* text is passed through for CID fonts with non Unicode CMap */ + if (currfont->passthrough) + { + if (logg2) + pdc_logg(p->pdc, "\t\ttext is passed through as is\n"); + + outtext = (pdc_byte *) ((flags & PDF_USE_TMPALLOC) ? + pdc_malloc_tmp(p->pdc, (size_t) len + 2, fn, NULL, NULL) : + pdc_malloc(p->pdc, (size_t) len + 2, fn)); + memcpy(outtext, text, (size_t) len); + outtext[len] = 0; + outtext[len + 1] = 0; + *outlen = len; + + outtextformat = pdc_bytes; + } + else + { + + if (flags & PDF_FORCE_NEWALLOC) + convflags |= PDC_CONV_NEWALLOC; + + if (flags & PDF_USE_TMPALLOC) + convflags |= PDC_CONV_TMPALLOC; + + if (to->glyphcheck == (int) text_replace) + { + replchar = currfont->replacementchar; + } + else + { + replchar = (int) to->glyphcheck; + if (to->glyphcheck == text_error) + { + convflags |= PDC_CONV_ENCERROR; + if (flags & PDF_KEEP_CONTROL) + convflags |= PDC_CONV_KEEPLBCHAR; + } + } + + if (flags & PDF_KEEP_UNICODE || to->glyphcheck != text_nocheck) + inev = ev; + + + /* "Pass through mode" for 8-bit text. + * The encoding vector must be specified, because + * the text could emerge as a Unicode text due to a BOM. + */ + if ((enc >= 0 && inev == NULL) || + (enc == pdc_builtin && !(flags & PDF_KEEP_UNICODE))) + { + inev = ev; + outev = ev; + outtextformat = pdc_bytes; + } + + /* input text format */ + pdf_get_input_textformat(currfont, &intextformat, &convflags); + + /* convert to 8-bit or UTF-16 text string */ + if (pdc_convert_textstring(p->pdc, intextformat, currfont->codepage, + inev, + NULL, 0, + replchar, intext, len, + &outtextformat, outev, &outtext, outlen, + convflags, pdc_false)) + { + if (newlen > -1) + pdc_free_tmp(p->pdc, intext); + goto PDF_CHECK_TEXT_ERROR; + } + } + + if (newlen > -1) + pdc_free_tmp(p->pdc, intext); + + /* check text string */ + if (outtext != NULL && *outlen) + { + pdc_ushort *usouttext = (pdc_ushort *) outtext; + pdc_ushort uvlist[PDC_MAX_UVLIST]; + pdc_ushort cglist[PDC_MAX_UVLIST]; + pdc_bool kcheck = pdc_true; + int i = 0, nv = 1, icp = 0, usvp; + int code, gid, usv, ic; + + (void) i; + + /* storage length of a character */ + if (outtextformat == pdc_utf16) + { + charlen = 2; + newcharlen = 2; + } + + /* maximal text string length - found out emprirically! */ + maxlen = (currfont->codesize == 1) ? PDF_MAXARRAYSIZE : PDF_MAXDICTSIZE; + if (!(flags & PDF_KEEP_TEXTLEN) && *outlen > maxlen) + { + pdc_set_errmsg(p->pdc, PDF_E_TEXT_TOOLONG, + pdc_errprintf(p->pdc, "%d", maxlen), 0, 0, 0); + goto PDF_CHECK_TEXT_ERROR; + } + + len = *outlen / charlen; + switch (enc) + { + + + /* + * builtin + */ + case pdc_builtin: + if (charlen == 1 || !(flags & PDF_KEEP_UNICODE)) + newcharlen = 1; + for (ic = 0; ic < len; ic++) + { + if (charlen == 1) + code = (int) outtext[ic]; + else + code = (int) usouttext[ic]; + + if (code) + { + gid = fnt_get_glyphid(code, &currfont->ft); + + /* glyph id for code value not available */ + if (gid <= 0) + { + unmapgids++; + if (to->glyphcheck == text_error) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_CODENOTFOUND1, + pdc_errprintf(p->pdc, "x%02X", code), + currfont->ft.name, 0, 0); + goto PDF_CHECK_TEXT_ERROR; + } + else if (to->glyphcheck == text_replace) + { + pdc_warning(p->pdc, PDF_E_FONT_CODENOTFOUNDREP1, + pdc_errprintf(p->pdc, "x%02X", code), + currfont->ft.name, 0, 0); + code = currfont->replacementcode; + } + } + } + + if (newcharlen == 1) + outtext[icp] = (pdc_byte) code; + else + usouttext[icp] = (pdc_ushort) code; + icp++; + } + + break; + + + /* + * cid + */ + case pdc_cid: + /* + * pass through. check and temporary conversion in + * pdf_calculate_textsize(), because we want to keep native code. + */ + break; + + + /* + * encoding vector + */ + default: + if (charlen == 1 || !(flags & PDF_KEEP_UNICODE)) + newcharlen = 1; + for (ic = 0; ic < len; ic++) + { + if (charlen == 1) + { + code = (int) outtext[ic]; + usv = ev->codes[code]; + kcheck = code > 0; + } + else + { + usv = (int) usouttext[ic]; + code = pdc_get_encoding_bytecode(p->pdc, ev, + (pdc_ushort) usv); + if (code < 0) + code = 0; + kcheck = usv > 0; + } + + if ((flags & PDF_KEEP_CONTROL) && + pdc_is_linebreaking_relchar((pdc_ushort) usv)) + { + kcheck = pdc_false; + } + + /* glyph check */ + if (kcheck) + { + /* encoding vector hasn't defined [Uni]code */ + if (usv <= 0 || code <= 0) + { + unmapgids++; + if (to->glyphcheck == text_error) + { + if (usv <= 0) + { + pdc_set_errmsg(p->pdc, PDC_E_ENC_NOTDEF_CODE, + pdc_errprintf(p->pdc, "x%02X", code), + ev->apiname, 0, 0); + goto PDF_CHECK_TEXT_ERROR; + } + else if (code <= 0) + { + pdc_set_errmsg(p->pdc, PDC_E_ENC_NOTDEF_UNICODE, + pdc_errprintf(p->pdc, "%04X", usv), + ev->apiname, 0, 0); + goto PDF_CHECK_TEXT_ERROR; + } + } + else if (to->glyphcheck == text_replace) + { + usvp = (usv <= 0) ? code : usv; + nv = pdf_get_approximate_uvlist(p, currfont, ev, + usv, pdc_true, + uvlist, cglist); + usv = (int) uvlist[0]; + code = (int) cglist[0]; + + if (logg2) + { + pdf_logg_glyph_replacement(p, ic, usvp, + enc, charlen, uvlist, cglist, nv); + } + } + } + else + { + gid = fnt_get_glyphid(code, &currfont->ft); + + /* glyph id for code not available */ + if (gid <= 0 && currfont->gid0code != code) + { + unmapgids++; + if (to->glyphcheck == text_error) + { + pdc_set_errmsg(p->pdc, PDF_E_FONT_CODENOTFOUND2, + pdc_errprintf(p->pdc, "x%02X", code), + pdc_errprintf(p->pdc, "%04X", usv), + currfont->ft.name, 0); + goto PDF_CHECK_TEXT_ERROR; + } + else if (to->glyphcheck == text_replace) + { + pdc_warning(p->pdc, PDF_E_FONT_CODENOTFOUNDREP2, + pdc_errprintf(p->pdc, "x%02X", code), + pdc_errprintf(p->pdc, "%04X", usv), + currfont->ft.name, 0); + + usvp = (usv <= 0) ? code : usv; + nv = pdf_get_approximate_uvlist(p, currfont, ev, + usv, pdc_true, + uvlist, cglist); + usv = (int) uvlist[0]; + code = (int) cglist[0]; + + if (logg2) + { + pdf_logg_glyph_replacement(p, ic, usvp, + enc, charlen, uvlist, cglist, nv); + } + } + } + } + } + + if (newcharlen == 1) + { + outtext[icp] = (pdc_byte) code; + } + else + { + usouttext[icp] = (pdc_ushort) usv; + } + if (nv > 1) + { + if (newcharlen == 1) + ligatlist = pdf_register_ligat(p, ligatlist, icp, nv, + cglist, newcharlen); + else + ligatlist = pdf_register_ligat(p, ligatlist, + icp, nv, uvlist, newcharlen); + nv = 1; + } + icp++; + } + + break; + } + + if (icp) + { + /* calculate complete text length */ + len = newcharlen * icp; + if (ligatlist != NULL) + { + ligat = ligatlist; + while (ligat != NULL) + { + len += ligat->nb; + ligat = ligat->next; + } + } + + if (len != *outlen) + { + *outlen = len; + if (flags & PDF_USE_TMPALLOC) + outtext = (pdc_byte *) pdc_realloc_tmp(p->pdc, outtext, + (size_t) (*outlen + newcharlen), fn); + else + outtext = (pdc_byte *) pdc_realloc(p->pdc, outtext, + (size_t) (*outlen + newcharlen), fn); + outtext[*outlen] = 0; + if (newcharlen == 2) + outtext[*outlen + 1] = 0; + } + + /* insert ligature parts */ + if (ligatlist != NULL) + { + int nbrest, nbgap, nbmove = 0; + + len = newcharlen * icp; + ligat = ligatlist; + while (ligat != NULL) + { + nbgap = ligat->nb; + icp = ligat->icp + nbmove; + nbrest = len - icp; + icp += newcharlen; + ic = icp + nbgap; + + memmove(&outtext[ic], &outtext[icp], (size_t) nbrest); + memcpy(&outtext[icp], ligat->culist, (size_t) nbgap); + + nbmove += nbgap; + len += nbgap; + + ligat = ligat->next; + } + + pdf_cleanup_ligat(p, ligatlist); + } + } + } + + *outtext_p = outtext; + *outcharlen = newcharlen; + + if (logg1) + { + if (logg2) + pdc_logg_hexdump(p->pdc, "converted text", "\t\t", + (char *) outtext, *outlen); + else + pdc_logg(p->pdc, + "\tChecked and converted text of length %d: \"%T\"\n", + *outlen, outtext, *outlen); + } + return unmapgids; + + PDF_CHECK_TEXT_ERROR: + + if (outtext != NULL) + { + if (flags & PDF_USE_TMPALLOC) + pdc_free_tmp(p->pdc, outtext); + else + pdc_free(p->pdc, outtext); + } + + pdf_cleanup_ligat(p, ligatlist); + + if (verbose) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + + *outtext_p = NULL; + *outlen = 0; + + return -1; +} + + +/* ------------------------ Text width functions ------------------------ */ + +/* Calculates the geometrical width and height of input text string + * depending on + * + * to->font, to->fontsize, to->kerning, + * to->charspacing, to->horizscaling, to->wordspacing, + * to->xadvancelist + * + * In the case of vertical writing mode the width is the maximum + * of all glyph widths and height the height of the text string. + * + */ + +pdc_scalar +pdf_calculate_textsize(PDF *p, const pdc_byte *text, int len, int charlen, + pdf_text_options *to, int breakchar, pdc_scalar *height, + pdc_bool verbose) +{ + pdf_font *currfont = &p->fonts[to->font]; + pdc_encoding enc = currfont->ft.enc; + pdc_byte *tmpstring = (pdc_byte *) text; + pdc_ushort *ustext = (pdc_ushort *) text; + pdc_scalar glwidth = 0, width = 0; + pdc_scalar font2user = to->fontsize / 1000.0; + pdc_bool kbreak = pdc_false; + int usv, ic, icc, numglyphs = 0, numspaces = 0; + + /* We cannot handle empty strings or fonts without widths info */ + if (!len || currfont->widthsmissing) + { + if (height) + *height = 0.0; + return width; + } + + if (enc != pdc_cid) + len /= charlen; + + for (ic = 0; ic < len; ) + { + icc = ic; + + { + if (charlen == 1) + { + usv = (int) text[ic]; + } + else if (enc == pdc_unicode) + { + usv = pdc_char16_to_char32(p->pdc, ustext, &ic, len, verbose); + } + else + { + usv = (int) ustext[ic]; + } + + /* count spaces */ + if (usv == (int) currfont->ft.spacechar) + numspaces++; + + /* break character */ + if (breakchar > 0) + kbreak = (usv == breakchar); + + ic++; + } + + /* start by adding in the width of the character */ + if (currfont->opt.monospace) + { + glwidth = (pdc_scalar) currfont->opt.monospace; + } + else + { + glwidth = (pdc_scalar) fnt_get_glyphwidth(usv, &currfont->ft); + if (glwidth == FNT_MISSING_WIDTH) + glwidth = currfont->ft.m.defwidth; + } + + /* count glyphs */ + numglyphs++; + + /* horizontal or vertical writing mode */ + if (!currfont->ft.vertical) + { + width += glwidth; + + + /* supplied glyph widths */ + if (icc < to->nglyphs) + { + pdc_scalar shift = to->xadvancelist[icc] / font2user - glwidth; + width += shift; + if (p->pdc->ptfrun) + shift = PDC_ROUND(1e10 * shift) / 1e10; + shift = PDC_ROUND(1e1 * shift) / 1e1; + to->xadvancelist[icc] = shift; + } + } + else + { + /* maximum of width */ + if (glwidth > width) + width = glwidth; + } + + /* length of text part ranging to decimal character */ + if (kbreak) + break; + } + + if (breakchar > 0 && !kbreak) + return 0; + + /* charspacing and wordspacing */ + if (!currfont->ft.vertical) + { + if (to->charspacing) + width += numglyphs * to->charspacing / font2user; + if (to->wordspacing) + width += numspaces * to->wordspacing / font2user; + if (height) + *height = 0.0; + } + else + { + /* height for positive y direction. + * Acrobat calculates with negative direction (see pdf_place_text). + */ + *height = numglyphs * (to->fontsize + -to->charspacing) + + numspaces * (-to->wordspacing); + } + + /* take horizontal scaling factor and font scaling factor into account */ + width *= font2user * to->horizscaling; + + if (tmpstring != text) + pdc_free_tmp(p->pdc, tmpstring); + + return width; + +} + +pdc_scalar +pdf_trim_textwidth(pdc_scalar width, pdf_text_options *to) +{ + if (!PDC_FLOAT_ISNULL(width)) + width -= to->horizscaling * to->charspacing; + + return width; +} + + +pdc_scalar +pdf__stringwidth(PDF *p, const char *text, int len, int font, + pdc_scalar fontsize) +{ + pdc_byte *utext; + int charlen; + pdc_scalar width = 0, height = 0; + pdf_text_options to = *p->curr_ppt->currto; + + if (text && len == 0) + len = (int) strlen(text); + if (text == NULL || len <= 0) + return width; + + pdf_check_handle(p, font, pdc_fonthandle); + + pdc_check_number_zero(p->pdc, "fontsize", fontsize); + + /* convert text string */ + to.font = font; + to.fontsize = fontsize; + pdf_check_textstring(p, text, len, PDF_KEEP_TEXTLEN | PDF_USE_TMPALLOC, + &to, &utext, &len, &charlen, pdc_true); + if (utext && len) + width = pdf_calculate_textsize(p, utext, len, charlen, + &to, -1, &height, pdc_true); + + return width; +} + + +/* ------------------------ Text output functions ------------------------ */ + +static void +pdf_convert_text_towinansi(PDF *p, const pdc_byte *fromtext, int len, + pdc_byte *totext, pdf_font *currfont) +{ + pdc_encodingvector *evfrom = + pdc_get_encoding_vector(p->pdc, currfont->ft.enc); + pdc_encodingvector *evto = + pdc_get_encoding_vector(p->pdc, currfont->towinansi); + int i; + + for (i = 0; i < len; i++) + totext[i] = pdc_transform_bytecode(p->pdc, evto, evfrom, fromtext[i]); +} + +void +pdf_put_fieldtext(PDF *p, const char *text, int font) +{ + if (pdc_is_utf8_bytecode(text)) + { + pdf_put_hypertext(p, text); + } + else + { + static const char fn[] = "pdf_put_fieldtext"; + pdf_font *currfont = &p->fonts[font]; + char *tmpstring = (char *) text; + int len = (int) pdc_strlen(text); + + if (len && currfont->towinansi != pdc_invalidenc && + !pdc_is_utf16be_unicode(text)) + { + /* Convert 8-bit code string to winansi */ + tmpstring = (char *) pdc_malloc_tmp(p->pdc, + (size_t) len, fn, NULL, NULL); + pdf_convert_text_towinansi(p, (pdc_byte *) text, len, + (pdc_byte *) tmpstring, currfont); + } + + pdc_put_pdfstring(p->out, tmpstring, len); + if (tmpstring != text) + pdc_free_tmp(p->pdc, tmpstring); + } +} + +static void +pdf_put_textstring(PDF *p, const pdc_byte *text, int len, int charlen, + pdf_font *currfont) +{ + static const char fn[] = "pdf_put_textstring"; + pdc_byte *tmpstring = (pdc_byte *) text; + + (void) charlen; + + if (len) + { + + /* Convert 8-bit code string to winansi */ + if (currfont->towinansi != pdc_invalidenc) + { + tmpstring = (pdc_byte *) pdc_malloc_tmp(p->pdc, + (size_t) len, fn, NULL, NULL); + pdf_convert_text_towinansi(p, text, len, tmpstring, currfont); + } + + } + + pdc_put_pdfstring(p->out, (char *) tmpstring, len); + if (tmpstring != text) + pdc_free_tmp(p->pdc, tmpstring); +} + +static void +pdf_put_textstring_shift(PDF *p, pdc_byte *text, int len, int charlen, + pdf_text_options *to, pdc_scalar spaceshift) +{ + pdf_font *currfont = &p->fonts[to->font]; + pdc_ushort *ustext = (pdc_ushort *) text; + pdc_byte *currtext; + pdc_scalar shift; + pdc_bool isutf16; + int currlen, nchars; + int leftchar = 0, rightchar; + int ic, icp, incr = charlen; + + currlen = 0; + currtext = text; + nchars = len/charlen; + isutf16 = charlen == 2 && + currfont->codesize == 2 && + currfont->ft.enc == pdc_unicode; + for (ic = 0; ic < nchars; ic++) + { + if (charlen == 1) + { + rightchar = (int) text[ic]; + } + else if(!isutf16) + { + rightchar = (int) ustext[ic]; + } + else + { + icp = ic; + rightchar = + pdc_char16_to_char32(p->pdc, ustext, &ic, nchars, pdc_true); + incr = (1 + ic - icp) * charlen; + } + + if (ic) + { + /* PDF wants the inverse shift amount + * (positive numbers move left, negative move right!) */ + + if (spaceshift != 0 && leftchar == (int) currfont->ft.spacechar) + shift = -spaceshift; + else + shift = 0; + + + if (ic <= to->nglyphs) + shift -= to->xadvancelist[ic-1]; + + if (shift) + { + pdf_put_textstring(p, currtext, currlen, charlen, currfont); + pdc_printf(p->out, "%f", shift); + currtext = &text[charlen * ic]; + currlen = 0; + } + } + leftchar = rightchar; + currlen += incr; + } + + pdf_put_textstring(p, currtext, currlen, charlen, currfont); + + if (to->nglyphs && to->nglyphs >= nchars) + pdc_printf(p->out, "%f", -to->xadvancelist[nchars - 1]); + +} + + +/* --------------------- General text placing function --------------------- */ + + +#define PDF_RENDERMODE_FILLCLIP 4 +#define PDF_ITALICANGLE_DEFAULT -12 + +static void +pdf_place_singletext(PDF *p, pdc_byte *text, int len, int charlen, + pdf_text_options *to, pdc_scalar tx, pdc_scalar ty, + pdc_scalar width, pdc_scalar height, pdc_scalar leading, + pdc_bool cont) +{ + pdf_tstate *ts = &p->curr_ppt->tstate[p->curr_ppt->sl]; + pdf_font *currfont = &p->fonts[to->font]; + pdc_scalar dx, dy, spaceshift = 0; + pdc_scalar font2user = to->fontsize / 1000.0; + pdc_scalar linewidth = 0; + pdc_scalar deflinewidth = 0; + pdc_bool hasdeco = to->underline || to->overline || to->strikeout; + pdc_bool takeTJ = pdc_false; + + /* default linewidth for underlinewidth and strokewidth */ + if (hasdeco || (to->mask & (1 << to_strokewidth))) + { + if (currfont->ft.m.underlineThickness == 0) + currfont->ft.m.underlineThickness = 50; + deflinewidth = fabs(to->horizscaling * font2user * + currfont->ft.m.underlineThickness); + } + + /* fill and stroke color */ + if (to->mask & (1 << to_fillcolor)) + pdf_set_coloropt(p, (int) pdf_fill, &to->fillcolor); + if (to->mask & (1 << to_strokecolor)) + pdf_set_coloropt(p, (int) pdf_stroke, &to->strokecolor); + + + /* stroke width and dasharray for stroked text */ + if (to->mask & (1 << to_strokewidth)) + { + if (to->strokewidth == PDF_UNDERLINEWIDTH_AUTO) + { + linewidth = deflinewidth; + } + else + { + linewidth = to->strokewidth; + if ((to->pcmask & (1 << to_strokewidth))) + linewidth *= fabs(to->fontsize); + } + pdf__setlinewidth(p, linewidth); + } + if (to->mask & (1 << to_dasharray)) + pdf__setdash(p, to->dasharray[0], to->dasharray[1]); + + /* text decoration */ + if (width && hasdeco) + { + pdc_scalar scale = fabs(to->horizscaling); + pdc_scalar delta, fs, trise, lineheight; + pdc_scalar txe = 0, tye = 0; + pdc_scalar lineposition = 0; + + fs = p->ydirection * font2user; + trise = p->ydirection * to->textrise; + lineheight = fs * currfont->ft.m.ascender; + delta = scale * (fs * currfont->ft.m.underlinePosition + trise); + + pdf__save(p); + + if (to->underlinewidth == PDF_UNDERLINEWIDTH_AUTO) + { + linewidth = deflinewidth; + } + else + { + linewidth = to->underlinewidth; + if ((to->pcmask & (1 << to_underlinewidth))) + linewidth *= fabs(to->fontsize); + } + + if (to->underlineposition == PDF_UNDERLINEPOSITION_AUTO) + { + lineposition = delta; + } + else + { + lineposition = p->ydirection * to->underlineposition; + if ((to->pcmask & (1 << to_underlineposition))) + lineposition *= to->fontsize; + } + + if (!currfont->ft.vertical) + { + txe = tx + width; + } + else + { + txe = tx - width / 2.0; + tye = ty - p->ydirection * height; + lineposition *= p->ydirection; + delta = fabs(delta); + } + + pdf__setlinecap(p, 0); + if (!(to->mask & (1 << to_dasharray))) + pdf__setdash(p, 0, 0); + + if (to->underline) + { + pdf__setlinewidth(p, linewidth); + if (!currfont->ft.vertical) + { + pdf__moveto(p, tx, ty + lineposition); + pdf__lineto(p, txe, ty + lineposition); + } + else + { + pdf__moveto(p, txe + lineposition, ty); + pdf__lineto(p, txe + lineposition, tye); + } + pdf__stroke(p); + } + + if (to->strikeout) + { + pdf__setlinewidth(p, deflinewidth); + if (!currfont->ft.vertical) + { + pdf__moveto(p, tx, ty + lineheight/2 + delta); + pdf__lineto(p, txe, ty + lineheight/2 + delta); + } + else + { + pdf__moveto(p, tx, ty); + pdf__lineto(p, tx, tye); + } + pdf__stroke(p); + } + + if (to->overline) + { + pdf__setlinewidth(p, deflinewidth); + if (!currfont->ft.vertical) + { + delta = scale * (fs * currfont->ft.m.underlinePosition - trise); + pdf__moveto(p, tx, ty + lineheight - delta); + pdf__lineto(p, txe, ty + lineheight - delta); + } + else + { + pdf__moveto(p, txe + width + delta, ty); + pdf__lineto(p, txe + width + delta, tye); + } + pdf__stroke(p); + } + + pdf__restore(p); + } + + + + /* wordspacing */ + if (!PDC_FLOAT_ISNULL(to->wordspacing)) + { + spaceshift = to->wordspacing / font2user; + if (p->pdc->ptfrun) + spaceshift = PDC_ROUND(1e10 * spaceshift) / 1e10; + spaceshift = PDC_ROUND(1e1 * spaceshift) / 1e1; + takeTJ = PDC_FLOAT_ISNULL(spaceshift) ? pdc_false : pdc_true; + } + + + /* supplied glyph widths */ + if (!takeTJ) + takeTJ = to->nglyphs; + + /* begin text object */ + pdf_begin_text(p); + + /* italic angle - realized by Tm operator */ + if (!PDC_FLOAT_ISNULL(to->italicangle) || + currfont->metricflags & font_italic) + { + if (!currfont->ft.vertical) + { + pdc_scalar italicangle = -p->ydirection * to->italicangle; + + if (currfont->metricflags & font_italic && italicangle == 0) + italicangle = -p->ydirection * PDF_ITALICANGLE_DEFAULT; + + if (ts->hs < 0) + italicangle = -italicangle; + + pdc_printf(p->out, "1 0 %f 1 %f %f Tm\n", + tan(italicangle * PDC_DEG2RAD), tx, ty); + + cont = pdc_false; + ts->newpos = pdc_false; + ts->refptx = tx; + ts->refpty = ty; + } + else + { + pdc_error(p->pdc, PDF_E_TEXT_ITALUNSUPP, 0, 0, 0, 0); + } + } + else + { + /* components of text displacement vector */ + if (!cont) + { + dx = tx - ts->prevtx; + dy = ty - ts->prevty; + } + else + { + dx = tx - ts->refptx; + dy = ty - ts->refpty + leading; + } + + /* condition for text displacement operator Td */ + if (!PDC_FLOAT_ISNULL(dx) || !PDC_FLOAT_ISNULL(dy) || + ts->newpos || (cont && takeTJ)) + { + if (cont) + { + dy -= leading; + cont = pdc_false; + } + pdc_printf(p->out, "%f %f Td\n", dx, dy); + + /* new reference position for next line */ + ts->newpos = pdc_false; + ts->refptx = tx; + ts->refpty = ty; + } + else + { + ts->refpty -= leading; + } + } + + /* show text */ + if (!takeTJ) + { + pdf_put_textstring(p, text, len, charlen, currfont); + if (!cont) + pdc_puts(p->out, "Tj\n"); + else + pdc_puts(p->out, "'\n"); + } + else + { + pdc_puts(p->out, "["); + pdf_put_textstring_shift(p, text, len, charlen, to, spaceshift); + pdc_puts(p->out, "]TJ\n"); + } + + /* new text position */ + if (!currfont->ft.vertical) + { + ts->currtx = tx + width; + ts->currty = ty; + } + else + { + ts->currtx = tx; + ts->currty = ty - p->ydirection * height; + } + ts->prevtx = ts->currtx; + ts->prevty = ts->currty; + + if (to->textrendering >= PDF_RENDERMODE_FILLCLIP) + pdf_end_text(p); +} + +#define PDF_FAKEBOLD_OFFSET 0.03 /* 3% of font size */ + +void +pdf_place_text(PDF *p, pdc_byte *text, int len, int charlen, + pdf_text_options *to, pdc_scalar width, pdc_scalar height, + pdc_bool cont) +{ + pdf_tstate *ts = &p->curr_ppt->tstate[p->curr_ppt->sl]; + pdf_font *currfont = &p->fonts[to->font]; + pdc_scalar tx, ty, leading = 0; + + /* text position */ + if (!cont) + { + tx = ts->currtx; + ty = ts->currty; + } + else + { + leading = p->ydirection * to->leading; + tx = ts->linetx; + ty = ts->currty - leading; + } + + pdf_place_singletext(p, text, len, charlen, to, tx, ty, + width, height, leading, cont); + + /* text bolding */ + if (to->fakebold || currfont->metricflags & font_bold) + { + static const pdc_scalar fx[] = {0, 0.70711, 1}; + static const pdc_scalar fy[] = {1, 0.70711, 0}; + pdc_scalar offset, currtx, currty, linetx; + int it, nt = 3; + + offset = PDF_FAKEBOLD_OFFSET * to->fontsize; + + linetx = ts->linetx; + currtx = ts->currtx; + currty = ts->currty; + for (it = 0; it < nt; it++) + { + pdf__set_text_pos(p, tx + fx[it] * offset, + ty + p->ydirection * fy[it] * offset); + pdf_place_singletext(p, text, len, charlen, to, + ts->currtx, ts->currty, + width, height, leading, pdc_false); + } + pdf__set_text_pos(p, currtx, currty); + ts->linetx = linetx; + } +} + +/* --------------------- Simple text showing functions --------------------- */ + +void +pdf__show_text( + PDF *p, + const char *text, + int len, + pdc_bool cont) +{ + static const char *fn = "pdf__show_text"; + pdf_text_options *currto = p->curr_ppt->currto; + pdc_byte *utext = NULL; + int charlen = 1; + pdc_scalar width = 0, height = 0; + + if (text && len == 0) + len = (int) strlen(text); + if (text == NULL || len <= 0) + { + if (cont) + len = 0; + else + return; + } + + /* no font set */ + if (currto->font == -1) + pdc_error(p->pdc, PDF_E_TEXT_NOFONT, 0, 0, 0, 0); + + if (len) + { + /* convert text string */ + pdf_check_textstring(p, text, len, PDF_USE_TMPALLOC, + currto, &utext, &len, &charlen, pdc_true); + if (utext == NULL || (!cont && !len)) + return; + + /* width and height of text string */ + width = pdf_calculate_textsize(p, utext, len, charlen, + currto, -1, &height, pdc_true); + } + else + { + utext = (pdc_byte *) pdc_calloc_tmp(p->pdc, 2, fn, NULL, NULL); + } + + + /* place text */ + pdf_place_text(p, utext, len, charlen, currto, width, height, cont); +} + + +/* ---------- Text showing function with explicit glyph widths ---------- */ + +void +pdf__xshow(PDF *p, const char *text, int len, const pdc_scalar *xadvancelist) +{ + static const char *fn = "pdf__xshow"; + pdf_text_options *currto = p->curr_ppt->currto; + pdc_byte *utext = NULL; + int charlen = 1; + size_t nbytes = 0; + pdc_scalar width, height; + + if (text && len == 0) + len = (int) strlen(text); + if (text == NULL || !len) + return; + + /* no font set */ + if (currto->font == -1) + pdc_error(p->pdc, PDF_E_TEXT_NOFONT, 0, 0, 0, 0); + + /* convert text string */ + pdf_check_textstring(p, text, len, PDF_USE_TMPALLOC, + currto, &utext, &len, &charlen, pdc_true); + if (utext == NULL || !len) + return; + + /* allocating glyph widths arrays */ + nbytes = (size_t) (len / charlen) * sizeof(pdc_scalar); + currto->xadvancelist = (pdc_scalar *) pdc_malloc_tmp(p->pdc, + nbytes, fn, NULL, NULL); + memcpy(currto->xadvancelist, xadvancelist, nbytes); + currto->nglyphs = len / charlen; + + /* length of text */ + width = pdf_calculate_textsize(p, utext, len, charlen, + currto, -1, &height, pdc_true); + + + /* place text */ + pdf_place_text(p, utext, len, charlen, currto, width, height, pdc_false); + + currto->xadvancelist = NULL; + currto->nglyphs = 0; +} + + +/* --------------------------- Leader functions ---------------------------- */ + + + +/* ----------------------- Text fitting function ------------------------ */ + +struct pdf_fittext_s +{ + pdc_vector start; /* text start position */ + pdc_vector end; /* text end position */ + pdc_vector writingdir; /* unit vector of text writing direction */ + pdc_vector perpendiculardir;/* unit vector perpendicular to writing dir. */ + pdc_vector scale; /* x/y scaling */ + pdc_scalar angle; /* rotation angle of writingdir in degree */ + pdc_scalar width; /* textline width */ + pdc_scalar height; /* textline height */ + pdc_scalar mwidth; /* textline width with margins */ + pdc_scalar mheight; /* textline height with margins */ + pdc_scalar ascender; /* textline ascender */ + pdc_scalar capheight; /* textline capheight */ + pdc_scalar xheight; /* textline xheight */ + pdc_scalar descender; /* textline descender */ +}; + + +/* definitions of fit text options */ +static const pdc_defopt pdf_fit_textline_options[] = +{ + PDF_TEXT_OPTIONS + + {"xadvancelist", pdc_scalarlist, PDC_OPT_NOZERO, 0, PDC_USHRT_MAX, + PDC_FLOAT_MIN, PDC_FLOAT_MAX, NULL}, + + PDF_FIT_OPTIONS1 + PDF_FIT_OPTIONS2 + PDF_FIT_OPTIONS6 + + PDF_FONT_OPTIONS1 + PDF_FONT_OPTIONS2 + + PDF_ERRORPOLICY_OPTION + PDC_OPT_TERMINATE +}; + +pdc_resopt * +pdf_parse_fittextline_optlist(PDF *p, pdf_text_options *to, + pdf_fit_options *fit, const char *optlist) +{ + pdc_resopt *resopts = NULL; + pdf_font_options fo; + + /* *to must be initialized */ + + /* initialize fit options */ + pdf_init_fit_options(p, pdc_false, fit); + fit->flags |= is_textline; + + /* initialize font options */ + pdf_init_font_options(p, &fo); + fo.flags |= is_textline; + + /* parsing option list */ + if (optlist && strlen(optlist)) + { + pdc_clientdata data; + + pdf_set_clientdata(p, &data); + resopts = pdc_parse_optionlist(p->pdc, optlist, + pdf_fit_textline_options, &data, pdc_true); + + pdf_get_font_options(p, &fo, resopts); + pdf_get_text_options(p, to, resopts); + pdf_get_fit_options(p, pdc_false, fit, resopts); + } + + /* font options specified */ + if (fo.mask & (1 << fo_fontname) && fo.mask & (1 << fo_encoding)) + { + to->font = pdf_load_font_internal(p, &fo); + to->mask |= (1L << to_font); + to->fontset |= (1L << to_font); + } + else + { + pdf_cleanup_font_options(p, &fo); + } + + return resopts; +} + +static pdc_bool +pdf_parse_textline_options(PDF *p, const char *text, int len, + pdf_text_options *to, pdf_fit_options *fit, + const char *optlist) +{ + pdf_ppt *ppt = p->curr_ppt; + + if (text && len == 0) + len = (int) strlen(text); + if (text == NULL || len <= 0) + return pdc_false; + + /* initialize text options */ + *to = *ppt->currto; + to->text = (char *) text; + to->textlen = len; + + /* parsing option list */ + pdf_parse_fittextline_optlist(p, to, fit, optlist); + + /* no font set */ + if (to->font == -1) + pdc_error(p->pdc, PDF_E_TEXT_NOFONT, 0, 0, 0, 0); + + /* no font size set */ + if (to->fontsize == PDC_FLOAT_MIN) + { + pdc_error(p->pdc, PDF_E_TEXT_NOFONTSIZESET, 0, 0, 0, 0); + } + + return pdc_true; +} + +int +pdf_fit_textline_internal(PDF *p, pdf_fittext *fitres, + pdf_text_options *to, pdf_fit_options *fit, + pdc_matrix *matrix) +{ + pdc_bool logg5 = pdc_logg_is_enabled(p->pdc, 5, trc_text); + pdf_ppt *ppt = p->curr_ppt; + pdf_font *currfont = &p->fonts[to->font]; + pdc_byte *utext = (pdc_byte *) ""; + int len, charlen; + pdc_bool blind = (fitres != NULL) ? pdc_true : pdc_false; + pdc_bool vertical = currfont->ft.vertical; + + pdc_matrix ctm = ppt->gstate[ppt->sl].ctm; + pdc_matrix m, mm; + pdc_vector elemsize, elemscale, elemmargin, textrelpos, fitrelpos; + pdc_vector polyline[5]; + pdc_scalar textyextent[2]; + pdc_box fitbox, elembox; + pdc_scalar ss, width, height, boxwidth, boxheight, fontsizeref; + pdc_scalar ascender, capheight, xheight, descender; + pdc_scalar x, y, tx = 0, ty = 0, basey = 0; + pdc_bool hasfitbox = pdc_false; + pdc_scalar font2user; + int indangle = fit->orientate / 90; + int unmapgids = 0, i; + + (void) ppt; + + /* box size */ + boxwidth = fit->boxsize[0]; + boxheight = fit->boxsize[1]; + + /* reference for font size as percentage */ + if (indangle % 2) + fontsizeref = boxwidth; + else + fontsizeref = boxheight; + + /* calculate and set text options */ + pdf_calculate_text_options(p, to, pdc_false, 1.0, PDC_FLOAT_PREC, + fontsizeref); + if (!blind) + pdf_set_text_options(p, to); + + /* convert text string */ + unmapgids = pdf_check_textstring(p, to->text, to->textlen, PDF_USE_TMPALLOC, + to, &utext, &len, &charlen, pdc_true); + if (utext == NULL || !len) + return -1; + + if (to->nglyphs && len/charlen != to->nglyphs) + pdc_warning(p->pdc, PDF_E_TEXT_SIZENOMATCH, + pdc_errprintf(p->pdc, "%d", to->nglyphs), + pdc_errprintf(p->pdc, "%d", len/charlen), 0, 0); + + /* width and height of text */ + width = pdf_calculate_textsize(p, utext, len, charlen, + to, -1, &height, pdc_true); + width = pdf_trim_textwidth(width, to); + if (PDC_FLOAT_ISNULL(width)) + return -1; + + /* font specifics */ + font2user = to->fontsize / 1000.0; + ascender = font2user * currfont->ft.m.ascender; + capheight = font2user * currfont->ft.m.capHeight; + xheight = font2user * currfont->ft.m.xHeight; + descender = font2user * currfont->ft.m.descender; + + /* margin lower left corner */ + elemmargin.x = fit->margin[0]; + elemmargin.y = fit->margin[1]; + + /* new box size */ + boxwidth -= 2 * elemmargin.x; + if (boxwidth < 0) + boxwidth = 0; + boxheight -= 2 * elemmargin.y; + if (boxheight < 0) + boxheight = 0; + hasfitbox = boxwidth > PDC_FLOAT_PREC && boxheight > PDC_FLOAT_PREC; + + /* kind of text box */ + pdf_get_mbox_boxheight(p, fit->matchbox, textyextent); + + /* text x size */ + elemsize.x = width; + + /* TODO: for vertical text */ + /* text y size */ + if (!vertical) + { + height = 0; + for (i = 0; i < 2; i++) + { + basey = 0; + if (textyextent[i] <= 0) + { + switch ((int) textyextent[i]) + { + case text_none: + break; + + case text_ascender: + basey = ascender; + break; + + case text_capheight: + basey = capheight; + break; + + case text_xheight: + basey = xheight; + break; + + case text_descender: + basey = -descender; + break; + + case text_textrise: + basey = to->textrise; + break; + + case text_fontsize: + basey = to->fontsize; + break; + + case text_leading: + basey = to->leading; + break; + } + } + else + { + basey = textyextent[i]; + } + height += basey; + } + } + elemsize.y = height; + + /* orientation */ + if (indangle % 2) + { + ss = elemsize.x; + elemsize.x = elemsize.y; + elemsize.y = ss; + } + + /* box for fitting */ + fitbox.ll.x = 0; + fitbox.ll.y = 0; + fitbox.ur.x = boxwidth; + fitbox.ur.y = boxheight; + + /* relativ position in fit and text box */ + fitrelpos.x = fit->position[0] / 100.0; + fitrelpos.y = fit->position[1] / 100.0; + textrelpos = fitrelpos; + + /* decimal character and position */ + if (fit->alignchar) + { + pdc_encoding enc = currfont->ft.enc; + pdc_encodingvector *ev = pdc_get_encoding_vector(p->pdc, enc); + pdc_scalar decwidth, decheight, pos1, pos2; + int poschar = (int) fit->alignchar; + + switch(enc) + { + case pdc_cid: + if (currfont->codesize != 2) + poschar = -1; + break; + + case pdc_glyphid: + poschar = fnt_get_glyphid(poschar, &currfont->ft); + break; + + case pdc_builtin: + poschar = -1; + break; + + default: + if (ev != NULL && charlen == 1) + { + poschar = pdc_get_encoding_bytecode(p->pdc, ev, + (pdc_ushort) poschar); + } + break; + } + + /* width and height of text part ranging to decimal character */ + decwidth = pdf_calculate_textsize(p, utext, len, charlen, + to, poschar, &decheight, pdc_true); + + /* position found */ + if (decwidth > 0) + { + /* relative position of position character */ + pos1 = decwidth / width; + pos2 = 1 - pos1; + i = vertical ? ((indangle + 3) % 4) : indangle; + switch (i) + { + case 0: + textrelpos.x = pos1; + break; + + case 1: + textrelpos.y = pos1; + break; + + case 2: + textrelpos.x = pos2; + break; + + case 3: + textrelpos.y = pos2; + break; + } + } + } + + /* calculate image box */ + pdc_place_element(fit->fitmethod, fit->shrinklimit, &fitbox, &fitrelpos, + &elemsize, &textrelpos, &elembox, &elemscale); + + if (logg5) + pdc_logg(p->pdc, + "\t\tFitting input parameter:\n" + "\t\t\tfitmethod = %s\n" + "\t\t\tshrinklimit = %f\n" + "\t\t\trefpoint = %f, %f\n" + "\t\t\tboxsize = %f, %f\n" + "\t\t\tfitrelpos = %f, %f\n" + "\t\t\telemsize = %f, %f\n" + "\t\t\ttextrelpos = %f, %f\n" + "\t\tFitting output parameter:\n" + "\t\t\telembox = %f, %f, %f, %f\n" + "\t\t\telemscale = %f, %f\n", + pdc_get_keyword(fit->fitmethod, pdf_fitmethod_keylist), + fit->shrinklimit, fit->refpoint[0], fit->refpoint[1], + fitbox.ur.x, fitbox.ur.y, fitrelpos.x, fitrelpos.y, + elemsize.x, elemsize.y, textrelpos.x, textrelpos.y, + elembox.ll.x, elembox.ll.y, elembox.ur.x, elembox.ur.y, + elemscale.x, elemscale.y); + + /* reference point */ + pdc_translation_matrix(fit->refpoint[0], fit->refpoint[1], &mm); + if (matrix == NULL) + { + if (blind) + { + m = ctm; + pdc_multiply_matrix(&mm, &m); + } + else + m = mm; + } + else + { + m = *matrix; + pdc_multiply_matrix(&mm, &m); + } + + /* optional rotation */ + if (fabs(fit->rotate) > PDC_FLOAT_PREC) + { + pdc_rotation_matrix(p->ydirection * fit->rotate, &mm); + pdc_multiply_matrix(&mm, &m); + } + + /* output after translation and rotation */ + if (!blind) + { + /* new CTM */ + if (fit->showborder || + fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice) + { + pdf_concat_raw(p, &m); + pdc_identity_matrix(&m); + } + + /* show border */ + if (fit->showborder) + { + pdf__rect(p, elemmargin.x, p->ydirection * elemmargin.y, + boxwidth, boxheight); + pdf__rect(p, 0, 0, fit->boxsize[0], fit->boxsize[1]); + pdf__stroke(p); + } + + /* clipping */ + if ( + (fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice)) + { + pdc_scalar cw = fit->boxsize[0]; + pdc_scalar ch = fit->boxsize[1]; + + if (cw < PDC_FLOAT_PREC) + cw = PDF_ACRO_MAXPAGE; + if (ch < PDC_FLOAT_PREC) + ch = PDF_ACRO_MAXPAGE; + pdf__rect(p, 0, 0, cw, ch); + pdf__clip(p); + } + } + + /* reference point for elembox */ + if (elemmargin.x > PDC_FLOAT_PREC || elemmargin.y > PDC_FLOAT_PREC) + { + tx = elemmargin.x; + if (boxwidth < PDC_FLOAT_PREC) + tx *= 1.0 - 2 * fitrelpos.x; + ty = elemmargin.y; + if (boxheight < PDC_FLOAT_PREC) + ty *= 1.0 - 2 * fitrelpos.y; + + pdc_translation_matrix(tx, p->ydirection * ty, &mm); + pdc_multiply_matrix(&mm, &m); + } + + + /* translation of element box */ + elembox.ll.y *= p->ydirection; + elembox.ur.y *= p->ydirection; + pdc_box2polyline(NULL, &elembox, polyline); + tx = polyline[indangle].x; + ty = polyline[indangle].y; + pdc_translation_matrix(tx, ty, &mm); + pdc_multiply_matrix(&mm, &m); + boxwidth = elembox.ur.x - elembox.ll.x; + boxheight = elembox.ur.y - elembox.ll.y; + + /* orientation of text */ + if (fit->orientate != 0) + { + pdc_rotation_matrix(p->ydirection * fit->orientate, &mm); + pdc_multiply_matrix(&mm, &m); + if (indangle % 2) + { + ss = elemscale.x; + elemscale.x = elemscale.y; + elemscale.y = ss; + + ss = boxwidth; + boxwidth = p->ydirection * boxheight; + boxheight = p->ydirection * ss; + + ss = elemmargin.x; + elemmargin.x = p->ydirection * elemmargin.y; + elemmargin.y = p->ydirection * ss; + } + } + + /* matchbox */ + if (!blind && fit->matchbox) + { + pdc_rectangle matchrect; + + pdf_concat_raw(p, &m); + pdc_identity_matrix(&m); + + matchrect.llx = 0; + matchrect.lly = 0; + matchrect.urx = boxwidth; + matchrect.ury = boxheight; + + pdf_set_mbox_rectangle(p, fit->matchbox, &matchrect, 0); + pdf_draw_mbox_rectangle(p, fit->matchbox, + mbox_saverestore | mbox_area | mbox_border); + + pdf_add_page_mbox(p, fit->matchbox); + } + + /* scaling */ + if (elemscale.x != 1 || elemscale.y != 1) + { + pdc_scale_matrix(elemscale.x, elemscale.y, &mm); + pdc_multiply_matrix(&mm, &m); + } + + /* relative text position */ + if (!vertical) + { + x = 0; + y = p->ydirection * basey; + } + else + { + x = width / 2.0; + y = p->ydirection * height; + } + + if (logg5) + pdc_logg(p->pdc, + "\t\tReference point:\n" + "\t\t\tx = %f\n" + "\t\t\ty = %f\n" + "\t\tEmbedding matrix components of textline fitting:\n" + "\t\t\ta = %f\n" + "\t\t\tb = %f\n" + "\t\t\tc = %f\n" + "\t\t\td = %f\n" + "\t\t\te = %f\n" + "\t\t\tf = %f\n", + x, y, m.a, m.b, m.c, m.d, m.e, m.f); + + /* + * blind mode: pdf__info_textline + */ + if (blind) + { + pdc_scalar mwidth = 2 * fabs(elemmargin.x); + pdc_scalar mheight = 2 * fabs(elemmargin.y); + pdc_scalar vlen; + + /* start position */ + pdc_transform_point(&m, x, y, &tx, &ty); + fitres->start.x = tx; + fitres->start.y = ty; + + /* end position */ + if (!vertical) + { + tx = x + width; + ty = y; + } + else + { + tx = x; + ty = y - p->ydirection * height; + } + pdc_transform_point(&m, tx, ty, &tx, &ty); + fitres->end.x = tx; + fitres->end.y = ty; + + /* relative vector from start to end */ + tx = fitres->end.x - fitres->start.x; + ty = fitres->end.y - fitres->start.y; + vlen = sqrt(tx * tx + ty * ty); + if (!vertical) + { + /* width and x scaling */ + fitres->width = vlen; + fitres->mwidth = vlen + mwidth; + fitres->scale.x = fitres->width / width; + + /* unit vector of base line */ + fitres->writingdir.x = tx / vlen; + fitres->writingdir.y = ty / vlen; + + /* relative vector of fontsize */ + tx = x; + ty = y + p->ydirection * height; + pdc_transform_point(&m, tx, ty, &tx, &ty); + tx -= fitres->start.x; + ty -= fitres->start.y; + vlen = sqrt(tx * tx + ty * ty); + + /* height and y scaling */ + fitres->height = vlen; + fitres->mheight = vlen + mheight; + fitres->scale.y = fitres->height / height; + } + else + { + /* height and y scaling */ + fitres->height = vlen; + fitres->mheight = vlen + mheight; + fitres->scale.y = fitres->height / height; + + /* unit vector of perpendiculardir line */ + fitres->writingdir.x = tx / vlen; + fitres->writingdir.y = ty / vlen; + + /* relative vector of width */ + tx = x + width; + ty = y; + pdc_transform_point(&m, tx, ty, &tx, &ty); + tx -= fitres->start.x; + ty -= fitres->start.y; + vlen = sqrt(tx * tx + ty * ty); + + /* width ans x scaling */ + fitres->width = vlen; + fitres->mwidth = vlen + mwidth; + fitres->scale.x = fitres->width / width; + } + + /* unit vector of perpendiculardir line */ + fitres->perpendiculardir.x = tx / vlen; + fitres->perpendiculardir.y = ty / vlen; + + /* rotation angle of base line */ + fitres->angle = atan2(fitres->writingdir.y, fitres->writingdir.x) / + PDC_DEG2RAD; + + /* font specifics */ + fitres->ascender = pdc_transform_scalar(&m, ascender); + fitres->capheight = pdc_transform_scalar(&m, capheight); + fitres->xheight = pdc_transform_scalar(&m, xheight); + fitres->descender = pdc_transform_scalar(&m, descender); + } + else + { + /* CTM */ + pdf_concat_raw(p, &m); + + /* set text position */ + pdf__set_text_pos(p, x, y); + + + /* place text */ + pdf_place_text(p, utext, len, charlen, to, width, height, pdc_false); + + + /* create a link - deprecated - */ + if (to->link) + { + pdf_check_textstring(p, to->text, to->textlen, + PDF_USE_TMPALLOC | PDF_KEEP_UNICODE, + to, &utext, &len, &charlen, pdc_true); + pdf_create_link(p, to->linktype, x, y + p->ydirection * descender, + x + width, y + p->ydirection * to->fontsize, + to->link, (char *) utext, len); + pdc_free_tmp(p->pdc, utext); + } + } + + return unmapgids; +} + +void +pdf_calculate_textline_size(PDF *p, pdf_text_options *to, pdf_fit_options *fit, + pdc_scalar *width, pdc_scalar *height) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_fittext fitres; + pdc_matrix ctminv; + + /* calculate textline size for table cells */ + fitres.width = 0.0; + fitres.height = 0.0; + pdf_fit_textline_internal(p, &fitres, to, fit, NULL); + + pdc_invert_matrix(p->pdc, &ctminv, &ppt->gstate[ppt->sl].ctm); + if (width) + *width = pdc_transform_scalar(&ctminv, fitres.mwidth); + if (height) + *height = pdc_transform_scalar(&ctminv, fitres.mheight); +} + +void +pdf__fit_textline(PDF *p, const char *text, int len, pdc_scalar x, pdc_scalar y, + const char *optlist) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_tstate *ts; + pdf_text_options to; + pdf_fit_options fit; + pdc_matrix ctminv; + pdc_scalar currtx, currty; + + pdc_check_number(p->pdc, "x", x); + pdc_check_number(p->pdc, "y", y); + + /* parse options */ + if (!pdf_parse_textline_options(p, text, len, &to, &fit, optlist)) + return; + + fit.refpoint[0] = x; + fit.refpoint[1] = y; + + pdf__save(p); + + /* output text line */ + pdf_fit_textline_internal(p, NULL, &to, &fit, NULL); + pdf_cleanup_fit_options(p, &fit); + + ts = &ppt->tstate[ppt->sl]; + pdc_transform_point(&ppt->gstate[ppt->sl].ctm, + ts->currtx, ts->currty, &currtx, &currty); + + pdf__restore(p); + + /* calculate current text position*/ + pdc_invert_matrix(p->pdc, &ctminv, &ppt->gstate[ppt->sl].ctm); + pdc_transform_point(&ctminv, currtx, currty, &currtx, &currty); + pdf__set_text_pos(p, currtx, currty); +} + +static const pdc_keyconn pdf_info_keylist[] = +{ + {"startx", 1}, + {"starty", 2}, + {"endx", 3}, + {"endy", 4}, + {"writingdirx", 5}, + {"writingdiry", 6}, + {"perpendiculardirx", 7}, + {"perpendiculardiry", 8}, + {"scalex", 9}, + {"scaley", 10}, + {"width", 11}, + {"height", 12}, + {"ascender", 13}, + {"capheight", 14}, + {"xheight", 15}, + {"descender", 16}, + {"unmappedglyphs", 17}, + {"angle", 18}, + {NULL, 0} +}; + +double +pdf__info_textline(PDF *p, const char *text, int len, const char *keyword, + const char *optlist) +{ + pdf_ppt *ppt = p->curr_ppt; + pdf_text_options to; + pdf_fit_options fit; + pdf_fittext fitres; + double tinfo = 0; + int retval, infokey; + + if (!keyword || !*keyword) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "keyword", 0, 0, 0); + + infokey = pdc_get_keycode_ci(keyword, pdf_info_keylist); + if (infokey == PDC_KEY_NOTFOUND) + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "keyword", keyword, 0, 0); + + /* parse options */ + retval = pdf_parse_textline_options(p, text, len, &to, &fit, optlist); + + if (retval) + { + /* calculate textline */ + retval = pdf_fit_textline_internal(p, &fitres, &to, &fit, NULL); + pdf_cleanup_fit_options(p, &fit); + + if (retval > -1) + { + pdf_font *currfont = &p->fonts[to.font]; + pdc_matrix ctminv; + + pdc_invert_matrix(p->pdc, &ctminv, &ppt->gstate[ppt->sl].ctm); + + switch(infokey) + { + case 1: + case 2: + pdc_transform_vector(&ctminv, &fitres.start, NULL); + break; + + case 3: + case 4: + pdc_transform_vector(&ctminv, &fitres.end, NULL); + break; + + case 5: + case 6: + pdc_transform_rvector(&ctminv, &fitres.writingdir, NULL); + break; + + case 7: + case 8: + pdc_transform_rvector(&ctminv, &fitres.perpendiculardir, NULL); + break; + } + + pdc_logg_cond(p->pdc, 1, trc_text, + "\tInfo textline%s:\n" + "\tstartx = %f\n" + "\tstarty = %f\n" + "\tendx = %f\n" + "\tendy = %f\n" + "\twritingdirx = %f\n" + "\twritingdiry = %f\n" + "\tperpendiculardirx = %f\n" + "\tperpendiculardiry = %f\n" + "\tscalex = %f\n" + "\tscaley = %f\n" + "\twidth = %f\n" + "\theight = %f\n" + "\tascender = %f\n" + "\tcapheight = %f\n" + "\txheight = %f\n" + "\tdescender = %f\n", + currfont->ft.vertical ? " (vertical writing mode)" : "", + fitres.start.x, fitres.start.y, + fitres.end.x, fitres.end.y, + fitres.writingdir.x, fitres.writingdir.y, + fitres.perpendiculardir.x, fitres.perpendiculardir.y, + fitres.scale.x, fitres.scale.y, + fitres.width, fitres.height, + fitres.ascender, fitres.capheight, + fitres.xheight,fitres.descender); + + switch(infokey) + { + case 1: + tinfo = (double) fitres.start.x; + break; + + case 2: + tinfo = (double) fitres.start.y; + break; + + case 3: + tinfo = (double) fitres.end.x; + break; + + case 4: + tinfo = (double) fitres.end.y; + break; + + case 5: + tinfo = (double) fitres.writingdir.x; + break; + + case 6: + tinfo = (double) fitres.writingdir.y; + break; + + case 7: + tinfo = (double) fitres.perpendiculardir.x; + break; + + case 8: + tinfo = (double) fitres.perpendiculardir.y; + break; + + case 9: + tinfo = (double) fitres.scale.x; + break; + + case 10: + tinfo = (double) fitres.scale.y; + break; + + case 11: + tinfo = (double) fitres.width; + break; + + case 12: + tinfo = (double) fitres.height; + break; + + case 13: + tinfo = (double) fitres.ascender; + break; + + case 14: + tinfo = (double) fitres.capheight; + break; + + case 15: + tinfo = (double) fitres.xheight; + break; + + case 16: + tinfo = (double) fitres.descender; + break; + + case 17: + tinfo = (double) retval; + break; + + case 18: + tinfo = (double) fitres.angle; + break; + } + } + } + + return tinfo; +} + + + +/*****************************************************************************/ +/** deprecated historical text formatting function **/ +/*****************************************************************************/ + +/* this helper function returns the width of the null-terminated string +** 'text' for the current font and size EXCLUDING the last character's +** additional charspacing. +*/ +static pdc_scalar +pdf_swidth(PDF *p, const char *text) +{ + pdf_text_options *currto = p->curr_ppt->currto; + + pdc_scalar width = pdf_calculate_textsize(p, + (pdc_byte *) text, (int)strlen(text), 1, + currto, -1, NULL, pdc_true); + return (width - currto->horizscaling * currto->charspacing); +} + +static void +pdf_show_aligned(PDF *p, const char *text, pdc_scalar x, pdc_scalar y, + pdc_scalar wordspacing, pdf_alignment mode) +{ + if (!text) + return; + + switch (mode) { + default: + case text_left: + case text_justify: + case text_fulljustify: + /* nothing extra here... */ + break; + + case text_right: + x -= pdf_swidth(p, text); + break; + + case text_center: + x -= pdf_swidth(p, text) / 2; + break; + } + + pdf__set_text_pos(p, x, y); + pdf_set_tstate(p, wordspacing, to_wordspacing); + pdf__show_text(p, text, (int) strlen(text), pdc_false); +} + +int +pdf__show_boxed( + PDF *p, + const char *text, int len, + pdc_scalar left, + pdc_scalar bottom, + pdc_scalar width, + pdc_scalar height, + const char *hmode, + const char *feature) +{ + pdc_scalar old_wordspacing, wordspacing, textwidth, curx, cury; + pdc_bool prematureexit; /* return because box is too small */ + int curTextPos; /* character currently processed */ + int lastdone; /* last input character processed */ + int toconv = len; + pdf_text_options *currto = p->curr_ppt->currto; + pdf_font *currfont; + pdc_byte *utext = NULL; + pdc_text_format old_textformat; + pdf_alignment mode = text_left; + pdc_bool blind = pdc_false; + + /* text length */ + if (text == NULL) + return 0; + if (!len) + len = (int) strlen(text); + if (!len) + return 0; + + pdc_check_number(p->pdc, "left", left); + pdc_check_number(p->pdc, "bottom", bottom); + pdc_check_number(p->pdc, "width", width); + pdc_check_number(p->pdc, "height", height); + + if (hmode == NULL || *hmode == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "hmode", 0, 0, 0); + + if (!strcmp(hmode, "left")) + mode = text_left; + else if (!strcmp(hmode, "right")) + mode = text_right; + else if (!strcmp(hmode, "center")) + mode = text_center; + else if (!strcmp(hmode, "justify")) + mode = text_justify; + else if (!strcmp(hmode, "fulljustify")) + mode = text_fulljustify; + else + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "hmode", hmode, 0, 0); + + if (feature != NULL && *feature != '\0') + { + if (!strcmp(feature, "blind")) + blind = pdc_true; + else + pdc_error(p->pdc, PDC_E_ILLARG_STRING, "feature", feature, 0, 0); + } + + /* no font set */ + if (currto->font == -1) + pdc_error(p->pdc, PDF_E_TEXT_NOFONT, 0, 0, 0, 0); + currfont = &p->fonts[currto->font]; + + if (width == 0 && height != 0) + pdc_error(p->pdc, PDC_E_ILLARG_FLOAT, + "width", pdc_errprintf(p->pdc, "%f", width), 0, 0); + + if (width != 0 && height == 0) + pdc_error(p->pdc, PDC_E_ILLARG_FLOAT, + "height", pdc_errprintf(p->pdc, "%f", height), 0, 0); + + if (currfont->ft.vertical) + { + pdc_error(p->pdc, PDF_E_DOC_FUNCUNSUPP, "vertical writing mode", + 0, 0, 0); + } + + /* we cannot handle several encodings */ + if (currfont->ft.enc == pdc_unicode) + { + pdc_error(p->pdc, PDF_E_DOC_FUNCUNSUPP, "Unicode", 0, 0, 0); + } + + if (currfont->ft.enc == pdc_glyphid) + { + pdc_error(p->pdc, PDF_E_DOC_FUNCUNSUPP, "glyphid", 0, 0, 0); + } + + if (currfont->ft.enc == pdc_cid) + { + pdc_error(p->pdc, PDF_E_DOC_FUNCUNSUPP, "CID", 0, 0, 0); + } + + if (currfont->ft.enc == pdc_ebcdic || + currfont->ft.enc == pdc_ebcdic_37 || + currfont->ft.enc == pdc_ebcdic_winansi) + { + pdc_error(p->pdc, PDF_E_DOC_FUNCUNSUPP, "EBCDIC", 0, 0, 0); + } + + /* old wordspacing */ + old_textformat = currto->textformat; + + /* convert text string */ + if (toconv) + { + int charlen; + + /* convert text string */ + pdf_check_textstring(p, text, len, + PDF_KEEP_CONTROL | PDF_KEEP_TEXTLEN | PDF_USE_TMPALLOC, + currto, &utext, &len, &charlen, pdc_true); + if (utext == NULL || !len) + return 0; + + utext[len] = 0; + text = (const char *) utext; + currto->textformat = pdc_bytes; + } + + /* old wordspacing */ + old_wordspacing = currto->wordspacing; + + /* special case for a single aligned line */ + if (width == 0 && height == 0) + { + if (!blind) + pdf_show_aligned(p, text, left, bottom, old_wordspacing, mode); + + if (toconv) + currto->textformat = old_textformat; + return 0; + } + + curx = left; + cury = bottom + p->ydirection * height; + prematureexit = pdc_false; + curTextPos = 0; + lastdone = 0; + + /* switch curx for right and center justification */ + if (mode == text_right) + curx += width; + else if (mode == text_center) + curx += (width / 2); + +#define MAX_CHARS_IN_LINE 2048 + + /* loop until all characters processed, or box full */ + + while ((curTextPos < len) && !prematureexit) + { + /* buffer for constructing the line */ + char linebuf[MAX_CHARS_IN_LINE]; + int curCharsInLine = 0; /* # of chars in constructed line */ + int lastWordBreak = 0; /* the last seen space char */ + int wordBreakCount = 0; /* # of blanks in this line */ + + /* loop over the input string */ + while (curTextPos < len) + { + if (curCharsInLine >= MAX_CHARS_IN_LINE) + pdc_error(p->pdc, PDC_E_ILLARG_TOOLONG, "(text line)", + pdc_errprintf(p->pdc, "%d", MAX_CHARS_IN_LINE-1), 0, 0); + + /* abandon DOS line-ends */ + if (text[curTextPos] == PDF_RETURN && + text[curTextPos+1] == PDF_NEWLINE) + curTextPos++; + + /* if it's a forced line break draw the line */ + if (text[curTextPos] == PDF_NEWLINE || + text[curTextPos] == PDF_RETURN) + { + cury -= p->ydirection * currto->leading; + + if (p->ydirection * (cury - bottom) < 0) { + prematureexit = pdc_true; /* box full */ + break; + } + + linebuf[curCharsInLine] = 0; /* terminate the line */ + + /* check whether the line is too long */ + wordspacing = 0; + pdf_set_tstate(p, wordspacing, to_wordspacing); + textwidth = pdf_swidth(p, linebuf); + + /* the forced break occurs too late for this line */ + if (textwidth > width) + { + if (wordBreakCount == 0) { /* no blank found */ + prematureexit = pdc_true; + break; + } + linebuf[lastWordBreak] = 0; /* terminate at last blank */ + if (curTextPos > 0 && text[curTextPos-1] == PDF_RETURN) + --curTextPos; + curTextPos -= (curCharsInLine - lastWordBreak); + + if (!blind) + { + textwidth = pdf_swidth(p, linebuf); + if (wordBreakCount != 1 && + (mode == text_justify || + mode == text_fulljustify)) + { + wordspacing = (width - textwidth) / + ((wordBreakCount - 1) * currto->horizscaling); + } + pdf_show_aligned(p, linebuf, curx, cury, wordspacing, + mode); + } + } + else if (!blind) + { + if (mode == text_fulljustify && wordBreakCount > 0) + { + wordspacing = (width - textwidth) / + (wordBreakCount * currto->horizscaling); + } + pdf_show_aligned(p, linebuf, curx, cury, wordspacing, mode); + } + + lastdone = curTextPos; + curCharsInLine = lastWordBreak = wordBreakCount = 0; + curTextPos++; + + } + else if (text[curTextPos] == PDF_SPACE) + { + linebuf[curCharsInLine] = 0; /* terminate the line */ + + /* line too long ==> break at last blank */ + wordspacing = 0; + pdf_set_tstate(p, wordspacing, to_wordspacing); + if (pdf_swidth(p, linebuf) > width) + { + cury -= p->ydirection * currto->leading; + + if (p->ydirection * (cury - bottom) < 0) + { + prematureexit = pdc_true; /* box full */ + break; + } + + linebuf[lastWordBreak] = 0; /* terminate at last blank */ + curTextPos -= (curCharsInLine - lastWordBreak - 1); + + if (lastWordBreak == 0) + curTextPos--; + + /* LATER: * force break if wordBreakCount == 1, + * i.e., no blank + */ + if (wordBreakCount == 0) + { + prematureexit = pdc_true; + break; + } + + /* adjust word spacing for full justify */ + if (wordBreakCount != 1 && (mode == text_justify || + mode == text_fulljustify)) + { + textwidth = pdf_swidth(p, linebuf); + wordspacing = (width - textwidth) / + ((wordBreakCount - 1) * currto->horizscaling); + } + + lastdone = curTextPos; + if (!blind) + { + pdf_show_aligned(p, linebuf, curx, cury, wordspacing, + mode); + } + curCharsInLine = lastWordBreak = wordBreakCount = 0; + } + else + { + /* blank found, and line still fits */ + wordBreakCount++; + lastWordBreak = curCharsInLine; + linebuf[curCharsInLine++] = text[curTextPos++]; + } + } + else + { + /* regular character ==> store in buffer */ + linebuf[curCharsInLine++] = text[curTextPos++]; + } + } + + if (prematureexit) { + break; /* box full */ + } + + /* if there is anything left in the buffer, draw it */ + if (curTextPos >= len && curCharsInLine != 0) + { + cury -= p->ydirection * currto->leading; + + if (p->ydirection * (cury - bottom) < 0) + { + prematureexit = pdc_true; /* box full */ + break; + } + + linebuf[curCharsInLine] = 0; /* terminate the line */ + + /* check if the last line is too long */ + wordspacing = 0; + pdf_set_tstate(p, wordspacing, to_wordspacing); + textwidth = pdf_swidth(p, linebuf); + + if (textwidth > width) + { + if (wordBreakCount == 0) + { + prematureexit = pdc_true; + break; + } + + linebuf[lastWordBreak] = 0; /* terminate at last blank */ + curTextPos -= (curCharsInLine - lastWordBreak - 1); + + /* recalculate the width */ + textwidth = pdf_swidth(p, linebuf); + + /* adjust word spacing for full justify */ + if (wordBreakCount != 1 && (mode == text_justify || + mode == text_fulljustify)) + { + wordspacing = (width - textwidth) / + ((wordBreakCount - 1) * currto->horizscaling); + } + } + else if (!blind) + { + if (mode == text_fulljustify && wordBreakCount) + { + wordspacing = (width - textwidth) / + (wordBreakCount * currto->horizscaling); + } + } + + lastdone = curTextPos; + if (!blind) + { + pdf_show_aligned(p, linebuf, curx, cury, wordspacing, mode); + } + curCharsInLine = lastWordBreak = wordBreakCount = 0; + } + } + + pdf_set_tstate(p, old_wordspacing, to_wordspacing); + + /* return number of remaining characters */ + + while (text[lastdone] == PDF_SPACE) + ++lastdone; + + if ((text[lastdone] == PDF_RETURN || + text[lastdone] == PDF_NEWLINE) && text[lastdone+1] == 0) + ++lastdone; + + if (toconv) + currto->textformat = old_textformat; + + return (int) (len - lastdone); +} diff --git a/src/pdflib/pdflib/p_textflow.c b/src/pdflib/pdflib/p_textflow.c new file mode 100644 index 0000000..006facb --- /dev/null +++ b/src/pdflib/pdflib/p_textflow.c @@ -0,0 +1,27 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_textflow.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib textflow function + * + */ + +#define P_TEXTFLOW_C + +#include "p_intern.h" +#include "p_color.h" +#include "p_font.h" +#include "p_defopt.h" +#include "p_tagged.h" + + diff --git a/src/pdflib/pdflib/p_tiff.c b/src/pdflib/pdflib/p_tiff.c new file mode 100644 index 0000000..5ed382f --- /dev/null +++ b/src/pdflib/pdflib/p_tiff.c @@ -0,0 +1,1169 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_tiff.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * TIFF processing for PDFlib + * + */ + +#include "p_intern.h" +#include "p_color.h" +#include "p_image.h" + +#ifndef HAVE_LIBTIFF + +pdc_bool /* CDPDF fixed last parameter declaration */ +pdf_is_TIFF_file(PDF *p, pdc_file *fp, pdf_tiff_info *tiff, pdc_bool check) +{ + (void) p; + (void) fp; + (void) tiff; + (void) check; + + return pdc_false; +} + +int +pdf_process_TIFF_data( + PDF *p, + int imageslot) +{ + pdf_image *image = &p->images[imageslot]; + + pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "TIFF", 0, 0, 0); + + return -1; +} + +#else + +#include "tiffiop.h" +static tsize_t +pdf_libtiff_read(void* fd, tdata_t buf, tsize_t size) +{ + pdc_file *fp = (pdc_file *) fd; + + return ((tsize_t) pdc_fread(buf, 1, (size_t) size, fp)); +} + +static toff_t +pdf_libtiff_seek(void* fd, toff_t off, int whence) +{ + pdc_file *fp = (pdc_file *) fd; + + return ((toff_t) pdc_fseek(fp, (long) off, whence)); +} + +static int +pdf_libtiff_close(void* fd) +{ + (void) fd; + + /* pdc_fclose(fp); this happens in caller function */ + + return 0; +} + +static toff_t +pdf_libtiff_size(void* fd) +{ + pdc_file *fp = (pdc_file *) fd; + + return (toff_t) pdc_file_size(fp); +} + +static void * +pdf_libtiff_malloc(TIFF *t, tsize_t size) +{ + PDF *p = (PDF*) t->pdflib_opaque; + return pdc_calloc(p->pdc, (size_t)size, "libtiff"); +} + +static void * +pdf_libtiff_realloc(TIFF *t, tdata_t mem, tsize_t size) +{ + PDF *p = (PDF*) t->pdflib_opaque; + return(pdc_realloc(p->pdc, (void*)mem, (size_t)size, "libtiff")); +} + +static void +pdf_libtiff_free(TIFF *t, tdata_t mem) +{ + PDF *p = (PDF*) t->pdflib_opaque; + pdc_free(p->pdc, (void*)mem); +} + +#define PDF_TIFF_LENGTH_MAX 512 +static void +pdf_libtiff_error(TIFF *t, const char* module, const char* fmt, va_list ap) +{ + PDF *p = (PDF*) t->pdflib_opaque; + + if (pdc_logg_is_enabled(p->pdc, 5, trc_image)) + { + char buffer[PDF_TIFF_LENGTH_MAX]; + + /* Create the message */ + pdc_vsnprintf(buffer, PDF_TIFF_LENGTH_MAX, fmt, ap); + pdc_logg(p->pdc, "\tlibtiff(%s): %s\n", module, buffer); + } +} + +static void +pdf_data_source_TIFF_init(PDF *p, PDF_data_source *src) +{ + static const char *fn = "pdf_data_source_TIFF_init"; + pdf_image *image; + + image = (pdf_image *) src->private_data; + + if (image->strips == 1) + image->info.tiff.cur_line = 0; + + if (image->use_raw) + { + /* malloc is done in the fill function */ + src->buffer_length = (size_t) 0; + src->buffer_start = (pdc_byte *) NULL; + } + else + { + if (image->bpc == 1) + src->buffer_length = + (size_t) (image->components * ((int) image->width+7)/8); + else + src->buffer_length = + (size_t) (image->components * image->width); + + src->buffer_start = (pdc_byte *) + pdc_malloc(p->pdc, src->buffer_length, fn); + } +} + +/* Convert the a and b samples of Lab data from signed to unsigned. */ + +static void +pdf_signed_to_unsigned(pdc_byte *buf, size_t count) +{ + size_t i; + + for(i=0; i < count; i+=3) + { + buf[i+1] ^= 0x80; + buf[i+2] ^= 0x80; + } +} + +#define MYTIFF image->info.tiff.tif + +static pdc_bool +pdf_data_source_TIFF_fill(PDF *p, PDF_data_source *src) +{ + static const char *fn = "pdf_data_source_TIFF_fill"; + pdf_image *image; + int col; + pdc_byte *dest; + uint16 fillorder; + uint32 *s, *bc; + + image = (pdf_image *) src->private_data; + + PDC_TRY(p->pdc) + { + if (image->use_raw) + { + if (image->info.tiff.cur_line == image->strips) + { + PDC_EXIT_TRY(p->pdc); + return pdc_false; + } + + TIFFGetField(MYTIFF, TIFFTAG_STRIPBYTECOUNTS, &bc); + + if (bc[image->info.tiff.cur_line] > src->buffer_length) + { + src->buffer_length = bc[image->info.tiff.cur_line]; + src->buffer_start = (pdc_byte *) + pdc_realloc(p->pdc, src->buffer_start, + src->buffer_length, fn); + } + + if (TIFFReadRawStrip(MYTIFF, (tstrip_t) image->info.tiff.cur_line, + (tdata_t) src->buffer_start, + (tsize_t) bc[image->info.tiff.cur_line]) == -1) + { + pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "TIFF", + pdf_get_image_filename(p, image), 0, 0); + } + + src->next_byte = src->buffer_start; + src->bytes_available = bc[image->info.tiff.cur_line]; + + /* special handling for uncompressed 16-bit images */ + if (MYTIFF->tif_header.tiff_magic == TIFF_LITTLEENDIAN && + image->compression == pdf_comp_none && image->bpc == 16) + { + TIFFSwabArrayOfShort((uint16 *) src->buffer_start, + (unsigned long) src->bytes_available/2); + } + + if (TIFFGetField(MYTIFF, TIFFTAG_FILLORDER, &fillorder) + && (fillorder == FILLORDER_LSB2MSB)) + { + TIFFReverseBits((unsigned char *) src->buffer_start, + (unsigned long) src->bytes_available); + } + + /* The a and b values of (uncompressed) Lab must be adjusted */ + if (p->colorspaces[image->colorspace].type == Lab) + { + pdf_signed_to_unsigned(src->buffer_start, src->bytes_available); + } + + if (image->strips > 1) + { + /* only a single strip of a multi-strip image */ + image->info.tiff.cur_line = image->strips; + } + else + image->info.tiff.cur_line++; + } + else + { + if (image->info.tiff.cur_line++ == image->height) + { + PDC_EXIT_TRY(p->pdc); + return pdc_false; + } + + src->next_byte = src->buffer_start; + src->bytes_available = src->buffer_length; + + dest = src->buffer_start; + s = image->info.tiff.raster + + ((int)image->height - image->info.tiff.cur_line) * + (int) image->width; + + switch (image->components) + { + case 1: + if (image->bpc == 1) + { + unsigned char mask; + + memset((void*) dest, 0, src->buffer_length); + + for (mask=0x80, col = 0; col < image->width; col++) + { + if (TIFFGetR(*s++) != 0) + *dest |= mask; + + if ((mask>>=1) == 0) + { + mask = 0x80; + ++dest; + } + } + } + else /* bpc == 8 */ + { + for (col = 0; col < image->width; col++, s++) + { + *dest++ = (pdc_byte) TIFFGetR(*s); + } + } + break; + + case 3: + for (col = 0; col < image->width; col++, s++) + { + *dest++ = (pdc_byte) TIFFGetR(*s); + *dest++ = (pdc_byte) TIFFGetG(*s); + *dest++ = (pdc_byte) TIFFGetB(*s); + } + break; + + case 4: + for (col = 0; col < image->width; col++, s++) + { + unsigned char* t = (unsigned char*)&(*s); + *dest++ = (pdc_byte) t[0]; + *dest++ = (pdc_byte) t[1]; + *dest++ = (pdc_byte) t[2]; + *dest++ = (pdc_byte) t[3]; + } + break; + + default: + pdc_error(p->pdc, PDF_E_IMAGE_BADCOMP, + pdc_errprintf(p->pdc, "%d", image->components), + pdf_get_image_filename(p, image), 0, 0); + } + } + } + PDC_CATCH(p->pdc) + { + image->corrupt = pdc_true; + } + + return !image->corrupt; +} + +static void +pdf_data_source_TIFF_terminate(PDF *p, PDF_data_source *src) +{ + pdc_free(p->pdc, (void *) src->buffer_start); +} + +static int +pdf_check_colormap(int n, uint16* r, uint16* g, uint16* b) +{ + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return(16); + return(8); +} + +pdc_bool +pdf_is_TIFF_file(PDF *p, pdc_file *fp, pdf_tiff_info *tiff_info, pdc_bool check) +{ + const char *filename; + + pdc_logg_cond(p->pdc, 1, trc_image, "\tChecking image type TIFF...\n"); + + filename = pdc_file_name(fp); + tiff_info->tif = TIFFClientOpen(filename, "rc", + (void *)fp, + pdf_libtiff_read, NULL, + pdf_libtiff_seek, pdf_libtiff_close, pdf_libtiff_size, + NULL, NULL, (void *)p, + pdf_libtiff_malloc, pdf_libtiff_realloc, pdf_libtiff_free, + pdf_libtiff_error, pdf_libtiff_error); + if (tiff_info->tif == NULL) + { + pdc_fseek(fp, 0L, SEEK_SET); + return pdc_false; + } + if (check) + TIFFClose(tiff_info->tif); + return pdc_true; +} + +int +pdf_process_TIFF_data( + PDF *p, + int imageslot) +{ + static const char *fn = "pdf_process_TIFF_data"; + uint32 w, h; + uint16 unit, bpc, compression, photometric, extra, *sinfo; + uint16 orientation, planarconfig; + uint16 *rmap, *gmap, *bmap; + tsample_t components; + pdf_image *image; + float res_x, res_y; /* sic! */ + pdf_colorspace cs; + int slot; + int errint = 0; + int errcode = 0; + pdc_bool isopen = pdc_false; + int strips; + + image = &p->images[imageslot]; + + image->info.tiff.raster = (uint32 *) NULL; + + if (!pdf_is_TIFF_file(p, image->fp, &image->info.tiff, pdc_false)) + { + errcode = PDF_E_IMAGE_CORRUPT; + goto PDF_TIFF_ERROR; + } + + MYTIFF->tif_fd = (FILE*) image->fp; + isopen = pdc_true; + + if (image->page != 1) + { + if (TIFFSetDirectory(MYTIFF, (tdir_t) (image->page - 1)) != 1 ) + { + errint = image->page; + errcode = PDF_E_IMAGE_NOPAGE; + goto PDF_TIFF_ERROR; + } + } + + TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_ORIENTATION, &orientation); + image->orientation = orientation; + + TIFFGetField(MYTIFF, TIFFTAG_COMPRESSION, &compression); + + TIFFGetField(MYTIFF, TIFFTAG_IMAGEWIDTH, &w); + image->width = (pdc_scalar) w; + + TIFFGetField(MYTIFF, TIFFTAG_IMAGELENGTH, &h); + image->height = (pdc_scalar) h; + + TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_BITSPERSAMPLE, &bpc); + image->bpc = bpc; + + TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_SAMPLESPERPIXEL, &components); + image->components = components; + + TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_EXTRASAMPLES, &extra, &sinfo); + + TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_PLANARCONFIG, &planarconfig); + + photometric = 255; /* dummy value */ + TIFFGetField(MYTIFF, TIFFTAG_PHOTOMETRIC, &photometric); + + /* fetch the resolution values if found in the file */ + if (TIFFGetField(MYTIFF, TIFFTAG_XRESOLUTION, &res_x) && + TIFFGetField(MYTIFF, TIFFTAG_YRESOLUTION, &res_y) && + TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_RESOLUTIONUNIT, &unit) && + res_x > 0 && res_y > 0) { + + if (unit == RESUNIT_INCH) { + image->dpi_x = res_x; + image->dpi_y = res_y; + + } else if (unit == RESUNIT_CENTIMETER) { + image->dpi_x = res_x * 2.54; + image->dpi_y = res_y * 2.54; + + } else if (unit == RESUNIT_NONE) { + image->dpi_x = -res_x; + image->dpi_y = -res_y; + } + +#define PDF_REALLY_BIG_DPI 10000 + + /* Guard against obviously wrong values */ + if (unit != RESUNIT_NONE && + (image->dpi_x <= 1 || + image->dpi_y <= 1 || + image->dpi_x > PDF_REALLY_BIG_DPI || + image->dpi_y > PDF_REALLY_BIG_DPI)) + + image->dpi_x = image->dpi_y = 0; /* unknown */ + } + + + + /* ------------------------------------------------------------ + * Reject unsupported flavors. + * ---------------------------------------------------------- */ + + /* Catch some rare properties related to compression, photometric, + * and bpc which are definitely not supported (neither in pass-through + * mode nor libtiff) in order to provide a better error message than + * the generic "Error reading data". + */ + + /* Unsupported compression types */ + switch ((int) compression) + { + case /* 34661 */ COMPRESSION_JBIG: + case /* 34712 */ COMPRESSION_JP2000: + case 9 /* JBIG T85 */: + case 10 /* TIFF-FX JBIG (T.82) MRC (T.43) */: + case 34715 /* TFX */: + errint = (int) compression; + errcode = PDF_E_TIFF_UNSUPP_COMPRESSION; + goto PDF_TIFF_ERROR; + break; + + default: + break; + } + + /* Unsupported photometric values */ + switch ((int) photometric) + { + case PHOTOMETRIC_ICCLAB /* 9 */: + case PHOTOMETRIC_ITULAB /* 10 */: + errint = (int) photometric; + errcode = PDF_E_TIFF_UNSUPP_COLORSPACE; + goto PDF_TIFF_ERROR; + break; + + default: + break; + } + + /* 32-bit images are not supported */ + if (image->bpc > 16) + { + errcode = PDF_E_TIFF_16BIT_UNSUPP; + goto PDF_TIFF_ERROR; + } + + /* We don't support 16-bit CMYK unless it's uncompressed */ + if (image->bpc == 16 && components == 4 && compression != COMPRESSION_NONE) + { + errcode = PDF_E_TIFF_16BITCMYK_UNSUPP; + goto PDF_TIFF_ERROR; + } + + + /* ------------------------------------------------------------ + * We assume pass-through mode in the beginning, and disable it + * for image types where it doesn't work. + * ---------------------------------------------------------- */ + + image->use_raw = image->passthrough; + + /* Pass-through is not implemented for tiled images */ + if (TIFFIsTiled(MYTIFF)) + image->use_raw = pdc_false; + + + + /* Can't handle these colorspaces in raw mode (except with OJPEG) */ + if (compression != COMPRESSION_OJPEG && + (photometric == PHOTOMETRIC_YCBCR || + photometric == PHOTOMETRIC_CIELAB || + photometric == PHOTOMETRIC_MASK)) + { + image->use_raw = pdc_false; + } + + /* Can't pass through extra bits or use multiple data sources in raw mode + * (except with OJPEG). + */ + if (extra != 0 || + (compression != COMPRESSION_OJPEG && + planarconfig == PLANARCONFIG_SEPARATE && components > 1)) + { + image->components -= extra; /* ignore the extra channels */ + image->use_raw = pdc_false; + } + + /* PDF doesn't support other values of the color depth */ + if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8 && bpc != 16) + image->use_raw = pdc_false; + + /* Disable pass-through for a large number of strips to avoid + * file size bloat (due to many small Image XObjects) and + * ugly display in Acrobat (because of banding artifacts). + * The threshold for the number of strips has been determined empirically + * as a good compromise between file size and performance. + * + * We must still maintain pass-through mode for those cases where it + * is functionally more advanced, and benefit from its better performance + * for small numbers of strips. + * + * Also, we maintain pass-through mode for very large images since + * pass-through mode - especially with pixel mode (RGBA retrieval) - + * may run out of memory. + */ + +/* ca. 10K x 10K pixels (nopassthrough requires up to 4 times as many bytes!) */ +#define PDF_TIFF_THRESHOLD 0x6000000 + + strips = (int) TIFFNumberOfStrips(MYTIFF); + + if (strips > 25 && + compression != COMPRESSION_OJPEG && compression != COMPRESSION_JPEG && + photometric != PHOTOMETRIC_PALETTE && + image->width * image->width < PDF_TIFF_THRESHOLD) + { + image->use_raw = pdc_false; + } + + if (image->bpc == 16) + { + /* PDF < 1.5 doesn't support 16-bit images, so we cannot pass through */ + if (p->compatibility < PDC_1_5) + { + image->use_raw = pdc_false; + } + + /* + * PDF requires big-endian 16-bit data. We therefore use passthrough + * mode only for big-endian input or uncompressed data. + * + * It's not nice to pull the endianness directly from the TIFF + * structure, but there doesn't seem to be a public interface for it. + */ + if (MYTIFF->tif_header.tiff_magic == TIFF_LITTLEENDIAN && + (compression == COMPRESSION_DEFLATE || + compression == COMPRESSION_ADOBE_DEFLATE)) + { + image->use_raw = pdc_false; + } + + /* We don't support 16-bit CMYK unless in passthrough mode. + * Compressed images have already been rejected earlier. + */ + if (components == 4 && image->use_raw == pdc_false) + { + errcode = PDF_E_TIFF_16BITCMYK_UNSUPP; + goto PDF_TIFF_ERROR; + } + } + + /* + * Disable pass-through for unknown compression schemes, + * and collect the necessary parameters for well-known schemes. + */ + + if (image->use_raw == pdc_true) + { + uint32 group3opts; + uint16 predictor; + toff_t jpegifoffset, jpegifbytecount; + + switch ((int) compression) + { + case COMPRESSION_CCITTRLE: + case COMPRESSION_CCITTRLEW: + image->params = (char *) pdc_malloc(p->pdc, PDF_MAX_PARAMSTRING, + fn); + + strcpy(image->params, "/EndOfBlock false"); + strcat(image->params, "/EncodedByteAlign true"); + + if (photometric == PHOTOMETRIC_MINISBLACK) + strcat(image->params, "/BlackIs1 true"); + + image->compression = pdf_comp_ccitt; + break; + + case COMPRESSION_CCITTFAX3: + image->params = (char*) pdc_malloc(p->pdc, PDF_MAX_PARAMSTRING, + fn); + + strcpy(image->params, "/EndOfBlock false"); + + /* The following contains disabled code segments. + * Apparently, and contrary to my reading of the specs, + * the following can not be deduced from the respective + * TIFF entry or option: + * - /EncodedByteAlign can not reliably be deduced from + * GROUP3OPT_FILLBITS; + * + * From practical experience, the respective lines are + * disabled, but I don't have any clear explanation for this. + * A few TIFF images still don't work with this setting, + * unfortunately. + */ + + /* SEE ABOVE! + strcat(image->params, "/DamagedRowsBeforeError 1"); + */ + + if (TIFFGetField(MYTIFF, TIFFTAG_GROUP3OPTIONS, &group3opts)) + { + /* /K = 0 (= G3,1D) is default */ + if (group3opts & GROUP3OPT_2DENCODING) + strcat(image->params, "/K 1"); + + /* SEE ABOVE! + if (group3opts & GROUP3OPT_FILLBITS) + strcat(image->params, "/EncodedByteAlign true"); + */ + } + + if (photometric == PHOTOMETRIC_MINISBLACK) + strcat(image->params, "/BlackIs1 true"); + + image->compression = pdf_comp_ccitt; + break; + + case COMPRESSION_CCITTFAX4: + image->params = (char*) pdc_malloc(p->pdc, PDF_MAX_PARAMSTRING, + fn); + + strcpy(image->params, "/K -1"); + /* Required for bug #511 */ + strcat(image->params, "/EndOfBlock false"); + + if (photometric == PHOTOMETRIC_MINISBLACK) + strcat(image->params, "/BlackIs1 true"); + + image->compression = pdf_comp_ccitt; + break; + + case COMPRESSION_OJPEG: + /* + * Check whether a full-blown JPEG can be found inside the TIFF + * + * Heuristic: + * If we find a positive JPEGIFOFFSET there should be valid + * JFIF data; however, sometimes there isn't and we must not + *call the JPEG module. Strangely enough, various creators which + * do not emit valid JFIF do emit the JPEGIFBYTECOUNT tag. + * Therefore we use the absence of JPEGIFBYTECOUNT as a hint + * that JFIF processing might work. + * + * Known trouble-makers which include JPEGIFBYTECOUNT: + * "Oi/GFS, writer v00.06.02" + */ + if (TIFFGetField(MYTIFF, TIFFTAG_JPEGIFOFFSET, &jpegifoffset) && + jpegifoffset != 0 && + !TIFFGetField(MYTIFF, TIFFTAG_JPEGIFBYTECOUNT, + &jpegifbytecount)) + { + /* stop TIFF processing */ + TIFFClose(MYTIFF); + + /* store data offset for the JPEG module (after TIFFClose() + * the image->info union is no longer used by the TIFF + * module) + */ + image->info.jpeg.jpegifoffset = jpegifoffset; + + /* ...and process the data at the offset as JPEG */ + pdc_logg_cond(p->pdc, 1, trc_image, + "\tTIFF with OJPEG: switching to JPEG processing...\n"); + return pdf_process_JPEG_data(p, imageslot); + } + else + { + /* We must repeat the check here since we omitted the OJPEG + * case when we applied the test for the first time. + */ + if (extra != 0 || + (planarconfig == PLANARCONFIG_SEPARATE && components > 1)) + { + /* ignore the extra channels */ + image->components -= extra; + } + image->use_raw = pdc_false; + } + break; + + case COMPRESSION_NONE: + if (photometric == PHOTOMETRIC_MINISWHITE) + image->invert = !image->invert; + + image->compression = pdf_comp_none; + break; + + case COMPRESSION_LZW: + if (TIFFGetField(MYTIFF, TIFFTAG_PREDICTOR, &predictor)) { + if (predictor != pred_default && predictor != pred_tiff) { + image->use_raw = pdc_false; + break; + } else + image->predictor = (pdf_predictor) predictor; + } + + if (photometric == PHOTOMETRIC_MINISWHITE) + image->invert = !image->invert; + + image->compression = pdf_comp_lzw; + break; + + case COMPRESSION_PACKBITS: + if (photometric == PHOTOMETRIC_MINISWHITE) + image->invert = !image->invert; + + image->compression = pdf_comp_runlength; + break; + + case COMPRESSION_DEFLATE: + case COMPRESSION_ADOBE_DEFLATE: + if (TIFFGetField(MYTIFF, TIFFTAG_PREDICTOR, &predictor)) { + if (predictor != pred_default && predictor != pred_tiff) { + image->use_raw = pdc_false; + break; + } else + image->predictor = (pdf_predictor) predictor; + } + + if (photometric == PHOTOMETRIC_MINISWHITE) + image->invert = !image->invert; + + image->compression = pdf_comp_flate; + break; + + default: + image->use_raw = pdc_false; + } + } + + if (image->use_raw) + { + /* pass-through mode: directly copy chunks of strip data */ + image->strips = strips; + + pdc_logg_cond(p->pdc, 1, trc_image, "\tpassthrough mode...\n"); + } + else + { + /* libtiff cannot handle JPEG-compressed TIFFs with separate image + * planes + */ + if (planarconfig == PLANARCONFIG_SEPARATE && + (compression == COMPRESSION_OJPEG || compression==COMPRESSION_JPEG)) + { + errcode = PDF_E_TIFF_UNSUPP_JPEG_SEPARATE; + goto PDF_TIFF_ERROR; + } + + /* Fallback: use TIFFlib to retrieve pixel data */ + + /* We have special handling for preserving bpc=1 if components=1, + * and therefore don't change bpc in this case. + */ + if (!(image->components == 1 && image->bpc == 1)) + { + /* Retrieve pixel data with libtiff, which converts to 8 bits. */ + image->bpc = 8; + } + + image->strips = 1; + image->compression = pdf_comp_none; + + /* Palette images are automatically converted to RGB by TIFFlib. + * Since there are actually 1-bit images (photometric=min-is-white) + * with a palette out there (which are invalid TIFF, and are not + * converted to RGB by TIFFlib) we must also check photometric. + */ + if (image->components == 1 && photometric == PHOTOMETRIC_PALETTE && + TIFFGetField(MYTIFF, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) + { + image->components = 3; + } + pdc_logg_cond(p->pdc, 1, trc_image, "\tno passthrough mode...\n"); + } + + if (image->imagemask) + { + if (image->components != 1) + { + errcode = PDF_E_IMAGE_BADMASK; + goto PDF_TIFF_ERROR; + } + + if (p->compatibility == PDC_1_3) + { + if (image->components != 1 || image->bpc != 1) + { + errcode = PDF_E_IMAGE_MASK1BIT13; + goto PDF_TIFF_ERROR; + } + } + else if (image->bpc > 1) + { + /* images with more than one bit will be written as /SMask, + * and don't require an /ImageMask entry. + */ + image->imagemask = pdc_false; + } + } + + if (image->mask != pdc_undef) + { + if (image->strips != 1) + { + errcode = PDF_E_TIFF_MASK_MULTISTRIP; + goto PDF_TIFF_ERROR; + } + } + + if (image->colorspace == pdc_undef) + { + uint16 inkset; + + switch (image->components) + { + case 1: + image->colorspace = DeviceGray; + break; + + case 3: + image->colorspace = DeviceRGB; + break; + + case 4: + if (photometric == PHOTOMETRIC_SEPARATED) + { + /* Can't handle CMYK with mask */ + if (extra != 0) + { + errint = image->components; + errcode = PDF_E_TIFF_CMYK_MASK; + goto PDF_TIFF_ERROR; + } + + TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) + { + errint = inkset; + errcode = PDF_E_TIFF_UNSUPP_SEP_NONCMYK; + goto PDF_TIFF_ERROR; + } + image->colorspace = DeviceCMYK; + } + else + { + /* if it's not separated it must be RGB with alpha */ + image->components = 3; + image->colorspace = DeviceRGB; + image->compression = pdf_comp_none; + } + break; + + default: + errint = image->components; + errcode = PDF_E_IMAGE_BADCOMP; + goto PDF_TIFF_ERROR; + } + } + + + image->src.private_data = (void *) image; + image->src.init = pdf_data_source_TIFF_init; + image->src.fill = pdf_data_source_TIFF_fill; + image->src.terminate = pdf_data_source_TIFF_terminate; + + if (image->use_raw) { + uint32 row, rowsperstrip; + int strip; + + /* must handle colormap ourselves */ + if (photometric == PHOTOMETRIC_PALETTE) + { + int i; + pdf_colormap colormap; + + if (!TIFFGetField(MYTIFF, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) + { + errcode = PDF_E_IMAGE_COLORMAP; + goto PDF_TIFF_ERROR; + } + + cs.type = Indexed; + cs.val.indexed.palette_size = 1 << bpc; + cs.val.indexed.colormap = &colormap; + cs.val.indexed.colormap_id = PDC_BAD_ID; + + cs.val.indexed.base = DeviceRGB; + +#define CVT(x) (uint16) (((x) * 255) / ((1L<<16)-1)) + /* TODO: properly deal with 16-bit palette entries in PDF 1.5 */ + if (pdf_check_colormap(cs.val.indexed.palette_size, + rmap, gmap, bmap) == 16) + { + /* convert colormap to 8 bit values */ + for (i = 0; i < cs.val.indexed.palette_size; i++) + { + rmap[i] = CVT(rmap[i]); + gmap[i] = CVT(gmap[i]); + bmap[i] = CVT(bmap[i]); + } + } +#undef CVT + + for (i = 0; i < cs.val.indexed.palette_size; i++) + { + colormap[i][0] = (pdc_byte) rmap[i]; + colormap[i][1] = (pdc_byte) gmap[i]; + colormap[i][2] = (pdc_byte) bmap[i]; + } + + image->components = 1; + + slot = pdf_add_colorspace(p, &cs, pdc_false); + image->colorspace = slot; + + + } + + + + if (image->strips > image->height) + image->strips = (int) image->height; + + if (TIFFGetFieldDefaulted(MYTIFF, + TIFFTAG_ROWSPERSTRIP, &rowsperstrip) == 1 && (int)rowsperstrip!= -1) + image->rowsperstrip = (int) rowsperstrip; + else + image->rowsperstrip = (int) image->height; + + /* + * The first strip must be handled separately because it carries the + * colormap for indexed images. Other strips reuse this colormap. + */ + image->info.tiff.cur_line = 0; + image->height = (pdc_scalar) + (image->rowsperstrip > (int) h ? (int) h : image->rowsperstrip); + + /* + * Images may also be written to the output before the first page + * We do this ourselves (instead of in pdf_put_image() to avoid + * many empty contents sections for multi-strip images. + */ + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_end_contents_section(p); + + pdf_put_image(p, imageslot, pdc_true, pdc_false); + + for (row = (uint32) image->rowsperstrip, strip = 1; + row < h; row += (uint32) image->rowsperstrip, strip++) { + + image->height = (pdc_scalar) (row+image->rowsperstrip > h ? + (int) (h - row) : image->rowsperstrip); + + /* + * tell pdf_data_source_TIFF_fill() to read only data of the + * current strip + */ + image->info.tiff.cur_line = strip; + pdf_put_image(p, imageslot, pdc_false, pdc_false); + } + + image->height = (pdc_scalar) h; + image->no -= (image->strips - 1); /* number of first strip */ + + /* Special handling for multi-strip images (see comment above) */ + if (PDF_GET_STATE(p) == pdf_state_page) + pdf_begin_contents_section(p); + + } else { /* !use_raw */ + size_t npixels; + + + + /* + * Retrieve full scan lines from TIFFlib for these color spaces, + * and Gray, RGB, or CMYK pixel data otherwise. + */ + if (p->colorspaces[image->colorspace].type == DeviceCMYK || + (p->colorspaces[image->colorspace].type == ICCBased && + image->components == 4)) + { + pdc_logg_cond(p->pdc, 1, trc_image, + "\tRetrieving full scan lines in native color space...\n"); + image->pixelmode = pdc_false; + } + else + { + pdc_logg_cond(p->pdc, 1, trc_image, + "\tRetrieving converted pixel data (pixel mode)...\n"); + image->pixelmode = pdc_true; + } + + if (image->pixelmode) + { + npixels = (size_t) (w * h); + + image->info.tiff.raster = (uint32 *) pdc_malloc(p->pdc, + (size_t) (npixels * sizeof (uint32)), fn); + + if (!TIFFReadRGBAImageOriented(MYTIFF, + w, h, image->info.tiff.raster, orientation, 1)) + { + errcode = PDC_E_IO_READ; + goto PDF_TIFF_ERROR; + } + } + else + { + int linecounter = 0; + + npixels = (size_t) (TIFFScanlineSize(MYTIFF) * h); + image->info.tiff.raster = (uint32 *) + pdc_malloc(p->pdc, (size_t) npixels, fn); + + while (linecounter < image->height) + { + if (TIFFReadScanline(MYTIFF, + (tdata_t) (image->info.tiff.raster + + ((int)image->height - linecounter - 1) * (int)image->width), + (uint32) linecounter, (tsample_t) 0) == -1) + { + errcode = PDC_E_IO_READ; + goto PDF_TIFF_ERROR; + } + linecounter++; + } + } + + pdf_put_image(p, imageslot, pdc_true, pdc_true); + + if (image->info.tiff.raster != NULL) + pdc_free(p->pdc, (void *) image->info.tiff.raster); + } + + image->in_use = pdc_true; /* mark slot as used */ + + if (!image->corrupt) + { + TIFFClose(MYTIFF); + return imageslot; + } + + PDF_TIFF_ERROR: + { + const char *stemp = NULL; + + if (errcode) + stemp = pdf_get_image_filename(p, image); + + if (image->info.tiff.raster != NULL) + pdc_free(p->pdc, (void *) image->info.tiff.raster); + + if (isopen) + TIFFClose(MYTIFF); + + switch (errcode) + { + case PDC_E_IO_READ: + case PDF_E_IMAGE_ICC: + case PDF_E_IMAGE_ICC2: + case PDF_E_IMAGE_MASK1BIT13: + case PDF_E_IMAGE_COLORIZE: + case PDF_E_TIFF_MASK_MULTISTRIP: + case PDF_E_IMAGE_COLORMAP: + case PDF_E_IMAGE_BADMASK: + case PDF_E_TIFF_CMYK_MASK: + case PDF_E_TIFF_UNSUPP_JPEG_SEPARATE: + case PDF_E_TIFF_16BITCMYK_UNSUPP: + case PDF_E_TIFF_16BIT_UNSUPP: + pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0); + break; + + case PDF_E_IMAGE_CORRUPT: + pdc_set_errmsg(p->pdc, errcode, "TIFF", stemp, 0, 0); + break; + + case PDF_E_TIFF_UNSUPP_COLORSPACE: + case PDF_E_TIFF_UNSUPP_COMPRESSION: + case PDF_E_IMAGE_BADCOMP: + pdc_set_errmsg(p->pdc, errcode, + pdc_errprintf(p->pdc, "%d", errint), stemp, 0, 0); + break; + + case PDF_E_IMAGE_NOPAGE: + pdc_set_errmsg(p->pdc, errcode, + pdc_errprintf(p->pdc, "%d", errint), "TIFF", stemp, 0); + break; + + case PDF_E_TIFF_UNSUPP_SEP_NONCMYK: + pdc_set_errmsg(p->pdc, errcode, + stemp, pdc_errprintf(p->pdc, "%d", errint), 0, 0); + break; + + case 0: /* error code and message already set */ + break; + } + } + + return -1; +} + +#undef MYTIFF +#endif /* HAVE_LIBTIFF */ diff --git a/src/pdflib/pdflib/p_truetype.c b/src/pdflib/pdflib/p_truetype.c new file mode 100644 index 0000000..80f2f10 --- /dev/null +++ b/src/pdflib/pdflib/p_truetype.c @@ -0,0 +1,301 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_truetype.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib TrueType handling routines + * + */ + +#include "p_intern.h" +#include "p_font.h" + +#include "ft_truetype.h" + +#ifdef PDF_TRUETYPE_SUPPORTED + + +pdc_bool +pdf_get_metrics_tt(PDF *p, pdf_font *font, const char *fontname, + pdc_encoding enc, const char *filename) +{ + pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_font); + pdc_bool logg2 = pdc_logg_is_enabled(p->pdc, 2, trc_font); + int filesize = 0; + double kbfilesize = 0; + int foundglyphs, flags = 0; + tt_file *ttf; + pdc_bool retval; + pdc_encoding enc_req; + pdc_encodingvector *ev = NULL; + pdc_bool isotf; + int errcode = 0; + + (void) logg2; + + /* + * Initialisation + */ + ttf = fnt_new_tt(p->pdc, &font->ft); + ttf->filename = filename; + ttf->fontname = fontname; + ttf->verbose = font->verbose; + ttf->incore = pdc_true; + ttf->monospace = font->opt.monospace; + filesize = font->ft.filelen; + kbfilesize = filesize / 1024.0; + + /* + * Read font file + */ + retval = fnt_read_tt(ttf); + if (retval == pdc_false) + goto PDF_TRUETYPE_ERROR2; + + /* + * Font type + */ + if (ttf->tab_CFF_) + { + isotf = pdc_true; + font->ft.m.type = fnt_Type1C; + font->cff_offset = (long) ttf->tab_CFF_->offset; + font->cff_length = ttf->tab_CFF_->length; + } + else + { + isotf = pdc_false; + font->ft.m.type = fnt_TrueType; + TT_IOCHECK(ttf, tt_tag2idx(ttf, fnt_str_glyf) != -1); + TT_IOCHECK(ttf, tt_tag2idx(ttf, fnt_str_loca) != -1); + } + + /* Number of Glyphs */ + if (ttf->numGlyphs <= 1) + { + errcode = FNT_E_TT_NOGLYFDESC; + goto PDF_TRUETYPE_ERROR1; + } + + + /* + * Encoding + */ + if (isotf) + { + /* OpenType font with CFF table */ + if (ttf->charcoll != cc_none) + { + /* CID font */ + if (font->ft.m.charcoll != cc_none) + { + if (!ttf->regisadobe) + { + errcode = PDF_E_CJK_UNSUPP_REGISTRY; + goto PDF_TRUETYPE_ERROR1; + } + + if (font->ft.m.charcoll != ttf->charcoll) + { + errcode = PDF_E_CJK_UNSUPP_CHARCOLL; + goto PDF_TRUETYPE_ERROR1; + } + + + if (font->outcmapname != NULL) + enc = pdc_cid; + + if (logg1) + pdc_logg(p->pdc, "\tCID font ordering: \"%s\"\n", + fnt_get_ordering_cid(ttf->charcoll)); + } + else if (enc == pdc_unicode || enc == pdc_glyphid) + { + font->ft.m.charcoll = ttf->charcoll; + font->supplement = ttf->supplement; + } + else + { + errcode = PDF_E_FONT_ONLY_CMAP; + goto PDF_TRUETYPE_ERROR1; + } + } + else if (font->ft.m.charcoll != cc_none) + { + /* SID font */ + errcode = PDF_E_FONT_UNSUPP_CMAP; + goto PDF_TRUETYPE_ERROR1; + } + } + else + { + if (font->ft.m.charcoll != cc_none) + { + int i; + pdc_bool iscjk = pdc_false; + + for (i = 0; i < PDC_NUMCHARCOLL; i++) + { + if (ttf->tab_OS_2->charcolls[i]) + iscjk = pdc_true; + + if (ttf->tab_OS_2->charcolls[i] == font->ft.m.charcoll) + break; + } + if (i == PDC_NUMCHARCOLL) + { + if (iscjk) + { + /* CJK font */ + errcode = PDF_E_CJK_UNSUPP_CHARCOLL; + goto PDF_TRUETYPE_ERROR1; + } + else + { + /* no CJK font */ + errcode = PDF_E_FONT_UNSUPP_CMAP; + goto PDF_TRUETYPE_ERROR1; + } + } + else + { + if (font->outcmapname != NULL) + { + ttf->charcoll = font->ft.m.charcoll; + enc = pdc_cid; + } + } + } + } + + /* encoding vector */ + enc_req = fnt_get_tt_encoding_key(ttf, enc); + if (enc_req == pdc_invalidenc) + { + errcode = FNT_E_TT_BADCMAP; + goto PDF_TRUETYPE_ERROR1; + } + else if (enc_req != enc) + { + if (strcmp(font->encapiname, "auto")) + { + pdc_warning(p->pdc, PDF_E_FONT_FORCEENC, + pdf_get_encoding_name(p, enc_req, NULL), + 0, 0, 0); + } + enc = enc_req; + } + if (enc >= 0) + ev = pdc_get_encoding_vector(p->pdc, enc); + font->ft.enc = enc; + font->ft.issymbfont = ttf->issymbol; + font->hasnomac = !ttf->tab_cmap || !ttf->tab_cmap->mac; + + + /* builtin encoding */ + if (enc == pdc_builtin) + { + if (font->ft.issymbfont == pdc_false) + { + errcode = PDF_E_FONT_BADENC; + goto PDF_TRUETYPE_ERROR1; + } + else + { + /* encoding vector for builtin */ + ev = pdf_create_font_encoding(p, enc, font, fontname, pdc_true); + font->symenc = font->ft.enc; + } + } + + { + /* optimizing PDF output */ + if (enc == pdc_ebcdic || + enc == pdc_ebcdic_37 || + enc == pdc_ebcdic_winansi) + font->towinansi = pdc_winansi; + + } + + /* /FontName in FontDescriptor */ + font->ft.m.name = pdc_strdup(p->pdc, ttf->tab_name->englishname4); + + /* /BaseFont name */ + font->ft.name = pdc_strdup(p->pdc, ttf->tab_name->englishname6); + + +#define PDF_RESTRICTED_TT_EMBEDDING 0x02 + /* check embedding flags */ + if ((font->opt.embedding) && ttf->tab_OS_2 && + ttf->tab_OS_2->fsType == PDF_RESTRICTED_TT_EMBEDDING) + { + errcode = FNT_E_TT_EMBED; + goto PDF_TRUETYPE_ERROR1; + } + + + if (logg1) + { + pdc_logg(p->pdc, + "\tFull font name: \"%s\"\n" + "\tPostScript font name: \"%s\"\n" + "\tFont embedding: %s\n", + font->ft.name, font->ft.m.name, + PDC_BOOLSTR(font->opt.embedding)); + + if (ttf->tab_name->producer != NULL) + pdc_logg(p->pdc, "\tFont producer: \"%s\"\n", + ttf->tab_name->producer); + + pdc_logg(p->pdc, "\tNumber of Glyphs: %d\n", ttf->numGlyphs); + } + + /* Save font values */ + fnt_set_tt_fontvalues(ttf); + + /* Flags for creating font arrays */ + flags = TT_FONT_code2gid | TT_FONT_m_widths; + + + /* Create font mapping and width arrays */ + foundglyphs = fnt_set_tt_fontarrays(ttf, flags); + + /***********************************/ + if (font->symenc != pdc_invalidenc) + font->ft.enc = pdc_builtin; + /***********************************/ + + if (!foundglyphs) + { + errcode = PDF_E_FONT_BADENC; + goto PDF_TRUETYPE_ERROR1; + } + + + fnt_delete_tt(ttf); + + if (!pdf_make_fontflag(p, font)) + return pdc_false; + + return pdc_true; + + PDF_TRUETYPE_ERROR1: + pdc_set_errmsg(p->pdc, errcode, 0, 0, 0, 0); + + PDF_TRUETYPE_ERROR2: + fnt_delete_tt(ttf); + + return pdc_false; +} + + +#endif /* PDF_TRUETYPE_SUPPORTED */ diff --git a/src/pdflib/pdflib/p_type1.c b/src/pdflib/pdflib/p_type1.c new file mode 100644 index 0000000..8483710 --- /dev/null +++ b/src/pdflib/pdflib/p_type1.c @@ -0,0 +1,427 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_type1.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib Type1 font handling routines + * + */ + +#include "pc_ctype.h" + +#include "p_intern.h" +#include "p_font.h" + + +/* Type 1 font portions: ASCII, encrypted, zeros */ +typedef enum { t1_ascii, t1_encrypted, t1_zeros } pdf_t1portion; + +typedef struct { + pdf_t1portion portion; + size_t length[4]; + pdc_file *fontfile; + pdc_byte *img; /* in-core Type1 font file image */ + pdc_byte *end; /* first byte above image buf */ + pdc_byte *pos; /* current "file" position */ +} t1_private_data; + +#define PFA_TESTBYTE 4 + +#define PDF_CURRENTFILE "currentfile eexec" + + +/* ---------------------------- General platforms --------------------------- */ + +#define LINEBUFLEN 256 + +/* + * PFA files are assumed to be encoded in host format. Therefore + * we must use literal strings and characters for interpreting the + * font file. + */ + +static int +PFA_data_fill(PDF *p, PDF_data_source *src) +{ + static const char *fn = "PFA_data_fill"; +#ifndef PDFLIB_EBCDIC + static const char HexToBin['F' - '0' + 1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, + 0, 10, 11, 12, 13, 14, 15 + }; +#else +#endif + char *s, *c; + int i; + int len; + t1_private_data *t1_private; + pdf_t1portion t1portion; + + t1_private = (t1_private_data *) src->private_data; + + if (src->buffer_start == NULL) + { + src->buffer_start = (pdc_byte *) pdc_malloc(p->pdc, LINEBUFLEN + 1, fn); + src->buffer_length = LINEBUFLEN; + } + + s = pdc_fgetline((char *) src->buffer_start, LINEBUFLEN, + t1_private->fontfile); + if (s == NULL) + return pdc_false; + + /* set unix line end */ + len = (int) strlen(s); + s[len] = '\n'; + len++; + s[len] = 0; + + /* check for line of zeros: set t1_zero flag if found */ + if (*s == '0') + { + for (i = 0; s[i] == '0'; i++) + { + /* */ ; + } + if (s[i] == '\n') + t1_private->portion = t1_zeros; + } + + /* check whether font data portion follows: set t1_encrypted flag later */ + t1portion = t1_private->portion; + if (t1_private->portion != t1_encrypted && + !strncmp((const char *)s, PDF_CURRENTFILE, strlen(PDF_CURRENTFILE))) + t1portion = t1_encrypted; + + src->next_byte = src->buffer_start; + + switch (t1_private->portion) + { + case t1_ascii: + { + t1_private->length[1] += (size_t) len; + src->bytes_available = (size_t) len; + } + break; + + case t1_encrypted: + { + src->bytes_available = 0; + + /* Convert to upper case for safe binary conversion */ + for (c = s; *c != '\n'; c++) + { + *c = (char) pdc_toupper(*c); + } + + /* convert ASCII to binary in-place */ + for (i = 0; s[i] != '\n'; i += 2) + { + if ((!pdc_isxdigit(s[i]) && !pdc_isspace(s[i])) || + (!pdc_isxdigit(s[i+1]) && !pdc_isspace(s[i+1]))) + { + pdc_fclose(t1_private->fontfile); + pdc_error(p->pdc, PDF_E_FONT_CORRUPT, "PFA", "?", 0, 0); + } +#ifndef PDFLIB_EBCDIC + s[i/2] = (char) (16*HexToBin[s[i]-'0'] + HexToBin[s[i+1]-'0']); +#else +#endif + src->bytes_available++; + } + t1_private->length[2] += src->bytes_available; + } + break; + + case t1_zeros: + { + t1_private->length[3] += (size_t) len; + src->bytes_available = (size_t) len; + } + break; + } + + t1_private->portion = t1portion; + + return pdc_true; +} + +#define PFB_MARKER 0x80 +#define PFB_ASCII 1 +#define PFB_BINARY 2 +#define PFB_EOF 3 + +static int +pdf_t1getc(t1_private_data *t1) +{ + int val; + + if (t1->fontfile) + { + return pdc_fgetc(t1->fontfile); + } + val = (int) *t1->pos; + t1->pos++; + + return val; +} + +static pdc_bool +pdf_read_pfb_segment(PDF *p, PDF_data_source *src, t1_private_data *t1, int i) +{ + static const char *fn = "pdf_read_pfb_segment"; + size_t length, len; + + length = (size_t) (pdf_t1getc(t1) & 0xff); + length |= (size_t) (pdf_t1getc(t1) & 0xff) << 8; + length |= (size_t) (pdf_t1getc(t1) & 0xff) << 16; + length |= (size_t) (pdf_t1getc(t1) & 0xff) << 24; + + if (src->buffer_start) + pdc_free(p->pdc, (void *) src->buffer_start); + src->buffer_start = (pdc_byte *) pdc_malloc(p->pdc, length, fn); + + if (t1->fontfile) { + len = pdc_fread(src->buffer_start, 1, length, t1->fontfile); + } else { + len = length; + if (t1->pos + len > t1->end) + len = (unsigned int)(t1->end - t1->pos); + memcpy(src->buffer_start, t1->pos, len); + t1->pos += len; + } + + t1->length[i] = len; + src->next_byte = src->buffer_start; + src->bytes_available = len; + + return (len != length) ? pdc_true : pdc_false;; +} + +static int +PFB_data_fill(PDF *p, PDF_data_source *src) +{ + t1_private_data *t1; + unsigned char c, type; + pdc_bool err = pdc_false; + + t1 = (t1_private_data *) src->private_data; + + c = (unsigned char) pdf_t1getc(t1); + type = (unsigned char) pdf_t1getc(t1); + + if (t1->length[1] == (size_t) 0) { + if (c != PFB_MARKER || type != PFB_ASCII) { + err = pdc_true; + } else { + err = pdf_read_pfb_segment(p, src, t1, 1); + } + + } else if (t1->length[2] == (size_t) 0) { + if (c != PFB_MARKER || type != PFB_BINARY) { + err = pdc_true; + } else { + err = pdf_read_pfb_segment(p, src, t1, 2); + } + + } else if (t1->length[3] == 0) { + if (c != PFB_MARKER || type != PFB_ASCII) { + err = pdc_true; + } else { + err = pdf_read_pfb_segment(p, src, t1, 3); + } + } else if (c != PFB_MARKER || type != PFB_EOF) { + err = pdc_true; + } else { + return pdc_false; + } + + if (err) { + if (t1->fontfile) + pdc_fclose(t1->fontfile); + pdc_error(p->pdc, PDF_E_FONT_CORRUPT, "PFB", "?", 0, 0); + } + + return pdc_true; +} + +static void +t1data_terminate(PDF *p, PDF_data_source *src) +{ + pdc_free(p->pdc, (void *) src->buffer_start); +} + +static void +t1data_init(PDF *p, PDF_data_source *src) +{ + t1_private_data *t1_private; + + (void) p; + + t1_private = (t1_private_data *) src->private_data; + + t1_private->portion = t1_ascii; + t1_private->length[1] = (size_t) 0; + t1_private->length[2] = (size_t) 0; + t1_private->length[3] = (size_t) 0; + + src->buffer_start = NULL; +} + + +pdc_bool +pdf_t1open_fontfile(PDF *p, pdf_font *font, const char *filename, + PDF_data_source *t1src, pdc_bool requested) +{ + static const char *fn = "pdf_t1open_fontfile"; + t1_private_data *t1_private = NULL; + pdc_file *fp = NULL; + const char *stemp = NULL; + unsigned char magic[PFA_TESTBYTE]; + char fullname[PDC_FILENAMELEN]; + int fflags = PDC_FILE_BINARY; + int ispfb = pdc_true; + + if (filename) + { + + fp = pdc_fsearch_fopen(p->pdc, filename, fullname, "PostScript Type1 ", + fflags); + if (fp == NULL) + { + if (t1src) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + return pdc_check_fopen_errmsg(p->pdc, requested); + } + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tLoading PostScript Type1 fontfile \"%s\":\n", fullname); + + } + + if (fp) + { + pdc_fread(magic, 1, PFA_TESTBYTE, fp); + stemp = filename; + } + else if (font->ft.img) + { + strncpy((char *) magic, (const char *)font->ft.img, PFA_TESTBYTE); + stemp = font->ft.name; + } + + /* try to identify PFA files */ + if (magic[0] != PFB_MARKER) + { + char startsequ[PFA_TESTBYTE + 1]; + + strcpy(startsequ, FNT_PFA_STARTSEQU); + + if (strncmp((const char *) magic, startsequ, PFA_TESTBYTE)) + { + if (fp) + pdc_fclose(fp); + pdc_set_errmsg(p->pdc, PDF_E_T1_NOFONT, stemp, 0, 0, 0); + if (t1src) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + return pdc_false; + } + ispfb = pdc_false; + } + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tPostScript Type1 font of format \"%s\" detected\n", + ispfb ? "PFB" : "PFA"); + + if (t1src) + { + t1src->private_data = (unsigned char *) + pdc_malloc(p->pdc, sizeof(t1_private_data), fn); + t1_private = (t1_private_data *) t1src->private_data; + + if (filename) + { + pdc_fclose(fp); + if (ispfb) + { + t1_private->fontfile = + pdc_fsearch_fopen(p->pdc, fullname, NULL, "PFB ", fflags); + } + else + { + t1_private->fontfile = + pdc_fsearch_fopen(p->pdc, fullname, NULL, "PFA ", + PDC_FILE_TEXT); + } + + if (t1_private->fontfile == NULL) + pdc_error(p->pdc, -1, 0, 0, 0, 0); + } + else if (font->ft.img) + { + t1_private->fontfile = NULL; + t1_private->img = font->ft.img; + t1_private->pos = font->ft.img; + t1_private->end = font->ft.img + font->ft.filelen; + } + + t1src->init = t1data_init; + t1src->fill = ispfb ? PFB_data_fill : PFA_data_fill; + t1src->terminate = t1data_terminate; + } + else if (fp != NULL) + { + if (pdc_file_isvirtual(fp) == pdc_true) + { + if (ispfb) + font->ft.img = + (pdc_byte *) pdc_freadall(fp, &font->ft.filelen, NULL); + font->ft.imgname = pdc_strdup(p->pdc, fullname); + pdc_lock_pvf(p->pdc, font->ft.imgname); + } + font->ft.filename = pdc_strdup(p->pdc, fullname); + pdc_fclose(fp); + } + + return pdc_true; +} + +pdc_bool +pdf_make_t1src (PDF *p, pdf_font *font, PDF_data_source *t1src) +{ + return pdf_t1open_fontfile(p, font, font->filename, t1src, pdc_true); +} + +void +pdf_put_length_objs(PDF *p, PDF_data_source *t1src, + pdc_id length1_id, pdc_id length2_id, pdc_id length3_id) +{ + pdc_begin_obj(p->out, length1_id); /* Length1 object */ + pdc_printf(p->out, "%ld\n", + (long) ((t1_private_data *) t1src->private_data)->length[1]); + pdc_end_obj(p->out); + + pdc_begin_obj(p->out, length2_id); /* Length2 object */ + pdc_printf(p->out, "%ld\n", + (long) ((t1_private_data *) t1src->private_data)->length[2]); + pdc_end_obj(p->out); + + pdc_begin_obj(p->out, length3_id); /* Length3 object */ + pdc_printf(p->out, "%ld\n", + (long) ((t1_private_data *) t1src->private_data)->length[3]); + pdc_end_obj(p->out); + + if (((t1_private_data *) t1src->private_data)->fontfile) + pdc_fclose(((t1_private_data *) t1src->private_data)->fontfile); + + pdc_free(p->pdc, (void *) t1src->private_data); +} diff --git a/src/pdflib/pdflib/p_type3.c b/src/pdflib/pdflib/p_type3.c new file mode 100644 index 0000000..411bd0d --- /dev/null +++ b/src/pdflib/pdflib/p_type3.c @@ -0,0 +1,740 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_type3.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Routines for Type 3 (user-defined) fonts + * + */ + +#include "p_intern.h" +#include "p_font.h" +#include "p_image.h" + +int +pdf_get_t3colorized(PDF *p) +{ + return p->fonts[p->t3slot].t3font->colorized; +} + +static void +pdf_init_t3font(PDF *p, pdf_t3font *t3font, int glyph_capacity) +{ + static char fn[] = "pdf_init_t3font"; + int i; + + /* statement order is critical for cleanup! + */ + t3font->curr_glyph = 0; + t3font->next_glyph = 0; + t3font->capacity = glyph_capacity; + t3font->glyphs = (pdf_t3glyph *) + pdc_malloc(p->pdc, t3font->capacity * sizeof (pdf_t3glyph), fn); + + for (i = 0; i < t3font->capacity; i++) + t3font->glyphs[i].name = NULL; + + t3font->charprocs_id = PDC_BAD_ID; + t3font->pass = 0; + +} + +void +pdf_cleanup_t3font(PDF *p, pdf_t3font *t3font) +{ + int i; + + for (i = 0; i < t3font->next_glyph; i++) + { + if (t3font->glyphs[i].name) + { + pdc_free(p->pdc, t3font->glyphs[i].name); + t3font->glyphs[i].name = NULL; + } + } + + pdc_free(p->pdc, t3font->glyphs); + t3font->glyphs = NULL; +} + +static void +pdf_type3_protocol(PDF *p, pdf_font *font, pdc_encodingvector *ev) +{ + /* logging protocol */ + if (pdc_logg_is_enabled(p->pdc, 2, trc_font)) + { + char *glyphname; + pdc_ushort uv = 0; + int gid, code, width = 0; + + for (gid = 0; gid < font->t3font->next_glyph; gid++) + { + glyphname = NULL; + + pdc_logg(p->pdc, "\t\tGlyph%4d: ", gid); + + if (ev != NULL) + { + code = font->ft.gid2code[gid]; + uv = ev->codes[code]; + if (glyphname == NULL) + glyphname = ev->chars[code]; + width = fnt_get_glyphwidth(code, &font->ft); + + pdc_logg(p->pdc, "code=%3d ", code); + } + + if (width == FNT_MISSING_WIDTH) + width = 0; + + pdc_logg(p->pdc, "U+%04X width=%4d \"%s\"\n", + uv, width, glyphname); + } + } +} + +/* + * We found a Type 3 font in the cache, but its encoding doesn't match. + * Make a copy of the font in a new slot, and attach the new encoding. + */ + +pdc_bool +pdf_handle_t3font(PDF *p, const char *fontname, pdc_encoding enc, + pdf_font *font, int *slot) +{ + static const char fn[] = "pdf_handle_t3font"; + const char *encname; + char *fname; + size_t namlen; + pdf_font *deffont = &p->fonts[*slot]; + pdc_encodingvector *ev = pdc_get_encoding_vector(p->pdc, enc); + fnt_font_metric *ftm = &font->ft.m; + size_t nalloc; + int code, gid; + pdc_bool newinst = pdc_false; + + /* font name incl. encoding name */ + encname = pdc_get_user_encoding(p->pdc, enc); + namlen = strlen(fontname) + strlen(encname) + 2; + fname = (char *) pdc_malloc(p->pdc, namlen, fn); + pdc_sprintf(p->pdc, pdc_false, fname, "%s.%s", fontname, encname); + + /* we have to copy the available font. + * otherwise the original font will be changed + */ + newinst = deffont->ft.enc != pdc_invalidenc; + + pdc_logg_cond(p->pdc, 1, trc_font, + "\n\tType3 font \"%s\" with %d glyphs found\n", + fontname, deffont->t3font->next_glyph); + + if (newinst) + { + pdc_logg_cond(p->pdc, 1, trc_font, + "\tInstance with specified encoding will be created\n"); + + } + + /* copy data from available font (see pdf__begin_font()) */ + font->ft.m.type = fnt_Type3; + font->ft.matrix = deffont->ft.matrix; + font->t3font = deffont->t3font; + font->ft.numglyphs = deffont->t3font->next_glyph; + nalloc = (size_t) font->ft.numglyphs; + + ftm->name = fname; + font->ft.name = pdc_strdup(p->pdc, fname); + font->ft.enc = enc; + font->ft.issymbfont = pdc_false; + font->opt.embedding = pdc_true; + + if (enc >= pdc_winansi) + { + font->codesize = 1; + font->ft.numcodes = 256; + font->lastcode = -1; + + ftm->widths = (int *) pdc_calloc(p->pdc, + (size_t) font->ft.numcodes * sizeof(int), fn); + ftm->numwidths = font->ft.numcodes; + } + + font->ft.code2gid = (pdc_ushort *) pdc_calloc(p->pdc, + (size_t) font->ft.numcodes * sizeof(pdc_ushort), fn); + + font->ft.gid2code = (pdc_ushort *) pdc_calloc(p->pdc, + nalloc * sizeof (pdc_ushort), fn); + + /* fill up font arrays */ + for (gid = 0; gid < font->ft.numglyphs; gid++) + { + const char *str = NULL, *glyphname = font->t3font->glyphs[gid].name; + + if (enc >= pdc_winansi) + { + /* search for code */ + for (code = 0; code < font->ft.numcodes; code++) + { + if (ev->chars[code] != NULL) + str = ev->chars[code]; + else if (ev->codes[code]) + str = pdc_unicode2glyphname(p->pdc, ev->codes[code]); + + if (str != NULL && !pdc_strcmp(glyphname, str)) + break; + } + + /* code found */ + if (code < font->ft.numcodes) + { + font->ft.code2gid[code] = gid; + font->ft.gid2code[gid] = code; + + if (!gid) + font->gid0code = code; + + if (font->opt.monospace) + ftm->widths[code] = font->opt.monospace; + else + ftm->widths[code] = + (int) (font->t3font->glyphs[gid].width + 0.5); + } + } + } + + + pdf_type3_protocol(p, font, ev); + + /* font flags */ + if (!pdf_make_fontflag(p, font)) + return pdc_false; + + if (newinst) + { + *slot = -1; + } + else + { + if (deffont->apiname != NULL) + pdc_free(p->pdc, deffont->apiname); + *deffont = *font; + deffont->hasoriginal = pdc_true; + } + + return pdc_true; +} + +pdc_bool +pdf_isvalid_font(PDF *p, int slot) +{ + if (slot > -1 && slot < p->fonts_number) + { + pdf_font *font = &p->fonts[slot]; + if (!font->opt.auxiliary && + (font->t3font == NULL || font->t3font->pass != 2)) + return pdc_true; + } + + return pdc_false; +} + +#define PDF_FAMILYNAME_FLAG PDC_OPT_UNSUPP +#define PDF_STRETCH_FLAG PDC_OPT_UNSUPP +#define PDF_WEIGHT_FLAG PDC_OPT_UNSUPP + +/* + * internal font stretch values + */ +#define PDF_FS_ULTRACONDENSED 1 +#define PDF_FS_EXTRACONDENSED 2 +#define PDF_FS_CONDENSED 3 +#define PDF_FS_SEMICONDENSED 4 +#define PDF_FS_NORMAL 5 +#define PDF_FS_SEMIEXPANDED 6 +#define PDF_FS_EXPANDED 7 +#define PDF_FS_EXTRAEXPANDED 8 +#define PDF_FS_ULTRAEXPANDED 9 + +static const pdc_keyconn pdf_fontstretch_keylist[] = +{ + {"UltraCondensed", PDF_FS_ULTRACONDENSED}, + {"ExtraCondensed", PDF_FS_EXTRACONDENSED}, + {"Condensed", PDF_FS_CONDENSED}, + {"SemiCondensed", PDF_FS_SEMICONDENSED}, + {"Normal", PDF_FS_NORMAL}, + {"SemiExpanded", PDF_FS_SEMIEXPANDED}, + {"Expanded", PDF_FS_EXPANDED}, + {"ExtraExpanded", PDF_FS_EXTRAEXPANDED}, + {"UltraExpanded", PDF_FS_ULTRAEXPANDED}, + {NULL, 0} +}; + +/* conf. with fnt_fontweight_keylist[] in ft_font.c */ +static const pdc_keyconn pdf_fontweight_keylist[] = +{ + {"thin", FNT_FW_THIN}, + {"extralight", FNT_FW_EXTRALIGHT}, + {"light", FNT_FW_LIGHT}, + {"normal", FNT_FW_NORMAL}, + {"medium", FNT_FW_MEDIUM}, + {"semibold", FNT_FW_SEMIBOLD}, + {"bold", FNT_FW_BOLD}, + {"extrabold", FNT_FW_EXTRABOLD}, + {"black", FNT_FW_BLACK}, + {NULL, 0} +}; + +/* definitions of begin font options */ +static const pdc_defopt pdf_begin_font_options[] = +{ + {"colorized", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"widthsonly", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL}, + + {"familyname", pdc_stringlist, PDF_FAMILYNAME_FLAG, 1, 1, + 1.0, PDF_MAX_FONTNAME, NULL}, + + {"stretch", pdc_keywordlist, PDF_STRETCH_FLAG, 1, 1, + 0.0, 0.0, pdf_fontstretch_keylist}, + + {"weight", pdc_keywordlist, PDF_WEIGHT_FLAG, 1, 1, + 0.0, 0.0, pdf_fontweight_keylist}, + + PDC_OPT_TERMINATE +}; + +void +pdf__begin_font( + PDF *p, + const char *fontname, int len, + pdc_scalar a, pdc_scalar b, pdc_scalar c, pdc_scalar d, + pdc_scalar e, pdc_scalar f, + const char *optlist) +{ + static const char fn[] = "pdf__begin_font"; + char *fname; + pdc_resopt *results; + pdf_font tmpfont, *font; + pdf_font_options fo; + pdc_scalar det; + pdc_clientdata cdata; + int colorized = pdc_false; + int metricsonly = pdc_false; + int slot; + + if (fontname == NULL) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0); + + /* Converting fontname */ + fname = pdf_convert_name(p, fontname, len, PDC_CONV_WITHBOM); + if (fname == NULL || *fname == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "fontname", 0, 0, 0); + fontname = pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, fname); + pdc_free(p->pdc, fname); + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tBegin of Type3 font \"%s\"\n", fontname); + + /* error message prefix */ + pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, fontname, 0, 0, 0); + + /* look for an already existing font */ + for (slot = 0; slot < p->fonts_number; slot++) + { + if (!pdc_strcmp(p->fonts[slot].apiname, fontname)) + { + if (p->fonts[slot].t3font->pass == 1) + { + pdc_logg_cond(p->pdc, 1, trc_font, + "\tType3 font [%d] with metric definition found\n", slot); + + PDF_CHECK_STATE(p, pdf_state_document); + + p->fonts[slot].t3font->pass = 2; + p->t3slot = slot; + + pdc_pop_errmsg(p->pdc); + + pdf_pg_suspend(p); + PDF_SET_STATE(p, pdf_state_font); + return; + } + + pdc_error(p->pdc, PDF_E_T3_FONTEXISTS, 0, 0, 0, 0); + } + } + + pdc_check_number(p->pdc, "a", a); + pdc_check_number(p->pdc, "b", b); + pdc_check_number(p->pdc, "c", c); + pdc_check_number(p->pdc, "d", d); + pdc_check_number(p->pdc, "e", e); + pdc_check_number(p->pdc, "f", f); + + det = a*d - b*c; + + if (det == 0) + pdc_error(p->pdc, PDC_E_ILLARG_MATRIX, + pdc_errprintf(p->pdc, "%f %f %f %f %f %f", a, b, c, d, e, f), + 0, 0, 0); + + /* parsing optlist */ + pdf_set_clientdata(p, &cdata); + results = pdc_parse_optionlist(p->pdc, optlist, pdf_begin_font_options, + &cdata, pdc_true); + + pdc_get_optvalues("colorized", results, &colorized, NULL); + pdc_get_optvalues("widthsonly", results, &metricsonly, NULL); + + + pdc_cleanup_optionlist(p->pdc, results); + + /* initialize font struct */ + font = &tmpfont; + pdf_init_font_options(p, &fo); + pdf_init_font(p, font, &fo); + + /* + * We store the new font in a font slot marked with "invalidenc" encoding. + * When the font is used for the first time we modify the encoding. + * Later uses will make a copy if the encoding is different. + */ + + /* API font name */ + font->apiname = pdc_strdup(p->pdc, fontname); + + font->ft.m.type = fnt_Type3; + font->hasoriginal = pdc_true; + + font->ft.matrix.a = a; + font->ft.matrix.b = b; + font->ft.matrix.c = c; + font->ft.matrix.d = d; + font->ft.matrix.e = e; + font->ft.matrix.f = f; + + font->t3font = (pdf_t3font*) pdc_malloc(p->pdc, sizeof(pdf_t3font), fn); + pdf_init_t3font(p, font->t3font, T3GLYPHS_CHUNKSIZE); + + font->t3font->colorized = colorized; + + + /* the resource id is needed until the font dict is written */ + font->t3font->res_id = pdc_alloc_id(p->out); + + /* Now everything is fine, insert Type3 font with invalid encoding */ + slot = pdf_insert_font(p, font); + + /* + * We must store a pointer to the current font because its glyph + * definitions may use other fonts and we would be unable to find + * "our" current font again. This pointer lives throughout the + * font definition, and will be reset in PDF_end_font() below. + */ + p->t3slot = slot; + + if (metricsonly) + { + font->t3font->pass = 1; + pdc_logg_cond(p->pdc, 2, trc_font, + "\t\tonly for metric definition\n"); + } + else + { + pdf_pg_suspend(p); + } + + pdc_pop_errmsg(p->pdc); + + PDF_SET_STATE(p, pdf_state_font); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Begin font %d]\n", p->t3slot); +} + +void +pdf__end_font(PDF *p) +{ + int ig; + pdf_font *font; + pdf_t3font *t3font; + + PDF_SET_STATE(p, pdf_state_document); + + font = &p->fonts[p->t3slot]; + t3font = font->t3font; + + /* error message prefix */ + pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, font->apiname, 0, 0, 0); + + if (t3font->pass == 0) + { + pdf_t3glyph glyph0 = t3font->glyphs[0]; + + /* search for .notdef glyph */ + if (pdc_strcmp(glyph0.name, (char *) pdc_get_notdef_glyphname())) + { + for (ig = 0; ig < t3font->next_glyph; ig++) + { + if (!pdc_strcmp(t3font->glyphs[ig].name, + (char *) pdc_get_notdef_glyphname())) + break; + } + + if (ig < t3font->next_glyph) + { + pdc_logg_cond(p->pdc, 2, trc_font, + "\tGlyph id %d: \"%s\" will be exchanged " + "with glyph id 0: \"%s\"\n", + ig, t3font->glyphs[ig].name, glyph0.name); + + t3font->glyphs[0] = t3font->glyphs[ig]; + t3font->glyphs[ig] = glyph0; + } + else + { + pdc_warning(p->pdc, PDF_E_T3_MISSNOTDEF, 0, 0, 0, 0); + } + } + } + + if (t3font->pass != 1) + { + t3font->charprocs_id = pdc_alloc_id(p->out); + pdc_begin_obj(p->out, t3font->charprocs_id); /* CharProcs dict */ + pdc_begin_dict(p->out); + + for (ig = 0; ig < t3font->next_glyph; ig++) + { + pdf_t3glyph *glyph = &t3font->glyphs[ig]; + + if (glyph->charproc_id != PDC_BAD_ID) + { + pdf_put_pdfname(p, glyph->name); + pdc_objref(p->out, "", glyph->charproc_id); + } + } + + pdc_end_dict(p->out); + pdc_end_obj(p->out); /* CharProcs dict */ + + pdc_begin_obj(p->out, t3font->res_id); + pdc_begin_dict(p->out); /* Resource dict */ + + pdf_write_page_fonts(p); /* Font resources */ + + pdf_write_page_colorspaces(p); /* Color space resources */ + + pdf_write_page_pattern(p); /* Pattern resources */ + + pdf_write_xobjects(p); /* XObject resources */ + + pdc_end_dict(p->out); /* Resource dict */ + pdc_end_obj(p->out); /* Resource object */ + + pdf_pg_resume(p, -1); + + if (p->flush & pdc_flush_content) + pdc_flush_stream(p->out); + + /* see pdf__begin_glyph */ + pdf_init_tstate(p); + pdf_init_gstate(p); + pdf_init_cstate(p); + } + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tEnd of Type3 font \"%s\"\n", font->apiname); + + pdc_pop_errmsg(p->pdc); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[End font %d]\n", p->t3slot); + + p->t3slot = -1; +} + +void +pdf__begin_glyph( + PDF *p, + const char *glyphname, + pdc_scalar wx, + pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury) +{ + static const char fn[] = "pdf__begin_glyph"; + pdf_font *font; + pdf_t3font *t3font; + pdf_t3glyph *glyph = NULL; + int ig; + + if (glyphname == NULL || *glyphname == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "glyphname", 0, 0, 0); + + font = &p->fonts[p->t3slot]; + t3font = font->t3font; + + /* error message prefix */ + pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, font->apiname, 0, 0, 0); + + for (ig = 0; ig < t3font->next_glyph; ig++) + { + glyph = &t3font->glyphs[ig]; + if (!pdc_strcmp(glyph->name, glyphname)) + { + if (t3font->pass == glyph->pass) + pdc_error(p->pdc, PDF_E_T3_GLYPH, glyphname, 0, 0, 0); + else + break; + } + } + + /* new glyph */ + if (ig == t3font->next_glyph) + { + if (t3font->pass == 2) + pdc_error(p->pdc, PDF_E_T3_UNKOWNGLYPH, glyphname, 0, 0, 0); + + pdc_check_number(p->pdc, "wx", wx); + pdc_check_number(p->pdc, "llx", llx); + pdc_check_number(p->pdc, "lly", lly); + pdc_check_number(p->pdc, "urx", urx); + pdc_check_number(p->pdc, "ury", ury); + + if (t3font->colorized == pdc_true && + (llx != 0 || lly != 0 || + urx != 0 || ury != 0)) + pdc_error(p->pdc, PDF_E_T3_BADBBOX, 0, 0, 0, 0); + + if (ig == t3font->capacity) + { + t3font->capacity *= 2; + t3font->glyphs = (pdf_t3glyph *) pdc_realloc(p->pdc, t3font->glyphs, + t3font->capacity * sizeof (pdf_t3glyph), fn); + } + + glyph = &t3font->glyphs[ig]; + glyph->charproc_id = PDC_BAD_ID; + glyph->name = pdc_strdup(p->pdc, glyphname); + glyph->wx = wx; + glyph->llx = llx; + glyph->lly = lly; + glyph->urx = urx; + glyph->ury = ury; + + /* see comment in p_font.c for explanation */ + glyph->width = 1000 * wx * font->ft.matrix.a; + + /* if the strdup above fails, cleanup won't touch this slot. */ + t3font->next_glyph++; + } + glyph->pass = t3font->pass; + t3font->curr_glyph = ig; + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tBegin of Type3 font glyph \"%s\"\n", glyphname); + + if (t3font->pass != 1) + { + if (t3font->pass == 2) + pdc_logg_cond(p->pdc, 2, trc_font, + "\t\tglyph [%d] was used in text\n", ig); + + glyph->charproc_id = pdc_begin_obj(p->out, PDC_NEW_ID); + pdc_begin_dict(p->out); + + p->length_id = pdc_alloc_id(p->out); + pdc_objref(p->out, "/Length", p->length_id); + + if (pdc_get_compresslevel(p->out)) + pdc_puts(p->out, "/Filter/FlateDecode\n"); + + pdc_end_dict(p->out); + + pdc_begin_pdfstream(p->out); + + if (t3font->colorized == pdc_true) + pdc_printf(p->out, "%f 0 d0\n", glyph->wx); + else + { + pdc_printf(p->out, "%f 0 %f %f %f %f d1\n", + glyph->wx, glyph->llx, glyph->lly, glyph->urx, glyph->ury); + + /* adjust the font's bounding box */ + if (glyph->llx < font->ft.bbox.llx) + font->ft.bbox.llx = glyph->llx; + if (glyph->lly < font->ft.bbox.lly) + font->ft.bbox.lly = glyph->lly; + if (glyph->urx > font->ft.bbox.urx) + font->ft.bbox.urx = glyph->urx; + if (glyph->ury > font->ft.bbox.ury) + font->ft.bbox.ury = glyph->ury; + } + + /* we must initialize the text, graphics and color state + * otherwise the user get unpredictable appearance of a + * glyph because of optimizing outputting graphics properties. + * Following statements were inserted due to bug #719 + */ + pdf_init_tstate(p); + pdf_init_gstate(p); + pdf_init_cstate(p); + + PDF_SET_STATE(p, pdf_state_glyph); + } + else + { + PDF_SET_STATE(p, pdf_state_glyphmetric); + } + + pdc_pop_errmsg(p->pdc); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[Begin glyph %d]\n", ig); +} + +void +pdf__end_glyph(PDF *p) +{ + pdf_t3font *t3font = p->fonts[p->t3slot].t3font; + pdf_t3glyph *glyph = &t3font->glyphs[t3font->curr_glyph]; + int ig = t3font->curr_glyph; + + if (t3font->pass != 1 && glyph->charproc_id != PDC_BAD_ID) + { + /* check whether pdf__save() and pdf__restore() calls are balanced */ + if (p->curr_ppt->sl > 0) + pdc_error(p->pdc, PDF_E_GSTATE_UNMATCHEDSAVE, 0, 0, 0, 0); + + pdf_end_text(p); + pdc_end_pdfstream(p->out); /* glyph description stream */ + pdc_end_obj(p->out); /* glyph description */ + + pdc_put_pdfstreamlength(p->out, p->length_id); + } + + PDF_SET_STATE(p, pdf_state_font); + + pdc_logg_cond(p->pdc, 1, trc_font, + "\tEnd of Type3 font glyph \"%s\"\n", + t3font->glyphs[ig].name); + + if (!p->pdc->smokerun) + pdc_logg_cond(p->pdc, 1, trc_api, "[End glyph %d]\n", ig); +} + + +void +pdf_init_type3(PDF *p) +{ + p->t3slot = -1; +} + diff --git a/src/pdflib/pdflib/p_util.c b/src/pdflib/pdflib/p_util.c new file mode 100644 index 0000000..2728236 --- /dev/null +++ b/src/pdflib/pdflib/p_util.c @@ -0,0 +1,733 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_util.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib utility functions + * + */ + +#define P_UTIL_C + +#include "p_intern.h" +#include "p_font.h" +#include "p_image.h" +#include "p_layer.h" + + +/* ------------------------- [hyper]textformat -----------------------------*/ + +void +pdf_check_textformat(PDF *p, pdc_text_format textformat) +{ + if (!p->pdc->ptfrun && p->pdc->unicaplang && textformat != pdc_auto2) + pdc_error(p->pdc, PDF_E_ENC_UNSUPPENCFORMAT, "textformat", 0, 0, 0); + + pdc_logg_cond(p->pdc, 1, trc_encoding, "\tTextformat: \"%s\"\n", + pdc_get_keyword(textformat, pdf_textformat_keylist)); +} + +void +pdf_check_hypertextformat(PDF *p, pdc_text_format hypertextformat) +{ + if (!p->pdc->ptfrun && p->pdc->unicaplang && hypertextformat != pdc_auto2) + pdc_error(p->pdc, PDF_E_ENC_UNSUPPENCFORMAT, "hypertextformat", + 0, 0, 0); + + pdc_logg_cond(p->pdc, 1, trc_encoding, "\tHypertextformat: \"%s\"\n", + pdc_get_keyword(hypertextformat, pdf_textformat_keylist)); +} + + +/* ------------------------- hypertextencoding -----------------------------*/ + +void +pdf_check_hypertextencoding(PDF *p, pdc_encoding hypertextencoding) +{ + if (!p->pdc->ptfrun && p->pdc->unicaplang && + hypertextencoding != pdc_unicode) + pdc_error(p->pdc, PDF_E_ENC_UNSUPPENCFORMAT, "hypertextencoding", + 0, 0, 0); + + pdc_logg_cond(p->pdc, 1, trc_encoding, "\tHypertextencoding: \"%s\"\n", + pdc_get_user_encoding(p->pdc, hypertextencoding)); +} + + +/* ----------------------- string utility functions -----------------------*/ + +static void +pdf_set_convertflags(PDF *p, int *convflags) +{ + (void) p; + (void) convflags; + +} + +const char * +pdf__utf16_to_utf8(PDF *p, const char *utf16string, int len, int *size) +{ + char *utf8string; + int convflags = PDC_CONV_WITHBOM | PDC_CONV_EBCDIC | PDC_CONV_TRY7BYTES; + + pdf_set_convertflags(p, &convflags); + utf8string = pdc_utf16_to_utf8(p->pdc, utf16string, len, convflags, size); + + pdf_insert_utilstring(p, utf8string, pdc_false); + + return utf8string; +} + +const char * +pdf__utf32_to_utf16(PDF *p, const char *utf32string, int len, + const char *ordering, int *outlen) +{ + char *utf16string = pdc_utf32_to_utf16(p->pdc, utf32string, len, + ordering, 0, outlen); + + pdf_insert_utilstring(p, utf16string, pdc_false); + + return utf16string; +} + +const char * +pdf__utf8_to_utf16(PDF *p, const char *utf8string, const char *ordering, + int *outlen) +{ + char *utf16string; + int convflags = PDC_CONV_EBCDIC; + + pdf_set_convertflags(p, &convflags); + utf16string = pdc_utf8_to_utf16(p->pdc, utf8string, ordering, + convflags, outlen); + + pdf_insert_utilstring(p, utf16string, pdc_false); + + return utf16string; +} + +void +pdf_init_stringlists(PDF *p) +{ + p->stringlists_number = 0; + p->stringlists_capacity = 0; + p->stringlists = NULL; + p->stringlistsizes = NULL; + p->utilstrlist_index = -1; + p->utilstring_number = 0; +} + +int +pdf_insert_stringlist(PDF *p, char **stringlist, int ns) +{ + static const char fn[] = "pdf_insert_stringlist"; + int i; + + if (p->stringlists_number == p->stringlists_capacity) + { + int j = p->stringlists_capacity; + + if (!p->stringlists_capacity) + { + p->stringlists_capacity = STRINGLISTS_CHUNKSIZE; + + p->stringlists = (char ***) pdc_malloc(p->pdc, + sizeof(char **) * p->stringlists_capacity, fn); + + p->stringlistsizes = (int *) pdc_malloc(p->pdc, + sizeof(int) * p->stringlists_capacity, fn); + } + else + { + p->stringlists_capacity *= 2; + p->stringlists = (char ***) pdc_realloc(p->pdc, p->stringlists, + sizeof(char **) * p->stringlists_capacity, fn); + + p->stringlistsizes = (int *) pdc_realloc(p->pdc, p->stringlistsizes, + sizeof(int) * p->stringlists_capacity, fn); + } + for (i = j; i < p->stringlists_capacity; i++) + { + p->stringlists[i] = NULL; + p->stringlistsizes[i] = 0; + } + } + + i = p->stringlists_number; + p->stringlists[i] = stringlist; + p->stringlistsizes[i] = ns; + p->stringlists_number++; + + return i; +} + +void +pdf_cleanup_stringlists(PDF *p) +{ + int i; + + if (p->stringlists) + { + for (i = 0; i < p->stringlists_number; i++) + { + if (p->stringlists[i]) + pdc_cleanup_optstringlist(p->pdc, + p->stringlists[i], p->stringlistsizes[i]); + } + pdc_free(p->pdc, p->stringlists); + pdc_free(p->pdc, p->stringlistsizes); + } + + pdf_init_stringlists(p); +} + +#define PDF_MAX_UTILSTRLISTS 10 + +int +pdf_insert_utilstring(PDF *p, const char *utilstring, pdc_bool kdup) +{ + static const char fn[] = "pdf_insert_utilstring"; + char **utilstrlist; + int i = 0; + + if (p->utilstrlist_index == -1) + { + utilstrlist = (char **) pdc_calloc(p->pdc, + PDF_MAX_UTILSTRLISTS * sizeof (char *), fn); + p->utilstrlist_index = + pdf_insert_stringlist(p, utilstrlist, PDF_MAX_UTILSTRLISTS); + } + utilstrlist = p->stringlists[p->utilstrlist_index]; + + if (p->utilstring_number >= PDF_MAX_UTILSTRLISTS) + p->utilstring_number = 0; + i = p->utilstring_number; + if (utilstrlist[i] != NULL) + pdc_free(p->pdc, utilstrlist[i]); + if (kdup) + utilstrlist[i] = pdc_strdup_ext(p->pdc, utilstring, 0, fn); + else + utilstrlist[i] = (char *) utilstring; + p->utilstring_number++; + + return i; +} + +const char * +pdf_get_utilstring(PDF *p, int i) +{ + if (p->utilstrlist_index > -1 && i > -1 && i < p->utilstring_number) + { + char **utilstrlist = p->stringlists[p->utilstrlist_index]; + return utilstrlist[i]; + } + + return NULL; +} + +/* ------------------------ name treatment -------------------------------*/ + +void +pdf_put_pdfname(PDF *p, const char *name) +{ + char *ascname = (char *) name; + int len = (int) strlen(ascname); + + + pdc_put_pdfname(p->out, ascname, len); + +} + + +/* ---------------------- hyper text treatment -------------------------------*/ + +pdc_encoding +pdf_get_hypertextencoding_opt(PDF *p, pdc_resopt *resopts, int *codepage, + pdc_bool verbose) +{ + char **strlist; + pdc_encoding htenc; + + if (pdc_get_optvalues("hypertextencoding", resopts, NULL, &strlist)) + { + int cp; + + htenc = pdf_get_hypertextencoding(p, strlist[0], &cp, verbose); + pdf_check_hypertextencoding(p, htenc); + + if (codepage) + *codepage = cp; + } + else + { + htenc = pdf_get_hypertextencoding_param(p, codepage); + } + + return htenc; +} + +/* hypertext conversion for deprecated functions */ +char * +pdf_convert_hypertext_depr(PDF *p, const char *text, int len) +{ + int outlen; + + pdf_get_hypertextencoding_param(p, NULL); + + return pdf_convert_hypertext(p, text, len, p->hypertextformat, + p->hypertextencoding, p->hypertextcodepage, &outlen, + PDC_UTF8_FLAG, pdc_true); +} + +/* + * Conversion to PDFDoc/EBCDIC or UTF-16/[EBCDIC-]UTF-8 + */ +char * +pdf_convert_hypertext(PDF *p, const char *text, int len, + pdc_text_format hypertextformat, pdc_encoding hypertextencoding, + int codepage, int *outlen, pdc_bool oututf8, pdc_bool verbose) +{ + pdc_encodingvector *inev = NULL, *outev = NULL; + pdc_byte *intext = (pdc_byte *) text, *outtext = NULL; + pdc_text_format textformat = pdc_utf16be; + int convflags = PDC_CONV_WITHBOM | PDC_CONV_TRYBYTES; + + *outlen = 0; + + if (text == NULL) + return NULL; + + if (len == 0) + len = (int) strlen(text); + + /* incoming encoding */ + if (hypertextencoding >= 0) + { + inev = pdc_get_encoding_vector(p->pdc, hypertextencoding); + } + + /* PDFDocEncoding */ + outev = pdc_get_encoding_vector(p->pdc, pdc_pdfdoc); + + /* conversion to UTF-16-BE or PDFDocEncoding / EBCDIC */ + pdf_set_convertflags(p, &convflags); + pdc_convert_string(p->pdc, hypertextformat, codepage, inev, + intext, len, + &textformat, outev, &outtext, outlen, + convflags, verbose); + + + /* conversion to UTF-8 if Unicode */ + if (oututf8 && textformat == pdc_utf16be) + { + pdc_text_format outtextformat = PDC_UTF8; + pdc_byte *newtext = NULL; + + pdc_convert_string(p->pdc, textformat, 0, NULL, outtext, *outlen, + &outtextformat, NULL, &newtext, outlen, + PDC_CONV_WITHBOM, verbose); + pdc_free(p->pdc, outtext); + outtext = newtext; + } + + return (char *) outtext; +} + + +/* + * Conversion from [EBCDIC-]UTF-8 to UTF-16 and from EBCDIC to PDFDoc + */ +static void +pdf_put_hypertext_ext(PDF *p, const char *text, pdc_bool isfilename) +{ + pdc_byte *newtext = NULL; + pdc_encodingvector *outev = pdc_get_encoding_vector(p->pdc, pdc_pdfdoc); + int len = (int) pdc_strlen(text); + int convflags = PDC_CONV_WITHBOM | PDC_CONV_TRYBYTES; + + if (pdc_is_utf8_bytecode(text)) + { + pdc_text_format textformat = PDC_UTF8; + pdc_text_format outtextformat = pdc_utf16be; + + pdf_set_convertflags(p, &convflags); + pdc_convert_string(p->pdc, textformat, 0, NULL, (pdc_byte *) text, len, + &outtextformat, outev, &newtext, &len, + convflags, pdc_true); + text = (const char *) newtext; + } + + if (isfilename) + { + if (pdc_is_utf16be_unicode(text)) + pdc_error(p->pdc, PDC_E_IO_UNSUPP_UNINAME, 0, 0, 0, 0); + pdc_put_pdffilename(p->out, text, len); + } + else + { + pdc_put_pdfstring(p->out, text, len); + } + + if (newtext != NULL) + pdc_free(p->pdc, newtext); +} + +void +pdf_put_hypertext(PDF *p, const char *text) +{ + pdf_put_hypertext_ext(p, text, pdc_false); +} + +void +pdf_put_pdffilename(PDF *p, const char *text) +{ + pdf_put_hypertext_ext(p, text, pdc_true); +} + + +/* ------------------------ name strings -------------------------------*/ + +static void +pdf_prepare_name_string(PDF *p, const char *name, int len, + char **newname, int *newlen, + pdc_encoding *htenc, int *htcp) +{ + *newname = (char *) name; + *newlen = len; + *htenc = pdc_invalidenc; + *htcp = 0; + + if (p->usehyptxtenc && !len && !pdc_is_utf8_bytecode(name)) + { + *htenc = pdf_get_hypertextencoding_param(p, htcp); + + } +} + +char * +pdf_convert_name(PDF *p, const char *name, int len, int flags) +{ + char *resname; + char *newname; + int newlen; + pdc_encoding htenc; + int htcp; + + pdf_prepare_name_string(p, name, len, &newname, &newlen, &htenc, &htcp); + + flags |= PDC_CONV_EBCDIC; + resname = pdc_convert_name_ext(p->pdc, newname, newlen, htenc, htcp, flags); + if (newname != name) + pdc_free(p->pdc, newname); + + return resname; +} + +const char * +pdf_convert_filename(PDF *p, const char *filename, int len, + const char *paramname, int flags) +{ + const char *resfilename; + char *newfilename; + int newlen; + pdc_encoding htenc; + int htcp; + + pdf_prepare_name_string(p, filename, len, &newfilename, &newlen, + &htenc, &htcp); + + flags |= PDC_CONV_EBCDIC; + resfilename = pdc_convert_filename_ext(p->pdc, newfilename, len, + paramname, htenc, htcp, flags); + if (newfilename != filename) + pdc_free(p->pdc, newfilename); + + return resfilename; +} + +void +pdf_add_resource(PDF *p, const char *category, const char *resname) +{ + char *newresname; + int newlen; + pdc_encoding htenc; + int htcp; + + pdf_prepare_name_string(p, resname, 0, &newresname, &newlen, + &htenc, &htcp); + if (newlen) + { + char *tmpresname = pdc_utf16_to_utf8(p->pdc, newresname, newlen, + PDC_CONV_EBCDIC | PDC_CONV_WITHBOM, + &newlen); + pdc_free(p->pdc, newresname); + newresname = tmpresname; + newlen = 0; + } + + pdc_add_resource_ext(p->pdc, category, newresname, NULL, htenc, htcp); + + if (newresname != resname) + pdc_free(p->pdc, newresname); +} + +/* ------------------------ option text list -------------------------------*/ + +int +pdf_get_opt_textlist(PDF *p, const char *keyword, pdc_resopt *resopts, + pdc_encoding enc, int codepage, pdc_bool ishypertext, + const char *fieldname, char **text, char ***textlist) +{ + pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_optlist); + int ns; + char **strlist; + + ns = pdc_get_optvalues(keyword, resopts, NULL, &strlist); + if (ns) + { + pdc_byte *string = NULL; + pdc_encodingvector *inev = NULL, *outev = NULL; + pdc_text_format intextformat = pdc_bytes, outtextformat = pdc_utf16be; + int convflags = PDC_CONV_WITHBOM | PDC_CONV_TRYBYTES; + pdc_bool isutf8; + int i, outlen; + + /* whole option list or string list is in UTF-8 */ + isutf8 = pdc_is_lastopt_utf8(resopts); + + /* Encoding */ + if (ishypertext) + { + /* Initialize */ + if (!isutf8) + { + if (enc < 0 && enc != pdc_unicode && enc != pdc_cid) + enc = pdf_get_hypertextencoding(p, "auto", &codepage, + pdc_true); + if (enc >= 0) + inev = pdc_get_encoding_vector(p->pdc, enc); + } + + /* PDFDocEncoding */ + outev = pdc_get_encoding_vector(p->pdc, pdc_pdfdoc); + } + else + { + if (enc == pdc_invalidenc) + { + if (fieldname) + { + pdc_cleanup_optionlist(p->pdc, resopts); + pdc_error(p->pdc, PDF_E_FF_FONTMISSING, fieldname, 0, 0, 0); + } + return 0; + } + else if (enc >= 0) + { + outev = pdc_get_encoding_vector(p->pdc, enc); + } + } + + if (logg1) + { + if (isutf8) + { + pdc_logg(p->pdc, "\tOption \"%s\" is "PDC_UTF8_STRG" encoded\n", + keyword); + } + else + { + pdc_logg(p->pdc, "\tOption \"%s\" is %s encoded\n", + keyword, pdc_get_user_encoding(p->pdc, enc)); + } + } + + for (i = 0; i < ns; i++) + { + string = (pdc_byte *) strlist[i]; + + { + if (ishypertext || isutf8) + { + intextformat = isutf8 ? PDC_UTF8 : pdc_bytes; + + if (pdc_logg_is_enabled(p->pdc, 2, trc_optlist)) + convflags |= PDC_CONV_LOGGING; + pdf_set_convertflags(p, &convflags); + pdc_convert_string(p->pdc, intextformat, codepage, inev, + string, (int) strlen((char *) string), + &outtextformat, outev, &string, &outlen, + convflags, pdc_true); + pdc_free(p->pdc, strlist[i]); + strlist[i] = (char *) string; + } + } + } + + if (text) + *text = strlist[0]; + else + *textlist = strlist; + + if (fieldname) + { + strlist = (char **) pdc_save_lastopt(resopts, PDC_OPT_SAVEALL); + pdf_insert_stringlist(p, strlist, ns); + } + } + + return ns; +} + +char * +pdf_get_opt_utf8name(PDF *p, const char *keyword, pdc_resopt *resopts) +{ + char **strlist = NULL; + char *utf8name = NULL; + + if (pdc_get_opt_utf8strings(p->pdc, keyword, resopts, PDC_OPT_SAVE1ELEM, + &strlist)) + { + utf8name = strlist[0]; + } + + return utf8name; +} + + +/* -------------------------- errorpolicy -------------------------------*/ + +pdc_bool +pdf_get_errorpolicy(PDF *p, pdc_resopt *resopts, pdc_bool verbose) +{ + int errpol = (int) p->errorpolicy; + + if (resopts != NULL) + pdc_get_optvalues("errorpolicy", resopts, &errpol, NULL); + + if (errpol != (int) errpol_legacy) + verbose = errpol; + + return verbose; +} + + +/* -------------------------- handle check -------------------------------*/ + +void +pdf_check_handle(PDF *p, int handle, pdc_opttype type) +{ + int minval = 0, maxval = 0; + pdc_bool empty = pdc_false; + + switch (type) + { + + case pdc_actionhandle: + maxval = pdf_get_max_action(p); + break; + + case pdc_bookmarkhandle: + maxval = p->outline_count; + break; + + case pdc_colorhandle: + maxval = p->colorspaces_number - 1; + break; + + + case pdc_fonthandle: + maxval = p->fonts_number - 1; + empty = !pdf_isvalid_font(p, handle); + break; + + case pdc_gstatehandle: + maxval = p->extgstates_number - 1; + break; + + + case pdc_imagehandle: + maxval = p->images_capacity - 1; + if (handle >= minval && handle <= maxval && + (!p->images[handle].in_use || + p->xobjects[p->images[handle].no].type == pdi_xobject)) + empty = pdc_true; + break; + + + case pdc_pagehandle: + maxval = p->images_capacity - 1; + if (handle >= minval && handle <= maxval && + (!p->images[handle].in_use || + p->xobjects[p->images[handle].no].type != pdi_xobject)) + empty = pdc_true; + break; + + case pdc_patternhandle: + maxval = p->pattern_number - 1; + break; + + case pdc_shadinghandle: + maxval = p->shadings_number - 1; + break; + + + case pdc_templatehandle: + maxval = p->images_capacity - 1; + if (handle >= minval && handle <= maxval && + (!p->images[handle].in_use || + p->xobjects[p->images[handle].no].type != form_xobject)) + empty = pdc_true; + break; + + + case pdc_stringhandle: + if (p->utilstrlist_index == -1) + empty = pdc_true; + maxval = p->utilstring_number - 1; + break; + + default: + break; + } + + if (handle < minval || handle > maxval || empty) + { + const char *stemp1 = pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, + pdc_get_handletype(type)); + const char *stemp2 = pdc_errprintf(p->pdc, "%d", + (p->pdc->hastobepos && type != pdc_stringhandle) ? + handle + 1 : handle); + pdc_error(p->pdc, PDC_E_ILLARG_HANDLE, stemp1, stemp2, 0, 0); + } +} + +void +pdf_set_clientdata(PDF *p, pdc_clientdata *cdata) +{ + memset(cdata, 0, sizeof(pdc_clientdata)); + + cdata->maxaction = pdf_get_max_action(p); + cdata->maxbookmark = p->outline_count; + cdata->maxcolor = p->colorspaces_number - 1; + cdata->maxdocument = p->pdi_capacity - 1; + cdata->maxfont = p->fonts_number - 1; + cdata->maxgstate = p->extgstates_number - 1; + cdata->maximage = p->images_capacity - 1; + cdata->maxpage = p->images_capacity - 1; + cdata->maxpattern = p->pattern_number - 1; + cdata->maxshading = p->shadings_number - 1; + cdata->maxtemplate = p->images_capacity - 1; + cdata->maxstring = p->utilstring_number - 1; + + cdata->compatibility = p->compatibility; +} diff --git a/src/pdflib/pdflib/p_xgstate.c b/src/pdflib/pdflib/p_xgstate.c new file mode 100644 index 0000000..0e62df9 --- /dev/null +++ b/src/pdflib/pdflib/p_xgstate.c @@ -0,0 +1,514 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_xgstate.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Extended graphics state handling + * + */ + +#define P_XGSTATE_C + +#include "p_intern.h" +#include "p_font.h" + +static const pdc_keyconn pdf_blendmode_pdfkeylist[] = +{ + {"Normal", BM_Normal}, + {"Multiply", BM_Multiply}, + {"Screen", BM_Screen}, + {"Overlay", BM_Overlay}, + {"Darken", BM_Darken}, + {"Lighten", BM_Lighten}, + {"ColorDodge", BM_ColorDodge}, + {"ColorBurn", BM_ColorBurn}, + {"HardLight", BM_HardLight}, + {"SoftLight", BM_SoftLight}, + {"Difference", BM_Difference}, + {"Exclusion", BM_Exclusion}, + {"Hue", BM_Hue}, + {"Saturation", BM_Saturation}, + {"Color", BM_Color}, + {"Luminosity", BM_Luminosity}, + {NULL, 0} +}; + +/* external graphic state */ +struct pdf_extgstateresource_s +{ + pdc_id obj_id; /* object id of this resource */ + pdc_bool used_on_current_page; /* this resource used on current page */ + + pdc_id font_obj; /* font to use */ + pdc_scalar font_size; /* at what size */ + + pdc_scalar line_width; + int line_cap; + int line_join; + pdc_scalar miter_limit; + pdc_scalar* dash_array; + int dash_count; + pdc_scalar dash_phase; + + pdf_renderingintent ri; + pdc_bool stroke_adjust; + pdc_bool overprint_stroke; + pdc_bool overprint_fill; + int overprint_mode; + + /* + The following entries which take functions are not implemented + since PDFlib has no concept of a function at this time. + + BG - black generation + BG2 - black generation + UCR - undercolor-removal + UCR2 - undercolor-removal + TR - transfer + TR2 - transfer + HT - halftone + */ + + pdc_scalar flatness; + pdc_scalar smoothness; + + /* PDF 1.4 additions */ + pdf_blendmode blendmode; /* blend mode */ + pdc_scalar opacity_fill; /* fill opacity level */ + pdc_scalar opacity_stroke; /* stroke opacity level */ + pdc_bool alpha_is_shape; + pdc_bool text_knockout; +}; + +pdc_id +pdf_get_gstate_id(PDF *p, int gstate) +{ + /* TODO: is this required for ExtGStates used in Shadings? */ + p->extgstates[gstate].used_on_current_page = pdc_true; + + return (p->extgstates[gstate].obj_id); +} + +/* Definitions of Explicit Graphics State options */ +static const pdc_defopt pdf_create_gstate_options[] = +{ + {"alphaisshape", pdc_booleanlist, PDC_OPT_PDC_1_4, 1, 1, 0.0, 0.0, NULL}, + + {"blendmode", pdc_keywordlist, PDC_OPT_BUILDOR | PDC_OPT_PDC_1_4, 1, 20, + 0.0, 0.0, pdf_blendmode_pdfkeylist}, + +/* These features do not work in Acrobat (5.0.1) + {"dasharray", pdc_scalarlist, PDC_OPT_PDC_1_3, 1, 8, + PDF_SMALLREAL, PDC_FLOAT_MAX, NULL}, + + {"dashphase", pdc_scalarlist, PDC_OPT_PDC_1_3, 1, 1, + 0.0, PDC_FLOAT_MAX, NULL}, + + {"fontsize", pdc_scalarlist, PDC_OPT_PDC_1_3, 1, 1, + PDF_SMALLREAL, PDC_FLOAT_MAX, NULL}, + + {"font", pdc_fonthandle, PDC_OPT_PDC_1_3 | PDC_OPT_REQUIRIF1, 1, 1, + 0, 0, NULL}, +*/ + + {"flatness", pdc_scalarlist, PDC_OPT_PDC_1_3, 1, 1, + PDF_SMALLREAL, PDC_FLOAT_MAX, NULL}, + + {"linecap", pdc_integerlist, PDC_OPT_PDC_1_3, 1, 1, 0.0, 2.0, + pdf_linecap_keylist}, + + {"linejoin", pdc_integerlist, PDC_OPT_PDC_1_3, 1, 1, 0.0, 2.0, + pdf_linejoin_keylist}, + + {"linewidth", pdc_scalarlist, PDC_OPT_PDC_1_3, 1, 1, + PDF_SMALLREAL, PDC_FLOAT_MAX, NULL}, + + {"miterlimit", pdc_scalarlist, PDC_OPT_PDC_1_3, 1, 1, 1.0, PDC_FLOAT_MAX, + NULL}, + + {"opacityfill", pdc_scalarlist, PDC_OPT_PDC_1_4 | PDC_OPT_PERCENT, + 1, 1, 0.0, 1.0, NULL}, + + {"opacitystroke", pdc_scalarlist, PDC_OPT_PDC_1_4 | PDC_OPT_PERCENT, + 1, 1, 0.0, 1.0, NULL}, + + {"overprintfill", pdc_booleanlist, PDC_OPT_PDC_1_3, 1, 1, 0.0, 0.0, NULL}, + + {"overprintmode", pdc_integerlist, PDC_OPT_PDC_1_3, 1, 1, 0.0, 1.0, NULL}, + + {"overprintstroke", pdc_booleanlist, PDC_OPT_PDC_1_3, 1, 1, 0.0, 0.0, NULL}, + + {"renderingintent", pdc_keywordlist, PDC_OPT_PDC_1_3, 1, 1, 0.0, 0.0, + pdf_renderingintent_pdfkeylist}, + + {"smoothness", pdc_scalarlist, PDC_OPT_PDC_1_3 | PDC_OPT_PERCENT, + 1, 1, 0.0, 1.0, NULL}, + + {"strokeadjust", pdc_booleanlist, PDC_OPT_PDC_1_3, 1, 1, 0.0, 0.0, NULL}, + + {"textknockout", pdc_booleanlist, PDC_OPT_PDC_1_4, 1, 1, 0.0, 0.0, NULL}, + + PDC_OPT_TERMINATE +}; + +static void +pdf_init_extgstateresource(pdf_extgstateresource *egsr) +{ + egsr->used_on_current_page = pdc_false; + + /* we need to tell which parms have been set and which haven't, + ** so we initialize to invalid values. even boolean parms are + ** declared as integers, so we can set them to -1 here. + */ + egsr->font_obj = PDC_NEW_ID; + egsr->font_size = pdc_undef; + + egsr->line_width = pdc_undef; + egsr->line_cap = pdc_undef; + egsr->line_join = pdc_undef; + egsr->miter_limit = pdc_undef; + + egsr->dash_array = NULL; + egsr->dash_count = 0; + egsr->dash_phase = 0.0; + + egsr->ri = AutoIntent; + egsr->stroke_adjust = pdc_undef; + egsr->overprint_stroke = pdc_undef; + egsr->overprint_fill = pdc_undef; + egsr->overprint_mode = pdc_undef; + egsr->flatness = pdc_undef; + egsr->smoothness = pdc_undef; + + egsr->blendmode = BM_None; + egsr->opacity_stroke = pdc_undef; + egsr->opacity_fill = pdc_undef; + egsr->alpha_is_shape = pdc_undef; + egsr->text_knockout = pdc_undef; +} + +static void +pdf_grow_extgstates(PDF *p) +{ + int i; + + p->extgstates = (pdf_extgstateresource *) pdc_realloc(p->pdc, p->extgstates, + sizeof(pdf_extgstateresource) * 2 * p->extgstates_capacity, + "pdf_grow_extgstates"); + + for (i = p->extgstates_capacity; i < 2 * p->extgstates_capacity; i++) { + pdf_init_extgstateresource( &p->extgstates[i] ); + } + + p->extgstates_capacity *= 2; +} + +void +pdf_init_extgstates(PDF *p) +{ + static const char fn[] = "pdf_init_extgstates"; + int i; + + p->extgstates_number = 0; + p->extgstates_capacity = EXTGSTATE_CHUNKSIZE; + + p->extgstates = (pdf_extgstateresource *) + pdc_malloc(p->pdc, + sizeof(pdf_extgstateresource) * p->extgstates_capacity, fn); + + for (i = 0; i < p->extgstates_capacity; i++) { + pdf_init_extgstateresource( &p->extgstates[i] ); + } +} + +void +pdf_write_page_extgstates(PDF *p) +{ + int i, total = 0; + int bias = p->curr_ppt->eg_bias; + + for (i = 0; i < p->extgstates_number; i++) + if (p->extgstates[i].used_on_current_page) + total++; + + if (total > 0 || bias) + { + pdc_puts(p->out, "/ExtGState"); + pdc_begin_dict(p->out); + } + + if (total > 0) + { + for (i = 0; i < p->extgstates_number; i++) + { + if (p->extgstates[i].used_on_current_page) + { + p->extgstates[i].used_on_current_page = pdc_false; /* reset */ + pdc_printf(p->out, "/GS%d", bias + i); + pdc_objref(p->out, "", p->extgstates[i].obj_id); + } + } + + if (!bias) + pdc_end_dict(p->out); + } +} + +void +pdf_get_page_extgstates(PDF *p, pdf_reslist *rl) +{ + int i; + + for (i = 0; i < p->extgstates_number; i++) { + if (p->extgstates[i].used_on_current_page) { + p->extgstates[i].used_on_current_page = pdc_false; /* reset */ + pdf_add_reslist(p, rl, i); + } + } +} + +void +pdf_mark_page_extgstate(PDF *p, int n) +{ + p->extgstates[n].used_on_current_page = pdc_true; +} + +void +pdf_write_doc_extgstates(PDF *p) +{ + int i, j; + + pdf_extgstateresource *gs; + + for (i = 0; i < p->extgstates_number; i++) + { + gs = &p->extgstates[i]; + + pdc_begin_obj(p->out, gs->obj_id); /* ExtGState resource */ + pdc_begin_dict(p->out); + + pdc_puts(p->out, "/Type/ExtGState\n"); + + if (gs->font_obj != PDC_NEW_ID) + { + pdc_puts(p->out, "/Font"); + pdc_begin_array(p->out); + pdc_objref(p->out, "", gs->font_obj); + pdc_printf(p->out, "%f", gs->font_size); + pdc_end_array(p->out); + } + + if (gs->line_width != pdc_undef) + pdc_printf(p->out, "/LW %f\n", gs->line_width); + + if (gs->line_cap != pdc_undef) + pdc_printf(p->out, "/LC %d\n", gs->line_cap); + + if (gs->line_join != pdc_undef) + pdc_printf(p->out, "/LJ %d\n", gs->line_join); + + if (gs->miter_limit != pdc_undef) + pdc_printf(p->out, "/ML %f\n", gs->miter_limit); + + if (gs->dash_count > 0) + { + pdc_printf(p->out, "/D"); + pdc_begin_array(p->out); + pdc_begin_array(p->out); + + for (j = 0; j < gs->dash_count; ++j) + pdc_printf(p->out, "%f ", gs->dash_array[j]); + + pdc_end_array_c(p->out); + pdc_printf(p->out, "%f", gs->dash_phase); + pdc_end_array(p->out); + /* but see page 157 of PDF Reference: integer */ + } + + if (gs->ri != AutoIntent) + pdc_printf(p->out, "/RI/%s\n", + pdc_get_keyword((long) gs->ri, pdf_renderingintent_pdfkeylist)); + + if (gs->stroke_adjust != pdc_undef) + pdc_printf(p->out, "/SA %s\n", PDC_BOOLSTR(gs->stroke_adjust)); + + if (gs->overprint_stroke != pdc_undef) + pdc_printf(p->out, "/OP %s\n", PDC_BOOLSTR(gs->overprint_stroke)); + + if (gs->overprint_fill != pdc_undef) + pdc_printf(p->out, "/op %s\n", PDC_BOOLSTR(gs->overprint_fill)); + else if (gs->overprint_stroke == pdc_true) + pdc_puts(p->out, "/op false\n"); + + if (gs->overprint_mode != pdc_undef) + pdc_printf(p->out, "/OPM %d\n", gs->overprint_mode); + + if (gs->flatness != pdc_undef) + pdc_printf(p->out, "/FL %f\n", gs->flatness); + + if (gs->smoothness != pdc_undef) + pdc_printf(p->out, "/SM %f\n", gs->smoothness); + + if (gs->opacity_fill != pdc_undef) + pdc_printf(p->out, "/ca %f\n", gs->opacity_fill); + + if (gs->blendmode != BM_None) { + const char *modename; + int modecount=0; + + for (j = 0; ; j++) { + if (!pdf_blendmode_pdfkeylist[j].word) + break; + if (gs->blendmode & pdf_blendmode_pdfkeylist[j].code) + modecount++; + } + + pdc_printf(p->out, "/BM"); + + /* + * ACROBUG: Acrobat 7 doesn't like Blend mode arrays with a + * singly entry under some circumstances (many entries? images + * involved?) so we avoid the array if we have only one entry. + */ + if (modecount > 1) + pdc_begin_array(p->out); + + for (j = 0; ; j++) { + modename = pdf_blendmode_pdfkeylist[j].word; + if (!modename) break; + if (gs->blendmode & pdf_blendmode_pdfkeylist[j].code) + pdc_printf(p->out, "/%s", modename); + } + + if (modecount > 1) + pdc_end_array(p->out); + } + + if (gs->opacity_stroke != pdc_undef) + pdc_printf(p->out, "/CA %f\n", gs->opacity_stroke); + + if (gs->alpha_is_shape != pdc_undef) + pdc_printf(p->out, "/AIS %s\n", PDC_BOOLSTR(gs->alpha_is_shape)); + + if (gs->text_knockout != pdc_undef) + pdc_printf(p->out, "/TK %s\n", PDC_BOOLSTR(gs->text_knockout)); + + pdc_end_dict(p->out); + pdc_end_obj(p->out); /* ExtGState resource */ + } +} + +void +pdf_cleanup_extgstates(PDF *p) +{ + int i; + + if (!p->extgstates) + return; + + for (i = 0; i < p->extgstates_number; i++) { + if (p->extgstates[i].dash_array) + pdc_free(p->pdc, p->extgstates[i].dash_array); + } + + pdc_free(p->pdc, p->extgstates); + p->extgstates = NULL; +} + +int +pdf__create_gstate(PDF *p, const char *optlist) +{ + pdf_extgstateresource *gs; + int slot = -1; + int font = pdc_undef; + int inum; + pdc_clientdata data; + pdc_resopt *results; + + if (optlist == NULL || !*optlist) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "optlist", 0, 0, 0); + + slot = p->extgstates_number; + if (slot == p->extgstates_capacity) + pdf_grow_extgstates(p); + + p->extgstates_number++; + gs = &p->extgstates[slot]; + gs->obj_id = pdc_alloc_id(p->out); + + /* parsing optlist */ + pdf_set_clientdata(p, &data); + results = pdc_parse_optionlist(p->pdc, optlist, pdf_create_gstate_options, + &data, pdc_true); + + pdc_get_optvalues("alphaisshape", results, &gs->alpha_is_shape, NULL); + + if (pdc_get_optvalues("blendmode", results, &inum, NULL)) + gs->blendmode = (pdf_blendmode) inum; + + gs->dash_count = pdc_get_optvalues("dasharray", results, NULL, NULL); + gs->dash_array = (pdc_scalar *) pdc_save_lastopt(results, PDC_OPT_SAVEALL); + + pdc_get_optvalues("dashphase", results, &gs->dash_phase, NULL); + + pdc_get_optvalues("flatness", results, &gs->flatness, NULL); + + pdc_get_optvalues("font", results, &font, NULL); + if (font != pdc_undef) + gs->font_obj = p->fonts[font].obj_id; + + pdc_get_optvalues("fontsize", results, &gs->font_size, NULL); + + pdc_get_optvalues("linecap", results, &gs->line_cap, NULL); + + pdc_get_optvalues("linejoin", results, &gs->line_join, NULL); + + pdc_get_optvalues("linewidth", results, &gs->line_width, NULL); + + pdc_get_optvalues("miterlimit", results, &gs->miter_limit, NULL); + + pdc_get_optvalues("opacityfill", results, &gs->opacity_fill, NULL); + + pdc_get_optvalues("opacitystroke", results, &gs->opacity_stroke, NULL); + + pdc_get_optvalues("overprintfill", results, &gs->overprint_fill, NULL); + + pdc_get_optvalues("overprintmode", results, &gs->overprint_mode, NULL); + + pdc_get_optvalues("overprintstroke", results, &gs->overprint_stroke, NULL); + + if (pdc_get_optvalues("renderingintent", results, &inum, NULL)) + gs->ri = (pdf_renderingintent) inum; + + pdc_get_optvalues("smoothness", results, &gs->smoothness, NULL); + + pdc_get_optvalues("strokeadjust", results, &gs->stroke_adjust, NULL); + + pdc_get_optvalues("textknockout", results, &gs->text_knockout, NULL); + + pdc_cleanup_optionlist(p->pdc, results); + + + + return slot; +} + +void +pdf__set_gstate(PDF *p, int gstate) +{ + int bias = p->curr_ppt->eg_bias; + + pdf_check_handle(p, gstate, pdc_gstatehandle); + + pdc_printf(p->out, "/GS%d gs\n", bias + gstate); + p->extgstates[gstate].used_on_current_page = pdc_true; +} diff --git a/src/pdflib/pdflib/p_xmp.c b/src/pdflib/pdflib/p_xmp.c new file mode 100644 index 0000000..eec4002 --- /dev/null +++ b/src/pdflib/pdflib/p_xmp.c @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: p_xmp.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib Metadata (XMP) related routines + * + */ + +#define P_XMP_C + +#include "p_intern.h" + + + + diff --git a/src/pdflib/pdflib/pdflib.c b/src/pdflib/pdflib/pdflib.c new file mode 100644 index 0000000..7ecd1f3 --- /dev/null +++ b/src/pdflib/pdflib/pdflib.c @@ -0,0 +1,4052 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pdflib.c,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * PDFlib API functions + * + */ + +#define PDFLIB_C + +#include "p_intern.h" + + +#if (defined(WIN32) || defined(__CYGWIN)) +#define WIN32_LEAN_AND_MEAN +#include +#include +#undef WIN32_LEAN_AND_MEAN +#endif /* WIN32 || __CYGWIN */ + +#if _MSC_VER >= 1310 /* VS .NET 2003 and later */ +/* pdflib.h declares some functions as deprecated, but we don't want to see + * these warnings here */ +#pragma warning(disable: 4995) +#endif + +static const PDFlib_api PDFlib = { + /* version numbers for checking the DLL against client code */ + sizeof(PDFlib_api), /* size of this structure */ + + PDFLIB_MAJORVERSION, /* PDFlib major version number */ + PDFLIB_MINORVERSION, /* PDFlib minor version number */ + PDFLIB_REVISION, /* PDFlib revision number */ + + 0, /* reserved */ + + PDF_activate_item, + PDF_add_bookmark, + PDF_add_bookmark2, + PDF_add_launchlink, + PDF_add_locallink, + PDF_add_nameddest, + PDF_add_note, + PDF_add_note2, + PDF_add_pdflink, + PDF_add_table_cell, + PDF_add_textflow, + PDF_add_thumbnail, + PDF_add_weblink, + PDF_arc, + PDF_arcn, + PDF_attach_file, + PDF_attach_file2, + PDF_begin_document, + PDF_begin_document_callback, + PDF_begin_font, + PDF_begin_glyph, + PDF_begin_item, + PDF_begin_layer, + PDF_begin_mc, + PDF_begin_page, + PDF_begin_page_ext, + PDF_begin_pattern, + PDF_begin_template, + PDF_begin_template_ext, + PDF_boot, + PDF_check_context, + PDF_circle, + PDF_clip, + PDF_close, + PDF_close_image, + PDF_close_pdi, + PDF_close_pdi_document, + PDF_close_pdi_page, + PDF_closepath, + PDF_closepath_fill_stroke, + PDF_closepath_stroke, + PDF_concat, + PDF_continue_text, + PDF_continue_text2, + PDF_create_3dview, + PDF_create_action, + PDF_create_annotation, + PDF_create_bookmark, + PDF_create_field, + PDF_create_fieldgroup, + PDF_create_gstate, + PDF_create_pvf, + PDF_create_textflow, + PDF_curveto, + PDF_define_layer, + PDF_delete, + PDF_delete_pvf, + PDF_delete_table, + PDF_delete_textflow, + PDF_encoding_set_char, + PDF_end_document, + PDF_end_font, + PDF_end_glyph, + PDF_end_item, + PDF_end_layer, + PDF_end_mc, + PDF_end_page, + PDF_end_page_ext, + PDF_end_pattern, + PDF_end_template, + PDF_endpath, + PDF_fill, + PDF_fill_imageblock, + PDF_fill_pdfblock, + PDF_fill_stroke, + PDF_fill_textblock, + PDF_findfont, + PDF_fit_image, + PDF_fit_pdi_page, + PDF_fit_table, + PDF_fit_textflow, + PDF_fit_textline, + PDF_get_api, + PDF_get_apiname, + PDF_get_buffer, + PDF_get_errmsg, + PDF_get_errnum, + PDF_get_majorversion, + PDF_get_minorversion, + PDF_get_opaque, + PDF_get_parameter, + PDF_get_pdi_parameter, + PDF_get_pdi_value, + PDF_get_value, + PDF_info_font, + PDF_info_matchbox, + PDF_info_table, + PDF_info_textflow, + PDF_info_textline, + PDF_initgraphics, + PDF_lineto, + PDF_load_3ddata, + PDF_load_font, + PDF_load_iccprofile, + PDF_load_image, + PDF_makespotcolor, + PDF_mc_point, + PDF_moveto, + PDF_new, + PDF_new2, + PDF_open_CCITT, + PDF_open_file, + PDF_open_image, + PDF_open_image_file, + PDF_open_mem, + PDF_open_pdi, + PDF_open_pdi_callback, + PDF_open_pdi_document, + PDF_open_pdi_page, + PDF_pcos_get_number, + PDF_pcos_get_string, + PDF_pcos_get_stream, + PDF_place_image, + PDF_place_pdi_page, + PDF_process_pdi, + PDF_rect, + PDF_restore, + PDF_resume_page, + PDF_rotate, + PDF_save, + PDF_scale, + PDF_set_border_color, + PDF_set_border_dash, + PDF_set_border_style, + PDF_set_gstate, + PDF_set_info, + PDF_set_info2, + PDF_set_layer_dependency, + PDF_set_parameter, + PDF_set_text_pos, + PDF_set_value, + PDF_setcolor, + PDF_setdash, + PDF_setdashpattern, + PDF_setflat, + PDF_setfont, + PDF_setgray, + PDF_setgray_fill, + PDF_setgray_stroke, + PDF_setlinecap, + PDF_setlinejoin, + PDF_setlinewidth, + PDF_setmatrix, + PDF_setmiterlimit, + PDF_setpolydash, + PDF_setrgbcolor, + PDF_setrgbcolor_fill, + PDF_setrgbcolor_stroke, + PDF_shading, + PDF_shading_pattern, + PDF_shfill, + PDF_show, + PDF_show2, + PDF_show_boxed, + PDF_show_boxed2, + PDF_show_xy, + PDF_show_xy2, + PDF_shutdown, + PDF_skew, + PDF_stringwidth, + PDF_stringwidth2, + PDF_stroke, + PDF_suspend_page, + PDF_translate, + PDF_utf16_to_utf8, + PDF_utf32_to_utf16, + PDF_utf8_to_utf16, + PDF_xshow, + pdf_catch, + pdf_exit_try, + pdf_jbuf, + pdf_rethrow +}; + +static pdc_bool +pdf__check_context(PDF *p) +{ + if (p == NULL || p->magic != PDC_MAGIC) + { + fprintf(stderr, "*** PDFlib context pointer %p is invalid ***\n", p); + return pdc_false; + } + + return pdc_true; +} + +static pdc_bool +pdf_enter_api(PDF *p, const char *funame, pdf_state s, const char *fmt, ...) +{ + /* check whether the client completely screwed up */ + if (pdf__check_context(p)) + { + pdc_bool retval; + va_list args; + + va_start(args, fmt); + retval = pdc_enter_api_logg(p->pdc, funame, pdc_true, fmt, args); + va_end(args); + + if (retval) + { + /* check whether we are in a valid scope */ + if ((p->state_stack[p->state_sp] & s) != 0) + { + return pdc_true; + } + + /* check glyphignore scope */ + if ((p->state_stack[p->state_sp] & pdf_state_glyphignore) == 0) + { + /* pdc_error() will NOT throw an exception + ** (and simply return instead) if the core + ** is already in error state. + */ + pdc_error(p->pdc, PDF_E_DOC_SCOPE, pdf_current_scope(p), + 0, 0, 0); + } + } + + pdc_logg_exit_api(p->pdc, pdc_true, "\n"); + } + + /* invalid PDFlib context or + ** core is in the error state or + ** glyphignore scope + */ + return pdc_false; +} + +static pdc_bool +pdf_enter_api_simple(PDF *p, const char *funame, const char *fmt, ...) +{ + /* check whether the client completely screwed up */ + if (pdf__check_context(p)) + { + pdc_bool retval; + va_list args; + + va_start(args, fmt); + retval = pdc_enter_api_logg(p->pdc, funame, pdc_false, fmt, args); + va_end(args); + + return retval; + } + + return pdc_false; +} + +static int +pdf_exit_boolean_api(PDF *p, int retval) +{ + /* check whether the client completely screwed up */ + if (pdf__check_context(p)) + { + if (p->pdc->hastobepos && retval == -1) + retval += 1; + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + + return retval; +} + +static int +pdf_exit_handle_api(PDF *p, int retval) +{ + /* check whether the client completely screwed up */ + if (pdf__check_context(p)) + { + if (p->pdc->hastobepos) + retval += 1; + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + + return retval; +} + + +/*************************** + * + * external API functions + * + ***************************/ + +PDFLIB_API void PDFLIB_CALL +PDF_boot(void) +{ + /* nothing yet */ +} + +PDFLIB_API void PDFLIB_CALL +PDF_shutdown(void) +{ + /* nothing yet */ +} + +PDFLIB_API const PDFlib_api * PDFLIB_CALL +PDF_get_api(void) +{ + return &PDFlib; +} + +PDFLIB_API int PDFLIB_CALL +PDF_get_majorversion(void) +{ + return PDFLIB_MAJORVERSION; +} + +PDFLIB_API int PDFLIB_CALL +PDF_get_minorversion(void) +{ + return PDFLIB_MINORVERSION; +} + + +#if (defined(WIN32) || defined(__CYGWIN)) && defined(PDFLIB_EXPORTS) + +/* + * DLL entry function as required by Visual C++. + * It is currently not necessary on Windows, but will eventually + * be used to boot thread-global resources for PDFlib + * (mainly font-related stuff). + */ +BOOL WINAPI +DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved); + +BOOL WINAPI +DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + (void) hModule; + (void) lpReserved; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + PDF_boot(); + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + PDF_shutdown(); + break; + } + + return TRUE; +} +#endif /* WIN32 && PDFLIB_EXPORT */ + + +/************************* + * + * general API functions + * + *************************/ + +PDFLIB_API int PDFLIB_CALL +PDF_check_context(PDF *p) +{ + return pdf__check_context(p); +} + +PDFLIB_API int PDFLIB_CALL +PDF_get_errnum(PDF *p) +{ + static const char fn[] = "PDF_get_errnum"; + int retval = -1; + + if (pdf_enter_api_simple(p, fn, "(p_%p)\n", (void *) p)) + { + retval = pdc_get_errnum(p->pdc); + pdc_logg_exit_api(p->pdc, pdc_false, "[%d]\n", retval); + } + + return retval; +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_get_errmsg(PDF *p) +{ + static const char fn[] = "PDF_get_errmsg"; + const char *retval = ""; + + if (pdf_enter_api_simple(p, fn, "(p_%p)\n", (void *) p)) + { + retval = pdc_get_errmsg(p->pdc); + pdc_logg_exit_api(p->pdc, pdc_false, "[\"%T\"]\n", retval, 0); + } + + return retval; +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_get_apiname(PDF *p) +{ + static const char fn[] = "PDF_get_apiname"; + const char *retval = ""; + + if (pdf_enter_api_simple(p, fn, "(p_%p)\n", (void *) p)) + { + retval = pdc_get_apiname(p->pdc); + pdc_logg_exit_api(p->pdc, pdc_false, "[\"%T\"]\n", retval, 0); + } + + return retval; +} + +PDFLIB_API void * PDFLIB_CALL +PDF_get_opaque(PDF *p) +{ + static const char fn[] = "PDF_get_opaque"; + void *retval = NULL; + + if (pdf__check_context(p)) + { + pdc_logg_cond(p->pdc, 1, trc_api, "/* "); + pdf_enter_api_simple(p, fn, "(p_%p) */\n", (void *) p); + retval = p->opaque; + pdc_logg_exit_api(p->pdc, pdc_false, "/* [%p] */\n", retval); + } + + return retval; +} + +PDFLIB_API pdf_jmpbuf * PDFLIB_CALL +pdf_jbuf(PDF *p) +{ + if (pdf__check_context(p)) + return (pdf_jmpbuf *) pdc_jbuf(p->pdc); + + return ((pdf_jmpbuf *) NULL); +} + +PDFLIB_API void PDFLIB_CALL +pdf_exit_try(PDF *p) +{ + if (pdf__check_context(p)) + pdc_exit_try(p->pdc); +} + +PDFLIB_API int PDFLIB_CALL +pdf_catch(PDF *p) +{ + if (pdf__check_context(p)) + return pdc_catch_extern(p->pdc); + + return pdc_false; +} + +PDFLIB_API void PDFLIB_CALL +pdf_rethrow(PDF *p) +{ + static const char fn[] = "pdf_rethrow"; + + if (pdf_enter_api_simple(p, fn, "(p_%p)\n", (void *) p)) + pdc_rethrow(p->pdc); +} + +PDFLIB_API void PDFLIB_CALL +pdf_throw(PDF *p, const char *parm1, const char *parm2, const char *parm3) +{ + if (pdf__check_context(p)) + { + pdc_enter_api(p->pdc, "pdf_throw"); + pdc_error(p->pdc, PDF_E_INT_WRAPPER, parm1, parm2, parm3, NULL); + } +} + + +/********************** + * + * p_3d.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_create_3dview( + PDF *p, + const char *username, + int len, + const char *optlist) +{ + static const char fn[] = "PDF_create_3dview"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_page | pdf_state_document), + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, username, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_3DANNOT, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_load_3ddata( + PDF *p, + const char *filename, + int len, + const char *optlist) +{ + static const char fn[] = "PDF_load_3ddata"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_page | pdf_state_document), + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, filename, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_3DANNOT, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + + +/********************** + * + * p_actions.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_create_action( + PDF *p, + const char *type, + const char *optlist) +{ + static const char fn[] = "PDF_create_action"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_page | pdf_state_document), + "(p_%p, \"%s\", \"%T\")\n", + (void *) p, type, optlist, 0)) + { + retval = pdf__create_action(p, type, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + + +/********************** + * + * p_annots.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_attach_file( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *filename, + const char *description, + const char *author, + const char *mimetype, + const char *icon) +{ + static const char fn[] = "PDF_attach_file"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%T\", \"%T\", \"%T\", \"%s\", \"%s\")\n", + (void *) p, llx, lly, urx, ury, filename, 0, description, 0, + author, 0, mimetype, icon)) + { + int len_descr = description ? (int) pdc_strlen(description) : 0; + int len_auth = author ? (int) pdc_strlen(author) : 0; + + pdf__attach_file(p, llx, lly, urx, ury, filename, 0, + description, len_descr, author, len_auth, mimetype, icon); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_attach_file2( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *filename, int len_filename, + const char *description, int len_descr, + const char *author, int len_auth, + const char *mimetype, + const char *icon) +{ + static const char fn[] = "PDF_attach_file2"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%T\", /*c*/%d, \"%T\", /*c*/%d, " + "\"%T\", /*c*/%d, \"%s\", \"%s\")\n", + (void *) p, llx, lly, urx, ury, + filename, len_filename, len_filename, + description, len_descr, len_descr, + author, len_auth, len_auth, + mimetype, icon)) + { + pdf__attach_file(p, llx, lly, urx, ury, filename, len_filename, + description, len_descr, author, len_auth, mimetype, icon); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_add_note( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *contents, + const char *title, + const char *icon, + int open) +{ + static const char fn[] = "PDF_add_note"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%T\", \"%T\", \"%s\", %d)\n", + (void *) p, llx, lly, urx, ury, contents, 0, title, 0, + icon, open)) + { + int len_cont = contents ? (int) pdc_strlen(contents) : 0; + int len_title = title ? (int) pdc_strlen(title) : 0; + + pdf__add_note(p, llx, lly, urx, ury, contents, len_cont, + title, len_title, icon, open); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_add_note2( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *contents, int len_cont, + const char *title, int len_title, + const char *icon, + int open) +{ + static const char fn[] = "PDF_add_note2"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%T\", /*c*/%d, \"%T\", " + "/*c*/%d, \"%s\", %d)\n", + (void *) p, llx, lly, urx, ury, contents, len_cont, len_cont, + title, len_title, len_title, icon, open)) + { + pdf__add_note(p, llx, lly, urx, ury, contents, len_cont, + title, len_title, icon, open); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_add_pdflink( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *filename, + int page, + const char *optlist) +{ + static const char fn[] = "PDF_add_pdflink"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%s\", %d, \"%T\")\n", + (void *) p, llx, lly, urx, ury, filename, page, + optlist, 0)) + { + pdf__add_pdflink(p, llx, lly, urx, ury, filename, page, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_add_launchlink( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *filename) +{ + static const char fn[] = "PDF_add_launchlink"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%s\")\n", + (void *)p, llx, lly, urx, ury, filename)) + { + pdf__add_launchlink(p, llx, lly, urx, ury, filename); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_add_locallink( + PDF *p, + double llx, + double lly, + double urx, + double ury, + int page, + const char *optlist) +{ + static const char fn[] = "PDF_add_locallink"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, %d, \"%T\")\n", + (void *) p, llx, lly, urx, ury, page, optlist, 0)) + { + pdf__add_locallink(p, llx, lly, urx, ury, page, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_add_weblink( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *url) +{ + static const char fn[] = "PDF_add_weblink"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%s\")\n", + (void *) p, llx, lly, urx, ury, url)) + { + pdf__add_weblink(p, llx, lly, urx, ury, url); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_create_annotation( + PDF *p, + double llx, + double lly, + double urx, + double ury, + const char *type, + const char *optlist) +{ + static const char fn[] = "PDF_create_annotation"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%s\", \"%T\")\n", + (void *) p, llx, lly, urx, ury, type, optlist, 0)) + { + pdf__create_annotation(p, llx, lly, urx, ury, type, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_border_color( + PDF *p, + double red, + double green, + double blue) +{ + static const char fn[] = "PDF_set_border_color"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %f, %f, %f)\n", (void *) p, red, green, blue)) + { + pdf__set_border_color(p, red, green, blue); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_border_dash( + PDF *p, + double b, + double w) +{ + static const char fn[] = "PDF_set_border_dash"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %f, %f)\n", (void *) p, b, w)) + { + pdf__set_border_dash(p, b, w); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_border_style( + PDF *p, + const char *style, + double width) +{ + static const char fn[] = "PDF_set_border_style"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, \"%s\", %f)\n", (void *) p, style, width)) + { + pdf__set_border_style(p, style, width); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_block.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_fill_imageblock( + PDF *p, + int page, + const char *blockname, + int image, + const char *optlist) +{ + static const char fn[] = "PDF_fill_imageblock"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) pdf_state_content, + "(p_%p, %d, \"%T\", %d, \"%T\")\n", + (void *) p, page, blockname, 0, image, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, + PDF_E_UNSUPP_BLOCK_CONFIG, PDF_E_UNSUPP_BLOCK, pdc_false); + } + + return pdf_exit_boolean_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_fill_pdfblock( + PDF *p, + int page, + const char *blockname, + int contents, + const char *optlist) +{ + static const char fn[] = "PDF_fill_pdfblock"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) pdf_state_content, + "(p_%p, %d, \"%T\", %d, \"%T\")\n", + (void *) p, page, blockname, 0, contents, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, + PDF_E_UNSUPP_BLOCK_CONFIG, PDF_E_UNSUPP_BLOCK, pdc_false); + } + + return pdf_exit_boolean_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_fill_textblock( + PDF *p, + int page, + const char *blockname, + const char *text, int len, + const char *optlist) +{ + static const char fn[] = "PDF_fill_textblock"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) pdf_state_content, + "(p_%p, %d, \"%T\", \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, page, blockname, 0, text, len, len, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, + PDF_E_UNSUPP_BLOCK_CONFIG, PDF_E_UNSUPP_BLOCK, pdc_false); + } + + return pdf_exit_boolean_api(p, retval); +} + + +/********************** + * + * p_color.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_makespotcolor(PDF *p, const char *spotname, int len) +{ + static const char fn[] = "PDF_makespotcolor"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_document), + "(p_%p, \"%T\", /*c*/%d)\n", + (void *) p, spotname, len, len)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_SPOTCOLOR, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_setcolor( + PDF *p, + const char *fstype, + const char *colorspace, + double c1, double c2, double c3, double c4) +{ + static const char fn[] = "PDF_setcolor"; + int legal_states; + + if (PDF_GET_STATE(p) == pdf_state_glyph && !pdf_get_t3colorized(p)) + legal_states = pdf_state_page | pdf_state_pattern | pdf_state_template; + else + legal_states = pdf_state_content | pdf_state_document; + + if (pdf_enter_api(p, fn, (pdf_state) legal_states, + "(p_%p, \"%s\", \"%s\", %f, %f, %f, %f)\n", + (void *) p, fstype, colorspace, c1, c2, c3, c4)) + { + pdf__setcolor(p, fstype, colorspace, c1, c2, c3, c4); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setgray(PDF *p, double g) +{ + static const char fn[] = "PDF_setgray"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f)\n", + (void *) p, g)) + { + pdf__setcolor(p, "fillstroke", "gray", g, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setgray_fill(PDF *p, double gray) +{ + static const char fn[] = "PDF_setgray_fill"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f)\n", + (void *) p, gray)) + { + pdf__setcolor(p, "fill", "gray", gray, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setgray_stroke(PDF *p, double gray) +{ + static const char fn[] = "PDF_setgray_stroke"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f)\n", + (void *) p, gray)) + { + pdf__setcolor(p, "stroke", "gray", gray, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setrgbcolor(PDF *p, double r, double g, double b) +{ + static const char fn[] = "PDF_setrgbcolor"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f, %f)\n", + (void *) p, r, g, b)) + { + pdf__setcolor(p, "fillstroke", "rgb", r, g, b, 0); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setrgbcolor_fill(PDF *p, double r, double g, double b) +{ + static const char fn[] = "PDF_setrgbcolor_fill"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f, %f)\n", + (void *) p, r, g, b)) + { + pdf__setcolor(p, "fill", "rgb", r, g, b, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setrgbcolor_stroke(PDF *p, double r, double g, double b) +{ + static const char fn[] = "PDF_setrgbcolor_stroke"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f, %f)\n", + (void *) p, r, g, b)) + { + pdf__setcolor(p, "stroke", "rgb", r, g, b, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_document.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_begin_document( + PDF *p, + const char *filename, int len, + const char *optlist) +{ + static const char fn[] = "\nPDF_begin_document"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_object, + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, filename, len, len, optlist, 0)) + { + if (filename && *filename && len < 0) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "len", pdc_errprintf(p->pdc, "%d", len), 0, 0); + retval = pdf__begin_document(p, filename, len, optlist); + } + + return pdf_exit_boolean_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_begin_document_callback( + PDF *p, + size_t (*i_writeproc)(PDF *p, void *data, size_t size), + const char *optlist) +{ + static const char fn[] = "\nPDF_begin_document_callback"; + size_t (*writeproc)(PDF *, void *, size_t) = i_writeproc; + + if (pdf_enter_api(p, fn, pdf_state_object, + "(p_%p, wp_%p), \"%T\"", (void *) p, (void *) writeproc, optlist, 0)) + { + pdf__begin_document_callback(p, writeproc, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_close(PDF *p) +{ + static const char fn[] = "\nPDF_close"; + + if (pdf_enter_api(p, fn, pdf_state_document, + "(p_%p)\n", (void *) p)) + { + pdf__end_document(p, ""); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_document(PDF *p, const char *optlist) +{ + static const char fn[] = "\nPDF_end_document"; + + if (pdf_enter_api(p, fn, pdf_state_document, + "(p_%p, \"%T\")\n", (void *) p, optlist, 0)) + { + pdf__end_document(p, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_get_buffer(PDF *p, long *size) +{ + static const char fn[] = "PDF_get_buffer"; + const char *retval = NULL; + + if (!size) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "size", 0, 0, 0); + + *size = (long) 0; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document), + "(p_%p, &size_%p)\n", (void *) p, (void *) size)) + { + retval = pdf__get_buffer(p, size); + + pdc_logg_exit_api(p->pdc, pdc_false, "[%p, size=%ld]\n", + (void *) (retval), *size); + } + + return retval; +} + +PDFLIB_API int PDFLIB_CALL +PDF_open_file(PDF *p, const char *filename) +{ + static const char fn[] = "\nPDF_open_file"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_object, "(p_%p, \"%s\")\n", + (void *) p, filename)) + { + retval = pdf__begin_document(p, filename, 0, ""); + } + + return pdf_exit_boolean_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_open_mem( + PDF *p, + size_t (*i_writeproc)(PDF *p, void *data, size_t size)) +{ + static const char fn[] = "\nPDF_open_mem"; + size_t (*writeproc)(PDF *, void *, size_t) = i_writeproc; + + if (pdf_enter_api(p, fn, pdf_state_object, + "(p_%p, wp_%p)\n", (void *) p, (void *) writeproc)) + { + pdf__begin_document_callback(p, writeproc, ""); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_draw.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_arc(PDF *p, double x, double y, double r, double alpha, double beta) +{ + static const char fn[] = "PDF_arc"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_path), + "(p_%p, %f, %f, %f, %f, %f)\n", (void *) p, x, y, r, alpha, beta)) + { + pdf__arc(p, x, y, r, alpha, beta); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_arcn(PDF *p, double x, double y, double r, double alpha, double beta) +{ + static const char fn[] = "PDF_arcn"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_path), + "(p_%p, %f, %f, %f, %f, %f)\n", (void *) p, x, y, r, alpha, beta)) + { + pdf__arcn(p, x, y, r, alpha, beta); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_circle(PDF *p, double x, double y, double r) +{ + static const char fn[] = "PDF_circle"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_path), + "(p_%p, %f, %f, %f)\n", (void *) p, x, y, r)) + { + pdf__circle(p, x, y, r); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_clip(PDF *p) +{ + static const char fn[] = "PDF_clip"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__clip(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_closepath(PDF *p) +{ + static const char fn[] = "PDF_closepath"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__closepath(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_closepath_fill_stroke(PDF *p) +{ + static const char fn[] = "PDF_closepath_fill_stroke"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__closepath_fill_stroke(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_closepath_stroke(PDF *p) +{ + static const char fn[] = "PDF_closepath_stroke"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__closepath_stroke(p); + } + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); +} + +PDFLIB_API void PDFLIB_CALL +PDF_curveto(PDF *p, + double x_1, double y_1, double x_2, double y_2, double x_3, double y_3) +{ + static const char fn[] = "PDF_curveto"; + + if (pdf_enter_api(p, fn, pdf_state_path, + "(p_%p, %f, %f, %f, %f, %f, %f)\n", + (void *) p, x_1, y_1, x_2, y_2, x_3, y_3)) + { + pdf__curveto(p, x_1, y_1, x_2, y_2, x_3, y_3); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_endpath(PDF *p) +{ + static const char fn[] = "PDF_endpath"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__endpath(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_fill(PDF *p) +{ + static const char fn[] = "PDF_fill"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__fill(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_fill_stroke(PDF *p) +{ + static const char fn[] = "PDF_fill_stroke"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__fill_stroke(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_lineto(PDF *p, double x, double y) +{ + static const char fn[] = "PDF_lineto"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p, %f, %f)\n", + (void *) p, x, y)) + { + pdf__lineto(p, x, y); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_moveto(PDF *p, double x, double y) +{ + static const char fn[] = "PDF_moveto"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_path), + "(p_%p, %f, %f)\n", (void *) p, x, y)) + { + pdf__moveto(p, x, y); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_rcurveto(PDF *p, + double x_1, double y_1, double x_2, double y_2, double x_3, double y_3) +{ + static const char fn[] = "PDF_rcurveto"; + + if (pdf_enter_api(p, fn, pdf_state_path, + "(p_%p, %f, %f, %f, %f, %f, %f)\n", + (void *) p, x_1, y_1, x_2, y_2, x_3, y_3)) + { + pdf__rcurveto(p, x_1, y_1, x_2, y_2, x_3, y_3); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_rect(PDF *p, double x, double y, double width, double height) +{ + static const char fn[] = "PDF_rect"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_path), + "(p_%p, %f, %f, %f, %f)\n", (void *) p, x, y, width, height)) + { + pdf__rect(p, x, y, width, height); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_rlineto(PDF *p, double x, double y) +{ + static const char fn[] = "PDF_rlineto"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p, %f, %f)\n", + (void *) p, x, y)) + { + pdf__rlineto(p, x, y); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_rmoveto(PDF *p, double x, double y) +{ + static const char fn[] = "PDF_rmoveto"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_path), + "(p_%p, %f, %f)\n", (void *) p, x, y)) + { + pdf__rmoveto(p, x, y); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_stroke(PDF *p) +{ + static const char fn[] = "PDF_stroke"; + + if (pdf_enter_api(p, fn, pdf_state_path, "(p_%p)\n", (void *) p)) + { + pdf__stroke(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + + +/********************** + * + * p_encoding.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_encoding_set_char( + PDF *p, + const char *encoding, + int slot, + const char *glyphname, + int uv) +{ + static const char fn[] = "PDF_encoding_set_char"; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%s\", %d, \"%s\", %d/*0x%04X*/)\n", + (void *) p, encoding, slot, glyphname, uv, uv)) + { + pdf__encoding_set_char(p, encoding, slot, glyphname, uv); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_fields.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_create_field( + PDF *p, + double llx, double lly, double urx, double ury, + const char *name, int len, + const char *type, + const char *optlist) +{ + static const char fn[] = "PDF_create_field"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %f, %f, %f, %f, \"%T\", /*c*/%d, \"%s\", \"%T\")\n", + (void *) p, llx, lly, urx, ury, name, len, len, + type, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_FORMFIELDS, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +PDFLIB_API void PDFLIB_CALL +PDF_create_fieldgroup( + PDF *p, + const char *name, int len, + const char *optlist) +{ + static const char fn[] = "PDF_create_fieldgroup"; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, name, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_FORMFIELDS, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_font.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_findfont( + PDF *p, + const char *fontname, + const char *encoding, + int embed) +{ + static const char fn[] = "PDF_findfont"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content | + pdf_state_path | pdf_state_font), + "(p_%p, \"%s\", \"%s\", %d)\n", + (void *) p, fontname, encoding, embed)) + { + if (embed < 0 || embed > 1) + pdc_error(p->pdc, PDC_E_ILLARG_INT, + "embed", pdc_errprintf(p->pdc, "%d", embed), 0, 0); + + retval = pdf__load_font(p, fontname, 0, encoding, + (embed > 0) ? "embedding" : ""); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API double PDFLIB_CALL +PDF_info_font(PDF *p, int font, const char *keyword, const char *optlist) +{ + static const char fn[] = "PDF_info_font"; + double retval = 0; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%s\", \"%s\")\n", + (void *) p, font, keyword, optlist)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_FONTINFO, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + +PDFLIB_API int PDFLIB_CALL +PDF_load_font( + PDF *p, + const char *fontname, int len, + const char *encoding, + const char *optlist) +{ + static const char fn[] = "PDF_load_font"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content | + pdf_state_path | pdf_state_font), + "(p_%p, \"%T\", /*c*/%d, \"%s\", \"%T\")\n", + (void *) p, fontname, len, len, encoding, optlist, 0)) + { + retval = pdf__load_font(p, fontname, len, encoding, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + + +/********************** + * + * p_gstate.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_concat(PDF *p, double a, double b, double c, double d, double e, double f) +{ + static const char fn[] = "PDF_concat"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, %f, %f, %f, %f, %f, %f)\n", (void *) p, a, b, c, d, e, f)) + { + pdf__concat(p, a, b, c, d, e, f); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_initgraphics(PDF *p) +{ + static const char fn[] = "PDF_initgraphics"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p)\n", (void *) p)) + { + pdf__initgraphics(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_restore(PDF *p) +{ + static const char fn[] = "PDF_restore"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p)\n", (void *) p)) + { + pdf__restore(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_rotate(PDF *p, double phi) +{ + static const char fn[] = "PDF_rotate"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f)\n", + (void *) p, phi)) + { + pdf__rotate(p, phi); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_save(PDF *p) +{ + static const char fn[] = "PDF_save"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p)\n", (void *) p)) + { + pdf__save(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_scale(PDF *p, double sx, double sy) +{ + static const char fn[] = "PDF_scale"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f)\n", + (void *) p, sx, sy)) + { + pdf__scale(p, sx, sy); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setdash(PDF *p, double b, double w) +{ + static const char fn[] = "PDF_setdash"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f)\n", + (void *) p, b, w)) + { + pdf__setdash(p, b, w); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setdashpattern(PDF *p, const char *optlist) +{ + static const char fn[] = "PDF_setdashpattern"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\")\n", (void *) p, optlist, 0)) + { + pdf__setdashpattern(p, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setflat(PDF *p, double flat) +{ + static const char fn[] = "PDF_setflat"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f)\n", + (void *) p, flat)) + { + pdf__setflat(p, flat); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setlinecap(PDF *p, int cap) +{ + static const char fn[] = "PDF_setlinecap"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %d)\n", + (void *) p, cap)) + { + pdf__setlinecap(p, cap); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setlinejoin(PDF *p, int join) +{ + static const char fn[] = "PDF_setlinejoin"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %d)\n", + (void *) p, join)) + { + pdf__setlinejoin(p, join); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setlinewidth(PDF *p, double width) +{ + static const char fn[] = "PDF_setlinewidth"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f)\n", + (void *) p, width)) + { + pdf__setlinewidth(p, width); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setmatrix(PDF *p, double a, double b, double c, double d, + double e, double f) +{ + static const char fn[] = "PDF_setmatrix"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, %f, %f, %f, %f, %f, %f)\n", (void *) p, a, b, c, d, e, f)) + { + pdf__setmatrix(p, a, b, c, d, e, f); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setmiterlimit(PDF *p, double miter) +{ + static const char fn[] = "PDF_setmiterlimit"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f)\n", + (void *) p, miter)) + { + pdf__setmiterlimit(p, miter); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_setpolydash(PDF *p, float *darray, int length) +{ + static const char fn[] = "PDF_setpolydash"; + int i; + + if (!darray) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "darray", 0, 0, 0); + + for (i = 0; i < length; i++) + pdc_logg_cond(p->pdc, 1, trc_api, + "/* *(darray+%d) = %f; */\n", i, darray[i]); + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, darray_%p, /*c*/%d)\n", (void *) p, (void *) darray, length)) + { + char optlist[1024], *sopt; + + sopt = optlist; + sopt += pdc_sprintf(p->pdc, pdc_false, optlist, "dasharray {"); + for (i = 0; i < length; i++) + { + pdc_check_number_limits(p->pdc, "darray", darray[i], + 0.0, PDC_FLOAT_MAX); + sopt += pdc_sprintf(p->pdc, pdc_false, sopt, "%f ", darray[i]); + } + pdc_sprintf(p->pdc, pdc_false, sopt, "}"); + + pdf__setdashpattern(p, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_skew(PDF *p, double alpha, double beta) +{ + static const char fn[] = "PDF_skew"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f)\n", + (void *) p, alpha, beta)) + { + pdf__skew(p, alpha, beta); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_translate(PDF *p, double tx, double ty) +{ + static const char fn[] = "PDF_translate"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f)\n", + (void *) p, tx, ty)) + { + pdf__translate(p, tx, ty); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + + +/********************** + * + * p_hyper.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_add_bookmark( + PDF *p, + const char *text, + int parent, + int open) +{ + static const char fn[] = "PDF_add_bookmark"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_page | pdf_state_document), + "(p_%p, \"%T\", %d, %d)\n", (void *) p, text, 0, parent, open)) + { + int len = text ? (int) pdc_strlen(text) : 0; + retval = pdf__add_bookmark(p, text, len, parent, open); + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + + return retval; +} + +PDFLIB_API int PDFLIB_CALL +PDF_add_bookmark2( + PDF *p, + const char *text, int len, + int parent, + int open) +{ + static const char fn[] = "PDF_add_bookmark2"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_page | pdf_state_document), + "(p_%p, \"%T\", /*c*/%d, %d, %d)\n", + (void *) p, text, len, len, parent, open)) + { + retval = pdf__add_bookmark(p, text, len, parent, open); + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + + return retval; +} + +PDFLIB_API void PDFLIB_CALL +PDF_add_nameddest( + PDF *p, + const char *name, int len, + const char *optlist) +{ + static const char fn[] = "PDF_add_nameddest"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_page | pdf_state_document), + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, name, len, len, optlist, 0)) + { + pdf__add_nameddest(p, name, len, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API int PDFLIB_CALL +PDF_create_bookmark( + PDF *p, + const char *text, int len, + const char *optlist) +{ + static const char fn[] = "PDF_create_bookmark"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_page | pdf_state_document), + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, text, len, len, optlist, 0)) + { + retval = pdf__create_bookmark(p, text, len, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + return retval; +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_info(PDF *p, const char *key, const char *value) +{ + static const char fn[] = "PDF_set_info"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page), + "(p_%p, \"%T\", \"%T\")\n", + (void *) p, key, 0, value, 0)) + { + int len = value ? (int) pdc_strlen(value) : 0; + pdf__set_info(p, key, value, len); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_info2(PDF *p, const char *key, const char *value, int len) +{ + static const char fn[] = "PDF_set_info2"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page), + "(p_%p, \"%T\", \"%T\", /*c*/%d)\n", + (void *) p, key, 0, value, len, len)) + { + pdf__set_info(p, key, value, len); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_icc.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_load_iccprofile( + PDF *p, + const char *profilename, int len, + const char *optlist) +{ + static const char fn[] = "PDF_load_iccprofile"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content), + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, profilename, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_ICC, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + + +/********************** + * + * p_image.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_add_thumbnail(PDF *p, int image) +{ + static const char fn[] = "PDF_add_thumbnail"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %d)\n", (void *) p, image)) + { + if (p->pdc->hastobepos) image -= 1; + pdf__add_thumbnail(p, image); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_close_image(PDF *p, int image) +{ + static const char fn[] = "PDF_close_image"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page | pdf_state_font), + "(p_%p, %d)\n", (void *) p, image)) + { + if (p->pdc->hastobepos) image -= 1; + pdf__close_image(p, image); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_fit_image( + PDF *p, + int image, + double x, + double y, + const char *optlist) +{ + static const char fn[] = "PDF_fit_image"; + + /* scope check dependent on image type in kernel function */ + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, %f, %f, \"%T\")\n", (void *) p, image, x, y, optlist, 0)) + { + if (p->pdc->hastobepos) image -= 1; + pdf__fit_image(p, image, x, y, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API int PDFLIB_CALL +PDF_load_image( + PDF *p, + const char *type, + const char *filename, + int len, + const char *optlist) +{ + static const char fn[] = "PDF_load_image"; + int retval = -1; + + /* scope check dependent on image type in kernel function */ + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page | + pdf_state_font | pdf_state_content), + "(p_%p, \"%s\", \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, type, filename, len, len, optlist, 0)) + { + filename = pdf_convert_filename(p, filename, len, + "filename", PDC_CONV_WITHBOM); + retval = pdf__load_image(p, type, filename, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_open_CCITT( + PDF *p, + const char *filename, + int width, + int height, + int BitReverse, int K, int BlackIs1) +{ + static const char fn[] = "PDF_open_CCITT"; + int retval = -1; + + /* scope check dependent on image type in kernel function */ + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page | + pdf_state_font | pdf_state_content), + "(p_%p, \"%s\", %d, %d, %d, %d, %d)\n", + (void *) p, filename, width, height, + BitReverse, K, BlackIs1)) + { + char optlist[128]; + + pdc_sprintf(p->pdc, pdc_false, optlist, + "width %d height %d bitreverse %s K %d invert %s", + width, height, PDC_BOOLSTR(BitReverse), K, PDC_BOOLSTR(BlackIs1)); + filename = pdf_convert_filename(p, filename, 0, + "filename", PDC_CONV_WITHBOM); + retval = pdf__load_image(p, "CCITT", filename, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_open_image( + PDF *p, + const char *type, + const char *source, + const char *data, + long length, + int width, + int height, + int components, + int bpc, + const char *params) +{ + static const char fn[] = "PDF_open_image"; + int retval = -1; + + /* scope check dependent on image type in kernel function */ + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page | + pdf_state_font | pdf_state_content), + "(p_%p, \"%s\", \"%s\", idata_%p, %ld, %d, %d, %d, %d, \"%s\")\n", + (void *) p, type, source, (void *) data, length, + width, height, components, bpc, params)) + { + const char *filename = data; + char optlist[512]; + pdc_bool memory = pdc_false; + + if (type == NULL || *type == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "type", 0, 0, 0); + + if (source == NULL || *source == '\0') + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "source", 0, 0, 0); + + if (!strcmp(type, "raw") && data == NULL) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "data", 0, 0, 0); + + /* create optlist */ + optlist[0] = 0; + if (!strcmp(type, "raw") || !strcmp(type, "ccitt")) + pdc_sprintf(p->pdc, pdc_false, optlist, + "width %d height %d components %d bpc %d ", + width, height, components, bpc); + + if (length < 0L) + { + strcat(optlist, "bitreverse true "); + length = -length; + } + + strcat(optlist, "reftype "); + if (!strcmp(source, "fileref")) + strcat(optlist, "fileref "); + else if (!strcmp(source, "memory")) + { + memory = pdc_true; + strcat(optlist, "direct "); + } + else if (!strcmp(source, "url")) + strcat(optlist, "url "); + + if (params != NULL && *params != '\0') + { + char **items; + int i, nitems; + + /* separator characters because of compatibility */ + nitems = pdc_split_stringlist(p->pdc, params, "\t :", 0, &items); + for (i = 0; i < nitems; i++) + { + if (!strcmp(items[i], "invert")) + strcat(optlist, "invert true "); + else if (!strcmp(items[i], "ignoremask")) + strcat(optlist, "ignoremask true "); + else if (!strcmp(items[i], "inline")) + strcat(optlist, "inline true "); + else if (!strcmp(items[i], "interpolate")) + strcat(optlist, "interpolate true "); + else if (!strcmp(items[i], "mask")) + strcat(optlist, "mask true "); + else if (!strcmp(items[i], "/K")) + strcat(optlist, "K "); + else if (!strcmp(items[i], "/BlackIs1")) + strcat(optlist, "invert "); + else + strcat(optlist, items[i]); + } + pdc_cleanup_stringlist(p->pdc, items); + } + + /* create virtual file */ + if (memory) + { + filename = "__raw__image__data__"; + pdc__create_pvf(p->pdc, filename, data, (size_t) length, ""); + } + + filename = pdf_convert_filename(p, filename, 0, + "filename", PDC_CONV_WITHBOM); + retval = pdf__load_image(p, type, filename, (const char *) optlist); + + if (memory) + (void) pdc__delete_pvf(p->pdc, filename); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_open_image_file( + PDF *p, + const char *type, + const char *filename, + const char *stringparam, + int intparam) +{ + static const char fn[] = "PDF_open_image_file"; + int retval = -1; + + /* scope check dependent on image type in kernel function */ + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page | + pdf_state_font | pdf_state_content), + "(p_%p, \"%s\", \"%s\", \"%s\", %d)\n", + (void *) p, type, filename, stringparam, intparam)) + { + char optlist[128]; + + optlist[0] = 0; + if (stringparam != NULL && *stringparam != '\0') + { + if (!strcmp(stringparam, "invert")) + strcpy(optlist, "invert true "); + else if (!strcmp(stringparam, "inline")) + strcpy(optlist, "inline true "); + else if (!strcmp(stringparam, "ignoremask")) + strcpy(optlist, "ignoremask true "); + else if (!strcmp(stringparam, "mask")) + strcpy(optlist, "mask true "); + else if (!strcmp(stringparam, "masked")) + pdc_sprintf(p->pdc, pdc_false, optlist, "masked %d ", + intparam); + else if (!strcmp(stringparam, "colorize")) + pdc_sprintf(p->pdc, pdc_false, optlist, "colorize %d ", + intparam); + else if (!strcmp(stringparam, "page")) + pdc_sprintf(p->pdc, pdc_false, optlist, "page %d ", + intparam); + else if (!strcmp(stringparam, "iccprofile")) + pdc_sprintf(p->pdc, pdc_false, optlist, "iccprofile %d ", + intparam); + } + filename = pdf_convert_filename(p, filename, 0, + "filename", PDC_CONV_WITHBOM); + retval = pdf__load_image(p, type, filename, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_place_image( + PDF *p, + int image, + double x, + double y, + double scale) +{ + static const char fn[] = "PDF_place_image"; + + /* scope check dependent on image type in kernel function */ + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, %f, %f, %f)\n", (void *) p, image, x, y, scale)) + { + char optlist[128]; + + pdc_sprintf(p->pdc, pdc_false, optlist, "dpi none scale %f", scale); + if (p->pdc->hastobepos) image -= 1; + pdf__fit_image(p, image, x, y, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_kerning.c + * + **********************/ + +PDFLIB_API double PDFLIB_CALL +PDF_get_kern_amount( + PDF *p, + int font, + int firstchar, + int secondchar) +{ + static const char fn[] = "PDF_get_kern_amount"; + double retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content | pdf_state_path), + "(p_%p, %d, %d, %d)\n", (void *) p, font, firstchar, secondchar)) + { + if (p->pdc->hastobepos) font -= 1; + pdc_error(p->pdc, PDF_E_UNSUPP_KERNING, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + + +/********************** + * + * p_layer.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_begin_layer(PDF *p, int layer) +{ + static const char fn[] = "PDF_begin_layer"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p, %d)\n", (void *) p, layer)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_LAYER, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API int PDFLIB_CALL +PDF_define_layer( + PDF *p, + const char *name, int len, + const char *optlist) +{ + static const char fn[] = "PDF_define_layer"; + int retval = -1; + + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, name, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_LAYER, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_layer(PDF *p) +{ + static const char fn[] = "PDF_end_layer"; + + if (pdf_enter_api(p, fn, pdf_state_page, + "(p_%p)\n", (void *) p)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_LAYER, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_layer_dependency( + PDF *p, + const char *type, + const char *optlist) +{ + static const char fn[] = "PDF_set_layer_dependency"; + + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, \"%s\", \"%T\")\n", (void *) p, type, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_LAYER, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_mbox.c + * + **********************/ + + PDFLIB_API double PDFLIB_CALL + PDF_info_matchbox(PDF *p, const char *boxname, int len, int num, + const char *keyword) + { + static const char fn[] = "PDF_info_matchbox"; + double retval = 0; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_content | pdf_state_path | pdf_state_font), + "(p_%p, \"%T\", /*c*/%d, %d, \"%s\")\n", + (void *) p, boxname, len, len, num, keyword)) + { + retval = pdf__info_matchbox(p, boxname, len, num, keyword); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + + +/********************** + * + * p_object.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_delete(PDF *p) +{ + static const char fn[] = "PDF_delete"; + + if (pdf_enter_api_simple(p, fn, "(p_%p)\n", (void *) p)) + { + pdf__delete(p); + } +} + +PDFLIB_API PDF * PDFLIB_CALL +PDF_new(void) +{ + return pdf__new(NULL, NULL, NULL, NULL, NULL); +} + +PDFLIB_API PDF * PDFLIB_CALL +PDF_new2( + void (*errorhandler)(PDF *p, int type, const char *msg), + void* (*allocproc)(PDF *p, size_t size, const char *caller), + void* (*reallocproc)(PDF *p, void *mem, size_t size, const char *caller), + void (*freeproc)(PDF *p, void *mem), + void *opaque) +{ + return pdf__new(errorhandler, allocproc, reallocproc, freeproc, opaque); +} + + +/********************** + * + * p_page.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_begin_page(PDF *p, double width, double height) +{ + static const char fn[] = "\nPDF_begin_page"; + + if (pdf_enter_api(p, fn, pdf_state_document, "(p_%p, %f, %f)\n", + (void *) p, width, height)) + { + pdf__begin_page(p, width, height); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_begin_page_ext(PDF *p, double width, double height, const char *optlist) +{ + static const char fn[] = "\nPDF_begin_page_ext"; + + if (pdf_enter_api(p, fn, pdf_state_document, "(p_%p, %f, %f, \"%T\")\n", + (void *) p, width, height, optlist, 0)) + { + pdf__begin_page_ext(p, width, height, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_page(PDF *p) +{ + static const char fn[] = "PDF_end_page"; + + if (pdf_enter_api(p, fn, pdf_state_page, "(p_%p)\n", (void *) p)) + { + pdf__end_page_ext(p, ""); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_page_ext(PDF *p, const char *optlist) +{ + static const char fn[] = "PDF_end_page_ext"; + + if (pdf_enter_api(p, fn, pdf_state_page, "(p_%p, \"%T\")\n", + (void *) p, optlist, 0)) + { + pdf__end_page_ext(p, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_resume_page(PDF *p, const char *optlist) +{ + static const char fn[] = "\nPDF_resume_page"; + + if (pdf_enter_api(p, fn, pdf_state_document, "(p_%p, \"%T\")\n", + (void *) p, optlist, 0)) + { + pdf__resume_page(p, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_suspend_page(PDF *p, const char *optlist) +{ + static const char fn[] = "PDF_suspend_page"; + + if (pdf_enter_api(p, fn, pdf_state_page, "(p_%p, \"%T\")\n", + (void *) p, optlist, 0)) + { + pdf__suspend_page(p, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_parameter.c + * + **********************/ + +PDFLIB_API const char * PDFLIB_CALL +PDF_get_parameter(PDF *p, const char *key, double modifier) +{ + static const char fn[] = "PDF_get_parameter"; + const char *retval = ""; + + if (!pdc_stricmp(key, "version")) + { + retval = PDFLIB_VERSIONSTRING; + } + else if (!pdc_stricmp(key, "pdi")) + { + retval = "false"; + } + else if (pdf_enter_api(p, fn, (pdf_state) pdf_state_all, + "(p_%p, \"%s\", %f)\n", (void *) p, key, modifier)) + { + retval = pdf__get_parameter(p, key, modifier); + + pdc_logg_exit_api(p->pdc, pdc_true, "[\"%T\"]\n", retval, 0); + } + + return retval; +} + +PDFLIB_API double PDFLIB_CALL +PDF_get_value(PDF *p, const char *key, double modifier) +{ + static const char fn[] = "PDF_get_value"; + double retval = -1; + + if (!pdc_stricmp(key, "major")) + { + retval = PDFLIB_MAJORVERSION; + } + else if (!pdc_stricmp(key, "minor")) + { + retval = PDFLIB_MINORVERSION; + } + else if (!pdc_stricmp(key, "revision")) + { + retval = PDFLIB_REVISION; + } + else if (pdf_enter_api(p, fn, (pdf_state) pdf_state_all, + "(p_%p, \"%s\", %f)\n", (void *) p, key, modifier)) + { + retval = pdf__get_value(p, key, modifier); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_parameter(PDF *p, const char *key, const char *value) +{ + static const char fn[] = "PDF_set_parameter"; + + if (pdf_enter_api(p, fn, (pdf_state) pdf_state_all, + "(p_%p, \"%s\", \"%T\")\n", + (void *) p, key, value, 0)) + { + pdf__set_parameter(p, key, value); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_value(PDF *p, const char *key, double value) +{ + static const char fn[] = "PDF_set_value"; + + if (pdf_enter_api(p, fn, (pdf_state) pdf_state_all, + "(p_%p, \"%s\", %f)\n", (void *) p, key, value)) + { + pdf__set_value(p, key, value); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + + +/********************** + * + * p_pattern.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_begin_pattern( + PDF *p, + double width, + double height, + double xstep, + double ystep, + int painttype) +{ + static const char fn[] = "\nPDF_begin_pattern"; + int retval = -1; + + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %f, %f, %f, %f, %d)\n", + (void *) p, width, height, xstep, ystep, painttype)) + { + retval = pdf__begin_pattern(p, width, height, xstep, ystep, painttype); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_pattern(PDF *p) +{ + static const char fn[] = "PDF_end_pattern"; + + if (pdf_enter_api(p, fn, pdf_state_pattern, "(p_%p)\n", (void *) p)) + { + pdf__end_pattern(p); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_pdi.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_close_pdi(PDF *p, int doc) +{ + static const char fn[] = "PDF_close_pdi"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page), + "(p_%p, %d)\n", (void *) p, doc)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_close_pdi_document(PDF *p, int doc) +{ + static const char fn[] = "PDF_close_pdi_document"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page), + "(p_%p, %d)\n", (void *) p, doc)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_close_pdi_page(PDF *p, int page) +{ + static const char fn[] = "PDF_close_pdi_page"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %d)\n", (void *) p, page)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_fit_pdi_page(PDF *p, int page, double x, double y, const char *optlist) +{ + static const char fn[] = "PDF_fit_pdi_page"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, %d, %f, %f, \"%T\")\n", (void *) p, page, x, y, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API const char *PDFLIB_CALL +PDF_get_pdi_parameter( + PDF *p, + const char *key, + int doc, + int page, + int reserved, + int *len) +{ + static const char fn[] = "PDF_get_pdi_parameter"; + const char *retval = ""; + + if (len) + *len = 0; + + if (pdf_enter_api(p, fn, pdf_state_all, + len ? "(p_%p, \"%s\", %d, %d, %d, /*c*/&len_%p)" : + "(p_%p, \"%s\", %d, %d, %d, /*c*/NULL)\n", + (void *) p, key, doc, page, reserved, len)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, "[\"%T\"]\n", retval, 0); + } + + return retval; +} + +PDFLIB_API double PDFLIB_CALL +PDF_get_pdi_value( + PDF *p, + const char *key, + int doc, + int page, + int reserved) +{ + static const char fn[] = "PDF_get_pdi_value"; + double retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%s\", %d, %d, %d)\n", + (void *) p, key, doc, page, reserved)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi( + PDF *p, + const char *filename, + const char *optlist, + int len) +{ + static const char fn[] = "PDF_open_pdi"; + int retval = -1; + + /* state "object" doesn't make sense until PDFlib can handle this, + ** but is allowed here for version compatibility + */ + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page), + "(p_%p, \"%T\", \"%T\", %d)\n", + (void *) p, filename, len, optlist, 0, len)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi_document( + PDF *p, + const char *filename, + int len, + const char *optlist) +{ + static const char fn[] = "PDF_open_pdi_document"; + int retval = -1; + + /* state "object" doesn't make sense until PDFlib can handle this, + ** but is allowed here for version compatibility + */ + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page), + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, filename, len, len, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi_callback( + PDF *p, + void *opaque, + size_t filesize, + size_t (*readproc)(void *opaque, void *buffer, size_t size), + int (*seekproc)(void *opaque, long offset), + const char *optlist) +{ + static const char fn[] = "PDF_open_pdi_callback"; + int retval = -1; + + /* state "object" doesn't make sense until PDFlib can handle this, + ** but is allowed here for version compatibility + */ + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_object | pdf_state_document | pdf_state_page), + "(p_%p, opaque_%p, %ld, readproc_%p, seekproc_%p \"%T\")\n", + (void *)p, opaque, filesize, readproc, seekproc, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + } + + return pdf_exit_handle_api(p, retval); +} + + +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi_page(PDF *p, int doc, int pagenumber, const char* optlist) +{ + static const char fn[] = "PDF_open_pdi_page"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %d, %d, \"%T\")\n", (void *) p, doc, pagenumber, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + } + + return pdf_exit_handle_api(p, retval); +} + +/* pCOS "context free parameters" +*/ +typedef enum +{ + cfp_none, cfp_major, cfp_minor, cfp_revision, cfp_version +} pcos_cfp; + +static pcos_cfp +get_pcos_cfp(const char *fmt, va_list args) +{ + const char *cfp = fmt; + + if (strcmp(fmt, "%s") == 0) + cfp = va_arg(args, char *); + + if (strcmp(cfp, "major") == 0) + return cfp_major; + + if (strcmp(cfp, "minor") == 0) + return cfp_minor; + + if (strcmp(cfp, "revision") == 0) + return cfp_revision; + + if (strcmp(cfp, "version") == 0) + return cfp_version; + + return cfp_none; +} /* get_pcos_cfp */ + + +PDFLIB_API double PDFLIB_CALL +PDF_pcos_get_number(PDF *p, int doc, const char *path, ...) +{ + static const char fn[] = "PDF_pcos_get_number"; + + double result = 0; + pcos_cfp cfp; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%s\")\n", (void *) p, doc, path)) + { + va_list args; + + if (!path) + path = ""; + + va_start(args, path); + cfp = get_pcos_cfp(path, args); + va_end(args); + + switch (cfp) + { + case cfp_major: + result = PDFLIB_MAJORVERSION; + break; + + case cfp_minor: + result = PDFLIB_MINORVERSION; + break; + + case cfp_revision: + result = PDFLIB_REVISION; + break; + + default: + { + pdc_set_unsupp_error(p->pdc, + PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, pdc_false); + break; + } + } /* switch */ + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", result); + } + return result; +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_pcos_get_string(PDF *p, int doc, const char *path, ...) +{ + static const char fn[] = "PDF_pcos_get_string"; + + const char *result = ""; + pcos_cfp cfp; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%s\")\n", (void *) p, doc, path)) + { + va_list args; + + if (!path) + path = ""; + + va_start(args, path); + cfp = get_pcos_cfp(path, args); + va_end(args); + + switch (cfp) + { + case cfp_version: + result = PDFLIB_VERSIONSTRING; + break; + + default: + { + pdc_set_unsupp_error(p->pdc, + PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, pdc_false); + break; + } + } /* switch */ + + pdc_logg_exit_api(p->pdc, pdc_true, "[\"%T\"]\n", result, 0); + } + return result; +} + +PDFLIB_API const unsigned char * PDFLIB_CALL +PDF_pcos_get_stream( + PDF *p, int doc, int *len, const char *optlist, const char *path, ...) +{ + static const char fn[] = "PDF_pcos_get_stream"; + + const unsigned char *result = (const unsigned char *) ""; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%s\", \"%s\")\n", (void *) p, doc, optlist, path)) + { + int length = 0; + + *len = 0; + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, "[\"%T\", len=%d]\n", + result, length, length); + } + + return result; +} + +PDFLIB_API void PDFLIB_CALL +PDF_place_pdi_page(PDF *p, int page, double x, double y, double sx, double sy) +{ + static const char fn[] = "PDF_place_pdi_page"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, %d, %f, %f, %f, %f)\n", (void *) p, page, x, y, sx, sy)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API int PDFLIB_CALL +PDF_process_pdi(PDF *p, int doc, int page, const char *optlist) +{ + static const char fn[] = "PDF_process_pdi"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document), + "(p_%p, %d, %d, \"%T\")\n", (void *) p, doc, page, optlist, 0)) + { + pdc_set_unsupp_error(p->pdc, PDF_E_UNSUPP_PDI_CONFIG, PDF_E_UNSUPP_PDI, + pdc_false); + } + + return pdf_exit_boolean_api(p, retval); +} + + +/********************** + * + * p_resource.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_create_pvf( + PDF *p, const char *filename, int len, + const void *data, size_t size, + const char *optlist) +{ + static const char fn[] = "PDF_create_pvf"; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%T\", /*c*/%d, data_%p, /*c*/%d, \"%T\")\n", + (void *) p, filename, len, len, data, size, optlist, 0)) + { + filename = pdf_convert_filename(p, filename, len, "filename", 0); + pdc__create_pvf(p->pdc, filename, data, size, optlist); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API int PDFLIB_CALL +PDF_delete_pvf(PDF *p, const char *filename, int len) +{ + static const char fn[] = "PDF_delete_pvf"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%T\", /*c*/%d)\n", + (void *) p, filename, len, len)) + { + filename = pdf_convert_filename(p, filename, len, "filename", 0); + retval = pdc__delete_pvf(p->pdc, filename); + } + + return pdf_exit_boolean_api(p, retval); +} + + +/********************** + * + * p_shading.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_shading( + PDF *p, + const char *type, + double x_0, double y_0, + double x_1, double y_1, + double c_1, double c_2, double c_3, double c_4, + const char *optlist) +{ + static const char fn[] = "PDF_shading"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page | pdf_state_font), + "(p_%p, \"%s\", %f, %f, %f, %f, %f, %f, %f, %f, \"%T\")\n", + (void *) p, type, x_0, y_0, x_1, y_1, c_1, c_2, c_3, c_4, + optlist, 0)) + { + retval = pdf__shading(p, type, x_0, y_0, x_1, y_1, + c_1, c_2, c_3, c_4, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_shading_pattern(PDF *p, int shading, const char *optlist) +{ + static const char fn[] = "PDF_shading_pattern"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_page | pdf_state_font), + "(p_%p, %d, \"%T\")\n", (void *) p, shading, optlist, 0)) + { + if (p->pdc->hastobepos) shading -= 1; + retval = pdf__shading_pattern(p, shading, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_shfill(PDF *p, int shading) +{ + static const char fn[] = "PDF_shfill"; + int legal_states; + + if (PDF_GET_STATE(p) == pdf_state_glyph && !pdf_get_t3colorized(p)) + legal_states = pdf_state_page | pdf_state_pattern | pdf_state_template; + + else if (PDF_GET_STATE(p) == pdf_state_pattern && + pdf_get_shading_painttype(p) == 2) + legal_states = pdf_state_page | pdf_state_glyph | pdf_state_template; + + else + legal_states = pdf_state_content; + + if (pdf_enter_api(p, fn, (pdf_state) legal_states, + "(p_%p, %d)\n", (void *) p, shading)) + { + if (p->pdc->hastobepos) shading -= 1; + pdf__shfill(p, shading); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_table.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_add_table_cell(PDF *p, int table, int column, int row, const char *text, + int len, const char *optlist) +{ + static const char fn[] = "PDF_add_table_cell"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, %d, %d, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, table, column, row, text, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TABLES, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_delete_table(PDF *p, int table, const char *optlist) +{ + static const char fn[] = "PDF_delete_table"; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%T\")\n", (void *) p, table, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TABLES, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_fit_table(PDF *p, int table, double llx, double lly, + double urx, double ury, const char *optlist) +{ + static const char fn[] = "PDF_fit_table"; + const char *retval = ""; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, %d, %f, %f, %f, %f, \"%T\")\n", + (void *) p, table, llx, lly, urx, ury, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TABLES, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, "[\"%s\"]\n", retval); + } + + return retval; +} + +PDFLIB_API double PDFLIB_CALL +PDF_info_table(PDF *p, int table, const char *keyword) +{ + static const char fn[] = "PDF_info_table"; + double retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%s\")\n", (void *) p, table, keyword)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TABLES, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + + +/********************** + * + * p_tagged.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_begin_mc(PDF *p, const char *tag, const char *optlist) +{ + static const char fn[] = "PDF_begin_mc"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%s\", \"%T\")\n", (void *) p, tag, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_MC, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_mc(PDF *p) +{ + static const char fn[] = "PDF_end_mc"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p", (void *) p)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_MC, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_mc_point(PDF *p, const char *tag, const char *optlist) +{ + static const char fn[] = "PDF_mc_point"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%s\", \"%T\")\n", (void *) p, tag, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_MC, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_activate_item(PDF *p, int id) +{ + static const char fn[] = "PDF_activate_item"; + + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %d)\n", (void *) p, id)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TAGGED, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API int PDFLIB_CALL +PDF_begin_item( + PDF *p, + const char *tag, + const char *optlist) +{ + static const char fn[] = "PDF_begin_item"; + int retval = -1; + + /* further check in kernel function */ + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, \"%s\", \"%T\")\n", (void *) p, tag, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TAGGED, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + return retval; +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_item(PDF *p, int id) +{ + static const char fn[] = "PDF_end_item"; + + /* further check in kernel function */ + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %d)\n", (void *) p, id)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TAGGED, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_template.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_begin_template(PDF *p, double width, double height) +{ + static const char fn[] = "\nPDF_begin_template"; + int retval = -1; + + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, %f, %f)\n", (void *) p, width, height)) + { + retval = pdf__begin_template(p, width, height, ""); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_begin_template_ext(PDF *p, double width, double height, const char *optlist) +{ + static const char fn[] = "\nPDF_begin_template_ext"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_document, "(p_%p, %f, %f, \"%T\")\n", + (void *) p, width, height, optlist, 0)) + { + retval = pdf__begin_template(p, width, height, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_template(PDF *p) +{ + static const char fn[] = "PDF_end_template"; + + if (pdf_enter_api(p, fn, pdf_state_template, "(p_%p)\n", (void *) p)) + { + pdf__end_template(p); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + + +/********************** + * + * p_text.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_continue_text(PDF *p, const char *text) +{ + static const char fn[] = "PDF_continue_text"; + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, \"%T\")\n", + (void *) p, text, 0)) + { + int len = text ? (int) strlen(text) : 0; + pdf__show_text(p, text, len, pdc_true); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_continue_text2(PDF *p, const char *text, int len) +{ + static const char fn[] = "PDF_continue_text2"; + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\", /*c*/%d)\n", (void *) p, text, len, len)) + { + pdf__show_text(p, text, len, pdc_true); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_fit_textline(PDF *p, const char *text, int len, double x, double y, + const char *optlist) +{ + static const char fn[] = "PDF_fit_textline"; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\", /*c*/%d, %f, %f, \"%T\")\n", + (void *) p, text, len, len, x, y, optlist, 0)) + { + pdf__fit_textline(p, text, len, x, y, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API double PDFLIB_CALL +PDF_info_textline(PDF *p, const char *text, int len, const char *keyword, + const char *optlist) +{ + static const char fn[] = "PDF_info_textline"; + double retval = 0; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content | + pdf_state_path | pdf_state_font), + "(p_%p, \"%T\", /*c*/%d, \"%s\", \"%T\")\n", + (void *) p, text, len, len, keyword, optlist, 0)) + { + retval = pdf__info_textline(p, text, len, keyword, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + +PDFLIB_API void PDFLIB_CALL +PDF_setfont(PDF *p, int font, double fontsize) +{ + static const char fn[] = "PDF_setfont"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %d, %f)\n", + (void *) p, font, fontsize)) + { + if (p->pdc->hastobepos) font -= 1; + pdf__setfont(p, font, fontsize); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_text_pos(PDF *p, double x, double y) +{ + static const char fn[] = "PDF_set_text_pos"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %f, %f)\n", + (void *) p, x, y)) + { + pdf__set_text_pos(p, x, y); + + pdc_logg_exit_api(p->pdc, pdc_false, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_show(PDF *p, const char *text) +{ + static const char fn[] = "PDF_show"; + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, \"%T\")\n", + (void *) p, text, 0)) + { + int len = text ? (int) strlen(text) : 0; + + pdf__show_text(p, text, len, pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_show2(PDF *p, const char *text, int len) +{ + static const char fn[] = "PDF_show2"; + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\", /*c*/%d)\n", (void *) p, text, len, len)) + { + pdf__show_text(p, text, len, pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API int PDFLIB_CALL +PDF_show_boxed( + PDF *p, + const char *text, + double left, + double bottom, + double width, + double height, + const char *hmode, + const char *feature) +{ + static const char fn[] = "PDF_show_boxed"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\", %f, %f, %f, %f, \"%s\", \"%s\")\n", + (void *) p, text, 0, left, bottom, width, height, hmode, feature)) + { + retval = pdf__show_boxed(p, text, 0, left, bottom, width, height, + hmode, feature); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + + return retval; +} + +PDFLIB_API int PDFLIB_CALL +PDF_show_boxed2( + PDF *p, + const char *text, + int len, + double left, + double bottom, + double width, + double height, + const char *hmode, + const char *feature) +{ + static const char fn[] = "PDF_show_boxed2"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\", /*c*/%d, %f, %f, %f, %f, \"%s\", \"%s\")\n", + (void *) p, text, len, len, left, bottom, width, height, + hmode, feature)) + { + retval = pdf__show_boxed(p, text, len, left, bottom, width, height, + hmode, feature); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%d]\n", retval); + } + + return retval; +} + +PDFLIB_API void PDFLIB_CALL +PDF_show_xy(PDF *p, const char *text, double x, double y) +{ + static const char fn[] = "PDF_show_xy"; + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, \"%T\", %f, %f)\n", + (void *) p, text, 0, x, y)) + { + int len = text ? (int) strlen(text) : 0; + pdf__set_text_pos(p, x, y); + pdf__show_text(p, text, len, pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_show_xy2(PDF *p, const char *text, int len, double x, double y) +{ + static const char fn[] = "PDF_show_xy2"; + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\", /*c*/%d, %f, %f)\n", + (void *) p, text, len, len, x, y)) + { + pdf__set_text_pos(p, x, y); + pdf__show_text(p, text, len, pdc_false); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API double PDFLIB_CALL +PDF_stringwidth(PDF *p, const char *text, int font, double fontsize) +{ + static const char fn[] = "PDF_stringwidth"; + double retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content | + pdf_state_path | pdf_state_font), + "(p_%p, \"%T\", %d, %f)\n", + (void *) p, text, 0, font, fontsize)) + { + int len = text ? (int) strlen(text) : 0; + if (p->pdc->hastobepos) font -= 1; + retval = pdf__stringwidth(p, text, len, font, fontsize); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + +PDFLIB_API double PDFLIB_CALL +PDF_stringwidth2(PDF *p, const char *text, int len, int font, double fontsize) +{ + static const char fn[] = "PDF_stringwidth2"; + double retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content | + pdf_state_path | pdf_state_font), + "(p_%p, \"%T\", /*c*/%d, %d, %f)\n", + (void *) p, text, len, len, font, fontsize)) + { + if (p->pdc->hastobepos) font -= 1; + retval = pdf__stringwidth(p, text, len, font, fontsize); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + +PDFLIB_API void PDFLIB_CALL +PDF_xshow(PDF *p, const char *text, int len, const double *xadvancelist) +{ + static const char fn[] = "PDF_xshow"; + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, \"%T\", %d, %p)\n", (void *) p, text, len, len, xadvancelist)) + { + pdf__xshow(p, text, len, xadvancelist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_textflow.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_add_textflow(PDF *p, int textflow, const char *text, int len, + const char *optlist) +{ + static const char fn[] = "PDF_add_textflow"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, textflow, text, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TEXTFLOWS, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API int PDFLIB_CALL +PDF_create_textflow(PDF *p, const char *text, int len, const char *optlist) +{ + static const char fn[] = "PDF_create_textflow"; + int retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%T\", /*c*/%d, \"%T\")\n", + (void *) p, text, len, len, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TEXTFLOWS, 0, 0, 0, 0); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_delete_textflow(PDF *p, int textflow) +{ + static const char fn[] = "PDF_delete_textflow"; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d)\n", (void *) p, textflow)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TEXTFLOWS, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_fit_textflow( + PDF *p, + int textflow, + double llx, + double lly, + double urx, + double ury, + const char *optlist) +{ + static const char fn[] = "PDF_fit_textflow"; + const char *retval = ""; + + if (pdf_enter_api(p, fn, pdf_state_content, + "(p_%p, %d, %f, %f, %f, %f, \"%T\")\n", + (void *) p, textflow, llx, lly, urx, ury, optlist, 0)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TEXTFLOWS, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, "[\"%s\"]\n", retval); + } + + return retval; +} + +PDFLIB_API double PDFLIB_CALL +PDF_info_textflow(PDF *p, int textflow, const char *keyword) +{ + static const char fn[] = "PDF_info_textflow"; + double retval = -1; + + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, %d, \"%s\")\n", (void *) p, textflow, keyword)) + { + pdc_error(p->pdc, PDF_E_UNSUPP_TEXTFLOWS, 0, 0, 0, 0); + + pdc_logg_exit_api(p->pdc, pdc_true, "[%f]\n", retval); + } + + return retval; +} + + +/********************** + * + * p_type3.c + * + **********************/ + +PDFLIB_API void PDFLIB_CALL +PDF_begin_font( + PDF *p, + const char *fontname, int len, + double a, double b, double c, double d, double e, double f, + const char *optlist) +{ + static const char fn[] = "\nPDF_begin_font"; + + if (pdf_enter_api(p, fn, (pdf_state) (pdf_state_document | pdf_state_page), + "(p_%p, \"%T\", /*c*/%d, %f, %f, %f, %f, %f, %f, \"%T\")\n", + (void *) p, fontname, len, len, a, b, c, d, e, f, optlist, 0)) + { + pdf__begin_font(p, fontname, len, a, b, c, d, e, f, optlist); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_begin_glyph( + PDF *p, + const char *glyphname, + double wx, double llx, double lly, double urx, double ury) +{ + static const char fn[] = "\nPDF_begin_glyph"; + + if (pdf_enter_api(p, fn, pdf_state_font, + "(p_%p, \"%s\", %f, %f, %f, %f, %f)\n", + (void *) p, glyphname, wx, llx, lly, urx, ury)) + { + pdf__begin_glyph(p, glyphname, wx, llx, lly, urx, ury); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + +PDFLIB_API void PDFLIB_CALL +PDF_end_font(PDF *p) +{ + static const char fn[] = "\nPDF_end_font"; + + if (pdf_enter_api(p, fn, pdf_state_font, "(p_%p)\n", (void *) p)) + { + pdf__end_font(p); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +PDFLIB_API void PDFLIB_CALL +PDF_end_glyph(PDF *p) +{ + static const char fn[] = "PDF_end_glyph"; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_glyph | pdf_state_glyphmetric | + pdf_state_glyphignore), + "(p_%p)\n", (void *) p)) + { + pdf__end_glyph(p); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} + + +/********************** + * + * p_util.c + * + **********************/ + +PDFLIB_API const char * PDFLIB_CALL +PDF_utf16_to_utf8(PDF *p, const char *utf16string, int len, int *size) +{ + static const char fn[] = "PDF_utf16_to_utf8"; + const char *retval = ""; + + if (pdf__check_context(p)) + { + if (p->pdc->unicaplang) + { + retval = pdf__utf16_to_utf8(p, utf16string, len, size); + } + else + { + pdc_logg_cond(p->pdc, 1, trc_api, "/* "); + if (pdf_enter_api(p, fn, pdf_state_all, + size ? "(p_%p, \"%T\", %d, &size_%p)" : + "(p_%p, \"%s\", %d, NULL) */\n", + (void *) p, utf16string, len, len, (void *) size)) + { + retval = pdf__utf16_to_utf8(p, utf16string, len, size); + } + + pdc_logg_exit_api(p->pdc, pdc_false, "/* [\"%T\", size=%d] */\n", + retval, 0, size ? *size : 0); + } + } + + return retval; +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_utf32_to_utf16(PDF *p, const char *utf32string, int len, + const char *ordering, int *size) +{ + static const char fn[] = "PDF_utf32_to_utf16"; + const char *retval = ""; + + if (pdf__check_context(p)) + { + if (p->pdc->unicaplang) + { + retval = pdf__utf32_to_utf16(p, utf32string, len, ordering, size); + } + else + { + if (size == NULL) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "size", 0, 0, 0); + + pdc_logg_cond(p->pdc, 1, trc_api, "/* "); + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%T\", %d, \"%s\", &size_%p) */\n", + (void *) p, utf32string, len, len, ordering, (void *) size)) + { + retval = pdf__utf32_to_utf16(p, utf32string, + len, ordering, size); + } + + pdc_logg_exit_api(p->pdc, pdc_false, "/* [\"%T\", size=%d] */\n", + retval, *size, *size); + } + } + + return retval; +} + +PDFLIB_API const char * PDFLIB_CALL +PDF_utf8_to_utf16(PDF *p, const char *utf8string, const char *format, + int *size) +{ + static const char fn[] = "PDF_utf8_to_utf16"; + const char *retval = ""; + + if (pdf__check_context(p)) + { + if (p->pdc->unicaplang) + { + retval = pdf__utf8_to_utf16(p, utf8string, format, size); + } + else + { + if (size == NULL) + pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "size", 0, 0, 0); + + pdc_logg_cond(p->pdc, 1, trc_api, "/* "); + if (pdf_enter_api(p, fn, pdf_state_all, + "(p_%p, \"%T\", \"%s\", &size_%p) */\n", + (void *) p, utf8string, 0, format, (void *) size)) + { + retval = pdf__utf8_to_utf16(p, utf8string, format, size); + } + + pdc_logg_exit_api(p->pdc, pdc_false, "/* [\"%T\", size=%d] */\n", + retval, *size, *size); + } + } + + return retval; +} + + +/********************** + * + * p_xgstate.c + * + **********************/ + +PDFLIB_API int PDFLIB_CALL +PDF_create_gstate(PDF *p, const char *optlist) +{ + static const char fn[] = "PDF_create_gstate"; + int retval = -1; + + if (pdf_enter_api(p, fn, + (pdf_state) (pdf_state_document | pdf_state_content), + "(p_%p, \"%T\")\n", (void *) p, optlist, 0)) + { + retval = pdf__create_gstate(p, optlist); + } + + return pdf_exit_handle_api(p, retval); +} + +PDFLIB_API void PDFLIB_CALL +PDF_set_gstate(PDF *p, int gstate) +{ + static const char fn[] = "PDF_set_gstate"; + + if (pdf_enter_api(p, fn, pdf_state_content, "(p_%p, %d)\n", + (void *) p, gstate)) + { + if (p->pdc->hastobepos) gstate -= 1; + pdf__set_gstate(p, gstate); + + pdc_logg_exit_api(p->pdc, pdc_true, NULL); + } +} diff --git a/src/pdflib/pdflib/pdflib.h b/src/pdflib/pdflib/pdflib.h new file mode 100644 index 0000000..23468dd --- /dev/null +++ b/src/pdflib/pdflib/pdflib.h @@ -0,0 +1,1572 @@ +/*---------------------------------------------------------------------------* + | PDFlib - A library for generating PDF on the fly | + +---------------------------------------------------------------------------+ + | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. | + +---------------------------------------------------------------------------+ + | | + | This software is subject to the PDFlib license. It is NOT in the | + | public domain. Extended versions and commercial licenses are | + | available, please check http://www.pdflib.com. | + | | + *---------------------------------------------------------------------------*/ + +/* $Id: pdflib.h,v 1.1 2008/10/17 06:11:49 scuri Exp $ + * + * Public function declarations for PDFlib Lite, PDFlib, PDFlib+PDI, and PPS; + * see PDFlib API reference for details. + * + */ + +#ifndef PDFLIB_H +#define PDFLIB_H + +/* Make our declarations C++ compatible */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define PDFLIB_PRODUCTNAME "PDFlib" + +/* + * The version defines below can be used to check the version of the + * include file against the library. + */ + +#define PDFLIB_MAJORVERSION 7 /* major version number */ +#define PDFLIB_MINORVERSION 0 /* minor version number */ +#define PDFLIB_REVISION 2 /* revision number */ +#define PDFLIB_VERSIONSTRING "7.0.2" /* The whole bunch */ + + +/* + * ---------------------------------------------------------------------- + * Setup, mostly Windows calling conventions and DLL stuff + * ---------------------------------------------------------------------- + */ + +#if defined(WIN32) && !defined(PDFLIB_CALL) + #define PDFLIB_CALL __cdecl +#endif + +#if defined(WIN32) + + #ifdef PDFLIB_EXPORTS + #define PDFLIB_API __declspec(dllexport) /* prepare a DLL (internal use) */ + + #elif defined(PDFLIB_DLL) + + #define PDFLIB_API __declspec(dllimport) /* PDFlib clients: import DLL */ + #endif /* PDFLIB_DLL */ + +#endif /* WIN32 */ + +#if !defined(WIN32) && \ + ((defined __IBMC__ || defined __IBMCPP__) && defined __DLL__ && defined OS2) + #define PDFLIB_CALL _Export + #define PDFLIB_API +#endif /* IBM VisualAge C++ DLL */ + +#ifndef PDFLIB_CALL + #define PDFLIB_CALL /* */ /* default: no special calling conventions */ +#endif + +#ifndef PDFLIB_API + #define PDFLIB_API /* */ /* default: generate or use static library */ +#endif + +/* Define the basic PDF type. This is used opaquely at the API level. */ +#if !defined(PDF) || defined(ACTIVEX) + typedef struct PDF_s PDF; +#endif /* !PDF */ + +/* Export the API functions when creating a shared library on the Mac with CW */ +#if defined(__MWERKS__) && defined(PDFLIB_EXPORTS) +#pragma export on +#endif + +/* The API structure with function pointers. */ +typedef struct PDFlib_api_s PDFlib_api; + + +/* + * ---------------------------------------------------------------------- + * Function prototypes for all supported API functions + * ---------------------------------------------------------------------- + */ + +/* Activate a previously created structure element or other content item. */ +PDFLIB_API void PDFLIB_CALL +PDF_activate_item(PDF *p, int id); + +/* Deprecated, use PDF_create_bookmark(). */ +PDFLIB_API int PDFLIB_CALL +PDF_add_bookmark(PDF *p, const char *text, int parent, int open); + +/* Deprecated, use PDF_create_bookmark(). */ +PDFLIB_API int PDFLIB_CALL +PDF_add_bookmark2(PDF *p, const char *text, int len, int parent, int open); + +/* Deprecated, use PDF_create_action() and PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_add_launchlink(PDF *p, double llx, double lly, double urx, double ury, + const char *filename); + +/* Deprecated, use PDF_create_action() and PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_add_locallink(PDF *p, double llx, double lly, double urx, double ury, + int page, const char *optlist); + +/* Create a named destination on an arbitrary page in the current document. */ +PDFLIB_API void PDFLIB_CALL +PDF_add_nameddest(PDF *p, const char *name, int len, const char *optlist); + +/* Deprecated, use PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_add_note(PDF *p, double llx, double lly, double urx, double ury, + const char *contents, const char *title, const char *icon, int open); + +/* Deprecated, use PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_add_note2(PDF *p, double llx, double lly, double urx, double ury, + const char *contents, int len_cont, const char *title, int len_title, + const char *icon, int open); + +/* Deprecated, use PDF_create_action() and PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_add_pdflink(PDF *p, double llx, double lly, double urx, double ury, + const char *filename, int page, const char *optlist); + +/* Add a cell to a new or existing table. + Returns: A table handle which can be used in subsequent table-related calls. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_add_table_cell(PDF *p, int table, int column, int row, const char *text, + int len, const char *optlist); + +/* Create a Textflow object, or add text and explicit options to an existing + Textflow. + Returns: A Textflow handle, or -1 (in PHP: 0) on error. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_add_textflow(PDF *p, int textflow, const char *text, int len, + const char *optlist); + +/* Add an existing image as thumbnail for the current page. */ +PDFLIB_API void PDFLIB_CALL +PDF_add_thumbnail(PDF *p, int image); + +/* Deprecated, use PDF_create_action() and PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_add_weblink(PDF *p, double llx, double lly, double urx, double ury, + const char *url); + +/* Draw a counterclockwise circular arc segment. */ +PDFLIB_API void PDFLIB_CALL +PDF_arc(PDF *p, double x, double y, double r, double alpha, double beta); + +/* Draw a clockwise circular arc segment. */ +PDFLIB_API void PDFLIB_CALL +PDF_arcn(PDF *p, double x, double y, double r, double alpha, double beta); + +/* Deprecated, use PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_attach_file(PDF *p, double llx, double lly, double urx, double ury, + const char *filename, const char *description, const char *author, + const char *mimetype, const char *icon); + +/* Deprecated, use PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_attach_file2(PDF *p, double llx, double lly, double urx, double ury, + const char *filename, int len_filename, const char *description, + int len_descr, const char *author, int len_auth, const char *mimetype, + const char *icon); + +/* Create a new PDF file subject to various options. + Returns: -1 (in PHP: 0) on error, and 1 otherwise. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_begin_document(PDF *p, const char *filename, int len, const char *optlist); + +/* Create a new PDF document subject to various options. */ +typedef size_t (*writeproc_t)(PDF *p1, void *data, size_t size); +PDFLIB_API void PDFLIB_CALL +PDF_begin_document_callback(PDF *p, writeproc_t writeproc, const char *optlist); + +/* Start a Type 3 font definition. */ +PDFLIB_API void PDFLIB_CALL +PDF_begin_font(PDF *p, const char *fontname, int len, + double a, double b, double c, double d, double e, double f, + const char *optlist); + +/* Start a glyph definition for a Type 3 font. */ +PDFLIB_API void PDFLIB_CALL +PDF_begin_glyph(PDF *p, const char *glyphname, double wx, + double llx, double lly, double urx, double ury); + +/* Open a structure element or other content item with attributes supplied + as options. + Returns: An item handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_begin_item(PDF *p, const char *tag, const char *optlist); + +/* Start a layer for subsequent output on the page (requires PDF 1.5). */ +PDFLIB_API void PDFLIB_CALL +PDF_begin_layer(PDF *p, int layer); + +/* Begin a marked content sequence with or without properties (unsupported). */ +PDFLIB_API void PDFLIB_CALL +PDF_begin_mc(PDF *p, const char *tag, const char *optlist); + +/* Deprecated, use PDF_begin_page_ext(). */ +PDFLIB_API void PDFLIB_CALL +PDF_begin_page(PDF *p, double width, double height); + +/* Add a new page to the document, and specify various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_begin_page_ext(PDF *p, double width, double height, const char *optlist); + +/* Start a pattern definition. + Returns: A pattern handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_begin_pattern(PDF *p, + double width, double height, double xstep, double ystep, int painttype); + +/* Deprecated, use PDF_begin_template_ext(). */ +PDFLIB_API int PDFLIB_CALL +PDF_begin_template(PDF *p, double width, double height); + +/* Start a template definition. + Returns: A template handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_begin_template_ext(PDF *p, double width, double height, + const char *optlist); + +/* Deprecated, and not required. */ +PDFLIB_API void PDFLIB_CALL +PDF_boot(void); + +/* Check the validity of a PDFlib context (unsupported). */ +PDFLIB_API int PDFLIB_CALL +PDF_check_context(PDF *p); + +/* Draw a circle. */ +PDFLIB_API void PDFLIB_CALL +PDF_circle(PDF *p, double x, double y, double r); + +/* Use the current path as clipping path, and terminate the path. */ +PDFLIB_API void PDFLIB_CALL +PDF_clip(PDF *p); + +/* Deprecated, use PDF_end_document(). */ +PDFLIB_API void PDFLIB_CALL +PDF_close(PDF *p); + +/* Close an image. */ +PDFLIB_API void PDFLIB_CALL +PDF_close_image(PDF *p, int image); + +/* Deprecated, use PDF_close_pdi_document(). */ +PDFLIB_API void PDFLIB_CALL +PDF_close_pdi(PDF *p, int doc); + +/* Close all open PDI page handles, and close the input PDF document. */ +PDFLIB_API void PDFLIB_CALL +PDF_close_pdi_document(PDF *p, int doc); + +/* Close the page handle and free all page-related resources. */ +PDFLIB_API void PDFLIB_CALL +PDF_close_pdi_page(PDF *p, int page); + +/* Close the current path. */ +PDFLIB_API void PDFLIB_CALL +PDF_closepath(PDF *p); + +/* Close the path, fill, and stroke it. */ +PDFLIB_API void PDFLIB_CALL +PDF_closepath_fill_stroke(PDF *p); + +/* Close the path, and stroke it. */ +PDFLIB_API void PDFLIB_CALL +PDF_closepath_stroke(PDF *p); + +/* Apply a transformation matrix to the current coordinate system. */ +PDFLIB_API void PDFLIB_CALL +PDF_concat(PDF *p, double a, double b, double c, double d, double e, double f); + +/* Print text at the next line. */ +PDFLIB_API void PDFLIB_CALL +PDF_continue_text(PDF *p, const char *text); + +/* Same as PDF_continue_text(), but with explicit string length. */ +PDFLIB_API void PDFLIB_CALL +PDF_continue_text2(PDF *p, const char *text, int len); + +/* Create a 3D view (requires PDF 1.6). + Returns: A 3D view handle, or -1 (in PHP: 0) on error. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_create_3dview(PDF *p, const char *username, int len, const char *optlist); + +/* Create an action which can be applied to various objects and events. + Returns: An action handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_create_action(PDF *p, const char *type, const char *optlist); + +/* Create a rectangular annotation on the current page. */ +PDFLIB_API void PDFLIB_CALL +PDF_create_annotation(PDF *p, double llx, double lly, double urx, double ury, + const char *type, const char *optlist); + +/* Create a bookmark subject to various options. + Returns: A handle for the generated bookmark. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_create_bookmark(PDF *p, const char *text, int len, const char *optlist); + +/* Create a form field on the current page subject to various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_create_field(PDF *p, double llx, double lly, double urx, double ury, + const char *name, int len, const char *type, const char *optlist); + +/* Create a form field group subject to various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_create_fieldgroup(PDF *p, const char *name, int len, const char *optlist); + +/* Create a graphics state object subject to various options. + Returns: A graphics state handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_create_gstate(PDF *p, const char *optlist); + +/* Create a named virtual read-only file from data provided in memory. */ +PDFLIB_API void PDFLIB_CALL +PDF_create_pvf(PDF *p, const char *filename, int len, + const void *data, size_t size, const char *optlist); + +/* Create a Textflow object from text contents, inline options, and explicit + options. + Returns: A Textflow handle, or -1 (in PHP: 0) on error. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_create_textflow(PDF *p, const char *text, int len, const char *optlist); + +/* Draw a Bezier curve from the current point, using 3 more control points. */ +PDFLIB_API void PDFLIB_CALL +PDF_curveto(PDF *p, + double x_1, double y_1, double x_2, double y_2, double x_3, double y_3); + +/* Create a new layer definition (requires PDF 1.5). + Returns: A layer handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_define_layer(PDF *p, const char *name, int len, const char *optlist); + +/* Delete a PDFlib object and free all internal resources. */ +PDFLIB_API void PDFLIB_CALL +PDF_delete(PDF *p); + +/* Delete a named virtual file and free its data structures (but not the + contents). + Returns: -1 (in PHP: 0) if the virtual file exists but is locked, and + 1 otherwise. + */ +PDFLIB_API int PDFLIB_CALL +PDF_delete_pvf(PDF *p, const char *filename, int len); + +/* Delete a table and all associated data structures. */ +PDFLIB_API void PDFLIB_CALL +PDF_delete_table(PDF *p, int table, const char *optlist); + +/* Delete a Textflow and all associated data structures. */ +PDFLIB_API void PDFLIB_CALL +PDF_delete_textflow(PDF *p, int textflow); + +/* Add a glyph name and/or Unicode value to a custom encoding. */ +PDFLIB_API void PDFLIB_CALL +PDF_encoding_set_char(PDF *p, const char *encoding, int slot, + const char *glyphname, int uv); + +/* Close the generated PDF document and apply various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_end_document(PDF *p, const char *optlist); + +/* Terminate a Type 3 font definition. */ +PDFLIB_API void PDFLIB_CALL +PDF_end_font(PDF *p); + +/* Terminate a glyph definition for a Type 3 font. */ +PDFLIB_API void PDFLIB_CALL +PDF_end_glyph(PDF *p); + +/* Close a structure element or other content item. */ +PDFLIB_API void PDFLIB_CALL +PDF_end_item(PDF *p, int id); + +/* Deactivate all active layers (requires PDF 1.5). */ +PDFLIB_API void PDFLIB_CALL +PDF_end_layer(PDF *p); + +/* End the least recently opened marked content sequence (unsupported). */ +PDFLIB_API void PDFLIB_CALL +PDF_end_mc(PDF *p); + +/* Deprecated, use PDF_end_page_ext(). */ +PDFLIB_API void PDFLIB_CALL +PDF_end_page(PDF *p); + +/* Finish a page, and apply various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_end_page_ext(PDF *p, const char *optlist); + +/* Finish a pattern definition. */ +PDFLIB_API void PDFLIB_CALL +PDF_end_pattern(PDF *p); + +/* Finish a template definition. */ +PDFLIB_API void PDFLIB_CALL +PDF_end_template(PDF *p); + +/* End the current path without filling or stroking it. */ +PDFLIB_API void PDFLIB_CALL +PDF_endpath(PDF *p); + +/* Fill the interior of the path with the current fill color. */ +PDFLIB_API void PDFLIB_CALL +PDF_fill(PDF *p); + +/* Fill an image block with variable data according to its properties. + Returns: -1 (in PHP: 0) on error, and 1 otherwise. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_fill_imageblock(PDF *p, int page, const char *blockname, + int image, const char *optlist); + +/* Fill a PDF block with variable data according to its properties. + Returns: -1 (in PHP: 0) on error, and 1 otherwise. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_fill_pdfblock(PDF *p, int page, const char *blockname, + int contents, const char *optlist); + +/* Fill and stroke the path with the current fill and stroke color. */ +PDFLIB_API void PDFLIB_CALL +PDF_fill_stroke(PDF *p); + +/* Fill a text block with variable data according to its properties. + Returns: -1 (in PHP: 0) on error, and 1 otherwise. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_fill_textblock(PDF *p, int page, const char *blockname, + const char *text, int len, const char *optlist); + +/* Deprecated, use PDF_load_font(). */ +PDFLIB_API int PDFLIB_CALL +PDF_findfont(PDF *p, const char *fontname, const char *encoding, int embed); + +/* Place an image or template on the page, subject to various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_fit_image(PDF *p, int image, double x, double y, const char *optlist); + +/* Place an imported PDF page on the page subject to various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_fit_pdi_page(PDF *p, int page, double x, double y, const char *optlist); + +/* Fully or partially place a table on the page. + Returns: A string which specifies the reason for returning. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_fit_table(PDF *p, int table, double llx, double lly, + double urx, double ury, const char *optlist); + +/* Format the next portion of a Textflow into a rectangular area. + Returns: A string which specifies the reason for returning. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_fit_textflow(PDF *p, int textflow, double llx, double lly, + double urx, double ury, const char *optlist); + +/* Place a single line of text at position (x, y) subject to various options. */ +PDFLIB_API void PDFLIB_CALL +PDF_fit_textline(PDF *p, const char *text, int len, double x, double y, + const char *optlist); + +/* + * Retrieve a structure with PDFlib API function pointers (mainly for DLLs). + * Although this function is published here, it is not supposed to be used + * directly by clients. Use PDF_new_dl() (in pdflibdl.c). + */ +PDFLIB_API const PDFlib_api * PDFLIB_CALL +PDF_get_api(void); + +/* Get the name of the API function which threw the last exception or failed. + Returns: Name of an API function. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_get_apiname(PDF *p); + +/* Get the contents of the PDF output buffer. + Returns: A buffer full of binary PDF data for consumption by the client. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_get_buffer(PDF *p, long *size); + +/* Get the text of the last thrown exception or the reason of a failed + function call. + Returns: Text containing the description of the most recent error condition. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_get_errmsg(PDF *p); + +/* Get the number of the last thrown exception or the reason of a failed + function call. + Returns: The error code of the most recent error condition. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_get_errnum(PDF *p); + +/* Request the amount of kerning between two characters (unsupported). */ +PDFLIB_API double PDFLIB_CALL +PDF_get_kern_amount(PDF *p, int font, int firstchar, int secondchar); + +/* Deprecated, use PDF_get_value(). */ +PDFLIB_API int PDFLIB_CALL +PDF_get_majorversion(void); + +/* Deprecated, use PDF_get_value(). */ +PDFLIB_API int PDFLIB_CALL +PDF_get_minorversion(void); + +/* Fetch the opaque application pointer stored in PDFlib. + Returns: The opaque application pointer stored in PDFlib. +*/ +PDFLIB_API void * PDFLIB_CALL +PDF_get_opaque(PDF *p); + +/* Get the contents of some PDFlib parameter with string type. + Returns: The string value of the parameter as a hypertext string. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_get_parameter(PDF *p, const char *key, double modifier); + +/* Deprecated, use PDF_pcos_get_string(). */ +PDFLIB_API const char *PDFLIB_CALL +PDF_get_pdi_parameter(PDF *p, const char *key, int doc, int page, + int reserved, int *len); + +/* Deprecated, use PDF_pcos_get_number. */ +PDFLIB_API double PDFLIB_CALL +PDF_get_pdi_value(PDF *p, const char *key, int doc, int page, int reserved); + +/* Get the value of some PDFlib parameter with numerical type. + Returns: The numerical value of the parameter. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_get_value(PDF *p, const char *key, double modifier); + +/* Query detailed information about a loaded font. + Returns: The value of some font property as requested by keyword. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_info_font(PDF *p, int font, const char *keyword, const char *optlist); + +/* Query information about a matchbox on the current page. + Returns: The value of some matchbox parameter as requested by keyword. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_info_matchbox(PDF *p, const char *boxname, int len, int num, + const char *keyword); + +/* Retrieve table information related to the most recently placed table + instance. + Returns: The value of some table parameter as requested by keyword. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_info_table(PDF *p, int table, const char *keyword); + +/* Query the current state of a Textflow. + Returns: The value of some Textflow parameter as requested by keyword. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_info_textflow(PDF *p, int textflow, const char *keyword); + +/* Perform textline formatting and query the resulting metrics. + Returns: The value of some text metric value as requested by keyword. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_info_textline(PDF *p, const char *text, int len, const char *keyword, + const char *optlist); + +/* Reset all color and graphics state parameters to their defaults. */ +PDFLIB_API void PDFLIB_CALL +PDF_initgraphics(PDF *p); + +/* Draw a line from the current point to another point. */ +PDFLIB_API void PDFLIB_CALL +PDF_lineto(PDF *p, double x, double y); + +/* Load a 3D model from a disk-based or virtual file (requires PDF 1.6). + Returns: A 3D handle, or -1 (in PHP: 0) on error. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_load_3ddata(PDF *p, const char *filename, int len, const char *optlist); + +/* Search for a font and prepare it for later use. + Returns: A font handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_load_font(PDF *p, const char *fontname, int len, + const char *encoding, const char *optlist); + +/* Search for an ICC profile and prepare it for later use. + Returns: A profile handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_load_iccprofile(PDF *p, const char *profilename, int len, + const char *optlist); + +/* Open a disk-based or virtual image file subject to various options. + Returns: An image handle, or -1 (in PHP: 0) on error. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_load_image(PDF *p, const char *imagetype, const char *filename, + int len, const char *optlist); + +/* Find a built-in spot color name, or make a named spot color from the + current fill color. + Returns: A color handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_makespotcolor(PDF *p, const char *spotname, int reserved); + +/* Add a marked content point with or without properties (unsupported). */ +PDFLIB_API void PDFLIB_CALL +PDF_mc_point(PDF *p, const char *tag, const char *optlist); + +/* Set the current point. */ +PDFLIB_API void PDFLIB_CALL +PDF_moveto(PDF *p, double x, double y); + +/* Create a new PDFlib object. + Returns: A handle to a PDFlib object. +*/ +PDFLIB_API PDF * PDFLIB_CALL +PDF_new(void); + +/* Create a new PDFlib object with client-supplied error handling and memory + allocation routines. + Returns: A handle to a PDFlib object. +*/ +typedef void (*errorproc_t)(PDF *p1, int errortype, const char *msg); +typedef void* (*allocproc_t)(PDF *p2, size_t size, const char *caller); +typedef void* (*reallocproc_t)(PDF *p3, + void *mem, size_t size, const char *caller); +typedef void (*freeproc_t)(PDF *p4, void *mem); + +PDFLIB_API PDF * PDFLIB_CALL +PDF_new2(errorproc_t errorhandler, allocproc_t allocproc, + reallocproc_t reallocproc, freeproc_t freeproc, void *opaque); + +/* Deprecated, use PDF_load_image(). */ +PDFLIB_API int PDFLIB_CALL +PDF_open_CCITT(PDF *p, const char *filename, int width, int height, + int BitReverse, int K, int BlackIs1); + +/* Deprecated, use PDF_begin_document(). */ +PDFLIB_API int PDFLIB_CALL +PDF_open_file(PDF *p, const char *filename); + +/* Deprecated, use PDF_load_image() with virtual files. */ +PDFLIB_API int PDFLIB_CALL +PDF_open_image(PDF *p, const char *imagetype, const char *source, + const char *data, long length, int width, int height, int components, + int bpc, const char *params); + +/* Deprecated, use PDF_load_image(). */ +PDFLIB_API int PDFLIB_CALL +PDF_open_image_file(PDF *p, const char *imagetype, const char *filename, + const char *stringparam, int intparam); + +/* Deprecated, use PDF_begin_document_callback(). */ +PDFLIB_API void PDFLIB_CALL +PDF_open_mem(PDF *p, writeproc_t writeproc); + +/* Deprecated, use PDF_open_pdi_document(). */ +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi(PDF *p, const char *filename, const char *optlist, int len); + +/* Open a disk-based or virtual PDF document and prepare it for later use. + Returns: A PDI document handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi_document(PDF *p, const char *filename, int len, + const char *optlist); + +/* Open a PDF document from a custom data source and prepare it for + later use. + Returns: A PDI document handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi_callback(PDF *p, void *opaque, size_t filesize, + size_t (*readproc)(void *opaque, void *buffer, size_t size), + int (*seekproc)(void *opaque, long offset), + const char *optlist); + +/* Prepare a page for later use with PDF_fit_pdi_page(). + Returns: A page handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_open_pdi_page(PDF *p, int doc, int pagenumber, const char *optlist); + +/* Get the value of a pCOS path with type number or boolean. + Returns: The numerical value of the object identified by the pCOS path. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_pcos_get_number(PDF *p, int doc, const char *path, ...); + +/* Get the value of a pCOS path with type name, string or boolean. + Returns: A string with the value of the object identified by the pCOS path. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_pcos_get_string(PDF *p, int doc, const char *path, ...); + +/* Get the contents of a pCOS path with type stream, fstream, or string. + Returns: The unencrypted data contained in the stream or string. +*/ +PDFLIB_API const unsigned char * PDFLIB_CALL +PDF_pcos_get_stream(PDF *p, int doc, int *length, const char *optlist, + const char *path, ...); + +/* Deprecated, use PDF_fit_image(). */ +PDFLIB_API void PDFLIB_CALL +PDF_place_image(PDF *p, int image, double x, double y, double scale); + +/* Deprecated, use PDF_fit_pdi_page(). */ +PDFLIB_API void PDFLIB_CALL +PDF_place_pdi_page(PDF *p, int page, double x, double y, double sx, double sy); + +/* Process certain elements of an imported PDF document. + Returns: -1 (in PHP: 0) on error, and 1 otherwise. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_process_pdi(PDF *p, int doc, int page, const char *optlist); + +/* Draw a Bezier curve using relative coordinates (unsupported). */ +PDFLIB_API void PDFLIB_CALL +PDF_rcurveto(PDF *p, + double x_1, double y_1, double x_2, double y_2, double x_3, double y_3); + +/* Draw a rectangle. */ +PDFLIB_API void PDFLIB_CALL +PDF_rect(PDF *p, double x, double y, double width, double height); + +/* Restore the most recently saved graphics state from the stack. */ +PDFLIB_API void PDFLIB_CALL +PDF_restore(PDF *p); + +/* Resume a page to add more content to it. */ +PDFLIB_API void PDFLIB_CALL +PDF_resume_page(PDF *p, const char *optlist); + +/* Draw a line from the current point to (cp + (x, y)) (unsupported). */ +PDFLIB_API void PDFLIB_CALL +PDF_rlineto(PDF *p, double x, double y); + +/* Set the new current point relative the old current point (unsupported). */ +PDFLIB_API void PDFLIB_CALL +PDF_rmoveto(PDF *p, double x, double y); + +/* Rotate the coordinate system. */ +PDFLIB_API void PDFLIB_CALL +PDF_rotate(PDF *p, double phi); + +/* Save the current graphics state to a stack. */ +PDFLIB_API void PDFLIB_CALL +PDF_save(PDF *p); + +/* Scale the coordinate system. */ +PDFLIB_API void PDFLIB_CALL +PDF_scale(PDF *p, double sx, double sy); + +/* Deprecated, use PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_set_border_color(PDF *p, double red, double green, double blue); + +/* Deprecated, use PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_set_border_dash(PDF *p, double b, double w); + +/* Deprecated, use PDF_create_annotation(). */ +PDFLIB_API void PDFLIB_CALL +PDF_set_border_style(PDF *p, const char *style, double width); + +/* Activate a graphics state object. */ +PDFLIB_API void PDFLIB_CALL +PDF_set_gstate(PDF *p, int gstate); + +/* Fill document information field key with value. */ +PDFLIB_API void PDFLIB_CALL +PDF_set_info(PDF *p, const char *key, const char *value); + +/* Like PDF_set_info(), but with explicit string length. */ +PDFLIB_API void PDFLIB_CALL +PDF_set_info2(PDF *p, const char *key, const char *value, int len); + +/* Define hierarchical, group, and lock conditions among layers (requires + PDF 1.5). +*/ +PDFLIB_API void PDFLIB_CALL +PDF_set_layer_dependency(PDF *p, const char *type, const char *optlist); + +/* Set some PDFlib parameter with string type. */ +PDFLIB_API void PDFLIB_CALL +PDF_set_parameter(PDF *p, const char *key, const char *value); + +/* Set the position for text output on the page. */ +PDFLIB_API void PDFLIB_CALL +PDF_set_text_pos(PDF *p, double x, double y); + +/* Set the value of some PDFlib parameter with numerical type. */ +PDFLIB_API void PDFLIB_CALL +PDF_set_value(PDF *p, const char *key, double value); + +/* Set the current color space and color. */ +PDFLIB_API void PDFLIB_CALL +PDF_setcolor(PDF *p, const char *fstype, const char *colorspace, + double c1, double c2, double c3, double c4); + +/* Set the current dash pattern. */ +PDFLIB_API void PDFLIB_CALL +PDF_setdash(PDF *p, double b, double w); + +/* Set a dash pattern defined by an option list. */ +PDFLIB_API void PDFLIB_CALL +PDF_setdashpattern(PDF *p, const char *optlist); + +/* Set the flatness parameter. */ +PDFLIB_API void PDFLIB_CALL +PDF_setflat(PDF *p, double flatness); + +/* Set the current font in the specified size. */ +PDFLIB_API void PDFLIB_CALL +PDF_setfont(PDF *p, int font, double fontsize); + +/* Deprecated, use PDF_setcolor(). */ +PDFLIB_API void PDFLIB_CALL +PDF_setgray(PDF *p, double gray); + +/* Deprecated, use PDF_setcolor(). */ +PDFLIB_API void PDFLIB_CALL +PDF_setgray_fill(PDF *p, double gray); + +/* Deprecated, use PDF_setcolor(). */ +PDFLIB_API void PDFLIB_CALL +PDF_setgray_stroke(PDF *p, double gray); + +/* Set the linecap parameter. */ +PDFLIB_API void PDFLIB_CALL +PDF_setlinecap(PDF *p, int linecap); + +/* Set the linejoin parameter. */ +PDFLIB_API void PDFLIB_CALL +PDF_setlinejoin(PDF *p, int linejoin); + +/* Set the current linewidth. */ +PDFLIB_API void PDFLIB_CALL +PDF_setlinewidth(PDF *p, double width); + +/* Explicitly set the current transformation matrix. */ +PDFLIB_API void PDFLIB_CALL +PDF_setmatrix(PDF *p, double a, double b, double c, double d, + double e, double f); + +/* Set the miter limit. */ +PDFLIB_API void PDFLIB_CALL +PDF_setmiterlimit(PDF *p, double miter); + +/* Deprecated, use PDF_setdashpattern(). */ +PDFLIB_API void PDFLIB_CALL +PDF_setpolydash(PDF *p, float *dasharray, int length); + +/* Deprecated, use PDF_setcolor(). */ +PDFLIB_API void PDFLIB_CALL +PDF_setrgbcolor(PDF *p, double red, double green, double blue); + +/* Deprecated, use PDF_setcolor(). */ +PDFLIB_API void PDFLIB_CALL +PDF_setrgbcolor_fill(PDF *p, double red, double green, double blue); + +/* Deprecated, use PDF_setcolor(). */ +PDFLIB_API void PDFLIB_CALL +PDF_setrgbcolor_stroke(PDF *p, double red, double green, double blue); + +/* Define a blend from the current fill color to another color (requires + PDF 1.4). + Returns: A shading handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_shading(PDF *p, const char *shtype, double x_0, double y_0, double x_1, + double y_1, double c_1, double c_2, double c_3, double c_4, + const char *optlist); + +/* Define a shading pattern using a shading object (requires PDF 1.4). + Returns: A pattern handle. +*/ +PDFLIB_API int PDFLIB_CALL +PDF_shading_pattern(PDF *p, int shading, const char *optlist); + +/* Fill an area with a shading, based on a shading object (requires PDF 1.4) */ +PDFLIB_API void PDFLIB_CALL +PDF_shfill(PDF *p, int shading); + +/* Print text in the current font and size at the current position. */ +PDFLIB_API void PDFLIB_CALL +PDF_show(PDF *p, const char *text); + +/* Same as PDF_show() but with explicit string length. */ +PDFLIB_API void PDFLIB_CALL +PDF_show2(PDF *p, const char *text, int len); + +/* Deprecated, use PDF_fit_textline() or PDF_fit_textflow(). */ +PDFLIB_API int PDFLIB_CALL +PDF_show_boxed(PDF *p, const char *text, double left, double top, + double width, double height, const char *hmode, const char *feature); + +/* Deprecated, use PDF_fit_textline() or PDF_fit_textflow(). */ +PDFLIB_API int PDFLIB_CALL +PDF_show_boxed2(PDF *p, const char *text, int len, double left, double top, + double width, double height, const char *hmode, const char *feature); + +/* Print text in the current font. */ +PDFLIB_API void PDFLIB_CALL +PDF_show_xy(PDF *p, const char *text, double x, double y); + +/* Same as PDF_show_xy(), but with explicit string length. */ +PDFLIB_API void PDFLIB_CALL +PDF_show_xy2(PDF *p, const char *text, int len, double x, double y); + +/* Deprecated, and not required. */ +PDFLIB_API void PDFLIB_CALL +PDF_shutdown(void); + +/* Skew the coordinate system. */ +PDFLIB_API void PDFLIB_CALL +PDF_skew(PDF *p, double alpha, double beta); + +/* Calculate the width of text in an arbitrary font. + Returns: The width of text. +*/ +PDFLIB_API double PDFLIB_CALL +PDF_stringwidth(PDF *p, const char *text, int font, double fontsize); + +/* Same as PDF_stringwidth(), but with explicit string length. */ +PDFLIB_API double PDFLIB_CALL +PDF_stringwidth2(PDF *p, const char *text, int len, int font, double fontsize); + +/* Stroke the path with the current color and line width, and clear it. */ +PDFLIB_API void PDFLIB_CALL +PDF_stroke(PDF *p); + +/* Suspend the current page so that it can later be resumed. */ +PDFLIB_API void PDFLIB_CALL +PDF_suspend_page(PDF *p, const char *optlist); + +/* Translate the origin of the coordinate system. */ +PDFLIB_API void PDFLIB_CALL +PDF_translate(PDF *p, double tx, double ty); + +/* Convert a string from UTF-16 format to UTF-8. + Returns: The converted UTF-8 string, starting with the UTF-8 BOM. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_utf16_to_utf8(PDF *p, const char *utf16string, int len, int *size); + +/* Convert a string from UTF-32 format to UTF-16. + Returns: The converted UTF-16 string. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_utf32_to_utf16(PDF *p, const char *utf32string, int len, + const char *ordering, int *size); + +/* Convert a string from UTF-8 format to UTF-16. + Returns: The converted UTF-16 string. +*/ +PDFLIB_API const char * PDFLIB_CALL +PDF_utf8_to_utf16(PDF *p, const char *utf8string, const char *ordering, + int *size); + +/* Print text in the current font and size, using individual horizontal + positions (unsupported). +*/ +PDFLIB_API void PDFLIB_CALL +PDF_xshow(PDF *p, const char *text, int len, const double *xadvancelist); + + +/* + * ---------------------------------------------------------------------- + * PDFlib API structure with function pointers to all API functions + * ---------------------------------------------------------------------- + */ + +/* Auxiliary structure for try/catch */ +typedef struct +{ + jmp_buf jbuf; +} pdf_jmpbuf; + + +/* The API structure with pointers to all PDFlib API functions */ +struct PDFlib_api_s { + /* version numbers for checking the DLL against client code */ + size_t sizeof_PDFlib_api; /* size of this structure */ + + int major; /* PDFlib major version number */ + int minor; /* PDFlib minor version number */ + int revision; /* PDFlib revision number */ + + int reserved; /* reserved */ + + void (PDFLIB_CALL * PDF_activate_item)(PDF *p, int id); + int (PDFLIB_CALL * PDF_add_bookmark)(PDF *p, const char *text, + int parent, int open); + int (PDFLIB_CALL * PDF_add_bookmark2)(PDF *p, const char *text, int len, + int parent, int open); + void (PDFLIB_CALL * PDF_add_launchlink)(PDF *p, + double llx, double lly, double urx, + double ury, const char *filename); + void (PDFLIB_CALL * PDF_add_locallink)(PDF *p, + double llx, double lly, double urx, + double ury, int page, const char *optlist); + void (PDFLIB_CALL * PDF_add_nameddest)(PDF *p, const char *name, + int len, const char *optlist); + void (PDFLIB_CALL * PDF_add_note)(PDF *p, double llx, double lly, + double urx, double ury, const char *contents, const char *title, + const char *icon, int open); + void (PDFLIB_CALL * PDF_add_note2)(PDF *p, double llx, double lly, + double urx, double ury, const char *contents, int len_cont, + const char *title, int len_title, const char *icon, int open); + void (PDFLIB_CALL * PDF_add_pdflink)(PDF *p, + double llx, double lly, double urx, double ury, + const char *filename, int page, const char *optlist); + int (PDFLIB_CALL * PDF_add_table_cell)(PDF *p, int table, int column, + int row, const char *text, int len, const char *optlist); + int (PDFLIB_CALL * PDF_add_textflow)(PDF *p, int textflow, const char *text, + int len, const char *optlist); + void (PDFLIB_CALL * PDF_add_thumbnail)(PDF *p, int image); + void (PDFLIB_CALL * PDF_add_weblink)(PDF *p, double llx, + double lly, double urx, double ury, const char *url); + void (PDFLIB_CALL * PDF_arc)(PDF *p, double x, double y, + double r, double alpha, double beta); + void (PDFLIB_CALL * PDF_arcn)(PDF *p, double x, double y, + double r, double alpha, double beta); + void (PDFLIB_CALL * PDF_attach_file)(PDF *p, double llx, double lly, + double urx, double ury, const char *filename, + const char *description, + const char *author, const char *mimetype, const char *icon); + void (PDFLIB_CALL * PDF_attach_file2)(PDF *p, double llx, double lly, + double urx, double ury, const char *filename, int len_filename, + const char *description, int len_descr, const char *author, + int len_auth, const char *mimetype, const char *icon); + int (PDFLIB_CALL * PDF_begin_document)(PDF *p, const char *filename, + int len, const char *optlist); + void (PDFLIB_CALL * PDF_begin_document_callback)(PDF *p, + writeproc_t writeproc, const char *optlist); + void (PDFLIB_CALL * PDF_begin_font)(PDF *p, const char *fontname, + int len, double a, double b, double c, double d, double e, + double f, const char *optlist); + void (PDFLIB_CALL * PDF_begin_glyph)(PDF *p, const char *glyphname, + double wx, double llx, double lly, double urx, double ury); + int (PDFLIB_CALL * PDF_begin_item)(PDF *p, const char *tag, + const char *optlist); + void (PDFLIB_CALL * PDF_begin_layer)(PDF *p, int layer); + void (PDFLIB_CALL * PDF_begin_mc)(PDF *p, + const char *tag, const char *optlist); + void (PDFLIB_CALL * PDF_begin_page)(PDF *p, double width, double height); + void (PDFLIB_CALL * PDF_begin_page_ext)(PDF *p, double width, + double height, const char *optlist); + int (PDFLIB_CALL * PDF_begin_pattern)(PDF *p, double width, double height, + double xstep, double ystep, int painttype); + int (PDFLIB_CALL * PDF_begin_template)(PDF *p, + double width, double height); + int (PDFLIB_CALL * PDF_begin_template_ext)(PDF *p, + double width, double height, const char *optlist); + void (PDFLIB_CALL * PDF_boot)(void); + int (PDFLIB_CALL * PDF_check_context)(PDF *p); + void (PDFLIB_CALL * PDF_circle)(PDF *p, double x, double y, double r); + void (PDFLIB_CALL * PDF_clip)(PDF *p); + void (PDFLIB_CALL * PDF_close)(PDF *p); + void (PDFLIB_CALL * PDF_close_image)(PDF *p, int image); + void (PDFLIB_CALL * PDF_close_pdi)(PDF *p, int doc); + void (PDFLIB_CALL * PDF_close_pdi_document)(PDF *p, int doc); + void (PDFLIB_CALL * PDF_close_pdi_page)(PDF *p, int page); + void (PDFLIB_CALL * PDF_closepath)(PDF *p); + void (PDFLIB_CALL * PDF_closepath_fill_stroke)(PDF *p); + void (PDFLIB_CALL * PDF_closepath_stroke)(PDF *p); + void (PDFLIB_CALL * PDF_concat)(PDF *p, double a, double b, + double c, double d, double e, double f); + void (PDFLIB_CALL * PDF_continue_text)(PDF *p, const char *text); + void (PDFLIB_CALL * PDF_continue_text2)(PDF *p, const char *text, int len); + int (PDFLIB_CALL * PDF_create_3dview)(PDF *p, const char *username, + int len, const char *optlist); + int (PDFLIB_CALL * PDF_create_action)(PDF *p, const char *type, + const char *optlist); + void (PDFLIB_CALL * PDF_create_annotation)(PDF *p, + double llx, double lly, double urx, double ury, + const char *type, const char *optlist); + int (PDFLIB_CALL * PDF_create_bookmark)(PDF *p, const char *text, int len, + const char *optlist); + void (PDFLIB_CALL * PDF_create_field)(PDF *p, double llx, double lly, + double urx, double ury, const char *name, int len, + const char *type, const char *optlist); + void (PDFLIB_CALL * PDF_create_fieldgroup)(PDF *p, const char *name, + int len, const char *optlist); + int (PDFLIB_CALL * PDF_create_gstate)(PDF *p, const char *optlist); + void (PDFLIB_CALL * PDF_create_pvf)(PDF *p, const char *filename, + int len, const void *data, size_t size, const char *optlist); + int (PDFLIB_CALL * PDF_create_textflow)(PDF *p, const char *text, int len, + const char *optlist); + void (PDFLIB_CALL * PDF_curveto)(PDF *p, double x_1, double y_1, + double x_2, double y_2, double x_3, double y_3); + int (PDFLIB_CALL * PDF_define_layer)(PDF *p, const char *name, int len, + const char *optlist); + void (PDFLIB_CALL * PDF_delete)(PDF *); + int (PDFLIB_CALL * PDF_delete_pvf)(PDF *p, const char *filename, int len); + void (PDFLIB_CALL * PDF_delete_table)(PDF *p, int table, + const char *optlist); + void (PDFLIB_CALL * PDF_delete_textflow)(PDF *p, int textflow); + void (PDFLIB_CALL * PDF_encoding_set_char)(PDF *p, const char *encoding, + int slot, const char *glyphname, int uv); + void (PDFLIB_CALL * PDF_end_document)(PDF *p, const char *optlist); + void (PDFLIB_CALL * PDF_end_font)(PDF *p); + void (PDFLIB_CALL * PDF_end_glyph)(PDF *p); + void (PDFLIB_CALL * PDF_end_item)(PDF *p, int id); + void (PDFLIB_CALL * PDF_end_layer)(PDF *p); + void (PDFLIB_CALL * PDF_end_mc)(PDF *p); + void (PDFLIB_CALL * PDF_end_page)(PDF *p); + void (PDFLIB_CALL * PDF_end_page_ext)(PDF *p, const char *optlist); + void (PDFLIB_CALL * PDF_end_pattern)(PDF *p); + void (PDFLIB_CALL * PDF_end_template)(PDF *p); + void (PDFLIB_CALL * PDF_endpath)(PDF *p); + void (PDFLIB_CALL * PDF_fill)(PDF *p); + int (PDFLIB_CALL * PDF_fill_imageblock)(PDF *p, int page, + const char *blockname, int image, const char *optlist); + int (PDFLIB_CALL * PDF_fill_pdfblock)(PDF *p, int page, + const char *blockname, int contents, const char *optlist); + void (PDFLIB_CALL * PDF_fill_stroke)(PDF *p); + int (PDFLIB_CALL * PDF_fill_textblock)(PDF *p, int page, + const char *blockname, const char *text, int len, + const char *optlist); + int (PDFLIB_CALL * PDF_findfont)(PDF *p, const char *fontname, + const char *encoding, int embed); + void (PDFLIB_CALL * PDF_fit_image)(PDF *p, int image, double x, double y, + const char *optlist); + void (PDFLIB_CALL * PDF_fit_pdi_page)(PDF *p, int page, double x, + double y, const char *optlist); + const char * (PDFLIB_CALL * PDF_fit_table)(PDF *p, int table, + double llx, double lly, double urx, double ury, + const char *optlist); + const char * (PDFLIB_CALL * PDF_fit_textflow)(PDF *p, int textflow, + double llx, double lly, double urx, double ury, + const char *optlist); + void (PDFLIB_CALL * PDF_fit_textline)(PDF *p, const char *text, + int len, double x, double y, const char *optlist); + const PDFlib_api * (PDFLIB_CALL * PDF_get_api)(void); + const char * (PDFLIB_CALL * PDF_get_apiname)(PDF *p); + const char * (PDFLIB_CALL * PDF_get_buffer)(PDF *p, long *size); + const char * (PDFLIB_CALL * PDF_get_errmsg)(PDF *p); + int (PDFLIB_CALL * PDF_get_errnum)(PDF *p); + int (PDFLIB_CALL * PDF_get_minorversion)(void); + int (PDFLIB_CALL * PDF_get_majorversion)(void); + void * (PDFLIB_CALL * PDF_get_opaque)(PDF *p); + const char * (PDFLIB_CALL * PDF_get_parameter)(PDF *p, + const char *key, double modifier); + const char * (PDFLIB_CALL * PDF_get_pdi_parameter)(PDF *p, + const char *key, int doc, int page, int reserved, int *len); + double (PDFLIB_CALL * PDF_get_pdi_value)(PDF *p, const char *key, + int doc, int page, int reserved); + double (PDFLIB_CALL * PDF_get_value)(PDF *p, const char *key, + double modifier); + double (PDFLIB_CALL * PDF_info_font)(PDF *p, int font, const char *keyword, + const char *optlist); + double (PDFLIB_CALL * PDF_info_matchbox)(PDF *p, const char *boxname, + int len, int num, const char *keyword); + double (PDFLIB_CALL * PDF_info_table)(PDF *p, int table, + const char *keyword); + double (PDFLIB_CALL * PDF_info_textflow)(PDF *p, int textflow, + const char *keyword); + double (PDFLIB_CALL * PDF_info_textline)(PDF *p, const char *text, int len, + const char *keyword, const char *optlist); + void (PDFLIB_CALL * PDF_initgraphics)(PDF *p); + void (PDFLIB_CALL * PDF_lineto)(PDF *p, double x, double y); + int (PDFLIB_CALL * PDF_load_3ddata)(PDF *p, const char *filename, int len, + const char *optlist); + int (PDFLIB_CALL * PDF_load_font)(PDF *p, const char *fontname, + int len, const char *encoding, const char *optlist); + int (PDFLIB_CALL * PDF_load_iccprofile)(PDF *p, const char *profilename, + int len, const char *optlist); + int (PDFLIB_CALL * PDF_load_image)(PDF *p, const char *imagetype, + const char *filename, int len, const char *optlist); + int (PDFLIB_CALL * PDF_makespotcolor)(PDF *p, const char *spotname, + int len); + void (PDFLIB_CALL * PDF_mc_point)(PDF *p, + const char *tag, const char *optlist); + void (PDFLIB_CALL * PDF_moveto)(PDF *p, double x, double y); + PDF* (PDFLIB_CALL * PDF_new)(void); + PDF* (PDFLIB_CALL * PDF_new2)(errorproc_t errorhandler, + allocproc_t allocproc, reallocproc_t reallocproc, + freeproc_t freeproc, void *opaque); + int (PDFLIB_CALL * PDF_open_CCITT)(PDF *p, const char *filename, + int width, int height, int BitReverse, int K, int BlackIs1); + int (PDFLIB_CALL * PDF_open_file)(PDF *p, const char *filename); + int (PDFLIB_CALL * PDF_open_image)(PDF *p, const char *imagetype, + const char *source, const char *data, long length, int width, + int height, int components, int bpc, const char *params); + int (PDFLIB_CALL * PDF_open_image_file)(PDF *p, const char *imagetype, + const char *filename, const char *stringparam, int intparam); + void (PDFLIB_CALL * PDF_open_mem)(PDF *p, writeproc_t writeproc); + int (PDFLIB_CALL * PDF_open_pdi)(PDF *p, const char *filename, + const char *optlist, int len); + int (PDFLIB_CALL * PDF_open_pdi_callback)(PDF *p, void *opaque, + size_t filesize, size_t (*readproc)(void *opaque, void *buffer, + size_t size), int (*seekproc)(void *opaque, long offset), + const char *optlist); + int (PDFLIB_CALL * PDF_open_pdi_document)(PDF *p, const char *filename, + int len, const char *optlist); + int (PDFLIB_CALL * PDF_open_pdi_page)(PDF *p, + int doc, int pagenumber, const char *optlist); + double (PDFLIB_CALL * PDF_pcos_get_number)(PDF *p, + int doc, const char *path, ...); + const char * (PDFLIB_CALL * PDF_pcos_get_string)(PDF *p, + int doc, const char *path, ...); + const unsigned char * (PDFLIB_CALL * PDF_pcos_get_stream)(PDF *p, + int doc, int *length, const char *optlist, + const char *path, ...); + void (PDFLIB_CALL * PDF_place_image)(PDF *p, int image, + double x, double y, double scale); + void (PDFLIB_CALL * PDF_place_pdi_page)(PDF *p, int page, + double x, double y, double sx, double sy); + int (PDFLIB_CALL * PDF_process_pdi)(PDF *p, int doc, int page, + const char *optlist); + void (PDFLIB_CALL * PDF_rect)(PDF *p, double x, double y, + double width, double height); + void (PDFLIB_CALL * PDF_restore)(PDF *p); + void (PDFLIB_CALL * PDF_resume_page)(PDF *p, const char *optlist); + void (PDFLIB_CALL * PDF_rotate)(PDF *p, double phi); + void (PDFLIB_CALL * PDF_save)(PDF *p); + void (PDFLIB_CALL * PDF_scale)(PDF *p, double sx, double sy); + void (PDFLIB_CALL * PDF_set_border_color)(PDF *p, + double red, double green, double blue); + void (PDFLIB_CALL * PDF_set_border_dash)(PDF *p, double b, double w); + void (PDFLIB_CALL * PDF_set_border_style)(PDF *p, + const char *style, double width); + void (PDFLIB_CALL * PDF_set_gstate)(PDF *p, int gstate); + void (PDFLIB_CALL * PDF_set_info)(PDF *p, const char *key, + const char *value); + void (PDFLIB_CALL * PDF_set_info2)(PDF *p, const char *key, + const char *value, int len); + void (PDFLIB_CALL * PDF_set_layer_dependency)(PDF *p, const char *type, + const char *optlist); + void (PDFLIB_CALL * PDF_set_parameter)(PDF *p, const char *key, + const char *value); + void (PDFLIB_CALL * PDF_set_text_pos)(PDF *p, double x, double y); + void (PDFLIB_CALL * PDF_set_value)(PDF *p, const char *key, double value); + void (PDFLIB_CALL * PDF_setcolor)(PDF *p, const char *fstype, + const char *colorspace, double c1, double c2, + double c3, double c4); + void (PDFLIB_CALL * PDF_setdash)(PDF *p, double b, double w); + void (PDFLIB_CALL * PDF_setdashpattern)(PDF *p, const char *optlist); + void (PDFLIB_CALL * PDF_setflat)(PDF *p, double flatness); + void (PDFLIB_CALL * PDF_setfont)(PDF *p, int font, double fontsize); + void (PDFLIB_CALL * PDF_setgray)(PDF *p, double gray); + void (PDFLIB_CALL * PDF_setgray_fill)(PDF *p, double gray); + void (PDFLIB_CALL * PDF_setgray_stroke)(PDF *p, double gray); + void (PDFLIB_CALL * PDF_setlinecap)(PDF *p, int linecap); + void (PDFLIB_CALL * PDF_setlinejoin)(PDF *p, int linejoin); + void (PDFLIB_CALL * PDF_setlinewidth)(PDF *p, double width); + void (PDFLIB_CALL * PDF_setmatrix)(PDF *p, double a, double b, + double c, double d, double e, double f); + void (PDFLIB_CALL * PDF_setmiterlimit)(PDF *p, double miter); + void (PDFLIB_CALL * PDF_setpolydash)(PDF *p, float *dasharray, int length); + void (PDFLIB_CALL * PDF_setrgbcolor)(PDF *p, double red, double green, + double blue); + void (PDFLIB_CALL * PDF_setrgbcolor_fill)(PDF *p, + double red, double green, double blue); + void (PDFLIB_CALL * PDF_setrgbcolor_stroke)(PDF *p, + double red, double green, double blue); + int (PDFLIB_CALL * PDF_shading)(PDF *p, const char *shtype, double x_0, + double y_0, double x_1, double y_1, double c_1, double c_2, + double c_3, double c_4, const char *optlist); + int (PDFLIB_CALL * PDF_shading_pattern)(PDF *p, int shading, + const char *optlist); + void (PDFLIB_CALL * PDF_shfill)(PDF *p, int shading); + void (PDFLIB_CALL * PDF_show)(PDF *p, const char *text); + void (PDFLIB_CALL * PDF_show2)(PDF *p, const char *text, int len); + int (PDFLIB_CALL * PDF_show_boxed)(PDF *p, const char *text, + double left, double top, double width, double height, + const char *hmode, const char *feature); + int (PDFLIB_CALL * PDF_show_boxed2)(PDF *p, const char *text, int len, + double left, double top, double width, double height, + const char *hmode, const char *feature); + void (PDFLIB_CALL * PDF_show_xy)(PDF *p, const char *text, double x, + double y); + void (PDFLIB_CALL * PDF_show_xy2)(PDF *p, const char *text, + int len, double x, double y); + void (PDFLIB_CALL * PDF_shutdown)(void); + void (PDFLIB_CALL * PDF_skew)(PDF *p, double alpha, double beta); + double (PDFLIB_CALL * PDF_stringwidth)(PDF *p, const char *text, + int font, double fontsize); + double (PDFLIB_CALL * PDF_stringwidth2)(PDF *p, const char *text, + int len, int font, double fontsize); + void (PDFLIB_CALL * PDF_stroke)(PDF *p); + void (PDFLIB_CALL * PDF_suspend_page)(PDF *p, const char *optlist); + void (PDFLIB_CALL * PDF_translate)(PDF *p, double tx, double ty); + const char * (PDFLIB_CALL * PDF_utf16_to_utf8)(PDF *p, + const char *utf16string, int len, int *size); + const char * (PDFLIB_CALL * PDF_utf32_to_utf16)(PDF *p, + const char *utf32string, int len, const char *ordering, + int *size); + const char * (PDFLIB_CALL * PDF_utf8_to_utf16)(PDF *p, + const char *utf8string, const char *format, int *size); + void (PDFLIB_CALL * PDF_xshow)(PDF *p, const char *text, int len, + const double *xadvancelist); + + int (PDFLIB_CALL * pdf_catch)(PDF *p); + void (PDFLIB_CALL * pdf_exit_try)(PDF *p); + pdf_jmpbuf * (PDFLIB_CALL * pdf_jbuf)(PDF *p); + void (PDFLIB_CALL * pdf_rethrow)(PDF *p); +}; + + +/* + * ---------------------------------------------------------------------- + * pCOS-specific enums and defines + * ---------------------------------------------------------------------- + */ + +/* + * PDFlib GmbH products implement the following pCOS interface numbers: + * + * pCOS interface Products + * 1 TET 2.0, 2.1 + * 2 pCOS 1.x + * 3 PDFlib 7.0.x + */ + +#ifndef PCOS_INTERFACE +#define PCOS_INTERFACE 3 + +/* document access levels. +*/ +typedef enum +{ + pcos_mode_minimum = 0, /* encrypted doc (opened w/o password) */ + pcos_mode_restricted = 1, /* encrypted doc (opened w/ user password) */ + pcos_mode_full = 2 /* unencrypted doc or opened w/ master password */ +} pcos_mode; + + +/* object types. +*/ +typedef enum +{ + pcos_ot_null = 0, + pcos_ot_boolean = 1, + pcos_ot_number = 2, + pcos_ot_name = 3, + pcos_ot_string = 4, + pcos_ot_array = 5, + pcos_ot_dict = 6, + pcos_ot_stream = 7, + pcos_ot_fstream = 8 +} pcos_object_type; + +#endif /* PCOS_INTERFACE */ + + +/* + * ---------------------------------------------------------------------- + * Exception handling with try/catch implementation + * ---------------------------------------------------------------------- + */ + +/* Set up an exception handling frame; must always be paired with PDF_CATCH().*/ + +#define PDF_TRY(p) if (p) { if (setjmp(pdf_jbuf(p)->jbuf) == 0) + +/* Inform the exception machinery that a PDF_TRY() will be left without + entering the corresponding PDF_CATCH( ) clause. */ +#define PDF_EXIT_TRY(p) pdf_exit_try(p) + +/* Catch an exception; must always be paired with PDF_TRY(). */ +#define PDF_CATCH(p) } if (pdf_catch(p)) + +/* Re-throw an exception to another handler. */ +#define PDF_RETHROW(p) pdf_rethrow(p) + + +/* + * ---------------------------------------------------------------------- + * End of supported public declarations + * ---------------------------------------------------------------------- + */ + +/* + * ------------------------------------------------------------------------ + * Deprecated: macros for page size formats + * ------------------------------------------------------------------------ + */ + +/* + * The page sizes are only available to the C and C++ bindings. + * These are deprecated; corresponding options are supported in + * PDF_begin_page_ext(). + */ + +#define a0_width 2380.0 +#define a0_height 3368.0 +#define a1_width 1684.0 +#define a1_height 2380.0 +#define a2_width 1190.0 +#define a2_height 1684.0 +#define a3_width 842.0 +#define a3_height 1190.0 +#define a4_width 595.0 +#define a4_height 842.0 +#define a5_width 421.0 +#define a5_height 595.0 +#define a6_width 297.0 +#define a6_height 421.0 +#define b5_width 501.0 +#define b5_height 709.0 +#define letter_width 612.0 +#define letter_height 792.0 +#define legal_width 612.0 +#define legal_height 1008.0 +#define ledger_width 1224.0 +#define ledger_height 792.0 +#define p11x17_width 792.0 +#define p11x17_height 1224.0 + + +/* + * ---------------------------------------------------------------------- + * Deprecated: Error classes + * ---------------------------------------------------------------------- + */ + +/* + * Error classes are deprecated; use PDF_TRY/PDF_CATCH instead. + * Note that old-style error handlers are still supported, but + * they will always receive PDF_UnknownError. + */ + +#define PDF_MemoryError 1 +#define PDF_IOError 2 +#define PDF_RuntimeError 3 +#define PDF_IndexError 4 +#define PDF_TypeError 5 +#define PDF_DivisionByZero 6 +#define PDF_OverflowError 7 +#define PDF_SyntaxError 8 +#define PDF_ValueError 9 +#define PDF_SystemError 10 +#define PDF_NonfatalError 11 +#define PDF_UnknownError 12 + + +/* + * ---------------------------------------------------------------------- + * Deprecated functions (should no longer be used) + * ---------------------------------------------------------------------- + */ + +#if _MSC_VER >= 1310 /* VS .NET 2003 and later */ +#pragma deprecated(PDF_add_bookmark) +#pragma deprecated(PDF_add_bookmark2) +#pragma deprecated(PDF_add_launchlink) +#pragma deprecated(PDF_add_locallink) +#pragma deprecated(PDF_add_note) +#pragma deprecated(PDF_add_note2) +#pragma deprecated(PDF_add_pdflink) +#pragma deprecated(PDF_add_weblink) +#pragma deprecated(PDF_attach_file) +#pragma deprecated(PDF_attach_file2) +#pragma deprecated(PDF_begin_page) +#pragma deprecated(PDF_begin_template) +#pragma deprecated(PDF_boot) +#pragma deprecated(PDF_close) +#pragma deprecated(PDF_end_page) +#pragma deprecated(PDF_findfont) +#pragma deprecated(PDF_get_majorversion) +#pragma deprecated(PDF_get_minorversion) +#pragma deprecated(PDF_get_pdi_value) +#pragma deprecated(PDF_get_pdi_parameter) +#pragma deprecated(PDF_open_CCITT) +#pragma deprecated(PDF_open_file) +#pragma deprecated(PDF_open_image) +#pragma deprecated(PDF_open_image_file) +#pragma deprecated(PDF_open_mem) +#pragma deprecated(PDF_place_image) +#pragma deprecated(PDF_place_pdi_page) +#pragma deprecated(PDF_set_border_color) +#pragma deprecated(PDF_set_border_dash) +#pragma deprecated(PDF_set_border_style) +#pragma deprecated(PDF_setgray) +#pragma deprecated(PDF_setgray_fill) +#pragma deprecated(PDF_setgray_stroke) +#pragma deprecated(PDF_setpolydash) +#pragma deprecated(PDF_setrgbcolor) +#pragma deprecated(PDF_setrgbcolor_fill) +#pragma deprecated(PDF_setrgbcolor_stroke) +#pragma deprecated(PDF_show_boxed) +#pragma deprecated(PDF_show_boxed2) +#pragma deprecated(PDF_shutdown) +#endif + +/* + * ---------------------------------------------------------------------- + * Private stuff, do not use explicitly but only via the macros above! + * ---------------------------------------------------------------------- + */ + +PDFLIB_API pdf_jmpbuf * PDFLIB_CALL +pdf_jbuf(PDF *p); + +PDFLIB_API void PDFLIB_CALL +pdf_exit_try(PDF *p); + +PDFLIB_API int PDFLIB_CALL +pdf_catch(PDF *p); + +PDFLIB_API void PDFLIB_CALL +pdf_rethrow(PDF *p); + +PDFLIB_API void PDFLIB_CALL +pdf_throw(PDF *p, const char *binding, const char *apiname, const char *errmsg); + + +/* + * ---------------------------------------------------------------------- + * End of useful stuff + * ---------------------------------------------------------------------- + */ + +#if defined(__MWERKS__) && defined(PDFLIB_EXPORTS) +#pragma export off +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PDFLIB_H */ + +/* + * vim600: sw=4 fdm=marker + */ -- cgit v1.2.3