#include "libpdftex.h"

key_entry font_keys[FONT_KEYS_NUM] = {
    {"Ascent",       "Ascender",     {0}, false},
    {"CapHeight",    "CapHeight",    {0}, false},
    {"Descent",      "Descender",    {0}, false},
    {"FontName",     "FontName",     {0}, false},
    {"ItalicAngle",  "ItalicAngle",  {0}, false},
    {"StemV",        "StdVW",        {0}, false},
    {"XHeight",      "XHeight",      {0}, false},
    {"FontBBox",     "FontBBox",     {0}, false},
    {"",             "",             {0}, false},
    {"",             "",             {0}, false},
    {"",             "",             {0}, false}
};

void print_key(integer code, integer v)
{
    PDF_PRINTF("/%s " AND font_keys[code].pdfname);
    if (!font_keys[code].valid) {
      /*
       * WARN("cannot read key `%s' from font file\nused value from %s.tfm"
       *      AND font_keys[code].pdfname AND makecstring(fontname[tex_font]));
       */
        PDF_PRINTF("%li" AND
                   (code == ITALIC_ANGLE_CODE) ? v :
                   dividescaled(v, pdffontsize[tex_font], 3));
    }
    else 
        PDF_PRINTF("%li" AND font_keys[code].value.i);
    PDF_PRINTF("\n");
}

integer getitalicangle(internalfontnumber f)
{
    return -atan(getslant(f)/65536.0)*(180/M_PI);
}

integer getstemv(internalfontnumber f)
{
    return getquad(f)/10;
}

void getbbox(internalfontnumber f)
{
    font_keys[FONTBBOX1_CODE].value.i = 0;
    font_keys[FONTBBOX2_CODE].value.i = 
        dividescaled(-getchardepth(f, 'q'), pdffontsize[f], 3);
    font_keys[FONTBBOX3_CODE].value.i = getquad(f);
    font_keys[FONTBBOX4_CODE].value.i = getcharheight(tex_font, 'h');
}

static char *subset_prefix(internalfontnumber f)
{
    integer k, l = 0;
    char buf[7], *p = buf;
    for (k = 0; k < MAX_CHAR_NUM; k++)
        if (pdfischarused(f, k))
            l = (l << 1) + k;
    if (l < 0)
        l = -l - 1;
    for (k = 0; k < 6; k++) {
        *p++ = 'A' + l%('Z' - 'A');
        l /= 'Z' - 'A';
    }
    *p = 0;
    return xstrdup(buf);
}

