From 23765aebbaa2e3d34cd96c904b9a7aae00a57905 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 13 Apr 2004 20:03:39 +0000 Subject: [PATCH] Implemented lines under chapter titles. git-svn-id: svn://svn.tartarus.org/sgt/halibut@4065 cda61777-01e9-0310-a592-d414129be87e --- bk_paper.c | 46 ++++++++++++++++++++++++++++++++++++++++------ bk_pdf.c | 11 +++++++++++ bk_ps.c | 10 +++++++++- paper.h | 12 ++++++++++++ 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/bk_paper.c b/bk_paper.c index 417edf8..5221434 100644 --- a/bk_paper.c +++ b/bk_paper.c @@ -12,10 +12,7 @@ /* * 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; diff --git a/bk_pdf.c b/bk_pdf.c index 44a9699..14db265 100644 --- 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 --- 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 --- 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. */ -- 2.11.0