/*
* Defaults.
*/
- ret.paper_width = 595 * 4096;
- ret.paper_height = 841 * 4096;
- ret.left_margin = 72 * 4096;
- ret.top_margin = 72 * 4096;
- ret.right_margin = 72 * 4096;
- ret.bottom_margin = 108 * 4096;
- ret.indent_list_bullet = 6 * 4096;
- ret.indent_list_after = 18 * 4096;
- ret.indent_quote = 18 * 4096;
- ret.base_leading = 4096;
- ret.base_para_spacing = 10 * 4096;
- ret.chapter_top_space = 72 * 4096;
- ret.sect_num_left_space = 12 * 4096;
- ret.chapter_underline_depth = 14 * 4096;
- ret.chapter_underline_thickness = 3 * 4096;
- ret.rule_thickness = 1 * 4096;
+ ret.paper_width = 595 * UNITS_PER_PT;
+ ret.paper_height = 841 * UNITS_PER_PT;
+ ret.left_margin = 72 * UNITS_PER_PT;
+ ret.top_margin = 72 * UNITS_PER_PT;
+ ret.right_margin = 72 * UNITS_PER_PT;
+ ret.bottom_margin = 108 * UNITS_PER_PT;
+ ret.indent_list_bullet = 6 * UNITS_PER_PT;
+ ret.indent_list_after = 18 * UNITS_PER_PT;
+ ret.indent_quote = 18 * UNITS_PER_PT;
+ ret.base_leading = UNITS_PER_PT;
+ ret.base_para_spacing = 10 * UNITS_PER_PT;
+ ret.chapter_top_space = 72 * UNITS_PER_PT;
+ ret.sect_num_left_space = 12 * UNITS_PER_PT;
+ 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.contents_indent_step = 24 * 4096;
- ret.contents_margin = 84 * 4096;
- ret.leader_separation = 12 * 4096;
- ret.index_gutter = 36 * 4096;
+ ret.contents_indent_step = 24 * UNITS_PER_PT;
+ ret.contents_margin = 84 * UNITS_PER_PT;
+ ret.leader_separation = 12 * UNITS_PER_PT;
+ ret.index_gutter = 36 * UNITS_PER_PT;
ret.index_cols = 2;
- ret.index_minsep = 18 * 4096;
+ ret.index_minsep = 18 * UNITS_PER_PT;
ret.pagenum_fontsize = 12;
- ret.footer_distance = 32 * 4096;
+ ret.footer_distance = 32 * UNITS_PER_PT;
ret.lquote = L"\x2018\0\x2019\0'\0'\0\0";
ret.rquote = uadv(ret.lquote);
ret.bullet = L"\x2022\0-\0\0";
ret.bullet = uadv(p->keyword);
} else if (!ustricmp(p->keyword, L"paper-page-width")) {
ret.paper_width =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-page-height")) {
ret.paper_height =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-left-margin")) {
ret.left_margin =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-top-margin")) {
ret.top_margin =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-right-margin")) {
ret.right_margin =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-bottom-margin")) {
ret.bottom_margin =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-list-indent")) {
ret.indent_list_bullet =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-listitem-indent")) {
ret.indent_list =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-quote-indent")) {
ret.indent_quote =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-base-leading")) {
ret.base_leading =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-base-para-spacing")) {
ret.base_para_spacing =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-chapter-top-space")) {
ret.chapter_top_space =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-sect-num-left-space")) {
ret.sect_num_left_space =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-chapter-underline-depth")) {
ret.chapter_underline_depth =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-chapter-underline-thickness")) {
ret.chapter_underline_thickness =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-rule-thickness")) {
ret.rule_thickness =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-contents-indent-step")) {
ret.contents_indent_step =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-contents-margin")) {
ret.contents_margin =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-leader-separation")) {
ret.leader_separation =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-index-gutter")) {
ret.index_gutter =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-index-minsep")) {
ret.index_minsep =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (int) 0.5 + FUNITS_PER_PT * utof(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"paper-footer-distance")) {
ret.footer_distance =
- (int) 0.5 + 4096.0 * utof(uadv(p->keyword));
+ (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));
return fe;
}
+static int kern_cmp(void *a, void *b)
+{
+ kern_pair const *ka = a, *kb = b;
+
+ if (ka->left < kb->left)
+ return -1;
+ if (ka->left > kb->left)
+ return 1;
+ if (ka->right < kb->right)
+ return -1;
+ if (ka->right > kb->right)
+ return 1;
+ return 0;
+}
+
static font_data *make_std_font(font_list *fontlist, char const *name)
{
const int *widths;
+ const kern_pair *kerns;
int nglyphs;
font_data *f;
font_encoding *fe;
int i;
+ /* XXXKERN */
widths = ps_std_font_widths(name);
- if (!widths)
+ kerns = ps_std_font_kerns(name);
+ if (!widths || !kerns)
return NULL;
for (nglyphs = 0; ps_std_glyphs[nglyphs] != NULL; nglyphs++);
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->subfont_map = snewn(nglyphs, subfont_map_entry);
/*
return f;
}
+/* NB: arguments are glyph numbers from font->bmp. */
+static int find_kern(font_data *font, int lindex, int rindex)
+{
+ kern_pair wantkp;
+ kern_pair const *kp;
+
+ if (lindex == 0xFFFF || rindex == 0xFFFF)
+ return 0;
+ wantkp.left = lindex;
+ wantkp.right = rindex;
+ kp = find234(font->kerns, &wantkp, NULL);
+ if (kp == NULL)
+ return 0;
+ return kp->kern;
+}
+
static int string_width(font_data *font, wchar_t const *string, int *errs)
{
int width = 0;
+ int index, oindex;
if (errs)
*errs = 0;
+ oindex = 0xFFFF;
for (; *string; string++) {
- int index;
+ index = (*string < 0 || *string > 0xFFFF ? 0xFFFF :
+ font->bmp[*string]);
- index = font->bmp[(unsigned short)*string];
if (index == 0xFFFF) {
if (errs)
*errs = 1;
} else {
- width += font->widths[index];
+ width += find_kern(font, oindex, index) + font->widths[index];
}
+ oindex = index;
}
return width;
for (i = 0; i < NFONTS; i++)
if (line_height < pdata->sizes[i])
line_height = pdata->sizes[i];
- line_height *= 4096;
+ line_height *= UNITS_PER_PT;
}
spacewidth = (pdata->sizes[FONT_NORMAL] *
* comes up, but I'll make a random guess anyway and set my
* space width to half the point size.
*/
- spacewidth = pdata->sizes[FONT_NORMAL] * 4096 / 2;
+ spacewidth = pdata->sizes[FONT_NORMAL] * UNITS_PER_PT / 2;
}
/*
*/
if (m != last && m->next && !m->next->page_break)
{
- int x = this_height - minheight;
+ int x = (this_height - minheight) / FUNITS_PER_PT *
+ 4096.0;
int xf;
xf = x & 0xFF;
int x, int y, wchar_t *str)
{
char *text;
- int textpos, textwid, glyph;
+ int textpos, textwid, kern, glyph, oglyph;
font_encoding *subfont = NULL, *sf;
text = snewn(1 + ustrlen(str), char);
textpos = textwid = 0;
+ glyph = 0xFFFF;
while (*str) {
- glyph = font->bmp[*str];
+ oglyph = glyph;
+ glyph = (*str < 0 || *str > 0xFFFF ? 0xFFFF :
+ font->bmp[*str]);
if (glyph == 0xFFFF) {
str++;
sf = font->latest_subfont;
}
- if (!subfont || sf != subfont) {
+ kern = find_kern(font, oglyph, glyph) * fontsize;
+
+ if (!subfont || sf != subfont || kern) {
if (subfont) {
text[textpos] = '\0';
add_string_to_page(page, x, y, subfont, fontsize, text,
textwid);
- x += textwid;
+ x += textwid + kern;
} else {
assert(textpos == 0);
}
textpos = 0;
+ textwid = 0;
subfont = sf;
}
ldata->pdata = pdata;
ldata->first = lhead;
ldata->end = NULL;
- ldata->line_height = conf->base_font_size * 4096;
+ ldata->line_height = conf->base_font_size * UNITS_PER_PT;
ldata->xpos = indent;