void dopdffont(int objnum, internalfontnumber f)
{
    int k, e = 0;
    tex_font = f;
    filename = 0;
    if (pdffontmap[f] == -1)
        FAIL("font %i has invalid index of font mapping" AND f);
    fm_cur = fm_tab + pdffontmap[f];
    if (!is_truetype() && is_subsetted())
        fm_cur->prefix = subset_prefix(f);
    if (is_reencoded())
        e = enc_objnum(fm_cur->encoding);
    pdfbegindict(objnum);
    PDF_PRINTF("/Type /Font\n/Subtype /%s\n" AND
               is_truetype() ? "TrueType" : "Type1");
    if (is_reencoded() && !is_truetype())
        PDF_PRINTF("/Encoding %i 0 R\n" AND e);
    if (is_basefont()) {
        PDF_PRINTF("/BaseFont /%s\n>> endobj\n" AND fm_cur->base_name);
        return;
    }
    PDF_PRINTF("/FirstChar %i\n/LastChar %i\n/Widths %i 0 R\n" AND
               fontbc[tex_font] AND fontec[tex_font] AND objptr + 1);
/*
 *    if font is included then
 *        |obj_ptr + 1| is the width array,
 *        |obj_ptr + 2| is the font file stream,
 *        if font is TrueType then
 *            |obj_ptr + 3| is the font file length
 *            |obj_ptr + 4| is the font base name,
 *            |obj_ptr + 5| is the font descriptor,
 *        else
 *            |obj_ptr + 3..obj_ptr + 6| are
 *                the lengths of sections in font file,
 *            |obj_ptr + 7| is the font base name,
 *            |obj_ptr + 8| is the font descriptor,
 *    else
 *         |obj_ptr + 1| is the width array,
 *         |obj_ptr + 2| is the font base name,
 *         if font file is present then
 *             |obj_ptr + 3| is the font descriptor,
 */
 
    if (is_included())
        if (is_truetype())
            PDF_PRINTF("/BaseFont %i 0 R\n/FontDescriptor %i 0 R\n" AND
                       objptr + 4 AND objptr + 5);
        else
            PDF_PRINTF("/BaseFont %i 0 R\n/FontDescriptor %i 0 R\n" AND
                       objptr + 7 AND objptr + 8);
    else if (!is_noparsing())
        PDF_PRINTF("/BaseFont %i 0 R\n/FontDescriptor %i 0 R\n" AND
                   objptr + 2 AND objptr + 3);
	else
        PDF_PRINTF("/BaseFont /%s\n" AND fm_cur->base_name);
    PDF_PRINTF(">> endobj\n");
    pdfnewobj(0, 0); /* chars width array */
    PDF_PRINTF("[ ");
    if (pdfextendfont[tex_font] == 0) {
        for (k = fontbc[tex_font]; k <= fontec[tex_font]; k++)
            PDF_PRINTF("%i " AND dividescaled(getcharwidth(tex_font, k),
                                              pdffontsize[tex_font], 3));
    }
    else {
        for (k = fontbc[tex_font]; k <= fontec[tex_font]; k++)
            PDF_PRINTF("%i " AND dividescaled(getcharwidth(tex_font, k),
            xnoverd(pdffontsize[tex_font], pdfextendfont[tex_font], 1000), 3));
    }
    PDF_PRINTF("]\nendobj\n");
    if (is_noparsing())
        return;
    if (is_included()) {
        pdfnewdict(0, 0); /* font file stream */
        if (!is_truetype())
            PDF_PRINTF("/Length %i 0 R\n/Length1 %i 0 R\n/Length2 %i 0 R\n/Length3 %i 0 R\n" AND
                       objptr + 1 AND objptr + 2 AND objptr + 3 AND objptr + 4);
        else 
            PDF_PRINTF("/Length %i 0 R\n/Length1 %i 0 R\n" AND
                       objptr + 1 AND objptr + 1);
        PDF_PRINTF(">>\nstream\n");
    }
    for (k = 0; k < FONT_KEYS_NUM; k++)
        font_keys[k].valid = false;
    font_file_not_found = false;
    if (is_truetype())
        writettf();
    else
        writet1();
    if (is_included() && !font_file_not_found) {
        if (!is_truetype()) {
            PDF_PRINTF("endstream\nendobj\n");
            pdfnewobj(0, 0);
            PDF_PRINTF("%i\nendobj\n" AND t1_length1 + t1_length2 + t1_length3);
            pdfnewobj(0, 0);
            PDF_PRINTF("%i\nendobj\n" AND t1_length1);
            pdfnewobj(0, 0);
            PDF_PRINTF("%i\nendobj\n" AND t1_length2);
            pdfnewobj(0, 0);
            PDF_PRINTF("%i\nendobj\n" AND t1_length3);
        }
        else {
            PDF_PRINTF("endstream\nendobj\n");
            pdfnewobj(0, 0);
            PDF_PRINTF("%i\nendobj\n" AND ttf_length);
        }
    }
    if (!font_keys[FONTNAME_CODE].valid)
        WARN("cannot read key `%s' from font file\nused value from map file" AND
             font_keys[FONTNAME_CODE].pdfname);
    else if (strcmp(font_keys[FONTNAME_CODE].value.s, fm_cur->base_name))
        WARN("Base font name mismatch: `%s' (in font file) and  `%s' (in map file)!\nThe name specified in map file was ignored"
             AND font_keys[FONTNAME_CODE].value.s 
             AND fm_cur->base_name);
    pdfnewobj(0, 0); /* font base name */
    PDF_PRINTF("/");
    if (fm_cur->prefix)
        PDF_PRINTF("%s+" AND fm_cur->prefix);
    if (font_keys[FONTNAME_CODE].valid) {
        PDF_PRINTF("%s" AND font_keys[FONTNAME_CODE].value.s);
        XFREE(font_keys[FONTNAME_CODE].value.s);
    }
    else
        PDF_PRINTF("%s" AND fm_cur->base_name);
    PDF_PRINTF("\nendobj\n");
    pdfnewdict(0, 0); /* font descriptor */
    print_key(ASCENT_CODE, getcharheight(tex_font, 'h'));
    print_key(CAPHEIGHT_CODE, getcharheight(tex_font, 'H'));
    print_key(DESCENT_CODE, -getchardepth(tex_font, 'q'));
    PDF_PRINTF("/FontName %i 0 R\n" AND objptr - 1);
    print_key(ITALIC_ANGLE_CODE, getitalicangle(tex_font));
    print_key(STEMV_CODE, getstemv(tex_font));
    print_key(XHEIGHT_CODE, getxheight(tex_font));
    if (!font_keys[FONTBBOX1_CODE].valid) {
        /*
        WARN("cannot read key `%s' from font file\nused value from %s.tfm"
             AND font_keys[FONTBBOX1_CODE].pdfname
             AND makecstring(fontname[tex_font]));
        */
        getbbox(tex_font);
    }
    PDF_PRINTF("/%s [ %i %i %i %i ]\n" AND font_keys[FONTBBOX1_CODE].pdfname
               AND font_keys[FONTBBOX1_CODE].value.i
               AND font_keys[FONTBBOX2_CODE].value.i
               AND font_keys[FONTBBOX3_CODE].value.i
               AND font_keys[FONTBBOX4_CODE].value.i);
    PDF_PRINTF("/Flags 00000%u\n" AND fm_cur->flags);
    if (is_subsetted() && !font_file_not_found) {
        PDF_PRINTF("/CharSet (");
        for (k = 0; k < MAX_CHAR_NUM; k++)
            if (pdfischarused(tex_font, k) && cur_glyph_names[k] != notdef)
                PDF_PRINTF("/%s" AND cur_glyph_names[k]);
        PDF_PRINTF(")\n");
        if (cur_glyph_names == builtin_glyph_names)
            for (k = 0; k < MAX_CHAR_NUM; k++)
                if (cur_glyph_names[k] != notdef)
                    XFREE(cur_glyph_names[k]);
    }
    if (is_included() && !font_file_not_found) 
        if (is_truetype())
            PDF_PRINTF("/FontFile2 %i 0 R\n" AND objptr - 3);
        else
            PDF_PRINTF("/FontFile %i 0 R\n" AND objptr - 6);
    PDF_PRINTF(">> endobj\n");
}
