commit 58fc5bb7a3e7f802e5309c3980344f7959f1b3e2 Author: Sam Liddicott Date: Thu Jun 30 17:51:43 2011 +0100 Add pdfmark support to reference diff --git a/src/src/Graphics/Renderer/printer.cpp b/src/src/Graphics/Renderer/printer.cpp index c1da452..946d522 100644 --- a/src/src/Graphics/Renderer/printer.cpp +++ b/src/src/Graphics/Renderer/printer.cpp @@ -118,6 +118,9 @@ printer_rep::~printer_rep () { generate_tex_fonts (); prologue << "end\n" + + << "systemdict /pdfmark known{userdict /?pdfmark systemdict /exec get put}{userdict /?pdfmark systemdict /pop get put userdict /pdfmark systemdict /cleartomark get put}ifelse\n" + << "%%EndProlog\n\n" << "%%BeginSetup\n" << "%%Feature: *Resolution " << as_string (dpi) << "dpi\n" @@ -822,6 +825,40 @@ printer_rep::apply_shadow (SI x1, SI y1, SI x2, SI y2) { (void) x1; (void) y1; (void) x2; (void) y2; } +void +printer_rep::anchor(string label, SI x, SI y) { + string s = "("; + s = s << prepare_text(label) << ") cvn"; + + if (linelen>0) cr(); + print("[ /Dest"); + print(s); + print("/View [/XYZ"); + print(x, y); + print("null] /DEST pdfmark"); + cr(); +} + +void +printer_rep::href(string label, SI x1, SI y1, SI x2, SI y2) { + string s = "("; + s = s << prepare_text(label) << ") cvn"; + + if (linelen>0) cr(); + + print("["); + print("/Dest"); + print(s); + print("/Rect ["); + print(x1, y1); + print(x2, y2); + print("]"); + print("/Border [16 16 1 [3 10]] /Color [1 0 0]"); + print("/Subtype /Link"); + print("/ANN pdfmark"); + cr(); +} + /****************************************************************************** * user interface ******************************************************************************/ diff --git a/src/src/Graphics/Renderer/printer.hpp b/src/src/Graphics/Renderer/printer.hpp index aff9c48..486435b 100644 --- a/src/src/Graphics/Renderer/printer.hpp +++ b/src/src/Graphics/Renderer/printer.hpp @@ -69,6 +69,10 @@ public: void select_tex_font (string name); void generate_tex_fonts (); + /************************ subroutines hyperlinks ***************************/ + void anchor(string label, SI x, SI y); + void href(string label, SI x1, SI y1, SI x2, SI y2); + /********************** routines from renderer.hpp *************************/ void set_clipping (SI x1, SI y1, SI x2, SI y2, bool restore= false); diff --git a/src/src/Graphics/Renderer/renderer.cpp b/src/src/Graphics/Renderer/renderer.cpp index 1d458ec..5e91ab1 100644 --- a/src/src/Graphics/Renderer/renderer.cpp +++ b/src/src/Graphics/Renderer/renderer.cpp @@ -64,6 +64,20 @@ renderer_rep::interrupted (bool check) { return false; } +void +renderer_rep::anchor(string label, SI x, SI y) { + (void) label; + return; +} + +void +renderer_rep::href(string label, SI x1, SI y1, SI x2, SI y2) { + (void) label; + (void) x1; (void) y1; (void) x2; (void) y2; + return; +} + + /****************************************************************************** * Origin and shrinking factor ******************************************************************************/ diff --git a/src/src/Graphics/Renderer/renderer.hpp b/src/src/Graphics/Renderer/renderer.hpp index f42060a..ae379c3 100644 --- a/src/src/Graphics/Renderer/renderer.hpp +++ b/src/src/Graphics/Renderer/renderer.hpp @@ -104,6 +104,10 @@ public: virtual void get_shadow (renderer ren, SI x1, SI y1, SI x2, SI y2) = 0; virtual void put_shadow (renderer ren, SI x1, SI y1, SI x2, SI y2) = 0; virtual void apply_shadow (SI x1, SI y1, SI x2, SI y2) = 0; + + /* href and stuff */ + virtual void anchor(string label, SI x, SI y); + virtual void href(string label, SI x1, SI y1, SI x2, SI y2); }; void abs_round (SI& l); diff --git a/src/src/Typeset/Boxes/Modifier/change_boxes.cpp b/src/src/Typeset/Boxes/Modifier/change_boxes.cpp index 3b4ab4d..d656d8e 100644 --- a/src/src/Typeset/Boxes/Modifier/change_boxes.cpp +++ b/src/src/Typeset/Boxes/Modifier/change_boxes.cpp @@ -469,20 +469,39 @@ action_box_rep::action (tree t, SI x, SI y, SI delta) { struct locus_box_rep: public change_box_rep { list ids; SI pixel; + string ref; + string anchor; locus_box_rep (path ip, box b, list ids, SI pixel); + locus_box_rep (path ip, box b, list ids, SI pixel, string _rep, string _anchor); operator tree () { return tree (TUPLE, "locus"); } void loci (SI x, SI y, SI delta, list& ids2, rectangles& rs); + void post_display (renderer &ren); + }; locus_box_rep::locus_box_rep (path ip, box b, list ids2, SI pixel2): change_box_rep (ip, true), ids (ids2), pixel (pixel2) { + ref = ""; + anchor = ""; insert (b, 0, 0); position (); left_justify (); finalize (); } +locus_box_rep::locus_box_rep (path ip, box b, list ids2, SI pixel2, string _ref, string _anchor): + change_box_rep (ip, true), ids (ids2), pixel (pixel2) +{ + ref = _ref; + anchor = _anchor; + insert (b, 0, 0); + position (); + left_justify (); + finalize (); +} + + void locus_box_rep::loci (SI x, SI y, SI delta, list& l, rectangles& rs) { bs[0]->loci (x, y, delta, l, rs); @@ -490,6 +509,12 @@ locus_box_rep::loci (SI x, SI y, SI delta, list& l, rectangles& rs) { rs= rs * outline (rectangles (rectangle (x1, y1, x2, y2)), pixel); } +void +locus_box_rep::post_display (renderer &ren) { + if (ref!="") ren->href(ref, x1, y1, x2, y2); + if (anchor!="") ren->anchor(anchor, x1, y1); +} + /****************************************************************************** * tag boxes ******************************************************************************/ @@ -630,6 +655,11 @@ locus_box (path ip, box b, list ids, SI pixel) { } box +locus_box (path ip, box b, list ids, SI pixel, string ref, string anchor) { + return tm_new (ip, b, ids, pixel, ref, anchor); +} + +box tag_box (path ip, box b, tree keys) { return tm_new (ip, b, keys); } diff --git a/src/src/Typeset/Boxes/construct.hpp b/src/src/Typeset/Boxes/construct.hpp index bd4eaf0..f146dd8 100644 --- a/src/src/Typeset/Boxes/construct.hpp +++ b/src/src/Typeset/Boxes/construct.hpp @@ -93,6 +93,7 @@ box page_box (path ip, tree page, SI w, SI h, box action_box (path ip, box b, tree filter, command cmd, bool child_flag); box action_box (path ip, box b, tree f, command c, bool ch, path vip); box locus_box (path ip, box b, list ids, SI pixel); +box locus_box (path ip, box b, list ids, SI pixel, string ref, string anchor); box macro_box (path ip, box b, font big_fn= font ()); box tag_box (path ip, box b, tree keys); diff --git a/src/src/Typeset/Concat/concat_active.cpp b/src/src/Typeset/Concat/concat_active.cpp index 86ed5eb..390f8ef 100644 --- a/src/src/Typeset/Concat/concat_active.cpp +++ b/src/src/Typeset/Concat/concat_active.cpp @@ -81,13 +81,16 @@ concater_rep::typeset_case (tree t, path ip) { ******************************************************************************/ bool -build_locus (edit_env env, tree t, list& ids, string& col) { +build_locus (edit_env env, tree t, list& ids, string& col, string &ref, string &anchor) { //cout << "Typeset " << t << "\n"; int last= N(t)-1; tree body= env->expand (t[last], true); //cout << "Typeset " << body << "\n"; bool accessible= is_accessible (obtain_ip (body)); bool visited= false; + ref=""; + anchor=""; + if (!is_nil (env->link_env)) { int i, j; for (i=0; i& ids, string& col) { << (env->secure? tree ("true"): tree ("false")); env->link_env->insert_link (arg); for (j=2; jlabel); - if (is_compound (arg[j], "url", 1) && is_atomic (arg[j][0])) + anchor = arg[j][0]->label; + } + if (is_compound (arg[j], "url", 1) && is_atomic (arg[j][0])) { visited= visited || has_been_visited ("url:" * arg[j][0]->label); + ref = arg[j][0]->label; + } } } } @@ -132,13 +139,23 @@ build_locus (edit_env env, tree t, list& ids, string& col) { return accessible; } +bool +build_locus (edit_env env, tree t, list& ids, string& col) { + string ref; + string anchor; + return build_locus(env, t, ids, col, ref, anchor); +} + void concater_rep::typeset_locus (tree t, path ip) { + string ref; + string anchor; + if (N(t) == 0) { typeset_error (t, ip); return; } int last= N(t)-1; list ids; string col; - if (build_locus (env, t, ids, col)) { + if (build_locus (env, t, ids, col, ref, anchor)) { marker (descend (ip, 0)); tree old= env->local_begin (COLOR, col); typeset (t[last], descend (ip, last)); @@ -149,7 +166,7 @@ concater_rep::typeset_locus (tree t, path ip) { tree old= env->local_begin (COLOR, col); box b= typeset_as_concat (env, t[last], descend (ip, last)); env->local_end (COLOR, old); - print (locus_box (ip, b, ids, env->get_int (SFACTOR) * PIXEL)); + print (locus_box (ip, b, ids, env->get_int (SFACTOR) * PIXEL, ref, anchor)); } } diff --git a/src/src/Typeset/Env/env_default.cpp b/src/src/Typeset/Env/env_default.cpp index ff41d06..7245129 100644 --- a/src/src/Typeset/Env/env_default.cpp +++ b/src/src/Typeset/Env/env_default.cpp @@ -252,9 +252,11 @@ initialize_default_env () { tree dest_url (URL, tree (ARG, "destination")); tree dest_script (SCRIPT, tree (ARG, "destination"), tree (ARG, "where")); tree dest_ref (URL, tree (MERGE, "#", tree (ARG, "Id"))); + tree anchor (ID, tree (MERGE, "#", tree (ARG, "Id"))); tree ln1 (LINK, "hyperlink", copy (src_id), copy (dest_url)); tree ln2 (LINK, "action", copy (src_id), copy (dest_script)); tree ln3 (LINK, "hyperlink", copy (ref_id), copy (dest_ref)); + tree ln4 (LINK, "anchor", anchor); tree labflag (FLAG, tree (ARG, "Id"), "blue", "Id"); tree labtxt (SET_BINDING, tree (ARG, "Id"), tree (VALUE, THE_LABEL)); tree merged (MERGE, tree (VALUE, THE_TAGS), tuple (tree (ARG, "Id"))); @@ -267,7 +269,8 @@ initialize_default_env () { env ("action")= tree (MACRO, "body", "destination", "where", tree (LOCUS, copy (src_id), ln2, tree (ARG, "body"))); - env ("label")= tree (MACRO, "Id", tree (CONCAT, labflag, labtxt)); + env ("label")= tree (MACRO, "Id", + tree (LOCUS, copy (ref_id), ln4, tree (CONCAT, labflag, labtxt))); env ("tag")= tree (MACRO, "Id", "body", tree (WITH, "the-tags", merged, tree (SURROUND, tagflag, "",