#include "mupdf/html.h"
static const char *font_names[16] =
{
"Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic",
"Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique",
"Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique",
"Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique",
};
static fz_font *
fz_load_html_fallback_font(fz_context *ctx, fz_html_font_set *set)
{
fz_font *font;
/* TODO: Use set->fallback[script] instead of font->fallback chain */
if (!set->fallback)
{
unsigned char *data;
unsigned int size;
int script;
data = fz_lookup_noto_symbol_font(ctx, &size);
if (data)
{
font = fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
font->fallback = set->fallback;
set->fallback = font;
}
for (script = UCDN_SCRIPT_LATIN; script < UCDN_SCRIPT_SIGNWRITING; ++script)
{
data = fz_lookup_noto_font(ctx, script, 1, &size);
if (data)
{
font = fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
font->fallback = set->fallback;
set->fallback = font;
}
}
}
return set->fallback;
}
fz_font *
fz_load_html_builtin_font(fz_context *ctx, fz_html_font_set *set, const char *family, int is_bold, int is_italic)
{
int is_mono = !strcmp(family, "monospace");
int is_sans = !strcmp(family, "sans-serif");
int idx = is_mono * 8 + is_sans * 4 + is_bold * 2 + is_italic;
if (!set->fonts[idx])
{
unsigned char *data;
unsigned int size;
data = fz_lookup_base14_font(ctx, font_names[idx], &size);
if (!data)
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load html font: %s", font_names[idx]);
set->fonts[idx] = fz_new_font_from_memory(ctx, font_names[idx], data, size, 0, 1);
set->fonts[idx]->fallback = fz_load_html_fallback_font(ctx, set);
}
return set->fonts[idx];
}
fz_font *
fz_load_html_font(fz_context *ctx, fz_html_font_set *set, const char *family, int is_bold, int is_italic)
{
fz_html_font_face *custom;
for (custom = set->custom; custom; custom = custom->next)
{
if (!strcmp(family, custom->family) &&
is_bold == custom->is_bold &&
is_italic == custom->is_italic)
{
return custom->font;
}
}
if (!strcmp(family, "monospace") ||
!strcmp(family, "sans-serif") ||
!strcmp(family, "serif"))
return fz_load_html_builtin_font(ctx, set, family, is_bold, is_italic);
return NULL;
}
void
fz_add_html_font_face(fz_context *ctx, fz_html_font_set *set,
const char *family, int is_bold, int is_italic, const char *src,
fz_font *font)
{
fz_html_font_face *custom;
custom = fz_malloc_struct(ctx, fz_html_font_face);
custom->font = fz_keep_font(ctx, font);
custom->src = fz_strdup(ctx, src);
custom->family = fz_strdup(ctx, family);
custom->is_bold = is_bold;
custom->is_italic = is_italic;
custom->next = set->custom;
set->custom = custom;
font->fallback = fz_load_html_builtin_font(ctx, set, family, is_bold, is_italic);
}
fz_html_font_set *fz_new_html_font_set(fz_context *ctx)
{
return fz_malloc_struct(ctx, fz_html_font_set);
}
void fz_drop_html_font_set(fz_context *ctx, fz_html_font_set *set)
{
fz_html_font_face *font, *next;
int i;
font = set->custom;
while (font)
{
next = font->next;
fz_drop_font(ctx, font->font);
fz_free(ctx, font->src);
fz_free(ctx, font->family);
fz_free(ctx, font);
font = next;
}
for (i = 0; i < nelem(set->fonts); ++i)
fz_drop_font(ctx, set->fonts[i]);
fz_drop_font(ctx, set->fallback);
fz_free(ctx, set);
}