summaryrefslogtreecommitdiff
path: root/src/cairo-type1-fallback.c
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2007-04-20 22:30:55 +0930
committerAdrian Johnson <ajohnson@redneon.com>2007-04-20 22:30:55 +0930
commit0c2a653033e0b631a1cb6591263cbd6125ccc00c (patch)
tree0568fe5c4f1f53468a91698dcc299041eea436a3 /src/cairo-type1-fallback.c
parentc68a2389f51880b0fa9df6750abdd840258666fc (diff)
downloadcairo-0c2a653033e0b631a1cb6591263cbd6125ccc00c.tar.gz
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.
Diffstat (limited to 'src/cairo-type1-fallback.c')
-rw-r--r--src/cairo-type1-fallback.c211
1 files changed, 152 insertions, 59 deletions
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index dcf55f440..3a0bd1249 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -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",
- name,
+ "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
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);
+}