void xps_free_context(xps_context *ctx) { xps_font_cache *font, *next; int i; if (ctx->file) fz_close(ctx->file); for (i = 0; i < ctx->zip_count; i++) fz_free(ctx->ctx, ctx->zip_table[i].name); fz_free(ctx->ctx, ctx->zip_table); font = ctx->font_table; while (font) { next = font->next; fz_drop_font(ctx->ctx, font->font); fz_free(ctx->ctx, font->name); fz_free(ctx->ctx, font); font = next; } xps_free_page_list(ctx); fz_free(ctx->ctx, ctx->start_part); fz_free(ctx->ctx, ctx->directory); fz_free(ctx->ctx, ctx); }
void xps_close_document(fz_context *ctx, xps_document *doc) { xps_font_cache *font, *next; if (!doc) return; if (doc->zip) fz_drop_archive(ctx, doc->zip); font = doc->font_table; while (font) { next = font->next; fz_drop_font(ctx, font->font); fz_free(ctx, font->name); fz_free(ctx, font); font = next; } xps_drop_page_list(ctx, doc); fz_free(ctx, doc->start_part); fz_free(ctx, doc); }
void fz_drop_html_font_set(fz_context *ctx, fz_html_font_set *set) { int i; for (i = 0; i < nelem(set->fonts); ++i) fz_drop_font(ctx, set->fonts[i]); fz_free(ctx, set); }
void fz_free_text(fz_context *ctx, fz_text *text) { if (text != NULL) { fz_drop_font(ctx, text->font); fz_free(ctx, text->items); } fz_free(ctx, text); }
void fz_free_text_sheet(fz_context *ctx, fz_text_sheet *sheet) { fz_text_style *style = sheet->style; while (style) { fz_text_style *next = style->next; fz_drop_font(ctx, style->font); fz_free(ctx, style); style = next; } fz_free(ctx, sheet); }
fz_text * fz_clone_text(fz_context *ctx, const fz_text *text) { fz_text *new_text; fz_text_span *span; fz_text_span **tail; new_text = fz_malloc_struct(ctx, fz_text); new_text->refs = 1; span = text->head; tail = &new_text->head; fz_var(span); fz_try(ctx) { while (span != NULL) { fz_text_span *new_span = fz_malloc_struct(ctx, fz_text_span); *tail = new_span; tail = &new_span->next; new_text->tail = new_span; new_span->font = fz_keep_font(ctx, span->font); new_span->trm = span->trm; new_span->wmode = span->wmode; new_span->len = span->len; new_span->cap = span->len; new_span->items = fz_malloc(ctx, span->len * sizeof(*span->items)); memcpy(new_span->items, span->items, span->len * sizeof(*span->items)); span = span->next; } } fz_catch(ctx) { span = new_text->head; while (span != NULL) { fz_text_span *next = span->next; fz_drop_font(ctx, span->font); fz_free(ctx, span->items); fz_free(ctx, span); span = next; } fz_free(ctx, new_text); fz_rethrow(ctx); } return new_text; }
void fz_free_text_span(fz_context *ctx, fz_text_span *span) { fz_text_span *next; while (span) { if (span->font) fz_drop_font(ctx, span->font); next = span->next; fz_free(ctx, span->text); fz_free(ctx, span); span = next; } }
static void svg_dev_drop_device(fz_context *ctx, fz_device *dev) { svg_device *sdev = (svg_device*)dev; int i; fz_free(ctx, sdev->tiles); fz_drop_buffer(ctx, sdev->defs_buffer); fz_drop_output(ctx, sdev->defs); for (i = 0; i < sdev->num_fonts; i++) { fz_drop_font(ctx, sdev->fonts[i].font); fz_free(ctx, sdev->fonts[i].sentlist); } fz_free(ctx, sdev->fonts); }
static void xps_load_links_in_glyphs(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, char *base_uri, xps_resource *dict, fz_xml *root, fz_link **link) { char *navigate_uri_att = fz_xml_att(root, "FixedPage.NavigateUri"); if (navigate_uri_att) { char *transform_att = fz_xml_att(root, "RenderTransform"); fz_xml *transform_tag = fz_xml_down(fz_xml_find_down(root, "Path.RenderTransform")); char *bidi_level_att = fz_xml_att(root, "BidiLevel"); char *font_size_att = fz_xml_att(root, "FontRenderingEmSize"); char *font_uri_att = fz_xml_att(root, "FontUri"); char *origin_x_att = fz_xml_att(root, "OriginX"); char *origin_y_att = fz_xml_att(root, "OriginY"); char *is_sideways_att = fz_xml_att(root, "IsSideways"); char *indices_att = fz_xml_att(root, "Indices"); char *unicode_att = fz_xml_att(root, "UnicodeString"); char *style_att = fz_xml_att(root, "StyleSimulations"); int is_sideways = 0; int bidi_level = 0; fz_matrix local_ctm; fz_font *font; fz_text *text; fz_rect area; xps_resolve_resource_reference(ctx, doc, dict, &transform_att, &transform_tag, NULL); xps_parse_transform(ctx, doc, transform_att, transform_tag, &local_ctm, ctm); if (is_sideways_att) is_sideways = !strcmp(is_sideways_att, "true"); if (bidi_level_att) bidi_level = atoi(bidi_level_att); font = xps_lookup_font(ctx, doc, base_uri, font_uri_att, style_att); text = xps_parse_glyphs_imp(ctx, doc, &local_ctm, font, fz_atof(font_size_att), fz_atof(origin_x_att), fz_atof(origin_y_att), is_sideways, bidi_level, indices_att, unicode_att); fz_bound_text(ctx, text, NULL, &local_ctm, &area); fz_drop_text(ctx, text); fz_drop_font(ctx, font); xps_add_link(ctx, doc, &area, base_uri, navigate_uri_att, link); } }
void fz_drop_text(fz_context *ctx, fz_text *text) { if (fz_drop_imp(ctx, text, &text->refs)) { fz_text_span *span = text->head; while (span) { fz_text_span *next = span->next; fz_drop_font(ctx, span->font); fz_free(ctx, span->items); fz_free(ctx, span); span = next; } fz_free(ctx, text); } }
void fz_drop_stext_sheet(fz_context *ctx, fz_stext_sheet *sheet) { fz_stext_style *style; if (sheet == NULL) return; style = sheet->style; while (style) { fz_stext_style *next = style->next; fz_drop_font(ctx, style->font); fz_free(ctx, style); style = next; } fz_free(ctx, sheet); }
static void pdf_free_font_imp(fz_context *ctx, fz_storable *fontdesc_) { pdf_font_desc *fontdesc = (pdf_font_desc *)fontdesc_; if (fontdesc->font) fz_drop_font(ctx, fontdesc->font); if (fontdesc->encoding) pdf_drop_cmap(ctx, fontdesc->encoding); if (fontdesc->to_ttf_cmap) pdf_drop_cmap(ctx, fontdesc->to_ttf_cmap); if (fontdesc->to_unicode) pdf_drop_cmap(ctx, fontdesc->to_unicode); fz_free(ctx, fontdesc->cid_to_gid); fz_free(ctx, fontdesc->cid_to_ucs); fz_free(ctx, fontdesc->hmtx); fz_free(ctx, fontdesc->vmtx); fz_free(ctx, fontdesc); }
void fz_drop_text(fz_context *ctx, const fz_text *textc) { fz_text *text = (fz_text *)textc; /* Explicit cast away of const */ if (fz_drop_imp(ctx, text, &text->refs)) { fz_text_span *span = text->head; while (span) { fz_text_span *next = span->next; fz_drop_font(ctx, span->font); fz_free(ctx, span->items); fz_free(ctx, span); span = next; } fz_free(ctx, text); } }
static void xps_drop_document(fz_context *ctx, fz_document *doc_) { xps_document *doc = (xps_document*)doc_; xps_font_cache *font, *next; if (doc->zip) fz_drop_archive(ctx, doc->zip); font = doc->font_table; while (font) { next = font->next; fz_drop_font(ctx, font->font); fz_free(ctx, font->name); fz_free(ctx, font); font = next; } xps_drop_page_list(ctx, doc); fz_free(ctx, doc->start_part); }
static void drop_glyph_cache_entry(fz_context *ctx, fz_glyph_cache_entry *entry) { fz_glyph_cache *cache = ctx->glyph_cache; if (entry->lru_next) entry->lru_next->lru_prev = entry->lru_prev; else cache->lru_tail = entry->lru_prev; if (entry->lru_prev) entry->lru_prev->lru_next = entry->lru_next; else cache->lru_head = entry->lru_next; cache->total -= fz_glyph_size(ctx, entry->val); if (entry->bucket_next) entry->bucket_next->bucket_prev = entry->bucket_prev; if (entry->bucket_prev) entry->bucket_prev->bucket_next = entry->bucket_next; else cache->entry[entry->hash] = entry->bucket_next; fz_drop_font(ctx, entry->key.font); fz_drop_glyph(ctx, entry->val); fz_free(ctx, entry); }
static void pdf_write_stamp_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect, fz_rect *bbox, pdf_obj **res) { fz_font *font; pdf_obj *res_font; pdf_obj *name; float w, h, xs, ys; fz_matrix rotate; name = pdf_dict_get(ctx, annot->obj, PDF_NAME(Name)); if (!name) name = PDF_NAME(Draft); h = rect->y1 - rect->y0; w = rect->x1 - rect->x0; xs = w / 190; ys = h / 50; font = fz_new_base14_font(ctx, "Times-Bold"); fz_try(ctx) { /* /Resources << /Font << /Times %d 0 R >> >> */ *res = pdf_new_dict(ctx, annot->page->doc, 1); res_font = pdf_dict_put_dict(ctx, *res, PDF_NAME(Font), 1); pdf_dict_put_drop(ctx, res_font, PDF_NAME(Times), pdf_add_simple_font(ctx, annot->page->doc, font, 0)); pdf_write_fill_color_appearance(ctx, annot, buf); pdf_write_stroke_color_appearance(ctx, annot, buf); rotate = fz_rotate(0.6f); fz_append_printf(ctx, buf, "%M cm\n", &rotate); fz_append_string(ctx, buf, "2 w\n2 2 186 44 re\nS\n"); if (name == PDF_NAME(Approved)) write_stamp(ctx, buf, font, "APPROVED", 13, 30); else if (name == PDF_NAME(AsIs)) write_stamp(ctx, buf, font, "AS IS", 13, 30); else if (name == PDF_NAME(Confidential)) write_stamp(ctx, buf, font, "CONFIDENTIAL", 17, 20); else if (name == PDF_NAME(Departmental)) write_stamp(ctx, buf, font, "DEPARTMENTAL", 17, 20); else if (name == PDF_NAME(Experimental)) write_stamp(ctx, buf, font, "EXPERIMENTAL", 17, 20); else if (name == PDF_NAME(Expired)) write_stamp(ctx, buf, font, "EXPIRED", 13, 30); else if (name == PDF_NAME(Final)) write_stamp(ctx, buf, font, "FINAL", 13, 30); else if (name == PDF_NAME(ForComment)) write_stamp(ctx, buf, font, "FOR COMMENT", 17, 20); else if (name == PDF_NAME(ForPublicRelease)) { write_stamp(ctx, buf, font, "FOR PUBLIC", 26, 18); write_stamp(ctx, buf, font, "RELEASE", 8.5f, 18); } else if (name == PDF_NAME(NotApproved)) write_stamp(ctx, buf, font, "NOT APPROVED", 17, 20); else if (name == PDF_NAME(NotForPublicRelease)) { write_stamp(ctx, buf, font, "NOT FOR", 26, 18); write_stamp(ctx, buf, font, "PUBLIC RELEASE", 8.5, 18); } else if (name == PDF_NAME(Sold)) write_stamp(ctx, buf, font, "SOLD", 13, 30); else if (name == PDF_NAME(TopSecret)) write_stamp(ctx, buf, font, "TOP SECRET", 14, 26); else if (name == PDF_NAME(Draft)) write_stamp(ctx, buf, font, "DRAFT", 13, 30); else write_stamp(ctx, buf, font, pdf_to_name(ctx, name), 17, 20); } fz_always(ctx) fz_drop_font(ctx, font); fz_catch(ctx) fz_rethrow(ctx); *bbox = fz_make_rect(0, 0, 190, 50); if (xs > ys) { float xc = (rect->x1+rect->x0) / 2; rect->x0 = xc - 95 * ys; rect->x1 = xc + 95 * ys; } else { float yc = (rect->y1+rect->y0) / 2; rect->y0 = yc - 25 * xs; rect->y1 = yc + 25 * xs; } }
int pdfportfolio_main(int argc, char **argv) { char *password = ""; char *outfile = NULL; char *outopts = "compress"; char *infile; int exit_code = 0; int do_save = 0; int has_old_file = 0; int c; while ((c = fz_getopt(argc, argv, "p:o:O:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'o': outfile = fz_optarg; break; case 'O': outopts = fz_optarg; break; default: usage(); break; } } if (fz_optind == argc) usage(); infile = argv[fz_optind++]; if (!outfile) outfile = infile; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } if (fz_file_exists(ctx, infile)) { doc = pdf_open_document(ctx, infile); if (pdf_needs_password(ctx, doc)) if (!pdf_authenticate_password(ctx, doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); has_old_file = 1; } else { doc = pdf_create_document(ctx); /* add a blank page */ { const char *template = "BT /Tm 16 Tf 50 434 TD (This is a portfolio document.) Tj ET\n"; const unsigned char *data; int size; fz_font *font; pdf_obj *font_obj, *page_obj; pdf_obj *resources; fz_buffer *contents; fz_rect mediabox = { 0, 0, 400, 500 }; data = fz_lookup_base14_font(ctx, "Times-Roman", &size); font = fz_new_font_from_memory(ctx, "Times-Roman", data, size, 0, 0); font_obj = pdf_add_simple_font(ctx, doc, font, PDF_SIMPLE_ENCODING_LATIN); fz_drop_font(ctx, font); resources = pdf_add_new_dict(ctx, doc, 1); pdf_dict_putp_drop(ctx, resources, "Font/Tm", font_obj); contents = fz_new_buffer_from_shared_data(ctx, (const unsigned char *)template, strlen(template));
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); } }
static void write_variable_text(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, pdf_obj **res, const char *text, const char *fontname, float size, float color[3], int q, float w, float h, float padding, float baseline, float lineheight, int multiline, int comb, int adjust_baseline) { pdf_obj *res_font; fz_font *font; w -= padding * 2; h -= padding * 2; font = fz_new_base14_font(ctx, full_font_name(&fontname)); fz_try(ctx) { if (size == 0) { if (multiline) size = 12; else { size = w / measure_simple_string(ctx, font, text); if (size > h) size = h; } } lineheight = size * lineheight; baseline = size * baseline; if (adjust_baseline) { /* Make sure baseline is inside rectangle */ if (baseline + 0.2f * size > h) baseline = h - 0.2f * size; } /* /Resources << /Font << /Helv %d 0 R >> >> */ *res = pdf_new_dict(ctx, annot->page->doc, 1); res_font = pdf_dict_put_dict(ctx, *res, PDF_NAME(Font), 1); pdf_dict_puts_drop(ctx, res_font, fontname, pdf_add_simple_font(ctx, annot->page->doc, font, 0)); fz_append_string(ctx, buf, "BT\n"); fz_append_printf(ctx, buf, "%g %g %g rg\n", color[0], color[1], color[2]); fz_append_printf(ctx, buf, "/%s %g Tf\n", fontname, size); if (multiline) { fz_append_printf(ctx, buf, "%g TL\n", lineheight); fz_append_printf(ctx, buf, "%g %g Td\n", padding, padding+h-baseline+lineheight); write_simple_string_with_quadding(ctx, buf, font, size, text, w, q); } else if (comb > 0) { float ty = (h - size) / 2; fz_append_printf(ctx, buf, "%g %g Td\n", padding, padding+h-baseline-ty); write_comb_string(ctx, buf, text, text + strlen(text), font, (w * 1000 / size) / comb); } else { float tx = 0, ty = (h - size) / 2; if (q > 0) { float tw = measure_simple_string(ctx, font, text) * size; if (q == 1) tx = (w - tw) / 2; else tx = (w - tw); } fz_append_printf(ctx, buf, "%g %g Td\n", padding+tx, padding+h-baseline-ty); write_simple_string(ctx, buf, text, text + strlen(text)); fz_append_printf(ctx, buf, " Tj\n"); } fz_append_string(ctx, buf, "ET\n"); } fz_always(ctx) fz_drop_font(ctx, font); fz_catch(ctx) fz_rethrow(ctx); }
void ui_finish_fonts(fz_context *ctx) { clear_font_cache(); fz_drop_font(ctx, g_font); }