Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 650 git-svn-id: svn://10.65.10.50/trunk@14148 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			784 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			784 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*---------------------------------------------------------------------------*
 | 
						|
 |              PDFlib - A library for generating PDF on the fly             |
 | 
						|
 +---------------------------------------------------------------------------+
 | 
						|
 | Copyright (c) 1997-2005 Thomas Merz and PDFlib GmbH. All rights reserved. |
 | 
						|
 +---------------------------------------------------------------------------+
 | 
						|
 |                                                                           |
 | 
						|
 |    This software is subject to the PDFlib license. It is NOT in the       |
 | 
						|
 |    public domain. Extended versions and commercial licenses are           |
 | 
						|
 |    available, please check http://www.pdflib.com.                         |
 | 
						|
 |                                                                           |
 | 
						|
 *---------------------------------------------------------------------------*/
 | 
						|
 | 
						|
/* $Id: p_afm.c,v 1.2 2006-07-11 13:10:33 alex Exp $
 | 
						|
 *
 | 
						|
 * PDFlib AFM parsing routines
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#include "p_intern.h"
 | 
						|
#include "p_font.h"
 | 
						|
 | 
						|
#define AFM_LINEBUF       4096
 | 
						|
 | 
						|
#define AFM_SEPARATORS    "\f\n\r\t\v ,:;"
 | 
						|
 | 
						|
#define AFM_MINNUMGLYPHS  5
 | 
						|
 | 
						|
/* The values of each of these enumerated items correspond to an entry in the
 | 
						|
 * table of strings defined below. Therefore, if you add a new string as
 | 
						|
 * new keyword into the keyStrings table, you must also add a corresponding
 | 
						|
 * pdf_afmkey AND it MUST be in the same position!
 | 
						|
 *
 | 
						|
 * IMPORTANT: since the sorting algorithm is a binary search, the strings of
 | 
						|
 * keywords must be placed in lexicographical order, below. [Therefore, the
 | 
						|
 * enumerated items are not necessarily in lexicographical order, depending
 | 
						|
 * on the name chosen. BUT, they must be placed in the same position as the
 | 
						|
 * corresponding key string.] The NOPE shall remain in the last position,
 | 
						|
 * since it does not correspond to any key string.
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef PDFLIB_EBCDIC
 | 
						|
typedef enum
 | 
						|
{
 | 
						|
    ASCENDER,
 | 
						|
    CHARBBOX,
 | 
						|
    CODE,
 | 
						|
    COMPCHAR,
 | 
						|
    CODEHEX,
 | 
						|
    CAPHEIGHT,
 | 
						|
    CHARWIDTH,
 | 
						|
    CHARACTERSET,
 | 
						|
    CHARACTERS,
 | 
						|
    COMMENT,
 | 
						|
    DESCENDER,
 | 
						|
    ENCODINGSCHEME,
 | 
						|
    ENDCHARMETRICS,
 | 
						|
    ENDCOMPOSITES,
 | 
						|
    ENDDIRECTION,
 | 
						|
    ENDFONTMETRICS,
 | 
						|
    ENDKERNDATA,
 | 
						|
    ENDKERNPAIRS,
 | 
						|
    ENDKERNPAIRS0,
 | 
						|
    ENDKERNPAIRS1,
 | 
						|
    ENDMASTERFONTMETRICS,
 | 
						|
    ENDTRACKKERN,
 | 
						|
    ESCCHAR,
 | 
						|
    FAMILYNAME,
 | 
						|
    FONTBBOX,
 | 
						|
    FONTNAME,
 | 
						|
    FULLNAME,
 | 
						|
    ISBASEFONT,
 | 
						|
    ISCIDFONT,
 | 
						|
    ISFIXEDPITCH,
 | 
						|
    ISFIXEDV,
 | 
						|
    ITALICANGLE,
 | 
						|
    KERNPAIR,
 | 
						|
    KERNPAIRHAMT,
 | 
						|
    KERNPAIRXAMT,
 | 
						|
    KERNPAIRYAMT,
 | 
						|
    LIGATURE,
 | 
						|
    MAPPINGSCHEME,
 | 
						|
    METRICSSETS,
 | 
						|
    CHARNAME,
 | 
						|
    NOTICE,
 | 
						|
    COMPCHARPIECE,
 | 
						|
    STARTCHARMETRICS,
 | 
						|
    STARTCOMPFONTMETRICS,
 | 
						|
    STARTCOMPOSITES,
 | 
						|
    STARTDIRECTION,
 | 
						|
    STARTFONTMETRICS,
 | 
						|
    STARTKERNDATA,
 | 
						|
    STARTKERNPAIRS,
 | 
						|
    STARTKERNPAIRS0,
 | 
						|
    STARTKERNPAIRS1,
 | 
						|
    STARTMASTERFONTMETRICS,
 | 
						|
    STARTTRACKKERN,
 | 
						|
    STDHW,
 | 
						|
    STDVW,
 | 
						|
    TRACKKERN,
 | 
						|
    UNDERLINEPOSITION,
 | 
						|
    UNDERLINETHICKNESS,
 | 
						|
    VVECTOR,
 | 
						|
    VERSION,
 | 
						|
    XYWIDTH,
 | 
						|
    XY0WIDTH,
 | 
						|
    X0WIDTH,
 | 
						|
    Y0WIDTH,
 | 
						|
    XY1WIDTH,
 | 
						|
    X1WIDTH,
 | 
						|
    Y1WIDTH,
 | 
						|
    XWIDTH,
 | 
						|
    YWIDTH,
 | 
						|
    WEIGHT,
 | 
						|
    XHEIGHT,
 | 
						|
    NOPE
 | 
						|
}
 | 
						|
pdf_afmkey;
 | 
						|
 | 
						|
/* keywords for the system:
 | 
						|
 * This a table of all of the current strings that are vaild AFM keys.
 | 
						|
 * Each entry can be referenced by the appropriate pdf_afmkey value (an
 | 
						|
 * enumerated data type defined above). If you add a new keyword here,
 | 
						|
 * a corresponding pdf_afmkey MUST be added to the enumerated data type
 | 
						|
 * defined above, AND it MUST be added in the same position as the
 | 
						|
 * string is in this table.
 | 
						|
 *
 | 
						|
 * IMPORTANT: since the sorting algorithm is a binary search, the keywords
 | 
						|
 * must be placed in lexicographical order. And, NULL should remain at the
 | 
						|
 * end.
 | 
						|
 */
 | 
						|
 | 
						|
static const char *keyStrings[] =
 | 
						|
{
 | 
						|
    "Ascender",
 | 
						|
    "B",
 | 
						|
    "C",
 | 
						|
    "CC",
 | 
						|
    "CH",
 | 
						|
    "CapHeight",
 | 
						|
    "CharWidth",
 | 
						|
    "CharacterSet",
 | 
						|
    "Characters",
 | 
						|
    "Comment",
 | 
						|
    "Descender",
 | 
						|
    "EncodingScheme",
 | 
						|
    "EndCharMetrics",
 | 
						|
    "EndComposites",
 | 
						|
    "EndDirection",
 | 
						|
    "EndFontMetrics",
 | 
						|
    "EndKernData",
 | 
						|
    "EndKernPairs",
 | 
						|
    "EndKernPairs0",
 | 
						|
    "EndKernPairs1",
 | 
						|
    "EndMasterFontMetrics",
 | 
						|
    "EndTrackKern",
 | 
						|
    "EscChar",
 | 
						|
    "FamilyName",
 | 
						|
    "FontBBox",
 | 
						|
    "FontName",
 | 
						|
    "FullName",
 | 
						|
    "IsBaseFont",
 | 
						|
    "IsCIDFont",
 | 
						|
    "IsFixedPitch",
 | 
						|
    "IsFixedV",
 | 
						|
    "ItalicAngle",
 | 
						|
    "KP",
 | 
						|
    "KPH",
 | 
						|
    "KPX",
 | 
						|
    "KPY",
 | 
						|
    "L",
 | 
						|
    "MappingScheme",
 | 
						|
    "MetricsSets",
 | 
						|
    "N",
 | 
						|
    "Notice",
 | 
						|
    "PCC",
 | 
						|
    "StartCharMetrics",
 | 
						|
    "StartCompFontMetrics",
 | 
						|
    "StartComposites",
 | 
						|
    "StartDirection",
 | 
						|
    "StartFontMetrics",
 | 
						|
    "StartKernData",
 | 
						|
    "StartKernPairs",
 | 
						|
    "StartKernPairs0",
 | 
						|
    "StartKernPairs1",
 | 
						|
    "StartMasterFontMetrics",
 | 
						|
    "StartTrackKern",
 | 
						|
    "StdHW",
 | 
						|
    "StdVW",
 | 
						|
    "TrackKern",
 | 
						|
    "UnderlinePosition",
 | 
						|
    "UnderlineThickness",
 | 
						|
    "VVector",
 | 
						|
    "Version",
 | 
						|
    "W",
 | 
						|
    "W0",
 | 
						|
    "W0X",
 | 
						|
    "W0Y",
 | 
						|
    "W1",
 | 
						|
    "W1X",
 | 
						|
    "W1Y",
 | 
						|
    "WX",
 | 
						|
    "WY",
 | 
						|
    "Weight",
 | 
						|
    "XHeight"
 | 
						|
};
 | 
						|
 | 
						|
