summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bk_pdf.c3
-rw-r--r--bk_ps.c99
-rw-r--r--paper.h5
3 files changed, 77 insertions, 30 deletions
diff --git a/bk_pdf.c b/bk_pdf.c
index 8b03ae2..ba19372 100644
--- a/bk_pdf.c
+++ b/bk_pdf.c
@@ -40,7 +40,6 @@ static void pdf_string_len(void (*add)(object *, char const *),
object *, char const *, int);
static void objref(object *o, object *dest);
static void objdest(object *o, page_data *p);
-static char *pdf_outline_convert(wchar_t *s, int *len);
static int is_std_font(char const *name);
@@ -725,7 +724,7 @@ static void make_pages_node(object *node, object *parent, page_data *first,
* encodes in either PDFDocEncoding (a custom superset of
* ISO-8859-1) or UTF-16BE.
*/
-static char *pdf_outline_convert(wchar_t *s, int *len) {
+char *pdf_outline_convert(wchar_t *s, int *len) {
char *ret;
ret = utoa_careful_dup(s, CS_PDF);
diff --git a/bk_ps.c b/bk_ps.c
index 86b8465..35fe582 100644
--- a/bk_ps.c
+++ b/bk_ps.c
@@ -7,6 +7,7 @@
#include "paper.h"
static void ps_comment(FILE *fp, char const *leader, word *words);
+static void ps_string_len(FILE *fp, char const *str, int len);
static void ps_string(FILE *fp, char const *str);
paragraph *ps_config_filename(char *filename)
@@ -24,6 +25,9 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords,
FILE *fp;
char *filename;
paragraph *p;
+ outline_element *oe;
+ int noe;
+
IGNORE(keywords);
IGNORE(idx);
@@ -119,6 +123,18 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords,
fprintf(fp, "%%%%BeginSetup\n");
/*
+ * Assign a destination name to each page for pdfmark purposes.
+ */
+ pageno = 0;
+ for (page = doc->pages; page; page = page->next) {
+ char *buf;
+ pageno++;
+ buf = snewn(12, char);
+ sprintf(buf, "/p%d", pageno);
+ page->spare = buf;
+ }
+
+ /*
* This is as good a place as any to put version IDs.
*/
for (p = sourceform; p; p = p->next)
@@ -137,11 +153,29 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords,
doc->paper_height / FUNITS_PER_PT);
fprintf(fp, "} if\n");
- /* Request outline view if the document is converted to PDF. */
- fprintf(fp,
- "/pdfmark where {\n"
- " pop [ /PageMode /UseOutlines /DOCVIEW pdfmark\n"
- "} if\n");
+ /* Outline etc, only if pdfmark is supported */
+ fprintf(fp, "/pdfmark where { pop %% if\n");
+ fprintf(fp, " [/PageMode/UseOutlines/DOCVIEW pdfmark\n");
+ noe = doc->n_outline_elements;
+ for (oe = doc->outline_elements; noe; oe++, noe--) {
+ char *title;
+ int titlelen, count, i;
+
+ title = pdf_outline_convert(oe->pdata->outline_title, &titlelen);
+
+ count = 0;
+ for (i = 1; i < noe && oe[i].level > oe->level; i++)
+ if (oe[i].level == oe->level + 1)
+ count++;
+ if (oe->level > 0) count = -count;
+
+ fprintf(fp, " [/Title");
+ ps_string_len(fp, title, titlelen);
+ sfree(title);
+ fprintf(fp, "/Dest%s/Count %d/OUT pdfmark\n",
+ (char *)oe->pdata->first->page->spare, count);
+ }
+ fprintf(fp, "} if\n");
for (fe = doc->fonts->head; fe; fe = fe->next) {
/* XXX This may request the same font multiple times. */
@@ -187,18 +221,6 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords,
fprintf(fp, "%%%%EndSetup\n");
/*
- * Assign a destination name to each page for pdfmark purposes.
- */
- pageno = 0;
- for (page = doc->pages; page; page = page->next) {
- char *buf;
- pageno++;
- buf = snewn(12, char);
- sprintf(buf, "/p%d", pageno);
- page->spare = buf;
- }
-
- /*
* Output the text and graphics.
*/
pageno = 0;
@@ -310,18 +332,39 @@ static void ps_comment(FILE *fp, char const *leader, word *words)
fprintf(fp, "\n");
}
-static void ps_string(FILE *fp, char const *str) {
+static void ps_string_len(FILE *fp, char const *str, int len) {
char const *c;
-
- fprintf(fp, "(");
- for (c = str; *c; c++) {
- if (*c < ' ' || *c > '~') {
- fprintf(fp, "\\%03o", 0xFF & (int)*c);
- } else {
- if (*c == '(' || *c == ')' || *c == '\\')
- fputc('\\', fp);
- fputc(*c, fp);
+ int score = 0;
+
+ for (c = str; c < str+len; c++) {
+ if (*c < ' ' || *c > '~')
+ score += 2;
+ else if (*c == '(' || *c == ')' || *c == '\\')
+ score += 0;
+ else
+ score -= 1;
+ }
+ if (score > 0) {
+ fprintf(fp, "<");
+ for (c = str; c < str+len; c++) {
+ fprintf(fp, "%02X", 0xFF & (int)*c);
}
+ fprintf(fp, ">");
+ } else {
+ fprintf(fp, "(");
+ for (c = str; c < str+len; c++) {
+ if (*c < ' ' || *c > '~') {
+ fprintf(fp, "\\%03o", 0xFF & (int)*c);
+ } else {
+ if (*c == '(' || *c == ')' || *c == '\\')
+ fputc('\\', fp);
+ fputc(*c, fp);
+ }
+ }
+ fprintf(fp, ")");
}
- fprintf(fp, ")");
+}
+
+static void ps_string(FILE *fp, char const *str) {
+ ps_string_len(fp, str, strlen(str));
}
diff --git a/paper.h b/paper.h
index 2811f37..03b0f1b 100644
--- a/paper.h
+++ b/paper.h
@@ -371,4 +371,9 @@ void init_std_fonts(void);
const int *ps_std_font_widths(char const *fontname);
const kern_pair *ps_std_font_kerns(char const *fontname);
+/*
+ * Function from bk_pdf.c borrowed by bk_ps.c
+ */
+char *pdf_outline_convert(wchar_t *s, int *len);
+
#endif