Implemented lines under chapter titles.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 13 Apr 2004 20:03:39 +0000 (20:03 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 13 Apr 2004 20:03:39 +0000 (20:03 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/halibut@4065 cda61777-01e9-0310-a592-d414129be87e

bk_paper.c
bk_pdf.c
bk_ps.c
paper.h

index 417edf8..5221434 100644 (file)
 /*
  * To be done:
  * 
- *  - implement some simple graphics
- *     * I had an underline below chapter headings in the original
- *      Perl version, and I thought it looked rather nice
- *     * also we need para_Rule.
+ *  - implement para_Rule
  * 
  *  - set up contents section now we know what sections begin on
  *    which pages
@@ -60,6 +57,7 @@ static int paper_width_simple(para_data *pdata, word *text);
 static void code_paragraph(para_data *pdata,
                           font_data *fn, font_data *fi, font_data *fb,
                           int font_size, int indent, word *words);
+static void add_rect_to_page(page_data *page, int x, int y, int w, int h);
 
 void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords,
                        indexdata *idx) {
@@ -89,6 +87,8 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords,
     int base_para_spacing = 10 * 4096;
     int chapter_top_space = 72 * 4096;
     int sect_num_left_space = 12 * 4096;
+    int chapter_underline_depth = 14 * 4096;
+    int chapter_underline_thickness = 3 * 4096;
 
     int base_width = paper_width - left_margin - right_margin;
     int page_height = paper_height - top_margin - bottom_margin;
@@ -124,7 +124,6 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords,
             */
          case para_IM:
          case para_BR:
-         case para_Rule:
          case para_Biblio:
          case para_NotParaType:
          case para_Config:
@@ -432,6 +431,8 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords,
                p->type == para_UnnumberedChapter) {
                pdata->first->page_break = TRUE;
                pdata->first->space_before = chapter_top_space;
+               pdata->last->space_after +=
+                   chapter_underline_depth + chapter_underline_thickness;
            }
 
            /*
@@ -473,6 +474,20 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords,
                if (ldata == pdata->last)
                    break;
            }
+
+           /*
+            * Some section headings (FIXME: should be configurable
+            * which) want to be underlined.
+            */
+           if (p->type == para_Chapter || p->type == para_Appendix ||
+               p->type == para_UnnumberedChapter || p->type == para_Title) {
+               add_rect_to_page(pdata->last->page,
+                                left_margin,
+                                (paper_height - top_margin -
+                                 pdata->last->ypos - chapter_underline_depth),
+                                base_width,
+                                chapter_underline_thickness);
+           }
        }
     }
 
@@ -881,8 +896,8 @@ static page_data *page_breaks(line_data *first, line_data *last,
        page->last_line = l->page_last;
 
        page->first_text = page->last_text = NULL;
-
        page->first_xref = page->last_xref = NULL;
+       page->first_rect = page->last_rect = NULL;
 
        /*
         * Now assign a y-coordinate to each line on the page.
@@ -910,6 +925,23 @@ static page_data *page_breaks(line_data *first, line_data *last,
     return ph;
 }
 
+static void add_rect_to_page(page_data *page, int x, int y, int w, int h)
+{
+    rect *r = mknew(rect);
+
+    r->next = NULL;
+    if (page->last_rect)
+       page->last_rect->next = r;
+    else
+       page->first_rect = r;
+    page->last_rect = r;
+
+    r->x = x;
+    r->y = y;
+    r->w = w;
+    r->h = h;
+}
+
 static void add_string_to_page(page_data *page, int x, int y,
                               font_encoding *fe, int size, char *text)
 {
@@ -1056,6 +1088,7 @@ static int render_text(page_data *page, para_data *pdata, line_data *ldata,
                else
                    page->first_xref = *xr;
                page->last_xref = *xr;
+               (*xr)->next = NULL;
 
                /*
                 * FIXME: Ideally we should have, and use, some
@@ -1156,6 +1189,7 @@ static void render_line(line_data *ldata, int left_x, int top_y,
      */
     if (dest->type != NONE) {
        xr = mknew(xref);
+       xr->next = NULL;
        xr->dest = *dest;    /* structure copy */
        if (ldata->page->last_xref)
            ldata->page->last_xref->next = xr;
index 44a9699..14db265 100644 (file)
--- a/bk_pdf.c
+++ b/bk_pdf.c
@@ -198,6 +198,7 @@ void pdf_backend(paragraph *sourceform, keywordlist *keywords,
     pageno = 0;
     for (page = doc->pages; page; page = page->next) {
        object *opage, *cstr;
+       rect *r;
        text_fragment *frag;
        char buf[256];
 
@@ -228,6 +229,16 @@ void pdf_backend(paragraph *sourceform, keywordlist *keywords,
        objref(opage, cstr);
        objtext(opage, "\n");
 
+       /*
+        * Render any rectangles on the page.
+        */
+       for (r = page->first_rect; r; r = r->next) {
+           char buf[512];
+           sprintf(buf, "%g %g %g %g re f\n", r->x / 4096.0,
+                   r->y / 4096.0, r->w / 4096.0, r->h / 4096.0);
+           objstream(cstr, buf);
+       }
+
        objstream(cstr, "BT\n");
        for (frag = page->first_text; frag; frag = frag->next) {
            char *c;
diff --git a/bk_ps.c b/bk_ps.c
index ae1feae..1ed3610 100644 (file)
--- a/bk_ps.c
+++ b/bk_ps.c
@@ -106,11 +106,12 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords,
     fprintf(fp, "%%%%EndSetup\n");
 
     /*
-     * Output the text.
+     * Output the text and graphics.
      */
     pageno = 0;
     for (page = doc->pages; page; page = page->next) {
        text_fragment *frag;
+       rect *r;
 
        pageno++;
        fprintf(fp, "%%%%Page: %d %d\n", pageno, pageno);
@@ -137,6 +138,13 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords,
        }
 #endif
 
+       for (r = page->first_rect; r; r = r->next) {
+           fprintf(fp, "%g %g moveto %g 0 rlineto 0 %g rlineto "
+                   "-%g 0 rlineto closepath fill\n",
+                   r->x / 4096.0, r->y / 4096.0, r->w / 4096.0,
+                   r->h / 4096.0, r->w / 4096.0);
+       }
+
        for (frag = page->first_text; frag; frag = frag->next) {
            char *c;
 
diff --git a/paper.h b/paper.h
index 8478e25..1f01f8b 100644 (file)
--- a/paper.h
+++ b/paper.h
@@ -19,6 +19,7 @@ typedef struct subfont_map_entry_Tag subfont_map_entry;
 typedef struct text_fragment_Tag text_fragment;
 typedef struct xref_Tag xref;
 typedef struct xref_dest_Tag xref_dest;
+typedef struct rect_Tag rect;
 
 /*
  * This data structure represents the overall document, in the form
@@ -227,6 +228,12 @@ struct page_data_Tag {
     xref *first_xref;
     xref *last_xref;
     /*
+     * Rectangles to be drawn. (These are currently only used for
+     * underlining chapter titles and drawing horizontal rules.)
+     */
+    rect *first_rect;
+    rect *last_rect;
+    /*
      * This spare pointer field is for use by the client backends.
      */
     void *spare;
@@ -252,6 +259,11 @@ struct xref_Tag {
     xref_dest dest;
 };
 
+struct rect_Tag {
+    rect *next;
+    int x, y, w, h;
+};
+
 /*
  * Functions and data exported from psdata.c.
  */