#include "mupdf/fitz.h" fz_text * fz_new_text(fz_context *ctx, fz_font *font, const fz_matrix *trm, int wmode) { fz_text *text; text = fz_malloc_struct(ctx, fz_text); text->refs = 1; text->font = fz_keep_font(ctx, font); text->trm = *trm; text->wmode = wmode; text->len = 0; text->cap = 0; text->items = NULL; return text; } fz_text * fz_keep_text(fz_context *ctx, fz_text *text) { return fz_keep_imp(ctx, text, &text->refs); } void fz_drop_text(fz_context *ctx, fz_text *text) { if (fz_drop_imp(ctx, text, &text->refs)) { fz_drop_font(ctx, text->font); fz_free(ctx, text->items); fz_free(ctx, text); } } fz_rect * fz_bound_text(fz_context *ctx, fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *bbox) { fz_matrix tm, trm; fz_rect gbox; int i; if (text->len == 0) { *bbox = fz_empty_rect; return bbox; } // TODO: stroke state tm = text->trm; tm.e = text->items[0].x; tm.f = text->items[0].y; fz_concat(&trm, &tm, ctm); fz_bound_glyph(ctx, text->font, text->items[0].gid, &trm, bbox); for (i = 1; i < text->len; i++) { if (text->items[i].gid >= 0) { tm.e = text->items[i].x; tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); fz_bound_glyph(ctx, text->font, text->items[i].gid, &trm, &gbox); bbox->x0 = fz_min(bbox->x0, gbox.x0); bbox->y0 = fz_min(bbox->y0, gbox.y0); bbox->x1 = fz_max(bbox->x1, gbox.x1); bbox->y1 = fz_max(bbox->y1, gbox.y1); } } if (stroke) fz_adjust_rect_for_stroke(ctx, bbox, stroke, ctm); /* Compensate for the glyph cache limited positioning precision */ bbox->x0 -= 1; bbox->y0 -= 1; bbox->x1 += 1; bbox->y1 += 1; return bbox; } static void fz_grow_text(fz_context *ctx, fz_text *text, int n) { int new_cap = text->cap; if (text->len + n < new_cap) return; while (text->len + n > new_cap) new_cap = new_cap + 36; text->items = fz_resize_array(ctx, text->items, new_cap, sizeof(fz_text_item)); text->cap = new_cap; } void fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y) { if (text->refs != 1) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot modify shared text objects"); fz_grow_text(ctx, text, 1); text->items[text->len].ucs = ucs; text->items[text->len].gid = gid; text->items[text->len].x = x; text->items[text->len].y = y; text->len++; }