PDF-Make
view release on metacpan or search on metacpan
src/pdfmake_textract.c view on Meta::CPAN
if (!n) return NULL;
r->font_cache = n;
r->font_cache_cap = new_cap;
}
slot = &r->font_cache[r->font_cache_len++];
memset(slot, 0, sizeof(*slot));
slot->font_dict = font_dict;
slot->std14_id = -1;
return slot;
}
/* Resolve the ToUnicode CMap for a font dict. Returns NULL if not present
* or if resolution fails. Caches the result (including NULL) per-font. */
static pdfmake_cmap_t *resolve_to_unicode(pdfmake_textract_result_t *r,
pdfmake_resolved_font_t *rf)
{
uint32_t key;
pdfmake_obj_t *tu;
pdfmake_buf_t buf;
pdfmake_err_t err;
if (rf->to_unicode_tried) return rf->to_unicode;
rf->to_unicode_tried = 1;
if (!r->reader || !rf->font_dict || !r->arena) return NULL;
key = pdfmake_arena_intern_name(r->arena, "ToUnicode", 9);
tu = pdfmake_dict_get(rf->font_dict, key);
if (!tu || tu->kind != PDFMAKE_REF) return NULL;
pdfmake_buf_init(&buf);
err = pdfmake_reader_resolve_stream(
r->reader, tu->as.ref.num, tu->as.ref.gen, &buf);
if (err != PDFMAKE_OK || buf.len == 0) {
pdfmake_buf_free(&buf);
return NULL;
}
rf->to_unicode = pdfmake_cmap_parse(r->arena, buf.data, buf.len);
pdfmake_buf_free(&buf);
return rf->to_unicode;
}
/* Resolve /Widths or /W for the font, plus font descriptor metrics. */
static void resolve_widths(pdfmake_textract_result_t *r,
pdfmake_resolved_font_t *rf)
{
if (rf->widths_resolved) return;
rf->widths_resolved = 1;
if (!rf->font_dict || !r->arena) {
pdfmake_font_widths_init(&rf->widths);
return;
}
if (rf->is_cid) {
pdfmake_font_widths_from_cid(r->arena, rf->font_dict, &rf->widths);
} else {
pdfmake_font_widths_from_simple(r->arena, rf->font_dict, &rf->widths);
}
/* Phase 6: overlay with TTF metrics from /FontFile2 if present.
* For simple fonts this requires the resolved /Encoding first; callers
* arrange the sequence in resolve_font(). */
if (r->reader) {
const uint32_t *byte_to_uni = NULL;
if (!rf->is_cid && rf->encoding_resolved) {
byte_to_uni = rf->encoding.map;
}
pdfmake_font_widths_enhance_with_ttf(
r->arena,
(struct pdfmake_reader *)r->reader,
rf->font_dict,
rf->is_cid,
byte_to_uni,
&rf->widths);
}
}
/* Resolve the /Encoding entry for a simple font. Populates rf->encoding.
* Std14 fonts without an explicit /Encoding default to WinAnsi in practice;
* other Type1 fonts default to StandardEncoding. */
static void resolve_encoding(pdfmake_textract_result_t *r,
pdfmake_resolved_font_t *rf)
{
uint32_t enc_key;
pdfmake_obj_t *enc_obj;
pdfmake_obj_t *resolved;
const pdfmake_std14_data_t *d;
if (rf->encoding_resolved) return;
rf->encoding_resolved = 1;
if (!rf->font_dict || !r->arena) {
pdfmake_font_encoding_init_winansi(&rf->encoding);
return;
}
enc_key = pdfmake_arena_intern_name(r->arena, "Encoding", 8);
enc_obj = pdfmake_dict_get(rf->font_dict, enc_key);
/* Resolve indirect reference if needed */
if (enc_obj && enc_obj->kind == PDFMAKE_REF && r->reader) {
/* We need to resolve the ref through the parser; expose a tiny helper */
/* For now, the parser returns the concrete obj via the reader's parser */
resolved = pdfmake_parser_resolve(
((pdfmake_reader_t *)r->reader)->parser, enc_obj->as.ref);
if (resolved) enc_obj = resolved;
}
if (enc_obj) {
pdfmake_font_encoding_from_dict(r->arena, enc_obj, &rf->encoding);
} else {
/* No /Encoding: pick a sane default based on Std14 kind */
if (rf->std14_id >= 0) {
/* Symbol and ZapfDingbats have their own encoding */
d = pdfmake_std14_get((pdfmake_std14_id_t)rf->std14_id);
if (d && d->name) {
if (strcmp(d->name, "Symbol") == 0)
pdfmake_font_encoding_init_symbol(&rf->encoding);
else if (strcmp(d->name, "ZapfDingbats") == 0)
pdfmake_font_encoding_init_zapfdingbats(&rf->encoding);
else
( run in 0.711 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )