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 )