static fz_font * fz_new_font(fz_context *ctx, char *name, int use_glyph_bbox, int glyph_count) { fz_font *font; int i; font = fz_malloc_struct(ctx, fz_font); font->refs = 1; if (name) fz_strlcpy(font->name, name, sizeof font->name); else fz_strlcpy(font->name, "(null)", sizeof font->name); font->ft_face = NULL; font->ft_substitute = 0; font->ft_bold = 0; font->ft_italic = 0; font->ft_hint = 0; font->ft_file = NULL; font->ft_data = NULL; font->ft_size = 0; font->t3matrix = fz_identity; font->t3resources = NULL; font->t3procs = NULL; font->t3lists = NULL; font->t3widths = NULL; font->t3flags = NULL; font->t3doc = NULL; font->t3run = NULL; font->bbox.x0 = 0; font->bbox.y0 = 0; font->bbox.x1 = 1; font->bbox.y1 = 1; font->use_glyph_bbox = use_glyph_bbox; if (use_glyph_bbox && glyph_count <= MAX_BBOX_TABLE_SIZE) { font->bbox_count = glyph_count; font->bbox_table = fz_malloc_array(ctx, glyph_count, sizeof(fz_rect)); for (i = 0; i < glyph_count; i++) font->bbox_table[i] = fz_infinite_rect; } else { if (use_glyph_bbox) fz_warn(ctx, "not building glyph bbox table for font '%s' with %d glyphs", font->name, glyph_count); font->bbox_count = 0; font->bbox_table = NULL; } font->width_count = 0; font->width_table = NULL; return font; }
static int epub_lookup_metadata(fz_context *ctx, fz_document *doc_, const char *key, char *buf, int size) { epub_document *doc = (epub_document*)doc_; if (!strcmp(key, FZ_META_FORMAT)) return (int)fz_strlcpy(buf, "EPUB", size); if (!strcmp(key, FZ_META_INFO_TITLE) && doc->dc_title) return (int)fz_strlcpy(buf, doc->dc_title, size); if (!strcmp(key, FZ_META_INFO_AUTHOR) && doc->dc_creator) return (int)fz_strlcpy(buf, doc->dc_creator, size); return -1; }
static void format_list_number(fz_context *ctx, int type, int x, char *buf, int size) { switch (type) { case LST_NONE: fz_strlcpy(buf, "", size); break; case LST_DISC: fz_strlcpy(buf, "\342\227\217 ", size); break; /* U+25CF BLACK CIRCLE */ case LST_CIRCLE: fz_strlcpy(buf, "\342\227\213 ", size); break; /* U+25CB WHITE CIRCLE */ case LST_SQUARE: fz_strlcpy(buf, "\342\226\240 ", size); break; /* U+25A0 BLACK SQUARE */ default: case LST_DECIMAL: fz_snprintf(buf, size, "%d. ", x); break; case LST_DECIMAL_ZERO: fz_snprintf(buf, size, "%02d. ", x); break; case LST_LC_ROMAN: format_roman_number(ctx, buf, size, x, roman_lc, "m"); break; case LST_UC_ROMAN: format_roman_number(ctx, buf, size, x, roman_uc, "M"); break; case LST_LC_ALPHA: format_alpha_number(ctx, buf, size, x, 'a', 'z'); break; case LST_UC_ALPHA: format_alpha_number(ctx, buf, size, x, 'A', 'Z'); break; case LST_LC_LATIN: format_alpha_number(ctx, buf, size, x, 'a', 'z'); break; case LST_UC_LATIN: format_alpha_number(ctx, buf, size, x, 'A', 'Z'); break; case LST_LC_GREEK: format_alpha_number(ctx, buf, size, x, 0x03B1, 0x03C9); break; case LST_UC_GREEK: format_alpha_number(ctx, buf, size, x, 0x0391, 0x03A9); break; } }
int htdoc_lookup_metadata(fz_context *ctx, fz_document *doc_, const char *key, char *buf, int size) { if (!strcmp(key, "format")) return fz_strlcpy(buf, "XHTML", size); return -1; }
static int tiff_lookup_metadata(fz_context *ctx, tiff_document *doc, const char *key, char *buf, int size) { if (!strcmp(key, "format")) return (int)fz_strlcpy(buf, "TIFF", size); return -1; }
fz_obj *xps_extract_doc_props(xps_context *ctx) { char path[1024]; xps_part *part; fz_obj *dict; if (xps_find_doc_props_path(ctx, path) != fz_okay) { fz_catch(-1, "couldn't find the exact part name for /docProps/core.xml"); fz_strlcpy(path, "/docProps/core.xml", sizeof(path)); } if (!*path) return NULL; part = xps_read_part(ctx, path); if (!part) { fz_catch(-1, "cannot read zip part '%s'", path); return NULL; } dict = fz_new_dict(8); xps_hacky_get_prop(part->data, dict, "Title", "dc:title"); xps_hacky_get_prop(part->data, dict, "Subject", "dc:subject"); xps_hacky_get_prop(part->data, dict, "Author", "dc:creator"); xps_hacky_get_prop(part->data, dict, "CreationDate", "dcterms:created"); xps_hacky_get_prop(part->data, dict, "ModDate", "dcterms:modified"); xps_free_part(ctx, part); return dict; }
static int xps_find_doc_props_path(xps_context *ctx, char path[1024]) { xml_element *root; int code = xps_open_and_parse(ctx, "/[Content_Types].xml", &root); if (code != fz_okay) return code; *path = '\0'; if (root && !strcmp(xml_tag(root), "Types")) { xml_element *item; for (item = xml_down(root); item; item = xml_next(item)) { if (!strcmp(xml_tag(item), "Override") && xml_att(item, "ContentType") && !strcmp(xml_att(item, "ContentType"), CONTENT_TYPE_CORE_PROPS) && xml_att(item, "PartName")) { fz_strlcpy(path, xml_att(item, "PartName"), 1024); } } } else code = fz_throw("couldn't parse part '[Content_Types].xml'"); xml_free_element(root); return code; }
static void sig_dialog(void) { const char *label = pdf_field_label(ctx, sig_widget->obj); ui_dialog_begin(400, (ui.gridsize+4)*3 + ui.lineheight*10); { ui_layout(T, X, NW, 2, 2); ui_label("%s", label); ui_spacer(); if (sig_result) ui_label("Signature is valid.\n%s", sig_status); else ui_label("Could not verify signature:\n%s", sig_status); ui_layout(B, X, NW, 2, 2); ui_panel_begin(0, ui.gridsize, 0, 0, 0); { ui_layout(R, NONE, S, 0, 0); if (ui_button("Cancel") || (!ui.focus && ui.key == KEY_ESCAPE)) ui.dialog = NULL; ui_spacer(); if (ui_button("Sign")) { fz_strlcpy(cert_filename, filename, sizeof cert_filename); ui_init_open_file(".", cert_file_filter); ui.dialog = cert_file_dialog; } } ui_panel_end(); } ui_dialog_end(); }
void fz_vwarn(fz_context *ctx, const char *fmt, va_list ap) { char buf[sizeof ctx->warn->message]; fz_vsnprintf(buf, sizeof buf, fmt, ap); buf[sizeof(buf) - 1] = 0; #ifdef USE_OUTPUT_DEBUG_STRING OutputDebugStringA(buf); OutputDebugStringA("\n"); #endif #ifdef USE_ANDROID_LOG __android_log_print(ANDROID_LOG_WARN, "libmupdf", "%s", buf); #endif if (!strcmp(buf, ctx->warn->message)) { ctx->warn->count++; } else { fz_flush_warnings(ctx); fprintf(stderr, "warning: %s\n", buf); fz_strlcpy(ctx->warn->message, buf, sizeof ctx->warn->message); ctx->warn->count = 1; } }
void pdfapp_reloadfile(pdfapp_t *app) { char filename[PATH_MAX]; fz_strlcpy(filename, app->docpath, PATH_MAX); pdfapp_close(app); pdfapp_open(app, filename, 1); }
static void xps_load_links_in_fixed_page(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, xps_page *page, fz_link **link) { fz_xml *node, *resource_tag; xps_resource *dict = NULL; char base_uri[1024]; char *s; if (!page->root) return; fz_strlcpy(base_uri, page->fix->name, sizeof base_uri); s = strrchr(base_uri, '/'); if (s) s[1] = 0; resource_tag = fz_xml_down(fz_xml_find_down(page->root, "FixedPage.Resources")); if (resource_tag) dict = xps_parse_resource_dictionary(ctx, doc, base_uri, resource_tag); for (node = fz_xml_down(page->root); node; node = fz_xml_next(node)) xps_load_links_in_element(ctx, doc, ctm, base_uri, dict, node, link); if (dict) xps_drop_resource_dictionary(ctx, doc, dict); }
static fz_document * epub_open_document(fz_context *ctx, const char *filename) { if (strstr(filename, "META-INF/container.xml") || strstr(filename, "META-INF\\container.xml")) { char dirname[2048], *p; fz_strlcpy(dirname, filename, sizeof dirname); p = strstr(dirname, "META-INF"); *p = 0; if (!dirname[0]) fz_strlcpy(dirname, ".", sizeof dirname); return epub_init(ctx, fz_open_directory(ctx, dirname)); } return epub_init(ctx, fz_open_zip_archive(ctx, filename)); }
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 int xps_lookup_metadata(fz_context *ctx, xps_document *doc, const char *key, char *buf, int size) { if (!strcmp(key, "format")) return fz_strlcpy(buf, "XPS", size); return -1; }
static void xps_parse_metadata(fz_context *ctx, xps_document *doc, xps_part *part, xps_fixdoc *fixdoc) { fz_xml *root; char buf[1024]; char *s; /* Save directory name part */ fz_strlcpy(buf, part->name, sizeof buf); s = strrchr(buf, '/'); if (s) s[0] = 0; /* _rels parts are voodoo: their URI references are from * the part they are associated with, not the actual _rels * part being parsed. */ s = strstr(buf, "/_rels"); if (s) *s = 0; doc->base_uri = buf; doc->part_uri = part->name; root = fz_parse_xml(ctx, part->data, part->size, 0); xps_parse_metadata_imp(ctx, doc, root, fixdoc); fz_drop_xml(ctx, root); doc->base_uri = NULL; doc->part_uri = NULL; }
static xps_resource * xps_parse_remote_resource_dictionary(xps_document *doc, char *base_uri, char *source_att) { char part_name[1024]; char part_uri[1024]; xps_resource *dict; xps_part *part; xml_element *xml; char *s; /* External resource dictionaries MUST NOT reference other resource dictionaries */ xps_resolve_url(part_name, base_uri, source_att, sizeof part_name); part = xps_read_part(doc, part_name); xml = xml_parse_document(doc->ctx, part->data, part->size); xps_free_part(doc, part); if (strcmp(xml_tag(xml), "ResourceDictionary")) { xml_free_element(doc->ctx, xml); fz_throw(doc->ctx, "expected ResourceDictionary element (found %s)", xml_tag(xml)); } fz_strlcpy(part_uri, part_name, sizeof part_uri); s = strrchr(part_uri, '/'); if (s) s[1] = 0; dict = xps_parse_resource_dictionary(doc, part_uri, xml); if (dict) dict->base_xml = xml; /* pass on ownership */ return dict; }
static int has_dir(const char *home, const char *user, int i, char dir[PATH_MAX], char vis[PATH_MAX]) { const char *subdir = common_dirs[i].name; int icon = common_dirs[i].icon; if (subdir[0] == '~') { if (!home) return 0; if (subdir[1] == '/') { fz_snprintf(dir, PATH_MAX, "%s/%s", home, subdir+2); fz_snprintf(vis, PATH_MAX, "%C %s", icon, subdir+2); } else { fz_snprintf(dir, PATH_MAX, "%s", home); fz_snprintf(vis, PATH_MAX, "%C %s", icon, user ? user : "******"); } } else { fz_strlcpy(dir, subdir, PATH_MAX); fz_snprintf(vis, PATH_MAX, "%C %s", icon, subdir); } return fz_is_directory(ctx, dir); }
int xps_open_file(fz_context *ctx, xps_context **ctxp, char *filename) { char buf[2048]; fz_stream *file; char *p; int code; if (strstr(filename, "/_rels/.rels") || strstr(filename, "\\_rels\\.rels")) { fz_strlcpy(buf, filename, sizeof buf); p = strstr(buf, "/_rels/.rels"); if (!p) p = strstr(buf, "\\_rels\\.rels"); *p = 0; return xps_open_directory(ctx, ctxp, buf); } file = fz_open_file(ctx, filename); if (!file) return fz_error_make(ctx, "cannot open file '%s': %s", filename, strerror(errno)); code = xps_open_stream(ctxp, file); fz_close(file); if (code) return fz_error_note(ctx, code, "cannot load document '%s'", filename); return fz_okay; }
fz_error pdf_loadbuiltinfont(pdf_fontdesc *fontdesc, char *fontname) { fz_error error; unsigned char *data; unsigned int len; int i; for (i = 0; basefonts[i].name; i++) if (!strcmp(fontname, basefonts[i].name)) goto found; return fz_throw("cannot find font: '%s'", fontname); found: pdf_logfont("load builtin font %s\n", fontname); data = (unsigned char *) basefonts[i].cff; len = *basefonts[i].len; error = fz_newfontfrombuffer(&fontdesc->font, data, len, 0); if (error) return fz_rethrow(error, "cannot load freetype font from buffer"); fz_strlcpy(fontdesc->font->name, fontname, sizeof fontdesc->font->name); if (!strcmp(fontname, "Symbol") || !strcmp(fontname, "ZapfDingbats")) fontdesc->flags |= FD_SYMBOLIC; return fz_okay; }
void fz_warn(fz_context *ctx, const char *fmt, ...) { va_list ap; char buf[sizeof ctx->warn->message]; va_start(ap, fmt); vsnprintf(buf, sizeof buf, fmt, ap); va_end(ap); #ifdef USE_OUTPUT_DEBUG_STRING OutputDebugStringA(buf); OutputDebugStringA("\n"); #endif if (!strcmp(buf, ctx->warn->message)) { ctx->warn->count++; } else { fz_flush_warnings(ctx); fprintf(stderr, "warning: %s\n", buf); LOGE("warning: %s\n", buf); fz_strlcpy(ctx->warn->message, buf, sizeof ctx->warn->message); ctx->warn->count = 1; } }
xps_document * xps_open_document(fz_context *ctx, const char *filename) { char buf[2048]; fz_stream *file; char *p; xps_document *doc; if (strstr(filename, "/_rels/.rels") || strstr(filename, "\\_rels\\.rels")) { fz_strlcpy(buf, filename, sizeof buf); p = strstr(buf, "/_rels/.rels"); if (!p) p = strstr(buf, "\\_rels\\.rels"); *p = 0; return xps_open_document_with_directory(ctx, buf); } file = fz_open_file(ctx, filename); fz_try(ctx) doc = xps_open_document_with_stream(ctx, file); fz_always(ctx) fz_drop_stream(ctx, file); fz_catch(ctx) fz_rethrow_message(ctx, "cannot load document '%s'", filename); return doc; }
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 int cbz_lookup_metadata(fz_context *ctx, fz_document *doc_, const char *key, char *buf, int size) { cbz_document *doc = (cbz_document*)doc_; if (!strcmp(key, "format")) return (int) fz_strlcpy(buf, fz_archive_format(ctx, doc->arch), size); return -1; }
static fz_error insertmapping(fz_context *ctx, pdf_windows_fontlist *fl, char *facename, char *path, int index) { if (fl->len == fl->cap) grow_system_font_list(ctx, fl); if (fl->len >= fl->cap) return fz_error_make(ctx, "fonterror : fontlist overflow"); fz_strlcpy(fl->fontmap[fl->len].fontface, facename, sizeof(fl->fontmap[0].fontface)); fz_strlcpy(fl->fontmap[fl->len].fontpath, path, sizeof(fl->fontmap[0].fontpath)); fl->fontmap[fl->len].index = index; ++fl->len; return fz_okay; }
static void xps_rels_for_part(char *buf, char *name, int bufSize) { char *baseName = xps_get_part_base_name(name); fz_strlcpy(buf, name, MIN(baseName - name + 1, bufSize)); fz_strlcat(buf, "_rels/", bufSize); fz_strlcat(buf, baseName, bufSize); fz_strlcat(buf, ".rels", bufSize); }
void xps_resolve_url(char *output, char *base_uri, char *path, int output_size) { char *p = skip_authority(skip_scheme(path)); if (p != path || path[0] == '/') { fz_strlcpy(output, path, output_size); } else { int len = fz_strlcpy(output, base_uri, output_size); if (len == 0 || output[len-1] != '/') fz_strlcat(output, "/", output_size); fz_strlcat(output, path, output_size); } xps_clean_path(output); }
static void pdf_filter_cs(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs) { pdf_filter_processor *p = (pdf_filter_processor*)proc; filter_gstate *gstate = gstate_to_update(ctx, p); fz_strlcpy(gstate->cs.name, name, sizeof gstate->cs.name); gstate->cs.cs = cs; copy_resource(ctx, p, PDF_NAME_ColorSpace, name); }
static void forward(pdf_csi *csi, pdf_filter_state *state, int op, float *f_argv, int f_argc, char *arg) { int top = csi->top; int to_save = top; float save_f[FZ_MAX_COLORS]; char save_name[sizeof(csi->name)]; int i; /* Store the stack */ if (to_save > f_argc) to_save = 6; for (i = 0; i < to_save; i++) { save_f[i] = csi->stack[i]; csi->stack[i] = f_argv[i]; } for (;i < f_argc; i++) { csi->stack[i] = f_argv[i]; } csi->top = f_argc; /* Store the name */ fz_strlcpy(save_name, csi->name, sizeof(csi->name)); if (arg) { fz_strlcpy(csi->name, arg, sizeof(csi->name)); } else { csi->name[0] = 0; } call_op(csi, state, op); /* Restore the name */ fz_strlcpy(csi->name, save_name, sizeof(save_name)); /* Restore the stack */ for (i = 0; i < to_save; i++) csi->stack[i] = save_f[i]; csi->top = top; }
static void pdf_filter_cs(pdf_csi *csi, void *state_) { pdf_filter_state *state = (pdf_filter_state *)state_; filter_gstate *gstate = gstate_to_update(csi, state); insert_resource(csi, state, "ColorSpace"); fz_strlcpy(gstate->cs, csi->name, sizeof(csi->name)); gstate->color_n = 0; }
static void pdf_filter_sc_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade) { pdf_filter_processor *p = (pdf_filter_processor*)proc; filter_gstate *gstate = gstate_to_update(ctx, p); fz_strlcpy(gstate->sc.name, name, sizeof gstate->sc.name); gstate->sc.pat = NULL; gstate->sc.shd = shade; gstate->sc.n = 0; copy_resource(ctx, p, PDF_NAME_Pattern, name); }