mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-14 09:48:08 +02:00
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:
parent
b34c248b92
commit
4c83179418
3 changed files with 75 additions and 11 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue