summaryrefslogtreecommitdiff
path: root/src/pdflib/pdflib
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdflib/pdflib')
-rw-r--r--src/pdflib/pdflib/p_3d.c22
-rw-r--r--src/pdflib/pdflib/p_actions.c1155
-rw-r--r--src/pdflib/pdflib/p_afm.c756
-rw-r--r--src/pdflib/pdflib/p_annots.c2078
-rw-r--r--src/pdflib/pdflib/p_block.c26
-rw-r--r--src/pdflib/pdflib/p_bmp.c795
-rw-r--r--src/pdflib/pdflib/p_ccitt.c186
-rw-r--r--src/pdflib/pdflib/p_cid.c198
-rw-r--r--src/pdflib/pdflib/p_color.c1130
-rw-r--r--src/pdflib/pdflib/p_color.h109
-rw-r--r--src/pdflib/pdflib/p_defopt.h494
-rw-r--r--src/pdflib/pdflib/p_document.c1939
-rw-r--r--src/pdflib/pdflib/p_draw.c410
-rw-r--r--src/pdflib/pdflib/p_encoding.c187
-rw-r--r--src/pdflib/pdflib/p_fields.c30
-rw-r--r--src/pdflib/pdflib/p_filter.c120
-rw-r--r--src/pdflib/pdflib/p_font.c2513
-rw-r--r--src/pdflib/pdflib/p_font.h225
-rw-r--r--src/pdflib/pdflib/p_generr.h705
-rw-r--r--src/pdflib/pdflib/p_gif.c744
-rw-r--r--src/pdflib/pdflib/p_gstate.c451
-rw-r--r--src/pdflib/pdflib/p_hkscmyk.h28
-rw-r--r--src/pdflib/pdflib/p_hkslab.h26
-rw-r--r--src/pdflib/pdflib/p_hyper.c1449
-rw-r--r--src/pdflib/pdflib/p_icc.c32
-rw-r--r--src/pdflib/pdflib/p_icc.h24
-rw-r--r--src/pdflib/pdflib/p_icc9809.h38
-rw-r--r--src/pdflib/pdflib/p_icclib.c62
-rw-r--r--src/pdflib/pdflib/p_icclib.h38
-rw-r--r--src/pdflib/pdflib/p_image.c2253
-rw-r--r--src/pdflib/pdflib/p_image.h358
-rw-r--r--src/pdflib/pdflib/p_intern.h1027
-rw-r--r--src/pdflib/pdflib/p_jpeg.c1560
-rw-r--r--src/pdflib/pdflib/p_jpx.c73
-rw-r--r--src/pdflib/pdflib/p_kerning.c21
-rw-r--r--src/pdflib/pdflib/p_keyconn.h827
-rw-r--r--src/pdflib/pdflib/p_layer.c36
-rw-r--r--src/pdflib/pdflib/p_layer.h24
-rw-r--r--src/pdflib/pdflib/p_mbox.c943
-rw-r--r--src/pdflib/pdflib/p_object.c257
-rw-r--r--src/pdflib/pdflib/p_opi.c21
-rw-r--r--src/pdflib/pdflib/p_page.c2261
-rw-r--r--src/pdflib/pdflib/p_page.h34
-rw-r--r--src/pdflib/pdflib/p_pantlab.h28
-rw-r--r--src/pdflib/pdflib/p_params.c1306
-rw-r--r--src/pdflib/pdflib/p_params.h373
-rw-r--r--src/pdflib/pdflib/p_pattern.c231
-rw-r--r--src/pdflib/pdflib/p_pdi.c28
-rw-r--r--src/pdflib/pdflib/p_pfm.c406
-rw-r--r--src/pdflib/pdflib/p_photoshp.c23
-rw-r--r--src/pdflib/pdflib/p_png.c855
-rw-r--r--src/pdflib/pdflib/p_shading.c381
-rw-r--r--src/pdflib/pdflib/p_subsett.c26
-rw-r--r--src/pdflib/pdflib/p_table.c26
-rw-r--r--src/pdflib/pdflib/p_tagged.c53
-rw-r--r--src/pdflib/pdflib/p_tagged.h25
-rw-r--r--src/pdflib/pdflib/p_template.c246
-rw-r--r--src/pdflib/pdflib/p_text.c3715
-rw-r--r--src/pdflib/pdflib/p_textflow.c27
-rw-r--r--src/pdflib/pdflib/p_tiff.c1169
-rw-r--r--src/pdflib/pdflib/p_truetype.c301
-rw-r--r--src/pdflib/pdflib/p_type1.c427
-rw-r--r--src/pdflib/pdflib/p_type3.c740
-rw-r--r--src/pdflib/pdflib/p_util.c733
-rw-r--r--src/pdflib/pdflib/p_xgstate.c514
-rw-r--r--src/pdflib/pdflib/p_xmp.c25
-rw-r--r--src/pdflib/pdflib/pdflib.c4052
-rw-r--r--src/pdflib/pdflib/pdflib.h1572
68 files changed, 42947 insertions, 0 deletions
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 <time.h>
+
+#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 <fcntl.h>
+#include <io.h>
+#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<</Registry");
+ pdf_put_hypertext(p, "Adobe");
+ pdc_puts(p->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<<MAX_LWZ_BITS); ++i)
+ table[0][i] = table[1][i] = 0;
+ code_size = set_code_size+1;
+ max_code_size = 2*clear_code;
+ max_code = clear_code+2;
+ sp = stack;
+ do {
+ firstcode = oldcode = nextCode(p, image, code_size);
+ } while (firstcode == clear_code);
+
+ return firstcode;
+ }
+ if (code == end_code) {
+ int count;
+ unsigned char lbuf[260];
+
+ if (ZeroDataBlock)
+ return -2;
+
+ while ((count = GetDataBlock(p, image, lbuf)) > 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_LWZ_BITS)) {
+ table[0][code] = oldcode;
+ table[1][code] = firstcode;
+ ++max_code;
+ if ((max_code >= max_code_size) &&
+ (max_code_size < (1<<MAX_LWZ_BITS))) {
+ max_code_size *= 2;
+ ++code_size;
+ }
+ }
+
+ oldcode = incode;
+
+ if (sp > 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 <windows.h>
+#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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+#ifdef __sun
+#include <unistd.h>
+#endif
+#if defined(__IBMC__) && defined(_M_IX86)
+#include <float.h>
+#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<</FS/URL/F");
+ pdc_put_pdfstring(p->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; comp<image->components; 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; comp<image->components; 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 <time.h>
+
+#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 <windows.h>
+#include <winbase.h>
+#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 <stdio.h>
+#include <setjmp.h>
+
+#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
+ */