/******************************************************************************* * ParseN * * Fatal error: return FALSE (PSDRV_GlyphName failure) * * Non-fatal error: leave metrics-> set to NULL * */ static BOOL ParseN(LPSTR sz, OLD_AFMMETRICS *metrics) { CHAR save, *cp, *end_ptr; cp = sz + 1; while (isspace(*cp)) ++cp; end_ptr = cp; while (*end_ptr != '\0' && !isspace(*end_ptr)) ++end_ptr; if (end_ptr == cp) { WARN("Error parsing glyph name '%s'\n", sz); return TRUE; } save = *end_ptr; *end_ptr = '\0'; metrics->N = PSDRV_GlyphName(cp); if (metrics->N == NULL) return FALSE; *end_ptr = save; return TRUE; }
/******************************************************************************* * 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; }