static void generate_image(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_html *box, const char *src) { fz_image *img; fz_buffer *buf; char path[2048]; fz_html *flow = box; while (flow->type != BOX_FLOW) flow = flow->up; fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, src, sizeof path); fz_cleanname(path); fz_try(ctx) { buf = fz_read_archive_entry(ctx, zip, path); img = fz_new_image_from_buffer(ctx, buf); fz_drop_buffer(ctx, buf); add_flow_image(ctx, flow, &box->style, img); } fz_catch(ctx) { const char *alt = "[image]"; fz_warn(ctx, "html: cannot add image src='%s'", src); add_flow_word(ctx, flow, &box->style, alt, alt + 7); } }
static fz_outline * epub_parse_ncx_imp(fz_context *ctx, epub_document *doc, fz_xml *node, char *base_uri) { char path[2048]; fz_outline *outline, *head, **tailp; head = NULL; tailp = &head; node = fz_xml_find_down(node, "navPoint"); while (node) { char *text = fz_xml_text(fz_xml_down(fz_xml_find_down(fz_xml_find_down(node, "navLabel"), "text"))); char *content = fz_xml_att(fz_xml_find_down(node, "content"), "src"); if (text && content) { fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, content, sizeof path); fz_urldecode(path); fz_cleanname(path); *tailp = outline = fz_new_outline(ctx); tailp = &(*tailp)->next; outline->title = fz_strdup(ctx, text); outline->uri = fz_strdup(ctx, path); outline->page = -1; outline->down = epub_parse_ncx_imp(ctx, doc, node, base_uri); } node = fz_xml_find_next(node, "navPoint"); } return head; }
static const char * path_from_idref(char *path, fz_xml *manifest, const char *base_uri, const char *idref, int n) { const char *rel_path = rel_path_from_idref(manifest, idref); if (!rel_path) { path[0] = 0; return NULL; } fz_strlcpy(path, base_uri, n); fz_strlcat(path, "/", n); fz_strlcat(path, rel_path, n); return fz_cleanname(fz_urldecode(path)); }
static fz_css_rule * html_load_css(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_css_rule *css, fz_xml *root) { fz_xml *node; fz_buffer *buf; char path[2048]; for (node = root; node; node = fz_xml_next(node)) { const char *tag = fz_xml_tag(node); if (tag && !strcmp(tag, "link")) { char *rel = fz_xml_att(node, "rel"); if (rel && !fz_strcasecmp(rel, "stylesheet")) { char *type = fz_xml_att(node, "type"); if ((type && !strcmp(type, "text/css")) || !type) { char *href = fz_xml_att(node, "href"); if (href) { fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, href, sizeof path); fz_cleanname(path); buf = fz_read_archive_entry(ctx, zip, path); fz_write_buffer_byte(ctx, buf, 0); css = fz_parse_css(ctx, css, (char*)buf->data, path); fz_drop_buffer(ctx, buf); } } } } if (tag && !strcmp(tag, "style")) { char *s = concat_text(ctx, node); css = fz_parse_css(ctx, css, s, "<style>"); fz_free(ctx, s); } if (fz_xml_down(node)) css = html_load_css(ctx, zip, base_uri, css, fz_xml_down(node)); } return css; }
static fz_css_rule * html_load_css(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_css_rule *css, fz_xml *root) { fz_xml *html, *head, *node; fz_buffer *buf; char path[2048]; fz_var(buf); html = fz_xml_find(root, "html"); head = fz_xml_find_down(html, "head"); for (node = fz_xml_down(head); node; node = fz_xml_next(node)) { if (fz_xml_is_tag(node, "link")) { char *rel = fz_xml_att(node, "rel"); if (rel && !fz_strcasecmp(rel, "stylesheet")) { char *type = fz_xml_att(node, "type"); if ((type && !strcmp(type, "text/css")) || !type) { char *href = fz_xml_att(node, "href"); if (href) { fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, href, sizeof path); fz_urldecode(path); fz_cleanname(path); buf = NULL; fz_try(ctx) { buf = fz_read_archive_entry(ctx, zip, path); fz_write_buffer_byte(ctx, buf, 0); css = fz_parse_css(ctx, css, (char*)buf->data, path); } fz_always(ctx) fz_drop_buffer(ctx, buf); fz_catch(ctx) fz_warn(ctx, "ignoring stylesheet %s", path); } } }
void ui_init_save_file(const char *path, int (*filter)(const char *fn)) { char dir[PATH_MAX], *p; fc.filter = filter; fz_strlcpy(dir, path, sizeof dir); for (p=dir; *p; ++p) if (*p == '\\') *p = '/'; fz_cleanname(dir); p = strrchr(dir, '/'); if (p) { *p = 0; load_dir(dir); ui_input_init(&fc.input_file, p+1); } else { load_dir("."); ui_input_init(&fc.input_file, dir); } }
void fz_add_css_font_face(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const char *base_uri, fz_css_property *declaration) { fz_html_font_face *custom; fz_css_property *prop; fz_font *font = NULL; fz_buffer *buf = NULL; int is_bold, is_italic; char path[2048]; const char *family = "serif"; const char *weight = "normal"; const char *style = "normal"; const char *src = NULL; for (prop = declaration; prop; prop = prop->next) { if (!strcmp(prop->name, "font-family")) family = prop->value->data; if (!strcmp(prop->name, "font-weight")) weight = prop->value->data; if (!strcmp(prop->name, "font-style")) style = prop->value->data; if (!strcmp(prop->name, "src")) src = prop->value->data; } if (!src) return; is_bold = is_bold_from_font_weight(weight); is_italic = is_italic_from_font_style(style); fz_strlcpy(path, base_uri, sizeof path); fz_strlcat(path, "/", sizeof path); fz_strlcat(path, src, sizeof path); fz_urldecode(path); fz_cleanname(path); for (custom = set->custom; custom; custom = custom->next) if (!strcmp(custom->src, path) && !strcmp(custom->family, family) && custom->is_bold == is_bold && custom->is_italic == is_italic) return; /* already loaded */ printf("epub: @font-face: family='%s' b=%d i=%d src=%s\n", family, is_bold, is_italic, src); fz_var(buf); fz_var(font); fz_try(ctx) { if (fz_has_archive_entry(ctx, zip, path)) buf = fz_read_archive_entry(ctx, zip, path); else buf = fz_read_file(ctx, src); font = fz_new_font_from_buffer(ctx, src, buf, 0, 0); fz_add_html_font_face(ctx, set, family, is_bold, is_italic, path, font); } fz_always(ctx) { fz_drop_buffer(ctx, buf); fz_drop_font(ctx, font); } fz_catch(ctx) { fz_warn(ctx, "cannot load font-face: %s", src); } }