summaryrefslogtreecommitdiff
path: root/gs/src/spsdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/spsdf.c')
-rw-r--r--gs/src/spsdf.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/gs/src/spsdf.c b/gs/src/spsdf.c
new file mode 100644
index 000000000..df6383ded
--- /dev/null
+++ b/gs/src/spsdf.c
@@ -0,0 +1,267 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Common utilities for PostScript and PDF format printing */
+#include "stdio_.h" /* for stream.h */
+#include "string_.h"
+#include "gstypes.h"
+#include "gsmemory.h"
+#include "gserror.h"
+#include "gserrors.h"
+#include "spprint.h"
+#include "spsdf.h"
+#include "stream.h"
+#include "strimpl.h"
+#include "sa85x.h"
+#include "sstring.h"
+#include "scanchar.h"
+
+/*
+ * Write a string in its shortest form ( () or <> ). Note that
+ * this form is different depending on whether binary data are allowed.
+ * Currently we don't support ASCII85 strings ( <~ ~> ).
+ */
+void
+s_write_ps_string(stream * s, const byte * str, uint size, int print_ok)
+{
+ uint added = 0;
+ uint i;
+ const stream_template *template;
+ stream_AXE_state state;
+ stream_state *st = NULL;
+
+ if (print_ok & PRINT_BINARY_OK) {
+ /* Only need to escape (, ), \, CR, EOL. */
+ pputc(s, '(');
+ for (i = 0; i < size; ++i) {
+ byte ch = str[i];
+
+ switch (ch) {
+ case char_CR:
+ pputs(s, "\\r");
+ continue;
+ case char_EOL:
+ pputs(s, "\\n");
+ continue;
+ case '(':
+ case ')':
+ case '\\':
+ pputc(s, '\\');
+ }
+ pputc(s, ch);
+ }
+ pputc(s, ')');
+ return;
+ }
+ for (i = 0; i < size; ++i) {
+ byte ch = str[i];
+
+ if (ch == 0 || ch >= 127)
+ added += 3;
+ else if (strchr("()\\\n\r\t\b\f", ch) != 0)
+ ++added;
+ else if (ch < 32)
+ added += 3;
+ }
+
+ if (added < size) {
+ /* More efficient to represent as PostScript string. */
+ template = &s_PSSE_template;
+ pputc(s, '(');
+ } else {
+ /* More efficient to represent as hex string. */
+ template = &s_AXE_template;
+ st = (stream_state *) & state;
+ s_AXE_init_inline(&state);
+ pputc(s, '<');
+ }
+
+ {
+ byte buf[100]; /* size is arbitrary */
+ stream_cursor_read r;
+ stream_cursor_write w;
+ int status;
+
+ r.ptr = str - 1;
+ r.limit = r.ptr + size;
+ w.limit = buf + sizeof(buf) - 1;
+ do {
+ w.ptr = buf - 1;
+ status = (*template->process) (st, &r, &w, true);
+ pwrite(s, buf, (uint) (w.ptr + 1 - buf));
+ }
+ while (status == 1);
+ }
+}
+
+/* Set up a write stream that just keeps track of the position. */
+int
+s_alloc_position_stream(stream ** ps, gs_memory_t * mem)
+{
+ stream *s = *ps = s_alloc(mem, "s_alloc_position_stream");
+
+ if (s == 0)
+ return_error(gs_error_VMerror);
+ swrite_position_only(s);
+ return 0;
+}
+
+/* ---------------- Parameter printing ---------------- */
+
+private_st_printer_param_list();
+const param_printer_params_t param_printer_params_default = {
+ param_printer_params_default_values
+};
+
+/* We'll implement the other printers later if we have to. */
+private param_proc_xmit_typed(param_print_typed);
+/*private param_proc_begin_xmit_collection(param_print_begin_collection); */
+/*private param_proc_end_xmit_collection(param_print_end_collection); */
+private const gs_param_list_procs printer_param_list_procs = {
+ param_print_typed,
+ NULL /* begin_collection */ ,
+ NULL /* end_collection */ ,
+ NULL /* get_next_key */ ,
+ gs_param_request_default,
+ gs_param_requested_default
+};
+
+int
+s_init_param_printer(printer_param_list_t *prlist,
+ const param_printer_params_t * ppp, stream * s)
+{
+ prlist->procs = &printer_param_list_procs;
+ prlist->memory = 0;
+ prlist->strm = s;
+ prlist->params = *ppp;
+ prlist->any = false;
+ return 0;
+}
+int
+s_alloc_param_printer(gs_param_list ** pplist,
+ const param_printer_params_t * ppp, stream * s,
+ gs_memory_t * mem)
+{
+ printer_param_list_t *prlist =
+ gs_alloc_struct(mem, printer_param_list_t, &st_printer_param_list,
+ "s_alloc_param_printer");
+ int code;
+
+ *pplist = (gs_param_list *)prlist;
+ if (prlist == 0)
+ return_error(gs_error_VMerror);
+ code = s_init_param_printer(prlist, ppp, s);
+ prlist->memory = mem;
+ return code;
+}
+
+void
+s_release_param_printer(printer_param_list_t *prlist)
+{
+ if (prlist) {
+ if (prlist->any && prlist->params.suffix)
+ pputs(prlist->strm, prlist->params.suffix);
+ }
+}
+void
+s_free_param_printer(gs_param_list * plist)
+{
+ if (plist) {
+ printer_param_list_t *const prlist = (printer_param_list_t *) plist;
+
+ s_release_param_printer(prlist);
+ gs_free_object(prlist->memory, plist, "s_free_param_printer");
+ }
+}
+
+private int
+param_print_typed(gs_param_list * plist, gs_param_name pkey,
+ gs_param_typed_value * pvalue)
+{
+ printer_param_list_t *const prlist = (printer_param_list_t *)plist;
+ stream *s = prlist->strm;
+
+ if (!prlist->any) {
+ if (prlist->params.prefix)
+ pputs(s, prlist->params.prefix);
+ prlist->any = true;
+ }
+ if (prlist->params.item_prefix)
+ pputs(s, prlist->params.item_prefix);
+ pprints1(s, "/%s", pkey);
+ switch (pvalue->type) {
+ case gs_param_type_null:
+ pputs(s, " null");
+ break;
+ case gs_param_type_bool:
+ pputs(s, (pvalue->value.b ? " true" : " false"));
+ break;
+ case gs_param_type_int:
+ pprintd1(s, " %d", pvalue->value.i);
+ break;
+ case gs_param_type_long:
+ pprintld1(s, " %l", pvalue->value.l);
+ break;
+ case gs_param_type_float:
+ pprintg1(s, " %g", pvalue->value.f);
+ break;
+ case gs_param_type_string:
+ s_write_ps_string(s, pvalue->value.s.data, pvalue->value.s.size,
+ prlist->params.print_ok);
+ break;
+ case gs_param_type_name:
+ /****** SHOULD USE #-ESCAPES FOR PDF ******/
+ pputc(s, '/');
+ pwrite(s, pvalue->value.n.data, pvalue->value.n.size);
+ break;
+ case gs_param_type_int_array:
+ {
+ uint i;
+ char sepr = (pvalue->value.ia.size <= 10 ? ' ' : '\n');
+
+ pputc(s, '[');
+ for (i = 0; i < pvalue->value.ia.size; ++i) {
+ pprintd1(s, "%d", pvalue->value.ia.data[i]);
+ pputc(s, sepr);
+ }
+ pputc(s, ']');
+ }
+ break;
+ case gs_param_type_float_array:
+ {
+ uint i;
+ char sepr = (pvalue->value.fa.size <= 10 ? ' ' : '\n');
+
+ pputc(s, '[');
+ for (i = 0; i < pvalue->value.fa.size; ++i) {
+ pprintg1(s, "%g", pvalue->value.fa.data[i]);
+ pputc(s, sepr);
+ }
+ pputc(s, ']');
+ }
+ break;
+ /*case gs_param_type_string_array: */
+ /*case gs_param_type_name_array: */
+ default:
+ return_error(gs_error_typecheck);
+ }
+ if (prlist->params.item_suffix)
+ pputs(s, prlist->params.item_suffix);
+ return 0;
+}