summaryrefslogtreecommitdiff
path: root/bk_paper.c
diff options
context:
space:
mode:
authorBen Harris <bjh21@bjh21.me.uk>2006-05-08 22:54:19 +0000
committerBen Harris <bjh21@bjh21.me.uk>2006-05-08 22:54:19 +0000
commit7e9483d0ffc2a400507c250df50dcf5ad3ef0cf8 (patch)
tree0fd99558a65ea26aec74e52337c92f20815a4e6b /bk_paper.c
parentb42099295f41ebbc172facd0757bcc255070b7c1 (diff)
downloadhalibut-7e9483d0ffc2a400507c250df50dcf5ad3ef0cf8.zip
halibut-7e9483d0ffc2a400507c250df50dcf5ad3ef0cf8.tar.gz
halibut-7e9483d0ffc2a400507c250df50dcf5ad3ef0cf8.tar.bz2
halibut-7e9483d0ffc2a400507c250df50dcf5ad3ef0cf8.tar.xz
Add font-selection mechanism to the paper backend. Since we have no way to
load font metrics dynamically, we're restricted to the fonts whose metrics are compiled into Halibut. Font structures aren't reused when the same font is specified twice, nor are unused fonts removed from the output. Finally, the default configuration overflows lines in the manual, but this would need a change to Halibut's grammar to fix. Still, what's there works. [originally from svn r6667]
Diffstat (limited to 'bk_paper.c')
-rw-r--r--bk_paper.c220
1 files changed, 157 insertions, 63 deletions
diff --git a/bk_paper.c b/bk_paper.c
index aed648c..dd90256 100644
--- a/bk_paper.c
+++ b/bk_paper.c
@@ -85,6 +85,11 @@
typedef struct paper_conf_Tag paper_conf;
typedef struct paper_idx_Tag paper_idx;
+typedef struct {
+ font_data *fonts[NFONTS];
+ int font_size;
+} font_cfg;
+
struct paper_conf_Tag {
int paper_width;
int paper_height;
@@ -103,7 +108,8 @@ struct paper_conf_Tag {
int chapter_underline_depth;
int chapter_underline_thickness;
int rule_thickness;
- int base_font_size;
+ font_cfg fbase, fcode, ftitle, fchapter, *fsect;
+ int nfsect;
int contents_indent_step;
int contents_margin;
int leader_separation;
@@ -117,8 +123,6 @@ struct paper_conf_Tag {
int base_width;
int page_height;
int index_colwidth;
- /* Fonts used in the configuration */
- font_data *tr, *ti, *hr, *hi, *cr, *co, *cb;
};
struct paper_idx_Tag {
@@ -192,6 +196,23 @@ static int fonts_ok(wchar_t *string, ...)
return ret;
}
+static void paper_cfg_fonts(font_data **fonts, font_list *fontlist,
+ wchar_t *wp, filepos *fpos) {
+ font_data *f;
+ char *fn;
+ int i;
+
+ for (i = 0; i < NFONTS && *wp; i++, wp = uadv(wp)) {
+ fn = utoa_dup(wp, CS_ASCII);
+ f = make_std_font(fontlist, fn);
+ if (f)
+ fonts[i] = f;
+ else
+ /* FIXME: proper error */
+ error(err_nofont, fpos, wp);
+ }
+}
+
static paper_conf paper_configure(paragraph *source, font_list *fontlist) {
paragraph *p;
paper_conf ret;
@@ -215,7 +236,41 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) {
ret.chapter_underline_depth = 14 * UNITS_PER_PT;
ret.chapter_underline_thickness = 3 * UNITS_PER_PT;
ret.rule_thickness = 1 * UNITS_PER_PT;
- ret.base_font_size = 12;
+ ret.fbase.font_size = 12;
+ ret.fbase.fonts[FONT_NORMAL] = make_std_font(fontlist, "Times-Roman");
+ ret.fbase.fonts[FONT_EMPH] = make_std_font(fontlist, "Times-Italic");
+ ret.fbase.fonts[FONT_CODE] = make_std_font(fontlist, "Courier");
+ ret.fcode.font_size = 12;
+ ret.fcode.fonts[FONT_NORMAL] = make_std_font(fontlist, "Courier-Bold");
+ ret.fcode.fonts[FONT_EMPH] = make_std_font(fontlist, "Courier-Oblique");
+ ret.fcode.fonts[FONT_CODE] = make_std_font(fontlist, "Courier");
+ ret.ftitle.font_size = 24;
+ ret.ftitle.fonts[FONT_NORMAL] = make_std_font(fontlist, "Helvetica-Bold");
+ ret.ftitle.fonts[FONT_EMPH] =
+ make_std_font(fontlist, "Helvetica-BoldOblique");
+ ret.ftitle.fonts[FONT_CODE] = make_std_font(fontlist, "Courier-Bold");
+ ret.fchapter.font_size = 20;
+ ret.fchapter.fonts[FONT_NORMAL]= make_std_font(fontlist, "Helvetica-Bold");
+ ret.fchapter.fonts[FONT_EMPH] =
+ make_std_font(fontlist, "Helvetica-BoldOblique");
+ ret.fchapter.fonts[FONT_CODE] = make_std_font(fontlist, "Courier-Bold");
+ ret.nfsect = 3;
+ ret.fsect = snewn(ret.nfsect, font_cfg);
+ ret.fsect[0].font_size = 16;
+ ret.fsect[0].fonts[FONT_NORMAL]= make_std_font(fontlist, "Helvetica-Bold");
+ ret.fsect[0].fonts[FONT_EMPH] =
+ make_std_font(fontlist, "Helvetica-BoldOblique");
+ ret.fsect[0].fonts[FONT_CODE] = make_std_font(fontlist, "Courier-Bold");
+ ret.fsect[1].font_size = 14;
+ ret.fsect[1].fonts[FONT_NORMAL]= make_std_font(fontlist, "Helvetica-Bold");
+ ret.fsect[1].fonts[FONT_EMPH] =
+ make_std_font(fontlist, "Helvetica-BoldOblique");
+ ret.fsect[1].fonts[FONT_CODE] = make_std_font(fontlist, "Courier-Bold");
+ ret.fsect[2].font_size = 13;
+ ret.fsect[2].fonts[FONT_NORMAL]= make_std_font(fontlist, "Helvetica-Bold");
+ ret.fsect[2].fonts[FONT_EMPH] =
+ make_std_font(fontlist, "Helvetica-BoldOblique");
+ ret.fsect[2].fonts[FONT_CODE] = make_std_font(fontlist, "Courier-Bold");
ret.contents_indent_step = 24 * UNITS_PER_PT;
ret.contents_margin = 84 * UNITS_PER_PT;
ret.leader_separation = 12 * UNITS_PER_PT;
@@ -322,15 +377,60 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) {
ret.footer_distance =
(int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-base-font-size")) {
- ret.base_font_size =
- utoi(uadv(p->keyword));
+ ret.fbase.font_size = utoi(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-index-columns")) {
- ret.index_cols =
- utoi(uadv(p->keyword));
+ ret.index_cols = utoi(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-pagenum-font-size")) {
- ret.pagenum_fontsize =
- utoi(uadv(p->keyword));
- }
+ ret.pagenum_fontsize = utoi(uadv(p->keyword));
+ } else if (!ustricmp(p->keyword, L"paper-base-fonts")) {
+ paper_cfg_fonts(ret.fbase.fonts, fontlist, uadv(p->keyword),
+ &p->fpos);
+ } else if (!ustricmp(p->keyword, L"paper-code-font-size")) {
+ ret.fcode.font_size = utoi(uadv(p->keyword));
+ } else if (!ustricmp(p->keyword, L"paper-code-fonts")) {
+ paper_cfg_fonts(ret.fcode.fonts, fontlist, uadv(p->keyword),
+ &p->fpos);
+ } else if (!ustricmp(p->keyword, L"paper-title-font-size")) {
+ ret.ftitle.font_size = utoi(uadv(p->keyword));
+ } else if (!ustricmp(p->keyword, L"paper-title-fonts")) {
+ paper_cfg_fonts(ret.ftitle.fonts, fontlist, uadv(p->keyword),
+ &p->fpos);
+ } else if (!ustricmp(p->keyword, L"paper-chapter-font-size")) {
+ ret.ftitle.font_size = utoi(uadv(p->keyword));
+ } else if (!ustricmp(p->keyword, L"paper-chapter-fonts")) {
+ paper_cfg_fonts(ret.ftitle.fonts, fontlist, uadv(p->keyword),
+ &p->fpos);
+ } else if (!ustricmp(p->keyword, L"paper-section-font-size")) {
+ wchar_t *q = uadv(p->keyword);
+ int n = 0;
+ if (uisdigit(*q)) {
+ n = utoi(q);
+ q = uadv(q);
+ }
+ if (n >= ret.nfsect) {
+ int i;
+ ret.fsect = sresize(ret.fsect, n+1, font_cfg);
+ for (i = ret.nfsect; i <= n; i++)
+ ret.fsect[i] = ret.fsect[ret.nfsect-1];
+ ret.nfsect = n+1;
+ }
+ ret.fsect[n].font_size = utoi(q);
+ } else if (!ustricmp(p->keyword, L"paper-section-fonts")) {
+ wchar_t *q = uadv(p->keyword);
+ int n = 0;
+ if (uisdigit(*q)) {
+ n = utoi(q);
+ q = uadv(q);
+ }
+ if (n >= ret.nfsect) {
+ int i;
+ ret.fsect = sresize(ret.fsect, n+1, font_cfg);
+ for (i = ret.nfsect; i <= n; i++)
+ ret.fsect[i] = ret.fsect[ret.nfsect-1];
+ ret.nfsect = n+1;
+ }
+ paper_cfg_fonts(ret.fsect[n].fonts, fontlist, q, &p->fpos);
+ }
}
}
@@ -348,17 +448,6 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) {
/ ret.index_cols;
/*
- * Set up the font structures.
- */
- ret.tr = make_std_font(fontlist, "Times-Roman");
- ret.ti = make_std_font(fontlist, "Times-Italic");
- ret.hr = make_std_font(fontlist, "Helvetica-Bold");
- ret.hi = make_std_font(fontlist, "Helvetica-BoldOblique");
- ret.cr = make_std_font(fontlist, "Courier");
- ret.co = make_std_font(fontlist, "Courier-Oblique");
- ret.cb = make_std_font(fontlist, "Courier-Bold");
-
- /*
* Now process fallbacks on quote characters and bullets. We
* use string_width() to determine whether all of the relevant
* fonts contain the same character, and fall back whenever we
@@ -367,9 +456,31 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) {
/* Quote characters need not be supported in the fixed code fonts,
* but must be in the title and body fonts. */
- while (*uadv(ret.rquote) && *uadv(uadv(ret.rquote)) &&
- (!fonts_ok(ret.lquote, ret.tr, ret.ti, ret.hr, ret.hi, NULL) ||
- !fonts_ok(ret.rquote, ret.tr, ret.ti, ret.hr, ret.hi, NULL))) {
+ while (*uadv(ret.rquote) && *uadv(uadv(ret.rquote))) {
+ int n;
+ if (!fonts_ok(ret.lquote,
+ ret.fbase.fonts[FONT_NORMAL],
+ ret.fbase.fonts[FONT_EMPH],
+ ret.ftitle.fonts[FONT_NORMAL],
+ ret.ftitle.fonts[FONT_EMPH],
+ ret.fchapter.fonts[FONT_NORMAL],
+ ret.fchapter.fonts[FONT_EMPH], NULL) ||
+ !fonts_ok(ret.rquote,
+ ret.fbase.fonts[FONT_NORMAL],
+ ret.fbase.fonts[FONT_EMPH],
+ ret.ftitle.fonts[FONT_NORMAL],
+ ret.ftitle.fonts[FONT_EMPH],
+ ret.fchapter.fonts[FONT_NORMAL],
+ ret.fchapter.fonts[FONT_EMPH], NULL))
+ break;
+ for (n = 0; n < ret.nfsect; n++)
+ if (!fonts_ok(ret.lquote,
+ ret.fsect[n].fonts[FONT_NORMAL],
+ ret.fsect[n].fonts[FONT_EMPH], NULL) ||
+ !fonts_ok(ret.rquote,
+ ret.fsect[n].fonts[FONT_NORMAL],
+ ret.fsect[n].fonts[FONT_EMPH], NULL))
+ break;
ret.lquote = uadv(ret.rquote);
ret.rquote = uadv(ret.lquote);
}
@@ -377,7 +488,7 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) {
/* The bullet character only needs to be supported in the normal body
* font (not even in italics). */
while (*ret.bullet && *uadv(ret.bullet) &&
- !fonts_ok(ret.bullet, ret.tr, NULL))
+ !fonts_ok(ret.bullet, ret.fbase.fonts[FONT_NORMAL], NULL))
ret.bullet = uadv(ret.bullet);
return ret;
@@ -897,9 +1008,11 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords,
int width;
width = conf->pagenum_fontsize *
- string_width(conf->tr, page->number, NULL);
+ string_width(conf->fbase.fonts[FONT_NORMAL], page->number,
+ NULL);
- render_string(page, conf->tr, conf->pagenum_fontsize,
+ render_string(page, conf->fbase.fonts[FONT_NORMAL],
+ conf->pagenum_fontsize,
conf->left_margin + (conf->base_width - width)/2,
conf->bottom_margin - conf->footer_distance,
page->number);
@@ -958,6 +1071,15 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords,
return doc;
}
+static void setfont(para_data *p, font_cfg *f) {
+ int i;
+
+ for (i = 0; i < NFONTS; i++) {
+ p->fonts[i] = f->fonts[i];
+ p->sizes[i] = f->font_size;
+ }
+}
+
static para_data *make_para_data(int ptype, int paux, int indent, int rmargin,
word *pkwtext, word *pkwtext2, word *pwords,
paper_conf *conf)
@@ -976,42 +1098,24 @@ static para_data *make_para_data(int ptype, int paux, int indent, int rmargin,
/*
* Choose fonts for this paragraph.
- *
- * FIXME: All of this ought to be completely
- * user-configurable.
*/
switch (ptype) {
case para_Title:
- pdata->fonts[FONT_NORMAL] = conf->hr;
- pdata->sizes[FONT_NORMAL] = 24;
- pdata->fonts[FONT_EMPH] = conf->hi;
- pdata->sizes[FONT_EMPH] = 24;
- pdata->fonts[FONT_CODE] = conf->cb;
- pdata->sizes[FONT_CODE] = 24;
+ setfont(pdata, &conf->ftitle);
pdata->outline_level = 0;
break;
case para_Chapter:
case para_Appendix:
case para_UnnumberedChapter:
- pdata->fonts[FONT_NORMAL] = conf->hr;
- pdata->sizes[FONT_NORMAL] = 20;
- pdata->fonts[FONT_EMPH] = conf->hi;
- pdata->sizes[FONT_EMPH] = 20;
- pdata->fonts[FONT_CODE] = conf->cb;
- pdata->sizes[FONT_CODE] = 20;
+ setfont(pdata, &conf->fchapter);
pdata->outline_level = 1;
break;
case para_Heading:
case para_Subsect:
- pdata->fonts[FONT_NORMAL] = conf->hr;
- pdata->fonts[FONT_EMPH] = conf->hi;
- pdata->fonts[FONT_CODE] = conf->cb;
- pdata->sizes[FONT_NORMAL] =
- pdata->sizes[FONT_EMPH] =
- pdata->sizes[FONT_CODE] =
- (paux == 0 ? 16 : paux == 1 ? 14 : 13);
+ setfont(pdata,
+ &conf->fsect[paux >= conf->nfsect ? conf->nfsect - 1 : paux]);
pdata->outline_level = 2 + paux;
break;
@@ -1022,12 +1126,7 @@ static para_data *make_para_data(int ptype, int paux, int indent, int rmargin,
case para_DescribedThing:
case para_Description:
case para_Copyright:
- pdata->fonts[FONT_NORMAL] = conf->tr;
- pdata->sizes[FONT_NORMAL] = 12;
- pdata->fonts[FONT_EMPH] = conf->ti;
- pdata->sizes[FONT_EMPH] = 12;
- pdata->fonts[FONT_CODE] = conf->cr;
- pdata->sizes[FONT_CODE] = 12;
+ setfont(pdata, &conf->fbase);
break;
}
@@ -2278,12 +2377,7 @@ static para_data *code_paragraph(int indent, word *words, paper_conf *conf)
* pretend the three normal fonts are the three code paragraph
* fonts.
*/
- pdata->fonts[FONT_NORMAL] = conf->cb;
- pdata->fonts[FONT_EMPH] = conf->co;
- pdata->fonts[FONT_CODE] = conf->cr;
- pdata->sizes[FONT_NORMAL] =
- pdata->sizes[FONT_EMPH] =
- pdata->sizes[FONT_CODE] = 12;
+ setfont(pdata, &conf->fcode);
pdata->first = pdata->last = NULL;
pdata->outline_level = -1;
@@ -2358,7 +2452,7 @@ static para_data *code_paragraph(int indent, word *words, paper_conf *conf)
ldata->pdata = pdata;
ldata->first = lhead;
ldata->end = NULL;
- ldata->line_height = conf->base_font_size * UNITS_PER_PT;
+ ldata->line_height = conf->fcode.font_size * UNITS_PER_PT;
ldata->xpos = indent;