X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/c419cb975a375cc3cd6d1407cda546dea9154bce..7b980ef7943673ea4c34a1ed889a66b2822e70b3:/bk_paper.c diff --git a/bk_paper.c b/bk_paper.c index dd90256..dff6dc4 100644 --- a/bk_paper.c +++ b/bk_paper.c @@ -78,6 +78,7 @@ #include #include #include +#include #include "halibut.h" #include "paper.h" @@ -119,6 +120,7 @@ struct paper_conf_Tag { int pagenum_fontsize; int footer_distance; wchar_t *lquote, *rquote, *bullet; + wchar_t *contents_text, *index_text; /* These are derived from the above */ int base_width; int page_height; @@ -221,7 +223,7 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) { * Defaults. */ ret.paper_width = 595 * UNITS_PER_PT; - ret.paper_height = 841 * UNITS_PER_PT; + ret.paper_height = 842 * UNITS_PER_PT; ret.left_margin = 72 * UNITS_PER_PT; ret.top_margin = 72 * UNITS_PER_PT; ret.right_margin = 72 * UNITS_PER_PT; @@ -282,6 +284,8 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) { ret.lquote = L"\x2018\0\x2019\0'\0'\0\0"; ret.rquote = uadv(ret.lquote); ret.bullet = L"\x2022\0-\0\0"; + ret.contents_text = L"Contents"; + ret.index_text = L"Index"; /* * Two-pass configuration so that we can pick up global config @@ -308,6 +312,10 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) { ret.lquote = uadv(p->keyword); ret.rquote = uadv(ret.lquote); } + } else if (!ustricmp(p->keyword, L"contents")) { + ret.contents_text = uadv(p->keyword); + } else if (!ustricmp(p->keyword, L"index")) { + ret.index_text = uadv(p->keyword); } else if (!ustricmp(p->keyword, L"paper-bullet")) { ret.bullet = uadv(p->keyword); } else if (!ustricmp(p->keyword, L"paper-page-width")) { @@ -396,9 +404,9 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) { 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)); + ret.fchapter.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), + paper_cfg_fonts(ret.fchapter.fonts, fontlist, uadv(p->keyword), &p->fpos); } else if (!ustricmp(p->keyword, L"paper-section-font-size")) { wchar_t *q = uadv(p->keyword); @@ -458,29 +466,31 @@ static paper_conf paper_configure(paragraph *source, font_list *fontlist) { * but must be in the title and body fonts. */ 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)) + 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)) { + 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; + if (n == ret.nfsect) break; + } ret.lquote = uadv(ret.rquote); ret.rquote = uadv(ret.lquote); } @@ -510,6 +520,7 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords, paragraph index_placeholder_para; page_data *first_index_page; + init_std_fonts(); fontlist = snew(font_list); fontlist->head = fontlist->tail = NULL; @@ -543,7 +554,7 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords, */ { word *contents_title; - contents_title = fake_word(L"Contents"); + contents_title = fake_word(conf->contents_text); firstcont = make_para_data(para_UnnumberedChapter, 0, 0, 0, NULL, NULL, contents_title, conf); @@ -611,7 +622,8 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords, if (has_index) { pdata = make_para_data(para_Normal, 0, 0, conf->contents_margin, - NULL, NULL, fake_word(L"Index"), conf); + NULL, NULL, + fake_word(conf->index_text), conf); pdata->next = NULL; pdata->contents_entry = &index_placeholder_para; lastcont->next = pdata; @@ -831,7 +843,7 @@ void *paper_pre_backend(paragraph *sourceform, keywordlist *keywords, /* * Create a set of paragraphs for the index. */ - index_title = fake_word(L"Index"); + index_title = fake_word(conf->index_text); firstidx = make_para_data(para_UnnumberedChapter, 0, 0, 0, NULL, NULL, index_title, conf); @@ -1347,7 +1359,7 @@ static font_encoding *new_font_encoding(font_data *font) return fe; } -static int kern_cmp(void *a, void *b) +int kern_cmp(void *a, void *b) { kern_pair const *ka = a, *kb = b; @@ -1362,33 +1374,68 @@ static int kern_cmp(void *a, void *b) return 0; } +/* This wouldn't be necessary if C had closures. */ +static font_info *glyph_cmp_fi; + +static int glyph_cmp(void const *a, void const *b) +{ + return strcmp(glyph_cmp_fi->glyphs[*(unsigned short *)a], + glyph_cmp_fi->glyphs[*(unsigned short *)b]); +} + +/* + * Set up the glyphsbyname index for a font. + */ +void font_index_glyphs(font_info *fi) { + int i; + + fi->glyphsbyname = snewn(fi->nglyphs, unsigned short); + for (i = 0; i < fi->nglyphs; i++) + fi->glyphsbyname[i] = i; + glyph_cmp_fi = fi; + qsort(fi->glyphsbyname, fi->nglyphs, sizeof(fi->glyphsbyname[0]), + glyph_cmp); +} + +int find_glyph(font_info *fi, char const *name) { + int i, j, k, r; + + i = -1; + j = fi->nglyphs; + while (j-i > 1) { + k = (i + j) / 2; + r = strcmp(fi->glyphs[fi->glyphsbyname[k]], name); + if (r == 0) + return fi->glyphsbyname[k]; + else if (r > 0) + j = k; + else + i = k; + } + return -1; +} + static font_data *make_std_font(font_list *fontlist, char const *name) { - const int *widths; - const kern_pair *kerns; int nglyphs; + font_info const *fi; font_data *f; font_encoding *fe; int i; - /* XXXKERN */ - widths = ps_std_font_widths(name); - kerns = ps_std_font_kerns(name); - if (!widths || !kerns) - return NULL; + for (fe = fontlist->head; fe; fe = fe->next) + if (strcmp(fe->font->info->name, name) == 0) + return fe->font; - for (nglyphs = 0; ps_std_glyphs[nglyphs] != NULL; nglyphs++); + for (fi = all_fonts; fi; fi = fi->next) + if (strcmp(fi->name, name) == 0) break; + if (!fi) return NULL; f = snew(font_data); f->list = fontlist; - f->name = name; - f->nglyphs = nglyphs; - f->glyphs = ps_std_glyphs; - f->widths = widths; - f->kerns = newtree234(kern_cmp); - for (;kerns->left != 0xFFFF; kerns++) - add234(f->kerns, (void *)kerns); + f->info = fi; + nglyphs = f->info->nglyphs; f->subfont_map = snewn(nglyphs, subfont_map_entry); /* @@ -1402,16 +1449,11 @@ static font_data *make_std_font(font_list *fontlist, char const *name) fe->free_pos = 0xA1; /* only the top half is free */ f->latest_subfont = fe; - for (i = 0; i < (int)lenof(f->bmp); i++) - f->bmp[i] = 0xFFFF; - for (i = 0; i < nglyphs; i++) { wchar_t ucs; - ucs = ps_glyph_to_unicode(f->glyphs[i]); - assert(ucs != 0xFFFF); - f->bmp[ucs] = i; + ucs = ps_glyph_to_unicode(f->info->glyphs[i]); if (ucs >= 0x20 && ucs <= 0x7E) { - fe->vector[ucs] = f->glyphs[i]; + fe->vector[ucs] = f->info->glyphs[i]; fe->indices[ucs] = i; fe->to_unicode[ucs] = ucs; f->subfont_map[i].subfont = fe; @@ -1438,7 +1480,7 @@ static int find_kern(font_data *font, int lindex, int rindex) return 0; wantkp.left = lindex; wantkp.right = rindex; - kp = find234(font->kerns, &wantkp, NULL); + kp = find234(font->info->kerns, &wantkp, NULL); if (kp == NULL) return 0; return kp->kern; @@ -1455,13 +1497,14 @@ static int string_width(font_data *font, wchar_t const *string, int *errs) oindex = 0xFFFF; for (; *string; string++) { index = (*string < 0 || *string > 0xFFFF ? 0xFFFF : - font->bmp[*string]); + font->info->bmp[*string]); if (index == 0xFFFF) { if (errs) *errs = 1; } else { - width += find_kern(font, oindex, index) + font->widths[index]; + width += find_kern(font, oindex, index) + + font->info->widths[index]; } oindex = index; } @@ -1909,7 +1952,7 @@ static int render_string(page_data *page, font_data *font, int fontsize, while (*str) { oglyph = glyph; glyph = (*str < 0 || *str > 0xFFFF ? 0xFFFF : - font->bmp[*str]); + font->info->bmp[*str]); if (glyph == 0xFFFF) { str++; @@ -1936,7 +1979,7 @@ static int render_string(page_data *page, font_data *font, int fontsize, font->subfont_map[glyph].subfont = font->latest_subfont; font->subfont_map[glyph].position = c; - font->latest_subfont->vector[c] = font->glyphs[glyph]; + font->latest_subfont->vector[c] = font->info->glyphs[glyph]; font->latest_subfont->indices[c] = glyph; font->latest_subfont->to_unicode[c] = *str; @@ -1960,7 +2003,7 @@ static int render_string(page_data *page, font_data *font, int fontsize, } text[textpos++] = font->subfont_map[glyph].position; - textwid += font->widths[glyph] * fontsize; + textwid += font->info->widths[glyph] * fontsize; str++; }