Win32-printing: Fix Type 1 font printing so fallback is not used

Using glyph indices with Type 1 fonts on a printer DC does not work.
Previously there was a temporary fix where Type 1 fonts were printed
as filled paths.

Now that _cairo_scaled_font_subsets_map_glyph() provides the reverse
mapping of the glyph index fix this by converting the glyph indices
back to the unicode values when printing Type 1 fonts.
This commit is contained in:
Adrian Johnson 2008-08-10 14:24:16 +09:30
parent b34c248b92
commit 4c83179418
3 changed files with 75 additions and 11 deletions

View file

@ -51,6 +51,7 @@
#include "cairo-clip-private.h"
#include "cairo-win32-private.h"
#include "cairo-meta-surface-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include <windows.h>
@ -1313,16 +1314,14 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
}
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
/* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1 or
* bitmap font on a printer DC prints garbled text. The text
* displays correctly on a display DC. It appears that when
* using a printer DC. ExtTextOutW() only works with
* characters and not glyph indices.
/* When printing bitmap fonts to a printer DC, Windows may
* substitute an outline font for bitmap font. As the win32
* font backend always uses a screen DC when obtaining the
* font metrics the metrics of the substituted font will not
* match the metrics that the win32 font backend returns.
*
* For now we don't use ExtTextOutW for Type 1 or bitmap
* fonts. These fonts will go through the fallback path for
* non Windows fonts. ie filled outlines for Type 1 fonts and
* fallback images for bitmap fonts.
* If we are printing a bitmap font, use fallback images to
* ensure the font is not substituted.
*/
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32) {
if (_cairo_win32_scaled_font_is_bitmap (scaled_font))
@ -1364,10 +1363,46 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
}
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 &&
! _cairo_win32_scaled_font_is_type1 (scaled_font) &&
source->type == CAIRO_PATTERN_TYPE_SOLID)
{
cairo_matrix_t ctm;
cairo_glyph_t *type1_glyphs = NULL;
cairo_scaled_font_subsets_glyph_t subset_glyph;
/* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1
* font on a printer DC prints garbled text. The text displays
* correctly on a display DC. When using a printer
* DC, ExtTextOutW() only works with characters and not glyph
* indices.
*
* For Type 1 fonts the glyph indices are converted back to
* unicode characters before calling _cairo_win32_surface_show_glyphs().
*
* As _cairo_win32_scaled_font_index_to_ucs4() is a slow
* operation, the font subsetting function
* _cairo_scaled_font_subsets_map_glyph() is used to obtain
* the unicode value because it caches the reverse mapping in
* the subsets.
*/
if (_cairo_win32_scaled_font_is_type1 (scaled_font)) {
type1_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
if (type1_glyphs == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
memcpy (type1_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t));
for (i = 0; i < num_glyphs; i++) {
status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
scaled_font,
type1_glyphs[i].index,
NULL, 0,
&subset_glyph);
if (status)
return status;
type1_glyphs[i].index = subset_glyph.unicode;
}
glyphs = type1_glyphs;
}
if (surface->has_ctm) {
for (i = 0; i < num_glyphs; i++)
@ -1385,6 +1420,9 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
if (surface->has_ctm)
cairo_scaled_font_destroy (scaled_font);
if (type1_glyphs != NULL)
free (type1_glyphs);
return status;
}
@ -1531,6 +1569,11 @@ cairo_win32_printing_surface_create (HDC hdc)
surface->saved_dc_bitmap = NULL;
surface->brush = NULL;
surface->old_brush = NULL;
surface->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
if (surface->font_subsets == NULL) {
free (surface);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
GetClipBox(hdc, &rect);
surface->extents.x = rect.left;

View file

@ -92,6 +92,7 @@ typedef struct _cairo_win32_surface {
cairo_bool_t has_ctm;
cairo_matrix_t ctm;
HBRUSH brush, old_brush;
cairo_scaled_font_subsets_t *font_subsets;
} cairo_win32_surface_t;
/* Surface DC flag values */

View file

@ -50,6 +50,7 @@
#include "cairo-clip-private.h"
#include "cairo-paginated-private.h"
#include "cairo-win32-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include <windows.h>
@ -359,6 +360,7 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
surface->had_simple_clip = FALSE;
surface->extents = surface->clip_rect;
surface->font_subsets = NULL;
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
_cairo_content_from_format (format));
@ -497,6 +499,9 @@ _cairo_win32_surface_finish (void *abstract_surface)
if (surface->initial_clip_rgn)
DeleteObject (surface->initial_clip_rgn);
if (surface->font_subsets != NULL)
_cairo_scaled_font_subsets_destroy (surface->font_subsets);
return CAIRO_STATUS_SUCCESS;
}
@ -1578,6 +1583,7 @@ _cairo_win32_surface_show_glyphs (void *surface,
int start_x, start_y;
double user_x, user_y;
int logical_x, logical_y;
unsigned int glyph_index_option;
/* We can only handle win32 fonts */
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
@ -1663,10 +1669,24 @@ _cairo_win32_surface_show_glyphs (void *surface,
}
}
/* Using glyph indices for a Type 1 font does not work on a
* printer DC. The win32 printing surface will convert the the
* glyph indices of Type 1 fonts to the unicode values.
*/
if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
_cairo_win32_scaled_font_is_type1 (scaled_font))
{
glyph_index_option = 0;
}
else
{
glyph_index_option = ETO_GLYPH_INDEX;
}
win_result = ExtTextOutW(dst->dc,
start_x,
start_y,
ETO_GLYPH_INDEX | ETO_PDY,
glyph_index_option | ETO_PDY,
NULL,
glyph_buf,
num_glyphs,