[cairo] PDF show glyphs
Adrian Johnson
ajohnson at redneon.com
Mon Feb 5 06:22:29 PST 2007
I've been putting together a patch to get the PDF backend to write out
strings using the TJ operator similar to what is described in bug 2713.
The current issues with the patch are:
- It currently does a _cairo_scaled_glyph_lookup() for every glyph.
I'm thinking of moving this into _cairo_sub_font_glyph_create()
and returning the x_advance it via
cairo_scaled_font_subsets_map_glyph().
- The gnome-print-pdf.c patch referenced in bug 2713 allows
a 0.001*font_scale error when comparing glyph positions. I haven't
done this although it seems to work.
- If the x coordinate of the next glyph in a sequence is > 10*font_scale
I terminate the string and reposition before starting a new string.
I'm not sure if this is necessary.
- Should I limit the maximum string length to prevent the accumulation
of rounding errors?
- It needs more testing.
-------------- next part --------------
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 18f79ca..b31403d 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2796,8 +2796,12 @@ _cairo_pdf_surface_show_glyphs (void *
cairo_pdf_surface_t *surface = abstract_surface;
unsigned int current_subset_id = (unsigned int)-1;
unsigned int font_id, subset_id, subset_glyph_index;
- cairo_bool_t diagonal;
+ cairo_bool_t diagonal, in_TJ;
cairo_status_t status;
+ cairo_scaled_glyph_t *scaled_glyph;
+ double x_advance;
+ double Tlm_x, Tlm_y;
+ double Tm_x;
int i;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
@@ -2818,38 +2822,110 @@ _cairo_pdf_surface_show_glyphs (void *
else
diagonal = FALSE;
+ in_TJ = FALSE;
for (i = 0; i < num_glyphs; i++) {
+ status = _cairo_scaled_glyph_lookup (scaled_font,
+ glyphs[i].index,
+ CAIRO_SCALED_GLYPH_INFO_METRICS,
+ &scaled_glyph);
+ if (status)
+ return status;
+ x_advance = scaled_glyph->metrics.x_advance;
+
status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
scaled_font, glyphs[i].index,
&font_id, &subset_id, &subset_glyph_index);
- if (status)
+ if (status)
return status;
- if (subset_id != current_subset_id)
+ if (subset_id != current_subset_id) {
+ if (in_TJ) {
+ _cairo_output_stream_printf (surface->output, "] TJ\r\n");
+ in_TJ = FALSE;
+ }
_cairo_output_stream_printf (surface->output,
"/CairoFont-%d-%d 1 Tf\r\n",
font_id, subset_id);
+ }
if (subset_id != current_subset_id || !diagonal) {
_cairo_output_stream_printf (surface->output,
- "%f %f %f %f %f %f Tm <%02x> Tj\r\n",
+ "%f %f %f %f %f %f Tm\r\n",
scaled_font->scale.xx,
scaled_font->scale.yx,
-scaled_font->scale.xy,
-scaled_font->scale.yy,
glyphs[i].x,
- glyphs[i].y,
- subset_glyph_index);
+ glyphs[i].y);
current_subset_id = subset_id;
+ Tlm_x = glyphs[i].x;
+ Tlm_y = glyphs[i].y;
+ Tm_x = Tlm_x;
+ }
+
+ if (diagonal) {
+ if (i < num_glyphs - 1 &&
+ glyphs[i].y == glyphs[i+1].y &&
+ fabs((glyphs[i].x - glyphs[i+1].x)/scaled_font->scale.xx) < 10) {
+ if (!in_TJ) {
+ if (i != 0) {
+ _cairo_output_stream_printf (surface->output,
+ "%f %f Td\r\n",
+ (glyphs[i].x - Tlm_x)/scaled_font->scale.xx,
+ (glyphs[i].y - Tlm_x)/-scaled_font->scale.yy);
+ Tlm_x = glyphs[i].x;
+ Tlm_y = glyphs[i].y;
+ Tm_x = Tlm_x;
+ }
+ _cairo_output_stream_printf (surface->output,
+ "[<%02x",
+ subset_glyph_index);
+ Tm_x += x_advance;
+ in_TJ = TRUE;
+ } else {
+ if (glyphs[i].x != Tm_x) {
+ double delta = (long)(1000.0*(glyphs[i].x - Tm_x));
+
+ _cairo_output_stream_printf (surface->output,
+ "> %f <",
+ -delta/scaled_font->scale.xx);
+ Tm_x += delta;
+ }
+ _cairo_output_stream_printf (surface->output,
+ "%02x",
+ subset_glyph_index);
+ Tm_x += x_advance;
+ }
+ }
+ else {
+ if (in_TJ) {
+ _cairo_output_stream_printf (surface->output,
+ "%02x>] TJ\r\n",
+ subset_glyph_index);
+ Tm_x += x_advance;
+ in_TJ = FALSE;
+ } else {
+ if (i != 0) {
+ _cairo_output_stream_printf (surface->output,
+ "%f %f Td ",
+ (glyphs[i].x - Tlm_x)/scaled_font->scale.xx,
+ (glyphs[i].y - Tlm_x)/-scaled_font->scale.yy);
+ Tlm_x = glyphs[i].x;
+ Tlm_y = glyphs[i].y;
+ Tm_x = Tlm_x;
+ }
+ _cairo_output_stream_printf (surface->output,
+ "<%02x> Tj",
+ subset_glyph_index);
+ Tm_x += x_advance;
+ }
+ }
} else {
_cairo_output_stream_printf (surface->output,
- "%f %f Td <%02x> Tj\r\n",
- (glyphs[i].x - glyphs[i-1].x)/scaled_font->scale.xx,
- (glyphs[i].y - glyphs[i-1].y)/scaled_font->scale.yy,
+ "<%02x> Tj\r\n",
subset_glyph_index);
}
}
-
_cairo_output_stream_printf (surface->output,
"ET\r\n");
More information about the cairo
mailing list