[cairo-commit] 2 commits - src/cairo-cff-subset.c
Adrian Johnson
ajohnson at kemper.freedesktop.org
Sat Oct 8 22:02:40 PDT 2011
src/cairo-cff-subset.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 102 insertions(+), 3 deletions(-)
New commits:
commit 61fdaaf7e59a6238dec22feeed03b1a56b614a9d
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sun Oct 9 15:25:42 2011 +1030
cff: fallback if seac style endchar is found
Bug 41548
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index f0abac2..db6fdf7 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -195,6 +195,7 @@ typedef struct _cairo_cff_font {
cairo_bool_t type2_find_width;
cairo_bool_t type2_found_width;
int type2_width;
+ cairo_bool_t type2_has_path;
} cairo_cff_font_t;
@@ -1536,6 +1537,7 @@ cairo_cff_parse_charstring (cairo_cff_font_t *font,
font->type2_stack_size = 0;
font->type2_find_width = FALSE;
+ font->type2_has_path = TRUE;
p++;
} else if (*p == TYPE2_hmoveto || *p == TYPE2_vmoveto) {
if (font->type2_find_width && font->type2_stack_size > 1)
@@ -1543,8 +1545,12 @@ cairo_cff_parse_charstring (cairo_cff_font_t *font,
font->type2_stack_size = 0;
font->type2_find_width = FALSE;
+ font->type2_has_path = TRUE;
p++;
} else if (*p == TYPE2_endchar) {
+ if (!font->type2_has_path && font->type2_stack_size > 3)
+ return CAIRO_INT_STATUS_UNSUPPORTED; /* seac (Ref Appendix C of Type 2 Charstring Format */
+
if (font->type2_find_width && font->type2_stack_size > 0)
font->type2_found_width = TRUE;
@@ -1645,6 +1651,7 @@ cairo_cff_find_width_and_subroutines_used (cairo_cff_font_t *font,
font->type2_find_width = TRUE;
font->type2_found_width = FALSE;
font->type2_width = 0;
+ font->type2_has_path = FALSE;
status = cairo_cff_parse_charstring (font, charstring, length, glyph_id, TRUE);
if (status)
commit e2dca74edf4c8f3cd66385b8ed931a412fc9698e
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sun Oct 9 14:55:46 2011 +1030
cff: in CID fonts the CID is the glyph index
Need to use charset to map CID to GID.
Bug 41548
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index c011cfc..f0abac2 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -144,6 +144,7 @@ typedef struct _cairo_cff_font {
cairo_array_t charstrings_index;
cairo_array_t global_sub_index;
cairo_array_t local_sub_index;
+ unsigned char *charset;
int num_glyphs;
cairo_bool_t is_cid;
cairo_bool_t is_opentype;
@@ -1176,6 +1177,15 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
goto fail;
font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
+ operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
+ if (font->is_cid && !operand)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ decode_integer (operand, &offset);
+ font->charset = font->data + offset;
+ if (font->charset >= font->data_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
if (!font->is_opentype)
cairo_cff_font_read_font_metrics (font, font->top_dict);
@@ -1660,16 +1670,91 @@ cairo_cff_find_width_and_subroutines_used (cairo_cff_font_t *font,
}
static cairo_int_status_t
+cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsigned long *gid)
+{
+ unsigned char *p;
+ unsigned long first_gid;
+ unsigned long first_cid;
+ int num_left;
+ unsigned long c, g;
+
+ if (cid == 0) {
+ *gid = 0;
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ switch (font->charset[0]) {
+ /* Format 0 */
+ case 0:
+ p = font->charset + 1;
+ g = 1;
+ while (g <= (unsigned)font->num_glyphs && p < font->data_end) {
+ c = be16_to_cpu( *((uint16_t *)p) );
+ if (c == cid) {
+ *gid = g;
+ return CAIRO_STATUS_SUCCESS;
+ }
+ g++;
+ p += 2;
+ }
+ break;
+
+ /* Format 1 */
+ case 1:
+ first_gid = 1;
+ p = font->charset + 1;
+ while (first_gid <= (unsigned)font->num_glyphs && p + 2 < font->data_end) {
+ first_cid = be16_to_cpu( *((uint16_t *)p) );
+ num_left = p[2];
+ if (cid >= first_cid && cid <= first_cid + num_left) {
+ *gid = first_gid + cid - first_cid;
+ return CAIRO_STATUS_SUCCESS;
+ }
+ first_gid += num_left + 1;
+ p += 3;
+ }
+ break;
+
+ /* Format 2 */
+ case 2:
+ first_gid = 1;
+ p = font->charset + 1;
+ while (first_gid <= (unsigned)font->num_glyphs && p + 3 < font->data_end) {
+ first_cid = be16_to_cpu( *((uint16_t *)p) );
+ num_left = be16_to_cpu( *((uint16_t *)(p+2)) );
+ if (cid >= first_cid && cid <= first_cid + num_left) {
+ *gid = first_gid + cid - first_cid;
+ return CAIRO_STATUS_SUCCESS;
+ }
+ first_gid += num_left + 1;
+ p += 4;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+static cairo_int_status_t
cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t *font)
{
cff_index_element_t *element;
unsigned int i;
cairo_int_status_t status;
- unsigned long glyph;
+ unsigned long glyph, cid;
font->subset_subroutines = TRUE;
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
- glyph = font->scaled_font_subset->glyphs[i];
+ if (font->is_cid) {
+ cid = font->scaled_font_subset->glyphs[i];
+ status = cairo_cff_font_get_gid_for_cid (font, cid, &glyph);
+ if (unlikely (status))
+ return status;
+ } else {
+ glyph = font->scaled_font_subset->glyphs[i];
+ }
element = _cairo_array_index (&font->charstrings_index, glyph);
status = cff_index_append (&font->charstrings_subset_index,
element->data,
@@ -1704,6 +1789,8 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
unsigned int i;
int fd;
int *reverse_map;
+ unsigned long cid, gid;
+ cairo_int_status_t status;
font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
sizeof (int));
@@ -1727,7 +1814,12 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
font->num_subset_fontdicts = 0;
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
- fd = font->fdselect[font->scaled_font_subset->glyphs[i]];
+ cid = font->scaled_font_subset->glyphs[i];
+ status = cairo_cff_font_get_gid_for_cid (font, cid, &gid);
+ if (unlikely (status))
+ return status;
+
+ fd = font->fdselect[gid];
if (reverse_map[fd] < 0) {
font->fd_subset_map[font->num_subset_fontdicts] = fd;
reverse_map[fd] = font->num_subset_fontdicts++;
More information about the cairo-commit
mailing list