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_resize_buffer(fz_context *ctx, fz_buffer *buf, int size) { /* SumatraPDF: prevent integer overflows in fz_grow_buffer and fz_trim_buffer */ if (size < 0) fz_throw(ctx, "size %d indicates integer overflow", size); buf->data = fz_resize_array(ctx, buf->data, size, 1); buf->cap = size; if (buf->len > buf->cap) buf->len = buf->cap; }
static void fz_grow_text_span(fz_context *ctx, fz_text_span *span, int n) { int new_cap = span->cap; if (span->len + n < new_cap) return; while (span->len + n > new_cap) new_cap = new_cap + 36; span->items = fz_resize_array(ctx, span->items, new_cap, sizeof(fz_text_item)); span->cap = new_cap; }
static void append_line(fz_context *ctx, fz_text_block *block, fz_text_line *line) { if (block->len == block->cap) { int new_cap = fz_maxi(16, block->cap * 2); block->lines = fz_resize_array(ctx, block->lines, new_cap, sizeof *block->lines); block->cap = new_cap; } fz_union_rect(&block->bbox, &line->bbox); block->lines[block->len++] = *line; }
static void gatherforms(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict) { int i, n; n = pdf_dict_len(dict); for (i = 0; i < n; i++) { pdf_obj *xobjdict; pdf_obj *type; pdf_obj *subtype; pdf_obj *group; pdf_obj *groupsubtype; pdf_obj *reference; int k; xobjdict = pdf_dict_get_val(dict, i); if (!pdf_is_dict(xobjdict)) { fz_warn(ctx, "not a xobject dict (%d %d R)", pdf_to_num(xobjdict), pdf_to_gen(xobjdict)); continue; } type = pdf_dict_gets(xobjdict, "Subtype"); if (strcmp(pdf_to_name(type), "Form")) continue; subtype = pdf_dict_gets(xobjdict, "Subtype2"); if (!strcmp(pdf_to_name(subtype), "PS")) continue; group = pdf_dict_gets(xobjdict, "Group"); groupsubtype = pdf_dict_gets(group, "S"); reference = pdf_dict_gets(xobjdict, "Ref"); for (k = 0; k < forms; k++) if (!pdf_objcmp(form[k].u.form.obj, xobjdict)) break; if (k < forms) continue; form = fz_resize_array(ctx, form, forms+1, sizeof(struct info)); forms++; form[forms - 1].page = page; form[forms - 1].pageref = pageref; form[forms - 1].pageobj = pageobj; form[forms - 1].u.form.obj = xobjdict; form[forms - 1].u.form.groupsubtype = groupsubtype; form[forms - 1].u.form.reference = reference; } }
static void add_root(fz_context *ctx, pdf_obj *obj, pdf_obj ***roots, int *num_roots, int *max_roots) { if (*num_roots == *max_roots) { int new_max_roots = *max_roots * 2; if (new_max_roots == 0) new_max_roots = 4; *roots = fz_resize_array(ctx, *roots, new_max_roots, sizeof(**roots)); *max_roots = new_max_roots; } (*roots)[(*num_roots)++] = pdf_keep_obj(ctx, obj); }
static void pdf_array_grow(pdf_obj *obj) { int i; int new_cap = (obj->u.a.cap * 3) / 2; obj->u.a.items = fz_resize_array(obj->ctx, obj->u.a.items, new_cap, sizeof(pdf_obj*)); obj->u.a.cap = new_cap; for (i = obj->u.a.len ; i < obj->u.a.cap; i++) obj->u.a.items[i] = NULL; }
static void region_masks_add(region_masks *rms, region_mask *rm) { /* Add rm to rms */ if (rms->len == rms->cap) { int newcap = (rms->cap ? rms->cap * 2 : 4); rms->mask = fz_resize_array(rms->ctx, rms->mask, newcap, sizeof(*rms->mask)); rms->cap = newcap; } rms->mask[rms->len] = rm; rms->len++; }
void fz_buffer_cat(fz_context *ctx, fz_buffer *buf, fz_buffer *extra) { if (buf->cap - buf->len < extra->len) { buf->data = fz_resize_array(ctx, buf->data, buf->len + extra->len, 1); buf->cap = buf->len + extra->len; } memcpy(buf->data + buf->len, extra->data, extra->len); buf->len += extra->len; }
static void fz_add_text_char_imp(fz_context *ctx, fz_text_span *span, int c, fz_bbox bbox) { if (span->len + 1 >= span->cap) { span->cap = span->cap > 1 ? (span->cap * 3) / 2 : 80; span->text = fz_resize_array(ctx, span->text, span->cap, sizeof(fz_text_char)); } span->text[span->len].c = c; span->text[span->len].bbox = bbox; span->len ++; }
static void pdf_array_grow(fz_context *ctx, pdf_obj_array *obj) { int i; int new_cap = (obj->cap * 3) / 2; obj->items = fz_resize_array(ctx, obj->items, new_cap, sizeof(pdf_obj*)); obj->cap = new_cap; for (i = obj->len ; i < obj->cap; i++) obj->items[i] = NULL; }
static void push_cmd(fz_context *ctx, fz_path *path, int cmd) { if (path->cmd_len + 1 >= path->cmd_cap) { int new_cmd_cap = fz_maxi(16, path->cmd_cap * 2); path->cmds = fz_resize_array(ctx, path->cmds, new_cmd_cap, sizeof(unsigned char)); path->cmd_cap = new_cmd_cap; } path->cmds[path->cmd_len++] = cmd; path->last_cmd = cmd; }
static int svg_dev_begin_tile(fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id) { svg_device *sdev = (svg_device *)dev->user; fz_output *out = sdev->out; fz_context *ctx = dev->ctx; fz_matrix inverse; int num; tile *t; if (sdev->num_tiles == sdev->max_tiles) { int n = (sdev->num_tiles == 0 ? 4 : sdev->num_tiles * 2); sdev->tiles = fz_resize_array(ctx, sdev->tiles, n, sizeof(tile)); sdev->max_tiles = n; } num = sdev->num_tiles++; t = &sdev->tiles[num]; t->area = *area; t->view = *view; t->ctm = *ctm; t->pattern = sdev->id++; t->step.x = xstep; t->step.y = ystep; /* view = area of our reference tile in pattern space. * area = area to tile into in pattern space. * xstep/ystep = pattern repeat step in pattern space. * All of these need to be transformed by ctm to get to device space. * SVG only allows us to specify pattern tiles as axis aligned * rectangles, so we send these through as is, and ensure that the * correct matrix is used on the fill. */ /* In svg, the reference tile is taken from (x,y) to (x+width,y+height) * and is repeated at (x+n*width,y+m*height) for all integer n and m. * This means that width and height correspond to xstep and ystep. */ fz_printf(out, "<pattern id=\"pa%d\" patternUnits=\"userSpaceOnUse\" patternContentUnits=\"userSpaceOnUse\"", t->pattern); fz_printf(out, " x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\">\n", view->x0, view->y0, xstep, ystep); /* All the pattern contents will have their own ctm applied. Let's * undo the current one to allow for this */ fz_invert_matrix(&inverse, ctm); fz_printf(out, "<g"); svg_dev_ctm(sdev, &inverse); fz_printf(out, ">\n"); return 0; }
static void pdf_dev_alpha(fz_context *ctx, pdf_device *pdev, float alpha, int stroke) { int i; pdf_document *doc = pdev->doc; gstate *gs = CURRENT_GSTATE(pdev); /* If the alpha is unchanged, nothing to do */ if (gs->alpha[stroke] == alpha) return; /* Have we sent such an alpha before? */ for (i = 0; i < pdev->num_alphas; i++) if (pdev->alphas[i].alpha == alpha && pdev->alphas[i].stroke == stroke) break; if (i == pdev->num_alphas) { pdf_obj *o, *ref; /* No. Need to make a new one */ if (pdev->num_alphas == pdev->max_alphas) { int newmax = pdev->max_alphas * 2; if (newmax == 0) newmax = 4; pdev->alphas = fz_resize_array(ctx, pdev->alphas, newmax, sizeof(*pdev->alphas)); pdev->max_alphas = newmax; } pdev->alphas[i].alpha = alpha; pdev->alphas[i].stroke = stroke; o = pdf_new_dict(ctx, doc, 1); fz_try(ctx) { char text[32]; pdf_dict_put_real(ctx, o, (stroke ? PDF_NAME(CA) : PDF_NAME(ca)), alpha); fz_snprintf(text, sizeof(text), "ExtGState/Alp%d", i); ref = pdf_add_object(ctx, doc, o); pdf_dict_putp_drop(ctx, pdev->resources, text, ref); } fz_always(ctx) { pdf_drop_obj(ctx, o); } fz_catch(ctx) { fz_rethrow(ctx); } pdev->num_alphas++; }
static void append_char(fz_context *ctx, fz_text_span *span, int c, fz_rect bbox) { if (span->len == span->cap) { int new_cap = fz_maxi(64, span->cap * 2); span->text = fz_resize_array(ctx, span->text, new_cap, sizeof(*span->text)); span->cap = new_cap; } fz_union_rect(&span->bbox, &bbox); span->text[span->len].c = c; span->text[span->len].bbox = bbox; span->len++; }
void pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w) { if (font->hmtx_len + 1 >= font->hmtx_cap) { font->hmtx_cap = font->hmtx_cap + 16; font->hmtx = fz_resize_array(ctx, font->hmtx, font->hmtx_cap, sizeof(pdf_hmtx)); } font->hmtx[font->hmtx_len].lo = lo; font->hmtx[font->hmtx_len].hi = hi; font->hmtx[font->hmtx_len].w = w; font->hmtx_len++; }
static void fz_dict_grow(fz_obj *obj) { int i; obj->u.d.cap = (obj->u.d.cap * 3) / 2; obj->u.d.items = fz_resize_array(obj->ctx, obj->u.d.items, obj->u.d.cap, sizeof(struct keyval)); for (i = obj->u.d.len; i < obj->u.d.cap; i++) { obj->u.d.items[i].k = NULL; obj->u.d.items[i].v = NULL; } }
static void add_span_to_soup(fz_context *ctx, span_soup *soup, fz_text_span *span) { if (span == NULL) return; if (soup->len == soup->cap) { int newcap = (soup->cap ? soup->cap * 2 : 16); soup->spans = fz_resize_array(ctx, soup->spans, newcap, sizeof(*soup->spans)); soup->cap = newcap; } add_bbox_to_span(span); soup->spans[soup->len++] = span; }
static void pdf_grow_mesh(fz_context *ctx, fz_shade *shade, int amount) { if (shade->mesh_len + amount < shade->mesh_cap) return; if (shade->mesh_cap == 0) shade->mesh_cap = 1024; while (shade->mesh_len + amount > shade->mesh_cap) shade->mesh_cap = (shade->mesh_cap * 3) / 2; shade->mesh = fz_resize_array(ctx, shade->mesh, shade->mesh_cap, sizeof(float)); }
static void append_span(fz_context *ctx, fz_text_line *line, fz_text_span *span) { if (span->len == 0) return; if (line->len == line->cap) { int new_cap = fz_maxi(8, line->cap * 2); line->spans = fz_resize_array(ctx, line->spans, new_cap, sizeof(*line->spans)); line->cap = new_cap; } fz_union_rect(&line->bbox, &span->bbox); line->spans[line->len++] = *span; }
static void pdf_dict_grow(fz_context *ctx, pdf_obj *obj) { int i; int new_cap = (obj->u.d.cap * 3) / 2; obj->u.d.items = fz_resize_array(ctx, obj->u.d.items, new_cap, sizeof(struct keyval)); obj->u.d.cap = new_cap; for (i = obj->u.d.len; i < obj->u.d.cap; i++) { obj->u.d.items[i].k = NULL; obj->u.d.items[i].v = NULL; } }
static void grow_path(fz_context *ctx, fz_path *path, int n) { int newcap = path->cap; if (path->len + n <= path->cap) { path->last = path->len; return; } while (path->len + n > newcap) newcap = newcap + 36; path->items = fz_resize_array(ctx, path->items, newcap, sizeof(fz_path_item)); path->cap = newcap; path->last = path->len; }
static void pdf_dict_grow(fz_context *ctx, pdf_obj *obj) { int i; int new_cap = (DICT(obj)->cap * 3) / 2; DICT(obj)->items = fz_resize_array(ctx, DICT(obj)->items, new_cap, sizeof(struct keyval)); DICT(obj)->cap = new_cap; for (i = DICT(obj)->len; i < DICT(obj)->cap; i++) { DICT(obj)->items[i].k = NULL; DICT(obj)->items[i].v = NULL; } }
/* * Add an integer to the table. */ static void add_table(fz_context *ctx, pdf_cmap *cmap, int value) { if (cmap->tlen == USHRT_MAX) { fz_warn(ctx, "cmap table is full; ignoring additional entries"); return; } if (cmap->tlen + 1 > cmap->tcap) { cmap->tcap = cmap->tcap > 1 ? (cmap->tcap * 3) / 2 : 256; cmap->table = fz_resize_array(ctx, cmap->table, cmap->tcap, sizeof(unsigned short)); } cmap->table[cmap->tlen++] = value; }
static void push_coord(fz_context *ctx, fz_path *path, float x, float y) { if (path->coord_len + 2 >= path->coord_cap) { int new_coord_cap = fz_maxi(32, path->coord_cap * 2); path->coords = fz_resize_array(ctx, path->coords, new_coord_cap, sizeof(float)); path->coord_cap = new_coord_cap; } path->coords[path->coord_len++] = x; path->coords[path->coord_len++] = y; path->current.x = x; path->current.y = y; }
static void pdf_resize_xref(fz_context *ctx, pdf_xref *xref, int newlen) { int i; xref->table = fz_resize_array(ctx, xref->table, newlen, sizeof(pdf_xref_entry)); for (i = xref->len; i < newlen; i++) { xref->table[i].type = 0; xref->table[i].ofs = 0; xref->table[i].gen = 0; xref->table[i].stm_ofs = 0; xref->table[i].stm_buf = NULL; xref->table[i].obj = NULL; } xref->len = newlen; }
ptrdiff_t pdf_lexbuf_grow(pdf_lexbuf *lb) { char *old = lb->scratch; int newsize = lb->size * 2; if (lb->size == lb->base_size) { lb->scratch = fz_malloc(lb->ctx, newsize); memcpy(lb->scratch, lb->buffer, lb->size); } else { lb->scratch = fz_resize_array(lb->ctx, lb->scratch, newsize, 1); } lb->size = newsize; return lb->scratch - old; }
static void fz_grow_stack(fz_draw_device *dev) { int max = dev->stack_max * 2; fz_draw_state *stack; if (dev->stack == &dev->init_stack[0]) { stack = fz_malloc(dev->ctx, sizeof(*stack) * max); memcpy(stack, dev->stack, sizeof(*stack) * dev->stack_max); } else { stack = fz_resize_array(dev->ctx, dev->stack, max, sizeof(*stack)); } dev->stack = stack; dev->stack_max = max; }
static int insert_active(fz_context *ctx, fz_gel *gel, int y, int *e_) { int h_min = INT_MAX; int e = *e_; /* insert edges that start here */ if (e < gel->len && gel->edges[e].y == y) { do { if (gel->alen + 1 == gel->acap) { int newcap = gel->acap + 64; fz_edge **newactive = fz_resize_array(ctx, gel->active, newcap, sizeof(fz_edge*)); gel->active = newactive; gel->acap = newcap; } gel->active[gel->alen++] = &gel->edges[e++]; } while (e < gel->len && gel->edges[e].y == y); *e_ = e; } if (e < gel->len) h_min = gel->edges[e].y - y; for (e=0; e < gel->alen; e++) { if (gel->active[e]->xmove != 0 || gel->active[e]->adj_up != 0) { h_min = 1; break; } if (gel->active[e]->h < h_min) { h_min = gel->active[e]->h; if (h_min == 1) break; } } /* shell-sort the edges by increasing x */ sort_active(gel->active, gel->alen); return h_min; }
static void gatherfonts(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict) { int i, n; n = pdf_dict_len(dict); for (i = 0; i < n; i++) { pdf_obj *fontdict = NULL; pdf_obj *subtype = NULL; pdf_obj *basefont = NULL; pdf_obj *name = NULL; int k; fontdict = pdf_dict_get_val(dict, i); if (!pdf_is_dict(fontdict)) { fz_warn(ctx, "not a font dict (%d %d R)", pdf_to_num(fontdict), pdf_to_gen(fontdict)); continue; } subtype = pdf_dict_gets(fontdict, "Subtype"); basefont = pdf_dict_gets(fontdict, "BaseFont"); if (!basefont || pdf_is_null(basefont)) name = pdf_dict_gets(fontdict, "Name"); for (k = 0; k < fonts; k++) if (!pdf_objcmp(font[k].u.font.obj, fontdict)) break; if (k < fonts) continue; font = fz_resize_array(ctx, font, fonts+1, sizeof(struct info)); fonts++; font[fonts - 1].page = page; font[fonts - 1].pageref = pageref; font[fonts - 1].pageobj = pageobj; font[fonts - 1].u.font.obj = fontdict; font[fonts - 1].u.font.subtype = subtype; font[fonts - 1].u.font.name = basefont ? basefont : name; } }