mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-17 09:30:19 +01:00
type1-subset: Remove FT dependency part 1
Remove cairo_type1_font_subset_get_glyph_names_and_widths(). The glyph names are read from the font file instead of via FT. The charstrings are parsed to extract the glyph widths. A new font backend function, index_to_glyph_name, has been added for obtaining the glyph name for a given glyph index. This function is supplied with the array of glyph names and a glyph index and is required to return the array index of the glyph name corresponding to the glyph index. The reason for passing in the array of glyph names is that: 1) On windows there is no API for accessing glyph names so we will use knowledge of how the glyphs in a Type 1 font are numbered to perform name lookup. 2) We can also use knowledge of how FT assigns the glyph numbers in a Type 1 font to optimize the name lookup.
This commit is contained in:
parent
9fc3f1086c
commit
d46df1dffb
3 changed files with 252 additions and 132 deletions
|
|
@ -2439,6 +2439,64 @@ _cairo_ft_is_synthetic (void *abstract_font)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_index_to_glyph_name (void *abstract_font,
|
||||
char **glyph_names,
|
||||
int num_glyph_names,
|
||||
unsigned long glyph_index,
|
||||
unsigned long *glyph_array_index)
|
||||
{
|
||||
cairo_ft_scaled_font_t *scaled_font = abstract_font;
|
||||
cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
|
||||
FT_Face face;
|
||||
char buffer[256]; /* PLRM spcifies max name length of 127 */
|
||||
FT_Error error;
|
||||
int i;
|
||||
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (!face)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
error = FT_Get_Glyph_Name (face, glyph_index, buffer, sizeof buffer);
|
||||
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
|
||||
if (error != FT_Err_Ok) {
|
||||
/* propagate fatal errors from FreeType */
|
||||
if (error == FT_Err_Out_Of_Memory)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* FT first numbers the glyphs in the order they are read from the
|
||||
* Type 1 font. Then if .notdef is not the first glyph, the first
|
||||
* glyph is swapped with .notdef to ensure that .notdef is at
|
||||
* glyph index 0.
|
||||
*
|
||||
* As all but two glyphs in glyph_names already have the same
|
||||
* index as the FT glyph index, we first check if
|
||||
* glyph_names[glyph_index] is the name we are looking for. If not
|
||||
* we fall back to searching the entire array.
|
||||
*/
|
||||
|
||||
if (strcmp (glyph_names[glyph_index], buffer) == 0) {
|
||||
*glyph_array_index = glyph_index;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_glyph_names; i++) {
|
||||
if (strcmp (glyph_names[i], buffer) == 0) {
|
||||
*glyph_array_index = i;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
|
||||
CAIRO_FONT_TYPE_FT,
|
||||
_cairo_ft_scaled_font_fini,
|
||||
|
|
@ -2448,7 +2506,8 @@ static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
|
|||
NULL, /* show_glyphs */
|
||||
_cairo_ft_load_truetype_table,
|
||||
_cairo_ft_index_to_ucs4,
|
||||
_cairo_ft_is_synthetic
|
||||
_cairo_ft_is_synthetic,
|
||||
_cairo_index_to_glyph_name
|
||||
};
|
||||
|
||||
/* #cairo_ft_font_face_t */
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ typedef struct _cairo_type1_font_subset {
|
|||
unsigned int num_glyphs;
|
||||
double x_min, y_min, x_max, y_max;
|
||||
double ascent, descent;
|
||||
double units_per_em;
|
||||
|
||||
const char *data;
|
||||
unsigned long header_size;
|
||||
|
|
@ -81,11 +82,24 @@ typedef struct _cairo_type1_font_subset {
|
|||
FT_Face face;
|
||||
int num_glyphs;
|
||||
|
||||
/* The glyphs and glyph_names arrays are indexed by the order of
|
||||
* the Charstrings in the font. This is not necessarily the same
|
||||
* order as the glyph index. The index_to_glyph_name() font backend
|
||||
* function is used to map the glyph index to the glyph order in
|
||||
* the Charstrings. */
|
||||
|
||||
struct {
|
||||
int subset_index;
|
||||
double width;
|
||||
char *name;
|
||||
const char *encrypted_charstring;
|
||||
int encrypted_charstring_length;
|
||||
} *glyphs;
|
||||
char **glyph_names;
|
||||
|
||||
/* Indexed by subset_index this maps to the glyph order in the
|
||||
* glyph_names and glyphs arrays. Has font->num_golyphs
|
||||
* elements. */
|
||||
int *subset_index_to_glyphs;
|
||||
|
||||
cairo_output_stream_t *output;
|
||||
cairo_array_t contents;
|
||||
|
|
@ -154,6 +168,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
|
|||
font->base.y_max = face->bbox.yMax / (double)face->units_per_EM;
|
||||
font->base.ascent = face->ascender / (double)face->units_per_EM;
|
||||
font->base.descent = face->descender / (double)face->units_per_EM;
|
||||
font->base.units_per_em = face->units_per_EM;
|
||||
|
||||
if (face->family_name) {
|
||||
font->base.base_font = strdup (face->family_name);
|
||||
|
|
@ -175,6 +190,18 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
|
|||
goto fail3;
|
||||
}
|
||||
|
||||
font->glyph_names = calloc (face->num_glyphs, sizeof font->glyph_names[0]);
|
||||
if (unlikely (font->glyph_names == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
font->subset_index_to_glyphs = calloc (face->num_glyphs, sizeof font->subset_index_to_glyphs[0]);
|
||||
if (unlikely (font->subset_index_to_glyphs == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail5;
|
||||
}
|
||||
|
||||
font->hex_encode = hex_encode;
|
||||
font->num_glyphs = 0;
|
||||
for (i = 0; i < face->num_glyphs; i++)
|
||||
|
|
@ -186,6 +213,12 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
|
|||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail5:
|
||||
if (font->glyph_names)
|
||||
free (font->glyph_names);
|
||||
fail4:
|
||||
if (font->glyphs)
|
||||
free (font->glyphs);
|
||||
fail3:
|
||||
if (font->base.base_font)
|
||||
free (font->base.base_font);
|
||||
|
|
@ -203,7 +236,9 @@ cairo_type1_font_subset_use_glyph (cairo_type1_font_subset_t *font, int glyph)
|
|||
if (font->glyphs[glyph].subset_index >= 0)
|
||||
return;
|
||||
|
||||
font->glyphs[glyph].subset_index = font->num_glyphs++;
|
||||
font->glyphs[glyph].subset_index = font->num_glyphs;
|
||||
font->subset_index_to_glyphs[font->num_glyphs] = glyph;
|
||||
font->num_glyphs++;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
|
|
@ -396,13 +431,13 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
|
|||
if (font->scaled_font_subset->is_latin) {
|
||||
for (i = 1; i < 256; i++) {
|
||||
int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
|
||||
int parent_glyph = font->scaled_font_subset->glyphs[subset_glyph];
|
||||
int glyph_num = font->subset_index_to_glyphs[subset_glyph];
|
||||
|
||||
if (subset_glyph > 0) {
|
||||
_cairo_output_stream_printf (font->output,
|
||||
"dup %d /%s put\n",
|
||||
i,
|
||||
font->glyphs[parent_glyph].name);
|
||||
font->glyph_names[glyph_num]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -412,7 +447,7 @@ cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
|
|||
_cairo_output_stream_printf (font->output,
|
||||
"dup %d /%s put\n",
|
||||
font->glyphs[i].subset_index,
|
||||
font->glyphs[i].name);
|
||||
font->glyph_names[i]);
|
||||
}
|
||||
}
|
||||
_cairo_output_stream_printf (font->output, "readonly def");
|
||||
|
|
@ -547,64 +582,6 @@ skip_token (const char *p, const char *end)
|
|||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
cairo_type1_font_subset_lookup_glyph (cairo_type1_font_subset_t *font,
|
||||
const char *glyph_name, int length)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
if (font->glyphs[i].name &&
|
||||
strncmp (font->glyphs[i].name, glyph_name, length) == 0 &&
|
||||
font->glyphs[i].name[length] == '\0')
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *font)
|
||||
{
|
||||
unsigned int i;
|
||||
char buffer[256];
|
||||
FT_Error error;
|
||||
|
||||
/* Get glyph names and width using the freetype API */
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
if (font->glyphs[i].name != NULL)
|
||||
continue;
|
||||
|
||||
error = FT_Load_Glyph (font->face, i,
|
||||
FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING |
|
||||
FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
|
||||
if (error != FT_Err_Ok) {
|
||||
/* propagate fatal errors from FreeType */
|
||||
if (error == FT_Err_Out_Of_Memory)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
font->glyphs[i].width = font->face->glyph->metrics.horiAdvance / (double)font->face->units_per_EM;
|
||||
|
||||
error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
|
||||
if (error != FT_Err_Ok) {
|
||||
/* propagate fatal errors from FreeType */
|
||||
if (error == FT_Err_Out_Of_Memory)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
font->glyphs[i].name = strdup (buffer);
|
||||
if (unlikely (font->glyphs[i].name == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_type1_font_subset_decrypt_charstring (const unsigned char *in, int size, unsigned char *out)
|
||||
{
|
||||
|
|
@ -642,6 +619,7 @@ static cairo_status_t
|
|||
use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
|
||||
{
|
||||
const char *glyph_name;
|
||||
unsigned int i;
|
||||
|
||||
if (index < 0 || index > 255)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
|
@ -650,24 +628,46 @@ use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
|
|||
if (glyph_name == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
index = cairo_type1_font_subset_lookup_glyph (font,
|
||||
glyph_name,
|
||||
strlen(glyph_name));
|
||||
if (index < 0)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
if (font->glyph_names[i] && strcmp (font->glyph_names[i], glyph_name) == 0) {
|
||||
cairo_type1_font_subset_use_glyph (font, i);
|
||||
|
||||
cairo_type1_font_subset_use_glyph (font, index);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
#define TYPE1_CHARSTRING_COMMAND_ESCAPE 0x0c
|
||||
#define TYPE1_CHARSTRING_COMMAND_SEAC 0x0c06
|
||||
#define TYPE1_CHARSTRING_COMMAND_SBW 0x0c07
|
||||
#define TYPE1_CHARSTRING_COMMAND_HSBW 0x0d
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_build_glyph_list (cairo_type1_font_subset_t *font,
|
||||
int glyph_number,
|
||||
const char *name, int name_length,
|
||||
const char *encrypted_charstring, int encrypted_charstring_length)
|
||||
{
|
||||
font->glyph_names[glyph_number] = malloc (name_length + 1);
|
||||
if (unlikely (font->glyph_names[glyph_number] == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
strncpy (font->glyph_names[glyph_number], name, name_length);
|
||||
font->glyph_names[glyph_number][name_length] = 0;
|
||||
|
||||
font->glyphs[glyph_number].encrypted_charstring = encrypted_charstring;
|
||||
font->glyphs[glyph_number].encrypted_charstring_length = encrypted_charstring_length;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define TYPE1_CHARSTRING_COMMAND_ESCAPE (12)
|
||||
#define TYPE1_CHARSTRING_COMMAND_SEAC (32 + 6)
|
||||
|
||||
/* Get glyph width and look for seac operatorParse charstring */
|
||||
static cairo_status_t
|
||||
cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
||||
const char *name, int name_length,
|
||||
const char *encrypted_charstring, int encrypted_charstring_length)
|
||||
cairo_type1_font_subset_parse_charstring(cairo_type1_font_subset_t *font, int glyph)
|
||||
{
|
||||
cairo_status_t status;
|
||||
unsigned char *charstring;
|
||||
|
|
@ -675,6 +675,11 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
|||
const unsigned char *p;
|
||||
int stack[5], sp, value;
|
||||
int command;
|
||||
const char *encrypted_charstring;
|
||||
int encrypted_charstring_length;
|
||||
|
||||
encrypted_charstring = font->glyphs[glyph].encrypted_charstring;
|
||||
encrypted_charstring_length = font->glyphs[glyph].encrypted_charstring_length;
|
||||
|
||||
charstring = malloc (encrypted_charstring_length);
|
||||
if (unlikely (charstring == NULL))
|
||||
|
|
@ -692,32 +697,42 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
|||
while (p < end) {
|
||||
if (*p < 32) {
|
||||
command = *p++;
|
||||
|
||||
if (command == TYPE1_CHARSTRING_COMMAND_ESCAPE)
|
||||
command = 32 + *p++;
|
||||
|
||||
switch (command) {
|
||||
case TYPE1_CHARSTRING_COMMAND_SEAC:
|
||||
/* The seac command takes five integer arguments. The
|
||||
* last two are glyph indices into the PS standard
|
||||
* encoding give the names of the glyphs that this
|
||||
* glyph is composed from. All we need to do is to
|
||||
* make sure those glyphs are present in the subset
|
||||
* under their standard names. */
|
||||
status = use_standard_encoding_glyph (font, stack[3]);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
case TYPE1_CHARSTRING_COMMAND_HSBW:
|
||||
font->glyphs[glyph].width = stack[1]/font->base.units_per_em;
|
||||
sp = 0;
|
||||
break;
|
||||
|
||||
status = use_standard_encoding_glyph (font, stack[4]);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
case TYPE1_CHARSTRING_COMMAND_ESCAPE:
|
||||
command = command << 8 | *p++;
|
||||
switch (command) {
|
||||
case TYPE1_CHARSTRING_COMMAND_SEAC:
|
||||
/* The seac command takes five integer arguments. The
|
||||
* last two are glyph indices into the PS standard
|
||||
* encoding give the names of the glyphs that this
|
||||
* glyph is composed from. All we need to do is to
|
||||
* make sure those glyphs are present in the subset
|
||||
* under their standard names. */
|
||||
status = use_standard_encoding_glyph (font, stack[3]);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
sp = 0;
|
||||
break;
|
||||
status = use_standard_encoding_glyph (font, stack[4]);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
default:
|
||||
sp = 0;
|
||||
break;
|
||||
sp = 0;
|
||||
break;
|
||||
|
||||
case TYPE1_CHARSTRING_COMMAND_SBW:
|
||||
font->glyphs[glyph].width = stack[2]/font->base.units_per_em;
|
||||
sp = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
sp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* integer argument */
|
||||
|
|
@ -734,6 +749,7 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
|
|||
|
||||
static cairo_status_t
|
||||
write_used_glyphs (cairo_type1_font_subset_t *font,
|
||||
int glyph_number,
|
||||
const char *name, int name_length,
|
||||
const char *charstring, int charstring_length)
|
||||
{
|
||||
|
|
@ -741,6 +757,9 @@ write_used_glyphs (cairo_type1_font_subset_t *font,
|
|||
char buffer[256];
|
||||
int length;
|
||||
|
||||
if (font->glyphs[glyph_number].subset_index < 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
length = snprintf (buffer, sizeof buffer,
|
||||
"/%.*s %d %s ",
|
||||
name_length, name, charstring_length, font->rd);
|
||||
|
|
@ -763,6 +782,7 @@ write_used_glyphs (cairo_type1_font_subset_t *font,
|
|||
}
|
||||
|
||||
typedef cairo_status_t (*glyph_func_t) (cairo_type1_font_subset_t *font,
|
||||
int glyph_number,
|
||||
const char *name, int name_length,
|
||||
const char *charstring, int charstring_length);
|
||||
|
||||
|
|
@ -773,9 +793,11 @@ cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
|
|||
glyph_func_t func,
|
||||
const char **dict_out)
|
||||
{
|
||||
int charstring_length, name_length, glyph_index;
|
||||
int charstring_length, name_length;
|
||||
const char *p, *charstring, *name;
|
||||
char *end;
|
||||
cairo_status_t status;
|
||||
int glyph_count;
|
||||
|
||||
/* We're looking at '/' in the name of the first glyph. The glyph
|
||||
* definitions are on the form:
|
||||
|
|
@ -792,7 +814,7 @@ cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
|
|||
*/
|
||||
|
||||
p = dict_start;
|
||||
|
||||
glyph_count = 0;
|
||||
while (*p == '/') {
|
||||
name = p + 1;
|
||||
p = skip_token (p, dict_end);
|
||||
|
|
@ -816,15 +838,11 @@ cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
|
|||
if (p == dict_end)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
glyph_index = cairo_type1_font_subset_lookup_glyph (font,
|
||||
name, name_length);
|
||||
if (font->glyphs[glyph_index].subset_index >= 0) {
|
||||
cairo_status_t status = func (font,
|
||||
name, name_length,
|
||||
charstring, charstring_length);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
status = func (font, glyph_count++,
|
||||
name, name_length,
|
||||
charstring, charstring_length);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
*dict_out = p;
|
||||
|
|
@ -842,6 +860,8 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
|
|||
const char *closefile_token;
|
||||
char buffer[32], *glyph_count_end;
|
||||
int num_charstrings, length;
|
||||
const cairo_scaled_font_backend_t *backend;
|
||||
unsigned int i;
|
||||
|
||||
/* The private dict holds hint information, common subroutines and
|
||||
* the actual glyph definitions (charstrings).
|
||||
|
|
@ -878,30 +898,49 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
|
|||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
dict_start = p;
|
||||
|
||||
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
/* Now that we have the private dictionary broken down in
|
||||
* sections, do the first pass through the glyph definitions to
|
||||
* figure out which subrs and othersubrs are use and which extra
|
||||
* glyphs may be required by the seac operator. */
|
||||
* build a list of glyph names and charstrings. */
|
||||
status = cairo_type1_font_subset_for_each_glyph (font,
|
||||
dict_start,
|
||||
font->cleartext_end,
|
||||
cairo_type1_font_subset_look_for_seac,
|
||||
cairo_type1_font_subset_build_glyph_list,
|
||||
&p);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
backend = font->scaled_font_subset->scaled_font->backend;
|
||||
if (!backend->index_to_glyph_name)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Find the glyph number corresponding to each glyph in the subset
|
||||
* and mark it as in use */
|
||||
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
unsigned long index;
|
||||
|
||||
status = backend->index_to_glyph_name (font->scaled_font_subset->scaled_font,
|
||||
font->glyph_names,
|
||||
font->base.num_glyphs,
|
||||
font->scaled_font_subset->glyphs[i],
|
||||
&index);
|
||||
if (unlikely(status))
|
||||
return status;
|
||||
|
||||
cairo_type1_font_subset_use_glyph (font, index);
|
||||
}
|
||||
|
||||
/* Go through the charstring of each glyph in use, get the glyph
|
||||
* width and figure out which extra glyphs may be required by the
|
||||
* seac operator. */
|
||||
for (i = 0; i < font->base.num_glyphs; i++) {
|
||||
status = cairo_type1_font_subset_parse_charstring (font, i);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
closefile_token = find_token (p, font->cleartext_end, "closefile");
|
||||
if (closefile_token == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
/* We're ready to start outputting. First write the header,
|
||||
* i.e. the public part of the font dict.*/
|
||||
status = cairo_type1_font_subset_write_header (font, name);
|
||||
|
|
@ -1086,20 +1125,24 @@ cairo_type1_font_subset_generate (void *abstract_font,
|
|||
font->face->stream->base, font->type1_length);
|
||||
}
|
||||
|
||||
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
|
||||
|
||||
status = _cairo_array_grow_by (&font->contents, 4096);
|
||||
if (unlikely (status))
|
||||
goto fail;
|
||||
return status;
|
||||
|
||||
font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
|
||||
if (unlikely ((status = font->output->status)))
|
||||
goto fail;
|
||||
return status;
|
||||
|
||||
status = cairo_type1_font_subset_write (font, name);
|
||||
if (unlikely (status))
|
||||
goto fail;
|
||||
return status;
|
||||
|
||||
font->base.data = _cairo_array_index (&font->contents, 0);
|
||||
|
||||
return status;
|
||||
|
||||
fail:
|
||||
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
|
||||
|
||||
|
|
@ -1118,9 +1161,11 @@ _cairo_type1_font_subset_fini (cairo_type1_font_subset_t *font)
|
|||
_cairo_array_fini (&font->contents);
|
||||
|
||||
free (font->type1_data);
|
||||
if (font->glyphs != NULL) {
|
||||
if (font->glyph_names != NULL) {
|
||||
for (i = 0; i < font->base.num_glyphs; i++)
|
||||
free (font->glyphs[i].name);
|
||||
free (font->glyph_names[i]);
|
||||
|
||||
free (font->glyph_names);
|
||||
}
|
||||
|
||||
_cairo_unscaled_font_destroy (font->base.unscaled_font);
|
||||
|
|
@ -1130,7 +1175,9 @@ _cairo_type1_font_subset_fini (cairo_type1_font_subset_t *font)
|
|||
|
||||
if (font->base.base_font)
|
||||
free (font->base.base_font);
|
||||
|
||||
free (font->glyphs);
|
||||
free (font->subset_index_to_glyphs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1143,7 +1190,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
|
|||
{
|
||||
cairo_type1_font_subset_t font;
|
||||
cairo_status_t status, status_ignored;
|
||||
unsigned long parent_glyph, length;
|
||||
unsigned long length;
|
||||
unsigned int i;
|
||||
cairo_unscaled_font_t *unscaled_font;
|
||||
char buf[30];
|
||||
|
|
@ -1166,11 +1213,6 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
for (i = 0; i < scaled_font_subset->num_glyphs; i++) {
|
||||
parent_glyph = scaled_font_subset->glyphs[i];
|
||||
cairo_type1_font_subset_use_glyph (&font, parent_glyph);
|
||||
}
|
||||
|
||||
status = cairo_type1_font_subset_generate (&font, name);
|
||||
if (unlikely (status))
|
||||
goto fail1;
|
||||
|
|
|
|||
|
|
@ -546,6 +546,25 @@ struct _cairo_scaled_font_backend {
|
|||
|
||||
cairo_warn cairo_bool_t
|
||||
(*is_synthetic)(void *scaled_font);
|
||||
|
||||
/* For type 1 fonts, return the glyph name for a given glyph index.
|
||||
* A glyph index and list of glyph names in the Type 1 fonts is provided.
|
||||
* The function returns the index of the glyph in the list of glyph names.
|
||||
* @scaled_font: font
|
||||
* @glyph_names: the names of each glyph in the Type 1 font in the
|
||||
* order they appear in the CharStrings array
|
||||
* @num_glyph_names: the number of names in the glyph_names array
|
||||
* @glyph_index: the given glyph index
|
||||
* @glyph_array_index: (index into glyph_names) the glyph name corresponding
|
||||
* to the glyph_index
|
||||
*/
|
||||
|
||||
cairo_warn cairo_int_status_t
|
||||
(*index_to_glyph_name)(void *scaled_font,
|
||||
char **glyph_names,
|
||||
int num_glyph_names,
|
||||
unsigned long glyph_index,
|
||||
unsigned long *glyph_array_index);
|
||||
};
|
||||
|
||||
struct _cairo_font_face_backend {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue