mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-06-02 13:28:39 +02:00
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:
parent
1deb1e4510
commit
2ed08f7801
3 changed files with 114 additions and 113 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue