mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 02:58:02 +02:00
Add CFF CID Fallback
Switching to CID font embedding requires a fallback font for the case where CFF CID or TrueType CID subsetting fails. The new function _cairo_type2_charstrings_init() added to cairo-type1-fallback.c creates Type2 charstrings from glyph paths. _cairo_cff_fallback_init() in cairo-cff-subset.c wraps these charstrings in a CFF CID font.
This commit is contained in:
parent
c68a2389f5
commit
0c2a653033
3 changed files with 432 additions and 59 deletions
|
|
@ -1915,3 +1915,215 @@ _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
|
|||
free (subset->widths);
|
||||
free (subset->data);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
cairo_cff_font_t **font_return,
|
||||
const char *subset_name)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_cff_font_t *font;
|
||||
|
||||
font = malloc (sizeof (cairo_cff_font_t));
|
||||
if (font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
font->backend = NULL;
|
||||
font->scaled_font_subset = scaled_font_subset;
|
||||
|
||||
_cairo_array_init (&font->output, sizeof (char));
|
||||
status = _cairo_array_grow_by (&font->output, 4096);
|
||||
if (status)
|
||||
goto fail1;
|
||||
|
||||
font->subset_font_name = strdup (subset_name);
|
||||
if (font->subset_font_name == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
font->font_name = strdup (subset_name);
|
||||
if (font->subset_font_name == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
font->x_min = 0;
|
||||
font->y_min = 0;
|
||||
font->x_max = 0;
|
||||
font->y_max = 0;
|
||||
font->ascent = 0;
|
||||
font->descent = 0;
|
||||
|
||||
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
|
||||
if (font->widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
font->data_length = 0;
|
||||
font->data = NULL;
|
||||
font->data_end = 0;
|
||||
|
||||
cff_dict_init (&font->top_dict);
|
||||
cff_dict_init (&font->private_dict);
|
||||
cff_index_init (&font->strings_index);
|
||||
cff_index_init (&font->charstrings_index);
|
||||
cff_index_init (&font->global_sub_index);
|
||||
cff_index_init (&font->local_sub_index);
|
||||
cff_index_init (&font->charstrings_subset_index);
|
||||
cff_index_init (&font->strings_subset_index);
|
||||
font->fdselect = NULL;
|
||||
font->fd_dict = NULL;
|
||||
font->fd_private_dict = NULL;
|
||||
font->fd_local_sub_index = NULL;
|
||||
font->fdselect_subset = NULL;
|
||||
font->fd_subset_map = NULL;
|
||||
font->private_dict_offset = NULL;
|
||||
|
||||
*font_return = font;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail4:
|
||||
free (font->font_name);
|
||||
fail3:
|
||||
free (font->subset_font_name);
|
||||
fail2:
|
||||
_cairo_array_fini (&font->output);
|
||||
fail1:
|
||||
free (font);
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
|
||||
cairo_type2_charstrings_t *type2_subset,
|
||||
const char **data,
|
||||
unsigned long *length)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cff_header_t header;
|
||||
cairo_array_t *charstring;
|
||||
unsigned char buf[40];
|
||||
unsigned char *end_buf;
|
||||
unsigned int i;
|
||||
|
||||
/* Create header */
|
||||
header.major = 1;
|
||||
header.minor = 0;
|
||||
header.header_size = 4;
|
||||
header.offset_size = 4;
|
||||
font->header = &header;
|
||||
|
||||
/* Create Top Dict */
|
||||
font->is_cid = FALSE;
|
||||
end_buf = encode_integer (buf, type2_subset->x_min);
|
||||
end_buf = encode_integer (end_buf, type2_subset->y_min);
|
||||
end_buf = encode_integer (end_buf, type2_subset->x_max);
|
||||
end_buf = encode_integer (end_buf, type2_subset->y_max);
|
||||
cff_dict_set_operands (font->top_dict, FONTBBOX_OP, buf, end_buf - buf);
|
||||
end_buf = encode_integer_max (buf, 0);
|
||||
cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
|
||||
cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
|
||||
cairo_cff_font_set_ros_strings (font);
|
||||
|
||||
/* Create CID FD dictionary */
|
||||
cairo_cff_font_create_cid_fontdict (font);
|
||||
|
||||
/* Create charstrings */
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
charstring = _cairo_array_index(&type2_subset->charstrings, i);
|
||||
|
||||
status = cff_index_append (&font->charstrings_subset_index,
|
||||
_cairo_array_index (charstring, 0),
|
||||
_cairo_array_num_elements (charstring));
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cairo_cff_font_write_subset (font);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
*data = _cairo_array_index (&font->output, 0);
|
||||
*length = _cairo_array_num_elements (&font->output);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
|
||||
const char *subset_name,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
|
||||
cairo_status_t status;
|
||||
const char *data = NULL; /* squelch bogus compiler warning */
|
||||
unsigned long length = 0; /* squelch bogus compiler warning */
|
||||
unsigned int i;
|
||||
cairo_type2_charstrings_t type2_subset;
|
||||
|
||||
status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
|
||||
if (status)
|
||||
goto fail1;
|
||||
|
||||
status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
|
||||
if (status)
|
||||
goto fail1;
|
||||
|
||||
cff_subset->base_font = strdup (font->font_name);
|
||||
if (cff_subset->base_font == NULL)
|
||||
goto fail1;
|
||||
|
||||
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
if (cff_subset->widths == NULL)
|
||||
goto fail2;
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
cff_subset->widths[i] = type2_subset.widths[i];
|
||||
|
||||
cff_subset->x_min = type2_subset.x_min;
|
||||
cff_subset->y_min = type2_subset.y_min;
|
||||
cff_subset->x_max = type2_subset.x_max;
|
||||
cff_subset->y_max = type2_subset.y_max;
|
||||
cff_subset->ascent = type2_subset.y_max;
|
||||
cff_subset->descent = type2_subset.y_min;
|
||||
|
||||
_cairo_type2_charstrings_fini (&type2_subset);
|
||||
|
||||
cff_subset->data = malloc (length);
|
||||
if (cff_subset->data == NULL)
|
||||
goto fail3;
|
||||
|
||||
memcpy (cff_subset->data, data, length);
|
||||
cff_subset->data_length = length;
|
||||
cff_subset->data_length = length;
|
||||
|
||||
cairo_cff_font_destroy (font);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail3:
|
||||
free (cff_subset->widths);
|
||||
fail2:
|
||||
free (cff_subset->base_font);
|
||||
fail1:
|
||||
cairo_cff_font_destroy (font);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
|
||||
{
|
||||
free (subset->base_font);
|
||||
free (subset->widths);
|
||||
free (subset->data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,6 +305,37 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
|
|||
cairo_private void
|
||||
_cairo_cff_subset_fini (cairo_cff_subset_t *cff_subset);
|
||||
|
||||
/**
|
||||
* _cairo_cff_fallback_init:
|
||||
* @cff_subset: a #cairo_cff_subset_t to initialize
|
||||
* @font_subset: the #cairo_scaled_font_subset_t to initialize from
|
||||
*
|
||||
* If possible (depending on the format of the underlying
|
||||
* cairo_scaled_font_t and the font backend in use) generate a cff
|
||||
* file corresponding to @font_subset and initialize @cff_subset
|
||||
* with information about the subset and the cff data.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful,
|
||||
* CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a
|
||||
* cff file, or an non-zero value indicating an error. Possible
|
||||
* errors include CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_private cairo_status_t
|
||||
_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
|
||||
const char *name,
|
||||
cairo_scaled_font_subset_t *font_subset);
|
||||
|
||||
/**
|
||||
* _cairo_cff_fallback_fini:
|
||||
* @cff_subset: a #cairo_cff_subset_t
|
||||
*
|
||||
* Free all resources associated with @cff_subset. After this
|
||||
* call, @cff_subset should not be used again without a
|
||||
* subsequent call to _cairo_cff_subset_init() again first.
|
||||
**/
|
||||
cairo_private void
|
||||
_cairo_cff_fallback_fini (cairo_cff_subset_t *cff_subset);
|
||||
|
||||
typedef struct _cairo_truetype_subset {
|
||||
char *base_font;
|
||||
double *widths;
|
||||
|
|
@ -446,6 +477,43 @@ _cairo_type1_fallback_init_hex (cairo_type1_subset_t *type_subset,
|
|||
cairo_private void
|
||||
_cairo_type1_fallback_fini (cairo_type1_subset_t *subset);
|
||||
|
||||
typedef struct _cairo_type2_charstrings {
|
||||
int *widths;
|
||||
long x_min, y_min, x_max, y_max;
|
||||
long ascent, descent;
|
||||
cairo_array_t charstrings;
|
||||
} cairo_type2_charstrings_t;
|
||||
|
||||
/**
|
||||
* _cairo_type2_charstrings_init:
|
||||
* @type2_subset: a #cairo_type2_subset_t to initialize
|
||||
* @font_subset: the #cairo_scaled_font_subset_t to initialize from
|
||||
*
|
||||
* If possible (depending on the format of the underlying
|
||||
* cairo_scaled_font_t and the font backend in use) generate type2
|
||||
* charstrings to @font_subset and initialize @type2_subset
|
||||
* with information about the subset.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful,
|
||||
* CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a type2
|
||||
* charstrings, or an non-zero value indicating an error. Possible errors
|
||||
* include CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_private cairo_status_t
|
||||
_cairo_type2_charstrings_init (cairo_type2_charstrings_t *charstrings,
|
||||
cairo_scaled_font_subset_t *font_subset);
|
||||
|
||||
/**
|
||||
* _cairo_type2_charstrings_fini:
|
||||
* @subset: a #cairo_type2_charstrings_t
|
||||
*
|
||||
* Free all resources associated with @type2_charstring. After this call,
|
||||
* @type2_charstring should not be used again without a subsequent call to
|
||||
* _cairo_type2_charstring_init() again first.
|
||||
**/
|
||||
cairo_private void
|
||||
_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *charstrings);
|
||||
|
||||
/**
|
||||
* _cairo_truetype_create_glyph_to_unicode_map:
|
||||
* @font_subset: the #cairo_scaled_font_subset_t to initialize from
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
typedef enum {
|
||||
CAIRO_CHARSTRING_TYPE1,
|
||||
CAIRO_CHARSTRING_TYPE2,
|
||||
} cairo_charstring_type_t;
|
||||
|
||||
typedef struct _cairo_type1_font {
|
||||
int *widths;
|
||||
|
||||
|
|
@ -90,7 +95,7 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
|||
|
||||
font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
|
||||
|
||||
cairo_matrix_init_scale (&font_matrix, 1000, 1000);
|
||||
cairo_matrix_init_scale (&font_matrix, 1000, -1000);
|
||||
cairo_matrix_init_identity (&ctm);
|
||||
|
||||
_cairo_font_options_init_default (&font_options);
|
||||
|
|
@ -156,7 +161,9 @@ charstring_encode_command (cairo_array_t *data, int command)
|
|||
* bytes that will be used is 5.
|
||||
*/
|
||||
static void
|
||||
charstring_encode_integer (cairo_array_t *data, int i)
|
||||
charstring_encode_integer (cairo_array_t *data,
|
||||
int i,
|
||||
cairo_charstring_type_t type)
|
||||
{
|
||||
cairo_status_t status;
|
||||
int orig_size;
|
||||
|
|
@ -174,11 +181,19 @@ charstring_encode_integer (cairo_array_t *data, int i)
|
|||
*p++ = (i >> 8)+ 251;
|
||||
*p++ = i & 0xff;
|
||||
} else {
|
||||
*p++ = 0xff;
|
||||
*p++ = i >> 24;
|
||||
*p++ = (i >> 16) & 0xff;
|
||||
*p++ = (i >> 8) & 0xff;
|
||||
*p++ = i & 0xff;
|
||||
if (type == CAIRO_CHARSTRING_TYPE1) {
|
||||
*p++ = 0xff;
|
||||
*p++ = i >> 24;
|
||||
*p++ = (i >> 16) & 0xff;
|
||||
*p++ = (i >> 8) & 0xff;
|
||||
*p++ = i & 0xff;
|
||||
} else {
|
||||
*p++ = 0xff;
|
||||
*p++ = (i >> 8) & 0xff;
|
||||
*p++ = i & 0xff;
|
||||
*p++ = 0;
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure the array doesn't grow, which allows this function to
|
||||
|
|
@ -193,6 +208,7 @@ charstring_encode_integer (cairo_array_t *data, int i)
|
|||
typedef struct _ps_path_info {
|
||||
cairo_array_t *data;
|
||||
int current_x, current_y;
|
||||
cairo_charstring_type_t type;
|
||||
} t1_path_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -209,8 +225,8 @@ _charstring_move_to (void *closure,
|
|||
|
||||
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
|
||||
dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
|
||||
charstring_encode_integer (path_info->data, dx);
|
||||
charstring_encode_integer (path_info->data, dy);
|
||||
charstring_encode_integer (path_info->data, dx, path_info->type);
|
||||
charstring_encode_integer (path_info->data, dy, path_info->type);
|
||||
path_info->current_x += dx;
|
||||
path_info->current_y += dy;
|
||||
|
||||
|
|
@ -233,8 +249,8 @@ _charstring_line_to (void *closure,
|
|||
|
||||
dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
|
||||
dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
|
||||
charstring_encode_integer (path_info->data, dx);
|
||||
charstring_encode_integer (path_info->data, dy);
|
||||
charstring_encode_integer (path_info->data, dx, path_info->type);
|
||||
charstring_encode_integer (path_info->data, dy, path_info->type);
|
||||
path_info->current_x += dx;
|
||||
path_info->current_y += dy;
|
||||
|
||||
|
|
@ -263,12 +279,12 @@ _charstring_curve_to (void *closure,
|
|||
dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1;
|
||||
dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2;
|
||||
dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2;
|
||||
charstring_encode_integer (path_info->data, dx1);
|
||||
charstring_encode_integer (path_info->data, dy1);
|
||||
charstring_encode_integer (path_info->data, dx2);
|
||||
charstring_encode_integer (path_info->data, dy2);
|
||||
charstring_encode_integer (path_info->data, dx3);
|
||||
charstring_encode_integer (path_info->data, dy3);
|
||||
charstring_encode_integer (path_info->data, dx1, path_info->type);
|
||||
charstring_encode_integer (path_info->data, dy1, path_info->type);
|
||||
charstring_encode_integer (path_info->data, dx2, path_info->type);
|
||||
charstring_encode_integer (path_info->data, dy2, path_info->type);
|
||||
charstring_encode_integer (path_info->data, dx3, path_info->type);
|
||||
charstring_encode_integer (path_info->data, dy3, path_info->type);
|
||||
path_info->current_x += dx1 + dx2 + dx3;
|
||||
path_info->current_y += dy1 + dy2 + dy3;
|
||||
charstring_encode_command (path_info->data, CHARSTRING_rcurveto);
|
||||
|
|
@ -282,6 +298,9 @@ _charstring_close_path (void *closure)
|
|||
cairo_status_t status;
|
||||
t1_path_info_t *path_info = (t1_path_info_t *) closure;
|
||||
|
||||
if (path_info->type == CAIRO_CHARSTRING_TYPE2)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_array_grow_by (path_info->data, 2);
|
||||
if (status)
|
||||
return status;
|
||||
|
|
@ -309,7 +328,7 @@ charstring_encrypt (cairo_array_t *data)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
create_notdef_charstring (cairo_array_t *data)
|
||||
create_notdef_charstring (cairo_array_t *data, cairo_charstring_type_t type)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -320,13 +339,15 @@ create_notdef_charstring (cairo_array_t *data)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
charstring_encode_integer (data, 0);
|
||||
charstring_encode_integer (data, 0);
|
||||
if (type == CAIRO_CHARSTRING_TYPE1) {
|
||||
charstring_encode_integer (data, 0, type);
|
||||
charstring_encode_integer (data, 0, type);
|
||||
|
||||
/* The width and height is arbitrary. */
|
||||
charstring_encode_integer (data, 500);
|
||||
charstring_encode_integer (data, 500);
|
||||
charstring_encode_command (data, CHARSTRING_sbw);
|
||||
/* The width and height is arbitrary. */
|
||||
charstring_encode_integer (data, 500, type);
|
||||
charstring_encode_integer (data, 500, type);
|
||||
charstring_encode_command (data, CHARSTRING_sbw);
|
||||
}
|
||||
|
||||
charstring_encode_command (data, CHARSTRING_endchar);
|
||||
|
||||
|
|
@ -334,10 +355,11 @@ create_notdef_charstring (cairo_array_t *data)
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_type1_font_create_charstring (cairo_type1_font_t *font,
|
||||
int subset_index,
|
||||
int glyph_index,
|
||||
cairo_array_t *data)
|
||||
cairo_type1_font_create_charstring (cairo_type1_font_t *font,
|
||||
int subset_index,
|
||||
int glyph_index,
|
||||
cairo_charstring_type_t type,
|
||||
cairo_array_t *data)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
|
@ -369,21 +391,29 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
|
|||
if (metrics->y_bearing + metrics->height > font->y_max)
|
||||
font->y_max = metrics->y_bearing + metrics->height;
|
||||
}
|
||||
font->widths[subset_index] = metrics->width;
|
||||
font->widths[subset_index] = metrics->x_advance;
|
||||
|
||||
status = _cairo_array_grow_by (data, 30);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.width);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.height);
|
||||
charstring_encode_command (data, CHARSTRING_sbw);
|
||||
if (type == CAIRO_CHARSTRING_TYPE1) {
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type);
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.height, type);
|
||||
charstring_encode_command (data, CHARSTRING_sbw);
|
||||
|
||||
path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
|
||||
path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
|
||||
} else {
|
||||
charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type);
|
||||
|
||||
path_info.current_x = 0;
|
||||
path_info.current_y = 0;
|
||||
}
|
||||
path_info.data = data;
|
||||
path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
|
||||
path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
|
||||
path_info.type = type;
|
||||
status = _cairo_path_fixed_interpret (scaled_glyph->path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_charstring_move_to,
|
||||
|
|
@ -429,6 +459,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
|
|||
goto fail;
|
||||
status = cairo_type1_font_create_charstring (font, i,
|
||||
font->scaled_font_subset->glyphs[i],
|
||||
CAIRO_CHARSTRING_TYPE1,
|
||||
&data);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
|
@ -448,7 +479,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
|
|||
status = _cairo_array_append_multiple (&data, zeros, 4);
|
||||
if (status)
|
||||
goto fail;
|
||||
status = create_notdef_charstring (&data);
|
||||
status = create_notdef_charstring (&data, CAIRO_CHARSTRING_TYPE1);
|
||||
if (status)
|
||||
goto fail;
|
||||
charstring_encrypt (&data);
|
||||
|
|
@ -464,35 +495,22 @@ fail:
|
|||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
static void
|
||||
cairo_type1_font_write_header (cairo_type1_font_t *font,
|
||||
const char *name)
|
||||
{
|
||||
cairo_matrix_t matrix;
|
||||
cairo_status_t status;
|
||||
unsigned int i;
|
||||
const char spaces[50] = " ";
|
||||
|
||||
matrix = font->type1_scaled_font->scale;
|
||||
matrix.xy = -matrix.xy;
|
||||
matrix.yy = -matrix.yy;
|
||||
status = cairo_matrix_invert (&matrix);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_printf (font->output,
|
||||
"%%!FontType1-1.1 %s 1.0\n"
|
||||
"11 dict begin\n"
|
||||
"/FontName /%s def\n"
|
||||
"/PaintType 0 def\n"
|
||||
"/FontType 1 def\n"
|
||||
"/FontMatrix [%f %f %f %f 0 0] readonly def\n",
|
||||
"/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
|
||||
name,
|
||||
name,
|
||||
matrix.xx,
|
||||
matrix.yx,
|
||||
matrix.xy,
|
||||
matrix.yy);
|
||||
name);
|
||||
|
||||
/* We don't know the bbox values until after the charstrings have
|
||||
* been generated. Reserve some space and fill in the bbox
|
||||
|
|
@ -515,8 +533,6 @@ cairo_type1_font_write_header (cairo_type1_font_t *font,
|
|||
"readonly def\n"
|
||||
"currentdict end\n"
|
||||
"currentfile eexec\n");
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -640,10 +656,7 @@ cairo_type1_font_write (cairo_type1_font_t *font,
|
|||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
status = cairo_type1_font_write_header (font, name);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cairo_type1_font_write_header (font, name);
|
||||
font->header_size = _cairo_output_stream_get_position (font->output);
|
||||
|
||||
status = cairo_type1_font_write_private_dict (font, name);
|
||||
|
|
@ -798,3 +811,83 @@ _cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
|
|||
free (subset->widths);
|
||||
free (subset->data);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
|
||||
cairo_scaled_font_subset_t *scaled_font_subset)
|
||||
{
|
||||
cairo_type1_font_t *font;
|
||||
cairo_status_t status;
|
||||
unsigned int i;
|
||||
cairo_array_t charstring;
|
||||
|
||||
status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
|
||||
|
||||
type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
if (type2_subset->widths == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
|
||||
_cairo_array_init (&charstring, sizeof (unsigned char));
|
||||
status = _cairo_array_grow_by (&charstring, 32);
|
||||
if (status)
|
||||
goto fail2;
|
||||
|
||||
if (i == 0) {
|
||||
status = create_notdef_charstring (&charstring, CAIRO_CHARSTRING_TYPE2);
|
||||
} else {
|
||||
status = cairo_type1_font_create_charstring (font, i,
|
||||
font->scaled_font_subset->glyphs[i],
|
||||
CAIRO_CHARSTRING_TYPE2,
|
||||
&charstring);
|
||||
}
|
||||
if (status)
|
||||
goto fail2;
|
||||
|
||||
status = _cairo_array_append (&type2_subset->charstrings, &charstring);
|
||||
if (status)
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
type2_subset->widths[i] = font->widths[i];
|
||||
|
||||
type2_subset->x_min = (int) font->x_min;
|
||||
type2_subset->y_min = (int) font->y_min;
|
||||
type2_subset->x_max = (int) font->x_max;
|
||||
type2_subset->y_max = (int) font->y_max;
|
||||
type2_subset->ascent = (int) font->y_max;
|
||||
type2_subset->descent = (int) font->y_min;
|
||||
|
||||
cairo_type1_font_destroy (font);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail2:
|
||||
_cairo_array_fini (&charstring);
|
||||
_cairo_type2_charstrings_fini (type2_subset);
|
||||
fail1:
|
||||
cairo_type1_font_destroy (font);
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
|
||||
{
|
||||
unsigned int i, num_charstrings;
|
||||
cairo_array_t *charstring;
|
||||
|
||||
num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings);
|
||||
for (i = 0; i < num_charstrings; i++) {
|
||||
charstring = _cairo_array_index (&type2_subset->charstrings, i);
|
||||
_cairo_array_fini (charstring);
|
||||
}
|
||||
_cairo_array_fini (&type2_subset->charstrings);
|
||||
|
||||
free (type2_subset->widths);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue