Пример #1
0
/*******************************************************************************
 *  ReadCharMetrics
 *
 *  Reads metrics for each glyph in a TrueType font.  Returns false for memory
 *  allocation or FreeType error; sets *p_metrics to NULL for non-fatal error.
 *
 */
static BOOL ReadCharMetrics(FT_Face face, AFM *afm, AFMMETRICS **p_metrics)
{
    FT_ULong	charcode, index;
    AFMMETRICS	*metrics;
    USHORT  	em_size = afm->WinMetrics.usUnitsPerEm;

    for (charcode = 0, index = 0; charcode < 65536; ++charcode)
    	if (pFT_Get_Char_Index(face, charcode) != 0)
	    ++index;	    	    	    	    	/* count # of glyphs */

    afm->NumofMetrics = index;

    *p_metrics = metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(*metrics));
    if (metrics == NULL)
    	return FALSE;

    for (charcode = 0, index = 0; charcode < 65536; ++charcode)
    {
    	FT_UInt     glyph_index = pFT_Get_Char_Index(face, charcode);
	FT_Error    error;
	CHAR	    buffer[128];  	    	/* for glyph names */

	if (glyph_index == 0)
	    continue;

	error = pFT_Load_Glyph(face, glyph_index, GLYPH_LOAD_FLAGS);
	if (error != FT_Err_Ok)
	{
	    ERR("%s returned %i\n", "FT_Load_Glyph", error);
	    goto cleanup;
	}

	error = pFT_Get_Glyph_Name(face, glyph_index, buffer, sizeof(buffer));
	if (error != FT_Err_Ok)
	{
	    ERR("%s returned %i\n", "FT_Get_Glyph_Name", error);
	    goto cleanup;
    	}

	metrics[index].N = PSDRV_GlyphName(buffer);
	if (metrics[index].N == NULL)
	    goto cleanup;

	metrics[index].C = metrics[index].UV = charcode;
	metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance, em_size);

	++index;
    }

    if (afm->WinMetrics.sAvgCharWidth == 0)
    	afm->WinMetrics.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);

    return TRUE;

    cleanup:
    	HeapFree(PSDRV_Heap, 0, metrics);

    return FALSE;
}
Пример #2
0
static BOOL ReadCharMetrics(FILE *file, CHAR buffer[], INT bufsize, AFM *afm,
    	AFMMETRICS **p_metrics)
{
    BOOL    	    retval, found;
    OLD_AFMMETRICS  *old_metrics, *encoded_metrics;
    AFMMETRICS	    *metrics;
    INT     	    i, len;

    retval = ReadInt(file, buffer, bufsize, "StartCharMetrics",
    	    &(afm->NumofMetrics), &found);
    if (retval == FALSE || found == FALSE)
    {
    	*p_metrics = NULL;
	return retval;
    }

    old_metrics = HeapAlloc(PSDRV_Heap, 0,
    	    afm->NumofMetrics * sizeof(*old_metrics));
    if (old_metrics == NULL)
    	return FALSE;

    for (i = 0; i < afm->NumofMetrics; ++i)
    {
    	retval = ReadLine(file, buffer, bufsize, &len);
    	if (retval == FALSE)
	    goto cleanup_old_metrics;

	if(len > 0)
	{
	    retval = ParseCharMetrics(buffer, len, old_metrics + i);
	    if (retval == FALSE || old_metrics[i].C == INT_MAX)
	    	goto cleanup_old_metrics;

	    continue;
	}

	switch (len)
	{
	    case 0: 	    --i;
		    	    continue;

	    case INT_MIN:   WARN("Ignoring long line '%32s...'\n", buffer);
			    goto cleanup_old_metrics;	    /* retval == TRUE */

	    case EOF:	    WARN("Unexpected EOF\n");
	    	    	    goto cleanup_old_metrics;  	    /* retval == TRUE */
	}
    }

    Unicodify(afm, old_metrics);    /* wait until glyph names have been read */

    qsort(old_metrics, afm->NumofMetrics, sizeof(*old_metrics),
    	    OldAFMMetricsByUV);

    for (i = 0; old_metrics[i].UV == -1; ++i);      /* count unencoded glyphs */

    afm->NumofMetrics -= i;
    encoded_metrics = old_metrics + i;

    afm->Metrics = *p_metrics = metrics = HeapAlloc(PSDRV_Heap, 0,
    	    afm->NumofMetrics * sizeof(*metrics));
    if (afm->Metrics == NULL)
    	goto cleanup_old_metrics;   	    	    	    /* retval == TRUE */

    for (i = 0; i < afm->NumofMetrics; ++i, ++metrics, ++encoded_metrics)
    {
    	metrics->C = encoded_metrics->C;
	metrics->UV = encoded_metrics->UV;
	metrics->WX = encoded_metrics->WX;
	metrics->N = encoded_metrics->N;
    }

    HeapFree(PSDRV_Heap, 0, old_metrics);

    afm->WinMetrics.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);

    return TRUE;

    cleanup_old_metrics:    	    	/* handle fatal or non-fatal errors */
    	HeapFree(PSDRV_Heap, 0, old_metrics);
	*p_metrics = NULL;
	return retval;
}