Factor out duplicate code in truetype and cff subsetting

The code for reading the font name from the name table has been moved
to a new function: _cairo_truetype_read_font_name().
This commit is contained in:
Adrian Johnson 2008-12-03 23:56:01 +10:30
parent 1deb1e4510
commit 2ed08f7801
3 changed files with 114 additions and 113 deletions

View file

@ -1716,10 +1716,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
cairo_cff_font_t *font;
tt_head_t head;
tt_hhea_t hhea;
tt_name_t *name;
tt_name_record_t *record;
unsigned long size, data_length;
int i, j;
backend = scaled_font_subset->scaled_font->backend;
if (!backend->load_truetype_table)
@ -1751,22 +1748,6 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
if (unlikely (status))
return status;
size = 0;
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_name, 0, NULL, &size);
if (unlikely (status))
return status;
name = malloc (size);
if (unlikely (name == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_name, 0,
(unsigned char *) name, &size);
if (unlikely (status))
goto fail1;
font = malloc (sizeof (cairo_cff_font_t));
if (unlikely (font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1793,47 +1774,24 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
font->descent = (int16_t) be16_to_cpu (hhea.descender);
/* Extract the font name from the name table. At present this
* just looks for the Mac platform/Roman encoded font name. It
* should be extended to use any suitable font name in the
* name table. If the mac/roman font name is not found a
* CairoFont-x-y name is created.
*/
font->font_name = NULL;
for (i = 0; i < be16_to_cpu(name->num_records); i++) {
record = &(name->records[i]);
if ((be16_to_cpu (record->platform) == 1) &&
(be16_to_cpu (record->encoding) == 0) &&
(be16_to_cpu (record->name) == 4)) {
font->font_name = malloc (be16_to_cpu(record->length) + 1);
if (font->font_name) {
strncpy(font->font_name,
((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
be16_to_cpu (record->length));
font->font_name[be16_to_cpu (record->length)] = 0;
}
break;
}
}
status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
&font->font_name);
if (_cairo_status_is_error (status))
goto fail3;
/* If the font name is not found, create a CairoFont-x-y name. */
if (font->font_name == NULL) {
font->font_name = malloc (30);
if (unlikely (font->font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
}
snprintf(font->font_name, 30, "CairoFont-%u-%u",
scaled_font_subset->font_id,
scaled_font_subset->subset_id);
}
for (i = 0, j = 0; font->font_name[j]; j++) {
if (font->font_name[j] == ' ')
continue;
font->font_name[i++] = font->font_name[j];
}
font->font_name[i] = '\0';
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
if (unlikely (font->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1880,7 +1838,6 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->fd_subset_map = NULL;
font->private_dict_offset = NULL;
free (name);
*font_return = font;
return CAIRO_STATUS_SUCCESS;
@ -1898,8 +1855,7 @@ fail3:
fail2:
_cairo_array_fini (&font->output);
free (font);
fail1:
free (name);
return status;
}

View file

@ -635,6 +635,24 @@ _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
unsigned long index,
uint32_t *ucs4);
/**
* _cairo_truetype_read_font_name:
* @scaled_font: the #cairo_scaled_font_t
* @font_name: returns the font name or NULL if the name could not be found.
*
* If possible (depending on the format of the underlying
* #cairo_scaled_font_t and the font backend in use) read the
* font name from a TrueType/OpenType font.
*
* Return value: %CAIRO_STATUS_SUCCESS if successful,
* %CAIRO_INT_STATUS_UNSUPPORTED if the font is not TrueType/OpenType
* or the name table is not present. Possible errors include
* %CAIRO_STATUS_NO_MEMORY.
**/
cairo_private cairo_int_status_t
_cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
char **font_name);
#endif /* CAIRO_HAS_FONT_SUBSET */
#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */

View file

@ -123,10 +123,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
tt_head_t head;
tt_hhea_t hhea;
tt_maxp_t maxp;
tt_name_t *name;
tt_name_record_t *record;
unsigned long size;
int i, j;
backend = scaled_font_subset->scaled_font->backend;
if (!backend->load_truetype_table)
@ -165,30 +162,9 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
if (unlikely (status))
return status;
size = 0;
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_name, 0,
NULL,
&size);
if (unlikely (status))
return status;
name = malloc (size);
if (unlikely (name == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font_subset->scaled_font,
TT_TAG_name, 0,
(unsigned char *) name,
&size);
if (unlikely (status))
goto fail0;
font = malloc (sizeof (cairo_truetype_font_t));
if (unlikely (font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail0;
}
if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->backend = backend;
font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
@ -224,32 +200,12 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
if (font->base.units_per_em == 0)
font->base.units_per_em = 2048;
/* Extract the font name from the name table. At present this
* just looks for the Mac platform/Roman encoded font name. It
* should be extended to use any suitable font name in the
* name table. If the mac/roman font name is not found a
* CairoFont-x-y name is created.
*/
font->base.base_font = NULL;
for (i = 0; i < be16_to_cpu(name->num_records); i++) {
record = &(name->records[i]);
if ((be16_to_cpu (record->platform) == 1) &&
(be16_to_cpu (record->encoding) == 0) &&
(be16_to_cpu (record->name) == 4)) {
font->base.base_font = malloc (be16_to_cpu(record->length) + 1);
if (font->base.base_font) {
strncpy(font->base.base_font,
((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
be16_to_cpu (record->length));
font->base.base_font[be16_to_cpu (record->length)] = 0;
}
break;
}
}
free (name);
name = NULL;
status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
&font->base.base_font);
if (_cairo_status_is_error (status))
goto fail3;
/* If the font name is not found, create a CairoFont-x-y name. */
if (font->base.base_font == NULL) {
font->base.base_font = malloc (30);
if (unlikely (font->base.base_font == NULL)) {
@ -262,13 +218,6 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
scaled_font_subset->subset_id);
}
for (i = 0, j = 0; font->base.base_font[j]; j++) {
if (font->base.base_font[j] == ' ')
continue;
font->base.base_font[i++] = font->base.base_font[j];
}
font->base.base_font[i] = '\0';
font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
if (unlikely (font->base.widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -298,9 +247,6 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
fail1:
_cairo_array_fini (&font->output);
free (font);
fail0:
if (name)
free (name);
return status;
}
@ -1335,4 +1281,85 @@ cleanup:
return status;
}
cairo_int_status_t
_cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
char **font_name_out)
{
cairo_status_t status;
const cairo_scaled_font_backend_t *backend;
tt_name_t *name;
tt_name_record_t *record;
unsigned long size;
int i, j;
char *font_name;
backend = scaled_font->backend;
if (!backend->load_truetype_table)
return CAIRO_INT_STATUS_UNSUPPORTED;
size = 0;
status = backend->load_truetype_table (scaled_font,
TT_TAG_name, 0,
NULL,
&size);
if (status)
return status;
name = malloc (size);
if (name == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = backend->load_truetype_table (scaled_font,
TT_TAG_name, 0,
(unsigned char *) name,
&size);
if (status)
goto fail;
/* Extract the font name and PS name from the name table. At
* present this just looks for the Mac platform/Roman encoded font
* name. It should be extended to use any suitable font name in
* the name table.
*/
font_name = NULL;
for (i = 0; i < be16_to_cpu(name->num_records); i++) {
record = &(name->records[i]);
if ((be16_to_cpu (record->platform) == 1) &&
(be16_to_cpu (record->encoding) == 0) &&
(be16_to_cpu (record->name) == 4)) {
font_name = malloc (be16_to_cpu(record->length) + 1);
if (font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
}
strncpy(font_name,
((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
be16_to_cpu (record->length));
font_name[be16_to_cpu (record->length)] = 0;
break;
}
}
free (name);
/* Ensure font name does not contain any spaces */
if (font_name) {
for (i = 0, j = 0; font_name[j]; j++) {
if (font_name[j] == ' ')
continue;
font_name[i++] = font_name[j];
}
font_name[i] = '\0';
}
*font_name_out = font_name;
return CAIRO_STATUS_SUCCESS;
fail:
free (name);
return status;
}
#endif /* CAIRO_HAS_FONT_SUBSET */