/* See LICENSE file for copyright and license details. */ #include "common.h" int libparsepcf_preparse_font(const void *file, size_t size, struct libparsepcf_font *font) { size_t min = SIZE_MAX, max = 0, table_i, table_n; struct libparsepcf_table *tables = NULL; *font = (struct libparsepcf_font){0}; if (libparsepcf_get_table_count(file, size, &table_n)) goto fail; tables = calloc(table_n, sizeof(*tables)); if (!tables) goto fail; if (libparsepcf_get_tables(file, size, tables, 0, table_n)) goto fail; for (table_i = 0; table_i < table_n; table_i++) { if (tables[table_i].type == LIBPARSEPCF_PROPERTIES) { font->prob_table = &tables[table_i]; if (libparsepcf_get_properties(file, size, &tables[table_i], &font->props)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_ACCELERATORS && !font->accel_table) { font->accel_table = &tables[table_i]; if (libparsepcf_get_accelerators(file, size, &tables[table_i], &font->accels)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_BDF_ACCELERATORS) { font->accel_table = &tables[table_i]; if (libparsepcf_get_accelerators(file, size, &tables[table_i], &font->accels)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_METRICS) { font->mtx_table = &tables[table_i]; if (libparsepcf_get_metrics_count(file, size, &tables[table_i], &font->metrics)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_INK_METRICS) { font->inkmtx_table = &tables[table_i]; if (libparsepcf_get_metrics_count(file, size, &tables[table_i], &font->ink_metrics)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_BDF_ENCODINGS) { font->enc_table = &tables[table_i]; if (libparsepcf_get_encoding(file, size, &tables[table_i], &font->encoding)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_BITMAPS) { font->bitmap_table = &tables[table_i]; if (libparsepcf_get_bitmaps(file, size, &tables[table_i], &font->bitmaps)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_GLYPH_NAMES) { font->name_table = &tables[table_i]; if (libparsepcf_get_glyph_names(file, size, &tables[table_i], &font->names)) goto fail; } else if (tables[table_i].type == LIBPARSEPCF_SWIDTHS) { font->swidth_table = &tables[table_i]; if (libparsepcf_get_swidth_count(file, size, &tables[table_i], &font->swidths)) goto fail; } } if (font->mtx_table) { if (font->metrics < min) min = font->metrics; if (font->metrics > max) max = font->metrics; } if (font->inkmtx_table) { if (font->ink_metrics < min) min = font->ink_metrics; if (font->ink_metrics > max) max = font->ink_metrics; } if (font->bitmap_table) { if (font->bitmaps.glyph_count < min) min = font->bitmaps.glyph_count; if (font->bitmaps.glyph_count > max) max = font->bitmaps.glyph_count; } if (font->name_table) { if (font->names.glyph_count < min) min = font->names.glyph_count; if (font->names.glyph_count > max) max = font->names.glyph_count; } if (font->swidth_table) { if (font->swidths < min) min = font->swidths; if (font->swidths > max) max = font->swidths; } if (min != max || !font->mtx_table || !font->enc_table) goto ebfont; if (!font->inkmtx_table && font->accel_table && font->accels.ink_metrics) goto ebfont; font->glyph_count = min; font->_tables = tables; return 0; ebfont: errno = EBFONT; fail: free(tables); return -1; }