#else   /* !PDFLIB_EBCDIC */
 | 
						|
#endif  /* PDFLIB_EBCDIC */
 | 
						|
 | 
						|
static pdc_bool
 | 
						|
pdf_parse_afm(
 | 
						|
    PDF *p,
 | 
						|
    pdc_file *fp,
 | 
						|
    pdc_font *font,
 | 
						|
    const char *fontname,
 | 
						|
    const char *filename)
 | 
						|
{
 | 
						|
    static const char fn[] = "pdf_parse_afm";
 | 
						|
    const char *afmtype = NULL;
 | 
						|
    char **wordlist, *keyword, *arg1;
 | 
						|
    char line[AFM_LINEBUF];
 | 
						|
    int i, cmp, lo, hi, nwords, nglyphs = 0, nline = 0;
 | 
						|
    int tablen = ((sizeof keyStrings) / (sizeof (char *)));
 | 
						|
    pdc_sint32 iz;
 | 
						|
    double dz;
 | 
						|
    pdc_scalar charwidth = -1;
 | 
						|
    pdf_afmkey keynumber;
 | 
						|
    pdc_glyphwidth *glw;
 | 
						|
    pdc_bool toskip = pdc_false;
 | 
						|
    pdc_bool is_zadbfont = !strcmp(fontname, "ZapfDingbats");
 | 
						|
 | 
						|
 | 
						|
    /* all new glyph names of AGL 2.0 are missing */
 | 
						|
    font->missingglyphs = 0xFFFFFFFF;
 | 
						|
 | 
						|
    /* read loop. because of Mac files we use pdc_fgetline */
 | 
						|
    while (pdc_fgetline(line, AFM_LINEBUF, fp) != NULL)
 | 
						|
    {
 | 
						|
        /* split line */
 | 
						|
        nline++;
 | 
						|
        nwords = pdc_split_stringlist(p->pdc, line, AFM_SEPARATORS, &wordlist);
 | 
						|
        if (!nwords) continue;
 | 
						|
        keyword = wordlist[0];
 | 
						|
 | 
						|
        /* find keynumber */
 | 
						|
        lo = 0;
 | 
						|
        hi = tablen;
 | 
						|
        keynumber = NOPE;
 | 
						|
        while (lo < hi)
 | 
						|
        {
 | 
						|
            i = (lo + hi) / 2;
 | 
						|
            cmp = strcmp(keyword, keyStrings[i]);
 | 
						|
 | 
						|
            if (cmp == 0)
 | 
						|
            {
 | 
						|
                keynumber = (pdf_afmkey) i;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
 | 
						|
            if (cmp < 0)
 | 
						|
                hi = i;
 | 
						|
            else
 | 
						|
                lo = i + 1;
 | 
						|
        }
 | 
						|
 | 
						|
        /* unkown key */
 | 
						|
        if (keynumber == NOPE)
 | 
						|
        {
 | 
						|
            if (font->verbose == pdc_true)
 | 
						|
                pdc_warning(p->pdc, PDF_E_T1_AFMBADKEY, keyword, filename, 0,0);
 | 
						|
 | 
						|
            goto PDF_PARSECONTD;
 | 
						|
        }
 | 
						|
        if (keynumber == ENDDIRECTION)
 | 
						|
            toskip = pdc_false;
 | 
						|
 | 
						|
        if (nwords == 1 || toskip == pdc_true)
 | 
						|
            goto PDF_PARSECONTD;
 | 
						|
 | 
						|
        /* key switch */
 | 
						|
        arg1 = wordlist[1];
 | 
						|
        switch (keynumber)
 | 
						|
        {
 | 
						|
            case STARTDIRECTION:
 | 
						|
            if (pdc_str2integer(arg1, 0, &iz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            if (iz)
 | 
						|
                toskip = pdc_true;
 | 
						|
            break;
 | 
						|
 | 
						|
            case STARTCOMPFONTMETRICS:
 | 
						|
            afmtype = "ACFM";
 | 
						|
            goto PDF_SYNTAXERROR;
 | 
						|
 | 
						|
            case STARTMASTERFONTMETRICS:
 | 
						|
            afmtype = "AMFM";
 | 
						|
            goto PDF_SYNTAXERROR;
 | 
						|
 | 
						|
            case ISCIDFONT:
 | 
						|
            afmtype = "CID font";
 | 
						|
            if (!strcmp(arg1, "true"))
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            break;
 | 
						|
 | 
						|
            case FONTNAME:
 | 
						|
            font->name = pdc_strdup(p->pdc, arg1);
 | 
						|
            pdc_trace_protocol(p->pdc, 1, trc_font,
 | 
						|
                "\tPostScript fontname: \"%s\"\n", font->name);
 | 
						|
            break;
 | 
						|
 | 
						|
            /* Recognize Multiple Master fonts by last part of name */
 | 
						|
            case FAMILYNAME:
 | 
						|
            if (!strcmp(wordlist[nwords-1], "MM"))
 | 
						|
                font->type = pdc_MMType1;
 | 
						|
            break;
 | 
						|
 | 
						|
            /* Default: FontSpecific */
 | 
						|
            case ENCODINGSCHEME:
 | 
						|
            if (!pdc_stricmp(arg1, "StandardEncoding") ||
 | 
						|
                !pdc_stricmp(arg1, "AdobeStandardEncoding"))
 | 
						|
                font->isstdlatin = pdc_true ;
 | 
						|
            break;
 | 
						|
 | 
						|
            case STDHW:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->StdHW = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            case STDVW:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->StdVW = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            /* If we don't know StdVW we guess it from the font weight */
 | 
						|
            case WEIGHT:
 | 
						|
            if (font->StdVW == 0)
 | 
						|
            {
 | 
						|
                if (!pdc_stricmp(arg1, "Light"))
 | 
						|
                    font->StdVW = PDF_STEMV_LIGHT;
 | 
						|
                else if (!pdc_stricmp(arg1, "Medium"))
 | 
						|
                    font->StdVW = PDF_STEMV_MEDIUM;
 | 
						|
                else if (!pdc_stricmp(arg1, "Semi") ||
 | 
						|
                         !pdc_stricmp(arg1, "SemiBold"))
 | 
						|
                    font->StdVW = PDF_STEMV_SEMIBOLD;
 | 
						|
                else if (!pdc_stricmp(arg1, "Bold"))
 | 
						|
                    font->StdVW = PDF_STEMV_BOLD;
 | 
						|
                else if (!pdc_stricmp(arg1, "Extra") ||
 | 
						|
                         !pdc_stricmp(arg1, "ExtraBold"))
 | 
						|
                    font->StdVW = PDF_STEMV_EXTRABOLD;
 | 
						|
                else if (!pdc_stricmp(arg1, "Black"))
 | 
						|
                    font->StdVW = PDF_STEMV_BLACK;
 | 
						|
                else
 | 
						|
                    font->StdVW = PDF_STEMV_NORMAL;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
 | 
						|
            case ISFIXEDPITCH:
 | 
						|
            if (!pdc_stricmp(arg1, "false"))
 | 
						|
                font->isFixedPitch = pdc_false;
 | 
						|
            else
 | 
						|
                font->isFixedPitch = pdc_true;
 | 
						|
            break;
 | 
						|
 | 
						|
            /* New AFM 4.1 keyword "CharWidth" implies fixed pitch */
 | 
						|
            case CHARWIDTH:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            charwidth = dz;
 | 
						|
            font->isFixedPitch = pdc_true;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ITALICANGLE:
 | 
						|
            {
 | 
						|
                if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                    goto PDF_SYNTAXERROR;
 | 
						|
                font->italicAngle = dz;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
 | 
						|
            case UNDERLINEPOSITION:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->underlinePosition = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            case UNDERLINETHICKNESS:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->underlineThickness = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            case FONTBBOX:
 | 
						|
            {
 | 
						|
                if (nwords != 5)
 | 
						|
                    goto PDF_SYNTAXERROR;
 | 
						|
                for (i = 1; i < nwords; i++)
 | 
						|
                {
 | 
						|
                    if (pdc_str2double(wordlist[i], &dz) != pdc_true)
 | 
						|
                        goto PDF_SYNTAXERROR;
 | 
						|
                    if (i == 1)
 | 
						|
                        font->llx = dz;
 | 
						|
                    else if (i == 2)
 | 
						|
                        font->lly = dz;
 | 
						|
                    else if (i == 3)
 | 
						|
                        font->urx = dz;
 | 
						|
                    else if (i == 4)
 | 
						|
                        font->ury = dz;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
 | 
						|
            case CAPHEIGHT:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->capHeight = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            case XHEIGHT:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->xHeight = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            case DESCENDER:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->descender = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ASCENDER:
 | 
						|
            if (pdc_str2double(arg1, &dz) != pdc_true)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->ascender = (int) dz;
 | 
						|
            break;
 | 
						|
 | 
						|
            /* Character widths */
 | 
						|
 | 
						|
            case STARTCHARMETRICS:
 | 
						|
            if (pdc_str2integer(arg1, PDC_INT_UNSIGNED, (pdc_sint32 *) &nglyphs)
 | 
						|
                != pdc_true || nglyphs <= 0)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            font->glw = (pdc_glyphwidth *) pdc_calloc(p->pdc,
 | 
						|
                            (size_t) nglyphs * sizeof(pdc_glyphwidth), fn);
 | 
						|
            break;
 | 
						|
 | 
						|
            /* Character code */
 | 
						|
            case CODE:
 | 
						|
            case CODEHEX:
 | 
						|
            if (!nglyphs || !font->glw)
 | 
						|
                goto PDF_SYNTAXERROR;
 | 
						|
            if (font->numOfGlyphs >= nglyphs)
 | 
						|
            {
 | 
						|
                nglyphs++;
 | 
						|
                font->glw = (pdc_glyphwidth *) pdc_realloc(p->pdc, font->glw,
 | 
						|
                                (size_t) nglyphs * sizeof(pdc_glyphwidth), fn);
 | 
						|
            }
 | 
						|
            glw = &font->glw[font->numOfGlyphs];
 | 
						|
            if (keynumber == CODE)
 | 
						|
            {
 | 
						|
                if (pdc_str2integer(arg1, 0, &iz) != pdc_true)
 | 
						|
                    goto PDF_SYNTAXERROR;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (pdc_str2integer(arg1, PDC_INT_HEXADEC, &iz) != pdc_true)
 | 
						|
                    goto PDF_SYNTAXERROR;
 | 
						|
            }
 | 
						|
            glw->code = (pdc_short) iz;
 | 
						|
            glw->unicode = 0;
 | 
						|
            glw->width = (pdc_ushort)
 | 
						|
                (font->monospace ? font->monospace : charwidth);
 | 
						|
            font->numOfGlyphs++;
 | 
						|
 | 
						|
            /* Character width and name */
 | 
						|
            for (i = 2; i < nwords; i++)
 | 
						|
            {
 | 
						|
                if (!strcmp(wordlist[i], "WX") ||
 | 
						|
                    !strcmp(wordlist[i], "W0X") ||
 | 
						|
                    !strcmp(wordlist[i], "W"))
 | 
						|
                {
 | 
						|
                    i++;
 | 
						|
                    if (i == nwords)
 | 
						|
                        goto PDF_SYNTAXERROR;
 | 
						|
                    if (pdc_str2double(wordlist[i], &dz) != pdc_true)
 | 
						|
                        goto PDF_SYNTAXERROR;
 | 
						|
                    glw->width = (pdc_ushort)
 | 
						|
                         (font->monospace ? font->monospace : dz);
 | 
						|
                }
 | 
						|
 | 
						|
                if (!strcmp(wordlist[i], "N"))
 | 
						|
                {
 | 
						|
                    i++;
 | 
						|
                    if (i == nwords)
 | 
						|
                        goto PDF_SYNTAXERROR;
 | 
						|
                    glw->unicode = is_zadbfont ?
 | 
						|
                                     (pdc_ushort) pdc_zadb2unicode(wordlist[i]):
 | 
						|
                                      pdc_insert_glyphname(p->pdc, wordlist[i]);
 | 
						|
                    pdc_delete_missingglyph_bit(glw->unicode,
 | 
						|
                                                &font->missingglyphs);
 | 
						|
 | 
						|
                    pdc_trace_protocol(p->pdc, 2, trc_font,
 | 
						|
                        "\t\tGlyph%4d: Code=%3d  U+%04X  Width=%4d  \"%s\"\n",
 | 
						|
                        font->numOfGlyphs, glw->code, glw->unicode,
 | 
						|
                        glw->width, wordlist[i]);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
 | 
						|
 | 
						|
            default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        PDF_PARSECONTD:
 | 
						|
        pdc_cleanup_stringlist(p->pdc, wordlist);
 | 
						|
        wordlist = NULL;
 | 
						|
 | 
						|
        if (keynumber == ENDFONTMETRICS)
 | 
						|
            break;
 | 
						|
    }
 | 
						|
 | 
						|
    /* necessary font struct members */
 | 
						|
    if (font->name == NULL || font->glw == NULL)
 | 
						|
        goto PDF_SYNTAXERROR;
 | 
						|
 | 
						|
    pdf_font_set_missvalues(p, font);
 | 
						|
 | 
						|
    pdc_fclose(fp);
 | 
						|
    return pdc_true;
 | 
						|
 | 
						|
    PDF_SYNTAXERROR:
 | 
						|
    pdc_fclose(fp);
 | 
						|
    pdc_cleanup_stringlist(p->pdc, wordlist);
 | 
						|
 | 
						|
    if (afmtype)
 | 
						|
        pdc_set_errmsg(p->pdc, PDF_E_T1_UNSUPP_FORMAT, afmtype, 0, 0, 0);
 | 
						|
    else
 | 
						|
        pdc_set_errmsg(p->pdc, PDC_E_IO_ILLSYNTAX, "AFM ", filename,
 | 
						|
                       pdc_errprintf(p->pdc, "%d", nline), 0);
 | 
						|
 | 
						|
    if (font->verbose == pdc_true)
 | 
						|
        pdc_error(p->pdc, -1, 0, 0, 0, 0);
 | 
						|
 | 
						|
    return pdc_false;
 | 
						|
}
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdf_process_metrics_data(
 | 
						|
    PDF *p,
 | 
						|
    pdc_font *font,
 | 
						|
    const char *fontname)
 | 
						|
{
 | 
						|
    static const char fn[] = "pdf_process_metrics_data";
 | 
						|
    int *widths;
 | 
						|
    pdc_ushort uv;
 | 
						|
    pdc_encoding enc = font->encoding;
 | 
						|
    pdc_encodingvector *ev = NULL;
 | 
						|
    int foundChars = 0, tofree = 0, i, k;
 | 
						|
 | 
						|
    /* Unallowed encoding */
 | 
						|
    if (enc == pdc_cid || enc < pdc_builtin) {
 | 
						|
 | 
						|
	pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC,
 | 
						|
	    fontname, pdf_get_encoding_name(p, enc, font), 0, 0);
 | 
						|
 | 
						|
        if (font->verbose == pdc_true)
 | 
						|
	    pdc_error(p->pdc, -1, 0, 0, 0, 0);
 | 
						|
 | 
						|
        return pdc_false;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Determine the default character width (width of space character) */
 | 
						|
    if (font->monospace)
 | 
						|
    {
 | 
						|
        font->defWidth = font->monospace;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        font->defWidth = PDF_DEFAULT_WIDTH;
 | 
						|
        for (i = 0; i < font->numOfGlyphs; i++)
 | 
						|
        {
 | 
						|
            if (font->glw[i].unicode == PDF_DEFAULT_GLYPH)
 | 
						|
            {
 | 
						|
                font->defWidth = (int) font->glw[i].width;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* builtin font */
 | 
						|
    if (font->isstdlatin == pdc_false && enc != pdc_builtin &&
 | 
						|
        !strcmp(font->encapiname, "auto"))
 | 
						|
    {
 | 
						|
        enc = pdc_builtin;
 | 
						|
        font->encoding = enc;
 | 
						|
    }
 | 
						|
 | 
						|
    /* optimizing PDF output */
 | 
						|
    if (enc == pdc_ebcdic || enc == pdc_ebcdic_37)
 | 
						|
        font->towinansi = pdc_winansi;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Generate character width according to the chosen encoding
 | 
						|
     */
 | 
						|
 | 
						|
    {
 | 
						|
        font->code2GID = (pdc_ushort *) pdc_calloc(p->pdc,
 | 
						|
                                   font->numOfCodes  * sizeof (pdc_ushort), fn);
 | 
						|
        font->widths = (int *) pdc_calloc(p->pdc,
 | 
						|
                                   font->numOfCodes * sizeof(int), fn);
 | 
						|
        widths = font->widths;
 | 
						|
 | 
						|
        /* Given encoding */
 | 
						|
        if (enc >= 0 && enc < p->encodings_number)
 | 
						|
        {
 | 
						|
            ev = pdf_get_encoding_vector(p, enc);
 | 
						|
            for (k = 0; k < font->numOfCodes; k++)
 | 
						|
            {
 | 
						|
                uv = ev->codes[k];
 | 
						|
                widths[k] = font->defWidth;
 | 
						|
                if (uv == 0x0000)
 | 
						|
                    continue;
 | 
						|
 | 
						|
                uv = pdc_get_alter_glyphname(uv, font->missingglyphs, NULL);
 | 
						|
                if (uv)
 | 
						|
                {
 | 
						|
                    for (i = 0; i < font->numOfGlyphs; i++)
 | 
						|
                    {
 | 
						|
                        if (font->glw[i].unicode == uv)
 | 
						|
                        {
 | 
						|
                            widths[k] = font->glw[i].width;
 | 
						|
                            font->code2GID[k] = 1;
 | 
						|
                            foundChars++;
 | 
						|
                            break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            /* No characters found and lex Symbolii */
 | 
						|
            if (foundChars < AFM_MINNUMGLYPHS ||
 | 
						|
                (!strcmp(fontname, "Symbol") && enc == pdc_winansi))
 | 
						|
            {
 | 
						|
                if (font->isstdlatin == pdc_true)
 | 
						|
                {
 | 
						|
                    pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC,
 | 
						|
                        fontname, pdf_get_encoding_name(p, enc, font),
 | 
						|
                        0, 0);
 | 
						|
 | 
						|
                    if (font->verbose)
 | 
						|
                        pdc_error(p->pdc, -1, 0, 0, 0, 0);
 | 
						|
 | 
						|
                    return pdc_false;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    /* We enforce builtin encoding */
 | 
						|
                    if (font->verbose && strcmp(font->encapiname, "auto"))
 | 
						|
                        pdc_warning(p->pdc, PDF_E_FONT_FORCEENC,
 | 
						|
                            pdf_get_encoding_name(p, pdc_builtin, font),
 | 
						|
                            pdf_get_encoding_name(p, enc, font), fontname,
 | 
						|
                            0);
 | 
						|
                    enc = pdc_builtin;
 | 
						|
                    font->encoding = enc;
 | 
						|
                    font->towinansi = pdc_invalidenc;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* built-in encoding */
 | 
						|
        if (enc == pdc_builtin)
 | 
						|
        {
 | 
						|
            if (font->glw == NULL)
 | 
						|
            {
 | 
						|
                pdc_set_errmsg(p->pdc, PDF_E_FONT_BADENC,
 | 
						|
                    fontname, pdf_get_encoding_name(p, enc, font), 0, 0);
 | 
						|
 | 
						|
                if (font->verbose)
 | 
						|
                    pdc_error(p->pdc, -1, 0, 0, 0, 0);
 | 
						|
 | 
						|
                return pdc_false;
 | 
						|
            }
 | 
						|
 | 
						|
            /* temporary encoding */
 | 
						|
            ev = (pdc_encodingvector *)
 | 
						|
                     pdc_malloc(p->pdc, sizeof(pdc_encodingvector), fn);
 | 
						|
            pdc_init_encoding(p->pdc, ev, "");
 | 
						|
            tofree = 1;
 | 
						|
            for (i = 0; i < font->numOfCodes; i++)
 | 
						|
            {
 | 
						|
                widths[i] = font->defWidth;
 | 
						|
                ev->codes[i] = PDF_DEFAULT_GLYPH;
 | 
						|
            }
 | 
						|
            for (i = 0; i < font->numOfGlyphs; i++)
 | 
						|
            {
 | 
						|
                pdc_short code = font->glw[i].code;
 | 
						|
 | 
						|
                if (code >= 0 && code < font->numOfCodes)
 | 
						|
                {
 | 
						|
                    widths[code] = font->glw[i].width;
 | 
						|
                    ev->codes[code] = font->glw[i].unicode;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    if (tofree) pdc_cleanup_encoding(p->pdc, ev);
 | 
						|
 | 
						|
    if (font->glw != NULL)
 | 
						|
    {
 | 
						|
        pdc_free(p->pdc, font->glw);
 | 
						|
        font->glw = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    return pdc_true;
 | 
						|
}
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdf_get_metrics_afm(
 | 
						|
    PDF *p,
 | 
						|
    pdc_font *font,
 | 
						|
    const char *fontname,
 | 
						|
    pdc_encoding enc,
 | 
						|
    const char *filename)
 | 
						|
{
 | 
						|
    char fullname[PDC_FILENAMELEN];
 | 
						|
    pdc_file *afmfile;
 | 
						|
 | 
						|
    /* open AFM file */
 | 
						|
    if ((afmfile = pdf_fopen_name(p, filename, fullname, "AFM ", 0)) == NULL)
 | 
						|
    {
 | 
						|
	if (font->verbose_open)
 | 
						|
	    pdc_error(p->pdc, -1, 0, 0, 0, 0);
 | 
						|
 | 
						|
        return pdc_undef;
 | 
						|
    }
 | 
						|
 | 
						|
    pdc_trace_protocol(p->pdc, 1, trc_font,
 | 
						|
        "\tLoading AFM metric fontfile \"%s\":\n", fullname);
 | 
						|
 | 
						|
    /* parse AFM file */
 | 
						|
    if (pdf_parse_afm(p, afmfile, font, fontname, fullname) == pdc_false)
 | 
						|
        return pdc_false;
 | 
						|
 | 
						|
    /* process metric data */
 | 
						|
    font->encoding = enc;
 | 
						|
    if (pdf_process_metrics_data(p, font, fontname) == pdc_false)
 | 
						|
        return pdc_false;
 | 
						|
 | 
						|
    if (!pdf_make_fontflag(p, font))
 | 
						|
        return pdc_false;
 | 
						|
 | 
						|
    return pdc_true;
 | 
						|
}
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdf_get_core_metrics_afm(
 | 
						|
    PDF *p,
 | 
						|
    pdc_font *font,
 | 
						|
    pdc_core_metric *metric,
 | 
						|
    const char *fontname,
 | 
						|
    const char *filename)
 | 
						|
{
 | 
						|
    pdc_file *afmfile;
 | 
						|
 | 
						|
    /* open AFM file */
 | 
						|
    if ((afmfile = pdf_fopen(p, filename, "AFM ", 0)) == NULL)
 | 
						|
	pdc_error(p->pdc, -1, 0, 0, 0, 0);
 | 
						|
 | 
						|
    /* parse AFM file */
 | 
						|
    if (pdf_parse_afm(p, afmfile, font, fontname, filename) == pdc_false)
 | 
						|
        return pdc_false;
 | 
						|
 | 
						|
    /* process metric data */
 | 
						|
    font->encoding = pdc_invalidenc;
 | 
						|
    pdc_fill_core_metric(p->pdc, font, metric);
 | 
						|
 | 
						|
    return pdc_true;
 | 
						|
}
 | 
						|
 |