/*
** This is the central routine of this section.
*/
void ttfont_CharStrings(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids)
    {
    Fixed post_format;

    /* The 'post' table format number. */
    post_format = getFixed( font->post_table );

    if( post_format.whole != 2 || post_format.fraction != 0 )
        throw TTException("TrueType fontdoes not have a format 2.0 'post' table");

    /* Emmit the start of the PostScript code to define the dictionary. */
    stream.printf("/CharStrings %d dict dup begin\n", glyph_ids.size());

    /* Emmit one key-value pair for each glyph. */
    for(std::vector<int>::const_iterator i = glyph_ids.begin();
        i != glyph_ids.end(); ++i)
        {
        if(font->target_type == PS_TYPE_42)     /* type 42 */
            {
            stream.printf("/%s %d def\n",ttfont_CharStrings_getname(font, *i), *i);
            }
        else                            /* type 3 */
            {
            stream.printf("/%s{",ttfont_CharStrings_getname(font, *i));

            tt_type3_charproc(stream, font, *i);

            stream.putline("}_d");      /* "} bind def" */
            }
        }

    stream.putline("end readonly def");
    } /* end of ttfont_CharStrings() */
void get_pdf_charprocs(const char *filename, std::vector<int>& glyph_ids, TTDictionaryCallback& dict) {
    struct TTFONT font;

    read_font(filename, PDF_TYPE_3, glyph_ids, font);

    for (std::vector<int>::const_iterator i = glyph_ids.begin();
         i != glyph_ids.end(); ++i) {
        StringStreamWriter writer;
        tt_type3_charproc(writer, &font, *i);
        const char* name = ttfont_CharStrings_getname(&font, *i);
        dict.add_pair(name, writer.str().c_str());
    }
}
/*-------------------------------------------------------------
** Define the encoding array for this font.
** Since we don't really want to deal with converting all of
** the possible font encodings in the wild to a standard PS
** one, we just explicitly create one for each font.
-------------------------------------------------------------*/
void ttfont_encoding(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids, font_type_enum target_type)
{
    if (target_type == PS_TYPE_3 || target_type == PS_TYPE_42_3_HYBRID)
    {
        stream.printf("/Encoding [ ");

        for (std::vector<int>::const_iterator i = glyph_ids.begin();
                i != glyph_ids.end(); ++i)
        {
            const char* name = ttfont_CharStrings_getname(font, *i);
            stream.printf("/%s ", name);
        }

        stream.printf("] def\n");
    }
    else
    {
        stream.putline("/Encoding StandardEncoding def");
    }
} /* end of ttfont_encoding() */
/*
** Emmit PostScript code for a composite character.
*/
void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph)
{
    USHORT flags;
    USHORT glyphIndex;
    int arg1;
    int arg2;
    USHORT xscale;
    USHORT yscale;
    USHORT scale01;
    USHORT scale10;

    /* Once around this loop for each component. */
    do
    {
        flags = getUSHORT(glyph);       /* read the flags word */
        glyph += 2;

        glyphIndex = getUSHORT(glyph);  /* read the glyphindex word */
        glyph += 2;

        if (flags & ARG_1_AND_2_ARE_WORDS)
        {
            /* The tt spec. seems to say these are signed. */
            arg1 = getSHORT(glyph);
            glyph += 2;
            arg2 = getSHORT(glyph);
            glyph += 2;
        }
        else                    /* The tt spec. does not clearly indicate */
        {
            /* whether these values are signed or not. */
            arg1 = *(signed char *)(glyph++);
            arg2 = *(signed char *)(glyph++);
        }

        if (flags & WE_HAVE_A_SCALE)
        {
            xscale = yscale = getUSHORT(glyph);
            glyph += 2;
            scale01 = scale10 = 0;
        }
        else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
        {
            xscale = getUSHORT(glyph);
            glyph += 2;
            yscale = getUSHORT(glyph);
            glyph += 2;
            scale01 = scale10 = 0;
        }
        else if (flags & WE_HAVE_A_TWO_BY_TWO)
        {
            xscale = getUSHORT(glyph);
            glyph += 2;
            scale01 = getUSHORT(glyph);
            glyph += 2;
            scale10 = getUSHORT(glyph);
            glyph += 2;
            yscale = getUSHORT(glyph);
            glyph += 2;
        }
        else
        {
            xscale = yscale = scale01 = scale10 = 0;
        }

        /* Debugging */
#ifdef DEBUG_TRUETYPE
        stream.printf("%% flags=%d, arg1=%d, arg2=%d, xscale=%d, yscale=%d, scale01=%d, scale10=%d\n",
                      (int)flags,arg1,arg2,(int)xscale,(int)yscale,(int)scale01,(int)scale10);
#endif

        if (pdf_mode)
        {
            if ( flags & ARGS_ARE_XY_VALUES )
            {
                /* We should have been able to use 'Do' to reference the
                   subglyph here.  However, that doesn't seem to work with
                   xpdf or gs (only acrobat), so instead, this just includes
                   the subglyph here inline. */
                stream.printf("q 1 0 0 1 %d %d cm\n", topost(arg1), topost(arg2));
            }
            else
            {
                stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2);
            }
            GlyphToType3(stream, font, glyphIndex, true);
            if ( flags & ARGS_ARE_XY_VALUES )
            {
                stream.printf("\nQ\n");
            }
        }
        else
        {
            /* If we have an (X,Y) shif and it is non-zero, */
            /* translate the coordinate system. */
            if ( flags & ARGS_ARE_XY_VALUES )
            {
                if ( arg1 != 0 || arg2 != 0 )
                    stream.printf("gsave %d %d translate\n", topost(arg1), topost(arg2) );
            }
            else
            {
                stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2);
            }

            /* Invoke the CharStrings procedure to print the component. */
            stream.printf("false CharStrings /%s get exec\n",
                          ttfont_CharStrings_getname(font,glyphIndex));

            /* If we translated the coordinate system, */
            /* put it back the way it was. */
            if ( flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) )
            {
                stream.puts("grestore ");
            }
        }

    }
    while (flags & MORE_COMPONENTS);

} /* end of do_composite() */