[cairo-commit] 4 commits - src/cairo-scaled-font-subsets.c src/cairo-scaled-font-subsets-private.h src/cairo-win32-font.c src/cairo-win32-printing-surface.c src/cairo-win32-private.h src/cairo-win32-surface.c
Adrian Johnson
ajohnson at kemper.freedesktop.org
Sat Aug 9 22:00:44 PDT 2008
src/cairo-scaled-font-subsets-private.h | 14 +++++--
src/cairo-scaled-font-subsets.c | 8 ++--
src/cairo-win32-font.c | 34 ++++++++++++++++-
src/cairo-win32-printing-surface.c | 63 ++++++++++++++++++++++++++------
src/cairo-win32-private.h | 1
src/cairo-win32-surface.c | 22 ++++++++++-
6 files changed, 121 insertions(+), 21 deletions(-)
New commits:
commit bc4635f07729d6a73054971f0e7ec04433f414da
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sun Aug 10 14:24:48 2008 +0930
Update _cairo_scaled_font_subsets_map_glyph() docs
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 1de3f86..bc1b955 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -127,12 +127,10 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets);
* @font_subsets: a #cairo_scaled_font_subsets_t
* @scaled_font: the font of the glyph to be mapped
* @scaled_font_glyph_index: the index of the glyph to be mapped
+ * @utf8: a string of text encoded in UTF-8
+ * @utf8_len: length of @utf8 in bytes
* @subset_glyph_ret: return structure containing subset font and glyph id
*
- * @font_id_ret: return value giving the font ID of the mapped glyph
- * @subset_id_ret: return value giving the subset ID of the mapped glyph within the @font_id_ret
- * @subset_glyph_index_ret: return value giving the index of the mapped glyph within the @subset_id_ret subset
- *
* Map a glyph from a #cairo_scaled_font to a new index within a
* subset of that font. The mapping performed is from the tuple:
*
@@ -170,6 +168,14 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets);
* used by #cairo_scaled_font_subset_t as provided by
* _cairo_scaled_font_subsets_foreach.
*
+ * @utf8 and @utf8_len specify a string of unicode characters that the
+ * glyph @scaled_font_glyph_index maps to. If @utf8_is_mapped in
+ * @subset_glyph_ret is TRUE, the font subsetting will (where index to
+ * unicode mapping is supported) ensure that @scaled_font_glyph_index
+ * maps to @utf8. If @utf8_is_mapped is FALSE,
+ * @scaled_font_glyph_index has already been mapped to a different
+ * unicode string.
+ *
* The returned values in the #cairo_scaled_font_subsets_glyph_t struct are:
*
* @font_id: The font ID of the mapped glyph
commit 4c8317941815971f1d060243e1f6153df06866ca
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sun Aug 10 14:24:16 2008 +0930
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.
diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c
index 0846daa..55d5b19 100644
--- a/src/cairo-win32-printing-surface.c
+++ b/src/cairo-win32-printing-surface.c
@@ -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;
diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h
index 1cdf597..8cbea87 100644
--- a/src/cairo-win32-private.h
+++ b/src/cairo-win32-private.h
@@ -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 */
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index d090ffb..236f052 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -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,
commit b34c248b92b2d1544a23c20ecaa12f64792cb1d3
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sun Aug 10 14:18:52 2008 +0930
Fix _cairo_sub_font_map_glyph() to return correct unicode value
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 2740d63..1f87838 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -460,10 +460,9 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
if (sub_font_glyph == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- if (utf8_len < 0)
- _cairo_sub_font_glyph_lookup_unicode (sub_font_glyph,
- sub_font->scaled_font,
- scaled_font_glyph_index);
+ _cairo_sub_font_glyph_lookup_unicode (sub_font_glyph,
+ sub_font->scaled_font,
+ scaled_font_glyph_index);
status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
if (status) {
@@ -493,6 +492,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
subset_glyph->x_advance = sub_font_glyph->x_advance;
subset_glyph->y_advance = sub_font_glyph->y_advance;
subset_glyph->utf8_is_mapped = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, utf8, utf8_len);
+ subset_glyph->unicode = sub_font_glyph->unicode;
return CAIRO_STATUS_SUCCESS;
}
commit d1c619bc7d51a8e96eaf391691bec142dbd34e0e
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sun Aug 10 14:17:01 2008 +0930
win32-font: Make cairo_show_text() work again
For now implement _ucs4_to_index() and leave _text_to_glyphs()
disabled.
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index ef2d2f0..4c1c929 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -826,6 +826,36 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
return status;
}
+static unsigned long
+_cairo_win32_scaled_font_ucs4_to_index (void *abstract_font,
+ uint32_t ucs4)
+{
+ cairo_win32_scaled_font_t *scaled_font = abstract_font;
+ wchar_t unicode[2];
+ WORD glyph_index;
+ HDC hdc = NULL;
+ cairo_status_t status;
+
+ hdc = _get_global_font_dc ();
+ if (!hdc)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
+ if (status)
+ return 0;
+
+ unicode[0] = ucs4;
+ unicode[1] = 0;
+ if (GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0) == GDI_ERROR) {
+ _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_ucs4_to_index:GetGlyphIndicesW");
+ glyph_index = 0;
+ }
+
+ cairo_win32_scaled_font_done_font (&scaled_font->base);
+
+ return glyph_index;
+}
+
static cairo_status_t
_cairo_win32_scaled_font_set_metrics (cairo_win32_scaled_font_t *scaled_font)
{
@@ -1780,8 +1810,8 @@ const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = {
_cairo_win32_scaled_font_create_toy,
_cairo_win32_scaled_font_fini,
_cairo_win32_scaled_font_glyph_init,
- /* _cairo_win32_scaled_font_text_to_glyphs, FIXME */
- NULL, /* ucs4_to_index */
+ NULL, /* _cairo_win32_scaled_font_text_to_glyphs, FIXME */
+ _cairo_win32_scaled_font_ucs4_to_index,
_cairo_win32_scaled_font_show_glyphs,
_cairo_win32_scaled_font_load_truetype_table,
_cairo_win32_scaled_font_index_to_ucs4,
More information about the cairo-commit
mailing list