[cairo] PS surface and composite glyphs
Adrian Johnson
ajohnson at redneon.com
Thu Aug 4 08:55:25 PDT 2005
I've been working with the postscript surface and found that printing of
composite glyphs was not working. Here's a patch that got it working for me.
Is Type 1 font support planned for the postscript backend?
BTW, I found that cairo-demo/PS/basket.c needed a call to
cairo_surface_destroy() to make it work.
-------------- next part --------------
Index: src/cairo-font-subset.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-font-subset.c,v
retrieving revision 1.2
diff -a -u -r1.2 cairo-font-subset.c
--- src/cairo-font-subset.c 13 Jul 2005 18:01:25 -0000 1.2
+++ src/cairo-font-subset.c 4 Aug 2005 14:24:41 -0000
@@ -71,6 +71,10 @@
cairo_status_t status;
};
+static int
+cairo_pdf_ft_font_use_glyph (void *abstract_font, int glyph);
+
+
#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
#define SFNT_VERSION 0x00010000
@@ -310,6 +314,65 @@
return 0;
}
+
+
+typedef struct composite_glyph composite_glyph_t;
+struct composite_glyph {
+ unsigned short flags;
+ unsigned short index;
+ unsigned short args[7]; /* 1 to 7 arguments depending on value of flags */
+};
+
+typedef struct glyph_data glyph_data_t;
+struct glyph_data {
+ short num_contours;
+ char data[8];
+ composite_glyph_t glyph;
+};
+
+/* composite_glyph_t flags */
+#define ARG_1_AND_2_ARE_WORDS 0x0001
+#define WE_HAVE_A_SCALE 0x0008
+#define MORE_COMPONENTS 0x0020
+#define WE_HAVE_AN_X_AND_Y_SCALE 0x0040
+#define WE_HAVE_A_TWO_BY_TWO 0x0080
+
+
+static void
+cairo_pdf_ft_font_remap_composite_glyphs (cairo_pdf_ft_font_t *font, char *buffer)
+{
+ glyph_data_t *glyph_data;
+ composite_glyph_t *composite_glyph;
+ int num_args;
+ int has_more_components;
+ unsigned short flags;
+ unsigned short index;
+
+ glyph_data = (glyph_data_t *) buffer;
+ if ((short)be16_to_cpu (glyph_data->num_contours) >= 0)
+ return;
+
+ composite_glyph = &glyph_data->glyph;
+ do {
+ flags = be16_to_cpu (composite_glyph->flags);
+ has_more_components = flags & MORE_COMPONENTS;
+ index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
+ composite_glyph->index = cpu_to_be16 (index);
+ num_args = 1;
+ if (flags & ARG_1_AND_2_ARE_WORDS)
+ num_args += 1;
+ if (flags & WE_HAVE_A_SCALE)
+ num_args += 1;
+ else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
+ num_args += 2;
+ else if (flags & WE_HAVE_A_TWO_BY_TWO)
+ num_args += 3;
+ composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]);
+ } while (has_more_components);
+
+
+}
+
static int
cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,
unsigned long tag)
@@ -357,8 +420,11 @@
buffer = cairo_pdf_ft_font_write (font, NULL, size);
if (buffer == NULL)
break;
- FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size);
- /* FIXME: remap composite glyphs */
+ if (size != 0)
+ {
+ FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size);
+ cairo_pdf_ft_font_remap_composite_glyphs (font, buffer);
+ }
}
font->glyphs[i].location =
@@ -513,10 +579,10 @@
};
static const table_t truetype_tables[] = {
+ { TTAG_glyf, cairo_pdf_ft_font_write_glyf_table },
{ TTAG_cmap, cairo_pdf_ft_font_write_cmap_table },
{ TTAG_cvt, cairo_pdf_ft_font_write_generic_table },
{ TTAG_fpgm, cairo_pdf_ft_font_write_generic_table },
- { TTAG_glyf, cairo_pdf_ft_font_write_glyf_table },
{ TTAG_head, cairo_pdf_ft_font_write_head_table },
{ TTAG_hhea, cairo_pdf_ft_font_write_hhea_table },
{ TTAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },
More information about the cairo
mailing list